INN commit: trunk (doc/pod/nnrpd.pod innd/rc.c nnrpd/nnrpd.c)

INN Commit Russ_Allbery at isc.org
Fri May 15 20:31:54 UTC 2009


    Date: Friday, May 15, 2009 @ 13:31:54
  Author: iulius
Revision: 8463

Remove the limitation nnrpd had to only listen to one socket.
We can now accept both IPv4 and IPv6 connections configured
with the "-b" and "-6" flags.

Modified:
  trunk/doc/pod/nnrpd.pod
  trunk/innd/rc.c
  trunk/nnrpd/nnrpd.c

-------------------+
 doc/pod/nnrpd.pod |   14 ++++-------
 innd/rc.c         |    2 -
 nnrpd/nnrpd.c     |   65 ++++++++++++++++++++++++++++++++++++++++------------
 3 files changed, 58 insertions(+), 23 deletions(-)

Modified: doc/pod/nnrpd.pod
===================================================================
--- doc/pod/nnrpd.pod	2009-05-14 05:43:04 UTC (rev 8462)
+++ doc/pod/nnrpd.pod	2009-05-15 20:31:54 UTC (rev 8463)
@@ -52,20 +52,18 @@
 has to be a valid IPv6 address belonging to an interface of the local
 host.  It can also be C<::0>, saying to bind to all IPv6 addresses.
 
-Only one of B<-6> or B<-b> may be specified.  By default, B<nnrpd> in
-daemon mode listens to only IPv4 addresses.  With this option, it will
-listen to the specified IPv6 addresses instead.  On some systems, a value
-of C<::0> will cause it to listen to all IPv4 addresses as well, but on
-other systems, two copies of B<nnrpd>, one with B<-6> and one without it,
-will have to be run to accept both IPv6 and IPv4 connections.
+By default, B<nnrpd> in daemon mode listens to both IPv4 and IPv6
+addresses.  With this option, it will listen only to the specified
+IPv6 addresses.  On some systems however, a value of C<::0> will cause
+it to listen to all IPv4 addresses as well.
 
 =item B<-b> I<address>
 
 The B<-b> parameter instructs B<nnrpd> to bind to the specified IPv4
 address when started as a standalone daemon using the B<-D> flag.  This
 has to be a valid IPv4 address belonging to an interface of the local
-host.  It can also be 0.0.0.0, saying to bind to all addresses (this is
-the default).
+host.  It can also be C<0.0.0.0>, saying to bind to all addresses (this
+is the default).
 
 =item B<-c> I<configfile>
 

Modified: innd/rc.c
===================================================================
--- innd/rc.c	2009-05-14 05:43:04 UTC (rev 8462)
+++ innd/rc.c	2009-05-15 20:31:54 UTC (rev 8463)
@@ -1748,7 +1748,7 @@
 /*
 **  Create the listening channels.  When IPv6 is available, if only one of
 **  bindaddress and bindaddress6 are set, INN only listens on that address.
-**  If both are set, INN listens to both IPv4 andn IPv6 connections on those
+**  If both are set, INN listens to both IPv4 and IPv6 connections on those
 **  addresses.  If neither is set, use getaddrinfo to walk through all the
 **  possible addresses.  (When IPv6 isn't available, this is obviously a lot
 **  simpler.)

Modified: nnrpd/nnrpd.c
===================================================================
--- nnrpd/nnrpd.c	2009-05-14 05:43:04 UTC (rev 8462)
+++ nnrpd/nnrpd.c	2009-05-15 20:31:54 UTC (rev 8463)
@@ -851,7 +851,10 @@
     unsigned short	ListenPort = NNTP_PORT;
     char                *ListenAddr = NULL;
     char                *ListenAddr6 = NULL;
-    int			lfd, fd;
+    int			*lfds;
+    int                 fd = -1;
+    int                 fdcount;
+    bool                fdokay;
     pid_t		pid = -1;
     FILE                *pidfile;
     int			clienttimeout;
@@ -959,8 +962,6 @@
     argc -= optind;
     if (argc)
 	Usage();
-    if (ListenAddr != NULL && ListenAddr6 != NULL)
-        die("-6 and -b may not both be given");
 
     /* Make other processes happier if someone is reading.  This allows other
      * processes like overchan to keep up when there are lots of readers.
@@ -979,13 +980,31 @@
 
 
     if (DaemonMode) {
-        if (ListenAddr6 != NULL)
-            lfd = network_bind_ipv6(ListenAddr6, ListenPort);
-        else if (ListenAddr != NULL)
-            lfd = network_bind_ipv4(ListenAddr, ListenPort);
-        else
-            lfd = network_bind_ipv4("0.0.0.0", ListenPort);
-        if (lfd < 0)
+        /* Allocate an lfds array to hold the file descriptors
+         * for IPv4 and/or IPv6 connections. */
+        if (ListenAddr == NULL && ListenAddr6 == NULL) {
+            network_bind_all(ListenPort, &lfds, &fdcount);
+        } else {
+            if (ListenAddr != NULL && ListenAddr6 != NULL)
+                fdcount = 2;
+            else
+                fdcount = 1;
+            lfds = xmalloc(fdcount * sizeof(int));
+            i = 0;
+            if (ListenAddr6 != NULL)
+                lfds[i++] = network_bind_ipv6(ListenAddr6, ListenPort);
+            if (ListenAddr != NULL)
+                lfds[i] = network_bind_ipv4(ListenAddr, ListenPort);
+        }
+
+        /* Bail if we couldn't listen on any sockets. */
+        fdokay = false;
+        for (i = 0; i < fdcount; i++) {
+            if (lfds[i] < 0)
+                continue;
+            fdokay = true;
+        }
+        if (!fdokay)
             die("can't bind to any addresses");
 
         /* If started as root, switch to news uid.  Unlike other parts of INN, we
@@ -1024,7 +1043,15 @@
  
 	setproctitle("accepting connections");
  	
-	listen(lfd, 128);	
+        for (i = 0; i < fdcount; i++) {
+            if (nonblocking(lfds[i], true) < 0)
+                syslog(L_ERROR, "can't nonblock %d %m", lfds[i]);
+            if (listen(lfds[i], 128) < 0) {
+                if (i != 0 && errno == EADDRINUSE)
+                    continue;
+                syslog(L_ERROR, "can't listen to socket");
+            }
+        }
 
 	if (respawn) {
 	    /* Pre-forked mode. */
@@ -1034,7 +1061,11 @@
 		    pid = fork();
 		    if (pid == 0) {
 			do {
-			    fd = accept(lfd, NULL, NULL);
+                            for (i = 0; i < fdcount; i++) {
+                                fd = accept(lfds[i], NULL, NULL);
+                                if (fd >= 0)
+                                    break;
+                            }
 			} while (fd < 0);
 			break;
 		    }
@@ -1052,7 +1083,11 @@
 	} else {
 	    /* Fork on demand. */
 	    do {
-		fd = accept(lfd, NULL, NULL);
+                for (i = 0; i < fdcount; i++) {
+                    fd = accept(lfds[i], NULL, NULL);
+                    if (fd >= 0)
+                        break;
+                }
 		if (fd < 0)
 		    continue;
 	    
@@ -1076,7 +1111,9 @@
 
 	/* Child process starts here. */
 	setproctitle("connected");
-	close(lfd);
+        for (i = 0; i < fdcount; i++) {
+            close(lfds[i]);
+        }
 	dup2(fd, 0);
 	close(fd);
 	dup2(0, 1);




More information about the inn-committers mailing list