Add a nice_socket_can_send and nice_socket_set_writable_callback APIs
authorYouness Alaoui <youness.alaoui@collabora.co.uk>
Fri, 25 Apr 2014 10:40:40 +0000 (06:40 -0400)
committerOlivier CrĂȘte <olivier.crete@collabora.com>
Sat, 17 May 2014 04:22:36 +0000 (00:22 -0400)
12 files changed:
socket/http.c
socket/pseudossl.c
socket/socket.c
socket/socket.h
socket/socks5.c
socket/tcp-active.c
socket/tcp-bsd.c
socket/tcp-bsd.h
socket/tcp-passive.c
socket/udp-bsd.c
socket/udp-turn-over-tcp.c
socket/udp-turn.c

index 40ee697..41ce1c3 100644 (file)
@@ -92,6 +92,9 @@ static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to,
 static gint socket_send_messages_reliable (NiceSocket *sock,
     const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages);
 static gboolean socket_is_reliable (NiceSocket *sock);
+static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr);
+static void socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data);
 
 NiceSocket *
 nice_http_socket_new (NiceSocket *base_socket,
@@ -121,6 +124,8 @@ nice_http_socket_new (NiceSocket *base_socket,
     sock->send_messages_reliable = socket_send_messages_reliable;
     sock->recv_messages = socket_recv_messages;
     sock->is_reliable = socket_is_reliable;
+    sock->can_send = socket_can_send;
+    sock->set_writable_callback = socket_set_writable_callback;
     sock->close = socket_close;
 
     /* Send HTTP CONNECT */
@@ -611,3 +616,20 @@ socket_is_reliable (NiceSocket *sock)
 
   return nice_socket_is_reliable (priv->base_socket);
 }
+
+static gboolean
+socket_can_send (NiceSocket *sock, NiceAddress *addr)
+{
+  HttpPriv *priv = sock->priv;
+
+  return nice_socket_can_send (priv->base_socket, addr);
+}
+
+static void
+socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data)
+{
+  HttpPriv *priv = sock->priv;
+
+  nice_socket_set_writable_callback (priv->base_socket, callback, user_data);
+}
index af9c7d5..bea75c5 100644 (file)
@@ -113,6 +113,9 @@ static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to,
 static gint socket_send_messages_reliable (NiceSocket *sock,
     const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages);
 static gboolean socket_is_reliable (NiceSocket *sock);
