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.
# one port, separated with ",". (Default: 6667)
;Ports = 6667, 6668, 6669
# 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:
# Text file with the "message of the day" (MOTD). This message will
# be shown to all users connecting to the server:
# Don't do any DNS lookups when a client connects to the server.
;NoDNS = no
# 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
# try to connect to other irc servers using ipv4 and ipv6, if possible
;ConnectIPv6 = yes
;ConnectIPv4 = yes
separated with ','. Default: 6667.
.TP
\fBListen\fR
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
.TP
\fBMotdFile\fR
Text file with the "message of the day" (MOTD). This message will be shown
perform a DNS lookup if required.
Default: No.
.TP
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.
\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.
int ret;
char portstr[64];
struct addrinfo *res0;
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;
+
+ assert(ip_str);
- if (ip_str == NULL)
- hints.ai_flags |= AI_PASSIVE;
+ 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);
/* 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)
ret = getaddrinfo(ip_str, portstr, &hints, &res0);
assert(ret == 0);
if (ret != 0)
freeaddrinfo(res0);
return ret == 0;
#else /* HAVE_GETADDRINFO */
freeaddrinfo(res0);
return ret == 0;
#else /* HAVE_GETADDRINFO */
- if (ip_str == NULL)
- ip_str = "0.0.0.0";
addr->sin4.sin_family = AF_INET;
# ifdef HAVE_INET_ATON
if (inet_aton(ip_str, &addr->sin4.sin_addr) == 0)
addr->sin4.sin_family = AF_INET;
# ifdef HAVE_INET_ATON
if (inet_aton(ip_str, &addr->sin4.sin_addr) == 0)
* 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
* 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));
* @param port: transport layer port number to use.
*/
GLOBAL bool ng_ipaddr_init PARAMS((ng_ipaddr_t *addr, const char *ip_str, UINT16 port));
static int New_Server_Idx;
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 ));
static void Set_Defaults PARAMS(( bool InitServers ));
static bool Read_Config PARAMS(( bool ngircd_starting ));
static void Validate_Config PARAMS(( bool TestOnly, bool Rehash ));
fputs(" Ports = ", stdout);
ports_puts(&Conf_ListenPorts);
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 );
pwd = getpwuid( Conf_UID );
if( pwd ) printf( " ServerUID = %s\n", pwd->pw_name );
else printf( " ServerUID = %ld\n", (long)Conf_UID );
printf( " NoDNS = %s\n", yesno_to_str(Conf_NoDNS));
#ifdef WANT_IPV6
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
printf(" ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6));
printf(" ConnectIPv6 = %s\n", yesno_to_str(Conf_ConnectIPv4));
#endif
strlcpy( Conf_PidFile, PID_FILE, sizeof( Conf_PidFile ));
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;
Conf_UID = Conf_GID = 0;
Conf_PingTimeout = 120;
+
+ 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 */
return true;
} /* Read_Config */
}
#ifdef WANT_IPV6
/* the default setting for all the WANT_IPV6 special options is 'true' */
}
#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 );
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 ");
- if( strcasecmp( Var, "ListenIPv4" ) == 0 ) {
+ if (strcasecmp(Var, "ListenIPv4") == 0) { /* DEPRECATED, option appeared in 0.12.0 */
/*
* listen on ipv4 sockets, if available?
/*
* 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 );
*/
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 ) {
return;
}
if( strcasecmp( Var, "ConnectIPv6" ) == 0 ) {
if( strcasecmp( Var, "Listen" ) == 0 ) {
/* IP-Address to bind sockets */
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);
+ }
-
- 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);
"No administrative information configured but required by RFC!");
}
"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++) {
#ifdef DEBUG
servers = servers_once = 0;
for (i = 0; i < MAX_SERVERS; i++) {
GLOBAL array Conf_ListenPorts;
/* Address to which the socket should be bound or empty (=all) */
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;
/* User and group ID the server should run with */
GLOBAL uid_t Conf_UID;
/* Disable all DNS functions? */
GLOBAL bool Conf_NoDNS;
/* 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)
/*
* try to connect to remote systems using the ipv6 protocol,
* if they have an ipv6 address? (default yes)
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 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;
static array My_Listeners;
static array My_ConnArray;
-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;
{
unsigned int created = 0;
size_t len;
len = array_length(a, sizeof (UINT16));
port = array_start(a);
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!",
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;
close(fd);
port++;
continue;
Conn_InitListeners( void )
{
/* Initialize ports on which the server should accept connections */
Conn_InitListeners( void )
{
/* Initialize ports on which the server should accept connections */
unsigned int created = 0;
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;
}
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 */
return created;
} /* Conn_InitListeners */
-InitSinaddrListenAddr(int af, ng_ipaddr_t *addr, UINT16 Port)
+InitSinaddrListenAddr(ng_ipaddr_t *addr, const char *listen_addrstr, UINT16 Port)
- 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) {
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 new listening port file descriptor or -1 on failure */
static int
/* 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;
{
/* Create new listening socket on specified port */
ng_ipaddr_t addr;
#ifdef ZEROCONF
char name[CLIENT_ID_LEN], *info;
#endif
#ifdef ZEROCONF
char name[CLIENT_ID_LEN], *info;
#endif
- if (!InitSinaddrListenAddr(af, &addr, Port))
+ if (!InitSinaddrListenAddr(&addr, listen_addr, Port))
- sock = socket(ng_ipaddr_af(&addr), SOCK_STREAM, 0);
+ af = ng_ipaddr_af(&addr);
+ sock = socket(af, SOCK_STREAM, 0);
- Log( LOG_CRIT, "Can't create socket: %s!", strerror( errno ));
+ Log(LOG_CRIT, "Can't create socket (af %d) : %s!", af, strerror(errno));
- af = ng_ipaddr_af(&addr);
-
set_v6_only(af, sock);
if (!Init_Socket(sock))
set_v6_only(af, sock);
if (!Init_Socket(sock))
-#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 */
#ifdef ZEROCONF
/* Get best server description text */
af_dest = ng_ipaddr_af(dest);
new_sock = socket(af_dest, SOCK_STREAM, 0);
if (new_sock < 0) {
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 ));