aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormnicholson <mnicholson@f38db490-d61c-443f-a65b-d21fe96a405b>2011-05-20 18:49:48 +0000
committermnicholson <mnicholson@f38db490-d61c-443f-a65b-d21fe96a405b>2011-05-20 18:49:48 +0000
commit3020830731b80ba4c03f7c274b802aacbc8bc6b8 (patch)
treecf05256e063becb6b706ed395b6c98075fab4985
parent6f3d6b7abe6c2e89929991a80741b09044214e72 (diff)
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 ........ git-svn-id: http://svn.digium.com/svn/asterisk/trunk@320181 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--channels/chan_sip.c64
1 files changed, 44 insertions, 20 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 75e902e5c..82b27acfa 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -2495,7 +2495,7 @@ static int sip_check_authtimeout(time_t start)
*/
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 @@ static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_sessi
/* 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 @@ static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_sessi
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 @@ static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_sessi
}
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;
}