]> arthur.barton.de Git - ngircd-alex.git/commitdiff
bind ListenAddress for outgoing connections
authorFlorian Westphal <fw@strlen.de>
Fri, 23 Nov 2007 16:26:03 +0000 (16:26 +0000)
committerFlorian Westphal <fw@strlen.de>
Fri, 23 Nov 2007 16:26:03 +0000 (16:26 +0000)
ngircd would always use INADDR_ANY for outgoing connections;
which might not be desirable. Added new [Server] option
"Bind" to set source ip.

doc/sample-ngircd.conf
man/ngircd.conf.5.tmpl
src/ngircd/conf.c
src/ngircd/conf.h
src/ngircd/conn.c
src/tool/tool.c
src/tool/tool.h

index 924f0595450939600f516516f97bf5b063bca401..973c68030107950717f74214077576cdcf3e57d1 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: sample-ngircd.conf,v 1.42 2007/11/21 12:16:35 alex Exp $
+# $Id: sample-ngircd.conf,v 1.43 2007/11/23 16:26:03 fw Exp $
 
 #
 # This is a sample configuration file for the ngIRCd, which must be adepted
 
 #
 # This is a sample configuration file for the ngIRCd, which must be adepted
        # this server should establish the connection).
        ;Host = connect-to-host.the.net
 
        # this server should establish the connection).
        ;Host = connect-to-host.the.net
 
+       # IP address to use as _source_ address for the connection. if unspecified,
+       # ngircd will let the operating system pick an address.
+       ;Bind = 10.0.0.1
+
        # Port of the server to which the ngIRCd should connect. If you
        # assign no port the ngIRCd waits for incoming connections.
        ;Port = 6667
        # Port of the server to which the ngIRCd should connect. If you
        # assign no port the ngIRCd waits for incoming connections.
        ;Port = 6667
index 457a162caba1c71918304b67262f81ca0bfb8343..3a6b7d56176af3d1d46e826afb9942b3e7e242ef 100644 (file)
@@ -1,5 +1,5 @@
 .\"
 .\"
-.\" $Id: ngircd.conf.5.tmpl,v 1.6 2007/11/21 12:16:36 alex Exp $
+.\" $Id: ngircd.conf.5.tmpl,v 1.7 2007/11/23 16:26:03 fw Exp $
 .\"
 .TH ngircd.conf 5 "August 2005" ngircd "ngIRCd Manual"
 .SH NAME
 .\"
 .TH ngircd.conf 5 "August 2005" ngircd "ngIRCd Manual"
 .SH NAME
@@ -212,6 +212,10 @@ IRC name of the server
 \fBHost\fR
 Internet host name of the peer
 .TP
 \fBHost\fR
 Internet host name of the peer
 .TP
+\fBBind\fR
+IP address to use as source IP for the outgoing connection. Default ist
+to let the operating system decide.
+.TP
 \fBPort\fR
 Port of the server to which the ngIRCd should connect. If you assign no port
 the ngIRCd waits for incoming connections.
 \fBPort\fR
 Port of the server to which the ngIRCd should connect. If you assign no port
 the ngIRCd waits for incoming connections.
index c55aaf53a775f8945706a73305d3157ed277b623..7ca5567d990158fba9a4835663831adf94081cce 100644 (file)
@@ -14,7 +14,7 @@
 
 #include "portab.h"
 
 
 #include "portab.h"
 
-static char UNUSED id[] = "$Id: conf.c,v 1.102 2007/11/21 12:16:36 alex Exp $";
+static char UNUSED id[] = "$Id: conf.c,v 1.103 2007/11/23 16:26:04 fw Exp $";
 
 #include "imp.h"
 #include <assert.h>
 
 #include "imp.h"
 #include <assert.h>
@@ -937,6 +937,14 @@ Handle_SERVER( int Line, char *Var, char *Arg )
                        Config_Error_TooLong( Line, Var );
                return;
        }
                        Config_Error_TooLong( Line, Var );
                return;
        }
