]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
backport change from the iaxclient sf repository rev 597.
authorMichael Jerris <mike@jerris.com>
Fri, 11 May 2007 17:49:38 +0000 (17:49 +0000)
committerMichael Jerris <mike@jerris.com>
Fri, 11 May 2007 17:49:38 +0000 (17:49 +0000)
adds proper POKE support and a bit better handling of binding failures and port selection.

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5154 d0543943-73ff-0310-b7d9-9358b9ac24b2

libs/iax/src/iax-client.h
libs/iax/src/iax.c

index d0a260cfbb36703e23f77e50c53bf9d33841655d..f2a0281d86dfb5b8e657957cf80db75e228495be 100644 (file)
@@ -81,6 +81,7 @@ struct iax_session;
 #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
index 6bafc65d130c1ac2fa2e8e0b6a957dd6d3665909..ae1fecaa66d72559ea1ae81eae8b20dbe17e04a9 100644 (file)
@@ -969,23 +969,35 @@ int iax_init(char *ip, int preferredportno)
                    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;\r
+               if (preferredportno < 0)  preferredportno = 0;\r
+\r
+               sin.sin_family = AF_INET;\r
+               sin.sin_addr.s_addr = 0;\r
+               sin.sin_port = htons((short)preferredportno);\r
+               if (bind(netfd, (struct sockaddr *) &sin, sizeof(sin)) < 0) \r
+               {\r
+#if defined(WIN32)  ||  defined(_WIN32_WCE)\r
+                       if (WSAGetLastError() == WSAEADDRINUSE)\r
+#else\r
+                       if (errno == EADDRINUSE)\r
+#endif\r
+                       {\r
+                               /*the port is already in use, so bind to a free port chosen by the IP stack*/\r
+                               DEBU(G "Unable to bind to preferred port - port is in use. Trying to bind to a free one");\r
+                               sin.sin_port = htons((short)0);\r
+                               if (bind(netfd, (struct sockaddr *) &sin, sizeof(sin)) < 0)\r
+                               {\r
+                                       IAXERROR "Unable to bind UDP socket\n");\r
+                                       return -1;\r
+                               }\r
+                       } else\r
+                       {\r
+                               IAXERROR "Unable to bind UDP socket\n");\r
+                               return -1;\r
+                       }\r
+               }
+               sinlen = sizeof(sin);
            if (getsockname(netfd, (struct sockaddr *) &sin, &sinlen) < 0) {
                    close(netfd);
                    netfd = -1;
@@ -1561,6 +1573,12 @@ static struct iax_event *handle_event(struct iax_event *event)
                                iax_send_pong(event->session, event->ts);
                                iax_event_free(event);
                                break;
+                       case IAX_EVENT_POKE:\r
+                               event->etype = IAX_EVENT_PONG;\r
+                               iax_send_pong(event->session, event->ts);\r
+                               destroy_session(event->session);\r
+                               iax_event_free(event);\r
+                               break;         \r
                        default:
                                return event;
                        }
@@ -2652,8 +2670,10 @@ static struct iax_event *iax_header_to_event(struct iax_session *session,
                                e->ts = ts;
                                e = schedule_delivery(e, ts, updatehistory);
                                break;
-                       case IAX_COMMAND_PING:
-                       case IAX_COMMAND_POKE:
+                       case IAX_COMMAND_POKE:\r
+                               e->etype = IAX_EVENT_POKE;\r
+                               e->ts = ts;\r
+                               break;                  case IAX_COMMAND_PING:
                                /* PINGS and PONGS don't get scheduled; */
                                e->etype = IAX_EVENT_PING;
                                e->ts = ts;