]> git.sesse.net Git - vlc/commitdiff
Factorize socket listen code
authorRémi Denis-Courmont <rem@videolan.org>
Sun, 5 Nov 2006 15:50:31 +0000 (15:50 +0000)
committerRémi Denis-Courmont <rem@videolan.org>
Sun, 5 Nov 2006 15:50:31 +0000 (15:50 +0000)
include/network.h
src/network/io.c
src/network/tcp.c

index 8051555eff24ffcb020b825c3d14fce2c2a5fd22..d83b55729c12d3202937eb1572f13e87746a4892 100644 (file)
@@ -87,6 +87,9 @@ struct network_socket_t
 #define net_OpenTCP(a, b, c) __net_ConnectTCP(VLC_OBJECT(a), b, c)
 VLC_EXPORT( int, __net_ConnectTCP, ( vlc_object_t *p_this, const char *psz_host, int i_port ) );
 
+VLC_EXPORT( int *, net_Listen, (vlc_object_t *p_this, const char *psz_host, int i_port,
+                 int family, int socktype, int protocol) );
+
 #define net_ListenTCP(a, b, c) __net_ListenTCP(VLC_OBJECT(a), b, c)
 VLC_EXPORT( int *, __net_ListenTCP, ( vlc_object_t *, const char *, int ) );
 
index c9113a8f693f241f44c2e6b61da261cb0100e2b8..63c3cc7ac4505175a3fdb931a6642dd38d80a033 100644 (file)
@@ -62,6 +62,9 @@
 # define EAFNOSUPPORT WSAEAFNOSUPPORT
 #endif
 
