]> git.pld-linux.org Git - packages/inn.git/blob - inn-ipv6.patch
1eece94d8be8a3c610d53032cbd1ba5096d6e72d
[packages/inn.git] / inn-ipv6.patch
1 diff -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.
67 diff -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.
288 diff -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
317 diff -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
331 diff -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__ */
361 diff -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  
383 diff -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 */
408 diff -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 +
458 diff -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 */
515 diff -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  
592 diff -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();
651 diff -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
671 diff -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 {
815 diff -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      }
827 diff -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);
1317 diff -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 =
1348 diff -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) ;
1484 diff -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  
1526 diff -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      }
1665 diff -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.
1677 diff -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
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 \
1684 -       xmalloc.c xsignal.c xwrite.c
1685 +       xmalloc.c xsignal.c xwrite.c inet_ntoa.c
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 \
1693 -       xmalloc.o xsignal.o xwrite.o
1694 +       xmalloc.o xsignal.o xwrite.o inet_ntoa.o
1695  
1696  LOBJECTS= $(OBJECTS:.o=.lo)
1697  
1698 diff -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);
1743 diff -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  }
1821 diff -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) {
1902 diff -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        }
1938 diff -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));
1987 diff -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);
2363 diff -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  
2403 diff -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)
2441 diff -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.649636 seconds and 2 git commands to generate.