]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
fix ref counting issue in tcp,tls,wss transports
authorAnthony Minessale <anthm@freeswitch.org>
Thu, 20 Jun 2013 02:54:58 +0000 (21:54 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Thu, 20 Jun 2013 02:54:58 +0000 (21:54 -0500)
libs/sofia-sip/.update
libs/sofia-sip/libsofia-sip-ua/nua/nua_registrar.c
libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c
libs/sofia-sip/libsofia-sip-ua/tport/ws.c
libs/sofia-sip/libsofia-sip-ua/tport/ws.h

index 569e4a2fb25c77f8cc716373ee92d8341cb3b1de..5998f9f02e1f58c8313051a31dc5c71dc587e0f6 100644 (file)
@@ -1 +1 @@
-Wed Jun 19 12:25:57 CDT 2013
+Thu Jun 20 01:13:57 EDT 2013
index cb661b1717cc43273218ac227bce329a2da11c05..fbef0166c88bef50787b66a3c9a664a22c25f3b6 100644 (file)
@@ -226,8 +226,10 @@ nua_registrar_server_preprocess(nua_server_request_t *sr)
 
   tport = nta_incoming_transport(nh->nh_nua->nua_nta, sr->sr_irq, sr->sr_request.msg);
 
-  if (!tport_is_tcp(tport))
-    return 0;
+  if (!tport_is_tcp(tport)) {
+         tport_unref(tport);
+         return 0;
+  }
 
   du = nua_dialog_usage_get(ds, nua_registrar_usage, NULL);
   if (du == NULL)
@@ -243,7 +245,7 @@ nua_registrar_server_preprocess(nua_server_request_t *sr)
     tport_unref(ru->tport), ru->tport = NULL;
   }
 
