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