commit - 024588dbe72e25b49439602670be7d8164183a74
commit + 82d32ffb28262b302fb435739e4c81bd3c1a1b85
blob - 924f0595450939600f516516f97bf5b063bca401
blob + 973c68030107950717f74214077576cdcf3e57d1
--- doc/sample-ngircd.conf
+++ doc/sample-ngircd.conf
-# $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 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
blob - 457a162caba1c71918304b67262f81ca0bfb8343
blob + 3a6b7d56176af3d1d46e826afb9942b3e7e242ef
--- man/ngircd.conf.5.tmpl
+++ man/ngircd.conf.5.tmpl
.\"
-.\" $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
.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
blob - c55aaf53a775f8945706a73305d3157ed277b623
blob + 7ca5567d990158fba9a4835663831adf94081cce
--- src/ngircd/conf.c
+++ src/ngircd/conf.c
#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>
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 == ':') {
Resolve_Init(&Server->res_stat);
Server->conn_id = NONE;
+ Server->bind_addr.s_addr = htonl(INADDR_ANY);
} /* Init_Server_Struct */
blob - 371f94db64233155d2169f16093d93e5df470195
blob + 9e15226674994e8dbe56a84f1d6a3e30be96b24e
--- src/ngircd/conf.h
+++ src/ngircd/conf.h
* (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)
*/
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
blob - 95ed30889160ac07899424755cfc1ca834cf0d45
blob + 07c8078374af0512ce69211b13fb363b9646dcf5
--- src/ngircd/conn.c
+++ src/ngircd/conn.c
#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>
}
array_free(&My_Listeners);
} /* 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 )
/* 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 ) {
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;
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_sock = socket( PF_INET, SOCK_STREAM, 0 );
if ( new_sock < 0 ) {
Log( LOG_CRIT, "Can't create socket: %s!", strerror( errno ));
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 )) {
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)",
blob - 01d892fd97a903c4e21cdde716bccbad2ffef67a
blob + dc2384519cd54e6337a0fd2cdc35722a83ecb257
--- src/tool/tool.c
+++ src/tool/tool.c
#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 <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"
} /* 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- */
blob - 5b386e59c71f19f89f2319a035abee4cec9afb52
blob + bdd846f75eb9d5e82839669d5b195389cd30587f
--- src/tool/tool.h
+++ src/tool/tool.h
* (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)
*/
#ifndef __tool_h__
#define __tool_h__
+#include "portab.h"
-
GLOBAL void ngt_TrimLastChr PARAMS((char *String, const char Chr ));
GLOBAL void ngt_TrimStr PARAMS((char *String ));
GLOBAL char *ngt_LowerStr PARAMS((char *String ));
-
+GLOBAL bool ngt_IPStrToBin PARAMS((const char *ip_str, struct in_addr *inaddr));
#endif