-  ru->tport = tport_ref(tport);
+  ru->tport = tport;
   ru->pending = tport_pend(tport, NULL, registrar_tport_error, nh);
 
   tport_set_params(tport,
index e57aa2839524c99dd65a60d519d38b748fe83f59..86baee0d62294e611087d3ebe6912b989084f88a 100644 (file)
@@ -185,6 +185,7 @@ tport_vtable_t const tport_wss_client_vtable =
 static void tport_ws_deinit_primary(tport_primary_t *pri)
 {
   tport_ws_primary_t *wspri = (tport_ws_primary_t *)pri;
+
   if ( wspri->ssl_ctx ) {
          SSL_CTX_free(wspri->ssl_ctx);
          wspri->ssl_ctx = NULL;
@@ -211,7 +212,9 @@ int tport_recv_stream_ws(tport_t *self)
   uint8_t *data;
   ws_opcode_t oc;
 
-  if ( !wstp->ws_initialized ) {
+  if (wstp->ws_initialized < 0) {
+         return -1;
+  } else if (wstp->ws_initialized == 0) {
          if (ws_init(ws, self->tp_socket, 65336, wstp->ws_secure ? wspri->ssl_ctx : NULL, 0) == -2) {
                  return 2;
          }
@@ -226,16 +229,17 @@ int tport_recv_stream_ws(tport_t *self)
          return 2;
   }
 
-  if ((N == -1000) ||(N == 0)) {
-    if (self->tp_msg)
-      msg_recv_commit(self->tp_msg, 0, 1);
-    return 0;    /* End of stream */
+  if ((N == -1000) || (N == 0)) {
+         if (self->tp_msg) {
+                 msg_recv_commit(self->tp_msg, 0, 1);
+         }
+         return 0;    /* End of stream */
   }
   if (N < 0) {
-         err = su_errno();
+         err = errno = EHOSTDOWN;
          SU_DEBUG_1(("%s(%p): su_getmsgsize(): %s (%d)\n", __func__, (void *)self,
                                  su_strerror(err), err));
-         return 0;;
+         return 0;
   }
 
   veclen = tport_recv_iovec(self, &self->tp_msg, iovec, N, 0);
@@ -455,10 +459,12 @@ int tport_ws_init_secondary(tport_t *self, int socket, int accepted,
 static void tport_ws_deinit_secondary(tport_t *self)
 {
        tport_ws_t *wstp = (tport_ws_t *)self;
-  
-       if (wstp->ws_initialized ) {
-               ws_close(wstp->ws, WS_NONE);
-               wstp->ws_initialized = 0;
+
+       if (wstp->ws_initialized == 1) {
+               wsh_t *wsh = wstp->ws;
+               SU_DEBUG_1(("%p destroy ws%s transport %p.\n", (void *) self, wstp->ws_secure ? "s" : "", (void *) wsh));
+               ws_destroy(&wsh);
+               wstp->ws_initialized = -1;
        }
 }
 
index 935dd7cd78e6850664935a2e8941468cf9e01ba5..938b3f6d049c678a1ce0ff5f4067578b4e6e53bd 100644 (file)
@@ -402,23 +402,26 @@ int ws_init(wsh_t *wsh, ws_socket_t sock, size_t buflen, SSL_CTX *ssl_ctx, int c
        return 0;
 }
 
-issize_t ws_close(wsh_t *wsh, int16_t reason) 
+void ws_destroy(wsh_t **wshp)
 {
-       
-       if (wsh->down) {
-               return -1;
-       }
-       wsh->down++;
+       wsh_t *wsh;
 
-       if (reason) {
-               uint16_t *u16;
-               uint8_t fr[4] = {WSOC_CLOSE | 0x80, 2, 0};
+       if (!wshp || ! *wshp) {
+               return;
+       }
 
-               u16 = (uint16_t *) &fr[2];
-               *u16 = htons((int16_t)reason);
-               ws_raw_write(wsh, fr, 4);
+       wsh = *wshp;
+       *wshp = NULL;
+       
+       if (!wsh->down) {
+               ws_close(wsh, WS_NONE);
        }
 
+       if (wsh->down > 1) {
+               return;
+       }
+       
+       wsh->down = 2;
 
        if (wsh->ssl) {
                int code;
@@ -430,12 +433,6 @@ issize_t ws_close(wsh_t *wsh, int16_t reason)
                wsh->ssl = NULL;
        }
 
-       if (wsh->close_sock) {
-               close(wsh->sock);
-       }
-
-       wsh->sock = ws_sock_invalid;
-
        if (wsh->buffer) {
                free(wsh->buffer);
                wsh->buffer = NULL;
@@ -445,7 +442,31 @@ issize_t ws_close(wsh_t *wsh, int16_t reason)
                free(wsh->wbuffer);
                wsh->wbuffer = NULL;
        }
+}
+
+issize_t ws_close(wsh_t *wsh, int16_t reason) 
+{
+       
+       if (wsh->down) {
+               return -1;
+       }
+
+       wsh->down = 1;
+       
+       if (reason && wsh->sock != ws_sock_invalid) {
+               uint16_t *u16;
+               uint8_t fr[4] = {WSOC_CLOSE | 0x80, 2, 0};
 
+               u16 = (uint16_t *) &fr[2];
+               *u16 = htons((int16_t)reason);
+               ws_raw_write(wsh, fr, 4);
+       }
+
+       if (wsh->close_sock) {
+               close(wsh->sock);
+       }
+
+       wsh->sock = ws_sock_invalid;
 
        return reason * -1;
        
index ada0597c7b8f789b286699da748e6587d4f8e04d..2182960c14ad216fa6f21cdf86201d7eebf8a8f3 100644 (file)
@@ -85,6 +85,7 @@ issize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data);
 issize_t ws_write_frame(wsh_t *wsh, ws_opcode_t oc, void *data, size_t bytes);
 int ws_init(wsh_t *wsh, ws_socket_t sock, size_t buflen, SSL_CTX *ssl_ctx, int close_sock);
 issize_t ws_close(wsh_t *wsh, int16_t reason);
+void ws_destroy(wsh_t **wshp);
 void init_ssl(void);
 void deinit_ssl(void);