[asterisk-commits] mnicholson: trunk r320181 - in /trunk: ./ channels/chan_sip.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri May 20 13:49:59 CDT 2011


Author: mnicholson
Date: Fri May 20 13:49:48 2011
New Revision: 320181

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=320181
Log:
Merged revisions 320180 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.8

........
  r320180 | mnicholson | 2011-05-20 13:48:46 -0500 (Fri, 20 May 2011) | 16 lines
  
  This commit modifies the way polling is done on TLS sockets.
  
  Because of the buffering the TLS layer does, polling is unreliable. If poll is
  called while there is data waiting to be read in the TLS layer but not at the
  network layer, the messaging processing engine will not proceed until something
  else writes data to the socket, which may not occur. This change modifies the
  logic around TLS sockets to only poll after a failed read on a non-blocking
  socket. This way we know that there is no data waiting to be read from the
  buffering layer.
  
  (closes issue #19182)
  Reported by: st
  Patches:
        ssl-poll-fix3.diff uploaded by mnicholson (license 96)
  Tested by: mnicholson
........

Modified:
    trunk/   (props changed)
    trunk/channels/chan_sip.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.8-merged' - no diff available.

Modified: trunk/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_sip.c?view=diff&rev=320181&r1=320180&r2=320181
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Fri May 20 13:49:48 2011
@@ -2495,7 +2495,7 @@
 */
 static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_session_instance *tcptls_session)
 {
-	int res, cl, timeout = -1, authenticated = 0, flags;
+	int res, cl, timeout = -1, authenticated = 0, flags, after_poll = 0, need_poll = 1;
 	time_t start;
 	struct sip_request req = { 0, } , reqcpy = { 0, };
 	struct sip_threadinfo *me = NULL;
@@ -2608,6 +2608,7 @@
 		/* handle the socket event, check for both reads from the socket fd,
 		 * and writes from alert_pipe fd */
 		if (fds[0].revents) { /* there is data on the socket to be read */
+			after_poll = 1;
 
 			fds[0].revents = 0;
 
@@ -2648,22 +2649,35 @@
 					timeout = -1;
 				}
 
-				res = ast_wait_for_input(tcptls_session->fd, timeout);
-				if (res < 0) {
-					ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "SSL": "TCP", res);
-					goto cleanup;
-				} else if (res == 0) {
-					/* timeout */
-					ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
-					goto cleanup;
+				/* special polling behavior is required for TLS
+				 * sockets because of the buffering done in the
+				 * TLS layer */
+				if (!tcptls_session->ssl || need_poll) {
+					need_poll = 0;
+					after_poll = 1;
+					res = ast_wait_for_input(tcptls_session->fd, timeout);
+					if (res < 0) {
+						ast_debug(2, "SIP TCP server :: ast_wait_for_input returned %d\n", res);
+						goto cleanup;
+					} else if (res == 0) {
+						/* timeout */
+						ast_debug(2, "SIP TCP server timed out\n");
+						goto cleanup;
+					}
 				}
 
 				ast_mutex_lock(&tcptls_session->lock);
 				if (!fgets(buf, sizeof(buf), tcptls_session->f)) {
 					ast_mutex_unlock(&tcptls_session->lock);
-					goto cleanup;
+					if (after_poll) {
+						goto cleanup;
+					} else {
+						need_poll = 1;
+						continue;
+					}
 				}
 				ast_mutex_unlock(&tcptls_session->lock);
+				after_poll = 0;
 				if (me->stop) {
 					 goto cleanup;
 				}
@@ -2682,30 +2696,40 @@
 						}
 
 						if (timeout == 0) {
-							ast_debug(2, "SIP %s server timed out", tcptls_session->ssl ? "SSL": "TCP");
+							ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
 							goto cleanup;
 						}
 					} else {
 						timeout = -1;
 					}
 
-					res = ast_wait_for_input(tcptls_session->fd, timeout);
-					if (res < 0) {
-						ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "SSL": "TCP", res);
-						goto cleanup;
-					} else if (res == 0) {
-						/* timeout */
-						ast_debug(2, "SIP %s server timed out", tcptls_session->ssl ? "SSL": "TCP");
-						goto cleanup;
+					if (!tcptls_session->ssl || need_poll) {
+						need_poll = 0;
+						after_poll = 1;
+						res = ast_wait_for_input(tcptls_session->fd, timeout);
+						if (res < 0) {
+							ast_debug(2, "SIP TCP server :: ast_wait_for_input returned %d\n", res);
+							goto cleanup;
+						} else if (res == 0) {
+							/* timeout */
+							ast_debug(2, "SIP TCP server timed out\n");
+							goto cleanup;
+						}
 					}
 
 					ast_mutex_lock(&tcptls_session->lock);
 					if (!(bytes_read = fread(buf, 1, MIN(sizeof(buf) - 1, cl), tcptls_session->f))) {
 						ast_mutex_unlock(&tcptls_session->lock);
-						goto cleanup;
+						if (after_poll) {
+							goto cleanup;
+						} else {
+							need_poll = 1;
+							continue;
+						}
 					}
 					buf[bytes_read] = '\0';
 					ast_mutex_unlock(&tcptls_session->lock);
+					after_poll = 0;
 					if (me->stop) {
 						goto cleanup;
 					}




More information about the asterisk-commits mailing list