agent: Actually fail gathering on UDP port unavailability
authorOlivier Crête <olivier.crete@collabora.com>
Wed, 22 Jul 2020 20:23:09 +0000 (16:23 -0400)
committerOlivier Crête <olivier.crete@collabora.com>
Tue, 18 Aug 2020 20:27:57 +0000 (16:27 -0400)
This will make it fail if either our test of UDP port clash fails
or if the kernel rejects the new socket because there is a port clash.

Also include a unit test for this.

agent/agent.c
agent/discovery.c
socket/tcp-passive.c
socket/tcp-passive.h
tests/test-set-port-range.c
tests/test-tcp.c

index 2c1a20c..a23d10f 100644 (file)
@@ -3193,7 +3193,8 @@ nice_agent_gather_candidates (
         host_candidate = NULL;
         while (res == HOST_CANDIDATE_CANT_CREATE_SOCKET ||
             res == HOST_CANDIDATE_DUPLICATE_PORT) {
-          nice_debug ("Agent %p: Trying to create host candidate on port %d", agent, current_port);
+          nice_debug ("Agent %p: Trying to create %s host candidate on port %d", agent,
+              nice_candidate_transport_to_string (transport), current_port);
           nice_address_set_port (addr, current_port);
           res = discovery_add_local_host_candidate (agent, stream->id, cid,
               addr, transport, accept_duplicate, &host_candidate);
@@ -3240,6 +3241,7 @@ nice_agent_gather_candidates (
                 nice_candidate_transport_to_string (transport), stream->id,
                 component->id);
            }
+           ret = FALSE;
            goto error;
         }
 
index 05efe54..60bc6e3 100644 (file)
@@ -680,6 +680,7 @@ HostCandidateResult discovery_add_local_host_candidate (
   NiceStream *stream;
   NiceSocket *nicesock = NULL;
   HostCandidateResult res = HOST_CANDIDATE_FAILED;
+  GError *error = NULL;
 
   if (!agent_find_component (agent, stream_id, component_id, &stream, &component))
     return res;
@@ -713,12 +714,16 @@ HostCandidateResult discovery_add_local_host_candidate (
   } else if (transport == NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE) {
     nicesock = nice_tcp_active_socket_new (agent->main_context, address);
   } else if (transport == NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE) {
-    nicesock = nice_tcp_passive_socket_new (agent->main_context, address);
+    nicesock = nice_tcp_passive_socket_new (agent->main_context, address, &error);
   } else {
     /* TODO: Add TCP-SO */
   }
   if (!nicesock) {
-    res = HOST_CANDIDATE_CANT_CREATE_SOCKET;
+    if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_ADDRESS_IN_USE))
+      res = HOST_CANDIDATE_DUPLICATE_PORT;
+    else
+      res = HOST_CANDIDATE_CANT_CREATE_SOCKET;
+    g_clear_error (&error);
     goto errors;
   }
 
index 6bc43d3..d804d3d 100644 (file)
@@ -79,7 +79,7 @@ static void socket_set_writable_callback (NiceSocket *sock,
 static guint nice_address_hash (const NiceAddress * key);
 
 NiceSocket *
-nice_tcp_passive_socket_new (GMainContext *ctx, NiceAddress *addr)
+nice_tcp_passive_socket_new (GMainContext *ctx, NiceAddress *addr, GError **error)
 {
   union {
     struct sockaddr_storage storage;
@@ -129,8 +129,8 @@ nice_tcp_passive_socket_new (GMainContext *ctx, NiceAddress *addr)
   /* GSocket: All socket file descriptors are set to be close-on-exec. */
   g_socket_set_blocking (gsock, false);
 
-  gret = g_socket_bind (gsock, gaddr, FALSE, NULL) &&
-      g_socket_listen (gsock, NULL);
+  gret = g_socket_bind (gsock, gaddr, FALSE, error) &&
+      g_socket_listen (gsock, error);
   g_object_unref (gaddr);
 
   if (gret == FALSE) {
index 914f081..a706a0c 100644 (file)
@@ -43,7 +43,8 @@
 G_BEGIN_DECLS
 
 
-NiceSocket * nice_tcp_passive_socket_new (GMainContext *ctx, NiceAddress *addr);
+NiceSocket * nice_tcp_passive_socket_new (GMainContext *ctx, NiceAddress *addr,
+    GError **gerror);
 NiceSocket * nice_tcp_passive_socket_accept (NiceSocket *socket);
 
 void nice_tcp_passive_socket_remove_connection (NiceSocket *socket,
index 4a19121..1ed1b4d 100644 (file)
@@ -50,10 +50,20 @@ int main (int argc, char **argv)
 
   agent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245);
 
-  stream1 = nice_agent_add_stream (agent, 1);
+  stream1 = nice_agent_add_stream (agent, 2);
 
   nice_agent_set_port_range (agent, stream1, 1, 8888, 8888);
-  nice_agent_gather_candidates (agent, stream1);
+  nice_agent_set_port_range (agent, stream1, 2, 8888, 8888);
+
+  /* First test with ICE-TCP enabled, this should fail on creating the port */
+  g_assert (nice_agent_gather_candidates (agent, stream1) == FALSE);
+
+  /* First test with ICE-TCP disabled, this should fail on our explicit test */
+  g_object_set (agent, "ice-tcp", FALSE, NULL);
+  g_assert (nice_agent_gather_candidates (agent, stream1) == FALSE);
+
+  nice_agent_set_port_range (agent, stream1, 2, 9999, 9999);
+  g_assert (nice_agent_gather_candidates (agent, stream1));
 
   g_object_unref (agent);
 
@@ -61,4 +71,4 @@ int main (int argc, char **argv)
   WSACleanup();
 #endif
   return 0;
-}
\ No newline at end of file
+}
index 243203c..6abb92d 100644 (file)
@@ -86,6 +86,7 @@ main (void)
 {
   NiceAddress active_bind_addr, passive_bind_addr;
   GSource *srv_listen_source, *srv_input_source, *cli_input_source;
+  GError *error = NULL;
 
   g_networking_init ();
 
@@ -101,7 +102,8 @@ main (void)
   nice_address_init (&tmp);
 
   passive_sock = nice_tcp_passive_socket_new (g_main_loop_get_context (mainloop),
-      &passive_bind_addr);
+      &passive_bind_addr, &error);
+  g_assert_no_error (error);
   g_assert (passive_sock);
 
   srv_listen_source = g_socket_create_source (passive_sock->fileno,