X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Fconn.c;h=6042db2f3f3a9e644b5ae4f3548ea803e57edcc5;hp=95ed30889160ac07899424755cfc1ca834cf0d45;hb=f99f9a8f02390e8d49dbaad478678a0427872f5e;hpb=06bfb3adfb7ed6aef01c2fa892ea396405ee040a diff --git a/src/ngircd/conn.c b/src/ngircd/conn.c index 95ed3088..6042db2f 100644 --- a/src/ngircd/conn.c +++ b/src/ngircd/conn.c @@ -17,7 +17,7 @@ #include "portab.h" #include "io.h" -static char UNUSED id[] = "$Id: conn.c,v 1.214 2007/11/18 15:05:35 alex Exp $"; +static char UNUSED id[] = "$Id: conn.c,v 1.220 2007/12/13 01:30:16 fw Exp $"; #include "imp.h" #include @@ -41,12 +41,6 @@ static char UNUSED id[] = "$Id: conn.c,v 1.214 2007/11/18 15:05:35 alex Exp $"; # include #endif -#ifdef HAVE_ARPA_INET_H -# include -#else -# define PF_INET AF_INET -#endif - #ifdef HAVE_STDINT_H # include /* e.g. for Mac OS X */ #endif @@ -92,7 +86,7 @@ static void Check_Connections PARAMS(( void )); static void Check_Servers PARAMS(( void )); static void Init_Conn_Struct PARAMS(( CONN_ID Idx )); static bool Init_Socket PARAMS(( int Sock )); -static void New_Server PARAMS(( int Server )); +static void New_Server PARAMS(( int Server, struct in_addr *dest)); static void Simple_Message PARAMS(( int Sock, const char *Msg )); static int Count_Connections PARAMS(( struct sockaddr_in addr )); static int NewListener PARAMS(( const UINT16 Port )); @@ -333,6 +327,42 @@ Conn_ExitListeners( void ) } /* Conn_ExitListeners */ +static void +InitSinaddr(struct sockaddr_in *addr, UINT16 Port) +{ + struct in_addr inaddr; + + memset(addr, 0, sizeof(*addr)); + memset( &inaddr, 0, sizeof(inaddr)); + + addr->sin_family = AF_INET; + addr->sin_port = htons(Port); + inaddr.s_addr = htonl(INADDR_ANY); + addr->sin_addr = inaddr; +} + + +static bool +InitSinaddrListenAddr(struct sockaddr_in *addr, UINT16 Port) +{ + struct in_addr inaddr; + + InitSinaddr(addr, Port); + + if (!Conf_ListenAddress[0]) + return true; + + if (!ngt_IPStrToBin(Conf_ListenAddress, &inaddr)) { + Log( LOG_CRIT, "Can't bind to %s:%u: can't convert ip address \"%s\"", + Conf_ListenAddress, Port, Conf_ListenAddress); + return false; + } + + addr->sin_addr = inaddr; + return true; +} + + /* return new listening port file descriptor or -1 on failure */ static int NewListener( const UINT16 Port ) @@ -340,33 +370,15 @@ NewListener( const UINT16 Port ) /* Create new listening socket on specified port */ struct sockaddr_in addr; - struct in_addr inaddr; int sock; #ifdef ZEROCONF char name[CLIENT_ID_LEN], *info; #endif - /* Server-"Listen"-Socket initialisieren */ - memset( &addr, 0, sizeof( addr )); - memset( &inaddr, 0, sizeof( inaddr )); + InitSinaddrListenAddr(&addr, Port); + addr.sin_family = AF_INET; addr.sin_port = htons( Port ); - if( Conf_ListenAddress[0] ) - { -#ifdef HAVE_INET_ATON - if( inet_aton( Conf_ListenAddress, &inaddr ) == 0 ) -#else - inaddr.s_addr = inet_addr( Conf_ListenAddress ); - if( inaddr.s_addr == (unsigned)-1 ) -#endif - { - Log( LOG_CRIT, "Can't listen on %s:%u: can't convert ip address %s!", - Conf_ListenAddress, Port, Conf_ListenAddress ); - return -1; - } - } - else inaddr.s_addr = htonl( INADDR_ANY ); - addr.sin_addr = inaddr; sock = socket( PF_INET, SOCK_STREAM, 0); if( sock < 0 ) { @@ -1355,36 +1367,19 @@ Check_Servers( void ) static void -New_Server( int Server ) +New_Server( int Server , struct in_addr *dest) { /* Establish new server link */ - + struct sockaddr_in local_addr; struct sockaddr_in new_addr; - struct in_addr inaddr; int res, new_sock; CLIENT *c; assert( Server > NONE ); - Log( LOG_INFO, "Establishing connection to \"%s\", %s, port %d ... ", Conf_Server[Server].host, - Conf_Server[Server].ip, Conf_Server[Server].port ); - -#ifdef HAVE_INET_ATON - if( inet_aton( Conf_Server[Server].ip, &inaddr ) == 0 ) -#else - memset( &inaddr, 0, sizeof( inaddr )); - inaddr.s_addr = inet_addr( Conf_Server[Server].ip ); - if( inaddr.s_addr == (unsigned)-1 ) -#endif - { - Log( LOG_ERR, "Can't connect to \"%s\": can't convert ip address %s!", - Conf_Server[Server].host, Conf_Server[Server].ip ); - return; - } - - memset( &new_addr, 0, sizeof( new_addr )); + memset(&new_addr, 0, sizeof( new_addr )); new_addr.sin_family = AF_INET; - new_addr.sin_addr = inaddr; + new_addr.sin_addr = *dest; new_addr.sin_port = htons( Conf_Server[Server].port ); new_sock = socket( PF_INET, SOCK_STREAM, 0 ); @@ -1395,6 +1390,12 @@ New_Server( int Server ) if( ! Init_Socket( new_sock )) return; + /* if we fail to bind, just continue and let connect() pick a source address */ + InitSinaddr(&local_addr, 0); + local_addr.sin_addr = Conf_Server[Server].bind_addr; + if (bind(new_sock, (struct sockaddr *)&local_addr, (socklen_t)sizeof(local_addr))) + Log(LOG_WARNING, "Can't bind socket to %s: %s!", inet_ntoa(Conf_Server[Server].bind_addr), strerror( errno )); + res = connect(new_sock, (struct sockaddr *)&new_addr, (socklen_t)sizeof(new_addr)); if(( res != 0 ) && ( errno != EINPROGRESS )) { @@ -1402,7 +1403,7 @@ New_Server( int Server ) close( new_sock ); return; } - + if (!array_alloc(&My_ConnArray, sizeof(CONNECTION), (size_t)new_sock)) { Log(LOG_ALERT, "Cannot allocate memory for server connection (socket %d)", @@ -1509,6 +1510,7 @@ cb_Connect_to_Server(int fd, UNUSED short events) /* Read result of resolver sub-process from pipe and start connection */ int i; size_t len; + struct in_addr dest_addr; char readbuf[HOST_LEN + 1]; LogDebug("Resolver: Got forward lookup callback on fd %d, events %d", fd, events); @@ -1517,7 +1519,7 @@ cb_Connect_to_Server(int fd, UNUSED short events) if (Resolve_Getfd(&Conf_Server[i].res_stat) == fd ) break; } - + if( i >= MAX_SERVERS) { /* Ops, no matching server found?! */ io_close( fd ); @@ -1526,16 +1528,23 @@ cb_Connect_to_Server(int fd, UNUSED short events) } /* Read result from pipe */ - len = Resolve_Read(&Conf_Server[i].res_stat, readbuf, sizeof readbuf -1); + len = Resolve_Read(&Conf_Server[i].res_stat, readbuf, sizeof(readbuf)-1); if (len == 0) return; - + readbuf[len] = '\0'; LogDebug("Got result from resolver: \"%s\" (%u bytes read).", readbuf, len); - strlcpy( Conf_Server[i].ip, readbuf, sizeof( Conf_Server[i].ip )); + if (!ngt_IPStrToBin(readbuf, &dest_addr)) { + Log(LOG_ERR, "Can't connect to \"%s\": can't convert ip address %s!", + Conf_Server[i].host, readbuf); + return; + } + + Log( LOG_INFO, "Establishing connection to \"%s\", %s, port %d ... ", + Conf_Server[i].host, readbuf, Conf_Server[i].port ); /* connect() */ - New_Server(i); + New_Server(i, &dest_addr); } /* cb_Read_Forward_Lookup */ @@ -1602,10 +1611,10 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events ) #ifdef IDENTAUTH ++identptr; if (*identptr) { - Log( LOG_INFO, "IDENT lookup for connection %ld: \"%s\".", i, identptr); - Client_SetUser( c, identptr, true ); + Log(LOG_INFO, "IDENT lookup for connection %d: \"%s\".", i, identptr); + Client_SetUser(c, identptr, true); } else { - Log( LOG_INFO, "IDENT lookup for connection %ld: no result.", i ); + Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i); } #endif }