diff options
| author | Jelmer Vernooij <jelmer@samba.org> | 2007-10-18 18:44:25 +0200 | 
|---|---|---|
| committer | Jelmer Vernooij <jelmer@samba.org> | 2007-10-18 18:44:25 +0200 | 
| commit | e9b755e3726fa41ac2d4ed1c3a6192d1af68edbc (patch) | |
| tree | e9940f353e77d615eed2e89479d5038c40fc3e92 | |
| parent | c511365ddc57359ab3020ccbd3f20e23b55ba5ca (diff) | |
Use standard functions for dealing with both IPv6 and IPv4. 
| -rw-r--r-- | bitlbee.c | 95 | ||||
| -rw-r--r-- | conf.c | 23 | ||||
| -rw-r--r-- | conf.h | 2 | ||||
| -rwxr-xr-x | configure | 7 | ||||
| -rw-r--r-- | irc.c | 66 | ||||
| -rw-r--r-- | lib/misc.c | 40 | ||||
| -rw-r--r-- | lib/misc.h | 3 | 
7 files changed, 61 insertions, 175 deletions
| @@ -37,72 +37,51 @@ static gboolean bitlbee_io_new_client( gpointer data, gint fd, b_input_condition  int bitlbee_daemon_init()  { -#ifdef IPV6 -	int use_ipv6 = 1; -	struct sockaddr_in6 listen_addr6; -#endif -	struct sockaddr_in listen_addr; +	struct addrinfo *res, hints, *addrinfo_bind;  	int i;  	FILE *fp;  	log_link( LOGLVL_ERROR, LOGOUTPUT_SYSLOG );  	log_link( LOGLVL_WARNING, LOGOUTPUT_SYSLOG ); -#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" ); -		return( -1 ); -	} -	 -	/* TIME_WAIT (?) sucks.. */ -	i = 1; -	setsockopt( global.listen_socket, SOL_SOCKET, SO_REUSEADDR, &i, sizeof( i ) ); -	 -#ifdef IPV6 -	memset( &listen_addr6, 0, sizeof( listen_addr6 ) ); -	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 -		memset( &listen_addr, 0, sizeof( listen_addr ) ); -		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 ) -	{ -		log_message( LOGLVL_ERROR, "Couldn't parse address `%s'", global.conf->iface ); -		return( -1 ); +	memset(&hints, 0, sizeof(hints)); +	hints.ai_family = PF_UNSPEC; +	hints.ai_socktype = SOCK_STREAM; +	hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE; + +	i = getaddrinfo(global.conf->iface, global.conf->port, &hints,  +						&addrinfo_bind); +	if (i) { +		log_message( LOGLVL_ERROR, "Couldn't parse address `%s': %s",  +					 global.conf->iface, gai_strerror(i) ); +		return -1;  	} -	 -#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" ); -		return( -1 ); + +	global.listen_socket = -1; + +	for (res = addrinfo_bind; res; res = res->ai_next) { +		global.listen_socket = socket(res->ai_family, res->ai_socktype,  +									  res->ai_protocol); +		if (global.listen_socket < 0) +			continue; + +		/* TIME_WAIT (?) sucks.. */ +		i = 1; +		setsockopt( global.listen_socket, SOL_SOCKET, SO_REUSEADDR, &i,  +					sizeof( i ) ); + +		i = bind( global.listen_socket, res->ai_addr, res->ai_addrlen); +		if( i == -1 ) +		{ +			log_error( "bind" ); +			return( -1 ); +		} + +		break;  	} -	 + +	freeaddrinfo(addrinfo_bind); +  	i = listen( global.listen_socket, 10 );  	if( i == -1 )  	{ @@ -46,12 +46,8 @@ conf_t *conf_load( int argc, char *argv[] )  	conf = g_new0( conf_t, 1 ); -#ifdef IPV6 -	conf->iface = "::"; -#else -	conf->iface = "0.0.0.0"; -#endif -	conf->port = 6667; +	conf->iface = NULL; +	conf->port = "6667";  	conf->nofork = 0;  	conf->verbose = 0;  	conf->primary_storage = "xml"; @@ -88,12 +84,8 @@ conf_t *conf_load( int argc, char *argv[] )  		}  		else if( opt == 'p' )  		{ -			if( ( sscanf( optarg, "%d", &i ) != 1 ) || ( i <= 0 ) || ( i > 65535 ) ) -			{ -				fprintf( stderr, "Invalid port number: %s\n", optarg ); -				return( NULL ); -			} -			conf->port = i; +			g_free( conf->port ); +			conf->port = g_strdup( optarg );  		}  		else if( opt == 'P' )  		{ @@ -203,12 +195,7 @@ static int conf_loadini( conf_t *conf, char *file )  			}  			else if( g_strcasecmp( ini->key, "daemonport" ) == 0 )  			{ -				if( ( sscanf( ini->value, "%d", &i ) != 1 ) || ( i <= 0 ) || ( i > 65535 ) ) -				{ -					fprintf( stderr, "Invalid port number: %s\n", ini->value ); -					return( 0 ); -				} -				conf->port = i; +				conf->port = g_strdup( ini->value );  			}  			else if( g_strcasecmp( ini->key, "authmode" ) == 0 )  			{ @@ -32,7 +32,7 @@ typedef enum authmode { AUTHMODE_OPEN, AUTHMODE_CLOSED, AUTHMODE_REGISTERED } au  typedef struct conf  {  	char *iface; -	signed int port; +	char *port;  	int nofork;  	int verbose;  	runmode_t runmode; @@ -29,7 +29,6 @@ debug=0  strip=1  gcov=0  plugins=1 -ipv6=1  events=glib  ldap=0 @@ -71,8 +70,6 @@ Option		Description				Default  --gcov=0/1	Disable/enable test coverage reporting	$gcov  --plugins=0/1	Disable/enable plugins support		$plugins ---ipv6=0/1	IPv6 socket support			$ipv6 -  --events=...	Event handler (glib, libevent)		$events  --ssl=...	SSL library to use (gnutls, nss, openssl, bogus, auto)  							$ssl @@ -134,10 +131,6 @@ cat<<EOF>config.h  #define CPU "$cpu"  EOF -if [ "$ipv6" = "1" ]; then -	echo '#define IPV6' >> config.h -fi -  if [ "$debug" = "1" ]; then  	[ -z "$CFLAGS" ] && CFLAGS=-g  	echo 'DEBUG=1' >> Makefile.settings @@ -44,14 +44,8 @@ static char *passchange( set_t *set, char *value )  irc_t *irc_new( int fd )  {  	irc_t *irc; -	struct hostent *peer; -	unsigned int i; -	char buf[128]; -#ifdef IPV6 -	struct sockaddr_in6 sock6[1]; -	unsigned int i6; -#endif -	struct sockaddr_in sock[1]; +	struct sockaddr_storage sock; +	socklen_t socklen = sizeof(sock);  	irc = g_new0( irc_t, 1 ); @@ -70,54 +64,30 @@ irc_t *irc_new( int fd )  	irc->mynick = g_strdup( ROOT_NICK );  	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*) sock6, &i6 ) == 0 && sock6->sin6_family == AF_INET6 ) -	{ -		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_INET6, &sock6->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL ) -			irc->myhost = g_strdup( ipv6_unwrap( buf ) ); -	} -#endif -	else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INET ) +	else if( getsockname( irc->fd, (struct sockaddr*) &sock, &socklen ) == 0)   	{ -		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_INET, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL ) -			irc->myhost = g_strdup( buf ); +		irc->myhost = g_new0(char, NI_MAXHOST); + +		if (getnameinfo((struct sockaddr *)&sock, socklen, irc->myhost,  +						NI_MAXHOST, NULL, -1, 0)) { +			/* Rare, but possible. */ +			strncpy(irc->myhost, "localhost.", NI_MAXHOST); +		}  	} -	i = sizeof( *sock ); -#ifdef IPV6 -	i6 = sizeof( *sock6 ); -	if( getpeername( irc->fd, (struct sockaddr*) sock6, &i6 ) == 0 && sock6->sin6_family == AF_INET6 ) +	if( getpeername( irc->fd, (struct sockaddr*) &sock, &socklen ) == 0)  	{ -		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_INET6, &sock6->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL ) -			irc->host = g_strdup( ipv6_unwrap( buf ) ); -	} -	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_INET ) ) ) -			irc->host = g_strdup( peer->h_name ); -		else if( inet_ntop( AF_INET, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL ) -			irc->host = g_strdup( buf ); +		irc->host = g_new0(char, NI_MAXHOST); + +		if (getnameinfo((struct sockaddr *)&sock, socklen, irc->host,  +						NI_MAXHOST, NULL, -1, 0)) { +			/* Rare, but possible. */ +			strncpy(irc->myhost, "localhost.", NI_MAXHOST); +		}  	} -	/* Rare, but possible. */ -	if( !irc->host ) irc->host = g_strdup( "localhost." ); -	if( !irc->myhost ) irc->myhost = g_strdup( "localhost." ); -  	if( global.conf->ping_interval > 0 && global.conf->ping_timeout > 0 )  		irc->ping_source_id = b_timeout_add( global.conf->ping_interval * 1000, irc_userping, irc ); @@ -321,46 +321,6 @@ char *strip_newlines( char *source )  	return source;  } -#ifdef IPV6 -/* Wrap an IPv4 address into IPv6 space. Not thread-safe... */ -char *ipv6_wrap( char *src ) -{ -	static char dst[64]; -	int i; -	 -	for( i = 0; src[i]; i ++ ) -		if( ( src[i] < '0' || src[i] > '9' ) && src[i] != '.' ) -			break; -	 -	/* Hmm, it's not even an IP... */ -	if( src[i] ) -		return src; -	 -	g_snprintf( dst, sizeof( dst ), "::ffff:%s", src ); -	 -	return dst; -} - -/* Unwrap an IPv4 address into IPv6 space. Thread-safe, because it's very simple. :-) */ -char *ipv6_unwrap( char *src ) -{ -	int i; -	 -	if( g_strncasecmp( src, "::ffff:", 7 ) != 0 ) -		return src; -	 -	for( i = 7; src[i]; i ++ ) -		if( ( src[i] < '0' || src[i] > '9' ) && src[i] != '.' ) -			break; -	 -	/* Hmm, it's not even an IP... */ -	if( src[i] ) -		return src; -	 -	return ( src + 7 ); -} -#endif -  /* Convert from one charset to another.     from_cs, to_cs: Source and destination charsets @@ -51,9 +51,6 @@ G_MODULE_EXPORT char *escape_html( const char *html );  G_MODULE_EXPORT void http_decode( char *s );  G_MODULE_EXPORT void http_encode( char *s ); -G_MODULE_EXPORT char *ipv6_wrap( char *src ); -G_MODULE_EXPORT char *ipv6_unwrap( char *src ); -  G_MODULE_EXPORT signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf );  G_MODULE_EXPORT void random_bytes( unsigned char *buf, int count ); | 