+static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr);
+static void socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data);
 
 NiceSocket *
 nice_pseudossl_socket_new (NiceSocket *base_socket,
@@ -147,6 +150,8 @@ nice_pseudossl_socket_new (NiceSocket *base_socket,
   sock->send_messages_reliable = socket_send_messages_reliable;
   sock->recv_messages = socket_recv_messages;
   sock->is_reliable = socket_is_reliable;
+  sock->can_send = socket_can_send;
+  sock->set_writable_callback = socket_set_writable_callback;
   sock->close = socket_close;
 
   /* We send 'to' NULL because it will always be to an already connected
@@ -288,3 +293,20 @@ socket_is_reliable (NiceSocket *sock)
 
   return nice_socket_is_reliable (priv->base_socket);
 }
+
+static gboolean
+socket_can_send (NiceSocket *sock, NiceAddress *addr)
+{
+  PseudoSSLPriv *priv = sock->priv;
+
+  return nice_socket_can_send (priv->base_socket, addr);
+}
+
+static void
+socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data)
+{
+  PseudoSSLPriv *priv = sock->priv;
+
+  nice_socket_set_writable_callback (priv->base_socket, callback, user_data);
+}
index a92d2d9..9c0d978 100644 (file)
@@ -249,6 +249,22 @@ nice_socket_is_reliable (NiceSocket *sock)
   return sock->is_reliable (sock);
 }
 
+gboolean
+nice_socket_can_send (NiceSocket *sock, NiceAddress *addr)
+{
+  if (sock->can_send)
+    return sock->can_send (sock, addr);
+  return TRUE;
+}
+
+void
+nice_socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data)
+{
+  if (sock->set_writable_callback)
+    sock->set_writable_callback (sock, callback, user_data);
+}
+
 void
 nice_socket_free (NiceSocket *sock)
 {
index 7969f21..41ea07b 100644 (file)
@@ -68,6 +68,8 @@ typedef enum {
   NICE_SOCKET_TYPE_TCP_SO
 } NiceSocketType;
 
+typedef void (*NiceSocketWritableCb) (NiceSocket *sock, gpointer user_data);
+
 struct _NiceSocket
 {
   NiceAddress addr;
@@ -83,10 +85,14 @@ struct _NiceSocket
   gint (*send_messages_reliable) (NiceSocket *sock, const NiceAddress *to,
       const NiceOutputMessage *messages, guint n_messages);
   gboolean (*is_reliable) (NiceSocket *sock);
+  gboolean (*can_send) (NiceSocket *sock, NiceAddress *addr);
+  void (*set_writable_callback) (NiceSocket *sock,
+      NiceSocketWritableCb callback, gpointer user_data);
   void (*close) (NiceSocket *sock);
   void *priv;
 };
 
+
 G_GNUC_WARN_UNUSED_RESULT
 gint
 nice_socket_recv_messages (NiceSocket *sock,
@@ -111,6 +117,12 @@ nice_socket_send_reliable (NiceSocket *sock, const NiceAddress *addr, gsize len,
 gboolean
 nice_socket_is_reliable (NiceSocket *sock);
 
+gboolean
+nice_socket_can_send (NiceSocket *sock, NiceAddress *addr);
+
+void
+nice_socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data);
 
 void
 nice_socket_free (NiceSocket *sock);
index 3d44e8e..65e46d6 100644 (file)
@@ -78,6 +78,9 @@ static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to,
 static gint socket_send_messages_reliable (NiceSocket *sock,
     const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages);
 static gboolean socket_is_reliable (NiceSocket *sock);
+static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr);
+static void socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data);
 
 
 NiceSocket *
@@ -103,6 +106,8 @@ nice_socks5_socket_new (NiceSocket *base_socket,
     sock->send_messages_reliable = socket_send_messages_reliable;
     sock->recv_messages = socket_recv_messages;
     sock->is_reliable = socket_is_reliable;
+    sock->can_send = socket_can_send;
+    sock->set_writable_callback = socket_set_writable_callback;
     sock->close = socket_close;
 
     /* Send SOCKS5 handshake */
@@ -459,3 +464,19 @@ socket_is_reliable (NiceSocket *sock)
   return nice_socket_is_reliable (priv->base_socket);
 }
 
+static gboolean
+socket_can_send (NiceSocket *sock, NiceAddress *addr)
+{
+  Socks5Priv *priv = sock->priv;
+
+  return nice_socket_can_send (priv->base_socket, addr);
+}
+
+static void
+socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data)
+{
+  Socks5Priv *priv = sock->priv;
+
+  nice_socket_set_writable_callback (priv->base_socket, callback, user_data);
+}
index 4a5733f..374782c 100644 (file)
@@ -64,6 +64,9 @@ static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to,
 static gint socket_send_messages_reliable (NiceSocket *sock,
     const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages);
 static gboolean socket_is_reliable (NiceSocket *sock);
+static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr);
+static void socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data);
 
 
 NiceSocket *
@@ -110,6 +113,8 @@ nice_tcp_active_socket_new (GMainContext *ctx, NiceAddress *addr)
   sock->send_messages_reliable = socket_send_messages_reliable;
   sock->recv_messages = socket_recv_messages;
   sock->is_reliable = socket_is_reliable;
+  sock->can_send = socket_can_send;
+  sock->set_writable_callback = socket_set_writable_callback;
   sock->close = socket_close;
 
   return sock;
@@ -152,6 +157,18 @@ socket_is_reliable (NiceSocket *sock)
   return TRUE;
 }
 
+static gboolean
+socket_can_send (NiceSocket *sock, NiceAddress *addr)
+{
+  return FALSE;
+}
+
+static void
+socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data)
+{
+}
+
 NiceSocket *
 nice_tcp_active_socket_connect (NiceSocket *sock, NiceAddress *addr)
 {
index 56f7ca4..2cfca53 100644 (file)
@@ -61,6 +61,8 @@ typedef struct {
   GSource *io_source;
   gboolean error;
   gboolean reliable;
+  NiceSocketWritableCb writable_cb;
+  gpointer writable_data;
 } TcpPriv;
 
 #define MAX_QUEUE_LENGTH 20
@@ -73,6 +75,9 @@ static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to,
 static gint socket_send_messages_reliable (NiceSocket *sock,
     const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages);
 static gboolean socket_is_reliable (NiceSocket *sock);
+static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr);
+static void socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data);
 
 static gboolean socket_send_more (GSocket *gsocket, GIOCondition condition,
     gpointer data);
