[asterisk-commits] dvossel: branch dvossel/sip_nonblocking_tcp_client r220303 - /team/dvossel/si...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Sep 24 15:18:56 CDT 2009


Author: dvossel
Date: Thu Sep 24 15:18:52 2009
New Revision: 220303

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=220303
Log:
moved tcptls socket write to tcptls connection thread.


Modified:
    team/dvossel/sip_nonblocking_tcp_client/channels/chan_sip.c

Modified: team/dvossel/sip_nonblocking_tcp_client/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/sip_nonblocking_tcp_client/channels/chan_sip.c?view=diff&rev=220303&r1=220302&r2=220303
==============================================================================
--- team/dvossel/sip_nonblocking_tcp_client/channels/chan_sip.c (original)
+++ team/dvossel/sip_nonblocking_tcp_client/channels/chan_sip.c Thu Sep 24 15:18:52 2009
@@ -2105,6 +2105,11 @@
 	TCPTLS_ALERT_STOP,
 };
 
+struct tcptls_packet {
+	AST_LIST_ENTRY(tcptls_packet) entry;
+	struct ast_str *data;
+	int len;
+};
 /*! \brief Definition of a thread that handles a socket */
 struct sip_threadinfo {
 	int stop;
@@ -2112,6 +2117,7 @@
 	pthread_t threadid;
 	struct ast_tcptls_session_instance *tcptls_session;
 	enum sip_transport type;	/*!< We keep a copy of the type here so we can display it in the connection list */
+	AST_LIST_HEAD_NOLOCK(, tcptls_packet) packet_q;
 };
 
 /*! \brief Definition of an MWI subscription to another server */
@@ -2896,6 +2902,32 @@
 	return res;
 }
 