+       if (strcasecmp(Var, "Bind") == 0) {
+               if (ngt_IPStrToBin(Arg, &New_Server.bind_addr))
+                       return;
+
+               Config_Error(LOG_ERR, "%s, line %d (section \"Server\"): Can't parse IP address \"%s\"",
+                               NGIRCd_ConfFile, Line, Arg);
+               return;
+       }
        if( strcasecmp( Var, "MyPassword" ) == 0 ) {
                /* Password of this server which is sent to the peer */
                if (*Arg == ':') {
        if( strcasecmp( Var, "MyPassword" ) == 0 ) {
                /* Password of this server which is sent to the peer */
                if (*Arg == ':') {
@@ -1205,6 +1213,7 @@ Init_Server_Struct( CONF_SERVER *Server )
 
        Resolve_Init(&Server->res_stat);
        Server->conn_id = NONE;
 
        Resolve_Init(&Server->res_stat);
        Server->conn_id = NONE;
+       Server->bind_addr.s_addr = htonl(INADDR_ANY);
 } /* Init_Server_Struct */
 
 
 } /* Init_Server_Struct */
 
 
index 371f94db64233155d2169f16093d93e5df470195..9e15226674994e8dbe56a84f1d6a3e30be96b24e 100644 (file)
@@ -8,7 +8,7 @@
  * (at your option) any later version.
  * Please read the file COPYING, README and AUTHORS for more information.
  *
  * (at your option) any later version.
  * Please read the file COPYING, README and AUTHORS for more information.
  *
- * $Id: conf.h,v 1.45 2007/11/21 12:16:36 alex Exp $
+ * $Id: conf.h,v 1.46 2007/11/23 16:26:04 fw Exp $
  *
  * Configuration management (header)
  */
  *
  * Configuration management (header)
  */
@@ -43,6 +43,7 @@ typedef struct _Conf_Server
        RES_STAT res_stat;              /* Status of the resolver */
        int flags;                      /* Flags */
        CONN_ID conn_id;                /* ID of server connection or NONE */
        RES_STAT res_stat;              /* Status of the resolver */
        int flags;                      /* Flags */
        CONN_ID conn_id;                /* ID of server connection or NONE */
+       struct in_addr bind_addr;       /* source address to use for outgoing connections */
 } CONF_SERVER;
 
 typedef struct _Conf_Channel
 } CONF_SERVER;
 
 typedef struct _Conf_Channel
index 95ed30889160ac07899424755cfc1ca834cf0d45..07c8078374af0512ce69211b13fb363b9646dcf5 100644 (file)
@@ -17,7 +17,7 @@
 #include "portab.h"
 #include "io.h"
 
 #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.215 2007/11/23 16:26:04 fw Exp $";
 
 #include "imp.h"
 #include <assert.h>
 
 #include "imp.h"
 #include <assert.h>
@@ -333,6 +333,42 @@ Conn_ExitListeners( void )
 } /* Conn_ExitListeners */
 
 
 } /* 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 )
 /* return new listening port file descriptor or -1 on failure */
 static int
 NewListener( const UINT16 Port )
@@ -340,33 +376,15 @@ NewListener( const UINT16 Port )
        /* Create new listening socket on specified port */
 
        struct sockaddr_in addr;
        /* 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
 
        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 );
        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 ) {
 
        sock = socket( PF_INET, SOCK_STREAM, 0);
        if( sock < 0 ) {
@@ -1358,7 +1376,7 @@ static void
 New_Server( int Server )
 {
        /* Establish new server link */
 New_Server( int Server )
 {
        /* Establish new server link */
-
+       struct sockaddr_in local_addr;
        struct sockaddr_in new_addr;
        struct in_addr inaddr;
        int res, new_sock;
        struct sockaddr_in new_addr;
        struct in_addr inaddr;
        int res, new_sock;
@@ -1382,11 +1400,12 @@ New_Server( int Server )
                return;
        }
 
                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_port = htons( Conf_Server[Server].port );
 
        new_addr.sin_family = AF_INET;
        new_addr.sin_addr = inaddr;
        new_addr.sin_port = htons( Conf_Server[Server].port );
 