@@ -95,6 +100,8 @@ nice_tcp_bsd_socket_new_from_gsock (GMainContext *ctx, GSocket *gsock,
   priv->remote_addr = *remote_addr;
   priv->error = FALSE;
   priv->reliable = reliable;
+  priv->writable_cb = NULL;
+  priv->writable_data = NULL;
 
   sock->type = NICE_SOCKET_TYPE_TCP_BSD;
   sock->fileno = g_object_ref (gsock);
@@ -103,6 +110,8 @@ nice_tcp_bsd_socket_new_from_gsock (GMainContext *ctx, GSocket *gsock,
   sock->send_messages_reliable = socket_send_messages_reliable;
   sock->recv_messages = socket_recv_messages;
   sock->is_reliable = socket_is_reliable;
+  sock->can_send = socket_can_send;
+  sock->set_writable_callback = socket_set_writable_callback;
   sock->close = socket_close;
 
   return sock;
@@ -374,13 +383,23 @@ socket_is_reliable (NiceSocket *sock)
   return priv->reliable;
 }
 
+static gboolean
+socket_can_send (NiceSocket *sock, NiceAddress *addr)
+{
+  TcpPriv *priv = sock->priv;
 
-/*
- * Returns:
- * -1 = error
- * 0 = have more to send
- * 1 = sent everything
- */
+  return g_queue_is_empty (&priv->send_queue);
+}
+
+static void
+socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data)
+{
+  TcpPriv *priv = sock->priv;
+
+  priv->writable_cb = callback;
+  priv->writable_data = user_data;
+}
 
 static gboolean
 socket_send_more (
@@ -409,6 +428,10 @@ socket_send_more (
     priv->io_source = NULL;
 
     agent_unlock ();
+
+    if (priv->writable_cb)
+      priv->writable_cb (sock, priv->writable_data);
+
     return FALSE;
   }
 
index 89566d6..58349cc 100644 (file)
@@ -41,7 +41,6 @@
 
 G_BEGIN_DECLS
 
-
 NiceSocket *
 nice_tcp_bsd_socket_new (GMainContext *ctx, NiceAddress *remote_addr,
     NiceAddress *local_addr, gboolean reliable);
index d83b232..2eb05dd 100644 (file)
@@ -53,6 +53,8 @@
 typedef struct {
   GMainContext *context;
   GHashTable *connections;
+  NiceSocketWritableCb writable_cb;
+  gpointer writable_data;
 } TcpPassivePriv;
 
 
@@ -64,7 +66,13 @@ static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to,
 static gint socket_send_messages_reliable (NiceSocket *sock,
     const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages);
 static gboolean socket_is_reliable (NiceSocket *sock);
+static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr);
+static void socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data);
+
 static guint nice_address_hash (const NiceAddress * key);
+static void _set_child_callbacks (NiceAddress *addr, NiceSocket *child,
+    NiceSocket *sock);
 
 NiceSocket *
 nice_tcp_passive_socket_new (GMainContext *ctx, NiceAddress *addr)
@@ -145,6 +153,8 @@ nice_tcp_passive_socket_new (GMainContext *ctx, NiceAddress *addr)
   priv->connections = g_hash_table_new_full ((GHashFunc) nice_address_hash,
       (GEqualFunc) nice_address_equal, (
           GDestroyNotify) nice_address_free, NULL);
+  priv->writable_cb = NULL;
+  priv->writable_data = NULL;
 
   sock->type = NICE_SOCKET_TYPE_TCP_PASSIVE;
   sock->fileno = gsock;
@@ -152,6 +162,8 @@ nice_tcp_passive_socket_new (GMainContext *ctx, NiceAddress *addr)
   sock->send_messages_reliable = socket_send_messages_reliable;
   sock->recv_messages = socket_recv_messages;
   sock->is_reliable = socket_is_reliable;
+  sock->can_send = socket_can_send;
+  sock->set_writable_callback = socket_set_writable_callback;
   sock->close = socket_close;
 
   return sock;
@@ -208,6 +220,42 @@ socket_is_reliable (NiceSocket *sock)
   return TRUE;
 }
 
