Author: mikej Date: Fri May 11 13:49:38 2007 New Revision: 5154 Modified: freeswitch/trunk/libs/iax/src/iax-client.h freeswitch/trunk/libs/iax/src/iax.c Log: backport change from the iaxclient sf repository rev 597. adds proper POKE support and a bit better handling of binding failures and port selection. Modified: freeswitch/trunk/libs/iax/src/iax-client.h ============================================================================== --- freeswitch/trunk/libs/iax/src/iax-client.h (original) +++ freeswitch/trunk/libs/iax/src/iax-client.h Fri May 11 13:49:38 2007 @@ -81,6 +81,7 @@ #define IAX_EVENT_REGREJ 30 /* Registration reply */ #define IAX_EVENT_LINKURL 31 /* Unlink */ #define IAX_EVENT_CNG 32 /* Comfort-noise (almost silence) */ +#define IAX_EVENT_POKE 33 /* moved from iax.c to support attended transfer */ #define IAX_EVENT_REREQUEST 999 Modified: freeswitch/trunk/libs/iax/src/iax.c ============================================================================== --- freeswitch/trunk/libs/iax/src/iax.c (original) +++ freeswitch/trunk/libs/iax/src/iax.c Fri May 11 13:49:38 2007 @@ -969,23 +969,35 @@ return -1; } - if (preferredportno == 0) - preferredportno = IAX_DEFAULT_PORTNO; - - if (preferredportno > 0) { - sin.sin_family = AF_INET; - if (ip) { - inet_aton(ip, &sin.sin_addr); - } else { - sin.sin_addr.s_addr = 0; - } - - sin.sin_port = htons((short)preferredportno); - if (bind(netfd, (struct sockaddr *) &sin, sizeof(sin)) < 0) { - DEBU(G "Unable to bind to preferred port. Using random one instead."); - } - } - sinlen = sizeof(sin); + if (preferredportno == 0) preferredportno = IAX_DEFAULT_PORTNO; + if (preferredportno < 0) preferredportno = 0; + + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = 0; + sin.sin_port = htons((short)preferredportno); + if (bind(netfd, (struct sockaddr *) &sin, sizeof(sin)) < 0) + { +#if defined(WIN32) || defined(_WIN32_WCE) + if (WSAGetLastError() == WSAEADDRINUSE) +#else + if (errno == EADDRINUSE) +#endif + { + /*the port is already in use, so bind to a free port chosen by the IP stack*/ + DEBU(G "Unable to bind to preferred port - port is in use. Trying to bind to a free one"); + sin.sin_port = htons((short)0); + if (bind(netfd, (struct sockaddr *) &sin, sizeof(sin)) < 0) + { + IAXERROR "Unable to bind UDP socket\n"); + return -1; + } + } else + { + IAXERROR "Unable to bind UDP socket\n"); + return -1; + } + } + sinlen = sizeof(sin); if (getsockname(netfd, (struct sockaddr *) &sin, &sinlen) < 0) { close(netfd); netfd = -1; @@ -1561,6 +1573,12 @@ iax_send_pong(event->session, event->ts); iax_event_free(event); break; + case IAX_EVENT_POKE: + event->etype = IAX_EVENT_PONG; + iax_send_pong(event->session, event->ts); + destroy_session(event->session); + iax_event_free(event); + break; default: return event; } @@ -2652,8 +2670,10 @@ e->ts = ts; e = schedule_delivery(e, ts, updatehistory); break; - case IAX_COMMAND_PING: - case IAX_COMMAND_POKE: + case IAX_COMMAND_POKE: + e->etype = IAX_EVENT_POKE; + e->ts = ts; + break; case IAX_COMMAND_PING: /* PINGS and PONGS don't get scheduled; */ e->etype = IAX_EVENT_PING; e->ts = ts;