+static void tcptls_packet_destructor(void *obj)
+{
+	struct tcptls_packet *packet = obj;
+
+	if (packet->data) {
+		ast_free(packet->data);
+	}
+}
+
+static void sip_threadinfo_destructor(void *obj)
+{
+	struct sip_threadinfo *th = obj;
+	struct tcptls_packet *packet;
+	if (th->alert_pipe[1] > -1) {
+		close(th->alert_pipe[0]);
+	}
+	if (th->alert_pipe[1] > -1) {
+		close(th->alert_pipe[1]);
+	}
+	th->alert_pipe[0] = th->alert_pipe[1] = -1;
+
+	while ((packet = AST_LIST_REMOVE_HEAD(&th->packet_q, entry))) {
+		ao2_t_ref(packet, -1, "thread destruction, removing packet from frame queue");
+	}
+}
+
 /*! \brief SIP TCP connection handler */
 static void *sip_tcp_worker_fn(void *data)
 {
@@ -2908,7 +2940,7 @@
 {
 	struct sip_threadinfo *th;
 
-	if (!(th = ao2_alloc(sizeof(*th), NULL))) {
+	if (!(th = ao2_alloc(sizeof(*th), sip_threadinfo_destructor))) {
 		return NULL;
 	}
 
@@ -2918,7 +2950,6 @@
 		ao2_t_ref(th, -1, "Failed to open alert pipe on sip_threadinfo");
 		return NULL;
 	}
-	ast_log(LOG_NOTICE, " alertpipe is supposed to be up\n"); //todohere remove
 	th->tcptls_session = tcptls_session;
 	th->type = tcptls_session->ssl ? SIP_TRANSPORT_TLS: SIP_TRANSPORT_TCP;
 	ao2_t_link(threadl, th, "Adding new tcptls helper thread");
@@ -2928,22 +2959,39 @@
 
 static int sip_tcptls_write(struct ast_tcptls_session_instance *tcptls_session, const void *buf, size_t len)
 {
-	int res = 0;
-	struct sip_threadinfo *th;
+	int res = len;
+	struct sip_threadinfo *th = NULL;
 	struct sip_threadinfo tmp = {
 		.tcptls_session = tcptls_session,
 	};
 	enum sip_tcptls_alert alert = TCPTLS_ALERT_DATA;
+	struct tcptls_packet *packet = NULL;
 	if (!(th = ao2_t_find(threadl, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread"))) {
 		return -1;
 	}
 
-	/* must lock the thread info object to guarantee control of alert_pipe fd */
+	/* must lock the thread info object to guarantee control of alert_pipe fd and the packet queue */
+
+	if (!(packet = ao2_alloc(sizeof(*packet), tcptls_packet_destructor))) {
+		ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo obj, could not create packet");
+		return -1;
+	}
+
+	if (!(packet->data = ast_str_create(len))) {
+		ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo obj, could not create packet");
+		ao2_t_ref(packet, -1, "could not allocate packet's data");
+		return -1;
+	}
+	ast_str_set(&packet->data, 0, "%s", (char *) buf);
+	packet->len = len;
+
+	/* alert tcptls thread handler that there is a packet to be sent */
 	ao2_lock(th);
-	res = ast_tcptls_server_write(tcptls_session, buf, len); //todohere, replace this with write to th info queue
+	AST_LIST_INSERT_TAIL(&th->packet_q, packet, entry);
 	if (write(th->alert_pipe[1], &alert, sizeof(alert)) == -1) {
 		ast_log(LOG_ERROR, "write() to alert pipe failed: %s\n", strerror(errno));
-		//todohere remove from data queue since alert failed
+		AST_LIST_REMOVE_HEAD(&th->packet_q, entry);
+		ao2_t_ref(packet, -1, "could not write to alert pipe, remove packet");
 		res = -1;
 	}
 	ao2_unlock(th);
@@ -3095,6 +3143,7 @@
 			handle_request_do(&req, &tcptls_session->remote_address);
 		} else if (fds[1].revents) { /* alert_pipe indicates there is data in the send queue to be sent */
 			enum sip_tcptls_alert alert;
+			struct tcptls_packet *packet;
 
 			if (read(me->alert_pipe[0], &alert, sizeof(alert)) == -1) {
 				ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
@@ -3105,8 +3154,18 @@
 			case TCPTLS_ALERT_STOP:
 				goto cleanup;
 			case TCPTLS_ALERT_DATA:
-				ast_log(LOG_NOTICE, "GOT SEND ALERT!\n"); //todohere remove
-				//todohere check threadinfo read queue for packets to send
+				ao2_lock(me);
+				if (!(packet = AST_LIST_REMOVE_HEAD(&me->packet_q, entry))) {
+					ast_log(LOG_WARNING, "TCPTLS thread alert_pipe indicated packet should be sent, but frame_q is empty");
+				} else if (ast_tcptls_server_write(tcptls_session, ast_str_buffer(packet->data), packet->len) == -1) {
+					ast_log(LOG_WARNING, "Failure to write to tcp/tls socket\n");
+				}
+
+				if (packet) {
+					ao2_t_ref(packet, -1, "tcptls packet sent, this is no longer needed");
+				}
+				ao2_unlock(me);
+
 				break;
 			default:
 				ast_log(LOG_ERROR, "Unknown tcptls thread alert '%d'\n", alert);
@@ -3116,15 +3175,6 @@
 
 cleanup:
 	ao2_t_unlink(threadl, me, "Removing tcptls helper thread, thread is closing");
-	ao2_lock(me);
-	if (me->alert_pipe[1] > -1) {
-		close(me->alert_pipe[0]);
-	}
-	if (me->alert_pipe[1] > -1) {
-		close(me->alert_pipe[1]);
-	}
-	me->alert_pipe[0] = me->alert_pipe[1] = -1;
-	ao2_unlock(me);
 	ao2_t_ref(me, -1, "Closing tcptls thread, decrementing ref of sip_threadinfo");
 cleanup2:
 	fclose(tcptls_session->f);
@@ -9972,7 +10022,6 @@
 static int add_rpid(struct sip_request *req, struct sip_pvt *p)
 {
 	struct ast_str *tmp = ast_str_alloca(256);
-	char tmp2[256];
 	char *lid_num = NULL;
 	char *lid_name = NULL;
 	int lid_pres;
@@ -9996,8 +10045,6 @@
 	if (ast_strlen_zero(lid_name))
 		lid_name = lid_num;
 	fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip.sin_addr));
-
-	lid_num = ast_uri_encode(lid_num, tmp2, sizeof(tmp2), 1);
 
 	if (ast_test_flag(&p->flags[0], SIP_SENDRPID_PAI)) {
 		if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {




More information about the asterisk-commits mailing list