+extern int rootwrap_bind (int family, int socktype, int protocol,
+                          const struct sockaddr *addr, size_t alen);
+
 int net_Socket (vlc_object_t *p_this, int family, int socktype,
                 int protocol)
 {
@@ -110,6 +113,97 @@ int net_Socket (vlc_object_t *p_this, int family, int socktype,
 }
 
 
+int *net_Listen (vlc_object_t *p_this, const char *psz_host, int i_port,
+                 int family, int socktype, int protocol)
+{
+    struct addrinfo hints, *res;
+
+    memset (&hints, 0, sizeof( hints ));
+    hints.ai_family = family;
+    hints.ai_socktype = socktype;
+    hints.ai_protocol = protocol;
+    hints.ai_flags = AI_PASSIVE;
+
+    msg_Dbg (p_this, "net: listening to %s port %d", psz_host, i_port);
+
+    int i_val = vlc_getaddrinfo (p_this, psz_host, i_port, &hints, &res);
+    if (i_val)
+    {
+        msg_Err (p_this, "Cannot resolve %s port %d : %s", psz_host, i_port,
+                 vlc_gai_strerror (i_val));
+        return NULL;
+    }
+
+    int *sockv = NULL;
+    unsigned sockc = 0;
+
+    for (struct addrinfo *ptr = res; ptr != NULL; ptr = ptr->ai_next)
+    {
+        int fd = net_Socket (p_this, ptr->ai_family, ptr->ai_socktype,
+                             ptr->ai_protocol);
+        if (fd == -1)
+        {
+            msg_Dbg (p_this, "socket error: %s", net_strerror (net_errno));
+            continue;
+        }
+
+        /* Bind the socket */
+        if (bind (fd, ptr->ai_addr, ptr->ai_addrlen))
+        {
+            int saved_errno = net_errno;
+
+            net_Close (fd);
+#if !defined(WIN32) && !defined(UNDER_CE)
+            fd = rootwrap_bind (ptr->ai_family, ptr->ai_socktype,
+                                ptr->ai_protocol, ptr->ai_addr,
+                                ptr->ai_addrlen);
+            if (fd != -1)
+            {
+                msg_Dbg (p_this, "got socket %d from rootwrap", fd);
+            }
+            else
+#endif
+            {
+                msg_Err (p_this, "socket bind error (%s)",
+                         net_strerror( saved_errno ) );
+                continue;
+            }
+        }
+
+        /* Listen */
+        switch (ptr->ai_socktype)
+        {
+            case SOCK_STREAM:
+            case SOCK_RDM:
+            case SOCK_SEQPACKET:
+                if (listen (fd, INT_MAX))
+                {
+                    msg_Err (p_this, "socket listen error (%s)",
+                            net_strerror (net_errno));
+                    net_Close (fd);
+                    continue;
+                }
+        }
+
+        int *nsockv = (int *)realloc (sockv, (sockc + 2) * sizeof (int));
+        if (nsockv != NULL)
+        {
+            nsockv[sockc++] = fd;
+            sockv = nsockv;
+        }
+        else
+            net_Close (fd);
+    }
+
+    vlc_freeaddrinfo (res);
+
+    if (sockv != NULL)
+        sockv[sockc] = -1;
+
+    return sockv;
+}
+
+
 /*****************************************************************************
  * __net_Close:
  *****************************************************************************
index 9c7edb74ead3c105d32118437a423713659920ee..8d0d59b41c9ea862f0ee2f9a9900ceefb8b823bf 100644 (file)
@@ -59,8 +59,6 @@ static int SocksHandshakeTCP( vlc_object_t *,
                               const char *psz_host, int i_port );
 extern int net_Socket( vlc_object_t *p_this, int i_family, int i_socktype,
                        int i_protocol );
-extern int rootwrap_bind (int family, int socktype, int protocol,
-                          const struct sockaddr *addr, size_t alen);
 
 /*****************************************************************************
  * __net_ConnectTCP:
@@ -267,91 +265,10 @@ next_ai: /* failure */
  * Open TCP passive "listening" socket(s)
  * This function returns NULL in case of error.
  *****************************************************************************/
-int *__net_ListenTCP( vlc_object_t *p_this, const char *psz_host, int i_port )
+int *__net_ListenTCP (vlc_object_t *p_this, const char *psz_host, int i_port)
 {
-    struct addrinfo hints, *res, *ptr;
-    int             i_val, *pi_handles, i_size;
-
-    memset( &hints, 0, sizeof( hints ) );
-    hints.ai_socktype = SOCK_STREAM;
-    hints.ai_flags = AI_PASSIVE;
-
-    msg_Dbg( p_this, "net: listening to %s port %d", psz_host, i_port );
-
-    i_val = vlc_getaddrinfo( p_this, psz_host, i_port, &hints, &res );
-    if( i_val )
-    {
-        msg_Err( p_this, "Cannot resolve %s port %d : %s", psz_host, i_port,
-                 vlc_gai_strerror( i_val ) );
-        return NULL;
-    }
-
-    pi_handles = NULL;
-    i_size = 1;
-
-    for( ptr = res; ptr != NULL; ptr = ptr->ai_next )
-    {
-        int fd, *newpi;
-
-        fd = net_Socket( p_this, ptr->ai_family, ptr->ai_socktype,
-                         ptr->ai_protocol );
-        if( fd == -1 )
-        {
-            msg_Dbg( p_this, "socket error: %s", net_strerror( net_errno ) );
-            continue;
-        }
-
-        /* Bind the socket */
-        if( bind( fd, ptr->ai_addr, ptr->ai_addrlen ) )
-        {
-            int saved_errno;
-
-            saved_errno = net_errno;
-            net_Close( fd );
-#if !defined(WIN32) && !defined(UNDER_CE)
-            fd = rootwrap_bind( ptr->ai_family, ptr->ai_socktype,
-                                ptr->ai_protocol, ptr->ai_addr,
-                                ptr->ai_addrlen );
-            if( fd != -1 )
-            {
-                msg_Dbg( p_this, "got socket %d from rootwrap", fd );
-            }
-            else
-#endif
-            {
-                msg_Err( p_this, "cannot bind socket (%s)",
-                         net_strerror( saved_errno ) );
-                continue;
-            }
-        }
-
-        /* Listen */
-        if( listen( fd, 100 ) == -1 )
-        {
-            msg_Err( p_this, "cannot bring the socket in listening mode (%s)",
-                     net_strerror( net_errno ) );
-            net_Close( fd );
-            continue;
-        }
-
-        newpi = (int *)realloc( pi_handles, (++i_size) * sizeof( int ) );
-        if( newpi == NULL )
-        {
-            net_Close( fd );
-            break;
-        }
-        else
-        {
-            newpi[i_size - 2] = fd;
-            pi_handles = newpi;
-        }
-    }
-
-    vlc_freeaddrinfo( res );
-
-    if( pi_handles != NULL )
-        pi_handles[i_size - 1] = -1;
-    return pi_handles;
+    return net_Listen (p_this, psz_host, i_port, AF_UNSPEC, SOCK_STREAM,
+                       IPPROTO_TCP);
 }
 
 /*****************************************************************************