+
        new_sock = socket( PF_INET, SOCK_STREAM, 0 );
        if ( new_sock < 0 ) {
                Log( LOG_CRIT, "Can't create socket: %s!", strerror( errno ));
        new_sock = socket( PF_INET, SOCK_STREAM, 0 );
        if ( new_sock < 0 ) {
                Log( LOG_CRIT, "Can't create socket: %s!", strerror( errno ));
@@ -1395,6 +1414,12 @@ New_Server( int Server )
 
        if( ! Init_Socket( new_sock )) return;
 
 
        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!", Conf_ListenAddress, strerror( errno ));
+
        res = connect(new_sock, (struct sockaddr *)&new_addr,
                        (socklen_t)sizeof(new_addr));
        if(( res != 0 ) && ( errno != EINPROGRESS )) {
        res = connect(new_sock, (struct sockaddr *)&new_addr,
                        (socklen_t)sizeof(new_addr));
        if(( res != 0 ) && ( errno != EINPROGRESS )) {
@@ -1402,7 +1427,7 @@ New_Server( int Server )
                close( new_sock );
                return;
        }
                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)",
        if (!array_alloc(&My_ConnArray, sizeof(CONNECTION), (size_t)new_sock)) {
                Log(LOG_ALERT,
                    "Cannot allocate memory for server connection (socket %d)",
index 01d892fd97a903c4e21cdde716bccbad2ffef67a..dc2384519cd54e6337a0fd2cdc35722a83ecb257 100644 (file)
@@ -14,7 +14,7 @@
 
 #include "portab.h"
 
 
 #include "portab.h"
 
-static char UNUSED id[] = "$Id: tool.c,v 1.6 2006/04/09 12:53:07 alex Exp $";
+static char UNUSED id[] = "$Id: tool.c,v 1.7 2007/11/23 16:26:05 fw Exp $";
 
 #include "imp.h"
 #include <assert.h>
 
 #include "imp.h"
 #include <assert.h>
@@ -22,6 +22,11 @@ static char UNUSED id[] = "$Id: tool.c,v 1.6 2006/04/09 12:53:07 alex Exp $";
 #include <stdio.h>
 #include <string.h>
 
 #include <stdio.h>
 #include <string.h>
 
+#include <netinet/in.h>
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
 #include "exp.h"
 #include "tool.h"
 
 #include "exp.h"
 #include "tool.h"
 
@@ -105,4 +110,22 @@ ngt_TrimLastChr( char *String, const char Chr)
 } /* ngt_TrimLastChr */
 
 
 } /* ngt_TrimLastChr */
 
 
+GLOBAL bool
+ngt_IPStrToBin(const char *ip_str, struct in_addr *inaddr)
+{
+       /* AF is always AF_INET for now */
+#ifdef HAVE_INET_ATON
+       if (inet_aton(ip_str, inaddr) == 0)
+               return false;
+#else
+       inaddr->s_addr = inet_addr(ip_str);
+       if (inaddr->s_addr == (unsigned)-1)
+               return false;
+#endif
+       return true;
+}
+
+
+
+
 /* -eof- */
 /* -eof- */
index 5b386e59c71f19f89f2319a035abee4cec9afb52..bdd846f75eb9d5e82839669d5b195389cd30587f 100644 (file)
@@ -8,7 +8,7 @@
  * (at your option) any later version.
  * Please read the file COPYING, README and AUTHORS for more information.
  *
  * (at your option) any later version.
  * Please read the file COPYING, README and AUTHORS for more information.
  *
- * $Id: tool.h,v 1.3 2005/03/19 18:43:53 fw Exp $
+ * $Id: tool.h,v 1.4 2007/11/23 16:26:05 fw Exp $
  *
  * Tool functions (Header)
  */
  *
  * Tool functions (Header)
  */
@@ -16,7 +16,7 @@
 
 #ifndef __tool_h__
 #define __tool_h__
 
 #ifndef __tool_h__
 #define __tool_h__
-
+#include "portab.h"
 
 GLOBAL void ngt_TrimLastChr PARAMS((char *String, const char Chr ));
 
 
 GLOBAL void ngt_TrimLastChr PARAMS((char *String, const char Chr ));
 
@@ -24,7 +24,7 @@ GLOBAL void ngt_TrimStr PARAMS((char *String ));
 
 GLOBAL char *ngt_LowerStr PARAMS((char *String ));
 
 
 GLOBAL char *ngt_LowerStr PARAMS((char *String ));
 
-
+GLOBAL bool ngt_IPStrToBin PARAMS((const char *ip_str, struct in_addr *inaddr));
 #endif
 
 
 #endif