]> git.pld-linux.org Git - packages/postfix.git/blob - postfix-ipv6.patch
- Release: 2 (STBR after AMD64 fixes)
[packages/postfix.git] / postfix-ipv6.patch
1 --- postfix-2.0.16.orig/makedefs        2003-01-23 14:45:02.000000000 +0100
2 +++ postfix-2.0.16/makedefs     2003-11-08 20:22:55.000000000 +0100
3 @@ -52,6 +52,21 @@
4  SYSTEM=`(uname -s) 2>/dev/null`
5  RELEASE=`(uname -r) 2>/dev/null`
6  VERSION=`(uname -v) 2>/dev/null`
7 +if test -f /usr/include/netinet6/in6.h; then
8 +       grep __KAME__ /usr/include/netinet6/in6.h 2>&1 >/dev/null
9 +       if [ $?  = 1 ]; then
10 +               INET6=
11 +       else
12 +               if [ -f /usr/local/v6/lib/libinet6.a ]; then
13 +                       INET6=kame
14 +               else
15 +                       INET6=kame-merged
16 +               fi
17 +       fi
18 +fi
19 +if [ -z "$INET6" -a -f /usr/include/netinet/ip6.h -a -f /usr/include/linux/icmpv6.h ]; then
20 +       INET6=linux
21 +fi
22  
23  case "$VERSION" in
24   dcosx*) SYSTEM=$VERSION;;
25 @@ -318,6 +333,26 @@
26  
27  : ${CC='gcc $(WARN)'} ${OPT='-O'} ${DEBUG='-g'} ${AWK=awk}
28  
29 +case "$INET6" in
30 +kame)
31 +       CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len"
32 +       if test -f /usr/local/v6/lib/libinet6.a; then
33 +               SYSLIBS="$SYSLIBS -L/usr/local/v6/lib -linet6"
34 +       fi
35 +       ;;
36 +kame-merged)
37 +       CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len"
38 +       ;;
39 +linux)
40 +       CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family"
41 +       if test -f /usr/include/libinet6/netinet/ip6.h
42 +                       then 
43 +               CCARGS="$CCARGS -I/usr/include/libinet6 -DUSAGI_LIBINET6"
44 +               SYSLIBS="$SYSLIBS -linet6"
45 +       fi
46 +       ;;
47 +esac
48 +
49  export SYSTYPE AR ARFL RANLIB SYSLIBS CC OPT DEBUG AWK OPTS
50  
51  sed 's/  / /g' <<EOF
52 --- postfix-2.0.16.orig/src/global/Makefile.in  2003-11-08 20:17:08.000000000 +0100
53 +++ postfix-2.0.16/src/global/Makefile.in       2003-11-08 20:22:55.000000000 +0100
54 @@ -19,7 +19,7 @@
55         timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \
56         tok822_resolve.c tok822_rewrite.c tok822_tree.c xtext.c bounce_log.c \
57         flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c \
58 -       verp_sender.c match_parent_style.c mime_state.c header_token.c \
59 +       verp_sender.c match_parent_style.c mime_state.c header_token.c wildcard_inet_addr.c\
60         strip_addr.c virtual8_maps.c hold_message.c dict_proxy.c mail_dict.c \
61         pfixtls.c
62  OBJS   = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
63 @@ -42,7 +42,7 @@
64         timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \
65         tok822_resolve.o tok822_rewrite.o tok822_tree.o xtext.o bounce_log.o \
66         flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o \
67 -       verp_sender.o match_parent_style.o mime_state.o header_token.o \
68 +       verp_sender.o match_parent_style.o mime_state.o header_token.o wildcard_inet_addr.o\
69         strip_addr.o virtual8_maps.o hold_message.o dict_proxy.o mail_dict.o \
70         pfixtls.o
71  HDRS   = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
72 @@ -61,7 +61,7 @@
73         rewrite_clnt.h sent.h smtp_stream.h split_addr.h string_list.h \
74         sys_exits.h timed_ipc.h tok822.h xtext.h bounce_log.h flush_clnt.h \
75         mbox_conf.h mbox_open.h abounce.h qmqp_proto.h verp_sender.h \
76 -       match_parent_style.h quote_flags.h mime_state.h header_token.h \
77 +       match_parent_style.h quote_flags.h mime_state.h header_token.h wildcard_inet_addr.h\
78         lex_822.h strip_addr.h virtual8_maps.h hold_message.h dict_proxy.h \
79         mail_dict.h pfixtls.h
80  TESTSRC        = rec2stream.c stream2rec.c recdump.c
81 --- postfix-2.0.16.orig/src/global/mynetworks.c 2001-02-25 02:46:07.000000000 +0100
82 +++ postfix-2.0.16/src/global/mynetworks.c      2003-11-08 20:22:55.000000000 +0100
83 @@ -50,6 +50,11 @@
84  #include <vstring.h>
85  #include <inet_addr_list.h>
86  #include <name_mask.h>
87 +#ifdef INET6
88 +#include <sys/socket.h>
89 +#include <netinet/in.h>
90 +#include <netdb.h>
91 +#endif
92  
93  /* Global library. */
94  
95 @@ -75,6 +80,9 @@
96  const char *mynetworks(void)
97  {
98      static VSTRING *result;
99 +#ifdef INET6
100 +    char hbuf[NI_MAXHOST];
101 +#endif
102  
103      if (result == 0) {
104         char   *myname = "mynetworks";
105 @@ -87,6 +95,13 @@
106         int     junk;
107         int     i;
108         int     mask_style;
109 +#ifdef INET6
110 +       struct sockaddr *sa;
111 +       struct sockaddr_in6 *addr6;
112 +       struct sockaddr_in6 *mask6;
113 +       struct in6_addr net6;
114 +       int j;
115 +#endif
116  
117         mask_style = name_mask("mynetworks mask style", mask_styles,
118                                var_mynetworks_style);
119 @@ -96,8 +111,45 @@
120         my_mask_list = own_inet_mask_list();
121  
122         for (i = 0; i < my_addr_list->used; i++) {
123 +#ifdef INET6
124 +           sa = (struct sockaddr *)&my_addr_list->addrs[i];
125 +           if (sa->sa_family == AF_INET6) {
126 +               addr6 = (struct sockaddr_in6 *)sa;
127 +               mask6 = (struct sockaddr_in6 *)&my_mask_list->addrs[i];
128 +
129 +               switch (mask_style) {
130 +               case MASK_STYLE_CLASS:
131 +                   /* treat as subnet for IPv6 */
132 +               case MASK_STYLE_SUBNET:
133 +                   for (j=0; j<16; j++)
134 +                       net6.s6_addr[j] = addr6->sin6_addr.s6_addr[j] & mask6->sin6_addr.s6_addr[j];
135 +                   for(shift=128; shift>0; shift--)
136 +                       if ((mask6->sin6_addr.s6_addr[(shift-1) / 8]) & (0x80 >> ((shift-1) % 8)))
137 +                           break;
138 +                   break;
139 +               case MASK_STYLE_HOST:
140 +                   memcpy (&net6, &(addr6->sin6_addr), sizeof(net6));
141 +                   shift=128;
142 +                   break;
143 +               default:
144 +                   msg_panic("unknown mynetworks mask style: %s",
145 +                             var_mynetworks_style);
146 +               }
147 +               inet_ntop(AF_INET6, &net6, hbuf, sizeof(hbuf));
148 +               if (!shift)
149 +                   msg_warn("%s: skipped network with zero mask: [%s/0]", myname, hbuf);
150 +               else
151 +                   vstring_sprintf_append(result, "[%s/%d] ", hbuf, shift);
152 +               continue;
153 +           } else if (sa->sa_family != AF_INET) {
154 +               continue;
155 +           }
156 +           addr = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr);
157 +           mask = ntohl(((struct sockaddr_in *)&my_mask_list->addrs[i])->sin_addr.s_addr);
158 +#else
159             addr = ntohl(my_addr_list->addrs[i].s_addr);
160             mask = ntohl(my_mask_list->addrs[i].s_addr);
161 +#endif
162  
163             switch (mask_style) {
164  
165 @@ -119,8 +171,15 @@
166                     mask = IN_CLASSD_NET;
167                     shift = IN_CLASSD_NSHIFT;
168                 } else {
169 +#ifdef INET6
170 +                   if (getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
171 +                           NI_NUMERICHOST))
172 +                       strncpy(hbuf, "???", sizeof(hbuf));
173 +                   msg_fatal("%s: bad address class: %s", myname, hbuf);
174 +#else
175                     msg_fatal("%s: bad address class: %s",
176                               myname, inet_ntoa(my_addr_list->addrs[i]));
177 +#endif
178                 }
179                 break;
180  
181 @@ -146,6 +205,18 @@
182                           var_mynetworks_style);
183             }
184             net.s_addr = htonl(addr & mask);
185 +           if (shift == BITS_PER_ADDR) {
186 +#ifdef INET6
187 +               if (getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
188 +                       NI_NUMERICHOST))
189 +                   strncpy(hbuf, "???", sizeof(hbuf));
190 +               msg_warn("%s: skipped network with zero mask: %s/0", myname, hbuf);
191 +#else
192 +               msg_warn("%s: skipped network with zero mask: %s/0",
193 +                        myname, inet_ntoa(my_addr_list->addrs[i]));
194 +#endif
195 +               continue;
196 +           }
197             vstring_sprintf_append(result, "%s/%d ",
198                                    inet_ntoa(net), BITS_PER_ADDR - shift);
199         }
200 --- postfix-2.0.16.orig/src/global/own_inet_addr.c      2002-10-25 01:19:19.000000000 +0200
201 +++ postfix-2.0.16/src/global/own_inet_addr.c   2003-11-08 20:22:55.000000000 +0100
202 @@ -50,6 +50,10 @@
203  #include <netinet/in.h>
204  #include <arpa/inet.h>
205  #include <string.h>
206 +#ifdef INET6
207 +#include <sys/socket.h>
208 +#include <netdb.h>
209 +#endif
210  
211  #ifdef STRCASECMP_IN_STRINGS_H
212  #include <strings.h>
213 @@ -113,10 +117,11 @@
214       */
215      else {
216         bufp = hosts = mystrdup(var_inet_interfaces);
217 -       while ((host = mystrtok(&bufp, sep)) != 0)
218 +       while ((host = mystrtok(&bufp, sep)) != 0) {
219             if (inet_addr_host(addr_list, host) == 0)
220                 msg_fatal("config variable %s: host not found: %s",
221                           VAR_INET_INTERFACES, host);
222 +       }
223         myfree(hosts);
224  
225         /*
226 @@ -133,15 +138,39 @@
227             msg_fatal("could not find any active network interfaces");
228         for (nvirtual = 0; nvirtual < addr_list->used; nvirtual++) {
229             for (nlocal = 0; /* see below */ ; nlocal++) {
230 -               if (nlocal >= local_addrs.used)
231 +               if (nlocal >= local_addrs.used) {
232 +#ifdef INET6
233 +                   char hbuf[NI_MAXHOST];
234 +                   if (getnameinfo((struct sockaddr *)&addr_list->addrs[nvirtual],
235 +                       SS_LEN(addr_list->addrs[nvirtual]), hbuf,
236 +                       sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
237 +                       strncpy(hbuf, "???", sizeof(hbuf));
238 +                   msg_fatal("parameter %s: no local interface found for %s",
239 +                             VAR_INET_INTERFACES, hbuf);
240 +#else
241                     msg_fatal("parameter %s: no local interface found for %s",
242                               VAR_INET_INTERFACES,
243                               inet_ntoa(addr_list->addrs[nvirtual]));
244 +#endif
245 +               }
246 +#ifdef INET6
247 +               if (addr_list->addrs[nvirtual].ss_family == 
248 +                   local_addrs.addrs[nlocal].ss_family &&
249 +                   SS_LEN(addr_list->addrs[nvirtual]) == 
250 +                   SS_LEN(local_addrs.addrs[nlocal]) &&
251 +                   memcmp(&addr_list->addrs[nvirtual],
252 +                   &local_addrs.addrs[nlocal],
253 +                   SS_LEN(local_addrs.addrs[nlocal])) == 0) {
254 +                   inet_addr_list_append(mask_list, (struct sockaddr *)&local_masks.addrs[nlocal]);
255 +                   break;
256 +               }
257 +#else
258                 if (addr_list->addrs[nvirtual].s_addr
259                     == local_addrs.addrs[nlocal].s_addr) {
260                     inet_addr_list_append(mask_list, &local_masks.addrs[nlocal]);
261                     break;
262                 }
263 +#endif
264             }
265         }
266         inet_addr_list_free(&local_addrs);
267 @@ -151,6 +180,42 @@
268  
269  /* own_inet_addr - is this my own internet address */
270  
271 +#ifdef INET6
272 +int     own_inet_addr(struct sockaddr * addr)
273 +{
274 +    int     i;
275 +    char *p, *q;
276 +    int l;
277 +    struct sockaddr *sa;
278 +
279 +    if (addr_list.used == 0)
280 +       own_inet_addr_init(&addr_list, &mask_list);
281 +
282 +    for (i = 0; i < addr_list.used; i++) {
283 +       sa = (struct sockaddr *)&addr_list.addrs[i];
284 +       if (addr->sa_family != sa->sa_family)
285 +           continue;
286 +       switch (addr->sa_family) {
287 +       case AF_INET:
288 +           p = (char *)&((struct sockaddr_in *)addr)->sin_addr;
289 +           q = (char *)&((struct sockaddr_in *)&addr_list.addrs[i])->sin_addr;
290 +           l = sizeof(struct in_addr);
291 +           break;
292 +       case AF_INET6:
293 +           /* XXX scope */
294 +           p = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr;
295 +           q = (char *)&((struct sockaddr_in6 *)&addr_list.addrs[i])->sin6_addr;
296 +           l = sizeof(struct in6_addr);
297 +           break;
298 +       default:
299 +           continue;
300 +       }
301 +       if (memcmp(p, q, l) == 0)
302 +           return (1);
303 +    }
304 +    return (0);
305 +}
306 +#else
307  int     own_inet_addr(struct in_addr * addr)
308  {
309      int     i;
310 @@ -161,8 +226,8 @@
311      for (i = 0; i < addr_list.used; i++)
312         if (addr->s_addr == addr_list.addrs[i].s_addr)
313             return (1);
314 -    return (0);
315  }
316 +#endif
317  
318  /* own_inet_addr_list - return list of addresses */
319  
320 @@ -213,6 +278,45 @@
321  
322  /* proxy_inet_addr - is this my proxy internet address */
323  
324 +#ifdef INET6
325 +int    proxy_inet_addr(struct sockaddr * addr)
326 +{
327 +    int     i;
328 +    char *p, *q;
329 +    int l;
330 +    struct sockaddr *sa;
331 +
332 +    if (*var_proxy_interfaces == 0)
333 +       return (0);
334 +
335 +    if (proxy_list.used == 0)
336 +       proxy_inet_addr_init(&proxy_list);
337 +
338 +    for (i = 0; i < proxy_list.used; i++) {
339 +       sa = (struct sockaddr *)&proxy_list.addrs[i];
340 +       if (addr->sa_family != sa->sa_family)
341 +           continue;
342 +       switch (addr->sa_family) {
343 +       case AF_INET:
344 +           p = (char *)&((struct sockaddr_in *)addr)->sin_addr;
345 +           q = (char *)&((struct sockaddr_in *)&addr_list.addrs[i])->sin_addr;
346 +           l = sizeof(struct in_addr);
347 +           break;
348 +       case AF_INET6:
349 +           /* XXX scope */
350 +           p = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr;
351 +           q = (char *)&((struct sockaddr_in6 *)&addr_list.addrs[i])->sin6_addr;
352 +           l = sizeof(struct in6_addr);
353 +           break;
354 +       default:
355 +           continue;
356 +       }
357 +       if (memcmp(p, q, l) == 0)
358 +           return (1);
359 +    }
360 +    return (0);
361 +}
362 +#else
363  int     proxy_inet_addr(struct in_addr * addr)
364  {
365      int     i;
366 @@ -228,6 +332,7 @@
367             return (1);
368      return (0);
369  }
370 +#endif
371  
372  /* proxy_inet_addr_list - return list of addresses */
373  
374 --- postfix-2.0.16.orig/src/global/own_inet_addr.h      2002-10-25 01:07:05.000000000 +0200
375 +++ postfix-2.0.16/src/global/own_inet_addr.h   2003-11-08 20:22:55.000000000 +0100
376 @@ -15,14 +15,25 @@
377    * System library.
378    */
379  #include <netinet/in.h>
380 +#ifdef INET6
381 +#include <sys/socket.h>
382 +#endif
383  
384   /*
385    * External interface.
386    */
387 +#ifdef INET6
388 +extern int own_inet_addr(struct sockaddr *);
389 +#else
390  extern int own_inet_addr(struct in_addr *);
391 +#endif
392  extern struct INET_ADDR_LIST *own_inet_addr_list(void);
393  extern struct INET_ADDR_LIST *own_inet_mask_list(void);
394 +#ifdef INET6
395 +extern int proxy_inet_addr(struct sockaddr *);
396 +#else
397  extern int proxy_inet_addr(struct in_addr *);
398 +#endif
399  extern struct INET_ADDR_LIST *proxy_inet_addr_list(void);
400  
401  /* LICENSE
402 --- postfix-2.0.16.orig/src/global/peer_name.c  2001-01-28 16:23:02.000000000 +0100
403 +++ postfix-2.0.16/src/global/peer_name.c       2003-11-08 20:22:55.000000000 +0100
404 @@ -69,12 +69,32 @@
405  PEER_NAME *peer_name(int sock)
406  {
407      static PEER_NAME peer;
408 -    struct sockaddr_in sin;
409 -    SOCKADDR_SIZE len = sizeof(sin);
410 +    union sockunion {
411 +       struct {
412 +           u_char si_len;
413 +           u_char si_family;
414 +           u_short si_port;
415 +       } su_si;
416 +       struct sockaddr peer_un;
417 +       struct sockaddr_in peer_un4;
418 +#ifdef INET6
419 +       struct sockaddr_in6 peer_un6;
420 +#endif
421 +    } p_un;
422 +#define sun p_un.peer_un
423 +#define sin p_un.peer_un4
424 +#ifdef INET6
425 +#define sin6 p_un.peer_un6
426 +    static char hbuf[NI_MAXHOST];
427 +    static char abuf[NI_MAXHOST];
428 +#else
429      struct hostent *hp;
430 +#endif
431 +    SOCKADDR_SIZE len = sizeof(p_un);
432  
433 -    if (getpeername(sock, (struct sockaddr *) & sin, &len) == 0) {
434 -       switch (sin.sin_family) {
435 +    if (getpeername(sock, (struct sockaddr *)&p_un, &len) == 0) {
436 +       switch (p_un.peer_un.sa_family) {
437 +#ifndef INET6
438         case AF_INET:
439             peer.type = PEER_TYPE_INET;
440             hp = gethostbyaddr((char *) &(sin.sin_addr),
441 @@ -83,6 +103,24 @@
442                          hp->h_name : "unknown");
443             peer.addr = inet_ntoa(sin.sin_addr);
444             return (&peer);
445 +#else
446 +       case AF_INET:
447 +           peer.type = PEER_TYPE_INET;
448 +           if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
449 +               peer.name = "unknown";
450 +           else
451 +               peer.name = hbuf;
452 +           peer.addr = abuf;
453 +           return (&peer);
454 +       case AF_INET6:
455 +           peer.type = PEER_TYPE_INET6;
456 +           if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
457 +               peer.name = "unknown";
458 +           else
459 +               peer.name = hbuf;
460 +           peer.addr = abuf;
461 +           return (&peer);
462 +#endif
463         case AF_UNSPEC:
464         case AF_UNIX:
465             peer.type = PEER_TYPE_LOCAL;
466 --- postfix-2.0.16.orig/src/global/peer_name.h  1998-12-11 19:55:32.000000000 +0100
467 +++ postfix-2.0.16/src/global/peer_name.h       2003-11-08 20:22:55.000000000 +0100
468 @@ -22,6 +22,9 @@
469  #define PEER_TYPE_UNKNOWN      0
470  #define PEER_TYPE_INET         1
471  #define PEER_TYPE_LOCAL                2
472 +#ifdef INET6
473 +#define PEER_TYPE_INET6                3
474 +#endif
475  
476  extern PEER_NAME *peer_name(int);
477  
478 --- postfix-2.0.16.orig/src/global/resolve_local.c      2002-10-25 01:21:20.000000000 +0200
479 +++ postfix-2.0.16/src/global/resolve_local.c   2003-11-08 20:22:55.000000000 +0100
480 @@ -43,6 +43,7 @@
481  #include <netinet/in.h>
482  #include <arpa/inet.h>
483  #include <string.h>
484 +#include <netdb.h>
485  
486  #ifndef INADDR_NONE
487  #define INADDR_NONE 0xffffffff
488 @@ -80,7 +81,12 @@
489  {
490      char   *saved_addr = mystrdup(addr);
491      char   *dest;
492 +#ifdef INET6
493 +    struct addrinfo hints, *res, *res0;
494 +    int error;
495 +#else
496      struct in_addr ipaddr;
497 +#endif
498      int     len;
499  
500  #define RETURN(x) { myfree(saved_addr); return(x); }
501 @@ -118,9 +124,25 @@
502      if (*dest == '[' && dest[len - 1] == ']') {
503         dest++;
504         dest[len -= 2] = 0;
505 +#ifdef INET6
506 +       memset(&hints, 0, sizeof(hints));
507 +       hints.ai_family = PF_UNSPEC;
508 +       hints.ai_socktype = SOCK_DGRAM;
509 +       error = getaddrinfo(dest, NULL, &hints, &res0);
510 +       if (!error) {
511 +           for (res = res0; res; res = res->ai_next) {
512 +               if (own_inet_addr(res->ai_addr)) {
513 +                   freeaddrinfo(res0);
514 +                   RETURN(1);
515 +               }
516 +           }
517 +           freeaddrinfo(res0);
518 +       }
519 +#else
520         if ((ipaddr.s_addr = inet_addr(dest)) != INADDR_NONE
521             && (own_inet_addr(&ipaddr) || proxy_inet_addr(&ipaddr)))
522             RETURN(1);
523 +#endif
524      }
525  
526      /*
527 --- postfix-2.0.16.orig/src/global/wildcard_inet_addr.c 1970-01-01 01:00:00.000000000 +0100
528 +++ postfix-2.0.16/src/global/wildcard_inet_addr.c      2003-11-08 20:22:55.000000000 +0100
529 @@ -0,0 +1,82 @@
530 +/* System library. */
531 +
532 +#include <sys_defs.h>
533 +#include <netinet/in.h>
534 +#include <arpa/inet.h>
535 +#include <string.h>
536 +#ifdef INET6
537 +#include <sys/socket.h>
538 +#endif
539 +#include <netdb.h>
540 +
541 +#ifdef STRCASECMP_IN_STRINGS_H
542 +#include <strings.h>
543 +#endif
544 +
545 +/* Utility library. */
546 +
547 +#include <msg.h>
548 +#include <mymalloc.h>
549 +#include <inet_addr_list.h>
550 +#include <inet_addr_local.h>
551 +#include <inet_addr_host.h>
552 +#include <stringops.h>
553 +
554 +/* Global library. */
555 +
556 +#include <mail_params.h>
557 +#include <wildcard_inet_addr.h>
558 +
559 +/* Application-specific. */
560 +static INET_ADDR_LIST addr_list;
561 +
562 +/* wildcard_inet_addr_init - initialize my own address list */
563 +
564 +static void wildcard_inet_addr_init(INET_ADDR_LIST *addr_list)
565 +{
566 +#ifdef INET6
567 +    struct addrinfo hints, *res, *res0;
568 +    char hbuf[NI_MAXHOST];
569 +    int error;
570 +#ifdef NI_WITHSCOPEID
571 +    const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
572 +#else
573 +    const int niflags = NI_NUMERICHOST;
574 +#endif
575 +
576 +    inet_addr_list_init(addr_list);
577 +
578 +    memset(&hints, 0, sizeof(hints));
579 +    hints.ai_family = PF_UNSPEC;
580 +    hints.ai_socktype = SOCK_STREAM;
581 +    hints.ai_flags = AI_PASSIVE;
582 +    error = getaddrinfo(NULL, "0", &hints, &res0);
583 +    if (error)
584 +       msg_fatal("could not get list of wildcard addresses");
585 +    for (res = res0; res; res = res->ai_next) {
586 +       if (res->ai_family != AF_INET && res->ai_family != AF_INET6)
587 +           continue;
588 +       if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
589 +           NULL, 0, niflags) != 0)
590 +           continue;
591 +       if (inet_addr_host(addr_list, hbuf) == 0)
592 +           continue; /* msg_fatal("config variable %s: host not found: %s",
593 +                     VAR_INET_INTERFACES, hbuf); */
594 +    }
595 +    freeaddrinfo(res0);
596 +#else
597 +    if (inet_addr_host(addr_list, "0.0.0.0") == 0)
598 +       msg_fatal("config variable %s: host not found: %s",
599 +                 VAR_INET_INTERFACES, "0.0.0.0");
600 +#endif
601 +}
602 +
603 +/* wildcard_inet_addr_list - return list of addresses */
604 +
605 +INET_ADDR_LIST *wildcard_inet_addr_list(void)
606 +{
607 +    if (addr_list.used == 0)
608 +       wildcard_inet_addr_init(&addr_list);
609 +
610 +    return (&addr_list);
611 +}
612 --- postfix-2.0.16.orig/src/global/wildcard_inet_addr.h 1970-01-01 01:00:00.000000000 +0100
613 +++ postfix-2.0.16/src/global/wildcard_inet_addr.h      2003-11-08 20:22:55.000000000 +0100
614 @@ -0,0 +1,36 @@
615 +#ifndef _WILDCARD_INET_ADDR_H_INCLUDED_
616 +#define _WILDCARD_INET_ADDR_H_INCLUDED_
617 +
618 +/*++
619 +/* NAME
620 +/*     wildcard_inet_addr_list 3h
621 +/* SUMMARY
622 +/*     grab the list of wildcard IP addresses.
623 +/* SYNOPSIS
624 +/*     #include <own_inet_addr.h>
625 +/* DESCRIPTION
626 +/* .nf
627 +/*--*/
628 +
629 + /*
630 +  * System library.
631 +  */
632 +#include <netinet/in.h>
633 +#ifdef INET6
634 +#include <sys/socket.h>
635 +#endif
636 +
637 + /*
638 +  * External interface.
639 +  */
640 +extern struct INET_ADDR_LIST *wildcard_inet_addr_list(void);
641 +
642 +/* LICENSE
643 +/* .ad
644 +/* .fi
645 +/*     foo
646 +/* AUTHOR(S)
647 +/*     Jun-ichiro itojun Hagino
648 +/*--*/
649 +
650 +#endif
651 --- postfix-2.0.16.orig/src/master/master_ent.c 2003-06-18 21:19:46.000000000 +0200
652 +++ postfix-2.0.16/src/master/master_ent.c      2003-11-08 20:22:55.000000000 +0100
653 @@ -307,8 +307,13 @@
654             inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv));
655             serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
656         } else if (strcasecmp(saved_interfaces, DEF_INET_INTERFACES) == 0) {
657 +#ifdef INET6
658 +           MASTER_INET_ADDRLIST(serv) = wildcard_inet_addr_list();
659 +           serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
660 +#else
661             MASTER_INET_ADDRLIST(serv) = 0;     /* wild-card */
662             serv->listen_fd_count = 1;
663 +#endif
664         } else {
665             MASTER_INET_ADDRLIST(serv) = own_inet_addr_list();  /* virtual */
666             inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv));
667 --- postfix-2.0.16.orig/src/master/master_listen.c      2001-05-01 00:47:57.000000000 +0200
668 +++ postfix-2.0.16/src/master/master_listen.c   2003-11-08 20:22:55.000000000 +0100
669 @@ -64,13 +64,22 @@
670  
671  #include "master.h"
672  
673 +#ifdef INET6
674 +#include <netdb.h>
675 +#include <stdio.h>
676 +#endif 
677 +
678  /* master_listen_init - enable connection requests */
679  
680  void    master_listen_init(MASTER_SERV *serv)
681  {
682      char   *myname = "master_listen_init";
683      char   *end_point;
684 -    int     n;
685 +    int     n,m,tmpfd;
686 +#ifdef INET6
687 +    char hbuf[NI_MAXHOST];
688 +    SOCKADDR_SIZE salen;
689 +#endif
690  
691      /*
692       * Find out what transport we should use, then create one or more
693 @@ -111,18 +120,31 @@
694             serv->listen_fd[0] =
695                 inet_listen(MASTER_INET_PORT(serv),
696                             serv->max_proc > var_proc_limit ?
697 -                           serv->max_proc : var_proc_limit, NON_BLOCKING);
698 +                           serv->max_proc : var_proc_limit, NON_BLOCKING, 1);
699             close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
700         } else {                                /* virtual or host:port */
701 -           for (n = 0; n < serv->listen_fd_count; n++) {
702 +           for (m = n = 0; n < serv->listen_fd_count; n++) {
703 +#ifdef INET6
704 +               if (getnameinfo((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n],
705 +                       SA_LEN((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n]), 
706 +                       hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) {
707 +                   strncpy(hbuf, "?????", sizeof(hbuf));
708 +               }
709 +               end_point = concatenate(hbuf, ":", MASTER_INET_PORT(serv), (char *) 0);
710 +#else
711                 end_point = concatenate(inet_ntoa(MASTER_INET_ADDRLIST(serv)->addrs[n]),
712                                    ":", MASTER_INET_PORT(serv), (char *) 0);
713 -               serv->listen_fd[n]
714 +#endif
715 +               tmpfd
716                     = inet_listen(end_point, serv->max_proc > var_proc_limit ?
717 -                            serv->max_proc : var_proc_limit, NON_BLOCKING);
718 -               close_on_exec(serv->listen_fd[n], CLOSE_ON_EXEC);
719 +                            serv->max_proc : var_proc_limit, NON_BLOCKING, 0);
720 +               if (tmpfd >= 0) {
721 +                   serv->listen_fd[m] = tmpfd;
722 +                   close_on_exec(serv->listen_fd[m++], CLOSE_ON_EXEC);
723 +               }
724                 myfree(end_point);
725             }
726 +           serv->listen_fd_count=m;
727         }
728         break;
729      default:
730 --- postfix-2.0.16.orig/src/smtp/Makefile.in    2003-11-08 20:17:08.000000000 +0100
731 +++ postfix-2.0.16/src/smtp/Makefile.in 2003-11-08 20:22:55.000000000 +0100
732 @@ -144,6 +144,7 @@
733  smtp_connect.o: ../../include/mail_params.h
734  smtp_connect.o: ../../include/own_inet_addr.h
735  smtp_connect.o: ../../include/dns.h
736 +smtp_connect.o: ../../include/get_port.h
737  smtp_connect.o: smtp.h
738  smtp_connect.o: ../../include/argv.h
739  smtp_connect.o: ../../include/deliver_request.h
740 --- postfix-2.0.16.orig/src/smtp/smtp_addr.c    2002-10-25 01:03:11.000000000 +0200
741 +++ postfix-2.0.16/src/smtp/smtp_addr.c 2003-11-08 20:22:55.000000000 +0100
742 @@ -134,18 +134,68 @@
743  static void smtp_print_addr(char *what, DNS_RR *addr_list)
744  {
745      DNS_RR *addr;
746 -    struct in_addr in_addr;
747 +#ifdef INET6
748 +    struct sockaddr_storage ss;
749 +#else
750 +    struct sockaddr ss;
751 +#endif
752 +    struct sockaddr_in *sin;
753 +#ifdef INET6
754 +    struct sockaddr_in6 *sin6;
755 +    char   hbuf[NI_MAXHOST];
756 +#else
757 +    char   hbuf[sizeof("255.255.255.255") + 1];
758 +#endif
759  
760      msg_info("begin %s address list", what);
761      for (addr = addr_list; addr; addr = addr->next) {
762 -       if (addr->data_len > sizeof(addr)) {
763 -           msg_warn("skipping address length %d", addr->data_len);
764 -       } else {
765 -           memcpy((char *) &in_addr, addr->data, sizeof(in_addr));
766 -           msg_info("pref %4d host %s/%s",
767 -                    addr->pref, addr->name,
768 -                    inet_ntoa(in_addr));
769 +       if (addr->class != C_IN) {
770 +           msg_warn("skipping unsupported address (class=%u)", addr->class);
771 +           continue;
772 +       }
773 +       switch (addr->type) {
774 +       case T_A:
775 +           if (addr->data_len != sizeof(sin->sin_addr)) {
776 +               msg_warn("skipping invalid address (AAAA, len=%u)",
777 +                   addr->data_len);
778 +               continue;
779 +           }
780 +           sin = (struct sockaddr_in *)&ss;
781 +           memset(sin, 0, sizeof(*sin));
782 +           sin->sin_family = AF_INET;
783 +#ifdef HAS_SA_LEN
784 +           sin->sin_len = sizeof(*sin);
785 +#endif
786 +           memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr));
787 +           break;
788 +#ifdef INET6
789 +       case T_AAAA:
790 +           if (addr->data_len != sizeof(sin6->sin6_addr)) {
791 +               msg_warn("skipping invalid address (AAAA, len=%u)",
792 +                   addr->data_len);
793 +               continue;
794 +           }
795 +           sin6 = (struct sockaddr_in6 *)&ss;
796 +           memset(sin6, 0, sizeof(*sin6));
797 +           sin6->sin6_family = AF_INET6;
798 +#ifdef HAS_SA_LEN
799 +           sin6->sin6_len = sizeof(*sin6);
800 +#endif
801 +           memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr));
802 +           break;
803 +#endif
804 +       default:
805 +           msg_warn("skipping unsupported address (type=%u)", addr->type);
806 +           continue;
807         }
808 +
809 +#ifdef INET6
810 +       (void)getnameinfo((struct sockaddr *)&ss, SS_LEN(ss),
811 +           hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
812 +#else
813 +       (void)inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf));
814 +#endif
815 +       msg_info("pref %4d host %s/%s", addr->pref, addr->name, hbuf);
816      }
817      msg_info("end %s address list", what);
818  }
819 @@ -155,15 +205,23 @@
820  static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRING *why)
821  {
822      char   *myname = "smtp_addr_one";
823 +#ifndef INET6
824      struct in_addr inaddr;
825 -    DNS_FIXED fixed;
826      DNS_RR *addr = 0;
827      DNS_RR *rr;
828      struct hostent *hp;
829 +#else
830 +    struct addrinfo hints, *res0, *res;
831 +    int error = -1;
832 +    char *addr;
833 +    size_t addrlen;
834 +#endif
835 +    DNS_FIXED fixed;
836  
837      if (msg_verbose)
838         msg_info("%s: host %s", myname, host);
839  
840 +#ifndef INET6
841      /*
842       * Interpret a numerical name as an address.
843       */
844 @@ -216,6 +274,48 @@
845         smtp_errno = SMTP_FAIL;
846         break;
847      }
848 +#else
849 +    memset(&hints, 0, sizeof(hints));
850 +    hints.ai_family = PF_UNSPEC;
851 +    hints.ai_socktype = SOCK_STREAM;
852 +    error = getaddrinfo(host, NULL, &hints, &res0);
853 +    if (error) {
854 +       switch (error) {
855 +       case EAI_AGAIN:
856 +           smtp_errno = SMTP_RETRY;
857 +           break;
858 +       default:
859 +           vstring_sprintf(why, "[%s]: %s",host,gai_strerror(error));
860 +           smtp_errno = SMTP_FAIL;
861 +           break;
862 +       }
863 +       return (addr_list);
864 +    }
865 +    for (res = res0; res; res = res->ai_next) {
866 +       memset((char *) &fixed, 0, sizeof(fixed));
867 +       switch(res->ai_family) {
868 +       case AF_INET6:
869 +           /* XXX not scope friendly */
870 +           fixed.type = T_AAAA;
871 +           addr = (char *)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
872 +           addrlen = sizeof(struct in6_addr);
873 +           break;
874 +       case AF_INET:
875 +           fixed.type = T_A;
876 +           addr = (char *)&((struct sockaddr_in *)res->ai_addr)->sin_addr;
877 +           addrlen = sizeof(struct in_addr);
878 +           break;
879 +       default:
880 +           msg_warn("%s: unknown address family %d for %s",
881 +               myname, res->ai_family, host);
882 +           continue;
883 +       }
884 +       addr_list = dns_rr_append(addr_list,
885 +           dns_rr_create(host, &fixed, pref, addr, addrlen));
886 +    }
887 +    if (res0)
888 +       freeaddrinfo(res0);
889 +#endif
890      return (addr_list);
891  }
892  
893 @@ -251,6 +351,9 @@
894      INET_ADDR_LIST *self;
895      DNS_RR *addr;
896      int     i;
897 +#ifdef INET6
898 +    struct sockaddr *sa;
899 +#endif
900  
901      /*
902       * Find the first address that lists any address that this mail system is
903 @@ -260,12 +363,36 @@
904  
905      self = own_inet_addr_list();
906      for (addr = addr_list; addr; addr = addr->next) {
907 -       for (i = 0; i < self->used; i++)
908 +       for (i = 0; i < self->used; i++) {
909 +#ifdef INET6
910 +           sa = (struct sockaddr *)&self->addrs[i];
911 +           switch(addr->type) {
912 +           case T_AAAA:
913 +               /* XXX scope */
914 +               if (sa->sa_family != AF_INET6)
915 +                   break;
916 +               if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr,
917 +                       addr->data, sizeof(struct in6_addr)) == 0) {
918 +                   return(addr);
919 +               }
920 +               break;
921 +           case T_A:
922 +               if (sa->sa_family != AF_INET)
923 +                   break;
924 +               if (memcmp(&((struct sockaddr_in *)sa)->sin_addr,
925 +                       addr->data, sizeof(struct in_addr)) == 0) {
926 +                   return(addr);
927 +               }
928 +               break;
929 +           }
930 +#else
931             if (INADDRP(addr->data)->s_addr == self->addrs[i].s_addr) {
932                 if (msg_verbose)
933                     msg_info("%s: found at pref %d", myname, addr->pref);
934                 return (addr);
935             }
936 +#endif
937 +       }
938      }
939  
940      /*
941 @@ -273,12 +400,36 @@
942       */
943      self = proxy_inet_addr_list();
944      for (addr = addr_list; addr; addr = addr->next) {
945 -       for (i = 0; i < self->used; i++)
946 +       for (i = 0; i < self->used; i++) {
947 +#ifdef INET6
948 +           sa = (struct sockaddr *)&self->addrs[i];
949 +           switch(addr->type) {
950 +           case T_AAAA:
951 +               /* XXX scope */
952 +               if (sa->sa_family != AF_INET6)
953 +                   break;
954 +               if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr,
955 +                       addr->data, sizeof(struct in6_addr)) == 0) {
956 +                   return(addr);
957 +               }
958 +               break;
959 +           case T_A:
960 +               if (sa->sa_family != AF_INET)
961 +                   break;
962 +               if (memcmp(&((struct sockaddr_in *)sa)->sin_addr,
963 +                       addr->data, sizeof(struct in_addr)) == 0) {
964 +                   return(addr);
965 +               }
966 +               break;
967 +           }
968 +#else
969             if (INADDRP(addr->data)->s_addr == self->addrs[i].s_addr) {
970                 if (msg_verbose)
971                     msg_info("%s: found at pref %d", myname, addr->pref);
972                 return (addr);
973             }
974 +#endif
975 +       }
976      }
977  
978      /*
979 --- postfix-2.0.16.orig/src/smtp/smtp_connect.c 2003-11-08 20:17:08.000000000 +0100
980 +++ postfix-2.0.16/src/smtp/smtp_connect.c      2003-11-08 20:32:33.000000000 +0100
981 @@ -81,6 +81,7 @@
982  /* System library. */
983  
984  #include <sys_defs.h>
985 +#include <stdlib.h>
986  #include <sys/socket.h>
987  #include <netinet/in.h>
988  #include <arpa/inet.h>
989 @@ -110,6 +111,7 @@
990  #include <inet_addr_list.h>
991  #include <iostuff.h>
992  #include <timed_connect.h>
993 +#include <get_port.h>
994  #include <stringops.h>
995  #include <host_port.h>
996  #include <sane_connect.h>
997 @@ -135,19 +137,45 @@
998                                                VSTRING *why)
999  {
1000      char   *myname = "smtp_connect_addr";
1001 -    struct sockaddr_in sin;
1002 -    int     sock;
1003 +#ifdef INET6
1004 +    struct sockaddr_storage ss;
1005 +#else
1006 +    struct sockaddr ss;
1007 +#endif
1008 +    struct sockaddr *sa;
1009 +    struct sockaddr_in *sin;
1010 +#ifdef INET6
1011 +    struct sockaddr_in6 *sin6;
1012 +#endif
1013 +    SOCKADDR_SIZE salen;
1014 +#ifdef INET6
1015 +    char hbuf[NI_MAXHOST];
1016 +#else
1017 +    char hbuf[sizeof("255.255.255.255") + 1];
1018 +#endif
1019 +    int     sock = -1;
1020      INET_ADDR_LIST *addr_list;
1021      int     conn_stat;
1022      int     saved_errno;
1023      VSTREAM *stream;
1024      int     ch;
1025 -    unsigned long inaddr;
1026 +
1027 +    sa = (struct sockaddr *)&ss;
1028 +    sin = (struct sockaddr_in *)&ss;
1029 +#ifdef INET6
1030 +    sin6 = (struct sockaddr_in6 *)&ss;
1031 +#endif
1032  
1033      /*
1034       * Sanity checks.
1035       */
1036 -    if (addr->data_len > sizeof(sin.sin_addr)) {
1037 +#ifdef INET6
1038 +    if (((addr->type==T_A) && (addr->data_len > sizeof(sin->sin_addr))) ||
1039 +       ((addr->type==T_AAAA) && (addr->data_len > sizeof(sin6->sin6_addr))))
1040 +#else
1041 +    if (addr->data_len > sizeof(sin->sin_addr))
1042 +#endif
1043 +    {
1044         msg_warn("%s: skip address with length %d", myname, addr->data_len);
1045         smtp_errno = SMTP_RETRY;
1046         return (0);
1047 @@ -156,17 +184,39 @@
1048      /*
1049       * Initialize.
1050       */
1051 -    memset((char *) &sin, 0, sizeof(sin));
1052 -    sin.sin_family = AF_INET;
1053 -
1054 -    if ((sock = socket(sin.sin_family, SOCK_STREAM, 0)) < 0)
1055 -       msg_fatal("%s: socket: %m", myname);
1056 -
1057 +    switch (addr->type) {
1058 +#ifdef INET6
1059 +    case T_AAAA:
1060 +       memset(sin6, 0, sizeof(*sin6));
1061 +       sin6->sin6_family = AF_INET6;
1062 +       salen = sizeof(*sin6);
1063 +       break;
1064 +#endif
1065 +    default: /* T_A: */
1066 +       memset(sin, 0, sizeof(*sin));
1067 +       sin->sin_family = AF_INET;
1068 +       salen = sizeof(*sin);
1069 +       break;
1070 +    }
1071 +#ifdef HAS_SA_LEN
1072 +    sa->sa_len = salen;
1073 +#endif
1074 +    if ((sock = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
1075 +       msg_warn("%s: socket: %m", myname);
1076 +                   
1077      /*
1078       * Allow the sysadmin to specify the source address, for example, as "-o
1079       * smtp_bind_address=x.x.x.x" in the master.cf file.
1080       */
1081      if (*var_smtp_bind_addr) {
1082 +#ifndef INET6
1083 +       struct sockaddr_in sin;
1084 +
1085 +       memset(&sin, 0, sizeof(sin));
1086 +       sin.sin_family = AF_INET;
1087 +#ifdef HAS_SA_LEN
1088 +       sin.sin_len = sizeof(sin);
1089 +#endif
1090         sin.sin_addr.s_addr = inet_addr(var_smtp_bind_addr);
1091         if (sin.sin_addr.s_addr == INADDR_NONE)
1092             msg_fatal("%s: bad %s parameter: %s",
1093 @@ -175,6 +225,25 @@
1094             msg_warn("%s: bind %s: %m", myname, inet_ntoa(sin.sin_addr));
1095         if (msg_verbose)
1096             msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
1097 +#else
1098 +       char hbufl[NI_MAXHOST];
1099 +       struct addrinfo hints, *res;
1100 +
1101 +       memset(&hints, 0, sizeof(hints));
1102 +       hints.ai_family = sa->sa_family;
1103 +       hints.ai_socktype = SOCK_STREAM;
1104 +       hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST;
1105 +       snprintf(hbufl, sizeof(hbufl)-1, "%s", var_smtp_bind_addr);
1106 +       if (getaddrinfo(hbufl, NULL, &hints, &res) == 0) {
1107 +           (void)getnameinfo(res->ai_addr, res->ai_addrlen, hbufl,
1108 +               sizeof(hbufl), NULL, 0, NI_NUMERICHOST);
1109 +           if (bind(sock, res->ai_addr, res->ai_addrlen) < 0)
1110 +               msg_warn("%s: bind %s: %m", myname, hbufl);
1111 +           freeaddrinfo(res);
1112 +           if (msg_verbose)
1113 +               msg_info("%s: bind %s", myname, hbufl);
1114 +       }
1115 +#endif
1116      }
1117  
1118      /*
1119 @@ -182,8 +251,17 @@
1120       * the mail appears to come from the "right" machine address.
1121       */
1122      else if ((addr_list = own_inet_addr_list())->used == 1) {
1123 +#ifndef INET6
1124 +       struct sockaddr_in sin;
1125 +       unsigned long inaddr;   /*XXX BAD!*/
1126 +
1127 +       memset(&sin, 0, sizeof(sin));
1128 +       sin.sin_family = AF_INET;
1129 +#ifdef HAS_SA_LEN
1130 +       sin.sin_len = sizeof(sin);
1131 +#endif
1132         memcpy((char *) &sin.sin_addr, addr_list->addrs, sizeof(sin.sin_addr));
1133 -       inaddr = ntohl(sin.sin_addr.s_addr);
1134 +       inaddr = (unsigned long)ntohl(sin.sin_addr.s_addr);
1135         if (!IN_CLASSA(inaddr)
1136             || !(((inaddr & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)) {
1137             if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
1138 @@ -191,30 +269,85 @@
1139             if (msg_verbose)
1140                 msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
1141         }
1142 +#else
1143 +       char hbufl[NI_MAXHOST];
1144 +       struct addrinfo hints, *res = NULL, *loopback = NULL;
1145 +
1146 +       memset(&hints, 0, sizeof(hints));
1147 +       hints.ai_family = sa->sa_family;
1148 +       hints.ai_socktype = SOCK_STREAM;
1149 +       if (getaddrinfo(NULL, "0", &hints, &loopback) != 0)
1150 +           loopback = NULL;
1151 +
1152 +       /*
1153 +        * getnameinfo -> getaddrinfo loop is here so that we can
1154 +        * get rid of port.
1155 +        */
1156 +       (void)getnameinfo((struct sockaddr *)addr_list->addrs, SA_LEN((struct sockaddr *)addr_list->addrs),
1157 +           hbufl, sizeof(hbufl), NULL, 0, NI_NUMERICHOST);
1158 +       hbufl[sizeof(hbufl)-1] = 0;
1159 +       memset(&hints, 0, sizeof(hints));
1160 +       hints.ai_family = sa->sa_family;
1161 +       hints.ai_socktype = SOCK_STREAM;
1162 +       hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST;
1163 +       if (getaddrinfo(hbufl, NULL, &hints, &res) == 0 &&
1164 +           !(res->ai_addrlen == loopback->ai_addrlen &&
1165 +             memcmp(res->ai_addr, loopback->ai_addr, res->ai_addrlen) == 0)) {
1166 +           if (bind(sock, res->ai_addr, res->ai_addrlen) < 0)
1167 +                msg_warn("%s: bind %s: %m", myname, hbufl);
1168 +           if (msg_verbose)
1169 +                msg_info("%s: bind %s", myname, hbufl);
1170 +       }
1171 +       if (res)
1172 +           freeaddrinfo(res);
1173 +       if (loopback)
1174 +           freeaddrinfo(loopback);
1175 +#endif
1176      }
1177  
1178      /*
1179       * Connect to the SMTP server.
1180       */
1181 -    sin.sin_port = port;
1182 -    memcpy((char *) &sin.sin_addr, addr->data, sizeof(sin.sin_addr));
1183 +    switch (addr->type) {
1184 +#ifdef INET6
1185 +    case T_AAAA:
1186 +       /* XXX scope unfriendly */
1187 +       memset(sin6, 0, sizeof(*sin6));
1188 +       sin6->sin6_port = port;
1189 +       sin6->sin6_family = AF_INET6;
1190 +       salen = sizeof(*sin6);
1191 +       memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr));
1192 +       inet_ntop(AF_INET6, &sin6->sin6_addr, hbuf, sizeof(hbuf));
1193 +       break;
1194 +#endif
1195 +    default: /* T_A */
1196 +       memset(sin, 0, sizeof(*sin));
1197 +       sin->sin_port = port;
1198 +       sin->sin_family = AF_INET;
1199 +       salen = sizeof(*sin);
1200 +       memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr));
1201 +       inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf));
1202 +       break;
1203 +    }
1204 +#ifdef HAS_SA_LEN
1205 +    sa->sa_len = salen;
1206 +#endif
1207  
1208      if (msg_verbose)
1209         msg_info("%s: trying: %s[%s] port %d...",
1210 -                myname, addr->name, inet_ntoa(sin.sin_addr), ntohs(port));
1211 +                myname, addr->name, hbuf, ntohs(port));
1212      if (var_smtp_conn_tmout > 0) {
1213         non_blocking(sock, NON_BLOCKING);
1214 -       conn_stat = timed_connect(sock, (struct sockaddr *) & sin,
1215 -                                 sizeof(sin), var_smtp_conn_tmout);
1216 +       conn_stat = timed_connect(sock, sa, salen, var_smtp_conn_tmout);
1217         saved_errno = errno;
1218         non_blocking(sock, BLOCKING);
1219         errno = saved_errno;
1220      } else {
1221 -       conn_stat = sane_connect(sock, (struct sockaddr *) & sin, sizeof(sin));
1222 +       conn_stat = connect(sock, sa, salen);
1223      }
1224      if (conn_stat < 0) {
1225         vstring_sprintf(why, "connect to %s[%s]: %m",
1226 -                       addr->name, inet_ntoa(sin.sin_addr));
1227 +                       addr->name, hbuf);
1228         smtp_errno = SMTP_RETRY;
1229         close(sock);
1230         return (0);
1231 @@ -224,8 +357,8 @@
1232       * Skip this host if it takes no action within some time limit.
1233       */
1234      if (read_wait(sock, var_smtp_helo_tmout) < 0) {
1235 -       vstring_sprintf(why, "connect to %s[%s]: read timeout",
1236 -                       addr->name, inet_ntoa(sin.sin_addr));
1237 +       vstring_sprintf(why, "connect to %s [%s]: read timeout",
1238 +                       addr->name, hbuf);
1239         smtp_errno = SMTP_RETRY;
1240         close(sock);
1241         return (0);
1242 @@ -237,7 +370,7 @@
1243      stream = vstream_fdopen(sock, O_RDWR);
1244      if ((ch = VSTREAM_GETC(stream)) == VSTREAM_EOF) {
1245         vstring_sprintf(why, "connect to %s[%s]: server dropped connection without sending the initial greeting",
1246 -                       addr->name, inet_ntoa(sin.sin_addr));
1247 +                       addr->name, hbuf);
1248         smtp_errno = SMTP_RETRY;
1249         vstream_fclose(stream);
1250         return (0);
1251 @@ -249,7 +382,7 @@
1252       */
1253      if (ch == '4' && var_smtp_skip_4xx_greeting) {
1254         vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
1255 -                       addr->name, inet_ntoa(sin.sin_addr));
1256 +                       addr->name, hbuf);
1257         smtp_errno = SMTP_RETRY;
1258         vstream_fclose(stream);
1259         return (0);
1260 @@ -260,12 +393,12 @@
1261       */
1262      if (ch == '5' && var_smtp_skip_5xx_greeting) {
1263         vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
1264 -                       addr->name, inet_ntoa(sin.sin_addr));
1265 +                       addr->name, hbuf);
1266         smtp_errno = SMTP_RETRY;
1267         vstream_fclose(stream);
1268         return (0);
1269      }
1270 -    return (smtp_session_alloc(dest, stream, addr->name, inet_ntoa(sin.sin_addr)));
1271 +    return (smtp_session_alloc(dest, stream, addr->name, hbuf));
1272  }
1273  
1274  /* smtp_connect_host - direct connection to host */
1275 --- postfix-2.0.16.orig/src/smtp/smtp_unalias.c 2000-09-28 19:06:09.000000000 +0200
1276 +++ postfix-2.0.16/src/smtp/smtp_unalias.c      2003-11-08 20:22:55.000000000 +0100
1277 @@ -86,7 +86,11 @@
1278      if ((result = htable_find(cache, name)) == 0) {
1279         fqdn = vstring_alloc(10);
1280         if (dns_lookup_types(name, smtp_unalias_flags, (DNS_RR **) 0,
1281 -                            fqdn, (VSTRING *) 0, T_MX, T_A, 0) != DNS_OK)
1282 +                            fqdn, (VSTRING *) 0, T_MX, T_A,
1283 +#ifdef INET6
1284 +                            T_AAAA,
1285 +#endif
1286 +                            0) != DNS_OK)
1287             vstring_strcpy(fqdn, name);
1288         htable_enter(cache, name, result = vstring_export(fqdn));
1289      }
1290 --- postfix-2.0.16.orig/src/smtpd/smtpd_check.c 2003-11-08 20:17:08.000000000 +0100
1291 +++ postfix-2.0.16/src/smtpd/smtpd_check.c      2003-11-08 20:22:55.000000000 +0100
1292 @@ -1369,6 +1369,49 @@
1293  static int has_my_addr(SMTPD_STATE *state, const char *host,
1294                             const char *reply_name, const char *reply_class)
1295  {
1296 +#ifdef INET6
1297 +    char   *myname = "has_my_addr";
1298 +    struct addrinfo hints, *res, *res0;
1299 +    int error;
1300 +    char hbuf[NI_MAXHOST];
1301 +
1302 +    if (msg_verbose)
1303 +       msg_info("%s: host %s", myname, host);
1304 +
1305 +    /*
1306 +     * If we can't lookup the host, play safe and assume it is OK.
1307 +     */
1308 +#define YUP    1
1309 +#define NOPE   0
1310 +
1311 +    memset(&hints, 0, sizeof(hints));
1312 +    hints.ai_family = PF_UNSPEC;
1313 +    hints.ai_socktype = SOCK_DGRAM;
1314 +    error = getaddrinfo(host, NULL, &hints, &res0);
1315 +    if (error) {
1316 +       if (msg_verbose)
1317 +           msg_info("%s: host %s: %s", myname, host, gai_strerror(error));
1318 +       return (YUP);
1319 +    }
1320 +    for (res = res0; res; res = res->ai_next) {
1321 +       if (msg_verbose) {
1322 +           if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
1323 +                   NULL, 0, NI_NUMERICHOST)) {
1324 +               strncpy(hbuf, "???", sizeof(hbuf));
1325 +           }
1326 +           msg_info("%s: addr %s", myname, hbuf);
1327 +       }
1328 +       if (own_inet_addr(res->ai_addr)) {
1329 +           freeaddrinfo(res0);
1330 +           return (YUP);
1331 +       }
1332 +    }
1333 +    freeaddrinfo(res0);
1334 +    if (msg_verbose)
1335 +       msg_info("%s: host %s: no match", myname, host);
1336 +
1337 +    return (NOPE);
1338 +#else
1339      char   *myname = "has_my_addr";
1340      struct in_addr addr;
1341      char  **cpp;
1342 @@ -1407,6 +1450,7 @@
1343         msg_info("%s: host %s: no match", myname, host);
1344  
1345      return (NOPE);
1346 +#endif
1347  }
1348  
1349  /* i_am_mx - is this machine listed as MX relay */
1350 @@ -1991,11 +2035,28 @@
1351  #define CHK_ADDR_RETURN(x,y) { *found = y; return(x); }
1352  
1353      addr = STR(vstring_strcpy(error_text, address));
1354 -
1355 +#ifdef INET6
1356 +    if (strncmp(addr, "::ffff:", 7) == 0 && msg_verbose)
1357 +       msg_info("%s: %s v6 addr in v4 compat-mode, "
1358 +               "converted to v4 for map checking compatibility (%s)", \
1359 +               myname, addr, addr+7);
1360 +#endif
1361 +    
1362      if ((dict = dict_handle(table)) == 0)
1363         msg_panic("%s: dictionary not found: %s", myname, table);
1364      do {
1365         if (flags == 0 || (flags & dict->flags) != 0) {
1366 +#ifdef INET6
1367 +           if (strncmp(addr, "::ffff:", 7) == 0) {
1368 +               /* try if ::ffff: formati is present in map, if not, try
1369 +                  traditional IPv4 format striping :ffff: part */
1370 +               if ((value = dict_get(dict, addr)) != 0 || \
1371 +                               (value = dict_get(dict, addr+7)) != 0)
1372 +                       CHK_ADDR_RETURN(check_table_result(state, table, value, address,
1373 +                                                  reply_name, reply_class,
1374 +                                                  def_acl), FOUND);    
1375 +           } else
1376 +#endif
1377             if ((value = dict_get(dict, addr)) != 0)
1378                 CHK_ADDR_RETURN(check_table_result(state, table, value, address,
1379                                                    reply_name, reply_class,
1380 @@ -2438,16 +2499,32 @@
1381      VSTRING *query;
1382      int     i;
1383      SMTPD_RBL_STATE *rbl;
1384 +#ifdef INET6
1385 +    struct in_addr a;
1386 +#else
1387 +    struct in6_addr a;
1388 +#endif
1389  
1390      if (msg_verbose)
1391         msg_info("%s: %s %s", myname, reply_class, addr);
1392  
1393 -    /*
1394 -     * IPv4 only for now
1395 -     */
1396 -#ifdef INET6
1397 +#ifndef INET6
1398 +    /* IPv4 only for now */
1399      if (inet_pton(AF_INET, addr, &a) != 1)
1400         return SMTPD_CHECK_DUNNO;
1401 +    octets = argv_split(state->addr, ".");
1402 +#else
1403 +    /* IPv4 and IPv6-mapped IPv4 only for now */
1404 +    if (inet_pton(AF_INET, state->addr, &a) == 1)
1405 +       octets = argv_split(state->addr, ".");
1406 +    else {
1407 +       struct in6_addr a6;
1408 +       if (inet_pton(AF_INET6, state->addr, &a6) != 1)
1409 +         return SMTPD_CHECK_DUNNO;
1410 +       if (!IN6_IS_ADDR_V4MAPPED(&a6) || (strrchr(state->addr,':') == NULL))
1411 +         return SMTPD_CHECK_DUNNO;
1412 +       octets = argv_split(strrchr(state->addr,':')+1, ".");
1413 +    }
1414  #endif
1415  
1416      /*
1417 --- postfix-2.0.16.orig/src/smtpd/smtpd_peer.c  2002-08-22 19:50:51.000000000 +0200
1418 +++ postfix-2.0.16/src/smtpd/smtpd_peer.c       2003-11-08 20:22:55.000000000 +0100
1419 @@ -63,6 +63,15 @@
1420  #include <netdb.h>
1421  #include <string.h>
1422  
1423 +/* Utility library. */
1424 +
1425 +#include <msg.h>
1426 +#include <mymalloc.h>
1427 +#include <valid_hostname.h>
1428 +#include <stringops.h>
1429 +
1430 +/* Global library. */
1431 +
1432   /*
1433    * Older systems don't have h_errno. Even modern systems don't have
1434    * hstrerror().
1435 @@ -84,16 +93,11 @@
1436      )
1437  #endif
1438  
1439 -/* Utility library. */
1440 -
1441 -#include <msg.h>
1442 -#include <mymalloc.h>
1443 -#include <valid_hostname.h>
1444 -#include <stringops.h>
1445 -
1446 -/* Global library. */
1447 -
1448 -
1449 +#ifdef INET6
1450 +#define GAI_STRERROR(error) \
1451 +       ((error = EAI_SYSTEM) ? gai_strerror(error) : strerror(errno))
1452 +#endif
1453 +       
1454  /* Application-specific. */
1455  
1456  #include "smtpd.h"
1457 @@ -102,21 +106,28 @@
1458  
1459  void    smtpd_peer_init(SMTPD_STATE *state)
1460  {
1461 -    struct sockaddr_in sin;
1462 -    SOCKADDR_SIZE len = sizeof(sin);
1463 +#ifdef INET6
1464 +    struct sockaddr_storage ss;
1465 +#else
1466 +    struct sockaddr ss;
1467 +    struct in_addr *in;
1468      struct hostent *hp;
1469 -    int     i;
1470 +#endif
1471 +    struct sockaddr *sa;
1472 +    SOCKADDR_SIZE len;
1473 +
1474 +    sa = (struct sockaddr *)&ss;
1475 +    len = sizeof(ss);
1476  
1477      /*
1478       * Avoid suprious complaints from Purify on Solaris.
1479       */
1480 -    memset((char *) &sin, 0, len);
1481 +    memset((char *) sa, 0, len);
1482  
1483      /*
1484       * Look up the peer address information.
1485       */
1486 -    if (getpeername(vstream_fileno(state->client),
1487 -                   (struct sockaddr *) & sin, &len) >= 0) {
1488 +    if (getpeername(vstream_fileno(state->client), sa, &len) >= 0) {
1489         errno = 0;
1490      }
1491  
1492 @@ -132,23 +143,56 @@
1493      /*
1494       * Look up and "verify" the client hostname.
1495       */
1496 -    else if (errno == 0 && sin.sin_family == AF_INET) {
1497 -       state->addr = mystrdup(inet_ntoa(sin.sin_addr));
1498 -       hp = gethostbyaddr((char *) &(sin.sin_addr),
1499 -                          sizeof(sin.sin_addr), AF_INET);
1500 -       if (hp == 0) {
1501 +    else if (errno == 0 && (sa->sa_family == AF_INET
1502 +#ifdef INET6
1503 +                           || sa->sa_family == AF_INET6
1504 +#endif
1505 +                   )) {
1506 +#ifdef INET6
1507 +       char hbuf[NI_MAXHOST];
1508 +       char abuf[NI_MAXHOST];
1509 +       struct addrinfo hints, *rnull = NULL;
1510 +#else
1511 +       char abuf[sizeof("255.255.255.255") + 1];
1512 +       char *hbuf;
1513 +#endif
1514 +       int error = -1;
1515 +
1516 +#ifdef INET6
1517 +       (void)getnameinfo(sa, len, abuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
1518 +#else
1519 +       in = &((struct sockaddr_in *)sa)->sin_addr;
1520 +       inet_ntop(AF_INET, in, abuf, sizeof(hbuf));
1521 +#endif
1522 +       state->addr = mystrdup(abuf);
1523 +#ifdef INET6
1524 +       error = getnameinfo(sa, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD);
1525 +#else
1526 +       hbuf = NULL;
1527 +       hp = gethostbyaddr((char *)in, sizeof(*in), AF_INET);
1528 +       if (hp) {
1529 +           error = 0;
1530 +               hbuf = mystrdup(hp->h_name);
1531 +       } else
1532 +           error = 1;
1533 +#endif
1534 +       if (error) {
1535             state->name = mystrdup("unknown");
1536 +#ifdef INET6
1537 +               state->peer_code = (error == EAI_AGAIN ? 4 : 5);
1538 +#else
1539             state->peer_code = (h_errno == TRY_AGAIN ? 4 : 5);
1540 -       } else if (valid_hostaddr(hp->h_name, DONT_GRIPE)) {
1541 +#endif
1542 +       } else if (valid_hostaddr(hbuf, DONT_GRIPE)) {
1543             msg_warn("numeric result %s in address->name lookup for %s",
1544 -                    hp->h_name, state->addr);
1545 +                    hbuf, state->addr);
1546             state->name = mystrdup("unknown");
1547             state->peer_code = 5;
1548 -       } else if (!valid_hostname(hp->h_name, DONT_GRIPE)) {
1549 +       } else if (!valid_hostname(hbuf, DONT_GRIPE)) {
1550             state->name = mystrdup("unknown");
1551             state->peer_code = 5;
1552         } else {
1553 -           state->name = mystrdup(hp->h_name); /* hp->name is clobbered!! */
1554 +           state->name = mystrdup(hbuf);       /* hp->name is clobbered!! */
1555             state->peer_code = 2;
1556  
1557             /*
1558 @@ -160,16 +204,31 @@
1559         state->peer_code = code; \
1560      }
1561  
1562 +#ifdef INET6
1563 +           memset(&hints, 0, sizeof(hints));
1564 +           hints.ai_family = AF_UNSPEC;
1565 +           hints.ai_socktype = SOCK_STREAM;
1566 +           error = getaddrinfo(state->name, NULL, &hints, &rnull);
1567 +           if (error) {
1568 +               msg_warn("%s: hostname %s verification failed: %s",
1569 +                        state->addr, state->name, GAI_STRERROR(error));
1570 +               REJECT_PEER_NAME(state, (error == EAI_AGAIN ? 4 : 5));
1571 +           }
1572 +           /* memcmp() isn't needed if we use getaddrinfo */
1573 +           if (rnull)
1574 +               freeaddrinfo(rnull);
1575 +#else
1576             hp = gethostbyname(state->name);    /* clobbers hp->name!! */
1577             if (hp == 0) {
1578                 msg_warn("%s: hostname %s verification failed: %s",
1579                          state->addr, state->name, HSTRERROR(h_errno));
1580                 REJECT_PEER_NAME(state, (h_errno == TRY_AGAIN ? 4 : 5));
1581 -           } else if (hp->h_length != sizeof(sin.sin_addr)) {
1582 +           } else if (hp->h_length != sizeof(*in)) {
1583                 msg_warn("%s: hostname %s verification failed: bad address size %d",
1584                          state->addr, state->name, hp->h_length);
1585                 REJECT_PEER_NAME(state, 5);
1586             } else {
1587 +               int i;
1588                 for (i = 0; /* void */ ; i++) {
1589                     if (hp->h_addr_list[i] == 0) {
1590                         msg_warn("%s: address not listed for hostname %s",
1591 @@ -177,12 +236,11 @@
1592                         REJECT_PEER_NAME(state, 5);
1593                         break;
1594                     }
1595 -                   if (memcmp(hp->h_addr_list[i],
1596 -                              (char *) &sin.sin_addr,
1597 -                              sizeof(sin.sin_addr)) == 0)
1598 +                   if (memcmp(hp->h_addr_list[i], (char *)in, sizeof(*in)) == 0)
1599                         break;                  /* keep peer name */
1600                 }
1601             }
1602 +#endif
1603         }
1604      }
1605  
1606 --- postfix-2.0.16.orig/src/smtpstone/smtp-sink.c       2003-09-13 02:46:56.000000000 +0200
1607 +++ postfix-2.0.16/src/smtpstone/smtp-sink.c    2003-11-08 20:22:55.000000000 +0100
1608 @@ -607,7 +607,7 @@
1609      } else {
1610         if (strncmp(argv[optind], "inet:", 5) == 0)
1611             argv[optind] += 5;
1612 -       sock = inet_listen(argv[optind], backlog, BLOCKING);
1613 +       sock = inet_listen(argv[optind], backlog, BLOCKING, 1);
1614      }
1615  
1616      /*
1617 --- postfix-2.0.16.orig/src/util/get_port.c     1970-01-01 01:00:00.000000000 +0100
1618 +++ postfix-2.0.16/src/util/get_port.c  2003-11-08 20:22:55.000000000 +0100
1619 @@ -0,0 +1,65 @@
1620 +/*++
1621 +/* NAME
1622 +/*     get_port 3
1623 +/* SUMMARY
1624 +/*     trivial host and port extracter
1625 +/* SYNOPSIS
1626 +/*     #include <get_port.h>
1627 +/*
1628 +/*     char    *get_port(data)
1629 +/*     char    *data;
1630 +/*
1631 +/* DESCRIPTION
1632 +/*     get_port() extract host name or ip address from
1633 +/*     strings such as [3ffe:902:12::10]:25, [::1]
1634 +/*     or 192.168.0.1:25, and null-terminates the
1635 +/*     \fIdata\fR at the first occurrence of port separator.
1636 +/* DIAGNOSTICS
1637 +/*     If port not found return null pointer.
1638 +/* LICENSE
1639 +/* .ad
1640 +/* .fi
1641 +/*     BSD Style (or BSD like) license.
1642 +/* AUTHOR(S)
1643 +/*     Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
1644 +/*     Wroclaw, POLAND
1645 +/*--*/
1646 +
1647 +/* System libraries */
1648 +
1649 +#include <sys_defs.h>
1650 +#include <string.h>
1651 +
1652 +/* Utility library. */
1653 +
1654 +#include "get_port.h"
1655 +
1656 +/* get_port - extract port number from string */
1657 +
1658 +char *get_port(char *data)
1659 +{
1660 +       const char *escl=strchr(data,'[');
1661 +       const char *sepl=strchr(data,':');
1662 +       char *escr=strrchr(data,']');
1663 +       char *sepr=strrchr(data,':');
1664 +
1665 +       /* extract from "[address]:port" or "[address]"*/
1666 +       if (escl && escr)
1667 +       {
1668 +               memmove(data, data + 1, strlen(data) - strlen(escr));
1669 +               data[strlen(data) - strlen(escr) - 1] = 0;
1670 +               *escr++ = 0;
1671 +               if (*escr == ':')
1672 +                       escr++;
1673 +               return (*escr ? escr : NULL);
1674 +       }
1675 +       /* extract from "address:port" or "address" */
1676 +       if ((sepl == sepr) && sepr && sepl)
1677 +       {
1678 +               *sepr++ = 0;
1679 +               return sepr;
1680 +       }
1681 +
1682 +       /* return empty string */
1683 +       return NULL;
1684 +}
1685 --- postfix-2.0.16.orig/src/util/get_port.h     1970-01-01 01:00:00.000000000 +0100
1686 +++ postfix-2.0.16/src/util/get_port.h  2003-11-08 20:22:55.000000000 +0100
1687 @@ -0,0 +1,28 @@
1688 +#ifndef _GET_PORT_H_INCLUDED_
1689 +#define _GET_PORT_H_INCLUDED_
1690 +
1691 +/*++
1692 +/* NAME
1693 +/*     get_port 3h
1694 +/* SUMMARY
1695 +/*     trivial host and port extracter
1696 +/* SYNOPSIS
1697 +/*     #include <get_port.h>
1698 +/* DESCRIPTION
1699 +/* .nf
1700 +
1701 + /* External interface. */
1702 +
1703 +extern char *get_port(char *);
1704 +
1705 +
1706 +/* LICENSE
1707 +/* .ad
1708 +/* .fi
1709 +/*     BSD Style (or BSD like) license.
1710 +/* AUTHOR(S)
1711 +/*     Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
1712 +/*     Wroclaw, POLAND
1713 +/*--*/
1714 +
1715 +#endif
1716 --- postfix-2.0.16.orig/src/util/inet_addr_host.c       1998-12-11 19:55:35.000000000 +0100
1717 +++ postfix-2.0.16/src/util/inet_addr_host.c    2003-11-08 20:22:55.000000000 +0100
1718 @@ -38,7 +38,10 @@
1719  #include <sys_defs.h>
1720  #include <netinet/in.h>
1721  #include <arpa/inet.h>
1722 +#include <sys/socket.h>
1723  #include <netdb.h>
1724 +#include <stdlib.h>
1725 +#include <string.h>
1726  
1727  #ifndef INADDR_NONE
1728  #define INADDR_NONE 0xffffffff
1729 @@ -48,15 +51,47 @@
1730  
1731  #include <inet_addr_list.h>
1732  #include <inet_addr_host.h>
1733 +#ifdef TEST
1734 +#include <msg.h>
1735 +#endif
1736  
1737  /* inet_addr_host - look up address list for host */
1738  
1739  int     inet_addr_host(INET_ADDR_LIST *addr_list, const char *hostname)
1740  {
1741 +#ifdef INET6
1742 +    int s;
1743 +    struct addrinfo hints, *res0, *res;
1744 +#ifdef TEST    
1745 +       char buforhosta[1024];
1746 +#endif 
1747 +    int error;
1748 +#else
1749      struct hostent *hp;
1750      struct in_addr addr;
1751 +#endif
1752      int     initial_count = addr_list->used;
1753  
1754 +#ifdef INET6
1755 +    memset(&hints, 0, sizeof(hints));
1756 +    hints.ai_family = PF_UNSPEC;
1757 +    hints.ai_socktype = SOCK_DGRAM;
1758 +    error = getaddrinfo(hostname, NULL, &hints, &res0);
1759 +    if (error == 0) {
1760 +       for (res = res0; res; res = res->ai_next) {
1761 +           if(res->ai_family != AF_INET && res->ai_family != AF_INET6)
1762 +               continue;
1763 +           /* filter out address families that are not supported */
1764 +           s = socket(res->ai_family, SOCK_DGRAM, 0);
1765 +           if (s < 0)
1766 +               continue;
1767 +           close(s);
1768 +
1769 +           inet_addr_list_append(addr_list, res->ai_addr);
1770 +       }
1771 +       freeaddrinfo(res0);
1772 +    }
1773 +#else
1774      if ((addr.s_addr = inet_addr(hostname)) != INADDR_NONE) {
1775         inet_addr_list_append(addr_list, &addr);
1776      } else {
1777 @@ -65,9 +100,12 @@
1778                 inet_addr_list_append(addr_list,
1779                                     (struct in_addr *) * hp->h_addr_list++);
1780      }
1781 +#endif
1782 +
1783      return (addr_list->used - initial_count);
1784  }
1785  
1786 +
1787  #ifdef TEST
1788  
1789  #include <msg.h>
1790 @@ -78,6 +116,8 @@
1791  {
1792      INET_ADDR_LIST addr_list;
1793      int     i;
1794 +    struct sockaddr *sa;
1795 +    char hbuf[NI_MAXHOST];
1796  
1797      msg_vstream_init(argv[0], VSTREAM_ERR);
1798  
1799 @@ -89,8 +129,12 @@
1800         if (inet_addr_host(&addr_list, *argv) == 0)
1801             msg_fatal("not found: %s", *argv);
1802  
1803 -       for (i = 0; i < addr_list.used; i++)
1804 -           vstream_printf("%s\n", inet_ntoa(addr_list.addrs[i]));
1805 +       for (i = 0; i < addr_list.used; i++) {
1806 +           sa = (struct sockaddr *)&addr_list.addrs[i];
1807 +           getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
1808 +                   NI_NUMERICHOST);
1809 +           vstream_printf("%s\n", hbuf);
1810 +       }
1811         vstream_fflush(VSTREAM_OUT);
1812      }
1813      inet_addr_list_free(&addr_list);
1814 --- postfix-2.0.16.orig/src/util/inet_addr_list.c       2001-07-31 20:13:41.000000000 +0200
1815 +++ postfix-2.0.16/src/util/inet_addr_list.c    2003-11-08 20:22:55.000000000 +0100
1816 @@ -51,6 +51,13 @@
1817  #include <arpa/inet.h>
1818  #include <stdlib.h>
1819  
1820 +#include <netdb.h>
1821 +
1822 +#ifdef INET6
1823 +#include <string.h>
1824 +#include <sys/socket.h>
1825 +#endif
1826 +
1827  /* Utility library. */
1828  
1829  #include <msg.h>
1830 @@ -63,12 +70,39 @@
1831  {
1832      list->used = 0;
1833      list->size = 2;
1834 +#ifdef INET6
1835 +    list->addrs = (struct sockaddr_storage *)
1836 +#else
1837      list->addrs = (struct in_addr *)
1838 +#endif
1839         mymalloc(sizeof(*list->addrs) * list->size);
1840  }
1841  
1842  /* inet_addr_list_append - append address to internet address list */
1843  
1844 +#ifdef INET6
1845 +void    inet_addr_list_append(INET_ADDR_LIST *list, 
1846 +                              struct sockaddr * addr)
1847 +{
1848 +    char   *myname = "inet_addr_list_append";
1849 +    char hbuf[NI_MAXHOST];
1850 +
1851 +    if (msg_verbose > 1) {
1852 +       if (getnameinfo(addr, SA_LEN(addr), hbuf, sizeof(hbuf), NULL, 0,
1853 +           NI_NUMERICHOST)) {
1854 +           strncpy(hbuf, "??????", sizeof(hbuf));
1855 +       }
1856 +       msg_info("%s: %s", myname, hbuf);
1857 +    }
1858 +
1859 +    if (list->used >= list->size)
1860 +       list->size *= 2;
1861 +    list->addrs = (struct sockaddr_storage *)
1862 +       myrealloc((char *) list->addrs,
1863 +                 sizeof(*list->addrs) * list->size);
1864 +    memcpy(&list->addrs[list->used++], addr, SA_LEN(addr));
1865 +}
1866 +#else
1867  void    inet_addr_list_append(INET_ADDR_LIST *list, struct in_addr * addr)
1868  {
1869      char   *myname = "inet_addr_list_append";
1870 @@ -83,15 +117,22 @@
1871                   sizeof(*list->addrs) * list->size);
1872      list->addrs[list->used++] = *addr;
1873  }
1874 +#endif
1875  
1876  /* inet_addr_list_comp - compare addresses */
1877  
1878  static int inet_addr_list_comp(const void *a, const void *b)
1879  {
1880 +#ifdef INET6
1881 +    if(((struct sockaddr*)a)->sa_family != ((struct sockaddr*)b)->sa_family)
1882 +       return ( ((struct sockaddr*)a)->sa_family - ((struct sockaddr*)b)->sa_family );
1883 +    return memcmp(a,b,SA_LEN((struct sockaddr*)a));
1884 +#else
1885      const struct in_addr *a_addr = (const struct in_addr *) a;
1886      const struct in_addr *b_addr = (const struct in_addr *) b;
1887  
1888      return (a_addr->s_addr - b_addr->s_addr);
1889 +#endif
1890  }
1891  
1892  /* inet_addr_list_uniq - weed out duplicates */
1893 --- postfix-2.0.16.orig/src/util/inet_addr_list.h       2001-07-31 19:56:47.000000000 +0200
1894 +++ postfix-2.0.16/src/util/inet_addr_list.h    2003-11-08 20:22:55.000000000 +0100
1895 @@ -16,19 +16,38 @@
1896    */
1897  #include <netinet/in.h>
1898  
1899 +#ifndef SA_LEN
1900 +#ifndef HAS_SA_LEN
1901 +#define SA_LEN(x)      (((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
1902 +#define SS_LEN(x)      (((x).ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
1903 +#else
1904 +#define SA_LEN(x)       ((x)->sa_len)
1905 +#define SS_LEN(x)       ((x).ss_len)
1906 +#endif
1907 +#endif
1908 +       
1909   /*
1910    * External interface.
1911    */
1912  typedef struct INET_ADDR_LIST {
1913      int     used;                      /* nr of elements in use */
1914      int     size;                      /* actual list size */
1915 +#ifdef INET6
1916 +    struct sockaddr_storage *addrs;   /* payload */
1917 +#else
1918      struct in_addr *addrs;             /* payload */
1919 +#endif
1920  } INET_ADDR_LIST;
1921  
1922  extern void inet_addr_list_init(INET_ADDR_LIST *);
1923  extern void inet_addr_list_free(INET_ADDR_LIST *);
1924  extern void inet_addr_list_uniq(INET_ADDR_LIST *);
1925 +#ifdef INET6
1926 +struct sockaddr;
1927 +extern void inet_addr_list_append(INET_ADDR_LIST *, struct sockaddr *);
1928 +#else
1929  extern void inet_addr_list_append(INET_ADDR_LIST *, struct in_addr *);
1930 +#endif
1931  
1932  /* LICENSE
1933  /* .ad
1934 --- postfix-2.0.16.orig/src/util/inet_addr_local.c      2001-02-25 19:20:19.000000000 +0100
1935 +++ postfix-2.0.16/src/util/inet_addr_local.c   2003-11-08 20:22:55.000000000 +0100
1936 @@ -47,6 +47,13 @@
1937  #endif
1938  #include <errno.h>
1939  #include <string.h>
1940 +#if defined(INET6) && (defined (LINUX) || defined (LINUX2))
1941 +#include <netdb.h>
1942 +#include <stdio.h>
1943 +#endif
1944 +#ifdef HAVE_GETIFADDRS
1945 +#include <ifaddrs.h>
1946 +#endif
1947  
1948  /* Utility library. */
1949  
1950 @@ -78,18 +85,104 @@
1951  
1952  int     inet_addr_local(INET_ADDR_LIST *addr_list, INET_ADDR_LIST *mask_list)
1953  {
1954 +#ifdef HAVE_GETIFADDRS
1955 +    char *myname = "inet_addr_local";
1956 +    struct ifaddrs *ifap, *ifa;
1957 +    int initial_count = addr_list->used;
1958 +    struct sockaddr *sa, *sam;
1959 +#ifdef INET6
1960 +#ifdef __KAME__
1961 +    struct sockaddr_in6 addr6;
1962 +#endif
1963 +#else
1964 +    void *addr,*addrm;
1965 +#endif
1966 +
1967 +    if (getifaddrs(&ifap) < 0)
1968 +       msg_fatal("%s: getifaddrs: %m", myname);
1969 +
1970 +    for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1971 +               if ((!(ifa->ifa_flags & IFF_RUNNING)) || (ifa->ifa_addr == NULL) || (ifa->ifa_netmask == NULL))
1972 +                       continue;
1973 +       sa = ifa->ifa_addr;
1974 +       sam = ifa->ifa_netmask;
1975 +       switch (ifa->ifa_addr->sa_family) {
1976 +       case AF_INET:
1977 +#ifndef INET6
1978 +           addr = (void *)&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
1979 +           addrm = (void *)&((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
1980 +#endif
1981 +           break;
1982 +#ifdef INET6
1983 +       case AF_INET6:
1984 +#ifdef __KAME__
1985 +           memcpy(&addr6, ifa->ifa_addr, ifa->ifa_addr->sa_len);
1986 +           /* decode scoped address notation */
1987 +           if ((IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) ||
1988 +                IN6_IS_ADDR_SITELOCAL(&addr6.sin6_addr)) &&
1989 +               addr6.sin6_scope_id == 0) {
1990 +               addr6.sin6_scope_id = ntohs(addr6.sin6_addr.s6_addr[3] |
1991 +                   (unsigned int)addr6.sin6_addr.s6_addr[2] << 8);
1992 +               addr6.sin6_addr.s6_addr[2] = addr6.sin6_addr.s6_addr[3] = 0;
1993 +               sa = (struct sockaddr *)&addr6;
1994 +           }
1995 +#endif
1996 +           break;
1997 +#endif
1998 +       default:
1999 +           continue;
2000 +       }
2001 +
2002 +#ifdef INET6
2003 +       inet_addr_list_append(addr_list, sa);
2004 +       if (mask_list != NULL)
2005 +           inet_addr_list_append(mask_list, sam);
2006 +#else
2007 +       inet_addr_list_append(addr_list, (struct in_addr *)addr);
2008 +       if (mask_list != NULL)
2009 +           inet_addr_list_append(mask_list, (struct in_addr *)addrm);
2010 +#endif
2011 +    }
2012 +
2013 +    freeifaddrs(ifap);
2014 +    return (addr_list->used - initial_count);
2015 +#else
2016      char   *myname = "inet_addr_local";
2017      struct ifconf ifc;
2018      struct ifreq *ifr;
2019      struct ifreq *the_end;
2020      int     sock;
2021 -    VSTRING *buf = vstring_alloc(1024);
2022 +    VSTRING *buf;
2023      int     initial_count = addr_list->used;
2024      struct in_addr addr;
2025      struct ifreq *ifr_mask;
2026 +    int af = AF_INET;
2027 +#ifdef INET6
2028 +#if defined (LINUX) || defined (LINUX2)
2029 +#define _PATH_PROCNET_IFINET6   "/proc/net/if_inet6"
2030 +    FILE *f;
2031 +    char addr6p[8][5], addr6res[40], devname[20];
2032 +    int plen, scope, dad_status, if_idx, gaierror;
2033 +    struct addrinfo hints, *res, *res0;
2034 +#endif
2035 +    struct sockaddr_in6 addr6;
2036 +
2037 +other_socket_type:
2038 +#endif
2039 +    buf = vstring_alloc(1024);
2040  
2041 -    if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
2042 +    if ((sock = socket(af, SOCK_DGRAM, 0)) < 0) {
2043 +#ifdef INET6
2044 +       if (af == AF_INET6)
2045 +       {
2046 +           if (msg_verbose)
2047 +                   msg_warn("%s: socket: %m", myname);
2048 +           goto end;
2049 +       }
2050 +       else
2051 +#endif
2052         msg_fatal("%s: socket: %m", myname);
2053 +    }
2054  
2055      /*
2056       * Get the network interface list. XXX The socket API appears to have no
2057 @@ -126,10 +219,15 @@
2058       */
2059      the_end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
2060      for (ifr = ifc.ifc_req; ifr < the_end;) {
2061 -       if (ifr->ifr_addr.sa_family == AF_INET) {       /* IP interface */
2062 +       if ((ifr->ifr_addr.sa_family == AF_INET) &&
2063 +                       (ifr->ifr_addr.sa_family == af)) { /* IP interface */
2064             addr = ((struct sockaddr_in *) & ifr->ifr_addr)->sin_addr;
2065             if (addr.s_addr != INADDR_ANY) {    /* has IP address */
2066 +#ifdef INET6
2067 +               inet_addr_list_append(addr_list, &ifr->ifr_addr);
2068 +#else
2069                 inet_addr_list_append(addr_list, &addr);
2070 +#endif
2071                 if (mask_list) {
2072                     ifr_mask = (struct ifreq *) mymalloc(IFREQ_SIZE(ifr));
2073                     memcpy((char *) ifr_mask, (char *) ifr, IFREQ_SIZE(ifr));
2074 @@ -141,11 +239,70 @@
2075                 }
2076             }
2077         }
2078 +#ifdef INET6
2079 +       else if ((ifr->ifr_addr.sa_family == AF_INET6) &&
2080 +                       (ifr->ifr_addr.sa_family == af)) {  /* IPv6 interface */
2081 +           addr6 = *((struct sockaddr_in6 *) & ifr->ifr_addr);
2082 +#ifdef __KAME__
2083 +           /* decode scoped address notation */
2084 +           if ((IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) ||
2085 +                IN6_IS_ADDR_SITELOCAL(&addr6.sin6_addr)) &&
2086 +               addr6.sin6_scope_id == 0) {
2087 +               addr6.sin6_scope_id = ntohs(addr6.sin6_addr.s6_addr[3] |
2088 +                   (unsigned int)addr6.sin6_addr.s6_addr[2] << 8);
2089 +               addr6.sin6_addr.s6_addr[2] = addr6.sin6_addr.s6_addr[3] = 0;
2090 +           }
2091 +#endif
2092 +           if (!(IN6_IS_ADDR_UNSPECIFIED(&addr6.sin6_addr))) {
2093 +               inet_addr_list_append(addr_list, (struct sockaddr *)&addr6);
2094 +               if (mask_list) {
2095 +#error "mask_list for IPv6 without libinet6 not done yet (error to avoid open-relay)"
2096 +                       /* TODO: how to get netmask here? */
2097 +               }
2098 +           }
2099 +       }
2100 +#endif
2101         ifr = NEXT_INTERFACE(ifr);
2102      }
2103      vstring_free(buf);
2104      (void) close(sock);
2105 +#ifdef INET6
2106 +end:
2107 +    if (af != AF_INET6) {
2108 +           af = AF_INET6;
2109 +           goto other_socket_type;
2110 +    }
2111 +#if defined (LINUX) || defined (LINUX2)
2112 +    if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) {
2113 +         while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
2114 +              addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4],
2115 +              addr6p[5], addr6p[6], addr6p[7],
2116 +              &if_idx, &plen, &scope, &dad_status, devname) != EOF) {
2117 +                sprintf(addr6res, "%s:%s:%s:%s:%s:%s:%s:%s",
2118 +                                addr6p[0], addr6p[1], addr6p[2], addr6p[3],
2119 +                                addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
2120 +                addr6res[sizeof(addr6res) - 1] = 0;
2121 +                memset(&hints, 0, sizeof(hints));
2122 +                hints.ai_flags = AI_NUMERICHOST;
2123 +                hints.ai_family = AF_UNSPEC;
2124 +                hints.ai_socktype = SOCK_DGRAM;
2125 +                gaierror = getaddrinfo(addr6res, NULL, &hints, &res0);
2126 +                if (!gaierror) {
2127 +                        for (res = res0; res; res = res->ai_next) {
2128 +                              inet_addr_list_append(addr_list, res->ai_addr);
2129 +                              if (mask_list) {
2130 +#error "mask_list for IPv6 without libinet6 not done yet (error to avoid open-relay)"
2131 +                                      /* TODO: calculate netmask basing on plen */
2132 +                              }
2133 +                        }
2134 +                        freeaddrinfo(res0);
2135 +                }
2136 +        }
2137 +    }
2138 +#endif /* linux */
2139 +#endif
2140      return (addr_list->used - initial_count);
2141 +#endif
2142  }
2143  
2144  #ifdef TEST
2145 @@ -158,6 +315,8 @@
2146      INET_ADDR_LIST addr_list;
2147      INET_ADDR_LIST mask_list;
2148      int     i;
2149 +    char abuf[NI_MAXHOST], mbuf[NI_MAXHOST];
2150 +    struct sockaddr *sa;
2151  
2152      msg_vstream_init(argv[0], VSTREAM_ERR);
2153  
2154 @@ -172,8 +331,17 @@
2155         msg_warn("found only one active network interface");
2156  
2157      for (i = 0; i < addr_list.used; i++) {
2158 -       vstream_printf("%s/", inet_ntoa(addr_list.addrs[i]));
2159 -       vstream_printf("%s\n", inet_ntoa(mask_list.addrs[i]));
2160 +       sa = (struct sockaddr *)&addr_list.addrs[i];
2161 +       if (getnameinfo(sa, SA_LEN(sa), abuf, sizeof(abuf), NULL, 0,
2162 +               NI_NUMERICHOST)) {
2163 +           strncpy(abuf, "???", sizeof(abuf));
2164 +       }
2165 +       sa = (struct sockaddr *)&mask_list.addrs[i];
2166 +       if (getnameinfo(sa, SA_LEN(sa), mbuf, sizeof(mbuf), NULL, 0,
2167 +               NI_NUMERICHOST)) {
2168 +           strncpy(mbuf, "???", sizeof(mbuf));
2169 +       }
2170 +       vstream_printf("%s/%s\n", abuf, mbuf);
2171      }
2172      vstream_fflush(VSTREAM_OUT);
2173      inet_addr_list_free(&addr_list);
2174 --- postfix-2.0.16.orig/src/util/inet_connect.c 2003-09-13 03:04:12.000000000 +0200
2175 +++ postfix-2.0.16/src/util/inet_connect.c      2003-11-08 20:22:55.000000000 +0100
2176 @@ -55,6 +55,9 @@
2177  #include <string.h>
2178  #include <unistd.h>
2179  #include <errno.h>
2180 +#ifdef INET6
2181 +#include <netdb.h>
2182 +#endif
2183  
2184  /* Utility library. */
2185  
2186 @@ -74,7 +77,12 @@
2187      char   *buf;
2188      char   *host;
2189      char   *port;
2190 +#ifdef INET6
2191 +    struct addrinfo hints, *res, *res0;
2192 +    int    error;
2193 +#else
2194      struct sockaddr_in sin;
2195 +#endif
2196      int     sock;
2197  
2198      /*
2199 @@ -82,14 +90,58 @@
2200       * the local host.
2201       */
2202      buf = inet_parse(addr, &host, &port);
2203 +#ifdef INET6
2204 +    if (*host == 0)
2205 +       host = NULL;
2206 +    memset(&hints, 0, sizeof(hints));
2207 +    hints.ai_family = PF_UNSPEC;
2208 +    hints.ai_socktype = SOCK_STREAM;
2209 +    hints.ai_flags = AI_NUMERICHOST;   /* find_inet_addr is numeric only */
2210 +    if (getaddrinfo(host, port, &hints, &res0))
2211 +       msg_fatal("host not found: %s", host);
2212 +#else
2213      if (*host == 0)
2214         host = "localhost";
2215      memset((char *) &sin, 0, sizeof(sin));
2216      sin.sin_family = AF_INET;
2217      sin.sin_addr.s_addr = find_inet_addr(host);
2218      sin.sin_port = find_inet_port(port, "tcp");
2219 +#endif
2220      myfree(buf);
2221  
2222 +#ifdef INET6
2223 +    sock = -1;
2224 +    for (res = res0; res; res = res->ai_next) {
2225 +       if ((res->ai_family != AF_INET) && (res->ai_family != AF_INET6))
2226 +           continue;
2227 +
2228 +       sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
2229 +       if (sock < 0)
2230 +           continue;
2231 +       if (timeout > 0) {
2232 +           non_blocking(sock, NON_BLOCKING);
2233 +           if (timed_connect(sock, res->ai_addr, res->ai_addrlen, timeout) < 0) {
2234 +               close(sock);
2235 +               sock = -1;
2236 +               continue;
2237 +           }
2238 +           if (block_mode != NON_BLOCKING)
2239 +               non_blocking(sock, block_mode);
2240 +           break;
2241 +       } else {
2242 +           non_blocking(sock, block_mode);
2243 +           if (connect(sock, res->ai_addr, res->ai_addrlen) < 0
2244 +               && errno != EINPROGRESS) {
2245 +               close(sock);
2246 +               sock = -1;
2247 +               continue;
2248 +           }
2249 +           break;
2250 +       }
2251 +    }
2252 +    freeaddrinfo(res0);
2253 +    return sock;
2254 +#else
2255      /*
2256       * Create a client socket.
2257       */
2258 @@ -122,4 +174,5 @@
2259         }
2260         return (sock);
2261      }
2262 +#endif
2263  }
2264 --- postfix-2.0.16.orig/src/util/inet_listen.c  2003-09-13 01:50:50.000000000 +0200
2265 +++ postfix-2.0.16/src/util/inet_listen.c       2003-11-08 20:22:55.000000000 +0100
2266 @@ -6,7 +6,7 @@
2267  /* SYNOPSIS
2268  /*     #include <listen.h>
2269  /*
2270 -/*     int     inet_listen(addr, backlog, block_mode)
2271 +/*     int     inet_listen(addr, backlog, block_mode, addinuse_fatal)
2272  /*     const char *addr;
2273  /*     int     backlog;
2274  /*     int     block_mode;
2275 @@ -51,11 +51,17 @@
2276  #include <sys_defs.h>
2277  #include <sys/socket.h>
2278  #include <netinet/in.h>
2279 +#ifdef INET6
2280 +#if (! __GLIBC__ >= 2 && __GLIBC_MINOR__ >=1 )
2281 +#include <netinet6/in6.h>
2282 +#endif
2283 +#endif
2284  #include <arpa/inet.h>
2285  #include <netdb.h>
2286  #ifndef MAXHOSTNAMELEN
2287  #include <sys/param.h>
2288  #endif
2289 +#include <errno.h>
2290  #include <string.h>
2291  #include <unistd.h>
2292  
2293 @@ -77,35 +83,116 @@
2294  
2295  /* inet_listen - create inet-domain listener */
2296  
2297 -int     inet_listen(const char *addr, int backlog, int block_mode)
2298 +int     inet_listen(const char *addr, int backlog, int block_mode, int addrinuse_fatal)
2299  {
2300 +#ifdef INET6
2301 +    struct addrinfo *res, *res0, hints;
2302 +    int error;
2303 +#else
2304 +    struct ai {
2305 +       int ai_family;
2306 +       int ai_socktype;
2307 +       int ai_protocol;
2308 +       struct sockaddr *ai_addr;
2309 +       SOCKADDR_SIZE ai_addrlen;
2310 +       struct ai *ai_next;
2311 +    } *res, *res0, resbody;
2312      struct sockaddr_in sin;
2313 +#endif
2314      int     sock;
2315      int     t = 1;
2316 +    int     addrinuse = 0;
2317      char   *buf;
2318      char   *host;
2319      char   *port;
2320 +#ifdef INET6
2321 +    char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
2322 +#else
2323 +    char hbuf[sizeof("255.255.255.255") + 1];
2324 +    char pbuf[sizeof("255.255.255.255") + 1];
2325 +#endif
2326 +    char *cause = "unknown";
2327  
2328      /*
2329       * Translate address information to internal form.
2330       */
2331      buf = inet_parse(addr, &host, &port);
2332 -    memset((char *) &sin, 0, sizeof(sin));
2333 +#ifdef INET6
2334 +    memset(&hints, 0, sizeof(hints));
2335 +    hints.ai_flags = AI_PASSIVE;
2336 +    hints.ai_family = AF_UNSPEC;
2337 +    hints.ai_socktype = SOCK_STREAM;
2338 +    error = getaddrinfo(*host ? host : NULL, *port ? port : "0", &hints, &res0);
2339 +    if (error) {
2340 +       msg_fatal("getaddrinfo: %s", gai_strerror(error));
2341 +    }
2342 +    myfree(buf);
2343 +#else
2344 +    memset(&sin, 0, sizeof(sin));
2345      sin.sin_family = AF_INET;
2346 +#ifdef HAS_SA_LEN
2347 +    sin.sin_len = sizeof(sin);
2348 +#endif
2349      sin.sin_port = find_inet_port(port, "tcp");
2350      sin.sin_addr.s_addr = (*host ? find_inet_addr(host) : INADDR_ANY);
2351 -    myfree(buf);
2352  
2353 -    /*
2354 -     * Create a listener socket.
2355 -     */
2356 -    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
2357 -       msg_fatal("socket: %m");
2358 -    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &t, sizeof(t)) < 0)
2359 -       msg_fatal("setsockopt: %m");
2360 -    if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
2361 -       msg_fatal("bind %s port %d: %m", sin.sin_addr.s_addr == INADDR_ANY ?
2362 -              "INADDR_ANY" : inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
2363 +    memset(&resbody, 0, sizeof(resbody)); 
2364 +    resbody.ai_socktype = SOCK_STREAM;
2365 +    resbody.ai_family = AF_INET;
2366 +    resbody.ai_addr = (struct sockaddr *)&sin;
2367 +    resbody.ai_addrlen = sizeof(sin);
2368 +
2369 +    res0 = &resbody;
2370 +#endif
2371 +
2372 +    sock = -1;
2373 +    for (res = res0; res; res = res->ai_next) {
2374 +       if ((res->ai_family != AF_INET) && (res->ai_family != AF_INET6))
2375 +           continue;
2376 +
2377 +       /*
2378 +        * Create a listener socket.
2379 +        */
2380 +       if ((sock = socket(res->ai_family, res->ai_socktype, 0)) < 0) {
2381 +           cause = "socket";
2382 +           continue;
2383 +       }
2384 +#ifdef IPV6_V6ONLY
2385 +       if (res->ai_family == AF_INET6 &&
2386 +           setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &t, sizeof(t)) < 0) {
2387 +               /* if kernel/libc don't support this simple ignore it
2388 +           cause = "setsockopt(IPV6_V6ONLY)";
2389 +           close(sock);
2390 +           sock = -1;
2391 +           continue;
2392 +               */
2393 +               ;
2394 +       }
2395 +#endif
2396 +       if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &t, sizeof(t)) < 0) {
2397 +           cause = "setsockopt(SO_REUSEADDR)";
2398 +           close(sock);
2399 +           sock = -1;
2400 +           continue;
2401 +       }
2402 +
2403 +       if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
2404 +           cause = "bind";
2405 +           if (errno == EADDRINUSE)
2406 +               addrinuse = 1;
2407 +           close(sock);
2408 +           sock = -1;
2409 +           continue;
2410 +       }
2411 +       break;
2412 +    }
2413 +    if (sock < 0 && (addrinuse_fatal || !addrinuse))
2414 +       msg_fatal("%s: %m", cause);
2415 +#ifdef INET6
2416 +    freeaddrinfo(res0);
2417 +#endif
2418 +    if (sock < 0)
2419 +       return -1;
2420      non_blocking(sock, block_mode);
2421      if (listen(sock, backlog) < 0)
2422         msg_fatal("listen: %m");
2423 --- postfix-2.0.16.orig/src/util/listen.h       1999-03-22 02:57:11.000000000 +0100
2424 +++ postfix-2.0.16/src/util/listen.h    2003-11-08 20:22:55.000000000 +0100
2425 @@ -20,7 +20,7 @@
2426    * Listener external interface.
2427    */
2428  extern int unix_listen(const char *, int, int);
2429 -extern int inet_listen(const char *, int, int);
2430 +extern int inet_listen(const char *, int, int, int);
2431  extern int fifo_listen(const char *, int, int);
2432  extern int stream_listen(const char *, int, int);
2433  
2434 --- postfix-2.0.16.orig/src/util/Makefile.in    2003-11-08 20:17:08.000000000 +0100
2435 +++ postfix-2.0.16/src/util/Makefile.in 2003-11-08 20:22:55.000000000 +0100
2436 @@ -8,7 +8,7 @@
2437         dict_tcp.c dict_unix.c dir_forest.c doze.c duplex_pipe.c \
2438         environ.c events.c exec_command.c fifo_listen.c fifo_trigger.c \
2439         file_limit.c find_inet.c fsspace.c fullname.c get_domainname.c \
2440 -       get_hostname.c hex_quote.c htable.c inet_addr_host.c \
2441 +       get_hostname.c get_port.c hex_quote.c htable.c inet_addr_host.c \
2442         inet_addr_list.c inet_addr_local.c inet_connect.c inet_listen.c \
2443         inet_trigger.c inet_util.c intv.c line_wrap.c lowercase.c \
2444         lstat_as.c mac_expand.c mac_parse.c make_dirs.c match_list.c \
2445 @@ -37,7 +37,7 @@
2446         dict_tcp.o dict_unix.o dir_forest.o doze.o duplex_pipe.o \
2447         environ.o events.o exec_command.o fifo_listen.o fifo_trigger.o \
2448         file_limit.o find_inet.o fsspace.o fullname.o get_domainname.o \
2449 -       get_hostname.o hex_quote.o htable.o inet_addr_host.o \
2450 +       get_hostname.o get_port.o hex_quote.o htable.o inet_addr_host.o \
2451         inet_addr_list.o inet_addr_local.o inet_connect.o inet_listen.o \
2452         inet_trigger.o inet_util.o intv.o line_wrap.o lowercase.o \
2453         lstat_as.o mac_expand.o mac_parse.o make_dirs.o match_list.o \
2454 @@ -62,7 +62,7 @@
2455         dict_ht.h dict_ldap.h dict_mysql.h dict_ni.h dict_nis.h \
2456         dict_nisplus.h dict_pcre.h dict_pgsql.h dict_regexp.h dict_static.h dict_tcp.h \
2457         dict_unix.h dir_forest.h events.h exec_command.h find_inet.h \
2458 -       fsspace.h fullname.h get_domainname.h get_hostname.h hex_quote.h \
2459 +       fsspace.h fullname.h get_domainname.h get_hostname.h get_port.h hex_quote.h \
2460         htable.h inet_addr_host.h inet_addr_list.h inet_addr_local.h \
2461         inet_util.h intv.h iostuff.h line_wrap.h listen.h lstat_as.h \
2462         mac_expand.h mac_parse.h make_dirs.h match_list.h match_ops.h \
2463 @@ -785,6 +785,7 @@
2464  get_domainname.o: mymalloc.h
2465  get_domainname.o: get_hostname.h
2466  get_domainname.o: get_domainname.h
2467 +get_port.o: sys_defs.h
2468  get_hostname.o: get_hostname.c
2469  get_hostname.o: sys_defs.h
2470  get_hostname.o: mymalloc.h
2471 @@ -911,6 +912,7 @@
2472  match_list.o: stringops.h
2473  match_list.o: argv.h
2474  match_list.o: dict.h
2475 +match_list.o: inet_util.h
2476  match_list.o: match_ops.h
2477  match_list.o: match_list.h
2478  match_ops.o: match_ops.c
2479 --- postfix-2.0.16.orig/src/util/match_list.c   2001-11-20 21:07:15.000000000 +0100
2480 +++ postfix-2.0.16/src/util/match_list.c        2003-11-08 20:22:55.000000000 +0100
2481 @@ -118,7 +118,7 @@
2482                     list = match_list_parse(list, vstring_str(buf));
2483             if (vstream_fclose(fp))
2484                 msg_fatal("%s: read file %s: %m", myname, pattern);
2485 -       } else if (strchr(pattern, ':') != 0) { /* type:table */
2486 +       } else if ((strchr(pattern, ']') == 0) && (strchr(pattern, ':') != 0)) {        /* type:table */
2487             for (cp = pattern; *cp == '!'; cp++)
2488                  /* void */ ;
2489             if (dict_handle(pattern) == 0)
2490 --- postfix-2.0.16.orig/src/util/match_ops.c    2003-04-14 16:44:19.000000000 +0200
2491 +++ postfix-2.0.16/src/util/match_ops.c 2003-11-08 20:22:55.000000000 +0100
2492 @@ -81,6 +81,308 @@
2493  #include <match_ops.h>
2494  #include <stringops.h>
2495  
2496 +#ifdef INET6
2497 +/*
2498 + *             $Id$
2499 + *
2500 + *             This program is free software; you can redistribute it and/or
2501 + *             modify it under the terms of the GNU General Public License
2502 + *             as published by the Free Software Foundation; either version
2503 + *             2 of the License, or (at your option) any later version.
2504 + *
2505 + * Authors:    Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
2506 + *
2507 + * Modifications:
2508 + *             Artur Frysiak <wiget@pld.org.pl>
2509 + *             Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
2510 + */
2511 +
2512 +#include <stdio.h>
2513 +#include <stdlib.h>
2514 +#include <unistd.h>
2515 +#include <syslog.h>
2516 +#include <fcntl.h>
2517 +#include <sys/socket.h>
2518 +#include <netinet/in.h>
2519 +#include <string.h>
2520 +#include <netdb.h>
2521 +#include <arpa/inet.h>
2522 +#include <resolv.h>
2523 +
2524 +#ifndef        AF_DECnet
2525 +#define        AF_DECnet       12
2526 +#endif
2527 +
2528 +#ifndef        PF_PACKET
2529 +#define        PF_PACKET       17
2530 +#endif
2531 +
2532 +typedef struct
2533 +{
2534 +       unsigned char family;
2535 +       unsigned char bytelen;
2536 +       signed short  bitlen;
2537 +       unsigned int data[4];
2538 +} inet_prefix;
2539 +
2540 +/* prototypes */
2541 +int masked_match(char *, char *, char *);
2542 +int get_integer(int *, char *, int);
2543 +int get_addr_1(inet_prefix *, char *, int);
2544 +int get_prefix_1(inet_prefix *, char *, int);
2545 +int get_addr(inet_prefix *, char *, int);
2546 +int get_prefix(inet_prefix *, char *, int);
2547 +unsigned int get_addr32(char *);
2548 +int matches(char *, char *);
2549 +int inet_addr_match(inet_prefix *, inet_prefix *, int);
2550 +int mask_match(char *, char *, char *);
2551 +
2552 +int get_integer(int *val, char *arg, int base)
2553 +{
2554 +       long res;
2555 +       char *ptr;
2556 +
2557 +       if (!arg || !*arg)
2558 +               return -1;
2559 +       res = strtol(arg, &ptr, base);
2560 +       if (!ptr || ptr == arg || *ptr || res > INT_MAX || res < INT_MIN)
2561 +               return -1;
2562 +       *val = res;
2563 +       return 0;
2564 +}
2565 +
2566 +int get_addr_1(inet_prefix *addr, char *name, int family)
2567 +{
2568 +       char *cp;
2569 +       unsigned char *ap = (unsigned char*)addr->data;
2570 +       int i;
2571 +
2572 +       memset(addr, 0, sizeof(*addr));
2573 +
2574 +       if (strcmp(name, "default") == 0 || strcmp(name, "any") == 0) {
2575 +               if (family == AF_DECnet)
2576 +                       return -1;
2577 +               addr->family = family;
2578 +               addr->bytelen = (family == AF_INET6 ? 16 : 4);
2579 +               addr->bitlen = -1;
2580 +               return 0;
2581 +       }
2582 +
2583 +       if (strchr(name, ':')) {
2584 +               addr->family = AF_INET6;
2585 +               if (family != AF_UNSPEC && family != AF_INET6)
2586 +                       return -1;
2587 +               if (inet_pton(AF_INET6, name, addr->data) <= 0)
2588 +                       return -1;
2589 +               addr->bytelen = 16;
2590 +               addr->bitlen = -1;
2591 +               return 0;
2592 +       }
2593 +       addr->family = AF_INET;
2594 +       if (family != AF_UNSPEC && family != AF_INET)
2595 +               return -1;
2596 +       addr->bytelen = 4;
2597 +       addr->bitlen = -1;
2598 +       for (cp = name, i = 0; *cp; cp++) {
2599 +               if (*cp <= '9' && *cp >= '0') {
2600 +                       ap[i] = 10*ap[i] + (*cp-'0');
2601 +                       continue;
2602 +               }
2603 +               if (*cp == '.' && ++i <= 3)
2604 +                       continue;
2605 +               return -1;
2606 +       }
2607 +       return 0;
2608 +}
2609 +
2610 +int get_prefix_1(inet_prefix *dst, char *arg, int family)
2611 +{
2612 +       int err;
2613 +       unsigned plen;
2614 +       char *slash;
2615 +
2616 +       memset(dst, 0, sizeof(*dst));
2617 +
2618 +       if (strcmp(arg, "default") == 0 || strcmp(arg, "any") == 0) {
2619 +               if (family == AF_DECnet)
2620 +                       return -1;
2621 +               dst->family = family;
2622 +               dst->bytelen = 0;
2623 +               dst->bitlen = 0;
2624 +               return 0;
2625 +       }
2626 +
2627 +       slash = strchr(arg, '/');
2628 +       if (slash)
2629 +               *slash = 0;
2630 +       err = get_addr_1(dst, arg, family);
2631 +       if (err == 0) {
2632 +               switch(dst->family) {
2633 +                       case AF_INET6:
2634 +                               dst->bitlen = 128;
2635 +                               break;
2636 +                       case AF_DECnet:
2637 +                               dst->bitlen = 16;
2638 +                               break;
2639 +                       default:
2640 +                       case AF_INET:
2641 +                               dst->bitlen = 32;
2642 +               }
2643 +               if (slash) {
2644 +                       if (get_integer(&plen, slash+1, 0) || plen > dst->bitlen) {
2645 +                               err = -1;
2646 +                               goto done;
2647 +                       }
2648 +                       dst->bitlen = plen;
2649 +               }
2650 +       }
2651 +done:
2652 +       if (slash)
2653 +               *slash = '/';
2654 +       return err;
2655 +}
2656 +
2657 +int get_addr(inet_prefix *dst, char *arg, int family)
2658 +{
2659 +#ifdef AF_PACKET
2660 +       if (family == AF_PACKET)
2661 +               return -1;
2662 +#endif
2663 +       if (get_addr_1(dst, arg, family))
2664 +               return -1;
2665 +       return 0;
2666 +}
2667 +
2668 +int get_prefix(inet_prefix *dst, char *arg, int family)
2669 +{
2670 +#ifdef AF_PACKET
2671 +       if (family == AF_PACKET)
2672 +               return -1;
2673 +#endif
2674 +       if (get_prefix_1(dst, arg, family))
2675 +               return -1;
2676 +       return 0;
2677 +}
2678 +
2679 +unsigned int get_addr32(char *name)
2680 +{
2681 +       inet_prefix addr;
2682 +       if (get_addr_1(&addr, name, AF_INET))
2683 +               return -1;
2684 +       return addr.data[0];
2685 +}
2686 +
2687 +int matches(char *cmd, char *pattern)
2688 +{
2689 +       int len = strlen(cmd);
2690 +       if (len > strlen(pattern))
2691 +               return -1;
2692 +       return memcmp(pattern, cmd, len);
2693 +}
2694 +
2695 +int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits)
2696 +{
2697 +       unsigned int *a1 = a->data;
2698 +       unsigned int *a2 = b->data;
2699 +       int words = bits >> 0x05;
2700 +
2701 +       bits &= 0x1f;
2702 +
2703 +       if (words)
2704 +               if (memcmp(a1, a2, words << 2))
2705 +                       return -1;
2706 +
2707 +       if (bits) {
2708 +               unsigned int w1, w2;
2709 +               unsigned int mask;
2710 +
2711 +               w1 = a1[words];
2712 +               w2 = a2[words];
2713 +
2714 +               mask = htonl((0xffffffff) << (0x20 - bits));
2715 +
2716 +               if ((w1 ^ w2) & mask)
2717 +                       return 1;
2718 +       }
2719 +
2720 +       return 0;
2721 +}
2722 +
2723 +/* zero if matches */
2724 +int mask_match(char *network, char *cprefix, char *address)
2725 +{
2726 +       inet_prefix *inetwork;
2727 +       inet_prefix *iaddress;
2728 +       int ret, prefix;
2729 +
2730 +       if (!(network && address && cprefix))
2731 +               return -1;
2732 +       prefix = strtol(cprefix, (char **)NULL, 10);
2733 +       if ((prefix < 0) || (prefix > 128))
2734 +               return -1;
2735 +       if ((strlen(network) == 0) || (strlen(address) == 0))
2736 +               return -1;
2737 +
2738 +       inetwork = malloc(sizeof(inet_prefix));
2739 +       iaddress = malloc(sizeof(inet_prefix));
2740 +
2741 +       if ((get_addr(iaddress, address, AF_UNSPEC) >= 0)
2742 +                       && (get_addr(inetwork, network, AF_UNSPEC) >= 0))
2743 +               ret = inet_addr_match(inetwork, iaddress, prefix);
2744 +       else
2745 +               ret = -1;
2746 +       free(inetwork);
2747 +       free(iaddress);
2748 +
2749 +       /* 1 if matches */
2750 +       /* return (!ret); */
2751 +       /* 0 if matches */
2752 +       return ret;
2753 +}
2754 +
2755 +/*
2756 + * masked_match() - universal for IPv4 and IPv6  - 1 if matches
2757 + */
2758 +int masked_match(net_tok, mask_tok, string)
2759 +char   *net_tok;
2760 +char   *mask_tok;
2761 +char   *string;
2762 +{
2763 +#ifdef INET6
2764 +       struct in6_addr in6[2];
2765 +       char v4addr[2][INET_ADDRSTRLEN];
2766 +       char newmask[6];
2767 +       int plen;
2768 +#endif
2769 +
2770 +       /* Check for NULL */
2771 +       if (!(net_tok && mask_tok && string))
2772 +               return 0; /* doesn't match!!! */
2773 +
2774 +       /* If IPv6 mapped convert to native-IPv4 */
2775 +#ifdef INET6
2776 +       if (inet_pton(AF_INET6, net_tok, &in6[0]) == 1 &&
2777 +           inet_pton(AF_INET6, string, &in6[1]) == 1 &&
2778 +           IN6_IS_ADDR_V4MAPPED(&in6[0]) && IN6_IS_ADDR_V4MAPPED(&in6[1])) {
2779 +               plen = atoi(mask_tok);
2780 +               if (32 < plen && plen < 129) {
2781 +                       sprintf(newmask, "%d", plen - 96);
2782 +                       mask_tok = newmask;
2783 +               }
2784 +
2785 +               (void)inet_ntop(AF_INET, &in6[0].s6_addr[12], v4addr[0],
2786 +                   sizeof(v4addr[0]));
2787 +               net_tok = v4addr[0];
2788 +               (void)inet_ntop(AF_INET, &in6[1].s6_addr[12], v4addr[1],
2789 +                   sizeof(v4addr[1]));
2790 +               string = v4addr[1];
2791 +       }
2792 +#endif
2793 +       return (!mask_match(net_tok, mask_tok, string));
2794 +}
2795 +#endif
2796 +
2797 +
2798  /* match_string - match a string literal */
2799  
2800  int     match_string(int unused_flags, const char *string, const char *pattern)
2801 @@ -177,6 +479,7 @@
2802      return (0);
2803  }
2804  
2805 +#ifndef INET6
2806  /* match_parse_mask - parse net/mask pattern */
2807  
2808  static int match_parse_mask(const char *pattern, unsigned long *net_bits,
2809 @@ -198,28 +501,55 @@
2810      return (mask != 0);
2811  }
2812  
2813 +#endif
2814  /* match_hostaddr - match host by address */
2815  
2816  int     match_hostaddr(int unused_flags, const char *addr, const char *pattern)
2817  {
2818      char   *myname = "match_hostaddr";
2819 +#ifdef INET6
2820 +    char *network, *mask, *escl, *escr, *patternx;
2821 +    struct in6_addr in6;
2822 +    char v4addr[INET_ADDRSTRLEN];
2823 +#else
2824      int     mask_shift;
2825      unsigned long mask_bits;
2826      unsigned long net_bits;
2827      unsigned long addr_bits;
2828      struct in_addr net_addr;
2829 +#endif
2830  
2831      if (msg_verbose)
2832         msg_info("%s: %s ~? %s", myname, addr, pattern);
2833  
2834 +#ifdef INET6
2835 +    if (addr[strspn(addr, "01234567890./:abcdef")] != 0)
2836 +#else
2837      if (addr[strspn(addr, "01234567890./:")] != 0)
2838 +#endif
2839         return (0);
2840  
2841 +#ifdef INET6
2842 +    patternx = mystrdup(pattern);
2843 +    escl = strchr(patternx,'[');
2844 +    escr = strrchr(patternx,']');
2845 +    if (escl && escr) {
2846 +      *escr = 0;
2847 +      sprintf(patternx, "%s%s", escl + 1, escr + 1);
2848 +      pattern = patternx;
2849 +    }
2850 +#endif
2851 +
2852      /*
2853       * Try dictionary lookup. This can be case insensitive. XXX Probably
2854       * should also try again after stripping least significant octets.
2855       */
2856 -    if (strchr(pattern, ':') != 0) {
2857 +#ifdef INET6
2858 +    if (!(escl && escr) && strchr(pattern, ':') != 0)
2859 +#else
2860 +    if (strchr(pattern, ':') != 0)
2861 +#endif
2862 +   {
2863         if (dict_lookup(pattern, addr) != 0)
2864             return (1);
2865         if (dict_errno != 0)
2866 @@ -230,6 +560,12 @@
2867      /*
2868       * Try an exact match with the host address.
2869       */
2870 +#ifdef INET6
2871 +    if (inet_pton(AF_INET6, addr, &in6) == 1 && IN6_IS_ADDR_V4MAPPED(&in6)) {
2872 +       (void)inet_ntop(AF_INET, &in6.s6_addr[12], v4addr, sizeof(v4addr));
2873 +       addr = v4addr;
2874 +    }
2875 +#endif
2876      if (strcasecmp(addr, pattern) == 0) {
2877         return (1);
2878      }
2879 @@ -238,6 +574,20 @@
2880       * In a net/mask pattern, the mask is specified as the number of bits of
2881       * the network part.
2882       */
2883 +#ifdef INET6
2884 +    network = mystrdup(patternx);
2885 +    mask = split_at(network, '/');
2886 +
2887 +    if (masked_match(network, mask, (char *)addr)) {
2888 +       myfree(network);
2889 +       myfree(patternx);
2890 +       return (1);
2891 +    } else {
2892 +       myfree(network);
2893 +       myfree(patternx);
2894 +    }
2895 +#else
2896 +
2897      if (match_parse_mask(pattern, &net_bits, &mask_shift)) {
2898         addr_bits = inet_addr(addr);
2899         if (addr_bits == INADDR_NONE)
2900 @@ -252,5 +602,6 @@
2901                       pattern, inet_ntoa(net_addr), mask_shift);
2902         }
2903      }
2904 +#endif
2905      return (0);
2906  }
2907 --- postfix-2.0.16.orig/src/util/sys_defs.h     2003-11-08 20:17:08.000000000 +0100
2908 +++ postfix-2.0.16/src/util/sys_defs.h  2003-11-08 20:22:55.000000000 +0100
2909 @@ -73,6 +73,10 @@
2910  #define DEF_MAILBOX_LOCK "flock, dotlock"
2911  #endif
2912  
2913 +#if ((defined(__NetBSD_Version__) && __NetBSD_Version__ >= 105000000) || defined(USAGI_LIBINET6))
2914 +#define HAVE_GETIFADDRS
2915 +#endif
2916 +
2917   /*
2918    * UNIX on MAC.
2919    */
2920 --- postfix-2.0.16.orig/src/util/valid_hostname.c       2002-12-20 02:33:41.000000000 +0100
2921 +++ postfix-2.0.16/src/util/valid_hostname.c    2003-11-08 20:22:55.000000000 +0100
2922 @@ -53,6 +53,13 @@
2923  #include <string.h>
2924  #include <ctype.h>
2925  
2926 +#ifdef INET6
2927 +#include <netinet/in.h>
2928 +#include <sys/socket.h>
2929 +#include <arpa/inet.h>
2930 +#include <netdb.h>
2931 +#endif
2932 +
2933  /* Utility library. */
2934  
2935  #include "msg.h"
2936 @@ -109,7 +116,23 @@
2937                     msg_warn("%s: misplaced hyphen: %.100s", myname, name);
2938                 return (0);
2939             }
2940 -       } else {
2941 +       }
2942 +#ifdef INET6
2943 +       else if (ch == ':') {
2944 +           struct addrinfo hints, *res;
2945 +
2946 +           memset(&hints, 0, sizeof(hints));
2947 +           hints.ai_family = AF_INET6;
2948 +           hints.ai_socktype = SOCK_STREAM;    /*dummy*/
2949 +           hints.ai_flags = AI_NUMERICHOST;
2950 +           if (getaddrinfo(name, "0", &hints, &res) == 0) {
2951 +               freeaddrinfo(res);
2952 +               return 1;
2953 +           } else
2954 +               return 0;
2955 +       }
2956 +#endif
2957 +       else {
2958             if (gripe)
2959                 msg_warn("%s: invalid character %d(decimal): %.100s",
2960                          myname, ch, name);
2961 @@ -141,6 +164,9 @@
2962      int     byte_count = 0;
2963      int     byte_val = 0;
2964      int     ch;
2965 +#ifdef INET6
2966 +    struct addrinfo hints, *res;
2967 +#endif
2968  
2969  #define BYTES_NEEDED   4
2970  
2971 @@ -166,6 +192,17 @@
2972         return (1);
2973      }
2974  
2975 +#ifdef INET6
2976 +    memset(&hints, 0, sizeof(hints));
2977 +    hints.ai_family = AF_INET6;
2978 +    hints.ai_socktype = SOCK_STREAM;   /*dummy*/
2979 +    hints.ai_flags = AI_NUMERICHOST;
2980 +    if (getaddrinfo(addr, "0", &hints, &res) == 0) {
2981 +       freeaddrinfo(res);
2982 +       return 1;
2983 +    }
2984 +#endif
2985 +
2986      /*
2987       * Scary code to avoid sscanf() overflow nasties.
2988       */
This page took 0.398639 seconds and 3 git commands to generate.