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