]> git.pld-linux.org Git - packages/postfix.git/blame - postfix-ipv6.patch
- mass commit; now req: name = epoch:version
[packages/postfix.git] / postfix-ipv6.patch
CommitLineData
1ce4542c
TO
1Note:
2 IPv6 support depends on v6-capable getifaddrs() function
3 (i.e. from USAGI libinet6, not glibc)
4
5 non-getifaddrs v6 support is not complete - network masks
6 are not read, which could cause postfix to act as open-relay
7 (when using mynetworks_style!=host and permit_mynetworks),
8 so I decided to add #errors if getifaddrs is not supported.
9
10 If you write (correctly working) missing code, please send
11 it to me and I'll add it to patch.
12
13 Jakub Bogusz <qboosh@pld.org.pl>
14
15diff -Nur postfix-2.0.9.orig/makedefs postfix-2.0.9/makedefs
16--- postfix-2.0.9.orig/makedefs Thu Jan 23 14:45:02 2003
17+++ postfix-2.0.9/makedefs Fri Apr 18 20:55:35 2003
23bbf6c1
JB
18@@ -52,6 +52,21 @@
19 SYSTEM=`(uname -s) 2>/dev/null`
20 RELEASE=`(uname -r) 2>/dev/null`
21 VERSION=`(uname -v) 2>/dev/null`
22+if test -f /usr/include/netinet6/in6.h; then
23+ grep __KAME__ /usr/include/netinet6/in6.h 2>&1 >/dev/null
24+ if [ $? = 1 ]; then
25+ INET6=
26+ else
27+ if [ -f /usr/local/v6/lib/libinet6.a ]; then
28+ INET6=kame
29+ else
30+ INET6=kame-merged
31+ fi
32+ fi
33+fi
34+if [ -z "$INET6" -a -f /usr/include/netinet/ip6.h -a -f /usr/include/linux/icmpv6.h ]; then
35+ INET6=linux
36+fi
37
38 case "$VERSION" in
39 dcosx*) SYSTEM=$VERSION;;
1ce4542c 40@@ -318,6 +333,26 @@
23bbf6c1
JB
41
42 : ${CC='gcc $(WARN)'} ${OPT='-O'} ${DEBUG='-g'} ${AWK=awk}
830ba608 43
23bbf6c1
JB
44+case "$INET6" in
45+kame)
46+ CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len"
47+ if test -f /usr/local/v6/lib/libinet6.a; then
48+ SYSLIBS="$SYSLIBS -L/usr/local/v6/lib -linet6"
49+ fi
50+ ;;
51+kame-merged)
52+ CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len"
53+ ;;
54+linux)
55+ CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family"
56+ if test -f /usr/include/libinet6/netinet/ip6.h -a \
57+ -f /usr/lib/libinet6.a; then
58+ CCARGS="$CCARGS -I/usr/include/libinet6 -DUSAGI_LIBINET6"
59+ SYSLIBS="$SYSLIBS -linet6"
60+ fi
61+ ;;
62+esac
830ba608 63+
23bbf6c1
JB
64 export SYSTYPE AR ARFL RANLIB SYSLIBS CC OPT DEBUG AWK OPTS
65
830ba608 66 sed 's/ / /g' <<EOF
1ce4542c
TO
67diff -Nur postfix-2.0.9.orig/src/global/Makefile.in postfix-2.0.9/src/global/Makefile.in
68--- postfix-2.0.9.orig/src/global/Makefile.in Fri Apr 18 20:55:10 2003
69+++ postfix-2.0.9/src/global/Makefile.in Fri Apr 18 20:55:35 2003
23bbf6c1
JB
70@@ -19,7 +19,7 @@
71 timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \
72 tok822_resolve.c tok822_rewrite.c tok822_tree.c xtext.c bounce_log.c \
73 flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c \
7e195e4d
TO
74- verp_sender.c match_parent_style.c mime_state.c header_token.c \
75+ verp_sender.c match_parent_style.c mime_state.c header_token.c wildcard_inet_addr.c\
76 strip_addr.c virtual8_maps.c hold_message.c dict_proxy.c mail_dict.c \
77 pfixtls.c
23bbf6c1 78 OBJS = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
7e195e4d 79@@ -42,7 +42,7 @@
23bbf6c1
JB
80 timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \
81 tok822_resolve.o tok822_rewrite.o tok822_tree.o xtext.o bounce_log.o \
82 flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o \
7e195e4d
TO
83- verp_sender.o match_parent_style.o mime_state.o header_token.o \
84+ verp_sender.o match_parent_style.o mime_state.o header_token.o wildcard_inet_addr.o\
85 strip_addr.o virtual8_maps.o hold_message.o dict_proxy.o mail_dict.o \
86 pfixtls.o
23bbf6c1 87 HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
7e195e4d 88@@ -61,7 +61,7 @@
23bbf6c1
JB
89 rewrite_clnt.h sent.h smtp_stream.h split_addr.h string_list.h \
90 sys_exits.h timed_ipc.h tok822.h xtext.h bounce_log.h flush_clnt.h \
447bfc58 91 mbox_conf.h mbox_open.h abounce.h qmqp_proto.h verp_sender.h \
7e195e4d
TO
92- match_parent_style.h quote_flags.h mime_state.h header_token.h \
93+ match_parent_style.h quote_flags.h mime_state.h header_token.h wildcard_inet_addr.h\
94 lex_822.h strip_addr.h virtual8_maps.h hold_message.h dict_proxy.h \
95 mail_dict.h pfixtls.h
23bbf6c1 96 TESTSRC = rec2stream.c stream2rec.c recdump.c
1ce4542c
TO
97diff -Nur postfix-2.0.9.orig/src/global/mynetworks.c postfix-2.0.9/src/global/mynetworks.c
98--- postfix-2.0.9.orig/src/global/mynetworks.c Sun Feb 25 02:46:07 2001
99+++ postfix-2.0.9/src/global/mynetworks.c Fri Apr 18 20:55:35 2003
23bbf6c1
JB
100@@ -50,6 +50,11 @@
101 #include <vstring.h>
102 #include <inet_addr_list.h>
103 #include <name_mask.h>
104+#ifdef INET6
105+#include <sys/socket.h>
106+#include <netinet/in.h>
107+#include <netdb.h>
108+#endif
109
110 /* Global library. */
111
112@@ -75,6 +80,9 @@
113 const char *mynetworks(void)
114 {
115 static VSTRING *result;
116+#ifdef INET6
117+ char hbuf[NI_MAXHOST];
118+#endif
119
120 if (result == 0) {
121 char *myname = "mynetworks";
1ce4542c 122@@ -87,6 +95,13 @@
23bbf6c1
JB
123 int junk;
124 int i;
125 int mask_style;
126+#ifdef INET6
127+ struct sockaddr *sa;
1ce4542c
TO
128+ struct sockaddr_in6 *addr6;
129+ struct sockaddr_in6 *mask6;
130+ struct in6_addr net6;
131+ int j;
23bbf6c1
JB
132+#endif
133
134 mask_style = name_mask("mynetworks mask style", mask_styles,
135 var_mynetworks_style);
1ce4542c 136@@ -96,8 +111,45 @@
23bbf6c1
JB
137 my_mask_list = own_inet_mask_list();
138
139 for (i = 0; i < my_addr_list->used; i++) {
140+#ifdef INET6
141+ sa = (struct sockaddr *)&my_addr_list->addrs[i];
1ce4542c
TO
142+ if (sa->sa_family == AF_INET6) {
143+ addr6 = (struct sockaddr_in6 *)sa;
144+ mask6 = (struct sockaddr_in6 *)&my_mask_list->addrs[i];
145+
146+ switch (mask_style) {
147+ case MASK_STYLE_CLASS:
148+ /* treat as subnet for IPv6 */
149+ case MASK_STYLE_SUBNET:
150+ for (j=0; j<16; j++)
151+ net6.s6_addr[j] = addr6->sin6_addr.s6_addr[j] & mask6->sin6_addr.s6_addr[j];
152+ for(shift=128; shift>0; shift--)
153+ if ((mask6->sin6_addr.s6_addr[(shift-1) / 8]) & (0x80 >> ((shift-1) % 8)))
154+ break;
155+ break;
156+ case MASK_STYLE_HOST:
157+ memcpy (&net6, &(addr6->sin6_addr), sizeof(net6));
158+ shift=128;
159+ break;
160+ default:
161+ msg_panic("unknown mynetworks mask style: %s",
162+ var_mynetworks_style);
163+ }
164+ inet_ntop(AF_INET6, &net6, hbuf, sizeof(hbuf));
165+ if (!shift)
166+ msg_warn("%s: skipped network with zero mask: [%s/0]", myname, hbuf);
167+ else
168+ vstring_sprintf_append(result, "[%s/%d] ", hbuf, shift);
169+ continue;
170+ } else if (sa->sa_family != AF_INET) {
23bbf6c1
JB
171+ continue;
172+ }
173+ addr = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr);
174+ mask = ntohl(((struct sockaddr_in *)&my_mask_list->addrs[i])->sin_addr.s_addr);
175+#else
176 addr = ntohl(my_addr_list->addrs[i].s_addr);
177 mask = ntohl(my_mask_list->addrs[i].s_addr);
178+#endif
179
180 switch (mask_style) {
181
1ce4542c 182@@ -119,8 +171,15 @@
23bbf6c1
JB
183 mask = IN_CLASSD_NET;
184 shift = IN_CLASSD_NSHIFT;
185 } else {
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_fatal("%s: bad address class: %s", myname, hbuf);
191+#else
192 msg_fatal("%s: bad address class: %s",
193 myname, inet_ntoa(my_addr_list->addrs[i]));
194+#endif
195 }
196 break;
197
1ce4542c
TO
198@@ -146,6 +205,18 @@
199 var_mynetworks_style);
200 }
201 net.s_addr = htonl(addr & mask);
202+ if (shift == BITS_PER_ADDR) {
203+#ifdef INET6
204+ if (getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
205+ NI_NUMERICHOST))
206+ strncpy(hbuf, "???", sizeof(hbuf));
207+ msg_warn("%s: skipped network with zero mask: %s/0", myname, hbuf);
208+#else
209+ msg_warn("%s: skipped network with zero mask: %s/0",
210+ myname, inet_ntoa(my_addr_list->addrs[i]));
211+#endif
212+ continue;
213+ }
214 vstring_sprintf_append(result, "%s/%d ",
215 inet_ntoa(net), BITS_PER_ADDR - shift);
216 }
217diff -Nur postfix-2.0.9.orig/src/global/own_inet_addr.c postfix-2.0.9/src/global/own_inet_addr.c
218--- postfix-2.0.9.orig/src/global/own_inet_addr.c Fri Oct 25 01:19:19 2002
219+++ postfix-2.0.9/src/global/own_inet_addr.c Fri Apr 18 20:55:35 2003
220@@ -50,6 +50,10 @@
23bbf6c1
JB
221 #include <netinet/in.h>
222 #include <arpa/inet.h>
223 #include <string.h>
224+#ifdef INET6
225+#include <sys/socket.h>
226+#include <netdb.h>
227+#endif
228
229 #ifdef STRCASECMP_IN_STRINGS_H
230 #include <strings.h>
1ce4542c 231@@ -113,10 +117,11 @@
23bbf6c1
JB
232 */
233 else {
234 bufp = hosts = mystrdup(var_inet_interfaces);
235- while ((host = mystrtok(&bufp, sep)) != 0)
236+ while ((host = mystrtok(&bufp, sep)) != 0) {
237 if (inet_addr_host(addr_list, host) == 0)
238 msg_fatal("config variable %s: host not found: %s",
239 VAR_INET_INTERFACES, host);
240+ }
241 myfree(hosts);
242
35140025 243 /*
1ce4542c 244@@ -133,15 +138,39 @@
23bbf6c1
JB
245 msg_fatal("could not find any active network interfaces");
246 for (nvirtual = 0; nvirtual < addr_list->used; nvirtual++) {
247 for (nlocal = 0; /* see below */ ; nlocal++) {
248- if (nlocal >= local_addrs.used)
249+ if (nlocal >= local_addrs.used) {
250+#ifdef INET6
251+ char hbuf[NI_MAXHOST];
252+ if (getnameinfo((struct sockaddr *)&addr_list->addrs[nvirtual],
253+ SS_LEN(addr_list->addrs[nvirtual]), hbuf,
254+ sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
255+ strncpy(hbuf, "???", sizeof(hbuf));
256+ msg_fatal("parameter %s: no local interface found for %s",
257+ VAR_INET_INTERFACES, hbuf);
258+#else
259 msg_fatal("parameter %s: no local interface found for %s",
260 VAR_INET_INTERFACES,
261 inet_ntoa(addr_list->addrs[nvirtual]));
262+#endif
263+ }
264+#ifdef INET6
265+ if (addr_list->addrs[nvirtual].ss_family ==
266+ local_addrs.addrs[nlocal].ss_family &&
267+ SS_LEN(addr_list->addrs[nvirtual]) ==
268+ SS_LEN(local_addrs.addrs[nlocal]) &&
269+ memcmp(&addr_list->addrs[nvirtual],
270+ &local_addrs.addrs[nlocal],
271+ SS_LEN(local_addrs.addrs[nlocal])) == 0) {
272+ inet_addr_list_append(mask_list, (struct sockaddr *)&local_masks.addrs[nlocal]);
273+ break;
274+ }
275+#else
276 if (addr_list->addrs[nvirtual].s_addr
277 == local_addrs.addrs[nlocal].s_addr) {
278 inet_addr_list_append(mask_list, &local_masks.addrs[nlocal]);
279 break;
280 }
281+#endif
282 }
283 }
284 inet_addr_list_free(&local_addrs);
1ce4542c 285@@ -151,6 +180,42 @@
23bbf6c1
JB
286
287 /* own_inet_addr - is this my own internet address */
288
289+#ifdef INET6
290+int own_inet_addr(struct sockaddr * addr)
291+{
292+ int i;
293+ char *p, *q;
294+ int l;
295+ struct sockaddr *sa;
296+
297+ if (addr_list.used == 0)
298+ own_inet_addr_init(&addr_list, &mask_list);
299+
300+ for (i = 0; i < addr_list.used; i++) {
301+ sa = (struct sockaddr *)&addr_list.addrs[i];
302+ if (addr->sa_family != sa->sa_family)
303+ continue;
304+ switch (addr->sa_family) {
305+ case AF_INET:
306+ p = (char *)&((struct sockaddr_in *)addr)->sin_addr;
307+ q = (char *)&((struct sockaddr_in *)&addr_list.addrs[i])->sin_addr;
308+ l = sizeof(struct in_addr);
309+ break;
310+ case AF_INET6:
311+ /* XXX scope */
312+ p = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr;
313+ q = (char *)&((struct sockaddr_in6 *)&addr_list.addrs[i])->sin6_addr;
314+ l = sizeof(struct in6_addr);
315+ break;
316+ default:
317+ continue;
318+ }
319+ if (memcmp(p, q, l) == 0)
320+ return (1);
321+ }
322+ return (0);
323+}
324+#else
325 int own_inet_addr(struct in_addr * addr)
326 {
327 int i;
1ce4542c 328@@ -161,8 +226,8 @@
23bbf6c1
JB
329 for (i = 0; i < addr_list.used; i++)
330 if (addr->s_addr == addr_list.addrs[i].s_addr)
331 return (1);
332- return (0);
333 }
334+#endif
335
336 /* own_inet_addr_list - return list of addresses */
337
9d0b6835
TO
338@@ -213,6 +278,45 @@
339
340 /* proxy_inet_addr - is this my proxy internet address */
341
342+#ifdef INET6
343+int proxy_inet_addr(struct sockaddr * addr)
344+{
345+ int i;
346+ char *p, *q;
347+ int l;
348+ struct sockaddr *sa;
349+
350+ if (*var_proxy_interfaces == 0)
351+ return (0);
352+
353+ if (proxy_list.used == 0)
354+ proxy_inet_addr_init(&proxy_list);
355+
356+ for (i = 0; i < proxy_list.used; i++) {
357+ sa = (struct sockaddr *)&proxy_list.addrs[i];
358+ if (addr->sa_family != sa->sa_family)
359+ continue;
360+ switch (addr->sa_family) {
361+ case AF_INET:
362+ p = (char *)&((struct sockaddr_in *)addr)->sin_addr;
363+ q = (char *)&((struct sockaddr_in *)&addr_list.addrs[i])->sin_addr;
364+ l = sizeof(struct in_addr);
365+ break;
366+ case AF_INET6:
367+ /* XXX scope */
368+ p = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr;
369+ q = (char *)&((struct sockaddr_in6 *)&addr_list.addrs[i])->sin6_addr;
370+ l = sizeof(struct in6_addr);
371+ break;
372+ default:
373+ continue;
374+ }
375+ if (memcmp(p, q, l) == 0)
376+ return (1);
377+ }
378+ return (0);
379+}
380+#else
381 int proxy_inet_addr(struct in_addr * addr)
382 {
383 int i;
384@@ -228,6 +332,7 @@
385 return (1);
386 return (0);
387 }
388+#endif
389
390 /* proxy_inet_addr_list - return list of addresses */
391
1ce4542c
TO
392diff -Nur postfix-2.0.9.orig/src/global/own_inet_addr.h postfix-2.0.9/src/global/own_inet_addr.h
393--- postfix-2.0.9.orig/src/global/own_inet_addr.h Fri Oct 25 01:07:05 2002
394+++ postfix-2.0.9/src/global/own_inet_addr.h Fri Apr 18 20:55:35 2003
cc66c172 395@@ -15,14 +15,25 @@
23bbf6c1
JB
396 * System library.
397 */
398 #include <netinet/in.h>
399+#ifdef INET6
400+#include <sys/socket.h>
401+#endif
402
403 /*
404 * External interface.
405 */
406+#ifdef INET6
407+extern int own_inet_addr(struct sockaddr *);
408+#else
409 extern int own_inet_addr(struct in_addr *);
410+#endif
411 extern struct INET_ADDR_LIST *own_inet_addr_list(void);
412 extern struct INET_ADDR_LIST *own_inet_mask_list(void);
cc66c172
TO
413+#ifdef INET6
414+extern int proxy_inet_addr(struct sockaddr *);
415+#else
416 extern int proxy_inet_addr(struct in_addr *);
417+#endif
418 extern struct INET_ADDR_LIST *proxy_inet_addr_list(void);
23bbf6c1 419
cc66c172 420 /* LICENSE
1ce4542c
TO
421diff -Nur postfix-2.0.9.orig/src/global/peer_name.c postfix-2.0.9/src/global/peer_name.c
422--- postfix-2.0.9.orig/src/global/peer_name.c Sun Jan 28 16:23:02 2001
423+++ postfix-2.0.9/src/global/peer_name.c Fri Apr 18 20:55:35 2003
23bbf6c1
JB
424@@ -69,12 +69,32 @@
425 PEER_NAME *peer_name(int sock)
426 {
427 static PEER_NAME peer;
428- struct sockaddr_in sin;
429- SOCKADDR_SIZE len = sizeof(sin);
430+ union sockunion {
431+ struct {
432+ u_char si_len;
433+ u_char si_family;
434+ u_short si_port;
435+ } su_si;
436+ struct sockaddr peer_un;
437+ struct sockaddr_in peer_un4;
438+#ifdef INET6
439+ struct sockaddr_in6 peer_un6;
440+#endif
441+ } p_un;
442+#define sun p_un.peer_un
443+#define sin p_un.peer_un4
444+#ifdef INET6
445+#define sin6 p_un.peer_un6
446+ static char hbuf[NI_MAXHOST];
447+ static char abuf[NI_MAXHOST];
448+#else
449 struct hostent *hp;
450+#endif
451+ SOCKADDR_SIZE len = sizeof(p_un);
452
453- if (getpeername(sock, (struct sockaddr *) & sin, &len) == 0) {
454- switch (sin.sin_family) {
455+ if (getpeername(sock, (struct sockaddr *)&p_un, &len) == 0) {
456+ switch (p_un.peer_un.sa_family) {
457+#ifndef INET6
458 case AF_INET:
459 peer.type = PEER_TYPE_INET;
460 hp = gethostbyaddr((char *) &(sin.sin_addr),
461@@ -83,6 +103,24 @@
462 hp->h_name : "unknown");
463 peer.addr = inet_ntoa(sin.sin_addr);
464 return (&peer);
465+#else
466+ case AF_INET:
467+ peer.type = PEER_TYPE_INET;
468+ if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
469+ peer.name = "unknown";
470+ else
471+ peer.name = hbuf;
472+ peer.addr = abuf;
473+ return (&peer);
474+ case AF_INET6:
475+ peer.type = PEER_TYPE_INET6;
476+ if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
477+ peer.name = "unknown";
478+ else
479+ peer.name = hbuf;
480+ peer.addr = abuf;
481+ return (&peer);
482+#endif
483 case AF_UNSPEC:
484 case AF_UNIX:
485 peer.type = PEER_TYPE_LOCAL;
1ce4542c
TO
486diff -Nur postfix-2.0.9.orig/src/global/peer_name.h postfix-2.0.9/src/global/peer_name.h
487--- postfix-2.0.9.orig/src/global/peer_name.h Fri Dec 11 19:55:32 1998
488+++ postfix-2.0.9/src/global/peer_name.h Fri Apr 18 20:55:35 2003
23bbf6c1
JB
489@@ -22,6 +22,9 @@
490 #define PEER_TYPE_UNKNOWN 0
491 #define PEER_TYPE_INET 1
492 #define PEER_TYPE_LOCAL 2
493+#ifdef INET6
494+#define PEER_TYPE_INET6 3
495+#endif
496
497 extern PEER_NAME *peer_name(int);
498
1ce4542c
TO
499diff -Nur postfix-2.0.9.orig/src/global/resolve_local.c postfix-2.0.9/src/global/resolve_local.c
500--- postfix-2.0.9.orig/src/global/resolve_local.c Fri Oct 25 01:21:20 2002
501+++ postfix-2.0.9/src/global/resolve_local.c Fri Apr 18 20:55:35 2003
502@@ -43,6 +43,7 @@
23bbf6c1
JB
503 #include <netinet/in.h>
504 #include <arpa/inet.h>
505 #include <string.h>
506+#include <netdb.h>
507
508 #ifndef INADDR_NONE
509 #define INADDR_NONE 0xffffffff
1ce4542c 510@@ -80,7 +81,12 @@
23bbf6c1
JB
511 {
512 char *saved_addr = mystrdup(addr);
513 char *dest;
514+#ifdef INET6
515+ struct addrinfo hints, *res, *res0;
516+ int error;
517+#else
518 struct in_addr ipaddr;
519+#endif
520 int len;
521
522 #define RETURN(x) { myfree(saved_addr); return(x); }
7e195e4d 523@@ -118,9 +124,25 @@
23bbf6c1
JB
524 if (*dest == '[' && dest[len - 1] == ']') {
525 dest++;
526 dest[len -= 2] = 0;
527+#ifdef INET6
528+ memset(&hints, 0, sizeof(hints));
529+ hints.ai_family = PF_UNSPEC;
530+ hints.ai_socktype = SOCK_DGRAM;
531+ error = getaddrinfo(dest, NULL, &hints, &res0);
532+ if (!error) {
533+ for (res = res0; res; res = res->ai_next) {
534+ if (own_inet_addr(res->ai_addr)) {
535+ freeaddrinfo(res0);
536+ RETURN(1);
537+ }
538+ }
539+ freeaddrinfo(res0);
540+ }
541+#else
542 if ((ipaddr.s_addr = inet_addr(dest)) != INADDR_NONE
7e195e4d 543 && (own_inet_addr(&ipaddr) || proxy_inet_addr(&ipaddr)))
23bbf6c1
JB
544 RETURN(1);
545+#endif
546 }
547
548 /*
1ce4542c
TO
549diff -Nur postfix-2.0.9.orig/src/global/wildcard_inet_addr.c postfix-2.0.9/src/global/wildcard_inet_addr.c
550--- postfix-2.0.9.orig/src/global/wildcard_inet_addr.c Thu Jan 1 01:00:00 1970
551+++ postfix-2.0.9/src/global/wildcard_inet_addr.c Fri Apr 18 20:55:35 2003
23bbf6c1
JB
552@@ -0,0 +1,82 @@
553+/* System library. */
554+
555+#include <sys_defs.h>
556+#include <netinet/in.h>
557+#include <arpa/inet.h>
558+#include <string.h>
559+#ifdef INET6
560+#include <sys/socket.h>
561+#endif
562+#include <netdb.h>
563+
564+#ifdef STRCASECMP_IN_STRINGS_H
565+#include <strings.h>
566+#endif
567+
568+/* Utility library. */
569+
570+#include <msg.h>
571+#include <mymalloc.h>
572+#include <inet_addr_list.h>
573+#include <inet_addr_local.h>
574+#include <inet_addr_host.h>
575+#include <stringops.h>
576+
577+/* Global library. */
578+
579+#include <mail_params.h>
580+#include <wildcard_inet_addr.h>
581+
582+/* Application-specific. */
583+static INET_ADDR_LIST addr_list;
584+
585+/* wildcard_inet_addr_init - initialize my own address list */
586+
587+static void wildcard_inet_addr_init(INET_ADDR_LIST *addr_list)
588+{
589+#ifdef INET6
590+ struct addrinfo hints, *res, *res0;
591+ char hbuf[NI_MAXHOST];
592+ int error;
593+#ifdef NI_WITHSCOPEID
594+ const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
595+#else
596+ const int niflags = NI_NUMERICHOST;
597+#endif
598+
599+ inet_addr_list_init(addr_list);
600+
601+ memset(&hints, 0, sizeof(hints));
602+ hints.ai_family = PF_UNSPEC;
603+ hints.ai_socktype = SOCK_STREAM;
604+ hints.ai_flags = AI_PASSIVE;
605+ error = getaddrinfo(NULL, "0", &hints, &res0);
606+ if (error)
607+ msg_fatal("could not get list of wildcard addresses");
608+ for (res = res0; res; res = res->ai_next) {
609+ if (res->ai_family != AF_INET && res->ai_family != AF_INET6)
610+ continue;
611+ if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
612+ NULL, 0, niflags) != 0)
613+ continue;
614+ if (inet_addr_host(addr_list, hbuf) == 0)
615+ continue; /* msg_fatal("config variable %s: host not found: %s",
616+ VAR_INET_INTERFACES, hbuf); */
617+ }
618+ freeaddrinfo(res0);
619+#else
620+ if (inet_addr_host(addr_list, "0.0.0.0") == 0)
621+ msg_fatal("config variable %s: host not found: %s",
622+ VAR_INET_INTERFACES, "0.0.0.0");
623+#endif
624+}
625+
626+/* wildcard_inet_addr_list - return list of addresses */
627+
628+INET_ADDR_LIST *wildcard_inet_addr_list(void)
629+{
630+ if (addr_list.used == 0)
631+ wildcard_inet_addr_init(&addr_list);
632+
633+ return (&addr_list);
634+}
1ce4542c
TO
635diff -Nur postfix-2.0.9.orig/src/global/wildcard_inet_addr.h postfix-2.0.9/src/global/wildcard_inet_addr.h
636--- postfix-2.0.9.orig/src/global/wildcard_inet_addr.h Thu Jan 1 01:00:00 1970
637+++ postfix-2.0.9/src/global/wildcard_inet_addr.h Fri Apr 18 20:55:35 2003
23bbf6c1
JB
638@@ -0,0 +1,36 @@
639+#ifndef _WILDCARD_INET_ADDR_H_INCLUDED_
640+#define _WILDCARD_INET_ADDR_H_INCLUDED_
641+
642+/*++
643+/* NAME
644+/* wildcard_inet_addr_list 3h
645+/* SUMMARY
646+/* grab the list of wildcard IP addresses.
647+/* SYNOPSIS
648+/* #include <own_inet_addr.h>
649+/* DESCRIPTION
650+/* .nf
651+/*--*/
652+
653+ /*
654+ * System library.
655+ */
656+#include <netinet/in.h>
657+#ifdef INET6
658+#include <sys/socket.h>
659+#endif
660+
661+ /*
662+ * External interface.
663+ */
664+extern struct INET_ADDR_LIST *wildcard_inet_addr_list(void);
665+
666+/* LICENSE
667+/* .ad
668+/* .fi
669+/* foo
670+/* AUTHOR(S)
671+/* Jun-ichiro itojun Hagino
672+/*--*/
673+
674+#endif
1ce4542c
TO
675diff -Nur postfix-2.0.9.orig/src/master/master_ent.c postfix-2.0.9/src/master/master_ent.c
676--- postfix-2.0.9.orig/src/master/master_ent.c Mon Jan 13 01:25:39 2003
677+++ postfix-2.0.9/src/master/master_ent.c Fri Apr 18 20:55:35 2003
678@@ -285,8 +285,13 @@
679 inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv));
23bbf6c1
JB
680 serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
681 } else if (strcasecmp(var_inet_interfaces, DEF_INET_INTERFACES) == 0) {
682+#ifdef INET6
683+ MASTER_INET_ADDRLIST(serv) = wildcard_inet_addr_list();
684+ serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
685+#else
686 MASTER_INET_ADDRLIST(serv) = 0; /* wild-card */
687 serv->listen_fd_count = 1;
688+#endif
689 } else {
690 MASTER_INET_ADDRLIST(serv) = own_inet_addr_list(); /* virtual */
1ce4542c
TO
691 inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv));
692diff -Nur postfix-2.0.9.orig/src/master/master_listen.c postfix-2.0.9/src/master/master_listen.c
693--- postfix-2.0.9.orig/src/master/master_listen.c Tue May 1 00:47:57 2001
694+++ postfix-2.0.9/src/master/master_listen.c Fri Apr 18 20:55:35 2003
e38d57a7 695@@ -64,13 +64,22 @@
23bbf6c1
JB
696
697 #include "master.h"
698
699+#ifdef INET6
700+#include <netdb.h>
701+#include <stdio.h>
702+#endif
703+
704 /* master_listen_init - enable connection requests */
705
706 void master_listen_init(MASTER_SERV *serv)
e38d57a7 707 {
23bbf6c1
JB
708 char *myname = "master_listen_init";
709 char *end_point;
e38d57a7
JB
710- int n;
711+ int n,m,tmpfd;
23bbf6c1
JB
712+#ifdef INET6
713+ char hbuf[NI_MAXHOST];
714+ SOCKADDR_SIZE salen;
715+#endif
716
717 /*
718 * Find out what transport we should use, then create one or more
e38d57a7
JB
719@@ -111,18 +120,31 @@
720 serv->listen_fd[0] =
721 inet_listen(MASTER_INET_PORT(serv),
722 serv->max_proc > var_proc_limit ?
723- serv->max_proc : var_proc_limit, NON_BLOCKING);
724+ serv->max_proc : var_proc_limit, NON_BLOCKING, 1);
23bbf6c1
JB
725 close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
726 } else { /* virtual or host:port */
e38d57a7
JB
727- for (n = 0; n < serv->listen_fd_count; n++) {
728+ for (m = n = 0; n < serv->listen_fd_count; n++) {
23bbf6c1
JB
729+#ifdef INET6
730+ if (getnameinfo((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n],
731+ SA_LEN((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n]),
732+ hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) {
733+ strncpy(hbuf, "?????", sizeof(hbuf));
734+ }
735+ end_point = concatenate(hbuf, ":", MASTER_INET_PORT(serv), (char *) 0);
736+#else
737 end_point = concatenate(inet_ntoa(MASTER_INET_ADDRLIST(serv)->addrs[n]),
738 ":", MASTER_INET_PORT(serv), (char *) 0);
e38d57a7 739- serv->listen_fd[n]
23bbf6c1 740+#endif
e38d57a7 741+ tmpfd
23bbf6c1 742 = inet_listen(end_point, serv->max_proc > var_proc_limit ?
e38d57a7
JB
743- serv->max_proc : var_proc_limit, NON_BLOCKING);
744- close_on_exec(serv->listen_fd[n], CLOSE_ON_EXEC);
745+ serv->max_proc : var_proc_limit, NON_BLOCKING, 0);
746+ if (tmpfd >= 0) {
747+ serv->listen_fd[m] = tmpfd;
748+ close_on_exec(serv->listen_fd[m++], CLOSE_ON_EXEC);
749+ }
750 myfree(end_point);
751 }
752+ serv->listen_fd_count=m;
753 }
754 break;
755 default:
1ce4542c
TO
756diff -Nur postfix-2.0.9.orig/src/smtp/Makefile.in postfix-2.0.9/src/smtp/Makefile.in
757--- postfix-2.0.9.orig/src/smtp/Makefile.in Fri Apr 18 20:55:10 2003
758+++ postfix-2.0.9/src/smtp/Makefile.in Fri Apr 18 20:55:35 2003
759@@ -143,6 +143,7 @@
23bbf6c1
JB
760 smtp_connect.o: ../../include/mail_params.h
761 smtp_connect.o: ../../include/own_inet_addr.h
762 smtp_connect.o: ../../include/dns.h
763+smtp_connect.o: ../../include/get_port.h
764 smtp_connect.o: smtp.h
765 smtp_connect.o: ../../include/argv.h
766 smtp_connect.o: ../../include/deliver_request.h
1ce4542c
TO
767diff -Nur postfix-2.0.9.orig/src/smtp/smtp_addr.c postfix-2.0.9/src/smtp/smtp_addr.c
768--- postfix-2.0.9.orig/src/smtp/smtp_addr.c Fri Oct 25 01:03:11 2002
769+++ postfix-2.0.9/src/smtp/smtp_addr.c Fri Apr 18 20:55:35 2003
35140025 770@@ -134,18 +134,68 @@
23bbf6c1
JB
771 static void smtp_print_addr(char *what, DNS_RR *addr_list)
772 {
773 DNS_RR *addr;
774- struct in_addr in_addr;
775+#ifdef INET6
776+ struct sockaddr_storage ss;
777+#else
778+ struct sockaddr ss;
779+#endif
780+ struct sockaddr_in *sin;
781+#ifdef INET6
782+ struct sockaddr_in6 *sin6;
783+ char hbuf[NI_MAXHOST];
784+#else
785+ char hbuf[sizeof("255.255.255.255") + 1];
786+#endif
787
788 msg_info("begin %s address list", what);
789 for (addr = addr_list; addr; addr = addr->next) {
790- if (addr->data_len > sizeof(addr)) {
791- msg_warn("skipping address length %d", addr->data_len);
792- } else {
793- memcpy((char *) &in_addr, addr->data, sizeof(in_addr));
794- msg_info("pref %4d host %s/%s",
795- addr->pref, addr->name,
796- inet_ntoa(in_addr));
797+ if (addr->class != C_IN) {
798+ msg_warn("skipping unsupported address (class=%u)", addr->class);
799+ continue;
800 }
801+ switch (addr->type) {
802+ case T_A:
803+ if (addr->data_len != sizeof(sin->sin_addr)) {
804+ msg_warn("skipping invalid address (AAAA, len=%u)",
805+ addr->data_len);
806+ continue;
807+ }
808+ sin = (struct sockaddr_in *)&ss;
809+ memset(sin, 0, sizeof(*sin));
810+ sin->sin_family = AF_INET;
811+#ifdef HAS_SA_LEN
812+ sin->sin_len = sizeof(*sin);
813+#endif
814+ memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr));
815+ break;
816+#ifdef INET6
817+ case T_AAAA:
818+ if (addr->data_len != sizeof(sin6->sin6_addr)) {
819+ msg_warn("skipping invalid address (AAAA, len=%u)",
820+ addr->data_len);
821+ continue;
822+ }
823+ sin6 = (struct sockaddr_in6 *)&ss;
824+ memset(sin6, 0, sizeof(*sin6));
825+ sin6->sin6_family = AF_INET6;
826+#ifdef HAS_SA_LEN
827+ sin6->sin6_len = sizeof(*sin6);
828+#endif
829+ memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr));
830+ break;
831+#endif
832+ default:
833+ msg_warn("skipping unsupported address (type=%u)", addr->type);
834+ continue;
835+ }
836+
837+#ifdef INET6
838+ (void)getnameinfo((struct sockaddr *)&ss, SS_LEN(ss),
839+ hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
840+#else
841+ (void)inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf));
842+#endif
843+ msg_info("pref %4d host %s/%s", addr->pref, addr->name, hbuf);
844 }
845 msg_info("end %s address list", what);
846 }
35140025 847@@ -155,15 +205,23 @@
23bbf6c1
JB
848 static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRING *why)
849 {
850 char *myname = "smtp_addr_one";
851+#ifndef INET6
852 struct in_addr inaddr;
853- DNS_FIXED fixed;
854 DNS_RR *addr = 0;
855 DNS_RR *rr;
856 struct hostent *hp;
857+#else
858+ struct addrinfo hints, *res0, *res;
859+ int error = -1;
860+ char *addr;
861+ size_t addrlen;
862+#endif
863+ DNS_FIXED fixed;
864
865 if (msg_verbose)
866 msg_info("%s: host %s", myname, host);
867
868+#ifndef INET6
869 /*
870 * Interpret a numerical name as an address.
871 */
35140025 872@@ -216,6 +274,48 @@
23bbf6c1
JB
873 smtp_errno = SMTP_FAIL;
874 break;
875 }
876+#else
877+ memset(&hints, 0, sizeof(hints));
878+ hints.ai_family = PF_UNSPEC;
879+ hints.ai_socktype = SOCK_STREAM;
880+ error = getaddrinfo(host, NULL, &hints, &res0);
881+ if (error) {
882+ switch (error) {
883+ case EAI_AGAIN:
884+ smtp_errno = SMTP_RETRY;
885+ break;
886+ default:
887+ vstring_sprintf(why, "[%s]: %s",host,gai_strerror(error));
888+ smtp_errno = SMTP_FAIL;
889+ break;
890+ }
891+ return (addr_list);
892+ }
893+ for (res = res0; res; res = res->ai_next) {
894+ memset((char *) &fixed, 0, sizeof(fixed));
895+ switch(res->ai_family) {
896+ case AF_INET6:
897+ /* XXX not scope friendly */
898+ fixed.type = T_AAAA;
899+ addr = (char *)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
900+ addrlen = sizeof(struct in6_addr);
901+ break;
902+ case AF_INET:
903+ fixed.type = T_A;
904+ addr = (char *)&((struct sockaddr_in *)res->ai_addr)->sin_addr;
905+ addrlen = sizeof(struct in_addr);
906+ break;
907+ default:
908+ msg_warn("%s: unknown address family %d for %s",
909+ myname, res->ai_family, host);
910+ continue;
911+ }
912+ addr_list = dns_rr_append(addr_list,
913+ dns_rr_create(host, &fixed, pref, addr, addrlen));
914+ }
915+ if (res0)
916+ freeaddrinfo(res0);
917+#endif
918 return (addr_list);
919 }
920
35140025 921@@ -251,6 +351,9 @@
23bbf6c1
JB
922 INET_ADDR_LIST *self;
923 DNS_RR *addr;
924 int i;
925+#ifdef INET6
926+ struct sockaddr *sa;
927+#endif
928
929 /*
930 * Find the first address that lists any address that this mail system is
35140025 931@@ -260,12 +363,36 @@
23bbf6c1
JB
932
933 self = own_inet_addr_list();
934 for (addr = addr_list; addr; addr = addr->next) {
935- for (i = 0; i < self->used; i++)
936+ for (i = 0; i < self->used; i++) {
937+#ifdef INET6
938+ sa = (struct sockaddr *)&self->addrs[i];
939+ switch(addr->type) {
940+ case T_AAAA:
941+ /* XXX scope */
942+ if (sa->sa_family != AF_INET6)
943+ break;
944+ if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr,
945+ addr->data, sizeof(struct in6_addr)) == 0) {
946+ return(addr);
947+ }
948+ break;
949+ case T_A:
950+ if (sa->sa_family != AF_INET)
951+ break;
952+ if (memcmp(&((struct sockaddr_in *)sa)->sin_addr,
953+ addr->data, sizeof(struct in_addr)) == 0) {
954+ return(addr);
955+ }
956+ break;
957+ }
958+#else
959 if (INADDRP(addr->data)->s_addr == self->addrs[i].s_addr) {
960 if (msg_verbose)
961 msg_info("%s: found at pref %d", myname, addr->pref);
962 return (addr);
963 }
964+#endif
965+ }
966 }
967
368b25b6 968 /*
1ce4542c 969@@ -273,12 +400,36 @@
368b25b6
TO
970 */
971 self = proxy_inet_addr_list();
972 for (addr = addr_list; addr; addr = addr->next) {
973- for (i = 0; i < self->used; i++)
974+ for (i = 0; i < self->used; i++) {
975+#ifdef INET6
976+ sa = (struct sockaddr *)&self->addrs[i];
977+ switch(addr->type) {
978+ case T_AAAA:
979+ /* XXX scope */
980+ if (sa->sa_family != AF_INET6)
981+ break;
982+ if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr,
983+ addr->data, sizeof(struct in6_addr)) == 0) {
984+ return(addr);
985+ }
986+ break;
987+ case T_A:
988+ if (sa->sa_family != AF_INET)
989+ break;
990+ if (memcmp(&((struct sockaddr_in *)sa)->sin_addr,
991+ addr->data, sizeof(struct in_addr)) == 0) {
992+ return(addr);
993+ }
994+ break;
995+ }
996+#else
997 if (INADDRP(addr->data)->s_addr == self->addrs[i].s_addr) {
998 if (msg_verbose)
999 msg_info("%s: found at pref %d", myname, addr->pref);
1000 return (addr);
1001 }
1002+#endif
1003+ }
1004 }
1005
23bbf6c1 1006 /*
1ce4542c
TO
1007diff -Nur postfix-2.0.9.orig/src/smtp/smtp_connect.c postfix-2.0.9/src/smtp/smtp_connect.c
1008--- postfix-2.0.9.orig/src/smtp/smtp_connect.c Fri Apr 18 20:55:10 2003
1009+++ postfix-2.0.9/src/smtp/smtp_connect.c Fri Apr 18 20:55:35 2003
23bbf6c1
JB
1010@@ -81,6 +81,7 @@
1011 /* System library. */
1012
1013 #include <sys_defs.h>
1014+#include <stdlib.h>
1015 #include <sys/socket.h>
1016 #include <netinet/in.h>
1017 #include <arpa/inet.h>
1018@@ -110,6 +111,7 @@
1019 #include <inet_addr_list.h>
1020 #include <iostuff.h>
1021 #include <timed_connect.h>
1022+#include <get_port.h>
1023 #include <stringops.h>
7e195e4d 1024 #include <host_port.h>
23bbf6c1 1025
7e195e4d 1026@@ -134,19 +136,45 @@
23bbf6c1
JB
1027 VSTRING *why)
1028 {
1029 char *myname = "smtp_connect_addr";
1030- struct sockaddr_in sin;
1031- int sock;
1032+#ifdef INET6
1033+ struct sockaddr_storage ss;
1034+#else
1035+ struct sockaddr ss;
1036+#endif
1037+ struct sockaddr *sa;
1038+ struct sockaddr_in *sin;
1039+#ifdef INET6
1040+ struct sockaddr_in6 *sin6;
1041+#endif
1042+ SOCKADDR_SIZE salen;
1043+#ifdef INET6
1044+ char hbuf[NI_MAXHOST];
1045+#else
1046+ char hbuf[sizeof("255.255.255.255") + 1];
1047+#endif
1048+ int sock = -1;
1049 INET_ADDR_LIST *addr_list;
1050 int conn_stat;
1051 int saved_errno;
1052 VSTREAM *stream;
1053 int ch;
1054- unsigned long inaddr;
1055+
1056+ sa = (struct sockaddr *)&ss;
1057+ sin = (struct sockaddr_in *)&ss;
1058+#ifdef INET6
1059+ sin6 = (struct sockaddr_in6 *)&ss;
1060+#endif
1061
1062 /*
1063 * Sanity checks.
1064 */
1065- if (addr->data_len > sizeof(sin.sin_addr)) {
1066+#ifdef INET6
1067+ if (((addr->type==T_A) && (addr->data_len > sizeof(sin->sin_addr))) ||
1068+ ((addr->type==T_AAAA) && (addr->data_len > sizeof(sin6->sin6_addr))))
1069+#else
1070+ if (addr->data_len > sizeof(sin->sin_addr))
1071+#endif
1072+ {
1073 msg_warn("%s: skip address with length %d", myname, addr->data_len);
1074 smtp_errno = SMTP_RETRY;
1075 return (0);
7e195e4d 1076@@ -155,17 +183,39 @@
23bbf6c1
JB
1077 /*
1078 * Initialize.
1079 */
1080- memset((char *) &sin, 0, sizeof(sin));
1081- sin.sin_family = AF_INET;
1082-
1083- if ((sock = socket(sin.sin_family, SOCK_STREAM, 0)) < 0)
1084- msg_fatal("%s: socket: %m", myname);
1085-
1086+ switch (addr->type) {
1087+#ifdef INET6
1088+ case T_AAAA:
1089+ memset(sin6, 0, sizeof(*sin6));
1090+ sin6->sin6_family = AF_INET6;
1091+ salen = sizeof(*sin6);
1092+ break;
1093+#endif
1094+ default: /* T_A: */
1095+ memset(sin, 0, sizeof(*sin));
1096+ sin->sin_family = AF_INET;
1097+ salen = sizeof(*sin);
1098+ break;
1099+ }
1100+#ifdef HAS_SA_LEN
1101+ sa->sa_len = salen;
1102+#endif
1103+ if ((sock = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
1104+ msg_warn("%s: socket: %m", myname);
1105+
1106 /*
1107 * Allow the sysadmin to specify the source address, for example, as "-o
1108 * smtp_bind_address=x.x.x.x" in the master.cf file.
1109 */
1110 if (*var_smtp_bind_addr) {
1111+#ifndef INET6
1112+ struct sockaddr_in sin;
1113+
1114+ memset(&sin, 0, sizeof(sin));
1115+ sin.sin_family = AF_INET;
1116+#ifdef HAS_SA_LEN
1117+ sin.sin_len = sizeof(sin);
1118+#endif
1119 sin.sin_addr.s_addr = inet_addr(var_smtp_bind_addr);
1120 if (sin.sin_addr.s_addr == INADDR_NONE)
1121 msg_fatal("%s: bad %s parameter: %s",
7e195e4d 1122@@ -174,6 +224,25 @@
23bbf6c1
JB
1123 msg_warn("%s: bind %s: %m", myname, inet_ntoa(sin.sin_addr));
1124 if (msg_verbose)
1125 msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
1126+#else
1127+ char hbufl[NI_MAXHOST];
1128+ struct addrinfo hints, *res;
1129+
1130+ memset(&hints, 0, sizeof(hints));
1131+ hints.ai_family = sa->sa_family;
1132+ hints.ai_socktype = SOCK_STREAM;
1133+ hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST;
1134+ snprintf(hbufl, sizeof(hbufl)-1, "%s", var_smtp_bind_addr);
1135+ if (getaddrinfo(hbufl, NULL, &hints, &res) == 0) {
1136+ (void)getnameinfo(res->ai_addr, res->ai_addrlen, hbufl,
1137+ sizeof(hbufl), NULL, 0, NI_NUMERICHOST);
1138+ if (bind(sock, res->ai_addr, res->ai_addrlen) < 0)
1139+ msg_warn("%s: bind %s: %m", myname, hbufl);
1140+ freeaddrinfo(res);
1141+ if (msg_verbose)
1142+ msg_info("%s: bind %s", myname, hbufl);
1143+ }
1144+#endif
1145 }
1146
1147 /*
7e195e4d 1148@@ -181,8 +250,17 @@
23bbf6c1
JB
1149 * the mail appears to come from the "right" machine address.
1150 */
1151 else if ((addr_list = own_inet_addr_list())->used == 1) {
1152+#ifndef INET6
1153+ struct sockaddr_in sin;
1154+ unsigned long inaddr; /*XXX BAD!*/
1155+
1156+ memset(&sin, 0, sizeof(sin));
1157+ sin.sin_family = AF_INET;
1158+#ifdef HAS_SA_LEN
1159+ sin.sin_len = sizeof(sin);
1160+#endif
1161 memcpy((char *) &sin.sin_addr, addr_list->addrs, sizeof(sin.sin_addr));
1162- inaddr = ntohl(sin.sin_addr.s_addr);
1163+ inaddr = (unsigned long)ntohl(sin.sin_addr.s_addr);
1164 if (!IN_CLASSA(inaddr)
1165 || !(((inaddr & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)) {
1166 if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
7e195e4d 1167@@ -190,30 +268,85 @@
23bbf6c1
JB
1168 if (msg_verbose)
1169 msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
1170 }
1171+#else
1172+ char hbufl[NI_MAXHOST];
1173+ struct addrinfo hints, *res = NULL, *loopback = NULL;
1174+
1175+ memset(&hints, 0, sizeof(hints));
1176+ hints.ai_family = sa->sa_family;
1177+ hints.ai_socktype = SOCK_STREAM;
1178+ if (getaddrinfo(NULL, "0", &hints, &loopback) != 0)
1179+ loopback = NULL;
1180+
1181+ /*
1182+ * getnameinfo -> getaddrinfo loop is here so that we can
1183+ * get rid of port.
1184+ */
1185+ (void)getnameinfo((struct sockaddr *)addr_list->addrs, SA_LEN((struct sockaddr *)addr_list->addrs),
1186+ hbufl, sizeof(hbufl), NULL, 0, NI_NUMERICHOST);
1187+ hbufl[sizeof(hbufl)-1] = 0;
1188+ memset(&hints, 0, sizeof(hints));
1189+ hints.ai_family = sa->sa_family;
1190+ hints.ai_socktype = SOCK_STREAM;
1191+ hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST;
1192+ if (getaddrinfo(hbufl, NULL, &hints, &res) == 0 &&
1193+ !(res->ai_addrlen == loopback->ai_addrlen &&
1194+ memcmp(res->ai_addr, loopback->ai_addr, res->ai_addrlen) == 0)) {
1195+ if (bind(sock, res->ai_addr, res->ai_addrlen) < 0)
1196+ msg_warn("%s: bind %s: %m", myname, hbufl);
1197+ if (msg_verbose)
1198+ msg_info("%s: bind %s", myname, hbufl);
1199+ }
1200+ if (res)
1201+ freeaddrinfo(res);
1202+ if (loopback)
1203+ freeaddrinfo(loopback);
1204+#endif
1205 }
1206
1207 /*
1208 * Connect to the SMTP server.
1209 */
1210- sin.sin_port = port;
1211- memcpy((char *) &sin.sin_addr, addr->data, sizeof(sin.sin_addr));
1212+ switch (addr->type) {
1213+#ifdef INET6
1214+ case T_AAAA:
1215+ /* XXX scope unfriendly */
1216+ memset(sin6, 0, sizeof(*sin6));
1217+ sin6->sin6_port = port;
1218+ sin6->sin6_family = AF_INET6;
1219+ salen = sizeof(*sin6);
1220+ memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr));
1221+ inet_ntop(AF_INET6, &sin6->sin6_addr, hbuf, sizeof(hbuf));
1222+ break;
1223+#endif
1224+ default: /* T_A */
1225+ memset(sin, 0, sizeof(*sin));
1226+ sin->sin_port = port;
1227+ sin->sin_family = AF_INET;
1228+ salen = sizeof(*sin);
1229+ memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr));
1230+ inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf));
1231+ break;
1232+ }
1233+#ifdef HAS_SA_LEN
1234+ sa->sa_len = salen;
1235+#endif
1236
1237 if (msg_verbose)
1238 msg_info("%s: trying: %s[%s] port %d...",
1239- myname, addr->name, inet_ntoa(sin.sin_addr), ntohs(port));
1240+ myname, addr->name, hbuf, ntohs(port));
1241 if (var_smtp_conn_tmout > 0) {
1242 non_blocking(sock, NON_BLOCKING);
1243- conn_stat = timed_connect(sock, (struct sockaddr *) & sin,
1244- sizeof(sin), var_smtp_conn_tmout);
1245+ conn_stat = timed_connect(sock, sa, salen, var_smtp_conn_tmout);
1246 saved_errno = errno;
1247 non_blocking(sock, BLOCKING);
1248 errno = saved_errno;
1249 } else {
1250- conn_stat = connect(sock, (struct sockaddr *) & sin, sizeof(sin));
1251+ conn_stat = connect(sock, sa, salen);
1252 }
1253 if (conn_stat < 0) {
1254 vstring_sprintf(why, "connect to %s[%s]: %m",
1255- addr->name, inet_ntoa(sin.sin_addr));
1256+ addr->name, hbuf);
1257 smtp_errno = SMTP_RETRY;
1258 close(sock);
1259 return (0);
7e195e4d 1260@@ -223,8 +356,8 @@
23bbf6c1
JB
1261 * Skip this host if it takes no action within some time limit.
1262 */
1263 if (read_wait(sock, var_smtp_helo_tmout) < 0) {
1264- vstring_sprintf(why, "connect to %s[%s]: read timeout",
1265- addr->name, inet_ntoa(sin.sin_addr));
1266+ vstring_sprintf(why, "connect to %s [%s]: read timeout",
1267+ addr->name, hbuf);
1268 smtp_errno = SMTP_RETRY;
1269 close(sock);
1270 return (0);
1ce4542c 1271@@ -236,7 +369,7 @@
368b25b6
TO
1272 stream = vstream_fdopen(sock, O_RDWR);
1273 if ((ch = VSTREAM_GETC(stream)) == VSTREAM_EOF) {
1274 vstring_sprintf(why, "connect to %s[%s]: server dropped connection without sending the initial greeting",
1275- addr->name, inet_ntoa(sin.sin_addr));
1276+ addr->name, hbuf);
1277 smtp_errno = SMTP_RETRY;
1278 vstream_fclose(stream);
1279 return (0);
1ce4542c 1280@@ -248,7 +381,7 @@
368b25b6
TO
1281 */
1282 if (ch == '4' && var_smtp_skip_4xx_greeting) {
1283 vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
1284- addr->name, inet_ntoa(sin.sin_addr));
1285+ addr->name, hbuf);
1286 smtp_errno = SMTP_RETRY;
1287 vstream_fclose(stream);
1288 return (0);
1ce4542c 1289@@ -259,12 +392,12 @@
368b25b6
TO
1290 */
1291 if (ch == '5' && var_smtp_skip_5xx_greeting) {
1292 vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
1293- addr->name, inet_ntoa(sin.sin_addr));
1294+ addr->name, hbuf);
1295 smtp_errno = SMTP_RETRY;
1296 vstream_fclose(stream);
1297 return (0);
1298 }
1299- return (smtp_session_alloc(dest, stream, addr->name, inet_ntoa(sin.sin_addr)));
1300+ return (smtp_session_alloc(dest, stream, addr->name, hbuf));
1301 }
1302
1303 /* smtp_connect_host - direct connection to host */
1ce4542c
TO
1304diff -Nur postfix-2.0.9.orig/src/smtp/smtp_unalias.c postfix-2.0.9/src/smtp/smtp_unalias.c
1305--- postfix-2.0.9.orig/src/smtp/smtp_unalias.c Thu Sep 28 19:06:09 2000
1306+++ postfix-2.0.9/src/smtp/smtp_unalias.c Fri Apr 18 20:55:35 2003
23bbf6c1
JB
1307@@ -86,7 +86,11 @@
1308 if ((result = htable_find(cache, name)) == 0) {
1309 fqdn = vstring_alloc(10);
1310 if (dns_lookup_types(name, smtp_unalias_flags, (DNS_RR **) 0,
1311- fqdn, (VSTRING *) 0, T_MX, T_A, 0) != DNS_OK)
1312+ fqdn, (VSTRING *) 0, T_MX, T_A,
1313+#ifdef INET6
1314+ T_AAAA,
1315+#endif
1316+ 0) != DNS_OK)
1317 vstring_strcpy(fqdn, name);
1318 htable_enter(cache, name, result = vstring_export(fqdn));
1319 }
1ce4542c
TO
1320diff -Nur postfix-2.0.9.orig/src/smtpd/smtpd_check.c postfix-2.0.9/src/smtpd/smtpd_check.c
1321--- postfix-2.0.9.orig/src/smtpd/smtpd_check.c Fri Apr 18 20:55:10 2003
1322+++ postfix-2.0.9/src/smtpd/smtpd_check.c Fri Apr 18 20:55:35 2003
1323@@ -1362,6 +1362,49 @@
1324 static int has_my_addr(SMTPD_STATE *state, const char *host,
1325 const char *reply_name, const char *reply_class)
23bbf6c1
JB
1326 {
1327+#ifdef INET6
1328+ char *myname = "has_my_addr";
1329+ struct addrinfo hints, *res, *res0;
1330+ int error;
1331+ char hbuf[NI_MAXHOST];
1332+
1333+ if (msg_verbose)
1334+ msg_info("%s: host %s", myname, host);
1335+
1336+ /*
1337+ * If we can't lookup the host, play safe and assume it is OK.
1338+ */
1339+#define YUP 1
1340+#define NOPE 0
1341+
1342+ memset(&hints, 0, sizeof(hints));
1343+ hints.ai_family = PF_UNSPEC;
1344+ hints.ai_socktype = SOCK_DGRAM;
1345+ error = getaddrinfo(host, NULL, &hints, &res0);
1346+ if (error) {
1347+ if (msg_verbose)
1348+ msg_info("%s: host %s: %s", myname, host, gai_strerror(error));
1349+ return (YUP);
1350+ }
1351+ for (res = res0; res; res = res->ai_next) {
1352+ if (msg_verbose) {
1353+ if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
1354+ NULL, 0, NI_NUMERICHOST)) {
1355+ strncpy(hbuf, "???", sizeof(hbuf));
1356+ }
1357+ msg_info("%s: addr %s", myname, hbuf);
1358+ }
1359+ if (own_inet_addr(res->ai_addr)) {
1360+ freeaddrinfo(res0);
1361+ return (YUP);
1362+ }
1363+ }
1364+ freeaddrinfo(res0);
1365+ if (msg_verbose)
1366+ msg_info("%s: host %s: no match", myname, host);
1367+
1368+ return (NOPE);
1369+#else
1370 char *myname = "has_my_addr";
1371 struct in_addr addr;
1372 char **cpp;
1ce4542c 1373@@ -1400,6 +1443,7 @@
23bbf6c1
JB
1374 msg_info("%s: host %s: no match", myname, host);
1375
1376 return (NOPE);
1377+#endif
1378 }
1379
35140025 1380 /* i_am_mx - is this machine listed as MX relay */
1ce4542c 1381@@ -1984,11 +2028,28 @@
a4192b77
JB
1382 #define CHK_ADDR_RETURN(x,y) { *found = y; return(x); }
1383
1384 addr = STR(vstring_strcpy(error_text, address));
1385-
1386+#ifdef INET6
1387+ if (strncmp(addr, "::ffff:", 7) == 0 && msg_verbose)
1388+ msg_info("%s: %s v6 addr in v4 compat-mode, "
1389+ "converted to v4 for map checking compatibility (%s)", \
1390+ myname, addr, addr+7);
1391+#endif
1392+
1393 if ((dict = dict_handle(table)) == 0)
1394 msg_panic("%s: dictionary not found: %s", myname, table);
1395 do {
1396 if (flags == 0 || (flags & dict->flags) != 0) {
1397+#ifdef INET6
1398+ if (strncmp(addr, "::ffff:", 7) == 0) {
1399+ /* try if ::ffff: formati is present in map, if not, try
1400+ traditional IPv4 format striping :ffff: part */
1401+ if ((value = dict_get(dict, addr)) != 0 || \
1402+ (value = dict_get(dict, addr+7)) != 0)
1403+ CHK_ADDR_RETURN(check_table_result(state, table, value, address,
1404+ reply_name, reply_class,
1405+ def_acl), FOUND);
1406+ } else
1407+#endif
1408 if ((value = dict_get(dict, addr)) != 0)
1409 CHK_ADDR_RETURN(check_table_result(state, table, value, address,
1410 reply_name, reply_class,
1ce4542c 1411@@ -2431,16 +2492,32 @@
c6bc5048
TO
1412 VSTRING *query;
1413 int i;
1414 SMTPD_RBL_STATE *rbl;
1415+#ifdef INET6
1416+ struct in_addr a;
1417+#else
1418+ struct in6_addr a;
1419+#endif
1420
23bbf6c1 1421 if (msg_verbose)
7e195e4d 1422 msg_info("%s: %s %s", myname, reply_class, addr);
e38d57a7 1423
da71bd09
JB
1424- /*
1425- * IPv4 only for now
1426- */
1427-#ifdef INET6
1428+#ifndef INET6
23bbf6c1 1429+ /* IPv4 only for now */
7e195e4d 1430 if (inet_pton(AF_INET, addr, &a) != 1)
da71bd09
JB
1431 return SMTPD_CHECK_DUNNO;
1432+ octets = argv_split(state->addr, ".");
1433+#else
1434+ /* IPv4 and IPv6-mapped IPv4 only for now */
1435+ if (inet_pton(AF_INET, state->addr, &a) == 1)
7e195e4d 1436+ octets = argv_split(state->addr, ".");
da71bd09 1437+ else {
7e195e4d
TO
1438+ struct in6_addr a6;
1439+ if (inet_pton(AF_INET6, state->addr, &a6) != 1)
da71bd09 1440+ return SMTPD_CHECK_DUNNO;
7e195e4d 1441+ if (!IN6_IS_ADDR_V4MAPPED(&a6) || (strrchr(state->addr,':') == NULL))
da71bd09 1442+ return SMTPD_CHECK_DUNNO;
7e195e4d 1443+ octets = argv_split(strrchr(state->addr,':')+1, ".");
da71bd09
JB
1444+ }
1445 #endif
1446
23bbf6c1 1447 /*
1ce4542c
TO
1448diff -Nur postfix-2.0.9.orig/src/smtpd/smtpd_peer.c postfix-2.0.9/src/smtpd/smtpd_peer.c
1449--- postfix-2.0.9.orig/src/smtpd/smtpd_peer.c Thu Aug 22 19:50:51 2002
1450+++ postfix-2.0.9/src/smtpd/smtpd_peer.c Fri Apr 18 20:55:35 2003
23bbf6c1
JB
1451@@ -63,6 +63,15 @@
1452 #include <netdb.h>
1453 #include <string.h>
1454
1455+/* Utility library. */
1456+
1457+#include <msg.h>
1458+#include <mymalloc.h>
1459+#include <valid_hostname.h>
1460+#include <stringops.h>
1461+
1462+/* Global library. */
1463+
1464 /*
1465 * Older systems don't have h_errno. Even modern systems don't have
1466 * hstrerror().
1467@@ -84,16 +93,11 @@
1468 )
1469 #endif
1470
1471-/* Utility library. */
1472-
1473-#include <msg.h>
1474-#include <mymalloc.h>
1475-#include <valid_hostname.h>
1476-#include <stringops.h>
1477-
1478-/* Global library. */
1479-
1480-
1481+#ifdef INET6
1482+#define GAI_STRERROR(error) \
1483+ ((error = EAI_SYSTEM) ? gai_strerror(error) : strerror(errno))
1484+#endif
1485+
1486 /* Application-specific. */
1487
1488 #include "smtpd.h"
c6bc5048 1489@@ -102,21 +106,28 @@
23bbf6c1
JB
1490
1491 void smtpd_peer_init(SMTPD_STATE *state)
1492 {
1493- struct sockaddr_in sin;
1494- SOCKADDR_SIZE len = sizeof(sin);
1495+#ifdef INET6
1496+ struct sockaddr_storage ss;
1497+#else
1498+ struct sockaddr ss;
1499+ struct in_addr *in;
1500 struct hostent *hp;
1501- int i;
1502+#endif
1503+ struct sockaddr *sa;
1504+ SOCKADDR_SIZE len;
1505+
1506+ sa = (struct sockaddr *)&ss;
1507+ len = sizeof(ss);
1508
7e195e4d
TO
1509 /*
1510 * Avoid suprious complaints from Purify on Solaris.
c6bc5048
TO
1511 */
1512- memset((char *) &sin, 0, len);
b733fb75 1513+ memset((char *) sa, 0, len);
c6bc5048 1514
23bbf6c1
JB
1515 /*
1516 * Look up the peer address information.
1517 */
1518- if (getpeername(vstream_fileno(state->client),
1519- (struct sockaddr *) & sin, &len) >= 0) {
1520+ if (getpeername(vstream_fileno(state->client), sa, &len) >= 0) {
1521 errno = 0;
1522 }
1523
7e195e4d 1524@@ -132,23 +143,56 @@
23bbf6c1
JB
1525 /*
1526 * Look up and "verify" the client hostname.
1527 */
1528- else if (errno == 0 && sin.sin_family == AF_INET) {
1529- state->addr = mystrdup(inet_ntoa(sin.sin_addr));
1530- hp = gethostbyaddr((char *) &(sin.sin_addr),
1531- sizeof(sin.sin_addr), AF_INET);
1532- if (hp == 0) {
1533+ else if (errno == 0 && (sa->sa_family == AF_INET
1534+#ifdef INET6
1535+ || sa->sa_family == AF_INET6
1536+#endif
1537+ )) {
1538+#ifdef INET6
1539+ char hbuf[NI_MAXHOST];
1540+ char abuf[NI_MAXHOST];
1541+ struct addrinfo hints, *rnull = NULL;
1542+#else
1543+ char abuf[sizeof("255.255.255.255") + 1];
1544+ char *hbuf;
1545+#endif
1546+ int error = -1;
1547+
1548+#ifdef INET6
1549+ (void)getnameinfo(sa, len, abuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
1550+#else
1551+ in = &((struct sockaddr_in *)sa)->sin_addr;
1552+ inet_ntop(AF_INET, in, abuf, sizeof(hbuf));
1553+#endif
1554+ state->addr = mystrdup(abuf);
1555+#ifdef INET6
1556+ error = getnameinfo(sa, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD);
1557+#else
1558+ hbuf = NULL;
1559+ hp = gethostbyaddr((char *)in, sizeof(*in), AF_INET);
1560+ if (hp) {
1561+ error = 0;
1562+ hbuf = mystrdup(hp->h_name);
1563+ } else
1564+ error = 1;
1565+#endif
1566+ if (error) {
1567 state->name = mystrdup("unknown");
1568+#ifdef INET6
1569+ state->peer_code = (error == EAI_AGAIN ? 4 : 5);
1570+#else
1571 state->peer_code = (h_errno == TRY_AGAIN ? 4 : 5);
7e195e4d 1572- } else if (valid_hostaddr(hp->h_name, DONT_GRIPE)) {
23bbf6c1 1573+#endif
7e195e4d
TO
1574+ } else if (valid_hostaddr(hbuf, DONT_GRIPE)) {
1575 msg_warn("numeric result %s in address->name lookup for %s",
1576- hp->h_name, state->addr);
c6bc5048 1577+ hbuf, state->addr);
7e195e4d
TO
1578 state->name = mystrdup("unknown");
1579 state->peer_code = 5;
1580- } else if (!valid_hostname(hp->h_name, DONT_GRIPE)) {
23bbf6c1
JB
1581+ } else if (!valid_hostname(hbuf, DONT_GRIPE)) {
1582 state->name = mystrdup("unknown");
1583 state->peer_code = 5;
1584 } else {
1585- state->name = mystrdup(hp->h_name); /* hp->name is clobbered!! */
c6bc5048 1586+ state->name = mystrdup(hbuf); /* hp->name is clobbered!! */
23bbf6c1
JB
1587 state->peer_code = 2;
1588
1589 /*
1ce4542c 1590@@ -160,16 +204,31 @@
23bbf6c1
JB
1591 state->peer_code = code; \
1592 }
1593
1594+#ifdef INET6
1595+ memset(&hints, 0, sizeof(hints));
1596+ hints.ai_family = AF_UNSPEC;
1597+ hints.ai_socktype = SOCK_STREAM;
1598+ error = getaddrinfo(state->name, NULL, &hints, &rnull);
1599+ if (error) {
1600+ msg_warn("%s: hostname %s verification failed: %s",
1601+ state->addr, state->name, GAI_STRERROR(error));
1602+ REJECT_PEER_NAME(state, (error == EAI_AGAIN ? 4 : 5));
1603+ }
1604+ /* memcmp() isn't needed if we use getaddrinfo */
1605+ if (rnull)
1606+ freeaddrinfo(rnull);
1607+#else
1608 hp = gethostbyname(state->name); /* clobbers hp->name!! */
1609 if (hp == 0) {
1610 msg_warn("%s: hostname %s verification failed: %s",
1611 state->addr, state->name, HSTRERROR(h_errno));
1612 REJECT_PEER_NAME(state, (h_errno == TRY_AGAIN ? 4 : 5));
1613- } else if (hp->h_length != sizeof(sin.sin_addr)) {
1614+ } else if (hp->h_length != sizeof(*in)) {
1615 msg_warn("%s: hostname %s verification failed: bad address size %d",
1616 state->addr, state->name, hp->h_length);
1617 REJECT_PEER_NAME(state, 5);
1618 } else {
1619+ int i;
1620 for (i = 0; /* void */ ; i++) {
1621 if (hp->h_addr_list[i] == 0) {
1622 msg_warn("%s: address not listed for hostname %s",
1ce4542c 1623@@ -177,12 +236,11 @@
23bbf6c1
JB
1624 REJECT_PEER_NAME(state, 5);
1625 break;
1626 }
1627- if (memcmp(hp->h_addr_list[i],
1628- (char *) &sin.sin_addr,
1629- sizeof(sin.sin_addr)) == 0)
1630+ if (memcmp(hp->h_addr_list[i], (char *)in, sizeof(*in)) == 0)
1631 break; /* keep peer name */
1632 }
1633 }
1634+#endif
1635 }
1636 }
1637
1ce4542c
TO
1638diff -Nur postfix-2.0.9.orig/src/smtpstone/smtp-sink.c postfix-2.0.9/src/smtpstone/smtp-sink.c
1639--- postfix-2.0.9.orig/src/smtpstone/smtp-sink.c Fri Aug 16 17:05:25 2002
1640+++ postfix-2.0.9/src/smtpstone/smtp-sink.c Fri Apr 18 20:55:35 2003
1641@@ -606,7 +606,7 @@
e38d57a7
JB
1642 } else {
1643 if (strncmp(argv[optind], "inet:", 5) == 0)
1644 argv[optind] += 5;
1645- sock = inet_listen(argv[optind], backlog, BLOCKING);
1646+ sock = inet_listen(argv[optind], backlog, BLOCKING, 1);
1647 }
1648
23bbf6c1 1649 /*
1ce4542c
TO
1650diff -Nur postfix-2.0.9.orig/src/util/Makefile.in postfix-2.0.9/src/util/Makefile.in
1651--- postfix-2.0.9.orig/src/util/Makefile.in Fri Apr 18 20:55:10 2003
1652+++ postfix-2.0.9/src/util/Makefile.in Fri Apr 18 20:55:35 2003
830ba608 1653@@ -8,7 +8,7 @@
1654 dict_tcp.c dict_unix.c dir_forest.c doze.c duplex_pipe.c \
1655 environ.c events.c exec_command.c fifo_listen.c fifo_trigger.c \
1656 file_limit.c find_inet.c fsspace.c fullname.c get_domainname.c \
1657- get_hostname.c hex_quote.c htable.c inet_addr_host.c \
1658+ get_hostname.c get_port.c hex_quote.c htable.c inet_addr_host.c \
1659 inet_addr_list.c inet_addr_local.c inet_connect.c inet_listen.c \
1660 inet_trigger.c inet_util.c intv.c line_wrap.c lowercase.c \
1661 lstat_as.c mac_expand.c mac_parse.c make_dirs.c match_list.c \
1662@@ -36,7 +36,7 @@
1663 dict_tcp.o dict_unix.o dir_forest.o doze.o duplex_pipe.o \
1664 environ.o events.o exec_command.o fifo_listen.o fifo_trigger.o \
1665 file_limit.o find_inet.o fsspace.o fullname.o get_domainname.o \
1666- get_hostname.o hex_quote.o htable.o inet_addr_host.o \
1667+ get_hostname.o get_port.o hex_quote.o htable.o inet_addr_host.o \
1668 inet_addr_list.o inet_addr_local.o inet_connect.o inet_listen.o \
1669 inet_trigger.o inet_util.o intv.o line_wrap.o lowercase.o \
1670 lstat_as.o mac_expand.o mac_parse.o make_dirs.o match_list.o \
1671@@ -60,7 +60,7 @@
1672 dict_ht.h dict_ldap.h dict_mysql.h dict_ni.h dict_nis.h \
1ce4542c 1673 dict_nisplus.h dict_pcre.h dict_pgsql.h dict_regexp.h dict_static.h dict_tcp.h \
830ba608 1674 dict_unix.h dir_forest.h events.h exec_command.h find_inet.h \
1675- fsspace.h fullname.h get_domainname.h get_hostname.h hex_quote.h \
1676+ fsspace.h fullname.h get_domainname.h get_hostname.h get_port.h hex_quote.h \
1677 htable.h inet_addr_host.h inet_addr_list.h inet_addr_local.h \
1678 inet_util.h intv.h iostuff.h line_wrap.h listen.h lstat_as.h \
1679 mac_expand.h mac_parse.h make_dirs.h match_list.h match_ops.h \
1ce4542c 1680@@ -780,6 +780,7 @@
23bbf6c1
JB
1681 get_domainname.o: mymalloc.h
1682 get_domainname.o: get_hostname.h
1683 get_domainname.o: get_domainname.h
1684+get_port.o: sys_defs.h
1685 get_hostname.o: get_hostname.c
1686 get_hostname.o: sys_defs.h
1687 get_hostname.o: mymalloc.h
1ce4542c 1688@@ -905,6 +906,7 @@
23bbf6c1
JB
1689 match_list.o: stringops.h
1690 match_list.o: argv.h
1691 match_list.o: dict.h
1692+match_list.o: inet_util.h
447bfc58 1693 match_list.o: match_ops.h
23bbf6c1
JB
1694 match_list.o: match_list.h
1695 match_ops.o: match_ops.c
1ce4542c
TO
1696diff -Nur postfix-2.0.9.orig/src/util/get_port.c postfix-2.0.9/src/util/get_port.c
1697--- postfix-2.0.9.orig/src/util/get_port.c Thu Jan 1 01:00:00 1970
1698+++ postfix-2.0.9/src/util/get_port.c Fri Apr 18 20:55:35 2003
23bbf6c1
JB
1699@@ -0,0 +1,65 @@
1700+/*++
1701+/* NAME
1702+/* get_port 3
1703+/* SUMMARY
1704+/* trivial host and port extracter
1705+/* SYNOPSIS
1706+/* #include <get_port.h>
1707+/*
1708+/* char *get_port(data)
1709+/* char *data;
1710+/*
1711+/* DESCRIPTION
1712+/* get_port() extract host name or ip address from
1713+/* strings such as [3ffe:902:12::10]:25, [::1]
1714+/* or 192.168.0.1:25, and null-terminates the
1715+/* \fIdata\fR at the first occurrence of port separator.
1716+/* DIAGNOSTICS
1717+/* If port not found return null pointer.
1718+/* LICENSE
1719+/* .ad
1720+/* .fi
1721+/* BSD Style (or BSD like) license.
1722+/* AUTHOR(S)
1723