+static gboolean
+socket_can_send (NiceSocket *sock, NiceAddress *addr)
+{
+  TcpPassivePriv *priv = sock->priv;
+  NiceSocket *peer_socket = NULL;
+
+  /* FIXME: Danger if child socket was closed */
+  if (addr)
+    peer_socket = g_hash_table_lookup (priv->connections, addr);
+  if (peer_socket)
+    return nice_socket_can_send (peer_socket, addr);
+  return FALSE;
+}
+
+static void
+_set_child_callbacks (NiceAddress *addr, NiceSocket *child, NiceSocket *sock)
+{
+  TcpPassivePriv *priv = sock->priv;
+
+  /* FIXME: Danger if child socket was closed */
+  nice_socket_set_writable_callback (child, priv->writable_cb,
+      priv->writable_data);
+}
+
+static void
+socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data)
+{
+  TcpPassivePriv *priv = sock->priv;
+
+  priv->writable_cb = callback;
+  priv->writable_data = user_data;
+
+  g_hash_table_foreach (priv->connections, (GHFunc) _set_child_callbacks, sock);
+}
+
 NiceSocket *
 nice_tcp_passive_socket_accept (NiceSocket *sock)
 {
@@ -248,6 +296,7 @@ nice_tcp_passive_socket_accept (NiceSocket *sock)
   if (new_socket) {
     NiceAddress *key = nice_address_dup (&remote_addr);
 
+    _set_child_callbacks (key, new_socket, sock);
     g_hash_table_insert (priv->connections, key, new_socket);
   }
   return new_socket;
index 7075d3f..304d945 100644 (file)
@@ -64,6 +64,9 @@ static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to,
 static gint socket_send_messages_reliable (NiceSocket *sock,
     const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages);
 static gboolean socket_is_reliable (NiceSocket *sock);
+static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr);
+static void socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data);
 
 struct UdpBsdSocketPrivate
 {
@@ -149,6 +152,8 @@ nice_udp_bsd_socket_new (NiceAddress *addr)
   sock->send_messages_reliable = socket_send_messages_reliable;
   sock->recv_messages = socket_recv_messages;
   sock->is_reliable = socket_is_reliable;
+  sock->can_send = socket_can_send;
+  sock->set_writable_callback = socket_set_writable_callback;
   sock->close = socket_close;
 
   return sock;
@@ -309,3 +314,15 @@ socket_is_reliable (NiceSocket *sock)
   return FALSE;
 }
 
+static gboolean
+socket_can_send (NiceSocket *sock, NiceAddress *addr)
+{
+  return TRUE;
+}
+
+static void
+socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data)
+{
+}
+
index 225ea35..0a1a062 100644 (file)
@@ -83,6 +83,9 @@ static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to,
 static gint socket_send_messages_reliable (NiceSocket *sock,
     const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages);
 static gboolean socket_is_reliable (NiceSocket *sock);
+static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr);
+static void socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data);
 
 NiceSocket *
 nice_udp_turn_over_tcp_socket_new (NiceSocket *base_socket,
@@ -102,6 +105,8 @@ nice_udp_turn_over_tcp_socket_new (NiceSocket *base_socket,
   sock->send_messages_reliable = socket_send_messages_reliable;
   sock->recv_messages = socket_recv_messages;
   sock->is_reliable = socket_is_reliable;
+  sock->can_send = socket_can_send;
+  sock->set_writable_callback = socket_set_writable_callback;
   sock->close = socket_close;
 
   return sock;
@@ -420,3 +425,19 @@ socket_is_reliable (NiceSocket *sock)
   return nice_socket_is_reliable (priv->base_socket);
 }
 
+static gboolean
+socket_can_send (NiceSocket *sock, NiceAddress *addr)
+{
+  TurnTcpPriv *priv = sock->priv;
+
+  return nice_socket_can_send (priv->base_socket, addr);
+}
+
+static void
+socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data)
+{
+  TurnTcpPriv *priv = sock->priv;
+
+  nice_socket_set_writable_callback (priv->base_socket, callback, user_data);
+}
index 36ae94b..e4fd270 100644 (file)
@@ -122,6 +122,9 @@ static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to,
 static gint socket_send_messages_reliable (NiceSocket *sock,
     const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages);
 static gboolean socket_is_reliable (NiceSocket *sock);
+static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr);
+static void socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data);
 
 static void priv_process_pending_bindings (UdpTurnPriv *priv);
 static gboolean priv_retransmissions_tick_unlocked (UdpTurnPriv *priv);
@@ -238,6 +241,8 @@ nice_udp_turn_socket_new (GMainContext *ctx, NiceAddress *addr,
   sock->send_messages_reliable = socket_send_messages_reliable;
   sock->recv_messages = socket_recv_messages;
   sock->is_reliable = socket_is_reliable;
+  sock->can_send = socket_can_send;
+  sock->set_writable_callback = socket_set_writable_callback;
   sock->close = socket_close;
   sock->priv = (void *) priv;
 
@@ -915,6 +920,23 @@ socket_is_reliable (NiceSocket *sock)
 }
 
 static gboolean
+socket_can_send (NiceSocket *sock, NiceAddress *addr)
+{
+  UdpTurnPriv *priv = sock->priv;
+
+  return nice_socket_can_send (priv->base_socket, addr);
+}
+
+static void
+socket_set_writable_callback (NiceSocket *sock,
+    NiceSocketWritableCb callback, gpointer user_data)
+{
+  UdpTurnPriv *priv = sock->priv;
+
+  nice_socket_set_writable_callback (priv->base_socket, callback, user_data);
+}
+
+static gboolean
 priv_forget_send_request (gpointer pointer)
 {
   SendRequest *req = pointer;