]> arthur.barton.de Git - ngircd-alex.git/commitdiff
make Listen parameter a comma-seperated list of addresses.
authorFlorian Westphal <fw@strlen.de>
Sun, 18 May 2008 22:12:41 +0000 (00:12 +0200)
committerFlorian Westphal <fw@strlen.de>
Mon, 19 May 2008 12:27:35 +0000 (14:27 +0200)
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.

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

index 9f107a83f42e524da59a604d5879509d069a3e9f..87a94d9df8be365b4de8d2597cf06ed4d316800b 100644 (file)
        # 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
index cff474965d7a33c4e48e0a13fb51caa8623a74c3..7c9ce3163e4f8b0b69b0cca9cecd66bf993199f7 100644 (file)
@@ -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
 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
@@ -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
 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.
index 3b0595d79719b92b13edfd0f4a5422311f1ff550..b412cc83af6e2789b03b2e34f7b74b4c962f8f1c 100644 (file)
@@ -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;
        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)
@@ -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 */
        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)
        addr->sin4.sin_family = AF_INET;
 # ifdef HAVE_INET_ATON
        if (inet_aton(ip_str, &addr->sin4.sin_addr) == 0)
index 7894af25fbebefdb22f24adac1afe9a9dcb639b6..6490a0747a9ac0f62ff4608c8d7cbaea9e8023a5 100644 (file)
@@ -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
  * 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));
index c5a621fee65d9a7f8f484c592f45ab58a4599f78..554fee4a92d12e973c8b1f94864c8360e1dff6cf 100644 (file)
@@ -56,6 +56,18 @@ static CONF_SERVER New_Server;
 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 ));
@@ -199,8 +211,7 @@ Conf_Test( void )
        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 );
@@ -216,8 +227,11 @@ Conf_Test( void )
        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
@@ -448,8 +462,8 @@ Set_Defaults( bool InitServers )
 
        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;
@@ -650,6 +664,23 @@ Read_Config( bool ngircd_starting )
                        exit( 1 );
                }
        }
                        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 */
 
        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' */
        }
 #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 ");
                return;
        }
                return;
        }
-       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 ) {
@@ -911,14 +950,24 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
 
        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);
+               }
                return;
        }
                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 */
 
 
 } /* Handle_GLOBAL */
 
 
@@ -1186,16 +1235,6 @@ Validate_Config(bool Configtest, bool Rehash)
                             "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++) {
index 3bc206605e208d40b78cd02c1cab05fcb9eeb8cb..6ec5bce909010e47075b672542bb398bf071ddd8 100644 (file)
@@ -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 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;
@@ -124,12 +124,6 @@ GLOBAL bool Conf_OperCanMode;
 /* 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)
index 4772fd34628b660f8f517fcb1edc30515b0c283e..7c4c8d23782cc995fc11c41baeee9041e0ae1416 100644 (file)
@@ -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 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;
@@ -272,7 +272,7 @@ Conn_Exit( void )
 
 
 static unsigned int
 
 
 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;
 {
        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);
 
        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;
@@ -297,7 +297,6 @@ ports_initlisteners(array *a, int af, void (*func)(int,short))
                created++;
                port++;
        }
                created++;
                port++;
        }
-
        return created;
 }
 
        return created;
 }
 
@@ -306,21 +305,39 @@ GLOBAL unsigned int
 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 */
 
@@ -350,25 +367,15 @@ Conn_ExitListeners( void )
 
 
 static bool
 
 
 static bool
-InitSinaddrListenAddr(int af, ng_ipaddr_t *addr, UINT16 Port)
+InitSinaddrListenAddr(ng_ipaddr_t *addr, const char *listen_addrstr, UINT16 Port)
 {
        bool ret;
 {
        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) {
 
        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;
 }
        }
        return ret;
 }
@@ -394,25 +401,24 @@ set_v6_only(int af, int sock)
 
 /* 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;
-       int sock;
+       int sock, af;
 #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))
                return -1;
 
                return -1;
 
-       sock = socket(ng_ipaddr_af(&addr), SOCK_STREAM, 0);
+       af = ng_ipaddr_af(&addr);
+       sock = socket(af, SOCK_STREAM, 0);
        if( sock < 0 ) {
        if( sock < 0 ) {
-               Log( LOG_CRIT, "Can't create socket: %s!", strerror( errno ));
+               Log(LOG_CRIT, "Can't create socket (af %d) : %s!", af, strerror(errno));
                return -1;
        }
 
                return -1;
        }
 
-       af = ng_ipaddr_af(&addr);
-
        set_v6_only(af, sock);
 
        if (!Init_Socket(sock))
        set_v6_only(af, sock);
 
        if (!Init_Socket(sock))
@@ -438,12 +444,7 @@ NewListener(int af, const UINT16 Port)
                return -1;
        }
 
                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 */
 
 #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) {
        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;
        }
 
                return;
        }