]> git.pld-linux.org Git - packages/inn.git/blame - inn-ipv6.patch
- merge from DEVEL
[packages/inn.git] / inn-ipv6.patch
CommitLineData
2aec8557
JB
1diff -Nur inn-2.3.2.orig/authprogs/auth_pass.c inn-2.3.2/authprogs/auth_pass.c
2--- inn-2.3.2.orig/authprogs/auth_pass.c Thu May 3 22:27:32 2001
3+++ inn-2.3.2/authprogs/auth_pass.c Tue Jun 19 16:06:41 2001
4@@ -70,8 +70,11 @@
5 int length;
6 char password[256];
7 char peername[1024];
8+#ifdef INET6
9+ char tmpname[1048];
10+#endif /* INET6 */
11 struct passwd * pwd;
12- struct sockaddr_in sin;
13+ struct sockaddr_storage ss;
14 char username[32];
15
16 /*
17@@ -105,22 +108,43 @@
18 /*
19 * Get the hostname of the peer.
20 */
21- length = sizeof(sin);
22- if (getpeername(0, (struct sockaddr *)&sin, &length) < 0) {
23+ length = sizeof(ss);
24+ if (getpeername(0, (struct sockaddr *)&ss, &length) < 0) {
25 if (!isatty(0)) {
26 fprintf(stderr, "cant getpeername()::%s:+:!*\n", username);
27 exit(1);
28 }
29 (void)strcpy(peername, "stdin");
30- } else if (sin.sin_family != AF_INET) {
31+#ifdef INET6
32+ } else if (ss.ss_family != AF_INET && ss.ss_family != AF_INET6) {
33+#else
34+ } else if (ss.ss_family != AF_INET) {
35+#endif
36 fprintf(stderr, "Bad address family %ld::%s:+:!*\n",
37- (long)sin.sin_family, username);
38+ (long)ss.ss_family, username);
39 exit(1);
40- } else if ((hp = gethostbyaddr((char *)&sin.sin_addr, sizeof(sin.sin_addr), AF_INET)) == NULL) {
41- strcpy(peername, inet_ntoa(sin.sin_addr));
42+#ifdef INET6
43+ } else {
44+#ifdef HAVE_SOCKADDR_LEN
45+ getnameinfo((struct sockaddr *)&ss, ss.ss_len, peername,
46+ sizeof(peername), NULL, 0, 0);
47+#else
48+ getnameifno((struct sockaddr *)&ss, SA_LEN((struct sockaddr *)&ss),
49+ peername, sizeof(peername), NULL, 0, 0);
50+#endif /* HAVE_SOCKADDR_LEN */
51+ if (strchr(peername, ':') != NULL) {
52+ sprintf(tmpname, "[%s]", peername);
53+ if (strlen(tmpname) < sizeof(peername))
54+ strcpy(peername, tmpname);
55+ }
56+ }
57+#else /* INET6 */
58+ } else if ((hp = gethostbyaddr((char *)&((struct sockaddr_in *)&ss)-sin_addr, sizeof(struct in_addr), AF_INET)) == NULL) {
59+ strcpy(peername, inet_ntoa(((struct sockaddr *)&ss)->sin_addr));
60 } else {
61 strncpy(peername, hp->h_name, sizeof(peername));
62 }
63+#endif /* INET6 */
64
65 /*
66 * Get the user name in the passwd file.
67diff -Nur inn-2.3.2.orig/configure.in inn-2.3.2/configure.in
68--- inn-2.3.2.orig/configure.in Thu May 3 22:27:32 2001
69+++ inn-2.3.2/configure.in Tue Jun 19 16:06:41 2001
70@@ -380,6 +380,199 @@
71 fi
72 esac
73
74+dnl === part for IPv6 support ===
75+AC_MSG_CHECKING([whether to enable ipv6])
76+AC_ARG_ENABLE(ipv6,
77+[ --enable-ipv6 Enable ipv6 (with ipv4) support
78+ --disable-ipv6 Disable ipv6 support],
79+[ case "$enableval" in
80+ no)
81+ AC_MSG_RESULT(no)
82+ ipv6=no
83+ ;;
84+ *) AC_MSG_RESULT(yes)
85+ AC_DEFINE(ENABLE_IPV6)
86+ ipv6=yes
87+ ;;
88+ esac ],
89+
90+ AC_TRY_RUN([ /* AF_INET6 avalable check */
91+#include <sys/types.h>
92+#include <sys/socket.h>
93+main()
94+{
95+ if (socket(AF_INET6, SOCK_STREAM, 0) < 0)
96+ exit(1);
97+ else
98+ exit(0);
99+}
100+],
101+ AC_MSG_RESULT(yes)
102+ AC_DEFINE(ENABLE_IPV6)
103+ ipv6=yes,
104+ AC_MSG_RESULT(no)
105+ ipv6=no,
106+ AC_MSG_RESULT(no)
107+ ipv6=no
108+))
109+
110+ipv6type=unknown
111+ipv6lib=none
112+
113+if test "$ipv6" = "yes"; then
114+ AC_MSG_CHECKING([IPv6 stack type])
115+ for i in inria kame linux-glibc linux-inet6 toshiba v6d zeta; do
116+ case $i in
117+ inria)
118+ dnl http://www.kame.net/
119+ AC_EGREP_CPP(%%%yes%%%, [dnl
120+#include <netinet/in.h>
121+#ifdef IPV6_INRIA_VERSION
122+%%%yes%%%
123+#endif],
124+ [ipv6type=$i;
125+ CFLAGS="-DINET6 $CFLAGS"])
126+ ;;
127+ kame)
128+ dnl http://www.kame.net/
129+ AC_EGREP_CPP(%%%yes%%%, [dnl
130+#include <netinet/in.h>
131+#ifdef __KAME__
132+%%%yes%%%
133+#endif],
134+ [ipv6type=$i;
135+ CFLAGS="-DINET6 $CFLAGS"])
136+ ;;
137+ linux-glibc)
138+ dnl http://www.v6.linux.or.jp/
139+ AC_EGREP_CPP(%%%yes%%%, [dnl
140+#include <features.h>
141+#if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
142+%%%yes%%%
143+#endif],
144+ [ipv6type=$i;
145+ CFLAGS="-DINET6 $CFLAGS"])
146+ ;;
147+ linux-inet6)
148+ dnl http://www.v6.linux.or.jp/
149+ if test -d /usr/inet6; then
150+ ipv6type=$i
151+ ipv6lib=inet6
152+ ipv6libdir=/usr/inet6/lib
153+ CFLAGS="-DINET6 -I/usr/inet6/include $CFLAGS"
154+ fi
155+ ;;
156+ toshiba)
157+ AC_EGREP_CPP(%%%yes%%%, [dnl
158+#include <sys/param.h>
159+#ifdef _TOSHIBA_INET6
160+%%%yes%%%
161+#endif],
162+ [ipv6type=$i;
163+ ipv6lib=inet6;
164+ ipv6libdir=/usr/local/v6/lib;
165+ CFLAGS="-DINET6 $CFLAGS"])
166+ ;;
167+ v6d)
168+ AC_EGREP_CPP(%%%yes%%%, [dnl
169+#include </usr/local/v6/include/sys/v6config.h>
170+#ifdef __V6D__
171+%%%yes%%%
172+#endif],
173+ [ipv6type=$i;
174+ ipv6lib=v6;
175+ ipv6libdir=/usr/local/v6/lib;
176+ CFLAGS="-I/usr/local/v6/include $CFLAGS"])
177+ ;;
178+ zeta)
179+ AC_EGREP_CPP(%%%yes%%%, [dnl
180+#include <sys/param.h>
181+#ifdef _ZETA_MINAMI_INET6
182+yes
183+#endif],
184+ [ipv6type=$i;
185+ ipv6lib=inet6;
186+ ipv6libdir=/usr/local/v6/lib;
187+ CFLAGS="-DINET6 $CFLAGS"])
188+ ;;
189+ esac
190+ if test "$ipv6type" != "unknown"; then
191+ break
192+ fi
193+ done
194+ AC_MSG_RESULT($ipv6type)
195+fi
196+
197+if test "$ipv6" = "yes"; then
198+ if test -d /usr/local/v6/lib; then
199+ ac_inet6_LDFLAGS="inet6"
200+ ipv6libdir=/usr/local/v6/lib
201+ LDFLAGS="$LDFLAGS -L/usr/local/v6/lib"
202+ AC_CHECK_LIB(inet6, getaddrinfo, , ipv6lib="$ac_inet6_LDFLAGS")
203+ else
204+ AC_CHECK_FUNCS(getaddrinfo)
205+ fi
206+fi
207+
208+if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then
209+ if test -d $ipv6libdir -a -f $ipv6libdir/lib$ipv6lib.a; then
210+ LIBS="-L$ipv6libdir -l$ipv6lib $LIBS"
211+ fi
212+fi
213+AC_SUBST(ipv6)
214+
215+dnl checking for sa_len;
216+dnl the following check says 'yes' if your system has __libc_sa_len
217+dnl AC_EGREP_HEADER(sa_len, sys/socket.h,
218+dnl [ AC_DEFINE(HAVE_SOCKADDR_LEN) AC_MSG_RESULT(yes)], AC_MSG_RESULT(no))
219+AC_MSG_CHECKING([whether struct sockaddr has sa_len])
220+AC_TRY_COMPILE([
221+#include <sys/types.h>
222+#include <sys/socket.h>
223+],[
224+struct sockaddr sa;
225+int i = sa.sa_len;
226+],
227+[AC_MSG_RESULT(yes)
228+ AC_DEFINE(HAVE_SOCKADDR_LEN)],
229+AC_MSG_RESULT(no))
230+
231+AC_MSG_CHECKING([whether sys/socket.h has SA_LEN])
232+AC_TRY_RUN([
233+#include <sys/types.h>
234+#include <sys/socket.h>
235+struct sockaddr sa;
236+int main(){ int i = SA_LEN((struct sockaddr*)&sa); return 0;}
237+],
238+[AC_MSG_RESULT(yes)
239+ AC_DEFINE(HAVE_SA_LEN)],
240+AC_MSG_RESULT(no),AC_MSG_RESULT(no))
241+
242+AC_MSG_CHECKING([whether sys/socket.h has struct sockaddr_storage])
243+AC_TRY_COMPILE([
244+#include <sys/types.h>
245+#include <sys/socket.h>
246+],[
247+struct sockaddr_storage ss;
248+],
249+[AC_MSG_RESULT(yes)
250+ AC_DEFINE(HAVE_SOCKADDR_STORAGE)],
251+AC_MSG_RESULT(no))
252+
253+AC_MSG_CHECKING([whether struct sockaddr_storage has __ss_family])
254+AC_TRY_COMPILE([
255+#include <sys/types.h>
256+#include <sys/socket.h>
257+],[
258+struct sockaddr_storage ss;
259+int i = ss.__ss_family;
260+],
261+[AC_MSG_RESULT(yes)
262+ AC_DEFINE(HAVE_2553_STYLE_SS_FAMILY)],
263+AC_MSG_RESULT(no), AC_MSG_RESULT(no))
264+
265+dnl === end of part for IPv6 support ===
266+
267 dnl Checks for pathnames.
268
269 dnl See if we have ctags; if so, set CTAGS to its full path plus the -t -w
270@@ -1061,7 +1254,7 @@
271 AC_CHECK_FUNCS(atexit fchmod fcntl gethostname getpagesize getrusage \
272 getspnam gettimeofday mkfifo setbuffer sigaction setsid \
273 socketpair statvfs strcspn strncasecmp strstr strtoul \
274- symlink waitpid)
275+ symlink waitpid inet_ntoa)
276
277 dnl We only care if we have setreuid() if we don't have seteuid().
278 AC_CHECK_FUNCS(seteuid setreuid, break)
279@@ -1095,7 +1288,7 @@
280 fi
281
282 dnl If we can't find any of the following, we have replacements for them.
283-AC_REPLACE_FUNCS(fseeko ftello getopt inet_aton inet_ntoa pread pwrite \
284+AC_REPLACE_FUNCS(fseeko ftello getopt inet_aton pread pwrite \
285 strcasecmp strdup strerror strspn setenv hstrerror)
286
287 dnl If replacing fseeko or ftello, see if we can use fsetpos/fgetpos.
288diff -Nur inn-2.3.2.orig/doc/man/inn.conf.5 inn-2.3.2/doc/man/inn.conf.5
289--- inn-2.3.2.orig/doc/man/inn.conf.5 Thu May 3 22:27:32 2001
290+++ inn-2.3.2/doc/man/inn.conf.5 Tue Jun 19 16:06:41 2001
291@@ -1055,6 +1055,25 @@
292 directory). It must be on the same partition as \fIpathincoming\fR for
293 \&\fIrnews\fR\|(1) to work correctly. The default value is set at configure time
294 and defaults to \fIpathnews\fR/tmp.
295+.Sh "IPv6 Configurations"
296+.IX Subsection "IPv6 Configurations"
297+If your system can use IPv6, the following parameters are available.
298+.Ip "\fIlistenonipv6\fR" 4
299+.IX Item "listenonipv6"
300+If set to true, \fIinnd\fR\|(8) creates an IPv6 socket for waiting connections
301+from IPv6 clients.
302+.Ip "\fIbindipv6address\fR" 4
303+.IX Item "bindipv6address"
304+Which IPv6 address \fIinnd\fR\|(8) should bind itself to. This must be in
305+numeric IPv6 address format. If set to \f(CW\*(C`all\*(C'\fR or not set, innd
306+defaults to listening on all interfaces. The default value is unset.
307+.Ip "\fIsourceipv6address\fR" 4
308+.IX Item "sourceipv6address"
309+Which local IPv6 address to bind to outgoing NNTP sockets (used by
310+\fIinnxmit\fR\|(8) among other programs). This must be in numeric IPv6
311+address format. If set to \f(CW\*(C`all\*(C'\fR or not set,
312+the operating system will choose the source IPv6 address for outgoing
313+connections. The default value is unset.
314 .SH "EXAMPLE"
315 .IX Header "EXAMPLE"
316 Here is a very minimalist example that only sets those parameters that are
317diff -Nur inn-2.3.2.orig/include/clibrary.h inn-2.3.2/include/clibrary.h
318--- inn-2.3.2.orig/include/clibrary.h Thu May 3 22:27:32 2001
319+++ inn-2.3.2/include/clibrary.h Tue Jun 19 16:06:41 2001
320@@ -102,9 +102,7 @@
321 #ifndef HAVE_PWRITE
322 extern ssize_t pwrite(int fd, void *buf, size_t nbyte, OFFSET_T offset);
323 #endif
324-#ifndef HAVE_INET_NTOA
325-extern char *inet_ntoa();
326-#endif
327+extern char *Inet_NtoA();
328 #ifndef HAVE_STRDUP
329 extern char *strdup();
330 #endif
331diff -Nur inn-2.3.2.orig/include/config.h.in inn-2.3.2/include/config.h.in
332--- inn-2.3.2.orig/include/config.h.in Thu May 3 22:27:32 2001
333+++ inn-2.3.2/include/config.h.in Tue Jun 19 16:06:41 2001
334@@ -732,4 +732,26 @@
335 /* All incoming control commands (ctlinnd, etc). */
336 #define L_CC_CMD LOG_INFO
337
338+/* IPv6 support */
339+
340+/* sockaddr.sa_len */
341+#undef HAVE_SOCKADDR_LEN
342+
343+/* SA_LEN() */
344+#undef HAVE_SA_LEN
345+
346+/* struct sockaddr_storage */
347+#undef HAVE_SOCKADDR_STORAGE
348+
349+/* getaddrinfo() */
350+#undef HAVE_GETADDRINFO
351+
352+/* sockaddr_storage.__ss_family */
353+#undef HAVE_2553_STYLE_SS_FAMILY
354+
355+#ifdef HAVE_2553_STYLE_SS_FAMILY
356+# define ss_family __ss_family
357+# define ss_len __ss_len
358+#endif
359+
360 #endif /* !__CONFIG_H__ */
361diff -Nur inn-2.3.2.orig/include/innconf.h inn-2.3.2/include/innconf.h
362--- inn-2.3.2.orig/include/innconf.h Thu May 3 22:27:32 2001
363+++ inn-2.3.2/include/innconf.h Tue Jun 19 16:06:41 2001
364@@ -329,7 +329,16 @@
365 { _CONF_WIPCHECK, "", 2, 1 },
366 #define _CONF_NNRPPYTHONAUTH "nnrppythonauth"
367 #define CONF_VAR_NNRPPYTHONAUTH 103
368- { _CONF_NNRPPYTHONAUTH, "", 2, 1 }
369+ { _CONF_NNRPPYTHONAUTH, "", 2, 1 },
370+#define _CONF_LISTENONIPV6 "listenonipv6"
371+#define CONF_VAR_LISTENONIPV6 104
372+ { _CONF_LISTENONIPV6, "", 2, 0 },
373+#define _CONF_BINDIPV6ADDRESS "bindipv6address"
374+#define CONF_VAR_BINDIPV6ADDRESS 105
375+ { _CONF_BINDIPV6ADDRESS, "", 1, 0 },
376+#define _CONF_SOURCEIPV6ADDRESS "sourceipv6address"
377+#define CONF_VAR_SOURCEIPV6ADDRESS 106
378+ { _CONF_SOURCEIPV6ADDRESS, "", 1, 0 }
379 };
380-#define MAX_CONF_VAR 104
381+#define MAX_CONF_VAR 106
382
383diff -Nur inn-2.3.2.orig/include/libinn.h inn-2.3.2/include/libinn.h
384--- inn-2.3.2.orig/include/libinn.h Thu May 3 22:27:32 2001
385+++ inn-2.3.2/include/libinn.h Tue Jun 19 16:06:41 2001
386@@ -101,6 +101,7 @@
387 /* Feed Configuration */
388 int artcutoff; /* Max accepted article age */
389 char *bindaddress; /* Which interface IP to bind to */
390+ char *bindipv6address; /* Which interface IP to bind to */
391 int hiscachesize; /* Size of the history cache in kB */
392 int ignorenewsgroups; /* Propagate cmsgs by affected group? */
393 int immediatecancel; /* Immediately cancel timecaf messages? */
394@@ -112,11 +113,13 @@
395 int refusecybercancels; /* Reject message IDs with "<cancel."? */
396 int remembertrash; /* Put unwanted article IDs into history */
397 char *sourceaddress; /* Source IP for outgoing NNTP connections */
398+ char *sourceipv6address; /* Source IP for outgoing NNTP connections */
399 int usecontrolchan; /* Use a channel feed for control messages? */
400 int verifycancels; /* Verify cancels against article author */
401 int wanttrash; /* Put unwanted articles in junk */
402 int wipcheck; /* How long to defer other copies of article */
403 int wipexpire; /* How long to keep pending article record */
404+ int listenonipv6; /* Listen on IPv6 socket */
405
406 /* Article Storage */
407 long cnfscheckfudgesize; /* Additional CNFS integrity checking */
408diff -Nur inn-2.3.2.orig/include/sa_len.h inn-2.3.2/include/sa_len.h
409--- inn-2.3.2.orig/include/sa_len.h Thu Jan 1 01:00:00 1970
410+++ inn-2.3.2/include/sa_len.h Tue Jun 19 16:06:41 2001
411@@ -0,0 +1,46 @@
412+/*
413+ * sa_len.h : tiny version of SA_LEN
414+ * (original written by <yoshfuji@ecei.tohoku.ac.jp>)
415+ */
416+
417+#include <sys/types.h>
418+#include <sys/socket.h>
419+#include <netinet/in.h>
420+#include <sys/un.h>
421+
422+#ifndef SIN6_LEN
423+#ifndef SA_LEN
424+#define SA_LEN(s_) ap_sa_len((s_)->sa_family)
425+
426+static int ap_sa_len (int af)
427+{
428+ switch (af) {
429+#if defined(AF_INET)
430+ case AF_INET:
431+ return (sizeof(struct sockaddr_in));
432+#endif /* AF_INET */
433+#if defined(INET6)
434+ case AF_INET6:
435+ return (sizeof(struct sockaddr_in6));
436+#endif /* AF_INET6 */
437+#if defined(AF_LOCAL)
438+ case AF_LOCAL:
439+#endif /* AF_LOCAL */
440+#if defined(AF_UNIX) && !(AF_UNIX == AF_LOCAL)
441+ case AF_UNIX:
442+#endif /* AF_UNIX */
443+#if defined(AF_FILE) && !(AF_FILE == AF_LOCAL)
444+ case AF_FILE:
445+#endif /* AF_FILE */
446+#if defined(AF_LOCAL) || defined(AF_UNIX) || defined(AF_FILE)
447+ return (sizeof(struct sockaddr_un));
448+#endif /* fdefined(AF_LOCAL) || defined(AF_UNIX) || defined(AF_FILE) */
449+ default:
450+ return 0;
451+ }
452+ return 0;
453+}
454+
455+#endif /* SA_LEN */
456+#endif /* SIN6_LEN */
457+
458diff -Nur inn-2.3.2.orig/include/sockaddr_storage.h inn-2.3.2/include/sockaddr_storage.h
459--- inn-2.3.2.orig/include/sockaddr_storage.h Thu Jan 1 01:00:00 1970
460+++ inn-2.3.2/include/sockaddr_storage.h Tue Jun 19 16:06:41 2001
461@@ -0,0 +1,53 @@
462+/*
463+struct sockaddr_storage
464+
465+ RFC2553 proposes struct sockaddr_storage.
466+ This is a placeholder for all sockaddr-variant structures. This is
467+ implemented like follows:
468+
469+ You should use this structure to hold any of sockaddr-variant
470+ structures.
471+*/
472+#ifndef HAVE_SOCKADDR_STORAGE
473+
474+struct sockaddr_storage {
475+#ifdef HAVE_SOCKADDR_LEN
476+ u_char ss_len;
477+ u_char ss_family;
478+#else
479+ u_short ss_family;
480+#endif
481+ u_char __padding[128 - 2];
482+};
483+
484+/*
485+union sockunion
486+
487+ Alternatively, you may want to implement sockunion.h, with the
488+ following content:
489+
490+ NOTE: For better portability, struct sockaddr_storage should be used.
491+ union sockunion is okay, but is not really portable enough.
492+*/
493+union sockunion {
494+ struct sockinet {
495+#ifdef HAVE_SOCKADDR_LEN
496+ u_char si_len;
497+ u_char si_family;
498+#else
499+ u_short si_family;
500+#endif
501+ u_short si_port;
502+ } su_si;
503+ struct sockaddr_in su_sin;
504+#ifdef INET6
505+ struct sockaddr_in6 su_sin6;
506+#endif
507+};
508+#ifdef HAVE_SOCKADDR_LEN
509+#define su_len su_si.si_len
510+#endif
511+#define su_family su_si.si_family
512+#define su_port su_si.si_port
513+
514+#endif /* HAVE_SOCKADDR_STORAGE */
515diff -Nur inn-2.3.2.orig/innd/chan.c inn-2.3.2/innd/chan.c
516--- inn-2.3.2.orig/innd/chan.c Thu May 3 22:27:32 2001
517+++ inn-2.3.2/innd/chan.c Tue Jun 19 16:06:41 2001
518@@ -36,8 +36,8 @@
519
520 #define PRIORITISE_REMCONN
521 #ifdef PRIORITISE_REMCONN
522-STATIC int CHANrcfd;
523-STATIC CHANNEL *CHANrc;
524+STATIC int CHANrcfd[2];
525+STATIC CHANNEL *CHANrc[2];
526 #endif /* PRIORITISE_REMCONN */
527
528 /*
529@@ -147,7 +147,7 @@
530 (void)memset((POINTER)CHANtable, 0,
531 (SIZE_T)(CHANtablesize * sizeof *CHANtable));
532 CHANnull.NextLog = innconf->chaninacttime;
533- CHANnull.Address.s_addr = MyAddress.s_addr;
534+ memcpy((POINTER)&CHANnull.Address, (POINTER)&MyAddress, sizeof MyAddress);
535 for (cp = CHANtable; --i >= 0; cp++)
536 *cp = CHANnull;
537 }
538@@ -239,8 +239,13 @@
539 #ifdef PRIORITISE_REMCONN
540 /* Note remconn channel, for efficiency */
541 if (Type == CTremconn) {
542- CHANrc = cp;
543- CHANrcfd = fd;
544+ if (CHANrc[0] == NULL) {
545+ CHANrc[0] = cp;
546+ CHANrcfd[0] = fd;
547+ } else {
548+ CHANrc[1] = cp;
549+ CHANrcfd[1] = fd;
550+ }
551 }
552 #endif /* PRIORITISE_REMCONN */
553 return cp;
554@@ -261,7 +266,7 @@
555 syslog(L_NOTICE, "%s trace badwrites %d blockwrites %d badreads %d",
556 p, cp->BadWrites, cp->BlockedWrites, cp->BadReads);
557 syslog(L_NOTICE, "%s trace address %s lastactive %ld nextlog %ld",
558- p, inet_ntoa(cp->Address), cp->LastActive, cp->NextLog);
559+ p, Inet_NtoA(&cp->Address), cp->LastActive, cp->NextLog);
560 if (FD_ISSET(cp->fd, &SCHANmask))
561 syslog(L_NOTICE, "%s trace sleeping %ld 0x%x",
562 p, (long)cp->Waketime, cp->Waker);
563@@ -383,7 +388,7 @@
564 break;
565 case CTnntp:
566 (void)sprintf(buff, "%s:%d",
567- cp->Address.s_addr == 0 ? "localhost" : RChostname(cp),
568+ cp->Address.ss_family == 0 ? "localhost" : RChostname(cp),
569 cp->fd);
570 break;
571 case CTlocalconn:
572@@ -922,11 +927,14 @@
573
574 #ifdef PRIORITISE_REMCONN
575 /* Try the remconn channel next. */
576- if (FD_ISSET(CHANrcfd, &RCHANmask) && FD_ISSET(CHANrcfd, &MyRead)) {
577- count--;
578- if (count > 3) count = 3; /* might be more requests */
579- (*CHANrc->Reader)(CHANrc);
580- FD_CLR(CHANrcfd, &MyRead);
581+ for (i = 0; i < 2; i++) {
582+ if (FD_ISSET(CHANrcfd[i], &RCHANmask) &&
583+ FD_ISSET(CHANrcfd[i], &MyRead)) {
584+ count--;
585+ if (count > 3) count = 3; /* might be more requests */
586+ (*CHANrc[i]->Reader)(CHANrc[i]);
587+ FD_CLR(CHANrcfd[i], &MyRead);
588+ }
589 }
590 #endif /* PRIORITISE_REMCONN */
591
592diff -Nur inn-2.3.2.orig/innd/innd.c inn-2.3.2/innd/innd.c
593--- inn-2.3.2.orig/innd/innd.c Thu May 3 22:27:32 2001
594+++ inn-2.3.2/innd/innd.c Tue Jun 19 16:06:41 2001
595@@ -558,7 +558,7 @@
596 {
597 static char WHEN[] = "PID file";
598 int i;
599- int fd;
600+ int fd[2];
601 int logflags;
602 char buff[SMBUF];
603 char *p;
604@@ -599,7 +599,7 @@
605 ShouldRenumber = FALSE;
606 ShouldSyntaxCheck = FALSE;
607 logflags = L_OPENLOG_FLAGS | LOG_NOWAIT;
608- fd = -1;
609+ fd[0] = fd[1] = -1;
610
611 #if defined(DO_FAST_RESOLV)
612 /* We only use FQDN's in the hosts.nntp file. */
613@@ -680,10 +680,12 @@
614 case 'p':
615 /* Silently ignore multiple -p flags, in case ctlinnd xexec
616 * called inndstart. */
617- if (fd == -1) {
618- fd = atoi(optarg);
619+ if (fd[0] == -1) {
620+ fd[0] = atoi(optarg);
621 AmRoot = FALSE;
622- }
623+ } else if (fd[1] == -1) {
624+ fd[1] = atoi(optarg);
625+ }
626 break;
627 case 'P':
628 innconf->port = atoi(optarg);
629@@ -774,7 +776,7 @@
630 syslog(L_FATAL, "%s internal cant stat control directory %m", LogName);
631 exit(1);
632 }
633- if (fd != -1 && setgid(NewsGID) < 0)
634+ if (fd[0] != -1 && setgid(NewsGID) < 0)
635 syslog(L_ERROR, "%s cant setgid running as %d not %d %m",
636 LogName, (int)getgid(), (int)NewsGID);
637
638@@ -884,7 +886,11 @@
639 HISsetup();
640 CCsetup();
641 LCsetup();
642- RCsetup(fd);
643+ RCsetup(fd[0]);
644+#ifdef INET6
645+ if (innconf->listenonipv6 && fd[1] != -1)
646+ RCsetup(fd[1]);
647+#endif
648 WIPsetup();
649 NCsetup(i);
650 ARTsetup();
651diff -Nur inn-2.3.2.orig/innd/innd.h inn-2.3.2/innd/innd.h
652--- inn-2.3.2.orig/innd/innd.h Thu May 3 22:27:32 2001
653+++ inn-2.3.2/innd/innd.h Tue Jun 19 16:06:41 2001
654@@ -51,6 +51,7 @@
655 #include "nntp.h"
656 #include "paths.h"
657 #include "storage.h"
658+#include "sockaddr_storage.h"
659
660 #if defined(DO_TCL)
661 #include <tcl.h>
662@@ -66,7 +67,7 @@
663 /*
664 ** Some convenient shorthands.
665 */
666-typedef struct in_addr INADDR;
667+typedef struct sockaddr_storage INADDR;
668
669 #ifndef u_long
670 #define u_long unsigned long
671diff -Nur inn-2.3.2.orig/innd/inndstart.c inn-2.3.2/innd/inndstart.c
672--- inn-2.3.2.orig/innd/inndstart.c Thu May 3 22:27:32 2001
673+++ inn-2.3.2/innd/inndstart.c Tue Jun 19 16:06:41 2001
674@@ -145,6 +145,12 @@
675 unsigned long address;
676 int s;
677 struct sockaddr_in server;
678+#ifdef INET6
679+ int s6;
680+ struct sockaddr_in6 server6;
681+ char p6flag[SMBUF];
682+ int in6any;
683+#endif
684 int i;
685 int j;
686 char * p;
687@@ -299,6 +305,64 @@
688
689 /* Create a socket and name it. innconf->bindaddress controls what
690 address we bind as, defaulting to INADDR_ANY. */
691+#ifdef INET6
692+ in6any = 1;
693+ s6 = -1;
694+ if (innconf->listenonipv6) {
695+ s6 = socket(AF_INET6, SOCK_STREAM, 0);
696+ if (s6 < 0) {
697+ syslog(L_FATAL, "can't open inet6 socket: %m");
698+ exit(1);
699+ }
700+#ifdef SO_REUSEADDR
701+ i = 1;
702+ if (setsockopt(s6, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof i) < 0)
703+ syslog(L_ERROR, "can't setsockopt: %m");
704+#endif
705+ memset(&server6, 0, sizeof server6);
706+ server6.sin6_port = htons(port);
707+ server6.sin6_family = AF_INET6;
708+ server6.sin6_addr = in6addr_any;
709+ p = innconf->bindipv6address;
710+ if (p && !EQ(p, "all") && !EQ(p, "any")) {
711+ if (inet_pton(AF_INET6, p, &server6.sin6_addr) < 1) {
712+ syslog(L_FATAL, "invalid bindipv6address in inn.conf (%s)", p);
713+ exit(1);
714+ }
715+ in6any = 0;
716+ }
717+#ifdef HAVE_SOCKADDR_LEN
718+ server6.sin6_len = sizeof server6;
719+#endif
720+ for (i = 1; i < argc; i++) {
721+ if (EQn("-6", argv[i], 2)) {
722+ if (strlen(argv[i]) > 2) {
723+ p = argv[i] + 2;
724+ } else {
725+ i++;
726+ if (argv[i] == NULL) {
727+ syslog(L_FATAL, "missing address after -6");
728+ fprintf(stderr, "Missing address after -6\n");
729+ exit(1);
730+ }
731+ p = argv[i];
732+ }
733+ if (inet_pton(AF_INET6, p, &server6) < 1) {
734+ syslog(L_FATAL, "invalid ipv6 address %s", p);
735+ fprintf(stderr, "Invalid ipv6 address %s\n", p);
736+ exit(1);
737+ }
738+ in6any = 0;
739+ }
740+ }
741+ if (bind(s6, (struct sockaddr *)&server6, sizeof server6) < 0) {
742+ syslog(L_FATAL, "can't bind: %m");
743+ exit(1);
744+ }
745+ }
746+ if (!innconf->listenonipv6 || !in6any)
747+#endif /* INET6 */
748+ {
749 s = socket(AF_INET, SOCK_STREAM, 0);
750 if (s < 0) {
751 syslog(L_FATAL, "can't open socket: %m");
752@@ -317,6 +381,8 @@
753 syslog(L_FATAL, "can't bind: %m");
754 exit(1);
755 }
756+ }
757+
758
759 /* Now, permanently drop privileges. */
760 if (setgid(news_gid) < 0 || getgid() != news_gid) {
761@@ -330,24 +396,47 @@
762
763 /* Build the argument vector for innd. Pass -p<port> to innd to tell it
764 what port we just created and bound to for it. */
765- innd_argv = NEW(char *, 1 + argc + 1);
766+#ifdef INET6
767+ if (innconf->listenonipv6 && !in6any)
768+ innd_argv = NEW(char *, 1 + argc + 2);
769+ else
770+#endif
771+ innd_argv = NEW(char *, 1 + argc + 1);
772 i = 0;
773 #ifdef DEBUGGER
774 innd_argv[i++] = DEBUGGER;
775 innd_argv[i++] = cpcatpath(innconf->pathbin, "innd");
776 innd_argv[i] = 0;
777+#ifdef INET6
778+ if (innconf->listenonipv6)
779+ printf("When starting innd, use -d -p%d [-p%d]\n", s6, s);
780+ else
781+#endif /* INET6 */
782 printf("When starting innd, use -dp%d\n", s);
783 #else /* DEBUGGER */
784- sprintf(pflag, "-p%d", s);
785 innd_argv[i++] = cpcatpath(innconf->pathbin, "innd");
786- innd_argv[i++] = pflag;
787+#ifdef INET6
788+ if (innconf->listenonipv6) {
789+ sprintf(p6flag, "-p%d", s6);
790+ innd_argv[i++] = p6flag;
791+ }
792+ if (innconf->listenonipv6 && in6any)
793+ {
794+ sprintf(pflag, "-p-1");
795+ innd_argv[i++] = pflag;
796+ } else
797+#endif
798+ {
799+ sprintf(pflag, "-p%d", s);
800+ innd_argv[i++] = pflag;
801+ }
802
803- /* Don't pass along -p, -P, or -I. Check the length of the argument
804+ /* Don't pass along -p, -P, -6, or -I. Check the length of the argument
805 string, and if it's == 2 (meaning there's nothing after the -p or -P
806- or -I), skip the next argument too, to support leaving a space
807+ or -6 or -I), skip the next argument too, to support leaving a space
808 between the argument and the value. */
809 for (j = 1; j < argc; j++) {
810- if (argv[j][0] == '-' && strchr("pPI", argv[j][1])) {
811+ if (argv[j][0] == '-' && strchr("6pPI", argv[j][1])) {
812 if (strlen(argv[j]) == 2) j++;
813 continue;
814 } else {
815diff -Nur inn-2.3.2.orig/innd/lc.c inn-2.3.2/innd/lc.c
816--- inn-2.3.2.orig/innd/lc.c Thu May 3 22:27:32 2001
817+++ inn-2.3.2/innd/lc.c Tue Jun 19 16:06:41 2001
818@@ -39,7 +39,7 @@
819 return;
820 }
821 if ((new = NCcreate(fd, FALSE, TRUE)) != NULL) {
822- new->Address.s_addr = MyAddress.s_addr;
823+ memcpy(&new->Address, &MyAddress, sizeof(MyAddress));
824 syslog(L_NOTICE, "%s connected %d", "localhost", new->fd);
825 NCwritereply(new, (char *)NCgreeting);
826 }
827diff -Nur inn-2.3.2.orig/innd/rc.c inn-2.3.2/innd/rc.c
828--- inn-2.3.2.orig/innd/rc.c Thu May 3 22:27:32 2001
829+++ inn-2.3.2/innd/rc.c Tue Jun 19 16:06:41 2001
830@@ -19,9 +19,6 @@
831 # define INADDR_NONE 0xffffffff
832 #endif
833
834-#define COPYADDR(dest, src) \
835- (void)memcpy((POINTER)dest, (POINTER)src, (SIZE_T)sizeof (INADDR))
836-
837 #define TEST_CONFIG(a, b) \
838 { \
839 b = ((peer_params.Keysetbit & (1 << a)) != 0) ? TRUE : FALSE; \
840@@ -66,7 +63,7 @@
841 STATIC char *RCslaveflag;
842 STATIC char *RCnnrpd = NULL;
843 STATIC char *RCnntpd = NULL;
844-STATIC CHANNEL *RCchan;
845+STATIC CHANNEL *RCchan[2];
846 STATIC REMOTEHOST_DATA *RCpeerlistfile;
847 STATIC REMOTEHOST *RCpeerlist;
848 STATIC int RCnpeerlist;
849@@ -112,6 +109,68 @@
850 STATIC int remotecount;
851 STATIC int remotefirst;
852
853+void
854+COPYADDR(INADDR *dst, char *src)
855+{
856+ struct sockaddr_in sin;
857+
858+ memset(&sin, 0, sizeof(sin));
859+ sin.sin_family = AF_INET;
860+#if defined(HAVE_SOCKADDR_LEN)
861+ sin.sin_len = sizeof(sin);
862+#endif /* defined(HAVE_SOCKADDR_LEN) */
863+ (void)memcpy((POINTER)&sin.sin_addr, src, sizeof(sin.sin_addr));
864+
865+ (void)memcpy((POINTER)dst, (POINTER)&sin, sizeof(sin));
866+}
867+
868+BOOL
869+RCaddressmatch(INADDR *cp, INADDR *rp)
870+{
871+#ifdef INET6
872+ struct sockaddr_in *sin_cp, *sin_rp;
873+ struct sockaddr_in6 *sin6_cp, *sin6_rp;
874+
875+ if (cp->ss_family == AF_INET6 && rp->ss_family == AF_INET) {
876+ sin6_cp = (struct sockaddr_in6 *)cp;
877+ sin_rp = (struct sockaddr_in *)rp;
878+ if (IN6_IS_ADDR_V4MAPPED(&sin6_cp->sin6_addr) &&
879+ memcmp(&sin6_cp->sin6_addr.s6_addr[12], &sin_rp->sin_addr.s_addr,
880+ sizeof(struct in_addr)) == 0)
881+ return TRUE;
882+ else
883+ return FALSE;
884+ } else if (cp->ss_family == AF_INET && rp->ss_family == AF_INET6) {
885+ sin_cp = (struct sockaddr_in *)cp;
886+ sin6_rp = (struct sockaddr_in6 *)rp;
887+ if (IN6_IS_ADDR_V4MAPPED(&sin6_rp->sin6_addr) &&
888+ memcmp(&sin6_rp->sin6_addr.s6_addr[12], &sin_cp->sin_addr.s_addr,
889+ sizeof(struct in_addr)) == 0)
890+ return TRUE;
891+ else
892+ return FALSE;
893+ }
894+#endif /* INET6 */
895+ if (cp->ss_family != rp->ss_family)
896+ return FALSE;
897+
898+ switch (cp->ss_family) {
899+ case AF_INET:
900+ if (((struct sockaddr_in *)cp)->sin_addr.s_addr ==
901+ ((struct sockaddr_in *)rp)->sin_addr.s_addr)
902+ return TRUE;
903+ return FALSE;
904+#ifdef INET6
905+ case AF_INET6:
906+ if (IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)cp)->sin6_addr,
907+ &((struct sockaddr_in6 *)rp)->sin6_addr))
908+ return TRUE;
909+ return FALSE;
910+#endif /* INET6 */
911+ }
912+
913+ return FALSE;
914+}
915
916 /*
917 * Split text into comma-separated fields. Return an allocated
918@@ -168,7 +227,7 @@
919 #endif
920
921 int
922-RCfix_options(int fd, struct sockaddr_in *remote)
923+RCfix_options(int fd, INADDR *remote)
924 {
925 #if IP_OPTIONS
926 unsigned char optbuf[BUFSIZ / 3], *cp;
927@@ -177,10 +236,22 @@
928 int ipproto;
929 struct protoent *ip;
930
931- if ((ip = getprotobyname("ip")) != 0)
932- ipproto = ip->p_proto;
933- else
934- ipproto = IPPROTO_IP;
935+ switch (remote->ss_family) {
936+ case AF_INET:
937+ if ((ip = getprotobyname("ip")) != 0)
938+ ipproto = ip->p_proto;
939+ else
940+ ipproto = IPPROTO_IP;
941+ break;
942+#if defined(INET6)
943+ case AF_INET6:
944+ if ((ip = getprotobyname("ipv6")) != 0)
945+ ipproto = ip->p_proto;
946+ else
947+ ipproto = IPPROTO_IPV6;
948+ break;
949+#endif /* defined(INET6) */
950+ }
951
952 if (getsockopt(fd, ipproto, IP_OPTIONS, (char *) optbuf, &optsize) == 0
953 && optsize != 0) {
954@@ -189,7 +260,7 @@
955 sprintf(lp, " %2.2x", *cp);
956 syslog(LOG_NOTICE,
957 "connect from %s with IP options (ignored):%s",
958- inet_ntoa(remote->sin_addr), lbuf);
959+ Inet_NtoA(remote), lbuf);
960 if (setsockopt(fd, ipproto, IP_OPTIONS, (char *) 0, optsize) != 0) {
961 syslog(LOG_ERR, "setsockopt IP_OPTIONS NULL: %m");
962 return -1;
963@@ -210,17 +281,17 @@
964 register int i;
965
966 for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
967- if (cp->Address.s_addr == rp->Address.s_addr) {
968+ if (RCaddressmatch(&cp->Address, &rp->Address)) {
969 if (rp->Password[0] == '\0' || EQ(pass, rp->Password))
970 return TRUE;
971 syslog(L_ERROR, "%s (%s) bad_auth", rp->Label,
972- inet_ntoa(cp->Address));
973+ Inet_NtoA(&cp->Address));
974 return FALSE;
975 }
976
977 if (!AnyIncoming)
978 /* Not found in our table; this can't happen. */
979- syslog(L_ERROR, "%s not_found", inet_ntoa(cp->Address));
980+ syslog(L_ERROR, "%s not_found", Inet_NtoA(&cp->Address));
981
982 /* Anonymous hosts should not authenticate. */
983 return FALSE;
984@@ -237,7 +308,7 @@
985 register int i;
986
987 for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
988- if (cp->Address.s_addr == rp->Address.s_addr)
989+ if (RCaddressmatch(&cp->Address, &rp->Address))
990 if (rp->MaxCnx)
991 return FALSE;
992 else
993@@ -256,7 +327,7 @@
994 register int i;
995
996 for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
997- if (cp->Address.s_addr == rp->Address.s_addr)
998+ if (RCaddressmatch(&cp->Address, &rp->Address))
999 return (rp->MaxCnx);
1000 /* Not found in our table; this can't happen. */
1001 return RemoteLimit;
1002@@ -270,7 +341,7 @@
1003 RCrejectreader(CHANNEL *cp)
1004 {
1005 syslog(L_ERROR, "%s internal RCrejectreader (%s)", LogName,
1006- inet_ntoa(cp->Address));
1007+ Inet_NtoA(&cp->Address));
1008 }
1009
1010
1011@@ -348,7 +419,7 @@
1012 RCreader(CHANNEL *cp)
1013 {
1014 int fd;
1015- struct sockaddr_in remote;
1016+ INADDR remote;
1017 ARGTYPE size;
1018 register int i;
1019 register REMOTEHOST *rp;
1020@@ -362,9 +433,9 @@
1021 CHANNEL tempchan;
1022 char buff[SMBUF];
1023
1024- if (cp != RCchan) {
1025- syslog(L_ERROR, "%s internal RCreader wrong channel 0x%x not 0x%x",
1026- LogName, cp, RCchan);
1027+ if (cp != RCchan[0] && cp != RCchan[1]) {
1028+ syslog(L_ERROR, "%s internal RCreader wrong channel 0x%x",
1029+ LogName, cp);
1030 return;
1031 }
1032
1033@@ -425,7 +496,7 @@
1034 ** Finally, if neither rejection happened, add the entry to the
1035 ** table, and continue on as a normal connect.
1036 */
1037- tempchan.Address.s_addr = remote.sin_addr.s_addr;
1038+ memcpy(&tempchan.Address, &remote, sizeof(remote));
1039 reject_message = NULL;
1040 if (RemoteTimer != 0) {
1041 now = time(NULL);
1042@@ -439,7 +510,7 @@
1043 i = (i + 1) & (REMOTETABLESIZE - 1);
1044 continue;
1045 }
1046- if (remotetable[i].Address.s_addr == remote.sin_addr.s_addr)
1047+ if (RCaddressmatch(&remotetable[i].Address, &remote))
1048 found++;
1049 i = (i + 1) & (REMOTETABLESIZE - 1);
1050 }
1051@@ -453,7 +524,7 @@
1052 }
1053 else {
1054 i = (remotefirst + remotecount) & (REMOTETABLESIZE - 1);
1055- remotetable[i].Address = remote.sin_addr;
1056+ memcpy(&remotetable[i].Address, &remote, sizeof(remote));
1057 remotetable[i].Expires = now + RemoteTimer;
1058 remotecount++;
1059 }
1060@@ -466,7 +537,7 @@
1061 if (reject_message) {
1062 new = CHANcreate(fd, CTreject, CSwritegoodbye, RCrejectreader,
1063 RCrejectwritedone);
1064- new->Address.s_addr = remote.sin_addr.s_addr;
1065+ memcpy(&new->Address, &remote, sizeof(remote));
1066 new->Rejected = reject_val;
1067 RCHANremove(new);
1068 WCHANset(new, reject_message, (int)strlen(reject_message));
1069@@ -477,7 +548,7 @@
1070
1071 /* See if it's one of our servers. */
1072 for (name = NULL, rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
1073- if (rp->Address.s_addr == remote.sin_addr.s_addr) {
1074+ if (RCaddressmatch(&rp->Address, &remote)) {
1075 name = rp->Name;
1076 break;
1077 }
1078@@ -491,7 +562,7 @@
1079 new->NoResendId = rp->NoResendId;
1080 new->MaxCnx = rp->MaxCnx;
1081 new->HoldTime = rp->HoldTime;
1082- new->Address.s_addr = remote.sin_addr.s_addr;
1083+ memcpy(&new->Address, &remote, sizeof(remote));
1084 if (new->MaxCnx > 0 && new->HoldTime == 0) {
1085 CHANsetActiveCnx(new);
1086 if((new->ActiveCnx > new->MaxCnx) && (new->fd > 0)) {
1087@@ -519,7 +590,7 @@
1088 reject_message = NNTP_ACCESS;
1089 new = CHANcreate(fd, CTreject, CSwritegoodbye, RCrejectreader,
1090 RCrejectwritedone);
1091- new->Address.s_addr = remote.sin_addr.s_addr;
1092+ memcpy(&new->Address, &remote, sizeof(remote));
1093 new->Rejected = reject_val;
1094 RCHANremove(new);
1095 WCHANset(new, reject_message, (int)strlen(reject_message));
1096@@ -529,9 +600,9 @@
1097 }
1098
1099 if (new != NULL) {
1100- new->Address.s_addr = remote.sin_addr.s_addr;
1101+ memcpy(&new->Address, &remote, sizeof(remote));
1102 syslog(L_NOTICE, "%s connected %d streaming %s",
1103- name ? name : inet_ntoa(new->Address), new->fd,
1104+ name ? name : Inet_NtoA(&new->Address), new->fd,
1105 (!StreamingOff && new->Streaming) ? "allowed" : "not allowed");
1106 }
1107 }
1108@@ -681,7 +752,9 @@
1109 register REMOTEHOST peer_params;
1110 register REMOTEHOST default_params;
1111 BOOL flag, bit, toolong;
1112-
1113+#if defined(HAVE_GETADDRINFO)
1114+ struct addrinfo hints, *res, *res0;
1115+#endif /* defined(HAVE_GETADDRINFO) */
1116
1117 *RCbuff = '\0';
1118 if (*list) {
1119@@ -880,9 +953,51 @@
1120 RENEW (*list, REMOTEHOST, *count);
1121 rp = *list + j;
1122
1123+#if defined(HAVE_GETADDRINFO)
1124+ (void)memset((POINTER)&hints, 0, sizeof hints);
1125+ hints.ai_family = PF_UNSPEC;
1126+ hints.ai_socktype = SOCK_STREAM;
1127+ if (getaddrinfo(*q, NULL, &hints, &res0) != 0) {
1128+ syslog(L_ERROR, "%s cant getaddrinfo %s %m", LogName, *q);
1129+ /* decrement *count, since we never got to add this record. */
1130+ (*count)--;
1131+ continue;
1132+ }
1133+ /* Count the addresses and see if we have to grow the list */
1134+ i = 0;
1135+ for (res = res0; res != NULL; res = res->ai_next)
1136+ i++;
1137+ /* Grow the array */
1138+ j = rp - *list;
1139+ *count += i - 1;
1140+ RENEW(*list, REMOTEHOST, *count);
1141+ rp = *list + j;
1142+
1143+ /* Add all hosts */
1144+ for (res = res0; res != NULL; res = res->ai_next) {
1145+ (void)memcpy(&rp->Address, res->ai_addr, res->ai_addrlen);
1146+ rp->Name = COPY (*q);
1147+ rp->Label = COPY (peer_params.Label);
1148+ rp->Email = COPY(peer_params.Email);
1149+ rp->Comment = COPY(peer_params.Comment);
1150+ rp->Streaming = peer_params.Streaming;
1151+ rp->Skip = peer_params.Skip;
1152+ rp->NoResendId = peer_params.NoResendId;
1153+ rp->Password = COPY(peer_params.Password);
1154+ rp->Patterns = peer_params.Pattern != NULL ?
1155+ RCCommaSplit(COPY(peer_params.Pattern)) : NULL;
1156+ rp->MaxCnx = peer_params.MaxCnx;
1157+ rp->HoldTime = peer_params.HoldTime;
1158+ rp++;
1159+ }
1160+ freeaddrinfo(res0);
1161+#else /* defined(HAVE_GETADDRINFO) */
1162 /* Was host specified as a dotted quad ? */
1163- if ((rp->Address.s_addr = inet_addr(*q)) != INADDR_NONE) {
1164+ if (inet_addr(*q) != INADDR_NONE) {
1165+ u_long addr;
1166 /* syslog(LOG_NOTICE, "think it's a dotquad: %s", *q); */
1167+ addr = inet_addr(*q);
1168+ COPYADDR(&rp->Address, (char *)&addr);
1169 rp->Name = COPY (*q);
1170 rp->Label = COPY (peer_params.Label);
1171 rp->Password = COPY(peer_params.Password);
1172@@ -920,7 +1035,9 @@
1173 int t = 0;
1174 /* Strange DNS ? try this.. */
1175 for (r = hp->h_aliases; *r != 0; r++) {
1176- if (inet_addr(*r) == INADDR_NONE) /* IP address ? */
1177+ u_long addr;
1178+ addr = inet_addr(*r);
1179+ if (addr == INADDR_NONE) /* IP address ? */
1180 continue;
1181 (*count)++;
1182 /* Grow the array */
1183@@ -928,7 +1045,7 @@
1184 RENEW (*list, REMOTEHOST, *count);
1185 rp = *list + j;
1186
1187- rp->Address.s_addr = inet_addr(*r);
1188+ COPYADDR(&rp->Address, (char *)&addr);
1189 rp->Name = COPY (*q);
1190 rp->Label = COPY (peer_params.Label);
1191 rp->Email = COPY(peer_params.Email);
1192@@ -1003,6 +1120,7 @@
1193 rp->HoldTime = peer_params.HoldTime;
1194 rp++;
1195 #endif /* defined(h_addr) */
1196+#endif /* defined(HAVE_GETADDRINFO) */
1197 }
1198 DISPOSE(r[0]);
1199 DISPOSE(r);
1200@@ -1496,9 +1614,9 @@
1201 register int i;
1202
1203 for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
1204- if (cp->Address.s_addr == rp->Address.s_addr)
1205+ if (RCaddressmatch(&cp->Address, &rp->Address))
1206 return rp->Name;
1207- (void)strcpy(buff, inet_ntoa(cp->Address));
1208+ (void)strcpy(buff, Inet_NtoA(&cp->Address));
1209 return buff;
1210 }
1211
1212@@ -1511,7 +1629,7 @@
1213 int i;
1214
1215 for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++) {
1216- if (cp->Address.s_addr == rp->Address.s_addr)
1217+ if (RCaddressmatch(&cp->Address, &rp->Address))
1218 return rp->Label;
1219 }
1220 return NULL;
1221@@ -1530,7 +1648,7 @@
1222 int i;
1223
1224 for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++) {
1225- if (cp->Address.s_addr != rp->Address.s_addr)
1226+ if (RCaddressmatch(&cp->Address, &rp->Address))
1227 continue;
1228 if (rp->Patterns == NULL)
1229 break;
1230@@ -1559,12 +1677,53 @@
1231 register int i;
1232 {
1233 struct sockaddr_in server;
1234+#if defined(INET6)
1235+ struct sockaddr_in6 server6;
1236+#endif /* defined(INET6) */
1237 #if defined(SO_REUSEADDR)
1238 int on;
1239 #endif /* defined(SO_REUSEADDR) */
1240+ int idx;
1241
1242 if (i < 0) {
1243 /* Create a socket and name it. */
1244+#if defined(INET6)
1245+ if (RCchan[0] != NULL && innconf->listenonipv6) {
1246+ if ((i = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {
1247+ syslog(L_FATAL, "%s cant ipv6 socket RCreader %m", LogName);
1248+ exit(1);
1249+ }
1250+#if defined(SO_REUSEADDR)
1251+ on = 1;
1252+ if (setsockopt(i, SOL_SOCKET, SO_REUSEADDR, (caddr_t)&on,
1253+ sizeof on) < 0)
1254+ syslog(L_ERROR, "%s cant setsockopt RCreader %m", LogName);
1255+#endif /* defined(SO_REUSEADDR) */
1256+ (void)memset((POINTER)&server6, 0, sizeof server6);
1257+ server6.sin6_port = htons(innconf->port);
1258+ server6.sin6_family = AF_INET6;
1259+ server6.sin6_addr = in6addr_any;
1260+#if defined(HAVE_SOCKADDR_LEN)
1261+ server6.sin6_len = sizeof server6;
1262+#endif /* defined(HAVE_SOCKADDR_LEN) */
1263+ if (innconf->bindipv6address) {
1264+ if (inet_pton(AF_INET6, innconf->bindipv6address,
1265+ &server6.sin6_addr) < 1) {
1266+ syslog(L_FATAL, "unable to determine bind ipv6 (%s) %m",
1267+ innconf->bindipv6address);
1268+ exit(1);
1269+ }
1270+ }
1271+ if (bind(i, (struct sockaddr *)&server6, sizeof server6) < 0) {
1272+ syslog(L_FATAL, "%s cant bind RCreader %m", LogName);
1273+ exit(1);
1274+ }
1275+ } else if (RCchan[0] != NULL) {
1276+ /* If "listenonipv6" not set, and one socket has already been
1277+ created, no need to create more socket */
1278+ return;
1279+ }
1280+#endif /* defined(INET6) */
1281 if ((i = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
1282 syslog(L_FATAL, "%s cant socket RCreader %m", LogName);
1283 exit(1);
1284@@ -1599,9 +1758,15 @@
1285 syslog(L_FATAL, "%s cant listen RCreader %m", LogName);
1286 exit(1);
1287 }
1288- RCchan = CHANcreate(i, CTremconn, CSwaiting, RCreader, RCwritedone);
1289- syslog(L_NOTICE, "%s rcsetup %s", LogName, CHANname(RCchan));
1290- RCHANadd(RCchan);
1291+
1292+ if (RCchan[0] == NULL)
1293+ idx = 0;
1294+ else
1295+ idx = 1;
1296+ RCchan[idx] = CHANcreate(i, CTremconn, CSwaiting, RCreader, RCwritedone);
1297+
1298+ syslog(L_NOTICE, "%s rcsetup %s", LogName, CHANname(RCchan[idx]));
1299+ RCHANadd(RCchan[idx]);
1300
1301 /* Get the list of hosts we handle. */
1302 RCreadlist();
1303@@ -1617,8 +1782,11 @@
1304 register REMOTEHOST *rp;
1305 register int i;
1306
1307- CHANclose(RCchan, CHANname(RCchan));
1308- RCchan = NULL;
1309+ for (i = 0; i < 2; i++)
1310+ if (RCchan[i] != NULL) {
1311+ CHANclose(RCchan[i], CHANname(RCchan[i]));
1312+ RCchan[i] = NULL;
1313+ }
1314 if (RCpeerlist) {
1315 for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++) {
1316 DISPOSE(rp->Name);
1317diff -Nur inn-2.3.2.orig/innd/status.c inn-2.3.2/innd/status.c
1318--- inn-2.3.2.orig/innd/status.c Thu May 3 22:27:32 2001
1319+++ inn-2.3.2/innd/status.c Tue Jun 19 16:06:41 2001
1320@@ -16,7 +16,7 @@
1321
1322 typedef struct _STATUS {
1323 char name[SMBUF];
1324- char ip_addr[15];
1325+ char ip_addr[64];
1326 BOOL can_stream;
1327 unsigned short activeCxn;
1328 unsigned short sleepingCxns;
1329@@ -134,7 +134,8 @@
1330 tmp = head = NULL;
1331 for (i = 0; (cp = CHANiter(&i, CTnntp)) != NULL; ) {
1332 j = 0;
1333- strcpy(TempString, cp->Address.s_addr == 0 ? "localhost" : RChostname(cp));
1334+ strcpy(TempString, cp->Address.ss_family == 0 ? "localhost" :
1335+ RChostname(cp));
1336 for (status = head ; status != NULL ; status = status->next) {
1337 if (strcmp(TempString, status->name) == 0)
1338 break;
1339@@ -143,7 +144,7 @@
1340 status = NEW(STATUS, 1);
1341 peers++; /* a new peer */
1342 strcpy (status->name, TempString); /* name */
1343- strcpy (status->ip_addr, inet_ntoa(cp->Address)); /* ip address */
1344+ strcpy (status->ip_addr, Inet_NtoA(&cp->Address)); /* ip address */
1345 status->can_stream = cp->Streaming;
1346 status->seconds = status->Size = status->DuplicateSize = 0;
1347 status->Ihave = status->Ihave_Duplicate =
1348diff -Nur inn-2.3.2.orig/innfeed/connection.c inn-2.3.2/innfeed/connection.c
1349--- inn-2.3.2.orig/innfeed/connection.c Thu May 3 22:27:32 2001
1350+++ inn-2.3.2/innfeed/connection.c Tue Jun 19 16:06:41 2001
1351@@ -131,6 +131,12 @@
1352 #include "host.h"
1353 #include "msgs.h"
1354
1355+#ifndef HAVE_SOCKADDR_STORAGE
1356+#include "sockaddr_storage.h"
1357+#endif
1358+
1359+#include "sa_len.h"
1360+
1361 #if defined (NDEBUG)
1362 #define VALIDATE_CONNECTION(x) ((void) 0)
1363 #else
1364@@ -263,7 +269,8 @@
1365 static u_int gCxnCount = 0 ;
1366 static u_int max_reconnect_period = MAX_RECON_PER ;
1367 static u_int init_reconnect_period = INIT_RECON_PER ;
1368-static u_long bind_addr = INADDR_ANY;
1369+static struct sockaddr_storage bind_addr;
1370+static int bind_addr_flag = 0;
1371 #if 0
1372 static bool inited = false ;
1373 #endif
1374@@ -406,17 +413,33 @@
1375 iv = INIT_RECON_PER ;
1376 init_reconnect_period = (u_int) iv ;
1377
1378+ memset (&bind_addr, 0, sizeof(bind_addr));
1379 if (getString (topScope,"bindaddress",&sv,NO_INHERIT))
1380 {
1381- bind_addr = inet_addr(sv);
1382- if (bind_addr == INADDR_NONE)
1383- {
1384+ if (inet_addr(sv) != INADDR_NONE) {
1385+ bind_addr.ss_family = AF_INET;
1386+ ((struct sockaddr_in *)&bind_addr)->sin_addr.s_addr = inet_addr(sv);
1387+#ifdef HAVE_SOCKADDR_LEN
1388+ bind_addr.ss_len = sizeof(struct sockaddr_in);
1389+#endif
1390+ bind_addr_flag = 1;
1391+ }
1392+#ifdef INET6
1393+ else if (inet_pton(AF_INET6, sv,
1394+ &((struct sockaddr_in6 *)&bind_addr)->sin6_addr) == 1) {
1395+ bind_addr.ss_family = AF_INET6;
1396+#ifdef HAVE_SOCKADDR_LEN
1397+ bind_addr.ss_len = sizeof(struct sockaddr_in6);
1398+#endif
1399+ bind_addr_flag = 1;
1400+ }
1401+#endif /* INET6 */
1402+ else {
1403 logOrPrint (LOG_ERR,fp,"innfeed unable to determine bind ip") ;
1404- bind_addr = INADDR_ANY;
1405+ bind_addr_flag = 0;
1406 }
1407- }
1408- else
1409- bind_addr = INADDR_ANY;
1410+ } else
1411+ bind_addr_flag = 0;
1412
1413 return rval ;
1414 }
1415@@ -533,9 +556,9 @@
1416 */
1417 bool cxnConnect (Connection cxn)
1418 {
1419- struct sockaddr_in cxnAddr, cxnSelf ;
1420+ struct sockaddr_storage cxnAddr, cxnSelf ;
1421 int fd, rval ;
1422- struct in_addr *addr = NULL;
1423+ struct sockaddr_storage *addr = NULL;
1424 const char *peerName = hostPeerName (cxn->myHost) ;
1425
1426 ASSERT (cxn->myEp == NULL) ;
1427@@ -566,12 +589,15 @@
1428 return false ;
1429 }
1430
1431- memset (&cxnAddr, 0, sizeof (cxnAddr)) ;
1432- cxnAddr.sin_family = AF_INET ;
1433- cxnAddr.sin_port = htons(cxn->port) ;
1434- cxnAddr.sin_addr.s_addr = addr->s_addr ;
1435+ memcpy (&cxnAddr, addr, sizeof(cxnAddr));
1436+ if (cxnAddr.ss_family == AF_INET)
1437+ ((struct sockaddr_in *)&cxnAddr)->sin_port = htons(cxn->port);
1438+#ifdef INET6
1439+ else if (cxnAddr.ss_family == AF_INET6)
1440+ ((struct sockaddr_in6 *)&cxnAddr)->sin6_port = htons(cxn->port);
1441+#endif
1442
1443- if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
1444+ if ((fd = socket (cxnAddr.ss_family, SOCK_STREAM, 0)) < 0)
1445 {
1446 syslog (LOG_ERR, SOCKET_CREATE_ERROR, peerName, cxn->ident) ;
1447 d_printf (1,"Can't get a socket: %m\n") ;
1448@@ -582,13 +608,15 @@
1449 }
1450
1451 /* bind to a specified virtual host */
1452- if (bind_addr != INADDR_ANY)
1453+ if (bind_addr_flag == 1)
1454 {
1455- memset (&cxnSelf, 0, sizeof (cxnSelf)) ;
1456- cxnSelf.sin_family = AF_INET ;
1457- cxnSelf.sin_port = 0 ;
1458- cxnSelf.sin_addr.s_addr = bind_addr;
1459- if (bind (fd, (struct sockaddr *) &cxnSelf,sizeof (cxnSelf)) < 0)
1460+ (void)memcpy (&cxnSelf, &bind_addr, sizeof(cxnSelf));
1461+#ifdef HAVE_SOCKADDR_LEN
1462+ if (bind (fd, (struct sockaddr *) &cxnSelf, cxnSelf.ss_len) < 0)
1463+#else
1464+ if (bind (fd, (struct sockaddr *) &cxnSelf,
1465+ SA_LEN((struct sockaddr *) &cxnSelf)) < 0)
1466+#endif
1467 {
1468 syslog (LOG_ERR,"bind: %m") ;
1469
1470@@ -620,7 +648,12 @@
1471 return false ;
1472 }
1473
1474- rval = connect (fd, (struct sockaddr *) &cxnAddr, sizeof (cxnAddr)) ;
1475+#ifdef HAVE_SOCKADDR_LEN
1476+ rval = connect (fd, (struct sockaddr *) &cxnAddr, cxnAddr.ss_len);
1477+#else
1478+ rval = connect (fd, (struct sockaddr *) &cxnAddr,
1479+ SA_LEN((struct sockaddr *) &cxnAddr));
1480+#endif
1481 if (rval < 0 && errno != EINPROGRESS)
1482 {
1483 syslog (LOG_ERR, CONNECT_ERROR, peerName, cxn->ident) ;
1484diff -Nur inn-2.3.2.orig/innfeed/endpoint.c inn-2.3.2/innfeed/endpoint.c
1485--- inn-2.3.2.orig/innfeed/endpoint.c Thu May 3 22:27:32 2001
1486+++ inn-2.3.2/innfeed/endpoint.c Tue Jun 19 16:06:41 2001
1487@@ -1628,6 +1628,11 @@
1488 EndPoint accConn ;
1489 struct sockaddr_in accNet ;
1490 int accFd = socket (AF_INET,SOCK_STREAM,0) ;
1491+#ifdef INET6
1492+ EndPoint accConn6;
1493+ struct sockaddr_in6 accNet6;
1494+ int accFd6 = socket (AF_INET6,SOCK_STREAM,0);
1495+#endif
1496 u_short port = atoi (argc > 1 ? argv[1] : "10000") ;
1497 time_t t = theTime() ;
1498
1499@@ -1663,6 +1668,26 @@
1500 accConn = newEndPoint (accFd) ;
1501
1502 prepareRead (accConn,NULL,newConn,NULL,0) ;
1503+
1504+#ifdef INET6
1505+ ASSERT(accFd6 >= 0);
1506+ memset (&accNet6,0,sizeof (accNet6));
1507+ accNet6.sin6_family = AF_INET6;
1508+ accNet6.sin6_addr = in6addr_any;
1509+ accNet6.sin6_port = htons (port);
1510+
1511+ if (bind (accFd6, (struct sockaddr_in6 *) &accNet6, sizeof (accNet6)) < 0)
1512+ {
1513+ perror ("bind: %m") ;
1514+ exit (1) ;
1515+ }
1516+
1517+ listen (accFd6,5);
1518+
1519+ accCon6 = newEndPoint (accFd6);
1520+
1521+ prepareRead (accCon6,NULL,newConn,NULL,0) ;
1522+#endif
1523
1524 prepareSleep (Timeout,5,(void *) 0x10) ;
1525
1526diff -Nur inn-2.3.2.orig/innfeed/host.c inn-2.3.2/innfeed/host.c
1527--- inn-2.3.2.orig/innfeed/host.c Thu May 3 22:27:32 2001
1528+++ inn-2.3.2/innfeed/host.c Tue Jun 19 16:06:41 2001
1529@@ -40,6 +40,8 @@
1530 #include "config.h"
1531 #include "clibrary.h"
1532
1533+#include <sys/types.h>
1534+#include <sys/socket.h>
1535 #include <netinet/in.h>
1536 #include <arpa/inet.h>
1537 #include <assert.h>
1538@@ -67,6 +69,10 @@
1539 #include "msgs.h"
1540 #include "tape.h"
1541
1542+#ifndef HAVE_SOCKADDR_STORAGE
1543+#include "sockaddr_storage.h"
1544+#endif
1545+
1546 #define REQ 1
1547 #define NOTREQ 0
1548 #define NOTREQNOADD 2
1549@@ -1128,22 +1134,63 @@
1550 return nh ;
1551 }
1552
1553-struct in_addr *hostIpAddr (Host host)
1554+struct sockaddr_storage *hostIpAddr (Host host)
1555 {
1556 int i ;
1557 char *p ;
1558 char **newIpAddrs = NULL;
1559- struct in_addr ipAddr, *returnAddr ;
1560+ struct sockaddr_storage ipAddr, *returnAddr;
1561 struct hostent *hostEnt ;
1562+#ifdef HAVE_GETADDRINFO
1563+ struct addrinfo hints, *res, *pr;
1564+#endif
1565 char *msgstr[SMBUF] ;
1566
1567 ASSERT(host->params != NULL);
1568+ returnAddr = NULL;
1569
1570 /* check to see if need to look up the host name */
1571 if (host->nextIpLookup <= theTime())
1572 {
1573+#ifdef HAVE_GETADDRINFO
1574+ memset(&hints, 0, sizeof(hints));
1575+ hints.ai_family = PF_UNSPEC;
1576+ hints.ai_socktype = SOCK_STREAM;
1577+ i = getaddrinfo(host->params->ipName, NULL, &hints, &res);
1578+ if (i != 0)
1579+ {
1580+ syslog (LOG_ERR, HOST_RESOLV_ERROR, host->params->peerName,
1581+ host->params->ipName, gai_strerror(i));
1582+ }
1583+ else
1584+ {
1585+ /* figure number of pointers that need space */
1586+ i = 0;
1587+ for (pr = res; pr != NULL; pr = pr->ai_next, i++)
1588+ ;
1589+ i++;
1590+
1591+ newIpAddrs =
1592+ (char **) MALLOC ( (i * sizeof(char *)) +
1593+ ( (i - 1) * sizeof(struct sockaddr_storage)) ) ;
1594+ ASSERT (newIpAddrs != NULL) ;
1595+
1596+ p = (char *)&newIpAddrs [ i ] ;
1597+ i = 0;
1598+ for (pr = res; pr != NULL; pr = pr->ai_next)
1599+ {
1600+ newIpAddrs[i] = p;
1601+ memcpy (p, pr->ai_addr, pr->ai_addrlen);
1602+ p += sizeof(struct sockaddr_storage);
1603+ i++;
1604+ }
1605+ newIpAddrs[i] = NULL;
1606+ freeaddrinfo(res);
1607+ }
1608+#else
1609 /* see if the ipName we're given is a dotted quad */
1610- if ( !inet_aton (host->params->ipName,&ipAddr) )
1611+ if ( !inet_aton (host->params->ipName,
1612+ &((struct sockaddr_in *)&ipAddr)->sin_addr) )
1613 {
1614 if ((hostEnt = gethostbyname (host->params->ipName)) == NULL)
1615 {
1616@@ -1159,7 +1206,8 @@
1617
1618 newIpAddrs =
1619 (char **) MALLOC ( (i * sizeof(char *)) +
1620- ( (i - 1) * hostEnt->h_length) ) ;
1621+ ( (i - 1) *
1622+ sizeof(struct sockaddr_storage) ) );
1623 ASSERT (newIpAddrs != NULL) ;
1624
1625 /* copy the addresses from gethostbyname() static space */
1626@@ -1168,7 +1216,13 @@
1627 for (i = 0 ; hostEnt->h_addr_list[i] ; i++)
1628 {
1629 newIpAddrs[i] = p;
1630- memcpy (p, hostEnt->h_addr_list[i], hostEnt->h_length) ;
1631+ memcpy (&((struct sockaddr_in *)p)->sin_addr,
1632+ hostEnt->h_addr_list[i], hostEnt->h_length) ;
1633+ ((struct sockaddr_in *)p)->sin_family = AF_INET;
1634+#ifdef HAVE_SOCKADDR_LEN
1635+ ((struct sockaddr_in *)p)->sin_len =
1636+ sizeof(struct sockaddr_in);
1637+#endif
1638 p += hostEnt->h_length ;
1639 }
1640 newIpAddrs[i] = NULL ;
1641@@ -1181,9 +1235,13 @@
1642 p = (char *)&newIpAddrs [ 2 ];
1643 newIpAddrs[0] = p;
1644 memcpy (p, (char *)&ipAddr, sizeof(ipAddr)) ;
1645+ ((struct sockaddr_in *)p)->sin_family = AF_INET;
1646+#ifdef HAVE_SOCKADDR_LEN
1647+ ((struct sockaddr_in *)p)->sin_len = sizeof(struct sockaddr_in);
1648+#endif
1649 newIpAddrs[1] = NULL;
1650 }
1651-
1652+#endif /* HAVE_GETADDRINFO */
1653 if (newIpAddrs)
1654 {
1655 if (host->ipAddrs)
1656@@ -1201,7 +1259,7 @@
1657
1658 if (host->ipAddrs)
1659 {
1660- returnAddr = (struct in_addr *)(host->nextIpAddr[0]) ;
1661+ returnAddr = (struct sockaddr_storage *)(host->nextIpAddr[0]) ;
1662 if (*(++host->nextIpAddr) == NULL)
1663 host->nextIpAddr = host->ipAddrs ;
1664 }
1665diff -Nur inn-2.3.2.orig/innfeed/host.h inn-2.3.2/innfeed/host.h
1666--- inn-2.3.2.orig/innfeed/host.h Thu May 3 22:27:32 2001
1667+++ inn-2.3.2/innfeed/host.h Tue Jun 19 16:06:41 2001
1668@@ -105,7 +105,7 @@
1669 void hostSendArticle (Host host, Article article) ;
1670
1671 /* return an IP address for the host */
1672-struct in_addr *hostIpAddr (Host host) ;
1673+struct sockaddr_storage *hostIpAddr (Host host) ;
1674
1675 /*
1676 * Functions used by the Connection to indicate Connection state.
03da3507
JB
1677diff -Nur inn-2.3.3.orig/lib/Makefile inn-2.3.3/lib/Makefile
1678--- inn-2.3.3.orig/lib/Makefile Thu May 3 22:27:32 2001
1679+++ inn-2.3.3/lib/Makefile Tue Jun 19 16:06:41 2001
2aec8557
JB
1680@@ -16,7 +16,7 @@
1681 md5.c nonblocking.c parsedate.c perl.c qio.c radix32.c readin.c \
1682 remopen.c reservedfd.c resource.c rwlock.c sendarticle.c \
1683 sendpass.c tempname.c waitnb.c wildmat.c version.c xfopena.c \
03da3507
JB
1684- xmalloc.c xsignal.c xwrite.c
1685+ xmalloc.c xsignal.c xwrite.c inet_ntoa.c
2aec8557
JB
1686
1687 OBJECTS = $(MISSING_OBJ) \
1688 argparse.o checkart.o cleanfrom.o clientactive.o clientlib.o \
1689@@ -26,7 +26,7 @@
1690 md5.o nonblocking.o parsedate.o qio.o radix32.o readin.o \
1691 remopen.o reservedfd.o resource.o rwlock.o sendarticle.o \
1692 sendpass.o tempname.o waitnb.o wildmat.o version.o xfopena.o \
03da3507
JB
1693- xmalloc.o xsignal.o xwrite.o
1694+ xmalloc.o xsignal.o xwrite.o inet_ntoa.o
2aec8557
JB
1695
1696 LOBJECTS= $(OBJECTS:.o=.lo)
1697
1698diff -Nur inn-2.3.2.orig/lib/getconfig.c inn-2.3.2/lib/getconfig.c
1699--- inn-2.3.2.orig/lib/getconfig.c Thu May 3 22:27:32 2001
1700+++ inn-2.3.2/lib/getconfig.c Tue Jun 19 16:06:41 2001
1701@@ -267,6 +267,9 @@
1702 innconf->groupbaseexpiry = TRUE;
1703 innconf->wipcheck = 5;
1704 innconf->wipexpire = 10;
1705+ innconf->listenonipv6 = FALSE;
1706+ innconf->bindipv6address = NULL;
1707+ innconf->sourceipv6address = NULL;
1708 }
1709
1710 void ClearInnConf()
1711@@ -304,6 +307,9 @@
1712 if (innconf->backoff_db != NULL) DISPOSE(innconf->backoff_db);
1713 if (innconf->ovmethod != NULL) DISPOSE(innconf->ovmethod);
1714 if (innconf->ovgrouppat != NULL) DISPOSE(innconf->ovgrouppat);
1715+ if (innconf->bindipv6address != NULL) DISPOSE(innconf->bindipv6address);
1716+ if (innconf->sourceipv6address != NULL) DISPOSE(innconf->sourceipv6address);
1717+
1718 memset(ConfigBit, '\0', ConfigBitsize);
1719 }
1720
1721@@ -981,6 +987,21 @@
1722 TEST_CONFIG(CONF_VAR_WIPEXPIRE, bit);
1723 if (!bit) innconf->wipexpire = atoi(p);
1724 SET_CONFIG(CONF_VAR_WIPEXPIRE);
1725+ } else
1726+ if (EQ(ConfigBuff, _CONF_LISTENONIPV6)) {
1727+ TEST_CONFIG(CONF_VAR_LISTENONIPV6, bit);
1728+ if (!bit && boolval != -1) innconf->listenonipv6 = boolval;
1729+ SET_CONFIG(CONF_VAR_LISTENONIPV6);
1730+ } else
1731+ if (EQ(ConfigBuff, _CONF_BINDIPV6ADDRESS)) {
1732+ TEST_CONFIG(CONF_VAR_BINDIPV6ADDRESS, bit);
1733+ if (!bit) innconf->bindipv6address = COPY(p);
1734+ SET_CONFIG(CONF_VAR_BINDIPV6ADDRESS);
1735+ } else
1736+ if (EQ(ConfigBuff, _CONF_SOURCEIPV6ADDRESS)) {
1737+ TEST_CONFIG(CONF_VAR_SOURCEIPV6ADDRESS, bit);
1738+ if (!bit) innconf->sourceipv6address = COPY(p);
1739+ SET_CONFIG(CONF_VAR_SOURCEIPV6ADDRESS);
1740 }
1741 }
1742 (void)Fclose(F);
1743diff -Nur inn-2.3.2.orig/lib/inet_ntoa.c inn-2.3.2/lib/inet_ntoa.c
1744--- inn-2.3.2.orig/lib/inet_ntoa.c Thu May 3 22:27:32 2001
1745+++ inn-2.3.2/lib/inet_ntoa.c Tue Jun 19 16:06:41 2001
1746@@ -5,9 +5,17 @@
1747 */
1748 #include <stdio.h>
1749 #include <sys/types.h>
1750+#include <sys/socket.h>
1751+#include <netinet/in.h>
1752+#include <arpa/inet.h>
1753+#include <netdb.h>
1754 #include "configdata.h"
1755 #include "clibrary.h"
1756+#include "sockaddr_storage.h"
1757
1758+#if !defined(HAVE_SOCKADDR_LEN)
1759+#include "sa_len.h"
1760+#endif
1761
1762 /*
1763 * Copyright (c) 1983 Regents of the University of California.
1764@@ -40,7 +48,7 @@
1765 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1766 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1767 * SUCH DAMAGE.
1768- */
1769+ /
1770
1771 #if defined(LIBC_SCCS) && !defined(lint)
1772 static char sccsid[] = "@(#)inet_ntoa.c 5.6 (Berkeley) 2/24/91";
1773@@ -50,16 +58,45 @@
1774 * Convert network-format internet address
1775 * to base 256 d.d.d.d representation.
1776 */
1777-#include <netinet/in.h>
1778
1779 #define UC(c) (((int)c) & 0xFF)
1780
1781-char *inet_ntoa(struct in_addr in)
1782+char *Inet_NtoA(struct sockaddr_storage *ss)
1783 {
1784+#if !defined(INET6)
1785+#if defined(HAVE_INET_NTOA)
1786+ return inet_ntoa(((struct sockaddr_in *)ss)->sin_addr);
1787+#else
1788 static char buff[18];
1789 char *p;
1790
1791 p = (char *)&in;
1792 (void)sprintf(buff, "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
1793 return buff;
1794+#endif /* HAVE_INET_NTOA */
1795+#else /* INET6 */
1796+ static char buff[256];
1797+ struct sockaddr_in sin;
1798+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ss;
1799+
1800+ if (ss->ss_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) ) {
1801+ memcpy(&sin.sin_addr, sin6->sin6_addr.s6_addr+12,
1802+ sizeof(sin.sin_addr));
1803+ sin.sin_port = ((struct sockaddr_in6 *)ss)->sin6_port;
1804+ sin.sin_family = AF_INET;
1805+#if defined(HAVE_SOCKADDR_LEN)
1806+ sin.sin_len = sizeof(struct sockaddr_in);
1807+#endif
1808+ return inet_ntoa(sin.sin_addr);
1809+ }
1810+#if defined(HAVE_SOCKADDR_LEN)
1811+ getnameinfo((struct sockaddr *)ss, ss->ss_len, buff, sizeof(buff), NULL, 0,
1812+ NI_NUMERICHOST);
1813+#else
1814+ getnameinfo((struct sockaddr *)ss, SA_LEN((struct sockaddr *)ss), buff,
1815+ sizeof(buff), NULL, 0, NI_NUMERICHOST);
1816+#endif /* HAVE_SOCKADDR_IN */
1817+
1818+ return buff;
1819+#endif /* INET6 */
1820 }
1821diff -Nur inn-2.3.2.orig/lib/remopen.c inn-2.3.2/lib/remopen.c
1822--- inn-2.3.2.orig/lib/remopen.c Thu May 3 22:27:32 2001
1823+++ inn-2.3.2/lib/remopen.c Tue Jun 19 16:06:41 2001
1824@@ -40,13 +40,69 @@
1825 int j;
1826 int oerrno;
1827 FILE *F;
1828+#if defined(HAVE_GETADDRINFO)
1829+ struct addrinfo hints, *res, *addr;
1830+ char portbuf[16];
1831+ struct sockaddr_storage client;
1832+#else
1833 struct hostent *hp;
1834 struct hostent fakehp;
1835 struct in_addr quadaddr;
1836 struct sockaddr_in server, client;
1837+#endif /* defined(HAVE_GETADDRINFO) */
1838
1839 buff = errbuff ? errbuff : mybuff;
1840 *buff = '\0';
1841+
1842+#if defined(HAVE_GETADDRINFO)
1843+ (void)memset((POINTER)&hints, 0, sizeof hints);
1844+ hints.ai_family = PF_UNSPEC;
1845+ hints.ai_socktype = SOCK_STREAM;
1846+ sprintf(portbuf, "%d", port);
1847+ if (getaddrinfo(host, portbuf, &hints, &res) != 0)
1848+ return -1;
1849+
1850+ for (addr = res; addr; addr = addr->ai_next) {
1851+ /* Make a socket and try to connect */
1852+ if ((i = socket(addr->ai_family, SOCK_STREAM, 0)) < 0)
1853+ break;
1854+ (void)memset((POINTER)&client, 0, sizeof client);
1855+ if (addr->ai_family == AF_INET) {
1856+ if (innconf->sourceaddress &&
1857+ inet_pton(AF_INET, innconf->sourceaddress,
1858+ &((struct sockaddr_in *)&client)->sin_addr) < 1) {
1859+ freeaddrinfo(addr);
1860+ return -1;
1861+ }
1862+ ((struct sockaddr_in *)&client)->sin_family = AF_INET;
1863+ }
1864+#if defined(INET6)
1865+ if (addr->ai_family == AF_INET6) {
1866+ if (innconf->sourceipv6address &&
1867+ inet_pton(AF_INET6, innconf->sourceipv6address,
1868+ &((struct sockaddr_in6 *)&client)->sin6_addr) < 1) {
1869+ freeaddrinfo(addr);
1870+ return -1;
1871+ }
1872+ ((struct sockaddr_in6 *)&client)->sin6_family = AF_INET6;
1873+ }
1874+#endif /* defined(INET6) */
1875+ /* Bind to the source address we want. */
1876+ if (bind(i, (struct sockaddr *)&client, addr->ai_addrlen) < 0) {
1877+ oerrno = errno;
1878+ (void)close(i);
1879+ errno = oerrno;
1880+ continue;
1881+ }
1882+ if (connect(i, addr->ai_addr, addr->ai_addrlen) < 0) {
1883+ oerrno = errno;
1884+ (void)close(i);
1885+ errno = oerrno;
1886+ continue;
1887+ }
1888+
1889+#else /* HAVE_GETADDRINFO */
1890+
1891 quadaddr.s_addr = inet_addr(host);
1892 if (quadaddr.s_addr != (unsigned int) -1) {
1893 /* Host was specified as a dotted-quad internet address. Fill in
1894@@ -111,6 +167,7 @@
1895 errno = oerrno;
1896 continue;
1897 }
1898+#endif /* defined(HAVE_GETADDRINFO) */
1899
1900 /* Connected -- now make sure we can post. */
1901 if ((F = fdopen(i, "r")) == NULL) {
1902diff -Nur inn-2.3.2.orig/nnrpd/commands.c inn-2.3.2/nnrpd/commands.c
1903--- inn-2.3.2.orig/nnrpd/commands.c Thu May 3 22:27:32 2001
1904+++ inn-2.3.2/nnrpd/commands.c Tue Jun 19 16:06:41 2001
1905@@ -184,7 +184,22 @@
1906
1907 /*syslog(L_NOTICE, "%s (%ld) returned: %d %s %d\n", av[0], (long) pid, i, path, status);*/
1908 /* Split "host:permissions:user:pass:groups" into fields. */
1909- for (fields[0] = path, i = 0, p = path; *p; p++)
1910+ /* "host" field for IPv6 address must be enclosed with "[" and "]" */
1911+ if (path[0] == '[') {
1912+ fields[0] = path + 1;
1913+ i = 0;
1914+ p = path + 1;
1915+ while (*p && *p != ']')
1916+ p++;
1917+ *p = '\0';
1918+ p += 2; /* Skip next ':' */
1919+ fields[++i] = p;
1920+ } else {
1921+ fields[0] = path;
1922+ i = 0;
1923+ p = path;
1924+ }
1925+ for (; *p; p++)
1926 if (*p == ':') {
1927 *p = '\0';
1928 fields[++i] = p + 1;
1929@@ -753,7 +768,7 @@
1930 /* Acquire lock (this could be in RateLimit but that would
1931 * invoke the spaghetti factor).
1932 */
1933- if ((path = (char *) PostRecFilename(ClientIP,PERMuser)) == NULL) {
1934+ if ((path = (char *) PostRecFilename(&ClientIP,PERMuser)) == NULL) {
1935 Reply("%s\r\n", NNTP_CANTPOST);
1936 return;
1937 }
1938diff -Nur inn-2.3.2.orig/nnrpd/misc.c inn-2.3.2/nnrpd/misc.c
1939--- inn-2.3.2.orig/nnrpd/misc.c Thu May 3 22:27:32 2001
1940+++ inn-2.3.2/nnrpd/misc.c Tue Jun 19 16:06:41 2001
1941@@ -664,12 +664,12 @@
1942 */
1943 char
1944 *PostRecFilename(ip,user)
1945- unsigned long ip;
1946+ INADDR *ip;
1947 char *user;
1948 {
1949 static char buff[SPOOLNAMEBUFF];
1950 char dirbuff[SPOOLNAMEBUFF];
1951- unsigned char addr[4];
1952+ unsigned char addr[16];
1953 unsigned int i;
1954
1955 if (PERMaccessconf->backoff_auth) {
1956@@ -677,11 +677,27 @@
1957 return(buff);
1958 }
1959
1960- for (i=0; i<4; i++) {
1961- addr[i] = (unsigned char) (0x000000ff & (ip>>(i*8)));
1962+ switch (ip->ss_family) {
1963+ case AF_INET:
1964+ for (i=0; i<4; i++) {
1965+ addr[i] = (unsigned char)
1966+ (0x000000ff & (((struct sockaddr_in *)ip)->sin_addr.s_addr >>
1967+ (i*8)));
1968+ }
1969+ sprintf(dirbuff,"%s/%03d%03d/%03d",postrec_dir,addr[3],addr[2],addr[1]);
1970+ break;
1971+#ifdef INET6
1972+ case AF_INET6:
1973+ for (i=0;i<15;i++)
1974+ addr[i] = ((struct sockaddr_in6 *)ip)->sin6_addr.s6_addr[i];
1975+ sprintf(dirbuff,"%s/%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x/%02x%02x",
1976+ postrec_dir,addr[0],addr[1],addr[2],addr[3],addr[4],addr[5],
1977+ addr[6],addr[7],addr[8],addr[9],addr[10],addr[11],
1978+ addr[12],addr[13]);
1979+ break;
1980+#endif
1981 }
1982
1983- sprintf(dirbuff,"%s/%03d%03d/%03d",postrec_dir,addr[3],addr[2],addr[1]);
1984 if (!MakeDirectory(dirbuff,TRUE)) {
1985 syslog(L_ERROR,"%s Unable to create postrec directories '%s': %s",
1986 ClientHost,dirbuff,strerror(errno));
1987diff -Nur inn-2.3.2.orig/nnrpd/nnrpd.c inn-2.3.2/nnrpd/nnrpd.c
1988--- inn-2.3.2.orig/nnrpd/nnrpd.c Thu May 3 22:27:32 2001
1989+++ inn-2.3.2/nnrpd/nnrpd.c Tue Jun 19 16:12:24 2001
1990@@ -34,6 +34,8 @@
1991 int nnrpd_starttls_done = 0;
1992 #endif
1993
1994+#include "sa_len.h"
1995+
1996 #if defined(hpux) || defined(__hpux) || defined(_SCO_DS)
1997 extern int h_errno;
1998 #endif
1999@@ -362,11 +364,82 @@
2000 Address2Name(INADDR *ap, char *hostname, int i)
2001 {
2002 char *p;
2003+#if defined(INET6)
2004+ struct addrinfo hints, *res, *res0;
2005+ int len, ret;
2006+ struct sockaddr_in sin;
2007+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ap;
2008+#else
2009 struct hostent *hp;
2010 #if defined(h_addr)
2011 char **pp;
2012 #endif
2013+#endif /* defined (INET6) */
2014+
2015+#if defined(INET6)
2016+ /* Get the official hostname, store it away. (with new API) */
2017+ if (ap->ss_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) ) {
2018+ memcpy(&sin.sin_addr, sin6->sin6_addr.s6_addr+12,
2019+ sizeof(sin.sin_addr));
2020+ sin.sin_port = ((struct sockaddr_in6 *)ap)->sin6_port;
2021+ sin.sin_family = AF_INET;
2022+#if defined(HAVE_SOCKADDR_LEN)
2023+ sin.sin_len = sizeof(struct sockaddr_in);
2024+#endif /* defined(HAVE_SOCKADDR_LEN) */
2025+ ap = &sin;
2026+ }
2027
2028+#if defined(HAVE_SOCKADDR_LEN)
2029+ len = ap->ss_len;
2030+#else
2031+ len = SA_LEN((struct sockaddr *)ap);
2032+#endif /* defined(HAVE_SOCKADDR_LEN) */
2033+ ret = getnameinfo((struct sockaddr *)ap, len, hostname, i, NULL, 0,
2034+ NI_NAMEREQD);
2035+ if (ret != 0) {
2036+ HostErrorStr = gai_strerror(ret);
2037+ return FALSE;
2038+ }
2039+
2040+ /* Get the address for this host */
2041+ (void)memset(&hints, 0, sizeof(hints));
2042+ hints.ai_family = PF_UNSPEC;
2043+ hints.ai_flags = AI_CANONNAME;
2044+ hints.ai_socktype = SOCK_STREAM;
2045+ ret = getaddrinfo(hostname, NULL, &hints, &res0);
2046+ if (ret != 0) {
2047+ HostErrorStr = gai_strerror(ret);
2048+ return FALSE;
2049+ }
2050+
2051+ /* Make sure one of those addresses is the address we got. */
2052+ for (res = res0; res != NULL; res = res->ai_next) {
2053+ if (res->ai_addr->sa_family == ap->ss_family) {
2054+ if (ap->ss_family == AF_INET &&
2055+ memcmp(&((struct sockaddr_in *)ap)->sin_addr,
2056+ &((struct sockaddr_in *)res->ai_addr)->sin_addr,
2057+ sizeof(struct in_addr)) == 0)
2058+ break;
2059+ else if (ap->ss_family == AF_INET6 &&
2060+ memcmp(&((struct sockaddr_in6 *)ap)->sin6_addr,
2061+ &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
2062+ sizeof(struct in6_addr)) == 0)
2063+ break;
2064+ }
2065+ }
2066+ if (res == NULL) {
2067+ freeaddrinfo(res0);
2068+ return FALSE;
2069+ }
2070+ if (res->ai_canonname == NULL) { /* XXX */
2071+ freeaddrinfo(res0);
2072+ return FALSE;
2073+ }
2074+ (void)strncpy(hostname, res->ai_canonname, i);
2075+ freeaddrinfo(res0);
2076+
2077+#else /* defined(INET6) */
2078+
2079 /* Get the official hostname, store it away. */
2080 if ((hp = gethostbyaddr((char *)ap, sizeof *ap, AF_INET)) == NULL) {
2081 HostErrorStr = (char *)hstrerror(h_errno);
2082@@ -385,25 +458,27 @@
2083 #if defined(h_addr)
2084 /* We have many addresses */
2085 for (pp = hp->h_addr_list; *pp; pp++)
2086- if (memcmp((POINTER)&ap->s_addr, (POINTER)*pp,
2087- (SIZE_T)hp->h_length) == 0)
2088+ if (memcmp((POINTER)&(((struct sockaddr_in *)ap)->sin_addr.s_addr),
2089+ (POINTER)*pp, (SIZE_T)hp->h_length) == 0)
2090 break;
2091 if (*pp == NULL)
2092 return FALSE;
2093 #else
2094 /* We have one address. */
2095- if (memcmp((POINTER)&ap->s_addr, (POINTER)hp->h_addr,
2096- (SIZE_T)hp->h_length) != 0)
2097+ if (memcmp((POINTER)&(((struct sockaddr_in *)ap)->sin_addr.s_addr),
2098+ (POINTER)hp->h_addr, (SIZE_T)hp->h_length) != 0)
2099 return FALSE;
2100 #endif
2101
2102 /* Only needed for misconfigured YP/NIS systems. */
2103- if (ap->s_addr != INADDR_LOOPBACK && strchr(hostname, '.') == NULL
2104- && (p = innconf->domain) != NULL) {
2105+ if (((struct sockaddr_in *)ap)->sin_addr.s_addr != INADDR_LOOPBACK &&
2106+ strchr(hostname, '.') == NULL && (p = innconf->domain) != NULL) {
2107 (void)strcat(hostname, ".");
2108 (void)strcat(hostname, p);
2109 }
2110
2111+#endif /* defined(INET6) */
2112+
2113 /* Make all lowercase, for wildmat. */
2114 for (p = hostname; *p; p++)
2115 if (CTYPE(isupper, (int)*p))
2116@@ -418,7 +493,7 @@
2117 */
2118 STATIC void StartConnection()
2119 {
2120- struct sockaddr_in sin;
2121+ struct sockaddr_storage ss;
2122 ARGTYPE length;
2123 char buff[SMBUF];
2124 char *ClientAddr;
2125@@ -427,9 +502,9 @@
2126 static ACCESSGROUP *authconf;
2127
2128 /* Get the peer's name. */
2129- length = sizeof sin;
2130+ length = sizeof ss;
2131 ClientAddr = NULL;
2132- if (getpeername(STDIN, (struct sockaddr *)&sin, &length) < 0) {
2133+ if (getpeername(STDIN, (struct sockaddr *)&ss, &length) < 0) {
2134 if (!isatty(STDIN)) {
2135 syslog(L_TRACE, "%s cant getpeername %m", "?");
2136 (void)strcpy(ClientHost, "?"); /* so stats generation looks correct. */
2137@@ -437,14 +512,18 @@
2138 ExitWithStats(1, TRUE);
2139 }
2140 (void)strcpy(ClientHost, "stdin");
2141- ClientIP = 0L;
2142+ memset(&ClientIP, 0, sizeof(ClientIP));
2143 ServerHost[0] = '\0';
2144 }
2145
2146 else {
2147- if (sin.sin_family != AF_INET) {
2148+#if defined(INET6)
2149+ if (ss.ss_family != AF_INET && ss.ss_family != AF_INET6) {
2150+#else
2151+ if (ss.ss_family != AF_INET) {
2152+#endif /* defined(INET6) */
2153 syslog(L_ERROR, "%s bad_address_family %ld",
2154- "?", (long)sin.sin_family);
2155+ "?", (long)ss.ss_family);
2156 Printf("%d Bad address family. Goodbye.\r\n", NNTP_ACCESS_VAL);
2157 ExitWithStats(1, TRUE);
2158 }
2159@@ -452,8 +531,8 @@
2160 /* Get client's name. */
2161 #if defined(DO_NNRP_GETHOSTBYADDR)
2162 HostErrorStr = NULL;
2163- if (!Address2Name(&sin.sin_addr, ClientHost, (int)sizeof ClientHost)) {
2164- (void)strcpy(ClientHost, inet_ntoa(sin.sin_addr));
2165+ if (!Address2Name(&ss, ClientHost, (int)sizeof ClientHost)) {
2166+ (void)strcpy(ClientHost, Inet_NtoA(&ss));
2167 if (HostErrorStr == NULL) {
2168 syslog(L_NOTICE,
2169 "? cant gethostbyaddr %s %m -- using IP address for access",
2170@@ -464,32 +543,32 @@
2171 ClientHost, HostErrorStr);
2172 }
2173 ClientAddr = ClientHost;
2174- ClientIP = inet_addr(ClientHost);
2175+ (void)memcpy(&ClientIP, &ss, sizeof(ss));
2176 }
2177 else {
2178 ClientAddr = buff;
2179- (void)strcpy(buff, inet_ntoa(sin.sin_addr));
2180- ClientIP = inet_addr(buff);
2181+ (void)strcpy(buff, Inet_NtoA(&ss));
2182+ (void)memcpy(&ClientIP, &ss, sizeof(ss));
2183 }
2184 #else
2185- (void)strcpy(ClientHost, inet_ntoa(sin.sin_addr));
2186- ClientIP = inet_addr(ClientHost);
2187+ (void)strcpy(ClientHost, Inet_NtoA(&ss));
2188+ (void)memcpy(&ClientIP, &ss, sizeof(ss));
2189 #endif /* defined(DO_NNRP_GETHOSTBYADDR) */
2190- (void)strncpy(ClientIp, inet_ntoa(sin.sin_addr), sizeof(ClientIp));
2191- length = sizeof sin;
2192- if (getsockname(STDIN, (struct sockaddr *)&sin, &length) < 0) {
2193+ (void)strncpy(ClientIp, Inet_NtoA(&ss), sizeof(ClientIp));
2194+ length = sizeof ss;
2195+ if (getsockname(STDIN, (struct sockaddr *)&ss, &length) < 0) {
2196 syslog(L_NOTICE, "%s can't getsockname %m", ClientHost);
2197 Printf("%d Can't figure out where you connected to. Goodbye\r\n", NNTP_ACCESS_VAL);
2198 ExitWithStats(1, TRUE);
2199 }
2200 #ifdef DO_NNRP_GETHOSTBYADDR
2201 HostErrorStr = NULL;
2202- if (!Address2Name(&sin.sin_addr, ServerHost, sizeof(ServerHost))) {
2203- strcpy(ServerHost, inet_ntoa(sin.sin_addr));
2204+ if (!Address2Name(&ss, ServerHost, sizeof(ServerHost))) {
2205+ strcpy(ServerHost, Inet_NtoA(&ss));
2206 /* suppress error reason */
2207 }
2208 #else
2209- strcpy(ServerHost, inet_ntoa(sin.sin_addr));
2210+ strcpy(ServerHost, Inet_NtoA(&ss));
2211 #endif /* DO_NNRP_GETHOSTBYADDR */
2212 }
2213
2214@@ -741,9 +820,14 @@
2215 struct timeval tv;
2216 unsigned short ListenPort = NNTP_PORT;
2217 unsigned long ListenAddr = htonl(INADDR_ANY);
2218- int lfd, fd;
2219+ int lfd[2], fd, maxfd, tmpfd;
2220+ fd_set fds;
2221+#ifdef INET6
2222+ struct sockaddr_in6 ListenAddr6;
2223+#endif
2224 ARGTYPE clen;
2225- struct sockaddr_in ssa, csa;
2226+ struct sockaddr_in ssa;
2227+ struct sockaddr_storage csa;
2228 struct stat Sb;
2229 PID_T pid = -1;
2230 GID_T NewsGID;
2231@@ -777,17 +861,27 @@
2232
2233 openlog("nnrpd", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
2234
2235+#ifdef INET6
2236+ memset(&ListenAddr6, '\0', sizeof(ListenAddr6));
2237+#endif
2238+
2239 if (ReadInnConf() < 0) exit(1);
2240
2241 #ifdef HAVE_SSL
2242- while ((i = getopt(argc, argv, "b:Di:g:op:Rr:s:tS")) != EOF)
2243+ while ((i = getopt(argc, argv, "6:b:Di:g:op:Rr:s:tS")) != EOF)
2244 #else
2245- while ((i = getopt(argc, argv, "b:Di:g:op:Rr:s:t")) != EOF)
2246+ while ((i = getopt(argc, argv, "6:b:Di:g:op:Rr:s:t")) != EOF)
2247 #endif /* HAVE_SSL */
2248 switch (i) {
2249 default:
2250 Usage();
2251 /* NOTREACHED */
2252+ case '6': /* bind to a certain ipv6 address in
2253+ daemon mode */
2254+#ifdef INET6
2255+ inet_pton(AF_INET6, optarg, &ListenAddr6.sin6_addr);
2256+#endif
2257+ break;
2258 case 'b': /* bind to a certain address in
2259 daemon mode */
2260 ListenAddr = inet_addr(optarg);
2261@@ -849,12 +943,12 @@
2262 SPOOLlen = strlen(innconf->patharticles);
2263
2264 if (DaemonMode) {
2265- if ((lfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
2266+ if ((lfd[0] = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
2267 syslog(L_FATAL, "can't open socket (%m)");
2268 exit(1);
2269 }
2270
2271- if (setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) {
2272+ if (setsockopt(lfd[0], SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) {
2273 syslog(L_FATAL, "can't setsockopt(SO_REUSEADDR) (%m)");
2274 exit(1);
2275 }
2276@@ -864,11 +958,38 @@
2277 ssa.sin_addr.s_addr = ListenAddr;
2278 ssa.sin_port = htons(ListenPort);
2279
2280- if (bind(lfd, (struct sockaddr *) &ssa, sizeof(ssa)) < 0) {
2281+ if (bind(lfd[0], (struct sockaddr *) &ssa, sizeof(ssa)) < 0) {
2282 fprintf(stderr, "%s: can't bind (%s)\n", argv[0], strerror(errno));
2283 syslog(L_FATAL, "can't bind local address (%m)");
2284 exit(1);
2285 }
2286+
2287+ lfd[1] = -1;
2288+#ifdef INET6
2289+ if (innconf->bindipv6address) {
2290+ if ((lfd[1] = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {
2291+ syslog(L_FATAL, "can't open socket(%m)");
2292+ exit(1);
2293+ }
2294+ if (setsockopt(lfd[1], SOL_SOCKET, SO_REUSEADDR, (char *)&one,
2295+ sizeof(one)) < 0) {
2296+ syslog(L_FATAL, "can't setsockopt(SO_REUSEADDR) (%m)");
2297+ exit(1);
2298+ }
2299+ ListenAddr6.sin6_family = AF_INET6;
2300+ ListenAddr6.sin6_port = htons(ListenPort);
2301+#ifdef HAVE_SOCKADDR_LEN
2302+ ListenAddr6.sin6_len = sizeof(ListenAddr6);
2303+#endif
2304+ if (bind(lfd[1], (struct sockaddr *)&ListenAddr6,
2305+ sizeof(ListenAddr6)) < 0) {
2306+ fprintf(stderr, "%s: can't bind (%s)\n", argv[0],
2307+ strerror(errno));
2308+ syslog(L_FATAL, "can't bind local address (%m)");
2309+ exit(1);
2310+ }
2311+ }
2312+#endif /* INET6 */
2313
2314 /* If started as root, switch to news uid */
2315 if (getuid() == 0) {
2316@@ -953,11 +1074,33 @@
2317
2318 TITLEset("nnrpd: accepting connections");
2319
2320- listen(lfd, 128);
2321+ listen(lfd[0], 128);
2322+ maxfd = lfd[0];
2323+ if (lfd[1] != -1) {
2324+ if (maxfd < lfd[1])
2325+ lfd[1] = maxfd;
2326+ listen(lfd[1], 128);
2327+ }
2328+ maxfd++;
2329
2330 do {
2331+ FD_ZERO(&fds);
2332+ FD_SET(lfd[0], &fds);
2333+ if (lfd[1] != -1)
2334+ FD_SET(lfd[1], &fds);
2335+
2336+ if (select(maxfd, &fds, NULL, NULL, NULL) < 0) {
2337+ syslog(L_FATAL, "%s: select cause error (%m)");
2338+ exit(1);
2339+ }
2340+
2341 clen = sizeof(csa);
2342- fd = accept(lfd, (struct sockaddr *) &csa, &clen);
2343+ if (FD_ISSET(lfd[0], &fds))
2344+ tmpfd = lfd[0];
2345+ else if (lfd[1] != -1 && FD_ISSET(lfd[1], &fds))
2346+ tmpfd = lfd[1];
2347+ fd = accept(tmpfd, (struct sockaddr *) &csa, &clen);
2348+
2349 if (fd < 0)
2350 continue;
2351
2352@@ -980,7 +1123,9 @@
2353
2354 /* child process starts here */
2355 TITLEset("nnrpd: connected");
2356- close(lfd);
2357+ close(lfd[0]);
2358+ if (lfd[1] != -1)
2359+ close(lfd[1]);
2360 dup2(fd, 0);
2361 close(fd);
2362 dup2(0, 1);
2363diff -Nur inn-2.3.2.orig/nnrpd/nnrpd.h inn-2.3.2/nnrpd/nnrpd.h
2364--- inn-2.3.2.orig/nnrpd/nnrpd.h Thu May 3 22:27:32 2001
2365+++ inn-2.3.2/nnrpd/nnrpd.h Tue Jun 19 16:06:41 2001
2366@@ -31,6 +31,9 @@
2367 #include "paths.h"
2368 #include "qio.h"
2369
2370+#ifndef HAVE_SOCKADDR_STORAGE
2371+#include "sockaddr_storage.h"
2372+#endif
2373
2374 /*
2375 ** Maximum input line length, sigh.
2376@@ -43,7 +46,7 @@
2377 /*
2378 ** Some convenient shorthands.
2379 */
2380-typedef struct in_addr INADDR;
2381+typedef struct sockaddr_storage INADDR;
2382
2383
2384 /*
2385@@ -138,7 +141,7 @@
2386 EXTERN char ClientHost[SMBUF];
2387 EXTERN char ServerHost[SMBUF];
2388 EXTERN char Username[SMBUF];
2389-EXTERN char ClientIp[20];
2390+EXTERN char ClientIp[64];
2391 EXTERN char LogName[256] ;
2392 extern char *ACTIVETIMES;
2393 extern char *HISTORY;
2394@@ -176,7 +179,7 @@
2395 EXTERN long POSTrejected;
2396
2397 EXTERN BOOL BACKOFFenabled;
2398-EXTERN long ClientIP;
2399+EXTERN INADDR ClientIP;
2400 EXTERN char *VirtualPath;
2401 EXTERN int VirtualPathlen;
2402
2403diff -Nur inn-2.3.2.orig/nnrpd/perm.c inn-2.3.2/nnrpd/perm.c
2404--- inn-2.3.2.orig/nnrpd/perm.c Thu May 3 22:27:32 2001
2405+++ inn-2.3.2/nnrpd/perm.c Tue Jun 19 16:06:41 2001
2406@@ -1488,6 +1488,10 @@
2407 if (!ret && (p = strchr(pat, '/')) != (char *)NULL) {
2408 int bits, c;
2409 struct in_addr ia, net;
2410+#ifdef INET6
2411+ int n;
2412+ struct in6_addr ia6, net6;
2413+#endif
2414 unsigned int mask;
2415
2416 *p = '\0';
2417@@ -1505,6 +1509,23 @@
2418 if ((ia.s_addr & mask) == (net.s_addr & mask))
2419 ret = 1;
2420 }
2421+#ifdef INET6
2422+ if (inet_pton(AF_INET6, ClientIp, &ia6) == 1 &&
2423+ inet_pton(AF_INET6, pat, &net6) == 1) {
2424+ if (strchr(p+1, '.') == (char *)NULL) {
2425+ mask = atoi(p+1);
2426+ n = mask / 8;
2427+ bits = mask % 8;
2428+ for (c = 0; c < n; c++)
2429+ if (ia6.s6_addr[c] != net6.s6_addr[c])
2430+ break;
2431+ if (c == n &&
2432+ (ia6.s6_addr[c] & (0x00ff << (8 - bits))) ==
2433+ (net6.s6_addr[c] & (0x00ff << (8 - bits))))
2434+ ret = 1;
2435+ }
2436+ }
2437+#endif /* INET6 */
2438 }
2439 }
2440 if (ret)
2441diff -Nur inn-2.3.2.orig/samples/inn.conf.in inn-2.3.2/samples/inn.conf.in
2442--- inn-2.3.2.orig/samples/inn.conf.in Thu May 3 22:27:32 2001
2443+++ inn-2.3.2/samples/inn.conf.in Tue Jun 19 16:06:41 2001
2444@@ -170,3 +170,7 @@
2445 pathrun: @RUNDIR@
2446 pathspool: @SPOOLDIR@
2447 pathtmp: @TMPPATH@
2448+
2449+# for IPv6 support
2450+
2451+listenonipv6: @ipv6@
This page took 0.317878 seconds and 4 git commands to generate.