[svn-commits] jamesgolovich: branch group/sip-tcptls r97578 - /team/group/sip-tcptls/channels/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Jan 9 12:58:51 CST 2008


Author: jamesgolovich
Date: Wed Jan  9 12:58:51 2008
New Revision: 97578

URL: http://svn.digium.com/view/asterisk?view=rev&rev=97578
Log:
Revert way we read TCP/TLS messages so we can deal with SIP messages
split across multiple packets.

Fix memory leaks when unloading module


Modified:
    team/group/sip-tcptls/channels/chan_sip.c

Modified: team/group/sip-tcptls/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/group/sip-tcptls/channels/chan_sip.c?view=diff&rev=97578&r1=97577&r2=97578
==============================================================================
--- team/group/sip-tcptls/channels/chan_sip.c (original)
+++ team/group/sip-tcptls/channels/chan_sip.c Wed Jan  9 12:58:51 2008
@@ -2006,9 +2006,10 @@
 /*! \brief SIP TCP helper function */
 static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct server_instance *ser) 
 {
-	int res;
-	struct sip_request req = { 0, };
+	int res, cl;
+	struct sip_request req = { 0, } , reqcpy = { 0, };
 	struct sip_threadinfo *me;
+	char buf[1024];
 
 	me = ast_calloc(1, sizeof(*me));
 
@@ -2044,31 +2045,46 @@
 			req.socket.type = SIP_TRANSPORT_TCP;
 			req.socket.port = htons(ourport_tcp);
 		}
-
 		res = ast_wait_for_input(ser->fd, -1);
-		if (res < 0)
+		if (res < 0) {
 			ast_log(LOG_DEBUG, "ast_wait_for_input returned %d\n", res);
-		if (req.socket.lock) 
-			ast_mutex_lock(req.socket.lock);
-
-		if (!(req.len = server_read(ser, req.data, sizeof(req.data)))) {
-			ast_log(LOG_DEBUG, "server_read failed: %s\n", strerror(errno));
 			goto cleanup;
 		}
 
-		if (req.socket.lock) 
-			ast_mutex_unlock(req.socket.lock);
-
-		if (me->stop) 
-			 goto cleanup;
-
+		/* Read in headers one line at a time */
+		while (req.len < 4 || strncmp((char *)&req.data + req.len - 4, "\r\n\r\n", 4)) {
+			if (req.socket.lock) 
+				ast_mutex_lock(req.socket.lock);
+			if (!fgets(buf, sizeof(buf), ser->f))
+				goto cleanup;
+			if (req.socket.lock) 
+				ast_mutex_unlock(req.socket.lock);
+			if (me->stop) 
+				 goto cleanup;
+			strncat(req.data, buf, sizeof(req.data) - req.len);
+			req.len = strlen(req.data);
+		}
+		parse_copy(&reqcpy, &req);
+		if (sscanf(get_header(&reqcpy, "Content-Length"), "%d", &cl)) {
+			while (cl > 0) {
+				if (req.socket.lock) 
+					ast_mutex_lock(req.socket.lock);
+				if (!fread(buf, (cl < sizeof(buf)) ? cl : sizeof(buf), 1, ser->f))
+					goto cleanup;
+				if (req.socket.lock) 
+					ast_mutex_unlock(req.socket.lock);
+				if (me->stop)
+					goto cleanup;
+				cl -= strlen(buf);
+				strncat(req.data, buf, sizeof(req.data) - req.len);
+				req.len = strlen(req.data);
+			}
+		}
 		req.socket.ser = ser;
 		handle_request_do(&req, &ser->requestor);
 	}
 
 cleanup:
-	if (req.socket.lock) 
-		ast_mutex_unlock(req.socket.lock);
 	AST_LIST_REMOVE(&threadl, me, list);
 	ast_free(me);
 cleanup2:
@@ -20127,13 +20143,6 @@
 	struct sip_threadinfo *th;
 	struct ast_context *con;
 	
-	while(!AST_LIST_EMPTY(&threadl)) {
-		AST_LIST_TRAVERSE(&threadl, th, list) {
-			th->stop = 1;
-			pthread_kill(th->threadid, SIGURG);
-		}
-	}
-
 	/* First, take us out of the channel type list */
 	ast_channel_unregister(&sip_tech);
 
@@ -20160,6 +20169,20 @@
 	ast_manager_unregister("SIPpeers");
 	ast_manager_unregister("SIPshowpeer");
 	ast_manager_unregister("SIPshowregistry");
+
+	/* Kill TCP/TLS server threads */
+	if (sip_tcp_desc.master)
+		pthread_cancel(sip_tcp_desc.master);
+	if (sip_tls_desc.master)
+		pthread_cancel(sip_tls_desc.master);
+
+	/* Kill all existing TCP/TLS threads */
+	while(!AST_LIST_EMPTY(&threadl)) {
+		AST_LIST_TRAVERSE(&threadl, th, list) {
+			th->stop = 1;
+			pthread_kill(th->threadid, SIGURG);
+		}
+	}
 
 	dialoglist_lock();
 	/* Hangup all dialogs if they have an owner */
@@ -20192,6 +20215,15 @@
 	/* Free memory for local network address mask */
 	ast_free_ha(localaddr);
 
+	if (default_tls_cfg.certfile)
+		ast_free(default_tls_cfg.certfile);
+	if (default_tls_cfg.cipher)
+		ast_free(default_tls_cfg.cipher);
+	if (default_tls_cfg.cafile)
+		ast_free(default_tls_cfg.cafile);
+	if (default_tls_cfg.capath)
+		ast_free(default_tls_cfg.capath);
+
 	ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
 	ASTOBJ_CONTAINER_DESTROY(&userl);
 	ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer);




More information about the svn-commits mailing list