Bug 1290365: add TURN TCP socket to read poll after connect. r=bwc draft
authorNils Ohlmeier [:drno] <drno@ohlmeier.org>
Tue, 02 Aug 2016 10:58:55 -0700
changeset 396950 8346b3b8e1655882584bdf1a60a8af75fc1da1bf
parent 396804 0ba72e8027cfcbcbf3426770ac264a7ade2af090
child 397738 7072dc37e850f345fa219992410f8ce754ae8b6c
push id25150
push userdrno@ohlmeier.org
push dateThu, 04 Aug 2016 22:06:06 +0000
reviewersbwc
bugs1290365
milestone51.0a1
Bug 1290365: add TURN TCP socket to read poll after connect. r=bwc MozReview-Commit-ID: FLITvQCt9Xq
media/mtransport/third_party/nICEr/src/ice/ice_socket.c
media/mtransport/third_party/nICEr/src/stun/nr_socket_buffered_stun.c
media/mtransport/third_party/nICEr/src/stun/nr_socket_buffered_stun.h
--- a/media/mtransport/third_party/nICEr/src/ice/ice_socket.c
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_socket.c
@@ -34,16 +34,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
 static char *RCSSTRING __UNUSED__="$Id: ice_socket.c,v 1.2 2008/04/28 17:59:01 ekr Exp $";
 
 #include <assert.h>
 #include <string.h>
 #include "nr_api.h"
 #include "ice_ctx.h"
 #include "stun.h"
