make Listen parameter a comma-seperated list of addresses.
this also obsoletes ListenIPv4 and ListenIPv6 options. If Listen is unset, it is treated as Listen="::,0.0.0.0". Note: ListenIPv4 and ListenIPv6 options are still recognized, but ngircd will print a warning if they are used in the config file. Also, some plattforms require that ai_socktype is set in the getaddrinfo() hints structure.
This commit is contained in:
parent
818a206a42
commit
4ed2cb1a02
|
@ -40,9 +40,11 @@
|
|||
# one port, separated with ",". (Default: 6667)
|
||||
;Ports = 6667, 6668, 6669
|
||||
|
||||
# IP address on which the server should listen. (Default: empty,
|
||||
# so the server listens on all IP addresses of the system)
|
||||
;Listen = 1.2.3.4
|
||||
# comma seperated list of IP addresses on which the server should
|
||||
# listen. Default values are:
|
||||
# "0.0.0.0" or (if compiled with IPv6 support) "::,0.0.0.0"
|
||||
# so the server listens on all IP addresses of the system by default.
|
||||
;Listen = 127.0.0.1,192.168.0.1
|
||||
|
||||
# Text file with the "message of the day" (MOTD). This message will
|
||||
# be shown to all users connecting to the server:
|
||||
|
@ -103,11 +105,6 @@
|
|||
# Don't do any DNS lookups when a client connects to the server.
|
||||
;NoDNS = no
|
||||
|
||||
# allow both ipv4 and ipv6 clients to connect by opening both
|
||||
# ipv4 and ipv6 sockets
|
||||
;ListenIPv6 = yes
|
||||
;ListenIPv4 = yes
|
||||
|
||||
# try to connect to other irc servers using ipv4 and ipv6, if possible
|
||||
;ConnectIPv6 = yes
|
||||
;ConnectIPv4 = yes
|
||||
|
|
|
@ -73,8 +73,10 @@ Ports on which the server should listen. There may be more than one port,
|
|||
separated with ','. Default: 6667.
|
||||
.TP
|
||||
\fBListen\fR
|
||||
The IP address on which the server should listen. Default is empty, so
|
||||
the server listens on all configured IP addresses and interfaces.
|
||||
A comma seperated list of IP address on which the server should listen.
|
||||
If unset, the defaults value is "0.0.0.0", or, if ngircd was compiled
|
||||
with IPv6 support, "::,0.0.0.0", so the server listens on all configured
|
||||
IP addresses and interfaces by default.
|
||||
.TP
|
||||
\fBMotdFile\fR
|
||||
Text file with the "message of the day" (MOTD). This message will be shown
|
||||
|
@ -160,15 +162,6 @@ If you configure ngircd to connect to other servers, ngircd may still
|
|||
perform a DNS lookup if required.
|
||||
Default: No.
|
||||
.TP
|
||||
\fBListenIPv4\fR
|
||||
Set this to no if you do not want ngircd to accept clients using the standard internet protocol, ipv4.
|
||||
This allows use of ngircd in ipv6-only setups.
|
||||
Default: Yes.
|
||||
.TP
|
||||
\fBListenIPv6\fR
|
||||
Set this to no if you do not want ngircd to accept clients using the new internet protocol, ipv6.
|
||||
Default: Yes.
|
||||
.TP
|
||||
\fBConnectIPv4\fR
|
||||
Set this to no if you do not want ngircd to connect to other irc servers using ipv4.
|
||||
This allows use of ngircd in ipv6-only setups.
|
||||
|
|
|
@ -24,18 +24,19 @@ ng_ipaddr_init(ng_ipaddr_t *addr, const char *ip_str, UINT16 port)
|
|||
int ret;
|
||||
char portstr[64];
|
||||
struct addrinfo *res0;
|
||||
struct addrinfo hints = {
|
||||
#ifndef WANT_IPV6 /* only accept v4 addresses */
|
||||
.ai_family = AF_INET,
|
||||
#endif
|
||||
.ai_flags = AI_NUMERICHOST
|
||||
};
|
||||
struct addrinfo hints;
|
||||
|
||||
if (ip_str == NULL)
|
||||
hints.ai_flags |= AI_PASSIVE;
|
||||
assert(ip_str);
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
|
||||
/* some getaddrinfo implementations require that ai_socktype is set. */
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
/* silly, but ngircd stores UINT16 in server config, not string */
|
||||
snprintf(portstr, sizeof(portstr), "%u", (unsigned int) port);
|
||||
|
||||
ret = getaddrinfo(ip_str, portstr, &hints, &res0);
|
||||
assert(ret == 0);
|
||||
if (ret != 0)
|
||||
|
@ -49,8 +50,7 @@ ng_ipaddr_init(ng_ipaddr_t *addr, const char *ip_str, UINT16 port)
|
|||
freeaddrinfo(res0);
|
||||
return ret == 0;
|
||||
#else /* HAVE_GETADDRINFO */
|
||||
if (ip_str == NULL)
|
||||
ip_str = "0.0.0.0";
|
||||
assert(ip_str);
|
||||
addr->sin4.sin_family = AF_INET;
|
||||
# ifdef HAVE_INET_ATON
|
||||
if (inet_aton(ip_str, &addr->sin4.sin_addr) == 0)
|
||||
|
|
|
@ -84,7 +84,6 @@ ng_ipaddr_getport(const ng_ipaddr_t *a)
|
|||
* init a ng_ipaddr_t object.
|
||||
* @param addr: pointer to ng_ipaddr_t to initialize.
|
||||
* @param ip_str: ip address in dotted-decimal (ipv4) or hexadecimal (ipv6) notation
|
||||
* if ip_str is NULL it is treated as 0.0.0.0/[::]
|
||||
* @param port: transport layer port number to use.
|
||||
*/
|
||||
GLOBAL bool ng_ipaddr_init PARAMS((ng_ipaddr_t *addr, const char *ip_str, UINT16 port));
|
||||
|
|
|
@ -56,6 +56,18 @@ static CONF_SERVER New_Server;
|
|||
static int New_Server_Idx;
|
||||
|
||||
|
||||
#ifdef WANT_IPV6
|
||||
/*
|
||||
* these options appeared in ngircd 0.12; they are here
|
||||
* for backwards compatibility. They should be removed
|
||||
* in the future. Instead of setting these options,
|
||||
* the "Listen" option should be set accordingly.
|
||||
*/
|
||||
static bool Conf_ListenIPv6;
|
||||
static bool Conf_ListenIPv4;
|
||||
#endif
|
||||
|
||||
|
||||
static void Set_Defaults PARAMS(( bool InitServers ));
|
||||
static bool Read_Config PARAMS(( bool ngircd_starting ));
|
||||
static void Validate_Config PARAMS(( bool TestOnly, bool Rehash ));
|
||||
|
@ -199,8 +211,7 @@ Conf_Test( void )
|
|||
fputs(" Ports = ", stdout);
|
||||
|
||||
ports_puts(&Conf_ListenPorts);
|
||||
|
||||
printf( " Listen = %s\n", Conf_ListenAddress );
|
||||
printf(" Listen = %s\n", Conf_ListenAddress);
|
||||
pwd = getpwuid( Conf_UID );
|
||||
if( pwd ) printf( " ServerUID = %s\n", pwd->pw_name );
|
||||
else printf( " ServerUID = %ld\n", (long)Conf_UID );
|
||||
|
@ -216,8 +227,11 @@ Conf_Test( void )
|
|||
printf( " NoDNS = %s\n", yesno_to_str(Conf_NoDNS));
|
||||
|
||||
#ifdef WANT_IPV6
|
||||
printf(" ListenIPv6 = %s\n", yesno_to_str(Conf_ListenIPv6));
|
||||
printf(" ListenIPv4 = %s\n", yesno_to_str(Conf_ListenIPv4));
|
||||
/* both are deprecated, only mention them if their default value changed. */
|
||||
if (!Conf_ListenIPv6)
|
||||
puts(" ListenIPv6 = no");
|
||||
if (!Conf_ListenIPv4)
|
||||
puts(" ListenIPv4 = no");
|
||||
printf(" ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6));
|
||||
printf(" ConnectIPv6 = %s\n", yesno_to_str(Conf_ConnectIPv4));
|
||||
#endif
|
||||
|
@ -448,8 +462,8 @@ Set_Defaults( bool InitServers )
|
|||
|
||||
strlcpy( Conf_PidFile, PID_FILE, sizeof( Conf_PidFile ));
|
||||
|
||||
strcpy( Conf_ListenAddress, "" );
|
||||
|
||||
free(Conf_ListenAddress);
|
||||
Conf_ListenAddress = NULL;
|
||||
Conf_UID = Conf_GID = 0;
|
||||
|
||||
Conf_PingTimeout = 120;
|
||||
|
@ -650,6 +664,23 @@ Read_Config( bool ngircd_starting )
|
|||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
if (!Conf_ListenAddress) {
|
||||
/* no Listen addresses configured, use default */
|
||||
#ifdef WANT_IPV6
|
||||
/* Conf_ListenIPv6/4 should no longer be used */
|
||||
if (Conf_ListenIPv6 && Conf_ListenIPv4)
|
||||
Conf_ListenAddress = strdup_warn("::,0.0.0.0");
|
||||
else if (Conf_ListenIPv6)
|
||||
Conf_ListenAddress = strdup_warn("::");
|
||||
else
|
||||
#endif
|
||||
Conf_ListenAddress = strdup_warn("0.0.0.0");
|
||||
}
|
||||
if (!Conf_ListenAddress) {
|
||||
Config_Error(LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME);
|
||||
exit(1);
|
||||
}
|
||||
return true;
|
||||
} /* Read_Config */
|
||||
|
||||
|
@ -840,17 +871,25 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
|
|||
}
|
||||
#ifdef WANT_IPV6
|
||||
/* the default setting for all the WANT_IPV6 special options is 'true' */
|
||||
if( strcasecmp( Var, "ListenIPv6" ) == 0 ) {
|
||||
/* listen on ipv6 sockets, if available? */
|
||||
if (strcasecmp(Var, "ListenIPv6") == 0) { /* DEPRECATED, option appeared in 0.12.0 */
|
||||
/*
|
||||
* listen on ipv6 sockets, if available?
|
||||
* Deprecated use "Listen = 0.0.0.0" (or, rather, do not list "::")
|
||||
*/
|
||||
Conf_ListenIPv6 = Check_ArgIsTrue( Arg );
|
||||
Config_Error(LOG_WARNING, "%s, line %d: %s=%s is deprecated, %sinclude '::' in \"Listen =\" option instead",
|
||||
NGIRCd_ConfFile, Line, Var, yesno_to_str(Conf_ListenIPv6), Conf_ListenIPv6 ? " ":"do not ");
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "ListenIPv4" ) == 0 ) {
|
||||
if (strcasecmp(Var, "ListenIPv4") == 0) { /* DEPRECATED, option appeared in 0.12.0 */
|
||||
/*
|
||||
* listen on ipv4 sockets, if available?
|
||||
* this allows "ipv6-only" setups.
|
||||
* this allows "ipv6-only" setups
|
||||
* Deprecated use "Listen = ::" (or, rather, do not list "0.0.0.0")
|
||||
*/
|
||||
Conf_ListenIPv4 = Check_ArgIsTrue( Arg );
|
||||
Config_Error(LOG_WARNING, "%s, line %d: %s=%s is deprecated, %sinclude '0.0.0.0' in \"Listen =\" option instead",
|
||||
NGIRCd_ConfFile, Line, Var, yesno_to_str(Conf_ListenIPv4), Conf_ListenIPv4 ? " ":"do not ");
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "ConnectIPv6" ) == 0 ) {
|
||||
|
@ -911,14 +950,24 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
|
|||
|
||||
if( strcasecmp( Var, "Listen" ) == 0 ) {
|
||||
/* IP-Address to bind sockets */
|
||||
len = strlcpy( Conf_ListenAddress, Arg, sizeof( Conf_ListenAddress ));
|
||||
if (len >= sizeof( Conf_ListenAddress ))
|
||||
Config_Error_TooLong( Line, Var );
|
||||
if (Conf_ListenAddress) {
|
||||
Config_Error(LOG_ERR, "Multiple Listen= options, ignoring: %s", Arg);
|
||||
return;
|
||||
}
|
||||
Conf_ListenAddress = strdup_warn(Arg);
|
||||
/*
|
||||
* if allocation fails, we're in trouble:
|
||||
* we cannot ignore the error -- otherwise ngircd
|
||||
* would listen on all interfaces.
|
||||
*/
|
||||
if (!Conf_ListenAddress) {
|
||||
Config_Error(LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME);
|
||||
exit(1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!",
|
||||
NGIRCd_ConfFile, Line, Var );
|
||||
Config_Error(LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!",
|
||||
NGIRCd_ConfFile, Line, Var);
|
||||
} /* Handle_GLOBAL */
|
||||
|
||||
|
||||
|
@ -1186,16 +1235,6 @@ Validate_Config(bool Configtest, bool Rehash)
|
|||
"No administrative information configured but required by RFC!");
|
||||
}
|
||||
|
||||
#ifdef WANT_IPV6
|
||||
if (!Conf_ListenIPv4 && !Conf_ListenIPv6)
|
||||
Config_Error(LOG_ALERT,
|
||||
"Both \"ListenIPv4\" and \"ListenIPv6\" are set to 'no'; no network protocol available!");
|
||||
|
||||
if (!Conf_ConnectIPv4 && !Conf_ConnectIPv6)
|
||||
Config_Error(LOG_ALERT,
|
||||
"Both \"ConnectIPv4\" and \"ConnectIPv6\" are set to 'no'; ngircd will fail to connect to other irc servers");
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
servers = servers_once = 0;
|
||||
for (i = 0; i < MAX_SERVERS; i++) {
|
||||
|
|
|
@ -86,7 +86,7 @@ GLOBAL char Conf_MotdPhrase[LINE_LEN];
|
|||
GLOBAL array Conf_ListenPorts;
|
||||
|
||||
/* Address to which the socket should be bound or empty (=all) */
|
||||
GLOBAL char Conf_ListenAddress[16];
|
||||
GLOBAL char *Conf_ListenAddress;
|
||||
|
||||
/* User and group ID the server should run with */
|
||||
GLOBAL uid_t Conf_UID;
|
||||
|
@ -124,12 +124,6 @@ GLOBAL bool Conf_OperCanMode;
|
|||
/* Disable all DNS functions? */
|
||||
GLOBAL bool Conf_NoDNS;
|
||||
|
||||
/* listen for incoming ipv6 connections if OS supports it (default: yes)? */
|
||||
GLOBAL bool Conf_ListenIPv6;
|
||||
|
||||
/* listen for incoming ipv4 connections if OS supports it (default: yes)? */
|
||||
GLOBAL bool Conf_ListenIPv4;
|
||||
|
||||
/*
|
||||
* try to connect to remote systems using the ipv6 protocol,
|
||||
* if they have an ipv6 address? (default yes)
|
||||
|
|
|
@ -88,7 +88,7 @@ static void Init_Conn_Struct PARAMS(( CONN_ID Idx ));
|
|||
static bool Init_Socket PARAMS(( int Sock ));
|
||||
static void New_Server PARAMS(( int Server, ng_ipaddr_t *dest ));
|
||||
static void Simple_Message PARAMS(( int Sock, const char *Msg ));
|
||||
static int NewListener PARAMS(( int af, const UINT16 Port ));
|
||||
static int NewListener PARAMS(( const char *listen_addr, UINT16 Port ));
|
||||
|
||||
static array My_Listeners;
|
||||
static array My_ConnArray;
|
||||
|
@ -272,7 +272,7 @@ Conn_Exit( void )
|
|||
|
||||
|
||||
static unsigned int
|
||||
ports_initlisteners(array *a, int af, void (*func)(int,short))
|
||||
ports_initlisteners(array *a, const char *listen_addr, void (*func)(int,short))
|
||||
{
|
||||
unsigned int created = 0;
|
||||
size_t len;
|
||||
|
@ -281,15 +281,15 @@ ports_initlisteners(array *a, int af, void (*func)(int,short))
|
|||
|
||||
len = array_length(a, sizeof (UINT16));
|
||||
port = array_start(a);
|
||||
while(len--) {
|
||||
fd = NewListener(af, *port);
|
||||
while (len--) {
|
||||
fd = NewListener(listen_addr, *port);
|
||||
if (fd < 0) {
|
||||
port++;
|
||||
continue;
|
||||
}
|
||||
if (!io_event_create( fd, IO_WANTREAD, func )) {
|
||||
Log( LOG_ERR, "io_event_create(): Could not add listening fd %d (port %u): %s!",
|
||||
fd, (unsigned int) *port, strerror(errno));
|
||||
fd, (unsigned int) *port, strerror(errno));
|
||||
close(fd);
|
||||
port++;
|
||||
continue;
|
||||
|
@ -297,7 +297,6 @@ ports_initlisteners(array *a, int af, void (*func)(int,short))
|
|||
created++;
|
||||
port++;
|
||||
}
|
||||
|
||||
return created;
|
||||
}
|
||||
|
||||
|
@ -306,21 +305,39 @@ GLOBAL unsigned int
|
|||
Conn_InitListeners( void )
|
||||
{
|
||||
/* Initialize ports on which the server should accept connections */
|
||||
|
||||
unsigned int created = 0;
|
||||
char *copy, *listen_addr;
|
||||
|
||||
if (!io_library_init(CONNECTION_POOL)) {
|
||||
Log(LOG_EMERG, "Cannot initialize IO routines: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef WANT_IPV6
|
||||
if (Conf_ListenIPv6)
|
||||
created = ports_initlisteners(&Conf_ListenPorts, AF_INET6, cb_listen);
|
||||
#endif
|
||||
if (Conf_ListenIPv4)
|
||||
created += ports_initlisteners(&Conf_ListenPorts, AF_INET, cb_listen);
|
||||
assert(Conf_ListenAddress);
|
||||
|
||||
/* can't use Conf_ListenAddress directly, see below */
|
||||
copy = strdup(Conf_ListenAddress);
|
||||
if (!copy) {
|
||||
Log(LOG_CRIT, "Cannot copy %s: %s", Conf_ListenAddress, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
listen_addr = strtok(copy, ",");
|
||||
|
||||
while (listen_addr) {
|
||||
ngt_TrimStr(listen_addr);
|
||||
if (*listen_addr)
|
||||
created += ports_initlisteners(&Conf_ListenPorts, listen_addr, cb_listen);
|
||||
|
||||
listen_addr = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
/*
|
||||
* can't free() Conf_ListenAddress here. On /REHASH, if the config file
|
||||
* cannot be re-loaded, we'd end up with a NULL Conf_ListenAddress.
|
||||
* Instead, free() takes place in conf.c, before the config file
|
||||
* is being parsed.
|
||||
*/
|
||||
free(copy);
|
||||
return created;
|
||||
} /* Conn_InitListeners */
|
||||
|
||||
|
@ -350,25 +367,15 @@ Conn_ExitListeners( void )
|
|||
|
||||
|
||||
static bool
|
||||
InitSinaddrListenAddr(int af, ng_ipaddr_t *addr, UINT16 Port)
|
||||
InitSinaddrListenAddr(ng_ipaddr_t *addr, const char *listen_addrstr, UINT16 Port)
|
||||
{
|
||||
bool ret;
|
||||
const char *listen_addrstr = NULL;
|
||||
#ifdef WANT_IPV6
|
||||
if (af == AF_INET)
|
||||
listen_addrstr = "0.0.0.0";
|
||||
#else
|
||||
(void)af;
|
||||
#endif
|
||||
if (Conf_ListenAddress[0]) /* overrides V4/V6 atm */
|
||||
listen_addrstr = Conf_ListenAddress;
|
||||
|
||||
ret = ng_ipaddr_init(addr, listen_addrstr, Port);
|
||||
if (!ret) {
|
||||
if (!listen_addrstr)
|
||||
listen_addrstr = "";
|
||||
Log(LOG_CRIT, "Can't bind to %s:%u: can't convert ip address \"%s\"",
|
||||
listen_addrstr, Port, listen_addrstr);
|
||||
assert(listen_addrstr);
|
||||
Log(LOG_CRIT, "Can't bind to [%s]:%u: can't convert ip address \"%s\"",
|
||||
listen_addrstr, Port, listen_addrstr);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -394,24 +401,23 @@ set_v6_only(int af, int sock)
|
|||
|
||||
/* return new listening port file descriptor or -1 on failure */
|
||||
static int
|
||||
NewListener(int af, const UINT16 Port)
|
||||
NewListener(const char *listen_addr, UINT16 Port)
|
||||
{
|
||||
/* Create new listening socket on specified port */
|
||||
ng_ipaddr_t addr;
|
||||
int sock;
|
||||
int sock, af;
|
||||
#ifdef ZEROCONF
|
||||
char name[CLIENT_ID_LEN], *info;
|
||||
#endif
|
||||
if (!InitSinaddrListenAddr(af, &addr, Port))
|
||||
if (!InitSinaddrListenAddr(&addr, listen_addr, Port))
|
||||
return -1;
|
||||
|
||||
sock = socket(ng_ipaddr_af(&addr), SOCK_STREAM, 0);
|
||||
if( sock < 0 ) {
|
||||
Log( LOG_CRIT, "Can't create socket: %s!", strerror( errno ));
|
||||
return -1;
|
||||
}
|
||||
|
||||
af = ng_ipaddr_af(&addr);
|
||||
sock = socket(af, SOCK_STREAM, 0);
|
||||
if( sock < 0 ) {
|
||||
Log(LOG_CRIT, "Can't create socket (af %d) : %s!", af, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
set_v6_only(af, sock);
|
||||
|
||||
|
@ -438,12 +444,7 @@ NewListener(int af, const UINT16 Port)
|
|||
return -1;
|
||||
}
|
||||
|
||||
#ifdef WANT_IPV6
|
||||
if (af == AF_INET6)
|
||||
Log(LOG_INFO, "Now listening on [%s]:%d (socket %d).", ng_ipaddr_tostr(&addr), Port, sock);
|
||||
else
|
||||
#endif
|
||||
Log(LOG_INFO, "Now listening on %s:%d (socket %d).", ng_ipaddr_tostr(&addr), Port, sock);
|
||||
Log(LOG_INFO, "Now listening on [%s]:%d (socket %d).", ng_ipaddr_tostr(&addr), Port, sock);
|
||||
|
||||
#ifdef ZEROCONF
|
||||
/* Get best server description text */
|
||||
|
@ -1461,7 +1462,7 @@ New_Server( int Server , ng_ipaddr_t *dest)
|
|||
af_dest = ng_ipaddr_af(dest);
|
||||
new_sock = socket(af_dest, SOCK_STREAM, 0);
|
||||
if (new_sock < 0) {
|
||||
Log( LOG_CRIT, "Can't create socket: %s!", strerror( errno ));
|
||||
Log( LOG_CRIT, "Can't create socket (af %d) : %s!", af_dest, strerror( errno ));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue