diff options
author | Youness Alaoui <youness.alaoui@collabora.co.uk> | 2014-04-15 19:49:45 -0400 |
---|---|---|
committer | Olivier CrĂȘte <olivier.crete@collabora.com> | 2014-05-17 00:22:36 -0400 |
commit | 05b1cea045c2d53e5d62f52177fdcc346a67eca0 (patch) | |
tree | 27d2c2471ae34355d995dfc75110be1e82f5e90b /socket | |
parent | 5bc8e4bc8a0a82daf396d08c50438db24c94d336 (diff) |
Store connections in tcp-passive to allow sending
In the case of TCP-ACTIVE, we don't have a problem, because the new
socket will generate a peer-reflexive candidate with the right
sockptr, and all sends will go through it, but for TCP-PASSIVE, there
is no peer reflexive candidates, so once the pair is selected, the local
candidate will point to the TCP-PASSIVE candidate with the TCP_PASSIVE
socket type which will cause all sends to fail, so we need to proxy
them to the child connections
Diffstat (limited to 'socket')
-rw-r--r-- | socket/tcp-passive.c | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/socket/tcp-passive.c b/socket/tcp-passive.c index 7f5151d..d83b232 100644 --- a/socket/tcp-passive.c +++ b/socket/tcp-passive.c @@ -52,6 +52,7 @@ typedef struct { GMainContext *context; + GHashTable *connections; } TcpPassivePriv; @@ -63,7 +64,7 @@ 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 guint nice_address_hash (const NiceAddress * key); NiceSocket * nice_tcp_passive_socket_new (GMainContext *ctx, NiceAddress *addr) @@ -141,6 +142,9 @@ nice_tcp_passive_socket_new (GMainContext *ctx, NiceAddress *addr) sock->priv = priv = g_slice_new0 (TcpPassivePriv); priv->context = g_main_context_ref (ctx); + priv->connections = g_hash_table_new_full ((GHashFunc) nice_address_hash, + (GEqualFunc) nice_address_equal, ( + GDestroyNotify) nice_address_free, NULL); sock->type = NICE_SOCKET_TYPE_TCP_PASSIVE; sock->fileno = gsock; @@ -160,6 +164,7 @@ socket_close (NiceSocket *sock) if (priv->context) g_main_context_unref (priv->context); + g_hash_table_unref (priv->connections); g_slice_free (TcpPassivePriv, sock->priv); } @@ -173,12 +178,27 @@ static gint socket_recv_messages (NiceSocket *sock, static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { + TcpPassivePriv *priv = sock->priv; + + if (to) { + NiceSocket *peer_socket = g_hash_table_lookup (priv->connections, to); + if (peer_socket) + return nice_socket_send_messages (peer_socket, to, messages, n_messages); + } return -1; } static gint socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { + TcpPassivePriv *priv = sock->priv; + + if (to) { + NiceSocket *peer_socket = g_hash_table_lookup (priv->connections, to); + if (peer_socket) + return nice_socket_send_messages_reliable (peer_socket, to, messages, + n_messages); + } return -1; } @@ -225,5 +245,24 @@ nice_tcp_passive_socket_accept (NiceSocket *sock) &sock->addr, &remote_addr, TRUE); g_object_unref (gsock); + if (new_socket) { + NiceAddress *key = nice_address_dup (&remote_addr); + + g_hash_table_insert (priv->connections, key, new_socket); + } return new_socket; } + +static guint nice_address_hash (const NiceAddress * key) +{ + gchar ip[INET6_ADDRSTRLEN]; + gchar *str; + guint hash; + + nice_address_to_string (key, ip); + str = g_strdup_printf ("%s:%u", ip, nice_address_get_port (key)); + hash = g_str_hash (str); + g_free (str); + + return hash; +} |