From b0a33a50735d93e1414a2e6c2007884d756429a3 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Tue, 11 Jul 2006 11:28:44 +0200 Subject: Better handling of situations where IPv6 is not available at run-time. --- bitlbee.c | 46 ++++++++++++++++++++++++++++++++++------------ irc.c | 41 ++++++++++++++++++++++------------------- sock.h | 7 ------- 3 files changed, 56 insertions(+), 38 deletions(-) diff --git a/bitlbee.c b/bitlbee.c index 1d4e2b34..f3cc3d4a 100644 --- a/bitlbee.c +++ b/bitlbee.c @@ -35,20 +35,31 @@ static gboolean bitlbee_io_new_client( gpointer data, gint fd, b_input_condition condition ); +#undef AF_INET6 +#define AF_INET6 666 + int bitlbee_daemon_init() { #ifdef IPV6 - struct sockaddr_in6 listen_addr; -#else - struct sockaddr_in listen_addr; + int use_ipv6 = 1; + struct sockaddr_in6 listen_addr6; #endif + struct sockaddr_in listen_addr; int i; FILE *fp; log_link( LOGLVL_ERROR, LOGOUTPUT_SYSLOG ); log_link( LOGLVL_WARNING, LOGOUTPUT_SYSLOG ); - global.listen_socket = socket( AF_INETx, SOCK_STREAM, 0 ); +#ifdef IPV6 + if( ( global.listen_socket = socket( AF_INET6, SOCK_STREAM, 0 ) ) == -1 ) + { + use_ipv6 = 0; +#endif + global.listen_socket = socket( AF_INET, SOCK_STREAM, 0 ); +#ifdef IPV6 + } +#endif if( global.listen_socket == -1 ) { log_error( "socket" ); @@ -60,13 +71,21 @@ int bitlbee_daemon_init() setsockopt( global.listen_socket, SOL_SOCKET, SO_REUSEADDR, &i, sizeof( i ) ); #ifdef IPV6 - listen_addr.sin6_family = AF_INETx; - listen_addr.sin6_port = htons( global.conf->port ); - i = inet_pton( AF_INETx, ipv6_wrap( global.conf->iface ), &listen_addr.sin6_addr ); -#else - listen_addr.sin_family = AF_INETx; - listen_addr.sin_port = htons( global.conf->port ); - i = inet_pton( AF_INETx, global.conf->iface, &listen_addr.sin_addr ); + listen_addr6.sin6_family = AF_INET6; + listen_addr6.sin6_port = htons( global.conf->port ); + if( ( i = inet_pton( AF_INET6, ipv6_wrap( global.conf->iface ), &listen_addr6.sin6_addr ) ) != 1 ) + { + /* Forget about IPv6 in this function. */ + use_ipv6 = 0; +#endif + listen_addr.sin_family = AF_INET; + listen_addr.sin_port = htons( global.conf->port ); + if( strcmp( global.conf->iface, "::" ) == 0 ) + i = inet_pton( AF_INET, "0.0.0.0", &listen_addr.sin_addr ); + else + i = inet_pton( AF_INET, global.conf->iface, &listen_addr.sin_addr ); +#ifdef IPV6 + } #endif if( i != 1 ) @@ -75,7 +94,10 @@ int bitlbee_daemon_init() return( -1 ); } - i = bind( global.listen_socket, (struct sockaddr *) &listen_addr, sizeof( listen_addr ) ); +#ifdef IPV6 + if( !use_ipv6 || ( i = bind( global.listen_socket, (struct sockaddr *) &listen_addr6, sizeof( listen_addr6 ) ) ) == -1 ) +#endif + i = bind( global.listen_socket, (struct sockaddr *) &listen_addr, sizeof( listen_addr ) ); if( i == -1 ) { log_error( "bind" ); diff --git a/irc.c b/irc.c index 1a7579b8..53ca7c4c 100644 --- a/irc.c +++ b/irc.c @@ -45,10 +45,10 @@ irc_t *irc_new( int fd ) unsigned int i; char buf[128]; #ifdef IPV6 - struct sockaddr_in6 sock[1]; -#else - struct sockaddr_in sock[1]; + struct sockaddr_in6 sock6[1]; + unsigned int i6; #endif + struct sockaddr_in sock[1]; irc = g_new0( irc_t, 1 ); @@ -68,45 +68,48 @@ irc_t *irc_new( int fd ) irc->channel = g_strdup( ROOT_CHAN ); i = sizeof( *sock ); +#ifdef IPV6 + i6 = sizeof( *sock6 ); +#endif if( global.conf->hostname ) irc->myhost = g_strdup( global.conf->hostname ); #ifdef IPV6 - else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin6_family == AF_INETx ) + else if( getsockname( irc->fd, (struct sockaddr*) sock6, &i6 ) == 0 && sock6->sin6_family == AF_INET6 ) { - if( ( peer = gethostbyaddr( (char*) &sock->sin6_addr, sizeof( sock->sin6_addr ), AF_INETx ) ) ) + if( ( peer = gethostbyaddr( (char*) &sock6->sin6_addr, sizeof( sock6->sin6_addr ), AF_INET6 ) ) ) irc->myhost = g_strdup( peer->h_name ); - else if( inet_ntop( AF_INETx, &sock->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL ) + else if( inet_ntop( AF_INET6, &sock6->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL ) irc->myhost = g_strdup( ipv6_unwrap( buf ) ); } -#else - else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INETx ) +#endif + else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INET ) { - if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INETx ) ) ) + if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INET ) ) ) irc->myhost = g_strdup( peer->h_name ); - else if( inet_ntop( AF_INETx, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL ) + else if( inet_ntop( AF_INET, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL ) irc->myhost = g_strdup( buf ); } -#endif i = sizeof( *sock ); #ifdef IPV6 - if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin6_family == AF_INETx ) + i6 = sizeof( *sock6 ); + if( getpeername( irc->fd, (struct sockaddr*) sock6, &i6 ) == 0 && sock6->sin6_family == AF_INET6 ) { - if( ( peer = gethostbyaddr( (char*) &sock->sin6_addr, sizeof( sock->sin6_addr ), AF_INETx ) ) ) + if( ( peer = gethostbyaddr( (char*) &sock6->sin6_addr, sizeof( sock6->sin6_addr ), AF_INET6 ) ) ) irc->host = g_strdup( peer->h_name ); - else if( inet_ntop( AF_INETx, &sock->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL ) + else if( inet_ntop( AF_INET6, &sock6->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL ) irc->host = g_strdup( ipv6_unwrap( buf ) ); } -#else - if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INETx ) + else +#endif + if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INET ) { - if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INETx ) ) ) + if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INET ) ) ) irc->host = g_strdup( peer->h_name ); - else if( inet_ntop( AF_INETx, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL ) + else if( inet_ntop( AF_INET, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL ) irc->host = g_strdup( buf ); } -#endif /* Rare, but possible. */ if( !irc->host ) irc->host = g_strdup( "localhost." ); diff --git a/sock.h b/sock.h index ff7034a6..c3c0428e 100644 --- a/sock.h +++ b/sock.h @@ -1,13 +1,6 @@ #include #include -/* To cut down on the ifdef stuff a little bit in other places */ -#ifdef IPV6 -#define AF_INETx AF_INET6 -#else -#define AF_INETx AF_INET -#endif - #ifndef _WIN32 #include #include -- cgit v1.2.3