Changeset f9ed311


Ignore:
Timestamp:
2010-04-14T19:08:23Z (9 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
e88fbe27
Parents:
156bbd7
Message:

getaddrinfo(NULL) may return an IPv4 address first but we should definitely
prefer IPv6.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • bitlbee.c

    r156bbd7 rf9ed311  
    3636static gboolean bitlbee_io_new_client( gpointer data, gint fd, b_input_condition condition );
    3737
     38static gboolean try_listen( struct addrinfo *res )
     39{
     40        int i;
     41       
     42        global.listen_socket = socket( res->ai_family, res->ai_socktype, res->ai_protocol );
     43        if( global.listen_socket < 0 )
     44        {
     45                log_error( "socket" );
     46                return FALSE;
     47        }
     48
     49#ifdef IPV6_V6ONLY             
     50        if( res->ai_family == AF_INET6 )
     51        {
     52                i = 0;
     53                setsockopt( global.listen_socket, IPPROTO_IPV6, IPV6_V6ONLY,
     54                            (char *) &i, sizeof( i ) );
     55        }
     56#endif
     57
     58        /* TIME_WAIT (?) sucks.. */
     59        i = 1;
     60        setsockopt( global.listen_socket, SOL_SOCKET, SO_REUSEADDR, &i, sizeof( i ) );
     61
     62        i = bind( global.listen_socket, res->ai_addr, res->ai_addrlen );
     63        if( i == -1 )
     64        {
     65                closesocket( global.listen_socket );
     66                global.listen_socket = -1;
     67               
     68                log_error( "bind" );
     69                return FALSE;
     70        }
     71       
     72        return TRUE;
     73}
     74
    3875int bitlbee_daemon_init()
    3976{
     
    63100
    64101        global.listen_socket = -1;
    65 
     102       
     103        /* Try IPv6 first (which will become an IPv6+IPv4 socket). */
    66104        for( res = addrinfo_bind; res; res = res->ai_next )
    67         {
    68                 global.listen_socket = socket( res->ai_family, res->ai_socktype, res->ai_protocol );
    69                 if( global.listen_socket < 0 )
    70                         continue;
    71 
    72 #ifdef IPV6_V6ONLY             
    73                 if( res->ai_family == AF_INET6 )
    74                 {
    75                         i = 0;
    76                         setsockopt( global.listen_socket, IPPROTO_IPV6, IPV6_V6ONLY,
    77                                     (char *) &i, sizeof( i ) );
    78                 }
    79 #endif
    80 
    81                 /* TIME_WAIT (?) sucks.. */
    82                 i = 1;
    83                 setsockopt( global.listen_socket, SOL_SOCKET, SO_REUSEADDR, &i, sizeof( i ) );
    84 
    85                 i = bind( global.listen_socket, res->ai_addr, res->ai_addrlen );
    86                 if( i == -1 )
    87                 {
    88                         log_error( "bind" );
    89                         return( -1 );
    90                 }
    91                 break;
    92         }
    93 
     105                if( res->ai_family == AF_INET6 && try_listen( res ) )
     106                        break;
     107       
     108        /* The rest (so IPv4, I guess). */
     109        if( res == NULL )
     110                for( res = addrinfo_bind; res; res = res->ai_next )
     111                        if( res->ai_family != AF_INET6 && try_listen( res ) )
     112                                break;
     113       
    94114        freeaddrinfo( addrinfo_bind );
    95115
Note: See TracChangeset for help on using the changeset viewer.