Changeset e9b755e


Ignore:
Timestamp:
2007-10-18T16:44:25Z (13 years ago)
Author:
Jelmer Vernooij <jelmer@…>
Branches:
master
Children:
7435ccf
Parents:
c511365
Message:

Use standard functions for dealing with both IPv6 and IPv4.

Files:
7 edited

Legend:

Unmodified
Added
Removed
  • bitlbee.c

    rc511365 re9b755e  
    3838int bitlbee_daemon_init()
    3939{
    40 #ifdef IPV6
    41         int use_ipv6 = 1;
    42         struct sockaddr_in6 listen_addr6;
    43 #endif
    44         struct sockaddr_in listen_addr;
     40        struct addrinfo *res, hints, *addrinfo_bind;
    4541        int i;
    4642        FILE *fp;
     
    4945        log_link( LOGLVL_WARNING, LOGOUTPUT_SYSLOG );
    5046       
    51 #ifdef IPV6
    52         if( ( global.listen_socket = socket( AF_INET6, SOCK_STREAM, 0 ) ) == -1 )
    53         {
    54                 use_ipv6 = 0;
    55 #endif
    56                 global.listen_socket = socket( AF_INET, SOCK_STREAM, 0 );
    57 #ifdef IPV6
    58         }
    59 #endif
    60         if( global.listen_socket == -1 )
    61         {
    62                 log_error( "socket" );
    63                 return( -1 );
    64         }
    65        
    66         /* TIME_WAIT (?) sucks.. */
    67         i = 1;
    68         setsockopt( global.listen_socket, SOL_SOCKET, SO_REUSEADDR, &i, sizeof( i ) );
    69        
    70 #ifdef IPV6
    71         memset( &listen_addr6, 0, sizeof( listen_addr6 ) );
    72         listen_addr6.sin6_family = AF_INET6;
    73         listen_addr6.sin6_port = htons( global.conf->port );
    74         if( ( i = inet_pton( AF_INET6, ipv6_wrap( global.conf->iface ), &listen_addr6.sin6_addr ) ) != 1 )
    75         {
    76                 /* Forget about IPv6 in this function. */
    77                 use_ipv6 = 0;
    78 #endif
    79                 memset( &listen_addr, 0, sizeof( listen_addr ) );
    80                 listen_addr.sin_family = AF_INET;
    81                 listen_addr.sin_port = htons( global.conf->port );
    82                 if( strcmp( global.conf->iface, "::" ) == 0 )
    83                         i = inet_pton( AF_INET, "0.0.0.0", &listen_addr.sin_addr );
    84                 else
    85                         i = inet_pton( AF_INET, global.conf->iface, &listen_addr.sin_addr );
    86 #ifdef IPV6
    87         }
    88 #endif
    89        
    90         if( i != 1 )
    91         {
    92                 log_message( LOGLVL_ERROR, "Couldn't parse address `%s'", global.conf->iface );
    93                 return( -1 );
    94         }
    95        
    96 #ifdef IPV6
    97         if( !use_ipv6 || ( i = bind( global.listen_socket, (struct sockaddr *) &listen_addr6, sizeof( listen_addr6 ) ) ) == -1 )
    98 #endif
    99                 i = bind( global.listen_socket, (struct sockaddr *) &listen_addr, sizeof( listen_addr ) );
    100         if( i == -1 )
    101         {
    102                 log_error( "bind" );
    103                 return( -1 );
    104         }
    105        
     47        memset(&hints, 0, sizeof(hints));
     48        hints.ai_family = PF_UNSPEC;
     49        hints.ai_socktype = SOCK_STREAM;
     50        hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
     51
     52        i = getaddrinfo(global.conf->iface, global.conf->port, &hints,
     53                                                &addrinfo_bind);
     54        if (i) {
     55                log_message( LOGLVL_ERROR, "Couldn't parse address `%s': %s",
     56                                         global.conf->iface, gai_strerror(i) );
     57                return -1;
     58        }
     59
     60        global.listen_socket = -1;
     61
     62        for (res = addrinfo_bind; res; res = res->ai_next) {
     63                global.listen_socket = socket(res->ai_family, res->ai_socktype,
     64                                                                          res->ai_protocol);
     65                if (global.listen_socket < 0)
     66                        continue;
     67
     68                /* TIME_WAIT (?) sucks.. */
     69                i = 1;
     70                setsockopt( global.listen_socket, SOL_SOCKET, SO_REUSEADDR, &i,
     71                                        sizeof( i ) );
     72
     73                i = bind( global.listen_socket, res->ai_addr, res->ai_addrlen);
     74                if( i == -1 )
     75                {
     76                        log_error( "bind" );
     77                        return( -1 );
     78                }
     79
     80                break;
     81        }
     82
     83        freeaddrinfo(addrinfo_bind);
     84
    10685        i = listen( global.listen_socket, 10 );
    10786        if( i == -1 )
  • conf.c

    rc511365 re9b755e  
    4747        conf = g_new0( conf_t, 1 );
    4848       
    49 #ifdef IPV6
    50         conf->iface = "::";
    51 #else
    52         conf->iface = "0.0.0.0";
    53 #endif
    54         conf->port = 6667;
     49        conf->iface = NULL;
     50        conf->port = "6667";
    5551        conf->nofork = 0;
    5652        conf->verbose = 0;
     
    8985                else if( opt == 'p' )
    9086                {
    91                         if( ( sscanf( optarg, "%d", &i ) != 1 ) || ( i <= 0 ) || ( i > 65535 ) )
    92                         {
    93                                 fprintf( stderr, "Invalid port number: %s\n", optarg );
    94                                 return( NULL );
    95                         }
    96                         conf->port = i;
     87                        g_free( conf->port );
     88                        conf->port = g_strdup( optarg );
    9789                }
    9890                else if( opt == 'P' )
     
    204196                        else if( g_strcasecmp( ini->key, "daemonport" ) == 0 )
    205197                        {
    206                                 if( ( sscanf( ini->value, "%d", &i ) != 1 ) || ( i <= 0 ) || ( i > 65535 ) )
    207                                 {
    208                                         fprintf( stderr, "Invalid port number: %s\n", ini->value );
    209                                         return( 0 );
    210                                 }
    211                                 conf->port = i;
     198                                conf->port = g_strdup( ini->value );
    212199                        }
    213200                        else if( g_strcasecmp( ini->key, "authmode" ) == 0 )
  • conf.h

    rc511365 re9b755e  
    3333{
    3434        char *iface;
    35         signed int port;
     35        char *port;
    3636        int nofork;
    3737        int verbose;
  • configure

    rc511365 re9b755e  
    3030gcov=0
    3131plugins=1
    32 ipv6=1
    3332
    3433events=glib
     
    7170--gcov=0/1      Disable/enable test coverage reporting  $gcov
    7271--plugins=0/1   Disable/enable plugins support          $plugins
    73 
    74 --ipv6=0/1      IPv6 socket support                     $ipv6
    7572
    7673--events=...    Event handler (glib, libevent)          $events
     
    134131#define CPU "$cpu"
    135132EOF
    136 
    137 if [ "$ipv6" = "1" ]; then
    138         echo '#define IPV6' >> config.h
    139 fi
    140133
    141134if [ "$debug" = "1" ]; then
  • irc.c

    rc511365 re9b755e  
    4545{
    4646        irc_t *irc;
    47         struct hostent *peer;
    48         unsigned int i;
    49         char buf[128];
    50 #ifdef IPV6
    51         struct sockaddr_in6 sock6[1];
    52         unsigned int i6;
    53 #endif
    54         struct sockaddr_in sock[1];
     47        struct sockaddr_storage sock;
     48        socklen_t socklen = sizeof(sock);
    5549       
    5650        irc = g_new0( irc_t, 1 );
     
    7165        irc->channel = g_strdup( ROOT_CHAN );
    7266       
    73         i = sizeof( *sock );
    74 #ifdef IPV6
    75         i6 = sizeof( *sock6 );
    76 #endif
    77        
    7867        if( global.conf->hostname )
    7968                irc->myhost = g_strdup( global.conf->hostname );
    80 #ifdef IPV6
    81         else if( getsockname( irc->fd, (struct sockaddr*) sock6, &i6 ) == 0 && sock6->sin6_family == AF_INET6 )
    82         {
    83                 if( ( peer = gethostbyaddr( (char*) &sock6->sin6_addr, sizeof( sock6->sin6_addr ), AF_INET6 ) ) )
    84                         irc->myhost = g_strdup( peer->h_name );
    85                 else if( inet_ntop( AF_INET6, &sock6->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL )
    86                         irc->myhost = g_strdup( ipv6_unwrap( buf ) );
    87         }
    88 #endif
    89         else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INET )
    90         {
    91                 if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INET ) ) )
    92                         irc->myhost = g_strdup( peer->h_name );
    93                 else if( inet_ntop( AF_INET, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL )
    94                         irc->myhost = g_strdup( buf );
    95         }
    96        
    97         i = sizeof( *sock );
    98 #ifdef IPV6
    99         i6 = sizeof( *sock6 );
    100         if( getpeername( irc->fd, (struct sockaddr*) sock6, &i6 ) == 0 && sock6->sin6_family == AF_INET6 )
    101         {
    102                 if( ( peer = gethostbyaddr( (char*) &sock6->sin6_addr, sizeof( sock6->sin6_addr ), AF_INET6 ) ) )
    103                         irc->host = g_strdup( peer->h_name );
    104                 else if( inet_ntop( AF_INET6, &sock6->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL )
    105                         irc->host = g_strdup( ipv6_unwrap( buf ) );
    106         }
    107         else
    108 #endif
    109         if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INET )
    110         {
    111                 if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INET ) ) )
    112                         irc->host = g_strdup( peer->h_name );
    113                 else if( inet_ntop( AF_INET, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL )
    114                         irc->host = g_strdup( buf );
    115         }
    116        
    117         /* Rare, but possible. */
    118         if( !irc->host ) irc->host = g_strdup( "localhost." );
    119         if( !irc->myhost ) irc->myhost = g_strdup( "localhost." );
    120 
     69        else if( getsockname( irc->fd, (struct sockaddr*) &sock, &socklen ) == 0)
     70        {
     71                irc->myhost = g_new0(char, NI_MAXHOST);
     72
     73                if (getnameinfo((struct sockaddr *)&sock, socklen, irc->myhost,
     74                                                NI_MAXHOST, NULL, -1, 0)) {
     75                        /* Rare, but possible. */
     76                        strncpy(irc->myhost, "localhost.", NI_MAXHOST);
     77                }
     78        }
     79       
     80        if( getpeername( irc->fd, (struct sockaddr*) &sock, &socklen ) == 0)
     81        {
     82                irc->host = g_new0(char, NI_MAXHOST);
     83
     84                if (getnameinfo((struct sockaddr *)&sock, socklen, irc->host,
     85                                                NI_MAXHOST, NULL, -1, 0)) {
     86                        /* Rare, but possible. */
     87                        strncpy(irc->myhost, "localhost.", NI_MAXHOST);
     88                }
     89        }
     90       
    12191        if( global.conf->ping_interval > 0 && global.conf->ping_timeout > 0 )
    12292                irc->ping_source_id = b_timeout_add( global.conf->ping_interval * 1000, irc_userping, irc );
  • lib/misc.c

    rc511365 re9b755e  
    322322}
    323323
    324 #ifdef IPV6
    325 /* Wrap an IPv4 address into IPv6 space. Not thread-safe... */
    326 char *ipv6_wrap( char *src )
    327 {
    328         static char dst[64];
    329         int i;
    330        
    331         for( i = 0; src[i]; i ++ )
    332                 if( ( src[i] < '0' || src[i] > '9' ) && src[i] != '.' )
    333                         break;
    334        
    335         /* Hmm, it's not even an IP... */
    336         if( src[i] )
    337                 return src;
    338        
    339         g_snprintf( dst, sizeof( dst ), "::ffff:%s", src );
    340        
    341         return dst;
    342 }
    343 
    344 /* Unwrap an IPv4 address into IPv6 space. Thread-safe, because it's very simple. :-) */
    345 char *ipv6_unwrap( char *src )
    346 {
    347         int i;
    348        
    349         if( g_strncasecmp( src, "::ffff:", 7 ) != 0 )
    350                 return src;
    351        
    352         for( i = 7; src[i]; i ++ )
    353                 if( ( src[i] < '0' || src[i] > '9' ) && src[i] != '.' )
    354                         break;
    355        
    356         /* Hmm, it's not even an IP... */
    357         if( src[i] )
    358                 return src;
    359        
    360         return ( src + 7 );
    361 }
    362 #endif
    363 
    364324/* Convert from one charset to another.
    365325   
  • lib/misc.h

    rc511365 re9b755e  
    5252G_MODULE_EXPORT void http_encode( char *s );
    5353
    54 G_MODULE_EXPORT char *ipv6_wrap( char *src );
    55 G_MODULE_EXPORT char *ipv6_unwrap( char *src );
    56 
    5754G_MODULE_EXPORT signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf );
    5855
Note: See TracChangeset for help on using the changeset viewer.