]> git.pld-linux.org Git - packages/inn.git/blame - inn-ipv6.patch
- fixes for compilaton with db4
[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) {
25ac00e1 761@@ -330,24 +396,42 @@
2aec8557
JB
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);
25ac00e1 766+ innd_argv = NEW(char *, 1 + argc + 2);
2aec8557
JB
767 i = 0;
768 #ifdef DEBUGGER
769 innd_argv[i++] = DEBUGGER;
770 innd_argv[i++] = cpcatpath(innconf->pathbin, "innd");
771 innd_argv[i] = 0;
772+#ifdef INET6
773+ if (innconf->listenonipv6)
774+ printf("When starting innd, use -d -p%d [-p%d]\n", s6, s);
775+ else
776+#endif /* INET6 */
777 printf("When starting innd, use -dp%d\n", s);
778 #else /* DEBUGGER */
779- sprintf(pflag, "-p%d", s);
780 innd_argv[i++] = cpcatpath(innconf->pathbin, "innd");
781- innd_argv[i++] = pflag;
782+#ifdef INET6
783+ if (innconf->listenonipv6) {
784+ sprintf(p6flag, "-p%d", s6);
785+ innd_argv[i++] = p6flag;
786+ }
787+ if (innconf->listenonipv6 && in6any)
788+ {
789+ sprintf(pflag, "-p-1");
790+ innd_argv[i++] = pflag;
791+ } else
792+#endif
793+ {
794+ sprintf(pflag, "-p%d", s);
795+ innd_argv[i++] = pflag;
796+ }
797
798- /* Don't pass along -p, -P, or -I. Check the length of the argument
799+ /* Don't pass along -p, -P, -6, or -I. Check the length of the argument
800 string, and if it's == 2 (meaning there's nothing after the -p or -P
801- or -I), skip the next argument too, to support leaving a space
802+ or -6 or -I), skip the next argument too, to support leaving a space
803 between the argument and the value. */
804 for (j = 1; j < argc; j++) {
805- if (argv[j][0] == '-' && strchr("pPI", argv[j][1])) {
806+ if (argv[j][0] == '-' && strchr("6pPI", argv[j][1])) {
807 if (strlen(argv[j]) == 2) j++;
808 continue;
809 } else {
810diff -Nur inn-2.3.2.orig/innd/lc.c inn-2.3.2/innd/lc.c
811--- inn-2.3.2.orig/innd/lc.c Thu May 3 22:27:32 2001
812+++ inn-2.3.2/innd/lc.c Tue Jun 19 16:06:41 2001
813@@ -39,7 +39,7 @@
814 return;
815 }
816 if ((new = NCcreate(fd, FALSE, TRUE)) != NULL) {
817- new->Address.s_addr = MyAddress.s_addr;
818+ memcpy(&new->Address, &MyAddress, sizeof(MyAddress));
819 syslog(L_NOTICE, "%s connected %d", "localhost", new->fd);
820 NCwritereply(new, (char *)NCgreeting);
821 }
822diff -Nur inn-2.3.2.orig/innd/rc.c inn-2.3.2/innd/rc.c
823--- inn-2.3.2.orig/innd/rc.c Thu May 3 22:27:32 2001
824+++ inn-2.3.2/innd/rc.c Tue Jun 19 16:06:41 2001
825@@ -19,9 +19,6 @@
826 # define INADDR_NONE 0xffffffff
827 #endif
828
829-#define COPYADDR(dest, src) \
830- (void)memcpy((POINTER)dest, (POINTER)src, (SIZE_T)sizeof (INADDR))
831-
832 #define TEST_CONFIG(a, b) \
833 { \
834 b = ((peer_params.Keysetbit & (1 << a)) != 0) ? TRUE : FALSE; \
835@@ -66,7 +63,7 @@
836 STATIC char *RCslaveflag;
837 STATIC char *RCnnrpd = NULL;
838 STATIC char *RCnntpd = NULL;
839-STATIC CHANNEL *RCchan;
840+STATIC CHANNEL *RCchan[2];
841 STATIC REMOTEHOST_DATA *RCpeerlistfile;
842 STATIC REMOTEHOST *RCpeerlist;
843 STATIC int RCnpeerlist;
844@@ -112,6 +109,68 @@
845 STATIC int remotecount;
846 STATIC int remotefirst;
847
848+void
849+COPYADDR(INADDR *dst, char *src)
850+{
851+ struct sockaddr_in sin;
852+
853+ memset(&sin, 0, sizeof(sin));
854+ sin.sin_family = AF_INET;
855+#if defined(HAVE_SOCKADDR_LEN)
856+ sin.sin_len = sizeof(sin);
857+#endif /* defined(HAVE_SOCKADDR_LEN) */
858+ (void)memcpy((POINTER)&sin.sin_addr, src, sizeof(sin.sin_addr));
859+
860+ (void)memcpy((POINTER)dst, (POINTER)&sin, sizeof(sin));
861+}
862+
863+BOOL
864+RCaddressmatch(INADDR *cp, INADDR *rp)
865+{
866+#ifdef INET6
867+ struct sockaddr_in *sin_cp, *sin_rp;
868+ struct sockaddr_in6 *sin6_cp, *sin6_rp;
869+
870+ if (cp->ss_family == AF_INET6 && rp->ss_family == AF_INET) {
871+ sin6_cp = (struct sockaddr_in6 *)cp;
872+ sin_rp = (struct sockaddr_in *)rp;
873+ if (IN6_IS_ADDR_V4MAPPED(&sin6_cp->sin6_addr) &&
874+ memcmp(&sin6_cp->sin6_addr.s6_addr[12], &sin_rp->sin_addr.s_addr,
875+ sizeof(struct in_addr)) == 0)
876+ return TRUE;
877+ else
878+ return FALSE;
879+ } else if (cp->ss_family == AF_INET && rp->ss_family == AF_INET6) {
880+ sin_cp = (struct sockaddr_in *)cp;
881+ sin6_rp = (struct sockaddr_in6 *)rp;
882+ if (IN6_IS_ADDR_V4MAPPED(&sin6_rp->sin6_addr) &&
883+ memcmp(&sin6_rp->sin6_addr.s6_addr[12], &sin_cp->sin_addr.s_addr,
884+ sizeof(struct in_addr)) == 0)
885+ return TRUE;
886+ else
887+ return FALSE;
888+ }
889+#endif /* INET6 */
890+ if (cp->ss_family != rp->ss_family)
891+ return FALSE;
892+
893+ switch (cp->ss_family) {
894+ case AF_INET:
895+ if (((struct sockaddr_in *)cp)->sin_addr.s_addr ==
896+ ((struct sockaddr_in *)rp)->sin_addr.s_addr)
897+ return TRUE;
898+ return FALSE;
899+#ifdef INET6
900+ case AF_INET6:
901+ if (IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)cp)->sin6_addr,
902+ &((struct sockaddr_in6 *)rp)->sin6_addr))
903+ return TRUE;
904+ return FALSE;
905+#endif /* INET6 */
906+ }
907+
908+ return FALSE;
909+}
910
911 /*
912 * Split text into comma-separated fields. Return an allocated
913@@ -168,7 +227,7 @@
914 #endif
915
916 int
917-RCfix_options(int fd, struct sockaddr_in *remote)
918+RCfix_options(int fd, INADDR *remote)
919 {
920 #if IP_OPTIONS
921 unsigned char optbuf[BUFSIZ / 3], *cp;
922@@ -177,10 +236,22 @@
923 int ipproto;
924 struct protoent *ip;
925
926- if ((ip = getprotobyname("ip")) != 0)
927- ipproto = ip->p_proto;
928- else
929- ipproto = IPPROTO_IP;
930+ switch (remote->ss_family) {
931+ case AF_INET:
932+ if ((ip = getprotobyname("ip")) != 0)
933+ ipproto = ip->p_proto;
934+ else
935+ ipproto = IPPROTO_IP;
936+ break;
937+#if defined(INET6)
938+ case AF_INET6:
939+ if ((ip = getprotobyname("ipv6")) != 0)
940+ ipproto = ip->p_proto;
941+ else
942+ ipproto = IPPROTO_IPV6;
943+ break;
944+#endif /* defined(INET6) */
945+ }
946
947 if (getsockopt(fd, ipproto, IP_OPTIONS, (char *) optbuf, &optsize) == 0
948 && optsize != 0) {
949@@ -189,7 +260,7 @@
950 sprintf(lp, " %2.2x", *cp);
951 syslog(LOG_NOTICE,
952 "connect from %s with IP options (ignored):%s",
953- inet_ntoa(remote->sin_addr), lbuf);
954+ Inet_NtoA(remote), lbuf);
955 if (setsockopt(fd, ipproto, IP_OPTIONS, (char *) 0, optsize) != 0) {
956 syslog(LOG_ERR, "setsockopt IP_OPTIONS NULL: %m");
957 return -1;
958@@ -210,17 +281,17 @@
959 register int i;
960
961 for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
962- if (cp->Address.s_addr == rp->Address.s_addr) {
963+ if (RCaddressmatch(&cp->Address, &rp->Address)) {
964 if (rp->Password[0] == '\0' || EQ(pass, rp->Password))
965 return TRUE;
966 syslog(L_ERROR, "%s (%s) bad_auth", rp->Label,
967- inet_ntoa(cp->Address));
968+ Inet_NtoA(&cp->Address));
969 return FALSE;
970 }
971
972 if (!AnyIncoming)
973 /* Not found in our table; this can't happen. */
974- syslog(L_ERROR, "%s not_found", inet_ntoa(cp->Address));
975+ syslog(L_ERROR, "%s not_found", Inet_NtoA(&cp->Address));
976
977 /* Anonymous hosts should not authenticate. */
978 return FALSE;
979@@ -237,7 +308,7 @@
980 register int i;
981
982 for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
983- if (cp->Address.s_addr == rp->Address.s_addr)
984+ if (RCaddressmatch(&cp->Address, &rp->Address))
985 if (rp->MaxCnx)
986 return FALSE;
987 else
988@@ -256,7 +327,7 @@
989 register int i;
990
991 for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
992- if (cp->Address.s_addr == rp->Address.s_addr)
993+ if (RCaddressmatch(&cp->Address, &rp->Address))
994 return (rp->MaxCnx);
995 /* Not found in our table; this can't happen. */
996 return RemoteLimit;
997@@ -270,7 +341,7 @@
998 RCrejectreader(CHANNEL *cp)
999 {
1000 syslog(L_ERROR, "%s internal RCrejectreader (%s)", LogName,
1001- inet_ntoa(cp->Address));
1002+ Inet_NtoA(&cp->Address));
1003 }
1004
1005
1006@@ -348,7 +419,7 @@
1007 RCreader(CHANNEL *cp)
1008 {
1009 int fd;
1010- struct sockaddr_in remote;
1011+ INADDR remote;
1012 ARGTYPE size;
1013 register int i;
1014 register REMOTEHOST *rp;
1015@@ -362,9 +433,9 @@
1016 CHANNEL tempchan;
1017 char buff[SMBUF];
1018
1019- if (cp != RCchan) {
1020- syslog(L_ERROR, "%s internal RCreader wrong channel 0x%x not 0x%x",
1021- LogName, cp, RCchan);
1022+ if (cp != RCchan[0] && cp != RCchan[1]) {
1023+ syslog(L_ERROR, "%s internal RCreader wrong channel 0x%x",
1024+ LogName, cp);
1025 return;
1026 }
1027
1028@@ -425,7 +496,7 @@
1029 ** Finally, if neither rejection happened, add the entry to the
1030 ** table, and continue on as a normal connect.
1031 */
1032- tempchan.Address.s_addr = remote.sin_addr.s_addr;
1033+ memcpy(&tempchan.Address, &remote, sizeof(remote));
1034 reject_message = NULL;
1035 if (RemoteTimer != 0) {
1036 now = time(NULL);
1037@@ -439,7 +510,7 @@
1038 i = (i + 1) & (REMOTETABLESIZE - 1);
1039 continue;
1040 }
1041- if (remotetable[i].Address.s_addr == remote.sin_addr.s_addr)
1042+ if (RCaddressmatch(&remotetable[i].Address, &remote))
1043 found++;
1044 i = (i + 1) & (REMOTETABLESIZE - 1);
1045 }
1046@@ -453,7 +524,7 @@
1047 }
1048 else {
1049 i = (remotefirst + remotecount) & (REMOTETABLESIZE - 1);
1050- remotetable[i].Address = remote.sin_addr;
1051+ memcpy(&remotetable[i].Address, &remote, sizeof(remote));
1052 remotetable[i].Expires = now + RemoteTimer;
1053 remotecount++;
1054 }
1055@@ -466,7 +537,7 @@
1056 if (reject_message) {
1057 new = CHANcreate(fd, CTreject, CSwritegoodbye, RCrejectreader,
1058 RCrejectwritedone);
1059- new->Address.s_addr = remote.sin_addr.s_addr;
1060+ memcpy(&new->Address, &remote, sizeof(remote));
1061 new->Rejected = reject_val;
1062 RCHANremove(new);
1063 WCHANset(new, reject_message, (int)strlen(reject_message));
1064@@ -477,7 +548,7 @@
1065
1066 /* See if it's one of our servers. */
1067 for (name = NULL, rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
1068- if (rp->Address.s_addr == remote.sin_addr.s_addr) {
1069+ if (RCaddressmatch(&rp->Address, &remote)) {
1070 name = rp->Name;
1071 break;
1072 }
1073@@ -491,7 +562,7 @@
1074 new->NoResendId = rp->NoResendId;
1075 new->MaxCnx = rp->MaxCnx;
1076 new->HoldTime = rp->HoldTime;
1077- new->Address.s_addr = remote.sin_addr.s_addr;
1078+ memcpy(&new->Address, &remote, sizeof(remote));
1079 if (new->MaxCnx > 0 && new->HoldTime == 0) {
1080 CHANsetActiveCnx(new);
1081 if((new->ActiveCnx > new->MaxCnx) && (new->fd > 0)) {
1082@@ -519,7 +590,7 @@
1083 reject_message = NNTP_ACCESS;
1084 new = CHANcreate(fd, CTreject, CSwritegoodbye, RCrejectreader,
1085 RCrejectwritedone);
1086- new->Address.s_addr = remote.sin_addr.s_addr;
1087+ memcpy(&new->Address, &remote, sizeof(remote));
1088 new->Rejected = reject_val;
1089 RCHANremove(new);
1090 WCHANset(new, reject_message, (int)strlen(reject_message));
1091@@ -529,9 +600,9 @@
1092 }
1093
1094 if (new != NULL) {
1095- new->Address.s_addr = remote.sin_addr.s_addr;
1096+ memcpy(&new->Address, &remote, sizeof(remote));
1097 syslog(L_NOTICE, "%s connected %d streaming %s",
1098- name ? name : inet_ntoa(new->Address), new->fd,
1099+ name ? name : Inet_NtoA(&new->Address), new->fd,
1100 (!StreamingOff && new->Streaming) ? "allowed" : "not allowed");
1101 }
1102 }
1103@@ -681,7 +752,9 @@
1104 register REMOTEHOST peer_params;
1105 register REMOTEHOST default_params;
1106 BOOL flag, bit, toolong;
1107-
1108+#if defined(HAVE_GETADDRINFO)
1109+ struct addrinfo hints, *res, *res0;
1110+#endif /* defined(HAVE_GETADDRINFO) */
1111
1112 *RCbuff = '\0';
1113 if (*list) {
1114@@ -880,9 +953,51 @@
1115 RENEW (*list, REMOTEHOST, *count);
1116 rp = *list + j;
1117
1118+#if defined(HAVE_GETADDRINFO)
1119+ (void)memset((POINTER)&hints, 0, sizeof hints);
1120+ hints.ai_family = PF_UNSPEC;
1121+ hints.ai_socktype = SOCK_STREAM;
1122+ if (getaddrinfo(*q, NULL, &hints, &res0) != 0) {
1123+ syslog(L_ERROR, "%s cant getaddrinfo %s %m", LogName, *q);
1124+ /* decrement *count, since we never got to add this record. */
1125+ (*count)--;
1126+ continue;
1127+ }
1128+ /* Count the addresses and see if we have to grow the list */
1129+ i = 0;
1130+ for (res = res0; res != NULL; res = res->ai_next)
1131+ i++;
1132+ /* Grow the array */
1133+ j = rp - *list;
1134+ *count += i - 1;
1135+ RENEW(*list, REMOTEHOST, *count);
1136+ rp = *list + j;
1137+
1138+ /* Add all hosts */
1139+ for (res = res0; res != NULL; res = res->ai_next) {
1140+ (void)memcpy(&rp->Address, res->ai_addr, res->ai_addrlen);
1141+ rp->Name = COPY (*q);
1142+ rp->Label = COPY (peer_params.Label);
1143+ rp->Email = COPY(peer_params.Email);
1144+ rp->Comment = COPY(peer_params.Comment);
1145+ rp->Streaming = peer_params.Streaming;
1146+ rp->Skip = peer_params.Skip;
1147+ rp->NoResendId = peer_params.NoResendId;
1148+ rp->Password = COPY(peer_params.Password);
1149+ rp->Patterns = peer_params.Pattern != NULL ?
1150+ RCCommaSplit(COPY(peer_params.Pattern)) : NULL;
1151+ rp->MaxCnx = peer_params.MaxCnx;
1152+ rp->HoldTime = peer_params.HoldTime;
1153+ rp++;
1154+ }
1155+ freeaddrinfo(res0);
1156+#else /* defined(HAVE_GETADDRINFO) */
1157 /* Was host specified as a dotted quad ? */
1158- if ((rp->Address.s_addr = inet_addr(*q)) != INADDR_NONE) {
1159+ if (inet_addr(*q) != INADDR_NONE) {
1160+ u_long addr;
1161 /* syslog(LOG_NOTICE, "think it's a dotquad: %s", *q); */
1162+ addr = inet_addr(*q);
1163+ COPYADDR(&rp->Address, (char *)&addr);
1164 rp->Name = COPY (*q);
1165 rp->Label = COPY (peer_params.Label);
1166 rp->Password = COPY(peer_params.Password);
1167@@ -920,7 +1035,9 @@
1168 int t = 0;
1169 /* Strange DNS ? try this.. */
1170 for (r = hp->h_aliases; *r != 0; r++) {
1171- if (inet_addr(*r) == INADDR_NONE) /* IP address ? */
1172+ u_long addr;
1173+ addr = inet_addr(*r);
1174+ if (addr == INADDR_NONE) /* IP address ? */
1175 continue;
1176 (*count)++;
1177 /* Grow the array */
1178@@ -928,7 +1045,7 @@
1179 RENEW (*list, REMOTEHOST, *count);
1180 rp = *list + j;
1181
1182- rp->Address.s_addr = inet_addr(*r);
1183+ COPYADDR(&rp->Address, (char *)&addr);
1184 rp->Name = COPY (*q);
1185 rp->Label = COPY (peer_params.Label);
1186 rp->Email = COPY(peer_params.Email);
1187@@ -1003,6 +1120,7 @@
1188 rp->HoldTime = peer_params.HoldTime;
1189 rp++;
1190 #endif /* defined(h_addr) */
1191+#endif /* defined(HAVE_GETADDRINFO) */
1192 }
1193 DISPOSE(r[0]);
1194 DISPOSE(r);
1195@@ -1496,9 +1614,9 @@
1196 register int i;
1197
1198 for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
1199- if (cp->Address.s_addr == rp->Address.s_addr)
1200+ if (RCaddressmatch(&cp->Address, &rp->Address))
1201 return rp->Name;
1202- (void)strcpy(buff, inet_ntoa(cp->Address));
1203+ (void)strcpy(buff, Inet_NtoA(&cp->Address));
1204 return buff;
1205 }
1206
1207@@ -1511,7 +1629,7 @@
1208 int i;
1209
1210 for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++) {
1211- if (cp->Address.s_addr == rp->Address.s_addr)
1212+ if (RCaddressmatch(&cp->Address, &rp->Address))
1213 return rp->Label;
1214 }
1215 return NULL;
1216@@ -1530,7 +1648,7 @@
1217 int i;
1218
1219 for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++) {
1220- if (cp->Address.s_addr != rp->Address.s_addr)
1221+ if (RCaddressmatch(&cp->Address, &rp->Address))
1222 continue;
1223 if (rp->Patterns == NULL)
1224 break;
1225@@ -1559,12 +1677,53 @@
1226 register int i;
1227 {
1228 struct sockaddr_in server;
1229+#if defined(INET6)
1230+ struct sockaddr_in6 server6;
1231+#endif /* defined(INET6) */
1232 #if defined(SO_REUSEADDR)
1233 int on;
1234 #endif /* defined(SO_REUSEADDR) */
1235+ int idx;
1236
1237 if (i < 0) {
1238 /* Create a socket and name it. */
1239+#if defined(INET6)
1240+ if (RCchan[0] != NULL && innconf->listenonipv6) {
1241+ if ((i = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {
1242+ syslog(L_FATAL, "%s cant ipv6 socket RCreader %m", LogName);
1243+ exit(1);
1244+ }
1245+#if defined(SO_REUSEADDR)
1246+ on = 1;
1247+ if (setsockopt(i, SOL_SOCKET, SO_REUSEADDR, (caddr_t)&on,
1248+ sizeof on) < 0)
1249+ syslog(L_ERROR, "%s cant setsockopt RCreader %m", LogName);
1250+#endif /* defined(SO_REUSEADDR) */
1251+ (void)memset((POINTER)&server6, 0, sizeof server6);
1252+ server6.sin6_port = htons(innconf->port);
1253+ server6.sin6_family = AF_INET6;
1254+ server6.sin6_addr = in6addr_any;
1255+#if defined(HAVE_SOCKADDR_LEN)
1256+ server6.sin6_len = sizeof server6;
1257+#endif /* defined(HAVE_SOCKADDR_LEN) */
1258+ if (innconf->bindipv6address) {
1259+ if (inet_pton(AF_INET6, innconf->bindipv6address,
1260+ &server6.sin6_addr) < 1) {
1261+ syslog(L_FATAL, "unable to determine bind ipv6 (%s) %m",
1262+ innconf->bindipv6address);
1263+ exit(1);
1264+ }
1265+ }
1266+ if (bind(i, (struct sockaddr *)&server6, sizeof server6) < 0) {
1267+ syslog(L_FATAL, "%s cant bind RCreader %m", LogName);
1268+ exit(1);
1269+ }
1270+ } else if (RCchan[0] != NULL) {
1271+ /* If "listenonipv6" not set, and one socket has already been
1272+ created, no need to create more socket */
1273+ return;
1274+ }
1275+#endif /* defined(INET6) */
1276 if ((i = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
1277 syslog(L_FATAL, "%s cant socket RCreader %m", LogName);
1278 exit(1);
1279@@ -1599,9 +1758,15 @@
1280 syslog(L_FATAL, "%s cant listen RCreader %m", LogName);
1281 exit(1);
1282 }
1283- RCchan = CHANcreate(i, CTremconn, CSwaiting, RCreader, RCwritedone);
1284- syslog(L_NOTICE, "%s rcsetup %s", LogName, CHANname(RCchan));
1285- RCHANadd(RCchan);
1286+
1287+ if (RCchan[0] == NULL)
1288+ idx = 0;
1289+ else
1290+ idx = 1;
1291+ RCchan[idx] = CHANcreate(i, CTremconn, CSwaiting, RCreader, RCwritedone);
1292+
1293+ syslog(L_NOTICE, "%s rcsetup %s", LogName, CHANname(RCchan[idx]));
1294+ RCHANadd(RCchan[idx]);
1295
1296 /* Get the list of hosts we handle. */
1297 RCreadlist();
1298@@ -1617,8 +1782,11 @@
1299 register REMOTEHOST *rp;
1300 register int i;
1301
1302- CHANclose(RCchan, CHANname(RCchan));
1303- RCchan = NULL;
1304+ for (i = 0; i < 2; i++)
1305+ if (RCchan[i] != NULL) {
1306+ CHANclose(RCchan[i], CHANname(RCchan[i]));
1307+ RCchan[i] = NULL;
1308+ }
1309 if (RCpeerlist) {
1310 for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++) {
1311 DISPOSE(rp->Name);
1312diff -Nur inn-2.3.2.orig/innd/status.c inn-2.3.2/innd/status.c
1313--- inn-2.3.2.orig/innd/status.c Thu May 3 22:27:32 2001
1314+++ inn-2.3.2/innd/status.c Tue Jun 19 16:06:41 2001
1315@@ -16,7 +16,7 @@
1316
1317 typedef struct _STATUS {
1318 char name[SMBUF];
1319- char ip_addr[15];
1320+ char ip_addr[64];
1321 BOOL can_stream;
1322 unsigned short activeCxn;
1323 unsigned short sleepingCxns;
1324@@ -134,7 +134,8 @@
1325 tmp = head = NULL;
1326 for (i = 0; (cp = CHANiter(&i, CTnntp)) != NULL; ) {
1327 j = 0;
1328- strcpy(TempString, cp->Address.s_addr == 0 ? "localhost" : RChostname(cp));
1329+ strcpy(TempString, cp->Address.ss_family == 0 ? "localhost" :
1330+ RChostname(cp));
1331 for (status = head ; status != NULL ; status = status->next) {
1332 if (strcmp(TempString, status->name) == 0)
1333 break;
1334@@ -143,7 +144,7 @@
1335 status = NEW(STATUS, 1);
1336 peers++; /* a new peer */
1337 strcpy (status->name, TempString); /* name */
1338- strcpy (status->ip_addr, inet_ntoa(cp->Address)); /* ip address */
1339+ strcpy (status->ip_addr, Inet_NtoA(&cp->Address)); /* ip address */
1340 status->can_stream = cp->Streaming;
1341 status->seconds = status->Size = status->DuplicateSize = 0;
1342 status->Ihave = status->Ihave_Duplicate =
1343diff -Nur inn-2.3.2.orig/innfeed/connection.c inn-2.3.2/innfeed/connection.c
1344--- inn-2.3.2.orig/innfeed/connection.c Thu May 3 22:27:32 2001
1345+++ inn-2.3.2/innfeed/connection.c Tue Jun 19 16:06:41 2001
1346@@ -131,6 +131,12 @@
1347 #include "host.h"
1348 #include "msgs.h"
1349
1350+#ifndef HAVE_SOCKADDR_STORAGE
1351+#include "sockaddr_storage.h"
1352+#endif
1353+
1354+#include "sa_len.h"
1355+
1356 #if defined (NDEBUG)
1357 #define VALIDATE_CONNECTION(x) ((void) 0)
1358 #else
1359@@ -263,7 +269,8 @@
1360 static u_int gCxnCount = 0 ;
1361 static u_int max_reconnect_period = MAX_RECON_PER ;
1362 static u_int init_reconnect_period = INIT_RECON_PER ;
1363-static u_long bind_addr = INADDR_ANY;
1364+static struct sockaddr_storage bind_addr;
1365+static int bind_addr_flag = 0;
1366 #if 0
1367 static bool inited = false ;
1368 #endif
1369@@ -406,17 +413,33 @@
1370 iv = INIT_RECON_PER ;
1371 init_reconnect_period = (u_int) iv ;
1372
1373+ memset (&bind_addr, 0, sizeof(bind_addr));
1374 if (getString (topScope,"bindaddress",&sv,NO_INHERIT))
1375 {
1376- bind_addr = inet_addr(sv);
1377- if (bind_addr == INADDR_NONE)
1378- {
1379+ if (inet_addr(sv) != INADDR_NONE) {
1380+ bind_addr.ss_family = AF_INET;
1381+ ((struct sockaddr_in *)&bind_addr)->sin_addr.s_addr = inet_addr(sv);
1382+#ifdef HAVE_SOCKADDR_LEN
1383+ bind_addr.ss_len = sizeof(struct sockaddr_in);
1384+#endif
1385+ bind_addr_flag = 1;
1386+ }
1387+#ifdef INET6
1388+ else if (inet_pton(AF_INET6, sv,
1389+ &((struct sockaddr_in6 *)&bind_addr)->sin6_addr) == 1) {
1390+ bind_addr.ss_family = AF_INET6;
1391+#ifdef HAVE_SOCKADDR_LEN
1392+ bind_addr.ss_len = sizeof(struct sockaddr_in6);
1393+#endif
1394+ bind_addr_flag = 1;
1395+ }
1396+#endif /* INET6 */
1397+ else {
1398 logOrPrint (LOG_ERR,fp,"innfeed unable to determine bind ip") ;
1399- bind_addr = INADDR_ANY;
1400+ bind_addr_flag = 0;
1401 }
1402- }
1403- else
1404- bind_addr = INADDR_ANY;
1405+ } else
1406+ bind_addr_flag = 0;
1407
1408 return rval ;
1409 }
1410@@ -533,9 +556,9 @@
1411 */
1412 bool cxnConnect (Connection cxn)
1413 {
1414- struct sockaddr_in cxnAddr, cxnSelf ;
1415+ struct sockaddr_storage cxnAddr, cxnSelf ;
1416 int fd, rval ;
1417- struct in_addr *addr = NULL;
1418+ struct sockaddr_storage *addr = NULL;
1419 const char *peerName = hostPeerName (cxn->myHost) ;
1420
1421 ASSERT (cxn->myEp == NULL) ;
1422@@ -566,12 +589,15 @@
1423 return false ;
1424 }
1425
1426- memset (&cxnAddr, 0, sizeof (cxnAddr)) ;
1427- cxnAddr.sin_family = AF_INET ;
1428- cxnAddr.sin_port = htons(cxn->port) ;
1429- cxnAddr.sin_addr.s_addr = addr->s_addr ;
1430+ memcpy (&cxnAddr, addr, sizeof(cxnAddr));
1431+ if (cxnAddr.ss_family == AF_INET)
1432+ ((struct sockaddr_in *)&cxnAddr)->sin_port = htons(cxn->port);
1433+#ifdef INET6
1434+ else if (cxnAddr.ss_family == AF_INET6)
1435+ ((struct sockaddr_in6 *)&cxnAddr)->sin6_port = htons(cxn->port);
1436+#endif
1437
1438- if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
1439+ if ((fd = socket (cxnAddr.ss_family, SOCK_STREAM, 0)) < 0)
1440 {
1441 syslog (LOG_ERR, SOCKET_CREATE_ERROR, peerName, cxn->ident) ;
1442 d_printf (1,"Can't get a socket: %m\n") ;
1443@@ -582,13 +608,15 @@
1444 }
1445
1446 /* bind to a specified virtual host */
1447- if (bind_addr != INADDR_ANY)
1448+ if (bind_addr_flag == 1)
1449 {
1450- memset (&cxnSelf, 0, sizeof (cxnSelf)) ;
1451- cxnSelf.sin_family = AF_INET ;
1452- cxnSelf.sin_port = 0 ;
1453- cxnSelf.sin_addr.s_addr = bind_addr;
1454- if (bind (fd, (struct sockaddr *) &cxnSelf,sizeof (cxnSelf)) < 0)
1455+ (void)memcpy (&cxnSelf, &bind_addr, sizeof(cxnSelf));
1456+#ifdef HAVE_SOCKADDR_LEN
1457+ if (bind (fd, (struct sockaddr *) &cxnSelf, cxnSelf.ss_len) < 0)
1458+#else
1459+ if (bind (fd, (struct sockaddr *) &cxnSelf,
1460+ SA_LEN((struct sockaddr *) &cxnSelf)) < 0)
1461+#endif
1462 {
1463 syslog (LOG_ERR,"bind: %m") ;
1464
1465@@ -620,7 +648,12 @@
1466 return false ;
1467 }
1468
1469- rval = connect (fd, (struct sockaddr *) &cxnAddr, sizeof (cxnAddr)) ;
1470+#ifdef HAVE_SOCKADDR_LEN
1471+ rval = connect (fd, (struct sockaddr *) &cxnAddr, cxnAddr.ss_len);
1472+#else
1473+ rval = connect (fd, (struct sockaddr *) &cxnAddr,
1474+ SA_LEN((struct sockaddr *) &cxnAddr));
1475+#endif
1476 if (rval < 0 && errno != EINPROGRESS)
1477 {
1478 syslog (LOG_ERR, CONNECT_ERROR, peerName, cxn->ident) ;
1479diff -Nur inn-2.3.2.orig/innfeed/endpoint.c inn-2.3.2/innfeed/endpoint.c
1480--- inn-2.3.2.orig/innfeed/endpoint.c Thu May 3 22:27:32 2001
1481+++ inn-2.3.2/innfeed/endpoint.c Tue Jun 19 16:06:41 2001
1482@@ -1628,6 +1628,11 @@
1483 EndPoint accConn ;
1484 struct sockaddr_in accNet ;
1485 int accFd = socket (AF_INET,SOCK_STREAM,0) ;
1486+#ifdef INET6
1487+ EndPoint accConn6;
1488+ struct sockaddr_in6 accNet6;
1489+ int accFd6 = socket (AF_INET6,SOCK_STREAM,0);
1490+#endif
1491 u_short port = atoi (argc > 1 ? argv[1] : "10000") ;
1492 time_t t = theTime() ;
1493
1494@@ -1663,6 +1668,26 @@
1495 accConn = newEndPoint (accFd) ;
1496
1497 prepareRead (accConn,NULL,newConn,NULL,0) ;
1498+
1499+#ifdef INET6
1500+ ASSERT(accFd6 >= 0);
1501+ memset (&accNet6,0,sizeof (accNet6));
1502+ accNet6.sin6_family = AF_INET6;
1503+ accNet6.sin6_addr = in6addr_any;
1504+ accNet6.sin6_port = htons (port);
1505+
1506+ if (bind (accFd6, (struct sockaddr_in6 *) &accNet6, sizeof (accNet6)) < 0)
1507+ {
1508+ perror ("bind: %m") ;
1509+ exit (1) ;
1510+ }
1511+
1512+ listen (accFd6,5);
1513+
1514+ accCon6 = newEndPoint (accFd6);
1515+
1516+ prepareRead (accCon6,NULL,newConn,NULL,0) ;
1517+#endif
1518
1519 prepareSleep (Timeout,5,(void *) 0x10) ;
1520
1521diff -Nur inn-2.3.2.orig/innfeed/host.c inn-2.3.2/innfeed/host.c
1522--- inn-2.3.2.orig/innfeed/host.c Thu May 3 22:27:32 2001
1523+++ inn-2.3.2/innfeed/host.c Tue Jun 19 16:06:41 2001
1524@@ -40,6 +40,8 @@
1525 #include "config.h"
1526 #include "clibrary.h"
1527
1528+#include <sys/types.h>
1529+#include <sys/socket.h>
1530 #include <netinet/in.h>
1531 #include <arpa/inet.h>
1532 #include <assert.h>
1533@@ -67,6 +69,10 @@
1534 #include "msgs.h"
1535 #include "tape.h"
1536
1537+#ifndef HAVE_SOCKADDR_STORAGE
1538+#include "sockaddr_storage.h"
1539+#endif
1540+
1541 #define REQ 1
1542 #define NOTREQ 0
1543 #define NOTREQNOADD 2
1544@@ -1128,22 +1134,63 @@
1545 return nh ;
1546 }
1547
1548-struct in_addr *hostIpAddr (Host host)
1549+struct sockaddr_storage *hostIpAddr (Host host)
1550 {
1551 int i ;
1552 char *p ;
1553 char **newIpAddrs = NULL;
1554- struct in_addr ipAddr, *returnAddr ;
1555+ struct sockaddr_storage ipAddr, *returnAddr;
1556 struct hostent *hostEnt ;
1557+#ifdef HAVE_GETADDRINFO
1558+ struct addrinfo hints, *res, *pr;
1559+#endif
1560 char *msgstr[SMBUF] ;
1561
1562 ASSERT(host->params != NULL);
1563+ returnAddr = NULL;
1564
1565 /* check to see if need to look up the host name */
1566 if (host->nextIpLookup <= theTime())
1567 {
1568+#ifdef HAVE_GETADDRINFO
1569+ memset(&hints, 0, sizeof(hints));
1570+ hints.ai_family = PF_UNSPEC;
1571+ hints.ai_socktype = SOCK_STREAM;
1572+ i = getaddrinfo(host->params->ipName, NULL, &hints, &res);
1573+ if (i != 0)
1574+ {
1575+ syslog (LOG_ERR, HOST_RESOLV_ERROR, host->params->peerName,
1576+ host->params->ipName, gai_strerror(i));
1577+ }
1578+ else
1579+ {
1580+ /* figure number of pointers that need space */
1581+ i = 0;
1582+ for (pr = res; pr != NULL; pr = pr->ai_next, i++)
1583+ ;
1584+ i++;
1585+
1586+ newIpAddrs =
1587+ (char **) MALLOC ( (i * sizeof(char *)) +
1588+ ( (i - 1) * sizeof(struct sockaddr_storage)) ) ;
1589+ ASSERT (newIpAddrs != NULL) ;
1590+
1591+ p = (char *)&newIpAddrs [ i ] ;
1592+ i = 0;
1593+ for (pr = res; pr != NULL; pr = pr->ai_next)
1594+ {
1595+ newIpAddrs[i] = p;
1596+ memcpy (p, pr->ai_addr, pr->ai_addrlen);
1597+ p += sizeof(struct sockaddr_storage);
1598+ i++;
1599+ }
1600+ newIpAddrs[i] = NULL;
1601+ freeaddrinfo(res);
1602+ }
1603+#else
1604 /* see if the ipName we're given is a dotted quad */
1605- if ( !inet_aton (host->params->ipName,&ipAddr) )
1606+ if ( !inet_aton (host->params->ipName,
1607+ &((struct sockaddr_in *)&ipAddr)->sin_addr) )
1608 {
1609 if ((hostEnt = gethostbyname (host->params->ipName)) == NULL)
1610 {
1611@@ -1159,7 +1206,8 @@
1612
1613 newIpAddrs =
1614 (char **) MALLOC ( (i * sizeof(char *)) +
1615- ( (i - 1) * hostEnt->h_length) ) ;
1616+ ( (i - 1) *
1617+ sizeof(struct sockaddr_storage) ) );
1618 ASSERT (newIpAddrs != NULL) ;
1619
1620 /* copy the addresses from gethostbyname() static space */
1621@@ -1168,7 +1216,13 @@
1622 for (i = 0 ; hostEnt->h_addr_list[i] ; i++)
1623 {
1624 newIpAddrs[i] = p;
1625- memcpy (p, hostEnt->h_addr_list[i], hostEnt->h_length) ;
1626+ memcpy (&((struct sockaddr_in *)p)->sin_addr,
1627+ hostEnt->h_addr_list[i], hostEnt->h_length) ;
1628+ ((struct sockaddr_in *)p)->sin_family = AF_INET;
1629+#ifdef HAVE_SOCKADDR_LEN
1630+ ((struct sockaddr_in *)p)->sin_len =
1631+ sizeof(struct sockaddr_in);
1632+#endif
1633 p += hostEnt->h_length ;
1634 }
1635 newIpAddrs[i] = NULL ;
1636@@ -1181,9 +1235,13 @@
1637 p = (char *)&newIpAddrs [ 2 ];
1638 newIpAddrs[0] = p;
1639 memcpy (p, (char *)&ipAddr, sizeof(ipAddr)) ;
1640+ ((struct sockaddr_in *)p)->sin_family = AF_INET;
1641+#ifdef HAVE_SOCKADDR_LEN
1642+ ((struct sockaddr_in *)p)->sin_len = sizeof(struct sockaddr_in);
1643+#endif
1644 newIpAddrs[1] = NULL;
1645 }
1646-
1647+#endif /* HAVE_GETADDRINFO */
1648 if (newIpAddrs)
1649 {
1650 if (host->ipAddrs)
1651@@ -1201,7 +1259,7 @@
1652
1653 if (host->ipAddrs)
1654 {
1655- returnAddr = (struct in_addr *)(host->nextIpAddr[0]) ;
1656+ returnAddr = (struct sockaddr_storage *)(host->nextIpAddr[0]) ;
1657 if (*(++host->nextIpAddr) == NULL)
1658 host->nextIpAddr = host->ipAddrs ;
1659 }
1660diff -Nur inn-2.3.2.orig/innfeed/host.h inn-2.3.2/innfeed/host.h
1661--- inn-2.3.2.orig/innfeed/host.h Thu May 3 22:27:32 2001
1662+++ inn-2.3.2/innfeed/host.h Tue Jun 19 16:06:41 2001
1663@@ -105,7 +105,7 @@
1664 void hostSendArticle (Host host, Article article) ;
1665
1666 /* return an IP address for the host */
1667-struct in_addr *hostIpAddr (Host host) ;
1668+struct sockaddr_storage *hostIpAddr (Host host) ;
1669
1670 /*
1671 * Functions used by the Connection to indicate Connection state.
03da3507
JB
1672diff -Nur inn-2.3.3.orig/lib/Makefile inn-2.3.3/lib/Makefile
1673--- inn-2.3.3.orig/lib/Makefile Thu May 3 22:27:32 2001
1674+++ inn-2.3.3/lib/Makefile Tue Jun 19 16:06:41 2001
2aec8557
JB
1675@@ -16,7 +16,7 @@
1676 md5.c nonblocking.c parsedate.c perl.c qio.c radix32.c readin.c \
1677 remopen.c reservedfd.c resource.c rwlock.c sendarticle.c \
1678 sendpass.c tempname.c waitnb.c wildmat.c version.c xfopena.c \
03da3507
JB
1679- xmalloc.c xsignal.c xwrite.c
1680+ xmalloc.c xsignal.c xwrite.c inet_ntoa.c
2aec8557
JB
1681
1682 OBJECTS = $(MISSING_OBJ) \
1683 argparse.o checkart.o cleanfrom.o clientactive.o clientlib.o \
1684@@ -26,7 +26,7 @@
1685 md5.o nonblocking.o parsedate.o qio.o radix32.o readin.o \
1686 remopen.o reservedfd.o resource.o rwlock.o sendarticle.o \
1687 sendpass.o tempname.o waitnb.o wildmat.o version.o xfopena.o \
03da3507
JB
1688- xmalloc.o xsignal.o xwrite.o
1689+ xmalloc.o xsignal.o xwrite.o inet_ntoa.o
2aec8557
JB
1690
1691 LOBJECTS= $(OBJECTS:.o=.lo)
1692
1693diff -Nur inn-2.3.2.orig/lib/getconfig.c inn-2.3.2/lib/getconfig.c
1694--- inn-2.3.2.orig/lib/getconfig.c Thu May 3 22:27:32 2001
1695+++ inn-2.3.2/lib/getconfig.c Tue Jun 19 16:06:41 2001
1696@@ -267,6 +267,9 @@
1697 innconf->groupbaseexpiry = TRUE;
1698 innconf->wipcheck = 5;
1699 innconf->wipexpire = 10;
1700+ innconf->listenonipv6 = FALSE;
1701+ innconf->bindipv6address = NULL;
1702+ innconf->sourceipv6address = NULL;
1703 }
1704
1705 void ClearInnConf()
1706@@ -304,6 +307,9 @@
1707 if (innconf->backoff_db != NULL) DISPOSE(innconf->backoff_db);
1708 if (innconf->ovmethod != NULL) DISPOSE(innconf->ovmethod);
1709 if (innconf->ovgrouppat != NULL) DISPOSE(innconf->ovgrouppat);
1710+ if (innconf->bindipv6address != NULL) DISPOSE(innconf->bindipv6address);
1711+ if (innconf->sourceipv6address != NULL) DISPOSE(innconf->sourceipv6address);
1712+
1713 memset(ConfigBit, '\0', ConfigBitsize);
1714 }
1715
1716@@ -981,6 +987,21 @@
1717 TEST_CONFIG(CONF_VAR_WIPEXPIRE, bit);
1718 if (!bit) innconf->wipexpire = atoi(p);
1719 SET_CONFIG(CONF_VAR_WIPEXPIRE);
1720+ } else
1721+ if (EQ(ConfigBuff, _CONF_LISTENONIPV6)) {
1722+ TEST_CONFIG(CONF_VAR_LISTENONIPV6, bit);
1723+ if (!bit && boolval != -1) innconf->listenonipv6 = boolval;
1724+ SET_CONFIG(CONF_VAR_LISTENONIPV6);
1725+ } else
1726+ if (EQ(ConfigBuff, _CONF_BINDIPV6ADDRESS)) {
1727+ TEST_CONFIG(CONF_VAR_BINDIPV6ADDRESS, bit);
1728+ if (!bit) innconf->bindipv6address = COPY(p);
1729+ SET_CONFIG(CONF_VAR_BINDIPV6ADDRESS);
1730+ } else
1731+ if (EQ(ConfigBuff, _CONF_SOURCEIPV6ADDRESS)) {
1732+ TEST_CONFIG(CONF_VAR_SOURCEIPV6ADDRESS, bit);
1733+ if (!bit) innconf->sourceipv6address = COPY(p);
1734+ SET_CONFIG(CONF_VAR_SOURCEIPV6ADDRESS);
1735 }
1736 }
1737 (void)Fclose(F);
1738diff -Nur inn-2.3.2.orig/lib/inet_ntoa.c inn-2.3.2/lib/inet_ntoa.c
1739--- inn-2.3.2.orig/lib/inet_ntoa.c Thu May 3 22:27:32 2001
1740+++ inn-2.3.2/lib/inet_ntoa.c Tue Jun 19 16:06:41 2001
1741@@ -5,9 +5,17 @@
1742 */
1743 #include <stdio.h>
1744 #include <sys/types.h>
1745+#include <sys/socket.h>
1746+#include <netinet/in.h>
1747+#include <arpa/inet.h>
1748+#include <netdb.h>
1749 #include "configdata.h"
1750 #include "clibrary.h"
1751+#include "sockaddr_storage.h"
1752
1753+#if !defined(HAVE_SOCKADDR_LEN)
1754+#include "sa_len.h"
1755+#endif
1756
1757 /*
1758 * Copyright (c) 1983 Regents of the University of California.
1759@@ -40,7 +48,7 @@
1760 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1761 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1762 * SUCH DAMAGE.
1763- */
1764+ /
1765
1766 #if defined(LIBC_SCCS) && !defined(lint)
1767 static char sccsid[] = "@(#)inet_ntoa.c 5.6 (Berkeley) 2/24/91";
1768@@ -50,16 +58,45 @@
1769 * Convert network-format internet address
1770 * to base 256 d.d.d.d representation.
1771 */
1772-#include <netinet/in.h>
1773
1774 #define UC(c) (((int)c) & 0xFF)
1775
1776-char *inet_ntoa(struct in_addr in)
1777+char *Inet_NtoA(struct sockaddr_storage *ss)
1778 {
1779+#if !defined(INET6)
1780+#if defined(HAVE_INET_NTOA)
1781+ return inet_ntoa(((struct sockaddr_in *)ss)->sin_addr);
1782+#else
1783 static char buff[18];
1784 char *p;
1785
1786 p = (char *)&in;
1787 (void)sprintf(buff, "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
1788 return buff;
1789+#endif /* HAVE_INET_NTOA */
1790+#else /* INET6 */
1791+ static char buff[256];
1792+ struct sockaddr_in sin;
1793+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ss;
1794+
1795+ if (ss->ss_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) ) {
1796+ memcpy(&sin.sin_addr, sin6->sin6_addr.s6_addr+12,
1797+ sizeof(sin.sin_addr));
1798+ sin.sin_port = ((struct sockaddr_in6 *)ss)->sin6_port;
1799+ sin.sin_family = AF_INET;
1800+#if defined(HAVE_SOCKADDR_LEN)
1801+ sin.sin_len = sizeof(struct sockaddr_in);
1802+#endif
1803+ return inet_ntoa(sin.sin_addr);
1804+ }
1805+#if defined(HAVE_SOCKADDR_LEN)
1806+ getnameinfo((struct sockaddr *)ss, ss->ss_len, buff, sizeof(buff), NULL, 0,
1807+ NI_NUMERICHOST);
1808+#else
1809+ getnameinfo((struct sockaddr *)ss, SA_LEN((struct sockaddr *)ss), buff,
1810+ sizeof(buff), NULL, 0, NI_NUMERICHOST);
1811+#endif /* HAVE_SOCKADDR_IN */
1812+
1813+ return buff;
1814+#endif /* INET6 */
1815 }
1816diff -Nur inn-2.3.2.orig/lib/remopen.c inn-2.3.2/lib/remopen.c
1817--- inn-2.3.2.orig/lib/remopen.c Thu May 3 22:27:32 2001
1818+++ inn-2.3.2/lib/remopen.c Tue Jun 19 16:06:41 2001
1819@@ -40,13 +40,69 @@
1820 int j;
1821 int oerrno;
1822 FILE *F;
1823+#if defined(HAVE_GETADDRINFO)
1824+ struct addrinfo hints, *res, *addr;
1825+ char portbuf[16];
1826+ struct sockaddr_storage client;
1827+#else
1828 struct hostent *hp;
1829 struct hostent fakehp;
1830 struct in_addr quadaddr;
1831 struct sockaddr_in server, client;
1832+#endif /* defined(HAVE_GETADDRINFO) */
1833
1834 buff = errbuff ? errbuff : mybuff;
1835 *buff = '\0';
1836+
1837+#if defined(HAVE_GETADDRINFO)
1838+ (void)memset((POINTER)&hints, 0, sizeof hints);
1839+ hints.ai_family = PF_UNSPEC;
1840+ hints.ai_socktype = SOCK_STREAM;
1841+ sprintf(portbuf, "%d", port);
1842+ if (getaddrinfo(host, portbuf, &hints, &res) != 0)
1843+ return -1;
1844+
1845+ for (addr = res; addr; addr = addr->ai_next) {
1846+ /* Make a socket and try to connect */
1847+ if ((i = socket(addr->ai_family, SOCK_STREAM, 0)) < 0)
1848+ break;
1849+ (void)memset((POINTER)&client, 0, sizeof client);
1850+ if (addr->ai_family == AF_INET) {
1851+ if (innconf->sourceaddress &&
1852+ inet_pton(AF_INET, innconf->sourceaddress,
1853+ &((struct sockaddr_in *)&client)->sin_addr) < 1) {
1854+ freeaddrinfo(addr);
1855+ return -1;
1856+ }
1857+ ((struct sockaddr_in *)&client)->sin_family = AF_INET;
1858+ }
1859+#if defined(INET6)
1860+ if (addr->ai_family == AF_INET6) {
1861+ if (innconf->sourceipv6address &&
1862+ inet_pton(AF_INET6, innconf->sourceipv6address,
1863+ &((struct sockaddr_in6 *)&client)->sin6_addr) < 1) {
1864+ freeaddrinfo(addr);
1865+ return -1;
1866+ }
1867+ ((struct sockaddr_in6 *)&client)->sin6_family = AF_INET6;
1868+ }
1869+#endif /* defined(INET6) */
1870+ /* Bind to the source address we want. */
1871+ if (bind(i, (struct sockaddr *)&client, addr->ai_addrlen) < 0) {
1872+ oerrno = errno;
1873+ (void)close(i);
1874+ errno = oerrno;
1875+ continue;
1876+ }
1877+ if (connect(i, addr->ai_addr, addr->ai_addrlen) < 0) {
1878+ oerrno = errno;
1879+ (void)close(i);
1880+ errno = oerrno;
1881+ continue;
1882+ }
1883+
1884+#else /* HAVE_GETADDRINFO */
1885+
1886 quadaddr.s_addr = inet_addr(host);
1887 if (quadaddr.s_addr != (unsigned int) -1) {
1888 /* Host was specified as a dotted-quad internet address. Fill in
1889@@ -111,6 +167,7 @@
1890 errno = oerrno;
1891 continue;
1892 }
1893+#endif /* defined(HAVE_GETADDRINFO) */
1894
1895 /* Connected -- now make sure we can post. */
1896 if ((F = fdopen(i, "r")) == NULL) {
1897diff -Nur inn-2.3.2.orig/nnrpd/commands.c inn-2.3.2/nnrpd/commands.c
1898--- inn-2.3.2.orig/nnrpd/commands.c Thu May 3 22:27:32 2001
1899+++ inn-2.3.2/nnrpd/commands.c Tue Jun 19 16:06:41 2001
1900@@ -184,7 +184,22 @@
1901
1902 /*syslog(L_NOTICE, "%s (%ld) returned: %d %s %d\n", av[0], (long) pid, i, path, status);*/
1903 /* Split "host:permissions:user:pass:groups" into fields. */
1904- for (fields[0] = path, i = 0, p = path; *p; p++)
1905+ /* "host" field for IPv6 address must be enclosed with "[" and "]" */
1906+ if (path[0] == '[') {
1907+ fields[0] = path + 1;
1908+ i = 0;
1909+ p = path + 1;
1910+ while (*p && *p != ']')
1911+ p++;
1912+ *p = '\0';
1913+ p += 2; /* Skip next ':' */
1914+ fields[++i] = p;
1915+ } else {
1916+ fields[0] = path;
1917+ i = 0;
1918+ p = path;
1919+ }
1920+ for (; *p; p++)
1921 if (*p == ':') {
1922 *p = '\0';
1923 fields[++i] = p + 1;
1924@@ -753,7 +768,7 @@
1925 /* Acquire lock (this could be in RateLimit but that would
1926 * invoke the spaghetti factor).
1927 */
1928- if ((path = (char *) PostRecFilename(ClientIP,PERMuser)) == NULL) {
1929+ if ((path = (char *) PostRecFilename(&ClientIP,PERMuser)) == NULL) {
1930 Reply("%s\r\n", NNTP_CANTPOST);
1931 return;
1932 }
1933diff -Nur inn-2.3.2.orig/nnrpd/misc.c inn-2.3.2/nnrpd/misc.c
1934--- inn-2.3.2.orig/nnrpd/misc.c Thu May 3 22:27:32 2001
1935+++ inn-2.3.2/nnrpd/misc.c Tue Jun 19 16:06:41 2001
1936@@ -664,12 +664,12 @@
1937 */
1938 char
1939 *PostRecFilename(ip,user)
1940- unsigned long ip;
1941+ INADDR *ip;
1942 char *user;
1943 {
1944 static char buff[SPOOLNAMEBUFF];
1945 char dirbuff[SPOOLNAMEBUFF];
1946- unsigned char addr[4];
1947+ unsigned char addr[16];
1948 unsigned int i;
1949
1950 if (PERMaccessconf->backoff_auth) {
1951@@ -677,11 +677,27 @@
1952 return(buff);
1953 }
1954
1955- for (i=0; i<4; i++) {
1956- addr[i] = (unsigned char) (0x000000ff & (ip>>(i*8)));
1957+ switch (ip->ss_family) {
1958+ case AF_INET:
1959+ for (i=0; i<4; i++) {
1960+ addr[i] = (unsigned char)
1961+ (0x000000ff & (((struct sockaddr_in *)ip)->sin_addr.s_addr >>
1962+ (i*8)));
1963+ }
1964+ sprintf(dirbuff,"%s/%03d%03d/%03d",postrec_dir,addr[3],addr[2],addr[1]);
1965+ break;
1966+#ifdef INET6
1967+ case AF_INET6:
1968+ for (i=0;i<15;i++)
1969+ addr[i] = ((struct sockaddr_in6 *)ip)->sin6_addr.s6_addr[i];
1970+ sprintf(dirbuff,"%s/%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x/%02x%02x",
1971+ postrec_dir,addr[0],addr[1],addr[2],addr[3],addr[4],addr[5],
1972+ addr[6],addr[7],addr[8],addr[9],addr[10],addr[11],
1973+ addr[12],addr[13]);
1974+ break;
1975+#endif
1976 }
1977
1978- sprintf(dirbuff,"%s/%03d%03d/%03d",postrec_dir,addr[3],addr[2],addr[1]);
1979 if (!MakeDirectory(dirbuff,TRUE)) {
1980 syslog(L_ERROR,"%s Unable to create postrec directories '%s': %s",
1981 ClientHost,dirbuff,strerror(errno));
1982diff -Nur inn-2.3.2.orig/nnrpd/nnrpd.c inn-2.3.2/nnrpd/nnrpd.c
1983--- inn-2.3.2.orig/nnrpd/nnrpd.c Thu May 3 22:27:32 2001
1984+++ inn-2.3.2/nnrpd/nnrpd.c Tue Jun 19 16:12:24 2001
1985@@ -34,6 +34,8 @@
1986 int nnrpd_starttls_done = 0;
1987 #endif
1988
1989+#include "sa_len.h"
1990+
1991 #if defined(hpux) || defined(__hpux) || defined(_SCO_DS)
1992 extern int h_errno;
1993 #endif
1994@@ -362,11 +364,82 @@
1995 Address2Name(INADDR *ap, char *hostname, int i)
1996 {
1997 char *p;
1998+#if defined(INET6)
1999+ struct addrinfo hints, *res, *res0;
2000+ int len, ret;
2001+ struct sockaddr_in sin;
2002+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ap;
2003+#else
2004 struct hostent *hp;
2005 #if defined(h_addr)
2006 char **pp;
2007 #endif
2008+#endif /* defined (INET6) */
2009+
2010+#if defined(INET6)
2011+ /* Get the official hostname, store it away. (with new API) */
2012+ if (ap->ss_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) ) {
2013+ memcpy(&sin.sin_addr, sin6->sin6_addr.s6_addr+12,
2014+ sizeof(sin.sin_addr));
2015+ sin.sin_port = ((struct sockaddr_in6 *)ap)->sin6_port;
2016+ sin.sin_family = AF_INET;
2017+#if defined(HAVE_SOCKADDR_LEN)
2018+ sin.sin_len = sizeof(struct sockaddr_in);
2019+#endif /* defined(HAVE_SOCKADDR_LEN) */
2020+ ap = &sin;
2021+ }
2022
2023+#if defined(HAVE_SOCKADDR_LEN)
2024+ len = ap->ss_len;
2025+#else
2026+ len = SA_LEN((struct sockaddr *)ap);
2027+#endif /* defined(HAVE_SOCKADDR_LEN) */
2028+ ret = getnameinfo((struct sockaddr *)ap, len, hostname, i, NULL, 0,
2029+ NI_NAMEREQD);
2030+ if (ret != 0) {
2031+ HostErrorStr = gai_strerror(ret);
2032+ return FALSE;
2033+ }
2034+
2035+ /* Get the address for this host */
2036+ (void)memset(&hints, 0, sizeof(hints));
2037+ hints.ai_family = PF_UNSPEC;
2038+ hints.ai_flags = AI_CANONNAME;
2039+ hints.ai_socktype = SOCK_STREAM;
2040+ ret = getaddrinfo(hostname, NULL, &hints, &res0);
2041+ if (ret != 0) {
2042+ HostErrorStr = gai_strerror(ret);
2043+ return FALSE;
2044+ }
2045+
2046+ /* Make sure one of those addresses is the address we got. */
2047+ for (res = res0; res != NULL; res = res->ai_next) {
2048+ if (res->ai_addr->sa_family == ap->ss_family) {
2049+ if (ap->ss_family == AF_INET &&
2050+ memcmp(&((struct sockaddr_in *)ap)->sin_addr,
2051+ &((struct sockaddr_in *)res->ai_addr)->sin_addr,
2052+ sizeof(struct in_addr)) == 0)
2053+ break;
2054+ else if (ap->ss_family == AF_INET6 &&
2055+ memcmp(&((struct sockaddr_in6 *)ap)->sin6_addr,
2056+ &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
2057+ sizeof(struct in6_addr)) == 0)
2058+ break;
2059+ }
2060+ }
2061+ if (res == NULL) {
2062+ freeaddrinfo(res0);
2063+ return FALSE;
2064+ }
2065+ if (res->ai_canonname == NULL) { /* XXX */
2066+ freeaddrinfo(res0);
2067+ return FALSE;
2068+ }
2069+ (void)strncpy(hostname, res->ai_canonname, i);
2070+ freeaddrinfo(res0);
2071+
2072+#else /* defined(INET6) */
2073+
2074 /* Get the official hostname, store it away. */
2075 if ((hp = gethostbyaddr((char *)ap, sizeof *ap, AF_INET)) == NULL) {
2076 HostErrorStr = (char *)hstrerror(h_errno);
2077@@ -385,25 +458,27 @@
2078 #if defined(h_addr)
2079 /* We have many addresses */
2080 for (pp = hp->h_addr_list; *pp; pp++)
2081- if (memcmp((POINTER)&ap->s_addr, (POINTER)*pp,
2082- (SIZE_T)hp->h_length) == 0)
2083+ if (memcmp((POINTER)&(((struct sockaddr_in *)ap)->sin_addr.s_addr),
2084+ (POINTER)*pp, (SIZE_T)hp->h_length) == 0)
2085 break;
2086 if (*pp == NULL)
2087 return FALSE;
2088 #else
2089 /* We have one address. */
2090- if (memcmp((POINTER)&ap->s_addr, (POINTER)hp->h_addr,
2091- (SIZE_T)hp->h_length) != 0)
2092+ if (memcmp((POINTER)&(((struct sockaddr_in *)ap)->sin_addr.s_addr),
2093+ (POINTER)hp->h_addr, (SIZE_T)hp->h_length) != 0)
2094 return FALSE;
2095 #endif
2096
2097 /* Only needed for misconfigured YP/NIS systems. */
2098- if (ap->s_addr != INADDR_LOOPBACK && strchr(hostname, '.') == NULL
2099- && (p = innconf->domain) != NULL) {
2100+ if (((struct sockaddr_in *)ap)->sin_addr.s_addr != INADDR_LOOPBACK &&
2101+ strchr(hostname, '.') == NULL && (p = innconf->domain) != NULL) {
2102 (void)strcat(hostname, ".");
2103 (void)strcat(hostname, p);
2104 }
2105
2106+#endif /* defined(INET6) */
2107+
2108 /* Make all lowercase, for wildmat. */
2109 for (p = hostname; *p; p++)
2110 if (CTYPE(isupper, (int)*p))
2111@@ -418,7 +493,7 @@
2112 */
2113 STATIC void StartConnection()
2114 {
2115- struct sockaddr_in sin;
2116+ struct sockaddr_storage ss;
2117 ARGTYPE length;
2118 char buff[SMBUF];
2119 char *ClientAddr;
2120@@ -427,9 +502,9 @@
2121 static ACCESSGROUP *authconf;
2122
2123 /* Get the peer's name. */
2124- length = sizeof sin;
2125+ length = sizeof ss;
2126 ClientAddr = NULL;
2127- if (getpeername(STDIN, (struct sockaddr *)&sin, &length) < 0) {
2128+ if (getpeername(STDIN, (struct sockaddr *)&ss, &length) < 0) {
2129 if (!isatty(STDIN)) {
2130 syslog(L_TRACE, "%s cant getpeername %m", "?");
2131 (void)strcpy(ClientHost, "?"); /* so stats generation looks correct. */
2132@@ -437,14 +512,18 @@
2133 ExitWithStats(1, TRUE);
2134 }
2135 (void)strcpy(ClientHost, "stdin");
2136- ClientIP = 0L;
2137+ memset(&ClientIP, 0, sizeof(ClientIP));
2138 ServerHost[0] = '\0';
2139 }
2140
2141 else {
2142- if (sin.sin_family != AF_INET) {
2143+#if defined(INET6)
2144+ if (ss.ss_family != AF_INET && ss.ss_family != AF_INET6) {
2145+#else
2146+ if (ss.ss_family != AF_INET) {
2147+#endif /* defined(INET6) */
2148 syslog(L_ERROR, "%s bad_address_family %ld",
2149- "?", (long)sin.sin_family);
2150+ "?", (long)ss.ss_family);
2151 Printf("%d Bad address family. Goodbye.\r\n", NNTP_ACCESS_VAL);
2152 ExitWithStats(1, TRUE);
2153 }
2154@@ -452,8 +531,8 @@
2155 /* Get client's name. */
2156 #if defined(DO_NNRP_GETHOSTBYADDR)
2157 HostErrorStr = NULL;
2158- if (!Address2Name(&sin.sin_addr, ClientHost, (int)sizeof ClientHost)) {
2159- (void)strcpy(ClientHost, inet_ntoa(sin.sin_addr));
2160+ if (!Address2Name(&ss, ClientHost, (int)sizeof ClientHost)) {
2161+ (void)strcpy(ClientHost, Inet_NtoA(&ss));
2162 if (HostErrorStr == NULL) {
2163 syslog(L_NOTICE,
2164 "? cant gethostbyaddr %s %m -- using IP address for access",
2165@@ -464,32 +543,32 @@
2166 ClientHost, HostErrorStr);
2167 }
2168 ClientAddr = ClientHost;
2169- ClientIP = inet_addr(ClientHost);
2170+ (void)memcpy(&ClientIP, &ss, sizeof(ss));
2171 }
2172 else {
2173 ClientAddr = buff;
2174- (void)strcpy(buff, inet_ntoa(sin.sin_addr));
2175- ClientIP = inet_addr(buff);
2176+ (void)strcpy(buff, Inet_NtoA(&ss));
2177+ (void)memcpy(&ClientIP, &ss, sizeof(ss));
2178 }
2179 #else
2180- (void)strcpy(ClientHost, inet_ntoa(sin.sin_addr));
2181- ClientIP = inet_addr(ClientHost);
2182+ (void)strcpy(ClientHost, Inet_NtoA(&ss));
2183+ (void)memcpy(&ClientIP, &ss, sizeof(ss));
2184 #endif /* defined(DO_NNRP_GETHOSTBYADDR) */
2185- (void)strncpy(ClientIp, inet_ntoa(sin.sin_addr), sizeof(ClientIp));
2186- length = sizeof sin;
2187- if (getsockname(STDIN, (struct sockaddr *)&sin, &length) < 0) {
2188+ (void)strncpy(ClientIp, Inet_NtoA(&ss), sizeof(ClientIp));
2189+ length = sizeof ss;
2190+ if (getsockname(STDIN, (struct sockaddr *)&ss, &length) < 0) {
2191 syslog(L_NOTICE, "%s can't getsockname %m", ClientHost);
2192 Printf("%d Can't figure out where you connected to. Goodbye\r\n", NNTP_ACCESS_VAL);
2193 ExitWithStats(1, TRUE);
2194 }
2195 #ifdef DO_NNRP_GETHOSTBYADDR
2196 HostErrorStr = NULL;
2197- if (!Address2Name(&sin.sin_addr, ServerHost, sizeof(ServerHost))) {
2198- strcpy(ServerHost, inet_ntoa(sin.sin_addr));
2199+ if (!Address2Name(&ss, ServerHost, sizeof(ServerHost))) {
2200+ strcpy(ServerHost, Inet_NtoA(&ss));
2201 /* suppress error reason */
2202 }
2203 #else
2204- strcpy(ServerHost, inet_ntoa(sin.sin_addr));
2205+ strcpy(ServerHost, Inet_NtoA(&ss));
2206 #endif /* DO_NNRP_GETHOSTBYADDR */
2207 }
2208
2209@@ -741,9 +820,14 @@
2210 struct timeval tv;
2211 unsigned short ListenPort = NNTP_PORT;
2212 unsigned long ListenAddr = htonl(INADDR_ANY);
2213- int lfd, fd;
2214+ int lfd[2], fd, maxfd, tmpfd;
2215+ fd_set fds;
2216+#ifdef INET6
2217+ struct sockaddr_in6 ListenAddr6;
2218+#endif
2219 ARGTYPE clen;
2220- struct sockaddr_in ssa, csa;
2221+ struct sockaddr_in ssa;
2222+ struct sockaddr_storage csa;
2223 struct stat Sb;
2224 PID_T pid = -1;
2225 GID_T NewsGID;
2226@@ -777,17 +861,27 @@
2227
2228 openlog("nnrpd", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
2229
2230+#ifdef INET6
2231+ memset(&ListenAddr6, '\0', sizeof(ListenAddr6));
2232+#endif
2233+
2234 if (ReadInnConf() < 0) exit(1);
2235
2236 #ifdef HAVE_SSL
2237- while ((i = getopt(argc, argv, "b:Di:g:op:Rr:s:tS")) != EOF)
2238+ while ((i = getopt(argc, argv, "6:b:Di:g:op:Rr:s:tS")) != EOF)
2239 #else
2240- while ((i = getopt(argc, argv, "b:Di:g:op:Rr:s:t")) != EOF)
2241+ while ((i = getopt(argc, argv, "6:b:Di:g:op:Rr:s:t")) != EOF)
2242 #endif /* HAVE_SSL */
2243 switch (i) {
2244 default:
2245 Usage();
2246 /* NOTREACHED */
2247+ case '6': /* bind to a certain ipv6 address in
2248+ daemon mode */
2249+#ifdef INET6
2250+ inet_pton(AF_INET6, optarg, &ListenAddr6.sin6_addr);
2251+#endif
2252+ break;
2253 case 'b': /* bind to a certain address in
2254 daemon mode */
2255 ListenAddr = inet_addr(optarg);
2256@@ -849,12 +943,12 @@
2257 SPOOLlen = strlen(innconf->patharticles);
2258
2259 if (DaemonMode) {
2260- if ((lfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
2261+ if ((lfd[0] = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
2262 syslog(L_FATAL, "can't open socket (%m)");
2263 exit(1);
2264 }
2265
2266- if (setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) {
2267+ if (setsockopt(lfd[0], SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) {
2268 syslog(L_FATAL, "can't setsockopt(SO_REUSEADDR) (%m)");
2269 exit(1);
2270 }
2271@@ -864,11 +958,38 @@
2272 ssa.sin_addr.s_addr = ListenAddr;
2273 ssa.sin_port = htons(ListenPort);
2274
2275- if (bind(lfd, (struct sockaddr *) &ssa, sizeof(ssa)) < 0) {
2276+ if (bind(lfd[0], (struct sockaddr *) &ssa, sizeof(ssa)) < 0) {
2277 fprintf(stderr, "%s: can't bind (%s)\n", argv[0], strerror(errno));
2278 syslog(L_FATAL, "can't bind local address (%m)");
2279 exit(1);
2280 }
2281+
2282+ lfd[1] = -1;
2283+#ifdef INET6
2284+ if (innconf->bindipv6address) {
2285+ if ((lfd[1] = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {
2286+ syslog(L_FATAL, "can't open socket(%m)");
2287+ exit(1);
2288+ }
2289+ if (setsockopt(lfd[1], SOL_SOCKET, SO_REUSEADDR, (char *)&one,
2290+ sizeof(one)) < 0) {
2291+ syslog(L_FATAL, "can't setsockopt(SO_REUSEADDR) (%m)");
2292+ exit(1);
2293+ }
2294+ ListenAddr6.sin6_family = AF_INET6;
2295+ ListenAddr6.sin6_port = htons(ListenPort);
2296+#ifdef HAVE_SOCKADDR_LEN
2297+ ListenAddr6.sin6_len = sizeof(ListenAddr6);
2298+#endif
2299+ if (bind(lfd[1], (struct sockaddr *)&ListenAddr6,
2300+ sizeof(ListenAddr6)) < 0) {
2301+ fprintf(stderr, "%s: can't bind (%s)\n", argv[0],
2302+ strerror(errno));
2303+ syslog(L_FATAL, "can't bind local address (%m)");
2304+ exit(1);
2305+ }
2306+ }
2307+#endif /* INET6 */
2308
2309 /* If started as root, switch to news uid */
2310 if (getuid() == 0) {
2311@@ -953,11 +1074,33 @@
2312
2313 TITLEset("nnrpd: accepting connections");
2314
2315- listen(lfd, 128);
2316+ listen(lfd[0], 128);
2317+ maxfd = lfd[0];
2318+ if (lfd[1] != -1) {
2319+ if (maxfd < lfd[1])
2320+ lfd[1] = maxfd;
2321+ listen(lfd[1], 128);
2322+ }
2323+ maxfd++;
2324
2325 do {
2326+ FD_ZERO(&fds);
2327+ FD_SET(lfd[0], &fds);
2328+ if (lfd[1] != -1)
2329+ FD_SET(lfd[1], &fds);
2330+
2331+ if (select(maxfd, &fds, NULL, NULL, NULL) < 0) {
2332+ syslog(L_FATAL, "%s: select cause error (%m)");
2333+ exit(1);
2334+ }
2335+
2336 clen = sizeof(csa);
2337- fd = accept(lfd, (struct sockaddr *) &csa, &clen);
2338+ if (FD_ISSET(lfd[0], &fds))
2339+ tmpfd = lfd[0];
2340+ else if (lfd[1] != -1 && FD_ISSET(lfd[1], &fds))
2341+ tmpfd = lfd[1];
2342+ fd = accept(tmpfd, (struct sockaddr *) &csa, &clen);
2343+
2344 if (fd < 0)
2345 continue;
2346
2347@@ -980,7 +1123,9 @@
2348
2349 /* child process starts here */
2350 TITLEset("nnrpd: connected");
2351- close(lfd);
2352+ close(lfd[0]);
2353+ if (lfd[1] != -1)
2354+ close(lfd[1]);
2355 dup2(fd, 0);
2356 close(fd);
2357 dup2(0, 1);
2358diff -Nur inn-2.3.2.orig/nnrpd/nnrpd.h inn-2.3.2/nnrpd/nnrpd.h
2359--- inn-2.3.2.orig/nnrpd/nnrpd.h Thu May 3 22:27:32 2001
2360+++ inn-2.3.2/nnrpd/nnrpd.h Tue Jun 19 16:06:41 2001
2361@@ -31,6 +31,9 @@
2362 #include "paths.h"
2363 #include "qio.h"
2364
2365+#ifndef HAVE_SOCKADDR_STORAGE
2366+#include "sockaddr_storage.h"
2367+#endif
2368
2369 /*
2370 ** Maximum input line length, sigh.
2371@@ -43,7 +46,7 @@
2372 /*
2373 ** Some convenient shorthands.
2374 */
2375-typedef struct in_addr INADDR;
2376+typedef struct sockaddr_storage INADDR;
2377
2378
2379 /*
2380@@ -138,7 +141,7 @@
2381 EXTERN char ClientHost[SMBUF];
2382 EXTERN char ServerHost[SMBUF];
2383 EXTERN char Username[SMBUF];
2384-EXTERN char ClientIp[20];
2385+EXTERN char ClientIp[64];
2386 EXTERN char LogName[256] ;
2387 extern char *ACTIVETIMES;
2388 extern char *HISTORY;
2389@@ -176,7 +179,7 @@
2390 EXTERN long POSTrejected;
2391
2392 EXTERN BOOL BACKOFFenabled;
2393-EXTERN long ClientIP;
2394+EXTERN INADDR ClientIP;
2395 EXTERN char *VirtualPath;
2396 EXTERN int VirtualPathlen;
2397
2398diff -Nur inn-2.3.2.orig/nnrpd/perm.c inn-2.3.2/nnrpd/perm.c
2399--- inn-2.3.2.orig/nnrpd/perm.c Thu May 3 22:27:32 2001
2400+++ inn-2.3.2/nnrpd/perm.c Tue Jun 19 16:06:41 2001
2401@@ -1488,6 +1488,10 @@
2402 if (!ret && (p = strchr(pat, '/')) != (char *)NULL) {
2403 int bits, c;
2404 struct in_addr ia, net;
2405+#ifdef INET6
2406+ int n;
2407+ struct in6_addr ia6, net6;
2408+#endif
2409 unsigned int mask;
2410
2411 *p = '\0';
2412@@ -1505,6 +1509,23 @@
2413 if ((ia.s_addr & mask) == (net.s_addr & mask))
2414 ret = 1;
2415 }
2416+#ifdef INET6
2417+ if (inet_pton(AF_INET6, ClientIp, &ia6) == 1 &&
2418+ inet_pton(AF_INET6, pat, &net6) == 1) {
2419+ if (strchr(p+1, '.') == (char *)NULL) {
2420+ mask = atoi(p+1);
2421+ n = mask / 8;
2422+ bits = mask % 8;
2423+ for (c = 0; c < n; c++)
2424+ if (ia6.s6_addr[c] != net6.s6_addr[c])
2425+ break;
2426+ if (c == n &&
2427+ (ia6.s6_addr[c] & (0x00ff << (8 - bits))) ==
2428+ (net6.s6_addr[c] & (0x00ff << (8 - bits))))
2429+ ret = 1;
2430+ }
2431+ }
2432+#endif /* INET6 */
2433 }
2434 }
2435 if (ret)
2436diff -Nur inn-2.3.2.orig/samples/inn.conf.in inn-2.3.2/samples/inn.conf.in
2437--- inn-2.3.2.orig/samples/inn.conf.in Thu May 3 22:27:32 2001
2438+++ inn-2.3.2/samples/inn.conf.in Tue Jun 19 16:06:41 2001
2439@@ -170,3 +170,7 @@
2440 pathrun: @RUNDIR@
2441 pathspool: @SPOOLDIR@
2442 pathtmp: @TMPPATH@
2443+
2444+# for IPv6 support
2445+
2446+listenonipv6: @ipv6@
This page took 0.323246 seconds and 4 git commands to generate.