+#include "nr_socket_buffered_stun.h"
 #include "nr_socket_multi_tcp.h"
 
 static void nr_ice_socket_readable_cb(NR_SOCKET s, int how, void *cb_arg)
   {
     int r;
     nr_ice_stun_ctx *sc1,*sc2;
     nr_ice_socket *sock=cb_arg;
     UCHAR buf[9216];
@@ -216,22 +217,27 @@ int nr_ice_socket_create(nr_ice_ctx *ctx
     else {
       assert(addr.protocol == IPPROTO_TCP);
     }
     sock->type=type;
 
     TAILQ_INIT(&sock->candidates);
     TAILQ_INIT(&sock->stun_ctxs);
 
-    if (sock->type != NR_ICE_SOCKET_TYPE_STREAM_TCP){
+    if (sock->type == NR_ICE_SOCKET_TYPE_DGRAM){
       if((r=nr_socket_getfd(nsock,&fd)))
         ABORT(r);
       NR_ASYNC_WAIT(fd,NR_ASYNC_WAIT_READ,nr_ice_socket_readable_cb,sock);
     }
-    else {
+    else if (sock->type == NR_ICE_SOCKET_TYPE_STREAM_TURN) {
+      /* some OS's (e.g. Linux) don't like to see un-connected TCP sockets in
+       * the poll socket set. */
+      nr_socket_buffered_stun_set_readable_cb(nsock,nr_ice_socket_readable_cb,sock);
+    }
+    else if (sock->type == NR_ICE_SOCKET_TYPE_STREAM_TCP) {
       /* in this case we can't hook up using NR_ASYNC_WAIT, because nr_socket_multi_tcp
          consists of multiple nr_sockets and file descriptors. */
       if((r=nr_socket_multi_tcp_set_readable_cb(nsock,nr_ice_socket_readable_cb,sock)))
         ABORT(r);
     }
 
     *sockp=sock;
 
--- a/media/mtransport/third_party/nICEr/src/stun/nr_socket_buffered_stun.c
+++ b/media/mtransport/third_party/nICEr/src/stun/nr_socket_buffered_stun.c
@@ -61,16 +61,18 @@ typedef struct nr_socket_buffered_stun_ 
   int read_state;
 #define NR_ICE_SOCKET_READ_NONE   0
 #define NR_ICE_SOCKET_READ_HDR    1
 #define NR_ICE_SOCKET_READ_FAILED 2
   UCHAR *buffer;
   size_t buffer_size;
   size_t bytes_needed;
   size_t bytes_read;
+  NR_async_cb readable_cb;
+  void *readable_cb_arg;
 
   /* Write state */
   nr_p_buf_ctx *p_bufs;
   nr_p_buf_head pending_writes;
   size_t pending;
   size_t max_pending;
   nr_framing_type framing_type;
 } nr_socket_buffered_stun;
@@ -99,16 +101,25 @@ static nr_socket_vtbl nr_socket_buffered
   nr_socket_buffered_stun_connect,
   0,
   0,
   nr_socket_buffered_stun_close,
   nr_socket_buffered_stun_listen,
   nr_socket_buffered_stun_accept
 };
 
+void nr_socket_buffered_stun_set_readable_cb(nr_socket *sock,
+  NR_async_cb readable_cb, void *readable_cb_arg)
+{
+  nr_socket_buffered_stun *buf_sock = (nr_socket_buffered_stun *)sock->obj;
+
+  buf_sock->readable_cb = readable_cb;
+  buf_sock->readable_cb_arg = readable_cb_arg;
+}
+
 int nr_socket_buffered_set_connected_to(nr_socket *sock, nr_transport_addr *remote_addr)
 {
   nr_socket_buffered_stun *buf_sock = (nr_socket_buffered_stun *)sock->obj;
   int r, _status;
 
   if ((r=nr_transport_addr_copy(&buf_sock->remote_addr, remote_addr)))
     ABORT(r);
 
@@ -400,24 +411,45 @@ static int nr_socket_buffered_stun_accep
   nr_socket_buffered_stun *bsock = (nr_socket_buffered_stun *)obj;
 
   return nr_socket_accept(bsock->inner, addrp, sockp);
 }
 
 static void nr_socket_buffered_stun_connected_cb(NR_SOCKET s, int how, void *arg)
 {
   nr_socket_buffered_stun *sock = (nr_socket_buffered_stun *)arg;
+  int r, _status;
 
   assert(!sock->connected);
 
   sock->connected = 1;
+
+  // once connected arm for read
+  if (sock->readable_cb) {
+    NR_SOCKET fd;
+
+    /* don't use |s| directly here because the NAT emulator depends on handing
+       you its implementation here. */
+    if ((r=nr_socket_getfd(sock->inner, &fd)))
+      ABORT(r);
+
+    NR_ASYNC_WAIT(fd, NR_ASYNC_WAIT_READ, sock->readable_cb, sock->readable_cb_arg);
+  }
+
   if (sock->pending) {
     r_log(LOG_GENERIC, LOG_INFO, "Invoking writable_cb on connected (%u)", (uint32_t) sock->pending);
     nr_socket_buffered_stun_writable_cb(s, how, arg);
   }
+
+  _status=0;
+abort:
+  if (_status) {
+    r_log(LOG_GENERIC, LOG_ERR, "Failure in nr_socket_buffered_stun_connected_cb: %d", _status);
+
+  }
 }
 
 static int nr_socket_buffered_stun_connect(void *obj, nr_transport_addr *addr)
 {
   nr_socket_buffered_stun *sock = (nr_socket_buffered_stun *)obj;
   int r, _status;
 
   if ((r=nr_transport_addr_copy(&sock->remote_addr, addr)))
--- a/media/mtransport/third_party/nICEr/src/stun/nr_socket_buffered_stun.h
+++ b/media/mtransport/third_party/nICEr/src/stun/nr_socket_buffered_stun.h
@@ -46,16 +46,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    This socket takes ownership of the inner socket |sock|.
  */
 
 typedef enum {
   TURN_TCP_FRAMING=0,
   ICE_TCP_FRAMING
 } nr_framing_type;
 
+void nr_socket_buffered_stun_set_readable_cb(nr_socket *sock,
+  NR_async_cb readable_cb, void *readable_cb_arg);
+
 int nr_socket_buffered_stun_create(nr_socket *inner, int max_pending,
   nr_framing_type framing_type, nr_socket **sockp);
 
 int nr_socket_buffered_set_connected_to(nr_socket *sock,
     nr_transport_addr *remote_addr);
 
 #endif