]> git.pld-linux.org Git - packages/postfix.git/blame - postfix-ipv6.patch
- do not check if a file exists to find out if a library is available (you never...
[packages/postfix.git] / postfix-ipv6.patch
CommitLineData
0b72d562 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
23bbf6c1
JB
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;;
1ce4542c 25@@ -318,6 +333,26 @@
23bbf6c1
JB
26
27 : ${CC='gcc $(WARN)'} ${OPT='-O'} ${DEBUG='-g'} ${AWK=awk}
830ba608 28
23bbf6c1
JB
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"
73f07215
JK
41+ if test -f /usr/include/libinet6/netinet/ip6.h
42+ then
23bbf6c1
JB
43+ CCARGS="$CCARGS -I/usr/include/libinet6 -DUSAGI_LIBINET6"
44+ SYSLIBS="$SYSLIBS -linet6"
45+ fi
46+ ;;
47+esac
830ba608 48+
23bbf6c1
JB
49 export SYSTYPE AR ARFL RANLIB SYSLIBS CC OPT DEBUG AWK OPTS
50
830ba608 51 sed 's/ / /g' <<EOF
0b72d562 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
23bbf6c1
JB
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 \
7e195e4d
TO
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
23bbf6c1 62 OBJS = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
7e195e4d 63@@ -42,7 +42,7 @@
23bbf6c1
JB
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 \
7e195e4d
TO
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
23bbf6c1 71 HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
7e195e4d 72@@ -61,7 +61,7 @@
23bbf6c1
JB
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 \
447bfc58 75 mbox_conf.h mbox_open.h abounce.h qmqp_proto.h verp_sender.h \
7e195e4d
TO
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
23bbf6c1 80 TESTSRC = rec2stream.c stream2rec.c recdump.c
0b72d562 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
23bbf6c1
JB
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";
1ce4542c 105@@ -87,6 +95,13 @@
23bbf6c1
JB
106 int junk;
107 int i;
108 int mask_style;
109+#ifdef INET6
110+ struct sockaddr *sa;
1ce4542c
TO
111+ struct sockaddr_in6 *addr6;
112+ struct sockaddr_in6 *mask6;
113+ struct in6_addr net6;
114+ int j;
23bbf6c1
JB
115+#endif
116
117 mask_style = name_mask("mynetworks mask style", mask_styles,
118 var_mynetworks_style);
1ce4542c 119@@ -96,8 +111,45 @@
23bbf6c1
JB
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];
1ce4542c
TO
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) {
23bbf6c1
JB
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
1ce4542c 165@@ -119,8 +171,15 @@
23bbf6c1
JB
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
1ce4542c
TO
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 }
0b72d562 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
1ce4542c 202@@ -50,6 +50,10 @@
23bbf6c1
JB
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>
1ce4542c 213@@ -113,10 +117,11 @@
23bbf6c1
JB
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
35140025 225 /*
1ce4542c 226@@ -133,15 +138,39 @@
23bbf6c1
JB
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);
1ce4542c 267@@ -151,6 +180,42 @@
23bbf6c1
JB
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;
1ce4542c 310@@ -161,8 +226,8 @@
23bbf6c1
JB
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
9d0b6835
TO
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
0b72d562 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
cc66c172 376@@ -15,14 +15,25 @@
23bbf6c1
JB
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);
cc66c172
TO
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);
23bbf6c1 400
cc66c172 401 /* LICENSE
0b72d562 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
23bbf6c1
JB
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;
0b72d562 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
23bbf6c1
JB
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
0b72d562 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
1ce4542c 480@@ -43,6 +43,7 @@
23bbf6c1
JB
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
1ce4542c 488@@ -80,7 +81,12 @@
23bbf6c1
JB
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); }
7e195e4d 501@@ -118,9 +124,25 @@
23bbf6c1
JB
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
7e195e4d 521 && (own_inet_addr(&ipaddr) || proxy_inet_addr(&ipaddr)))
23bbf6c1
JB
522 RETURN(1);
523+#endif
524 }
525
526 /*
0b72d562 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
23bbf6c1
JB
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+}
0b72d562 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
23bbf6c1
JB
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
0b72d562 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
48f922aa 653@@ -307,8 +307,13 @@
1ce4542c 654 inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv));
23bbf6c1 655 serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
48f922aa 656 } else if (strcasecmp(saved_interfaces, DEF_INET_INTERFACES) == 0) {
23bbf6c1 657+#ifdef INET6
48f922aa
TO
658+ MASTER_INET_ADDRLIST(serv) = wildcard_inet_addr_list();
659+ serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
23bbf6c1
JB
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 */
1ce4542c 666 inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv));
0b72d562 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
e38d57a7 669@@ -64,13 +64,22 @@
23bbf6c1
JB
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)
e38d57a7 681 {
23bbf6c1
JB
682 char *myname = "master_listen_init";
683 char *end_point;
e38d57a7
JB
684- int n;
685+ int n,m,tmpfd;
23bbf6c1
JB
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
e38d57a7
JB
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);
23bbf6c1
JB
699 close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
700 } else { /* virtual or host:port */
e38d57a7
JB
701- for (n = 0; n < serv->listen_fd_count; n++) {
702+ for (m = n = 0; n < serv->listen_fd_count; n++) {
23bbf6c1
JB
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);
e38d57a7 713- serv->listen_fd[n]
23bbf6c1 714+#endif
e38d57a7 715+ tmpfd
23bbf6c1 716 = inet_listen(end_point, serv->max_proc > var_proc_limit ?
e38d57a7
JB
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:
0b72d562 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 @@
23bbf6c1
JB
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
0b72d562 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
35140025 742@@ -134,18 +134,68 @@
23bbf6c1
JB
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;
0b72d562 772+ }
23bbf6c1
JB
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;
0b72d562 807 }
23bbf6c1
JB
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 }
35140025 819@@ -155,15 +205,23 @@
23bbf6c1
JB
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 */
35140025 844@@ -216,6 +274,48 @@
23bbf6c1
JB
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
35140025 893@@ -251,6 +351,9 @@
23bbf6c1
JB
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
35140025 903@@ -260,12 +363,36 @@
23bbf6c1
JB
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
368b25b6 940 /*
1ce4542c 941@@ -273,12 +400,36 @@
368b25b6
TO
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
23bbf6c1 978 /*
0b72d562 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
23bbf6c1
JB
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>
7e195e4d 995 #include <host_port.h>
0b72d562 996 #include <sane_connect.h>
997@@ -135,19 +137,45 @@
23bbf6c1
JB
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);
0b72d562 1047@@ -156,17 +184,39 @@
23bbf6c1
JB
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",
0b72d562 1093@@ -175,6 +225,25 @@
23bbf6c1
JB
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 /*
0b72d562 1119@@ -182,8 +251,17 @@
23bbf6c1
JB
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)
0b72d562 1138@@ -191,30 +269,85 @@
23bbf6c1
JB
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)
0b72d562 1167+ msg_warn("%s: bind %s: %m", myname, hbufl);
23bbf6c1 1168+ if (msg_verbose)
0b72d562 1169+ msg_info("%s: bind %s", myname, hbufl);
23bbf6c1
JB
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:
0b72d562 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;
23bbf6c1
JB
1194+#endif
1195+ default: /* T_A */
0b72d562 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;
23bbf6c1
JB
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 {
0b72d562 1221- conn_stat = sane_connect(sock, (struct sockaddr *) & sin, sizeof(sin));
23bbf6c1
JB
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);
0b72d562 1231@@ -224,8 +357,8 @@
23bbf6c1
JB
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);
0b72d562 1242@@ -237,7 +370,7 @@
368b25b6
TO
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);
0b72d562 1251@@ -249,7 +382,7 @@
368b25b6
TO
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);
0b72d562 1260@@ -260,12 +393,12 @@
368b25b6
TO
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 */
0b72d562 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
23bbf6c1
JB
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 }
0b72d562 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 @@
1ce4542c
TO
1293 static int has_my_addr(SMTPD_STATE *state, const char *host,
1294 const char *reply_name, const char *reply_class)
23bbf6c1
JB
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;
0b72d562 1342@@ -1407,6 +1450,7 @@
23bbf6c1
JB
1343 msg_info("%s: host %s: no match", myname, host);
1344
1345 return (NOPE);
1346+#endif
1347 }
1348
35140025 1349 /* i_am_mx - is this machine listed as MX relay */
0b72d562 1350@@ -1991,11 +2035,28 @@
a4192b77
JB
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,
0b72d562 1380@@ -2438,16 +2499,32 @@
c6bc5048
TO
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
23bbf6c1 1390 if (msg_verbose)
7e195e4d 1391 msg_info("%s: %s %s", myname, reply_class, addr);
e38d57a7 1392
da71bd09
JB
1393- /*
1394- * IPv4 only for now
1395- */
1396-#ifdef INET6
1397+#ifndef INET6
23bbf6c1 1398+ /* IPv4 only for now */
7e195e4d 1399 if (inet_pton(AF_INET, addr, &a) != 1)
da71bd09
JB
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)
7e195e4d 1405+ octets = argv_split(state->addr, ".");
da71bd09 1406+ else {
7e195e4d
TO
1407+ struct in6_addr a6;
1408+ if (inet_pton(AF_INET6, state->addr, &a6) != 1)
da71bd09 1409+ return SMTPD_CHECK_DUNNO;
7e195e4d 1410+ if (!IN6_IS_ADDR_V4MAPPED(&a6) || (strrchr(state->addr,':') == NULL))
da71bd09 1411+ return SMTPD_CHECK_DUNNO;
7e195e4d 1412+ octets = argv_split(strrchr(state->addr,':')+1, ".");
da71bd09
JB
1413+ }
1414 #endif
1415
23bbf6c1 1416 /*
0b72d562 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
23bbf6c1
JB
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"
c6bc5048 1457@@ -102,21 +106,28 @@
23bbf6c1
JB
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
7e195e4d
TO
1477 /*
1478 * Avoid suprious complaints from Purify on Solaris.
c6bc5048
TO
1479 */
1480- memset((char *) &sin, 0, len);
b733fb75 1481+ memset((char *) sa, 0, len);
c6bc5048 1482
23bbf6c1
JB
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
7e195e4d 1492@@ -132,23 +143,56 @@
23bbf6c1
JB
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);
7e195e4d 1540- } else if (valid_hostaddr(hp->h_name, DONT_GRIPE)) {
23bbf6c1 1541+#endif
7e195e4d
TO
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);
c6bc5048 1545+ hbuf, state->addr);
7e195e4d
TO
1546 state->name = mystrdup("unknown");
1547 state->peer_code = 5;
1548- } else if (!valid_hostname(hp->h_name, DONT_GRIPE)) {
23bbf6c1
JB
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!! */
c6bc5048 1554+ state->name = mystrdup(hbuf); /* hp->name is clobbered!! */
23bbf6c1
JB
1555 state->peer_code = 2;
1556
1557 /*
1ce4542c 1558@@ -160,16 +204,31 @@
23bbf6c1
JB
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",
1ce4542c 1591@@ -177,12 +236,11 @@
23bbf6c1
JB
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
0b72d562 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 @@
e38d57a7
JB
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
23bbf6c1 1616 /*
0b72d562 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
23bbf6c1
JB
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