Changeset 5c0d53e41a9bc53a611e0984c47ae4c5dae63980

Show
Ignore:
Timestamp:
05/11/06 16:50:31 (2 years ago)
Author:
Rémi Denis-Courmont <rem@videolan.org>
git-committer:
Rémi Denis-Courmont <rem@videolan.org> 1162741831 +0000
git-parent:

[3640b72ca1bc0be62ea95307cdb1bffad2fb358e]

git-author:
Rémi Denis-Courmont <rem@videolan.org> 1162741831 +0000
Message:

Factorize socket listen code

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • include/network.h

    r10d06d3 r5c0d53e  
    8888VLC_EXPORT( int, __net_ConnectTCP, ( vlc_object_t *p_this, const char *psz_host, int i_port ) ); 
    8989 
     90VLC_EXPORT( int *, net_Listen, (vlc_object_t *p_this, const char *psz_host, int i_port, 
     91                 int family, int socktype, int protocol) ); 
     92 
    9093#define net_ListenTCP(a, b, c) __net_ListenTCP(VLC_OBJECT(a), b, c) 
    9194VLC_EXPORT( int *, __net_ListenTCP, ( vlc_object_t *, const char *, int ) ); 
  • src/network/io.c

    rd39a408 r5c0d53e  
    6363#endif 
    6464 
     65extern int rootwrap_bind (int family, int socktype, int protocol, 
     66                          const struct sockaddr *addr, size_t alen); 
     67 
    6568int net_Socket (vlc_object_t *p_this, int family, int socktype, 
    6669                int protocol) 
     
    111114 
    112115 
     116int *net_Listen (vlc_object_t *p_this, const char *psz_host, int i_port, 
     117                 int family, int socktype, int protocol) 
     118{ 
     119    struct addrinfo hints, *res; 
     120 
     121    memset (&hints, 0, sizeof( hints )); 
     122    hints.ai_family = family; 
     123    hints.ai_socktype = socktype; 
     124    hints.ai_protocol = protocol; 
     125    hints.ai_flags = AI_PASSIVE; 
     126 
     127    msg_Dbg (p_this, "net: listening to %s port %d", psz_host, i_port); 
     128 
     129    int i_val = vlc_getaddrinfo (p_this, psz_host, i_port, &hints, &res); 
     130    if (i_val) 
     131    { 
     132        msg_Err (p_this, "Cannot resolve %s port %d : %s", psz_host, i_port, 
     133                 vlc_gai_strerror (i_val)); 
     134        return NULL; 
     135    } 
     136 
     137    int *sockv = NULL; 
     138    unsigned sockc = 0; 
     139 
     140    for (struct addrinfo *ptr = res; ptr != NULL; ptr = ptr->ai_next) 
     141    { 
     142        int fd = net_Socket (p_this, ptr->ai_family, ptr->ai_socktype, 
     143                             ptr->ai_protocol); 
     144        if (fd == -1) 
     145        { 
     146            msg_Dbg (p_this, "socket error: %s", net_strerror (net_errno)); 
     147            continue; 
     148        } 
     149 
     150        /* Bind the socket */ 
     151        if (bind (fd, ptr->ai_addr, ptr->ai_addrlen)) 
     152        { 
     153            int saved_errno = net_errno; 
     154 
     155            net_Close (fd); 
     156#if !defined(WIN32) && !defined(UNDER_CE) 
     157            fd = rootwrap_bind (ptr->ai_family, ptr->ai_socktype, 
     158                                ptr->ai_protocol, ptr->ai_addr, 
     159                                ptr->ai_addrlen); 
     160            if (fd != -1) 
     161            { 
     162                msg_Dbg (p_this, "got socket %d from rootwrap", fd); 
     163            } 
     164            else 
     165#endif 
     166            { 
     167                msg_Err (p_this, "socket bind error (%s)", 
     168                         net_strerror( saved_errno ) ); 
     169                continue; 
     170            } 
     171        } 
     172 
     173        /* Listen */ 
     174        switch (ptr->ai_socktype) 
     175        { 
     176            case SOCK_STREAM: 
     177            case SOCK_RDM: 
     178            case SOCK_SEQPACKET: 
     179                if (listen (fd, INT_MAX)) 
     180                { 
     181                    msg_Err (p_this, "socket listen error (%s)", 
     182                            net_strerror (net_errno)); 
     183                    net_Close (fd); 
     184                    continue; 
     185                } 
     186        } 
     187 
     188        int *nsockv = (int *)realloc (sockv, (sockc + 2) * sizeof (int)); 
     189        if (nsockv != NULL) 
     190        { 
     191            nsockv[sockc++] = fd; 
     192            sockv = nsockv; 
     193        } 
     194        else 
     195            net_Close (fd); 
     196    } 
     197 
     198    vlc_freeaddrinfo (res); 
     199 
     200    if (sockv != NULL) 
     201        sockv[sockc] = -1; 
     202 
     203    return sockv; 
     204} 
     205 
     206 
    113207/***************************************************************************** 
    114208 * __net_Close: 
  • src/network/tcp.c

    rc07085a r5c0d53e  
    6060extern int net_Socket( vlc_object_t *p_this, int i_family, int i_socktype, 
    6161                       int i_protocol ); 
    62 extern int rootwrap_bind (int family, int socktype, int protocol, 
    63                           const struct sockaddr *addr, size_t alen); 
    6462 
    6563/***************************************************************************** 
     
    268266 * This function returns NULL in case of error. 
    269267 *****************************************************************************/ 
    270 int *__net_ListenTCP( vlc_object_t *p_this, const char *psz_host, int i_port
     268int *__net_ListenTCP (vlc_object_t *p_this, const char *psz_host, int i_port
    271269{ 
    272     struct addrinfo hints, *res, *ptr; 
    273     int             i_val, *pi_handles, i_size; 
    274  
    275     memset( &hints, 0, sizeof( hints ) ); 
    276     hints.ai_socktype = SOCK_STREAM; 
    277     hints.ai_flags = AI_PASSIVE; 
    278  
    279     msg_Dbg( p_this, "net: listening to %s port %d", psz_host, i_port ); 
    280  
    281     i_val = vlc_getaddrinfo( p_this, psz_host, i_port, &hints, &res ); 
    282     if( i_val ) 
    283     { 
    284         msg_Err( p_this, "Cannot resolve %s port %d : %s", psz_host, i_port, 
    285                  vlc_gai_strerror( i_val ) ); 
    286         return NULL; 
    287     } 
    288  
    289     pi_handles = NULL; 
    290     i_size = 1; 
    291  
    292     for( ptr = res; ptr != NULL; ptr = ptr->ai_next ) 
    293     { 
    294         int fd, *newpi; 
    295  
    296         fd = net_Socket( p_this, ptr->ai_family, ptr->ai_socktype, 
    297                          ptr->ai_protocol ); 
    298         if( fd == -1 ) 
    299         { 
    300             msg_Dbg( p_this, "socket error: %s", net_strerror( net_errno ) ); 
    301             continue; 
    302         } 
    303  
    304         /* Bind the socket */ 
    305         if( bind( fd, ptr->ai_addr, ptr->ai_addrlen ) ) 
    306         { 
    307             int saved_errno; 
    308  
    309             saved_errno = net_errno; 
    310             net_Close( fd ); 
    311 #if !defined(WIN32) && !defined(UNDER_CE) 
    312             fd = rootwrap_bind( ptr->ai_family, ptr->ai_socktype, 
    313                                 ptr->ai_protocol, ptr->ai_addr, 
    314                                 ptr->ai_addrlen ); 
    315             if( fd != -1 ) 
    316             { 
    317                 msg_Dbg( p_this, "got socket %d from rootwrap", fd ); 
    318             } 
    319             else 
    320 #endif 
    321             { 
    322                 msg_Err( p_this, "cannot bind socket (%s)", 
    323                          net_strerror( saved_errno ) ); 
    324                 continue; 
    325             } 
    326         } 
    327  
    328         /* Listen */ 
    329         if( listen( fd, 100 ) == -1 ) 
    330         { 
    331             msg_Err( p_this, "cannot bring the socket in listening mode (%s)", 
    332                      net_strerror( net_errno ) ); 
    333             net_Close( fd ); 
    334             continue; 
    335         } 
    336  
    337         newpi = (int *)realloc( pi_handles, (++i_size) * sizeof( int ) ); 
    338         if( newpi == NULL ) 
    339         { 
    340             net_Close( fd ); 
    341             break; 
    342         } 
    343         else 
    344         { 
    345             newpi[i_size - 2] = fd; 
    346             pi_handles = newpi; 
    347         } 
    348     } 
    349  
    350     vlc_freeaddrinfo( res ); 
    351  
    352     if( pi_handles != NULL ) 
    353         pi_handles[i_size - 1] = -1; 
    354     return pi_handles; 
     270    return net_Listen (p_this, psz_host, i_port, AF_UNSPEC, SOCK_STREAM, 
     271                       IPPROTO_TCP); 
    355272} 
    356273