1 diff -Nur snapshot-20010525.nov6/IPV6_README snapshot-20010525/IPV6_README
2 --- snapshot-20010525.nov6/IPV6_README Thu Jan 1 01:00:00 1970
3 +++ snapshot-20010525/IPV6_README Wed Oct 17 11:38:17 2001
7 + ALPHA IPv6 patch for Postfix.
9 + You can use IPv6 addresses in configuration file but
10 +you must enclose them with [] for example: [3ffe:902:12::10].
12 +Probably not all things work properly, yet.
15 + - all previous versions of this patch (dated before 15 January
16 + 2000) was against postfix-19991231-pl02 with pfixtls patch
17 + applied (see ftp://ftp.aet.tu-cottbus.de/pub/pfixtls/ for more).
18 + All newer patches are created against clean postfix version.
21 + - getaddrinfo call in smtp_addr_one() function doesn't always
22 + return proper ai_addr structure (fixed).
23 + - lmtp code isn't IPv6 ready (not fixed).
25 +Please send all comments and patches to:
26 + Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>, PLD GNU/Linux
27 + Artur Frysiak <wiget@pld.org.pl>, PLD GNU/Linux
29 +Newest version of this patch can be found at:
30 + http://www.misiek.eu.org/ipv6/
33 +- Mark Huizer <xaa@timewasters.nl>
34 + author of first IPv6 patch for postfix
35 +- KAME Team <core@kame.net>
36 + fixes to Mark's patch
37 +diff -ruN --exclude *.orig --exclude *~ snapshot-20010329.noipv6/makedefs snapshot-20010329/makedefs
38 diff -Nur snapshot-20010525.nov6/makedefs snapshot-20010525/makedefs
39 --- snapshot-20010525.nov6/makedefs Tue May 1 01:16:07 2001
40 +++ snapshot-20010525/makedefs Wed Oct 17 11:38:17 2001
42 SYSTEM=`(uname -s) 2>/dev/null`
43 RELEASE=`(uname -r) 2>/dev/null`
44 VERSION=`(uname -v) 2>/dev/null`
45 +if test -f /usr/include/netinet6/in6.h; then
46 + grep __KAME__ /usr/include/netinet6/in6.h 2>&1 >/dev/null
50 + if [ -f /usr/local/v6/lib/libinet6.a ]; then
57 +if [ -z "$INET6" -a -f /usr/include/netinet/ip6.h -a -f /usr/include/linux/icmpv6.h ]; then
62 dcosx*) SYSTEM=$VERSION;;
65 : ${CC='gcc $(WARN)'} ${OPT='-O'} ${DEBUG='-g'} ${AWK=awk}
69 + CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len"
70 + if test -f /usr/local/v6/lib/libinet6.a; then
71 + SYSLIBS="$SYSLIBS -L/usr/local/v6/lib -linet6"
75 + CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len"
78 + CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family"
79 + if test -f /usr/include/libinet6/netinet/ip6.h -a \
80 + -f /usr/lib/libinet6.a; then
81 + CCARGS="$CCARGS -I/usr/include/libinet6 -DUSAGI_LIBINET6"
82 + SYSLIBS="$SYSLIBS -linet6"
87 export SYSTYPE AR ARFL RANLIB SYSLIBS CC OPT DEBUG AWK OPTS
90 diff -Nur snapshot-20010525.nov6/src/dns/dns_lookup.c snapshot-20010525/src/dns/dns_lookup.c
91 --- snapshot-20010525.nov6/src/dns/dns_lookup.c Sun Feb 4 19:16:20 2001
92 +++ snapshot-20010525/src/dns/dns_lookup.c Wed Oct 17 11:38:17 2001
96 #define INET_ADDR_LEN 4 /* XXX */
98 +#define INET6_ADDR_LEN 16
101 /* dns_query - query name server and pre-parse the reply */
104 memcpy(temp, pos, fixed->length);
105 data_len = fixed->length;
109 + if (fixed->length != INET6_ADDR_LEN) {
110 + msg_warn("extract_answer: bad IPv6 address length: %d", fixed->length);
113 + if (fixed->length > sizeof(temp))
114 + msg_panic("dns_get_rr: length %d > DNS_NAME_LEN",
116 + memcpy(temp, pos, fixed->length);
117 + data_len = fixed->length;
121 data_len = MIN2(pos[0] + 1, MIN2(fixed->length + 1, sizeof(temp)));
122 for (src = pos + 1, dst = (unsigned char *) (temp);
123 diff -Nur snapshot-20010525.nov6/src/global/Makefile.in snapshot-20010525/src/global/Makefile.in
124 --- snapshot-20010525.nov6/src/global/Makefile.in Tue Oct 16 13:15:43 2001
125 +++ snapshot-20010525/src/global/Makefile.in Wed Oct 17 11:38:17 2001
127 timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \
128 tok822_resolve.c tok822_rewrite.c tok822_tree.c xtext.c bounce_log.c \
129 flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c \
131 + pfixtls.c wildcard_inet_addr.c
132 OBJS = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
133 debug_peer.o debug_process.o defer.o deliver_completed.o \
134 deliver_flock.o deliver_pass.o deliver_request.o domain_list.o \
136 timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \
137 tok822_resolve.o tok822_rewrite.o tok822_tree.o xtext.o bounce_log.o \
138 flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o \
140 + pfixtls.o wildcard_inet_addr.o
141 HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
142 config.h debug_peer.h debug_process.h defer.h deliver_completed.h \
143 deliver_flock.h deliver_pass.h deliver_request.h domain_list.h \
145 recipient_list.h record.h resolve_clnt.h resolve_local.h \
146 rewrite_clnt.h sent.h smtp_stream.h split_addr.h string_list.h \
147 sys_exits.h timed_ipc.h tok822.h xtext.h bounce_log.h flush_clnt.h \
148 - mbox_conf.h mbox_open.h abounce.h pfixtls.h
149 + mbox_conf.h mbox_open.h abounce.h pfixtls.h wildcard_inet_addr.h
150 TESTSRC = rec2stream.c stream2rec.c recdump.c
151 WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
152 -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
153 diff -Nur snapshot-20010525.nov6/src/global/mynetworks.c snapshot-20010525/src/global/mynetworks.c
154 --- snapshot-20010525.nov6/src/global/mynetworks.c Sun Feb 25 02:46:07 2001
155 +++ snapshot-20010525/src/global/mynetworks.c Wed Oct 17 11:38:17 2001
158 #include <inet_addr_list.h>
159 #include <name_mask.h>
161 +#include <sys/socket.h>
162 +#include <netinet/in.h>
166 /* Global library. */
169 const char *mynetworks(void)
171 static VSTRING *result;
173 + char hbuf[NI_MAXHOST];
177 char *myname = "mynetworks";
183 + struct sockaddr *sa;
186 mask_style = name_mask("mynetworks mask style", mask_styles,
187 var_mynetworks_style);
189 my_mask_list = own_inet_mask_list();
191 for (i = 0; i < my_addr_list->used; i++) {
193 + sa = (struct sockaddr *)&my_addr_list->addrs[i];
194 + if (sa->sa_family != AF_INET) {
195 + vstring_sprintf_append(result, "XAATODOmynetworks ");
198 + addr = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr);
199 + mask = ntohl(((struct sockaddr_in *)&my_mask_list->addrs[i])->sin_addr.s_addr);
201 addr = ntohl(my_addr_list->addrs[i].s_addr);
202 mask = ntohl(my_mask_list->addrs[i].s_addr);
205 switch (mask_style) {
208 mask = IN_CLASSD_NET;
209 shift = IN_CLASSD_NSHIFT;
212 + if (getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
214 + strncpy(hbuf, "???", sizeof(hbuf));
215 + msg_fatal("%s: bad address class: %s", myname, hbuf);
217 msg_fatal("%s: bad address class: %s",
218 myname, inet_ntoa(my_addr_list->addrs[i]));
223 diff -Nur snapshot-20010525.nov6/src/global/own_inet_addr.c snapshot-20010525/src/global/own_inet_addr.c
224 --- snapshot-20010525.nov6/src/global/own_inet_addr.c Sun Feb 25 02:51:39 2001
225 +++ snapshot-20010525/src/global/own_inet_addr.c Wed Oct 17 11:38:17 2001
227 #include <netinet/in.h>
228 #include <arpa/inet.h>
231 +#include <sys/socket.h>
235 #ifdef STRCASECMP_IN_STRINGS_H
237 @@ -101,10 +105,11 @@
240 bufp = hosts = mystrdup(var_inet_interfaces);
241 - while ((host = mystrtok(&bufp, sep)) != 0)
242 + while ((host = mystrtok(&bufp, sep)) != 0) {
243 if (inet_addr_host(addr_list, host) == 0)
244 msg_fatal("config variable %s: host not found: %s",
245 VAR_INET_INTERFACES, host);
249 inet_addr_list_init(&local_addrs);
250 @@ -113,15 +118,39 @@
251 msg_fatal("could not find any active network interfaces");
252 for (nvirtual = 0; nvirtual < addr_list->used; nvirtual++) {
253 for (nlocal = 0; /* see below */ ; nlocal++) {
254 - if (nlocal >= local_addrs.used)
255 + if (nlocal >= local_addrs.used) {
257 + char hbuf[NI_MAXHOST];
258 + if (getnameinfo((struct sockaddr *)&addr_list->addrs[nvirtual],
259 + SS_LEN(addr_list->addrs[nvirtual]), hbuf,
260 + sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
261 + strncpy(hbuf, "???", sizeof(hbuf));
262 + msg_fatal("parameter %s: no local interface found for %s",
263 + VAR_INET_INTERFACES, hbuf);
265 msg_fatal("parameter %s: no local interface found for %s",
267 inet_ntoa(addr_list->addrs[nvirtual]));
271 + if (addr_list->addrs[nvirtual].ss_family ==
272 + local_addrs.addrs[nlocal].ss_family &&
273 + SS_LEN(addr_list->addrs[nvirtual]) ==
274 + SS_LEN(local_addrs.addrs[nlocal]) &&
275 + memcmp(&addr_list->addrs[nvirtual],
276 + &local_addrs.addrs[nlocal],
277 + SS_LEN(local_addrs.addrs[nlocal])) == 0) {
278 + inet_addr_list_append(mask_list, (struct sockaddr *)&local_masks.addrs[nlocal]);
282 if (addr_list->addrs[nvirtual].s_addr
283 == local_addrs.addrs[nlocal].s_addr) {
284 inet_addr_list_append(mask_list, &local_masks.addrs[nlocal]);
290 inet_addr_list_free(&local_addrs);
293 /* own_inet_addr - is this my own internet address */
296 +int own_inet_addr(struct sockaddr * addr)
301 + struct sockaddr *sa;
303 + if (addr_list.used == 0)
304 + own_inet_addr_init(&addr_list, &mask_list);
306 + for (i = 0; i < addr_list.used; i++) {
307 + sa = (struct sockaddr *)&addr_list.addrs[i];
308 + if (addr->sa_family != sa->sa_family)
310 + switch (addr->sa_family) {
312 + p = (char *)&((struct sockaddr_in *)addr)->sin_addr;
313 + q = (char *)&((struct sockaddr_in *)&addr_list.addrs[i])->sin_addr;
314 + l = sizeof(struct in_addr);
318 + p = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr;
319 + q = (char *)&((struct sockaddr_in6 *)&addr_list.addrs[i])->sin6_addr;
320 + l = sizeof(struct in6_addr);
325 + if (memcmp(p, q, l) == 0)
331 int own_inet_addr(struct in_addr * addr)
335 for (i = 0; i < addr_list.used; i++)
336 if (addr->s_addr == addr_list.addrs[i].s_addr)
342 /* own_inet_addr_list - return list of addresses */
344 diff -Nur snapshot-20010525.nov6/src/global/own_inet_addr.h snapshot-20010525/src/global/own_inet_addr.h
345 --- snapshot-20010525.nov6/src/global/own_inet_addr.h Sat Feb 24 02:25:32 2001
346 +++ snapshot-20010525/src/global/own_inet_addr.h Wed Oct 17 11:38:17 2001
350 #include <netinet/in.h>
352 +#include <sys/socket.h>
356 * External interface.
359 +extern int own_inet_addr(struct sockaddr *);
361 extern int own_inet_addr(struct in_addr *);
363 extern struct INET_ADDR_LIST *own_inet_addr_list(void);
364 extern struct INET_ADDR_LIST *own_inet_mask_list(void);
366 diff -Nur snapshot-20010525.nov6/src/global/peer_name.c snapshot-20010525/src/global/peer_name.c
367 --- snapshot-20010525.nov6/src/global/peer_name.c Sun Jan 28 16:23:02 2001
368 +++ snapshot-20010525/src/global/peer_name.c Wed Oct 17 11:38:17 2001
370 PEER_NAME *peer_name(int sock)
372 static PEER_NAME peer;
373 - struct sockaddr_in sin;
374 - SOCKADDR_SIZE len = sizeof(sin);
381 + struct sockaddr peer_un;
382 + struct sockaddr_in peer_un4;
384 + struct sockaddr_in6 peer_un6;
387 +#define sun p_un.peer_un
388 +#define sin p_un.peer_un4
390 +#define sin6 p_un.peer_un6
391 + static char hbuf[NI_MAXHOST];
392 + static char abuf[NI_MAXHOST];
396 + SOCKADDR_SIZE len = sizeof(p_un);
398 - if (getpeername(sock, (struct sockaddr *) & sin, &len) == 0) {
399 - switch (sin.sin_family) {
400 + if (getpeername(sock, (struct sockaddr *)&p_un, &len) == 0) {
401 + switch (p_un.peer_un.sa_family) {
404 peer.type = PEER_TYPE_INET;
405 hp = gethostbyaddr((char *) &(sin.sin_addr),
407 hp->h_name : "unknown");
408 peer.addr = inet_ntoa(sin.sin_addr);
412 + peer.type = PEER_TYPE_INET;
413 + if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
414 + peer.name = "unknown";
420 + peer.type = PEER_TYPE_INET6;
421 + if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
422 + peer.name = "unknown";
430 peer.type = PEER_TYPE_LOCAL;
431 diff -Nur snapshot-20010525.nov6/src/global/peer_name.h snapshot-20010525/src/global/peer_name.h
432 --- snapshot-20010525.nov6/src/global/peer_name.h Fri Dec 11 19:55:32 1998
433 +++ snapshot-20010525/src/global/peer_name.h Wed Oct 17 11:38:17 2001
435 #define PEER_TYPE_UNKNOWN 0
436 #define PEER_TYPE_INET 1
437 #define PEER_TYPE_LOCAL 2
439 +#define PEER_TYPE_INET6 3
442 extern PEER_NAME *peer_name(int);
444 diff -Nur snapshot-20010525.nov6/src/global/resolve_local.c snapshot-20010525/src/global/resolve_local.c
445 --- snapshot-20010525.nov6/src/global/resolve_local.c Mon Apr 26 00:05:42 1999
446 +++ snapshot-20010525/src/global/resolve_local.c Wed Oct 17 11:38:17 2001
448 #include <netinet/in.h>
449 #include <arpa/inet.h>
454 #define INADDR_NONE 0xffffffff
457 char *saved_addr = mystrdup(addr);
460 + struct addrinfo hints, *res, *res0;
463 struct in_addr ipaddr;
467 #define RETURN(x) { myfree(saved_addr); return(x); }
469 if (*dest == '[' && dest[len - 1] == ']') {
473 + memset(&hints, 0, sizeof(hints));
474 + hints.ai_family = PF_UNSPEC;
475 + hints.ai_socktype = SOCK_DGRAM;
476 + error = getaddrinfo(dest, NULL, &hints, &res0);
478 + for (res = res0; res; res = res->ai_next) {
479 + if (own_inet_addr(res->ai_addr)) {
480 + freeaddrinfo(res0);
484 + freeaddrinfo(res0);
487 if ((ipaddr.s_addr = inet_addr(dest)) != INADDR_NONE
488 && own_inet_addr(&ipaddr))
494 diff -Nur snapshot-20010525.nov6/src/global/wildcard_inet_addr.c snapshot-20010525/src/global/wildcard_inet_addr.c
495 --- snapshot-20010525.nov6/src/global/wildcard_inet_addr.c Thu Jan 1 01:00:00 1970
496 +++ snapshot-20010525/src/global/wildcard_inet_addr.c Wed Oct 17 11:38:17 2001
498 +/* System library. */
500 +#include <sys_defs.h>
501 +#include <netinet/in.h>
502 +#include <arpa/inet.h>
505 +#include <sys/socket.h>
509 +#ifdef STRCASECMP_IN_STRINGS_H
510 +#include <strings.h>
513 +/* Utility library. */
516 +#include <mymalloc.h>
517 +#include <inet_addr_list.h>
518 +#include <inet_addr_local.h>
519 +#include <inet_addr_host.h>
520 +#include <stringops.h>
522 +/* Global library. */
524 +#include <mail_params.h>
525 +#include <wildcard_inet_addr.h>
527 +/* Application-specific. */
528 +static INET_ADDR_LIST addr_list;
530 +/* wildcard_inet_addr_init - initialize my own address list */
532 +static void wildcard_inet_addr_init(INET_ADDR_LIST *addr_list)
535 + struct addrinfo hints, *res, *res0;
536 + char hbuf[NI_MAXHOST];
538 +#ifdef NI_WITHSCOPEID
539 + const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
541 + const int niflags = NI_NUMERICHOST;
544 + inet_addr_list_init(addr_list);
546 + memset(&hints, 0, sizeof(hints));
547 + hints.ai_family = PF_UNSPEC;
548 + hints.ai_socktype = SOCK_STREAM;
549 + hints.ai_flags = AI_PASSIVE;
550 + error = getaddrinfo(NULL, "0", &hints, &res0);
552 + msg_fatal("could not get list of wildcard addresses");
553 + for (res = res0; res; res = res->ai_next) {
554 + if (res->ai_family != AF_INET && res->ai_family != AF_INET6)
556 + if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
557 + NULL, 0, niflags) != 0)
559 + if (inet_addr_host(addr_list, hbuf) == 0)
560 + continue; /* msg_fatal("config variable %s: host not found: %s",
561 + VAR_INET_INTERFACES, hbuf); */
563 + freeaddrinfo(res0);
565 + if (inet_addr_host(addr_list, "0.0.0.0") == 0)
566 + msg_fatal("config variable %s: host not found: %s",
567 + VAR_INET_INTERFACES, "0.0.0.0");
571 +/* wildcard_inet_addr_list - return list of addresses */
573 +INET_ADDR_LIST *wildcard_inet_addr_list(void)
575 + if (addr_list.used == 0)
576 + wildcard_inet_addr_init(&addr_list);
578 + return (&addr_list);
580 diff -Nur snapshot-20010525.nov6/src/global/wildcard_inet_addr.h snapshot-20010525/src/global/wildcard_inet_addr.h
581 --- snapshot-20010525.nov6/src/global/wildcard_inet_addr.h Thu Jan 1 01:00:00 1970
582 +++ snapshot-20010525/src/global/wildcard_inet_addr.h Wed Oct 17 11:38:17 2001
584 +#ifndef _WILDCARD_INET_ADDR_H_INCLUDED_
585 +#define _WILDCARD_INET_ADDR_H_INCLUDED_
589 +/* wildcard_inet_addr_list 3h
591 +/* grab the list of wildcard IP addresses.
593 +/* #include <own_inet_addr.h>
601 +#include <netinet/in.h>
603 +#include <sys/socket.h>
607 + * External interface.
609 +extern struct INET_ADDR_LIST *wildcard_inet_addr_list(void);
616 +/* Jun-ichiro itojun Hagino
620 diff -Nur snapshot-20010525.nov6/src/master/master_ent.c snapshot-20010525/src/master/master_ent.c
621 --- snapshot-20010525.nov6/src/master/master_ent.c Tue May 1 00:45:54 2001
622 +++ snapshot-20010525/src/master/master_ent.c Wed Oct 17 11:38:17 2001
624 inet_addr_host(MASTER_INET_ADDRLIST(serv), host);
625 serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
626 } else if (strcasecmp(var_inet_interfaces, DEF_INET_INTERFACES) == 0) {
628 + MASTER_INET_ADDRLIST(serv) = wildcard_inet_addr_list();
629 + serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
631 MASTER_INET_ADDRLIST(serv) = 0; /* wild-card */
632 serv->listen_fd_count = 1;
635 MASTER_INET_ADDRLIST(serv) = own_inet_addr_list(); /* virtual */
636 serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
637 diff -Nur snapshot-20010525.nov6/src/master/master_listen.c snapshot-20010525/src/master/master_listen.c
638 --- snapshot-20010525.nov6/src/master/master_listen.c Tue May 1 00:47:57 2001
639 +++ snapshot-20010525/src/master/master_listen.c Wed Oct 17 11:43:52 2001
649 /* master_listen_init - enable connection requests */
651 void master_listen_init(MASTER_SERV *serv)
653 char *myname = "master_listen_init";
658 + char hbuf[NI_MAXHOST];
659 + SOCKADDR_SIZE salen;
663 * Find out what transport we should use, then create one or more
664 @@ -111,18 +120,31 @@
666 inet_listen(MASTER_INET_PORT(serv),
667 serv->max_proc > var_proc_limit ?
668 - serv->max_proc : var_proc_limit, NON_BLOCKING);
669 + serv->max_proc : var_proc_limit, NON_BLOCKING, 1);
670 close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
671 } else { /* virtual or host:port */
672 - for (n = 0; n < serv->listen_fd_count; n++) {
673 + for (m = n = 0; n < serv->listen_fd_count; n++) {
675 + if (getnameinfo((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n],
676 + SA_LEN((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n]),
677 + hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) {
678 + strncpy(hbuf, "?????", sizeof(hbuf));
680 + end_point = concatenate(hbuf, ":", MASTER_INET_PORT(serv), (char *) 0);
682 end_point = concatenate(inet_ntoa(MASTER_INET_ADDRLIST(serv)->addrs[n]),
683 ":", MASTER_INET_PORT(serv), (char *) 0);
687 = inet_listen(end_point, serv->max_proc > var_proc_limit ?
688 - serv->max_proc : var_proc_limit, NON_BLOCKING);
689 - close_on_exec(serv->listen_fd[n], CLOSE_ON_EXEC);
690 + serv->max_proc : var_proc_limit, NON_BLOCKING, 0);
692 + serv->listen_fd[m] = tmpfd;
693 + close_on_exec(serv->listen_fd[m++], CLOSE_ON_EXEC);
697 + serv->listen_fd_count=m;
701 diff -Nur snapshot-20010525.nov6/src/qmgr/qmgr_message.c snapshot-20010525/src/qmgr/qmgr_message.c
702 --- snapshot-20010525.nov6/src/qmgr/qmgr_message.c Tue Feb 27 00:49:31 2001
703 +++ snapshot-20010525/src/qmgr/qmgr_message.c Wed Oct 17 11:38:17 2001
705 * every front-ent program.
707 if ((at = strrchr(recipient->address, '@')) != 0
709 + && (at + 1)[strspn(at + 1, "[]0123456789.:abcdef")] != 0
711 && (at + 1)[strspn(at + 1, "[]0123456789.")] != 0
713 && valid_hostname(at + 1, DONT_GRIPE) == 0) {
714 qmgr_bounce_recipient(message, recipient,
715 "bad host/domain syntax: \"%s\"", at + 1);
716 diff -Nur snapshot-20010525.nov6/src/smtp/Makefile.in snapshot-20010525/src/smtp/Makefile.in
717 --- snapshot-20010525.nov6/src/smtp/Makefile.in Tue Oct 16 13:15:43 2001
718 +++ snapshot-20010525/src/smtp/Makefile.in Wed Oct 17 11:38:17 2001
720 smtp_connect.o: ../../include/mail_params.h
721 smtp_connect.o: ../../include/own_inet_addr.h
722 smtp_connect.o: ../../include/dns.h
723 +smtp_connect.o: ../../include/get_port.h
724 smtp_connect.o: smtp.h
725 smtp_connect.o: ../../include/argv.h
726 smtp_connect.o: ../../include/deliver_request.h
727 diff -Nur snapshot-20010525.nov6/src/smtp/smtp_addr.c snapshot-20010525/src/smtp/smtp_addr.c
728 --- snapshot-20010525.nov6/src/smtp/smtp_addr.c Sat May 5 14:55:36 2001
729 +++ snapshot-20010525/src/smtp/smtp_addr.c Wed Oct 17 11:38:17 2001
730 @@ -112,18 +112,68 @@
731 static void smtp_print_addr(char *what, DNS_RR *addr_list)
734 - struct in_addr in_addr;
736 + struct sockaddr_storage ss;
738 + struct sockaddr ss;
740 + struct sockaddr_in *sin;
742 + struct sockaddr_in6 *sin6;
743 + char hbuf[NI_MAXHOST];
745 + char hbuf[sizeof("255.255.255.255") + 1];
748 msg_info("begin %s address list", what);
749 for (addr = addr_list; addr; addr = addr->next) {
750 - if (addr->data_len > sizeof(addr)) {
751 - msg_warn("skipping address length %d", addr->data_len);
753 - memcpy((char *) &in_addr, addr->data, sizeof(in_addr));
754 - msg_info("pref %4d host %s/%s",
755 - addr->pref, addr->name,
756 - inet_ntoa(in_addr));
757 + if (addr->class != C_IN) {
758 + msg_warn("skipping unsupported address (class=%u)", addr->class);
761 + switch (addr->type) {
763 + if (addr->data_len != sizeof(sin->sin_addr)) {
764 + msg_warn("skipping invalid address (AAAA, len=%u)",
768 + sin = (struct sockaddr_in *)&ss;
769 + memset(sin, 0, sizeof(*sin));
770 + sin->sin_family = AF_INET;
772 + sin->sin_len = sizeof(*sin);
774 + memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr));
778 + if (addr->data_len != sizeof(sin6->sin6_addr)) {
779 + msg_warn("skipping invalid address (AAAA, len=%u)",
783 + sin6 = (struct sockaddr_in6 *)&ss;
784 + memset(sin6, 0, sizeof(*sin6));
785 + sin6->sin6_family = AF_INET6;
787 + sin6->sin6_len = sizeof(*sin6);
789 + memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr));
793 + msg_warn("skipping unsupported address (type=%u)", addr->type);
798 + (void)getnameinfo((struct sockaddr *)&ss, SS_LEN(ss),
799 + hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
801 + (void)inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf));
803 + msg_info("pref %4d host %s/%s", addr->pref, addr->name, hbuf);
805 msg_info("end %s address list", what);
807 @@ -133,15 +183,23 @@
808 static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRING *why)
810 char *myname = "smtp_addr_one";
812 struct in_addr inaddr;
818 + struct addrinfo hints, *res0, *res;
826 msg_info("%s: host %s", myname, host);
830 * Interpret a numerical name as an address.
833 smtp_errno = SMTP_FAIL;
837 + memset(&hints, 0, sizeof(hints));
838 + hints.ai_family = PF_UNSPEC;
839 + hints.ai_socktype = SOCK_STREAM;
840 + error = getaddrinfo(host, NULL, &hints, &res0);
844 + smtp_errno = SMTP_RETRY;
847 + vstring_sprintf(why, "[%s]: %s",host,gai_strerror(error));
848 + smtp_errno = SMTP_FAIL;
851 + return (addr_list);
853 + for (res = res0; res; res = res->ai_next) {
854 + memset((char *) &fixed, 0, sizeof(fixed));
855 + switch(res->ai_family) {
857 + /* XXX not scope friendly */
858 + fixed.type = T_AAAA;
859 + addr = (char *)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
860 + addrlen = sizeof(struct in6_addr);
864 + addr = (char *)&((struct sockaddr_in *)res->ai_addr)->sin_addr;
865 + addrlen = sizeof(struct in_addr);
868 + msg_warn("%s: unknown address family %d for %s",
869 + myname, res->ai_family, host);
872 + addr_list = dns_rr_append(addr_list,
873 + dns_rr_create(host, &fixed, pref, addr, addrlen));
876 + freeaddrinfo(res0);
882 INET_ADDR_LIST *self;
886 + struct sockaddr *sa;
890 * Find the first address that lists any address that this mail system is
891 @@ -238,12 +341,36 @@
893 self = own_inet_addr_list();
894 for (addr = addr_list; addr; addr = addr->next) {
895 - for (i = 0; i < self->used; i++)
896 + for (i = 0; i < self->used; i++) {
898 + sa = (struct sockaddr *)&self->addrs[i];
899 + switch(addr->type) {
902 + if (sa->sa_family != AF_INET6)
904 + if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr,
905 + addr->data, sizeof(struct in6_addr)) == 0) {
910 + if (sa->sa_family != AF_INET)
912 + if (memcmp(&((struct sockaddr_in *)sa)->sin_addr,
913 + addr->data, sizeof(struct in_addr)) == 0) {
919 if (INADDRP(addr->data)->s_addr == self->addrs[i].s_addr) {
921 msg_info("%s: found at pref %d", myname, addr->pref);
929 diff -Nur snapshot-20010525.nov6/src/smtp/smtp_connect.c snapshot-20010525/src/smtp/smtp_connect.c
930 --- snapshot-20010525.nov6/src/smtp/smtp_connect.c Tue Oct 16 13:15:43 2001
931 +++ snapshot-20010525/src/smtp/smtp_connect.c Wed Oct 17 11:38:17 2001
933 /* System library. */
935 #include <sys_defs.h>
937 #include <sys/socket.h>
938 #include <netinet/in.h>
939 #include <arpa/inet.h>
941 #include <inet_addr_list.h>
943 #include <timed_connect.h>
944 +#include <get_port.h>
945 #include <stringops.h>
947 /* Global library. */
948 @@ -133,19 +135,45 @@
951 char *myname = "smtp_connect_addr";
952 - struct sockaddr_in sin;
955 + struct sockaddr_storage ss;
957 + struct sockaddr ss;
959 + struct sockaddr *sa;
960 + struct sockaddr_in *sin;
962 + struct sockaddr_in6 *sin6;
964 + SOCKADDR_SIZE salen;
966 + char hbuf[NI_MAXHOST];
968 + char hbuf[sizeof("255.255.255.255") + 1];
971 INET_ADDR_LIST *addr_list;
976 - unsigned long inaddr;
978 + sa = (struct sockaddr *)&ss;
979 + sin = (struct sockaddr_in *)&ss;
981 + sin6 = (struct sockaddr_in6 *)&ss;
987 - if (addr->data_len > sizeof(sin.sin_addr)) {
989 + if (((addr->type==T_A) && (addr->data_len > sizeof(sin->sin_addr))) ||
990 + ((addr->type==T_AAAA) && (addr->data_len > sizeof(sin6->sin6_addr))))
992 + if (addr->data_len > sizeof(sin->sin_addr))
995 msg_warn("%s: skip address with length %d", myname, addr->data_len);
996 smtp_errno = SMTP_RETRY;
998 @@ -154,17 +182,39 @@
1002 - memset((char *) &sin, 0, sizeof(sin));
1003 - sin.sin_family = AF_INET;
1005 - if ((sock = socket(sin.sin_family, SOCK_STREAM, 0)) < 0)
1006 - msg_fatal("%s: socket: %m", myname);
1008 + switch (addr->type) {
1011 + memset(sin6, 0, sizeof(*sin6));
1012 + sin6->sin6_family = AF_INET6;
1013 + salen = sizeof(*sin6);
1016 + default: /* T_A: */
1017 + memset(sin, 0, sizeof(*sin));
1018 + sin->sin_family = AF_INET;
1019 + salen = sizeof(*sin);
1023 + sa->sa_len = salen;
1025 + if ((sock = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
1026 + msg_warn("%s: socket: %m", myname);
1029 * Allow the sysadmin to specify the source address, for example, as "-o
1030 * smtp_bind_address=x.x.x.x" in the master.cf file.
1032 if (*var_smtp_bind_addr) {
1034 + struct sockaddr_in sin;
1036 + memset(&sin, 0, sizeof(sin));
1037 + sin.sin_family = AF_INET;
1039 + sin.sin_len = sizeof(sin);
1041 sin.sin_addr.s_addr = inet_addr(var_smtp_bind_addr);
1042 if (sin.sin_addr.s_addr == INADDR_NONE)
1043 msg_fatal("%s: bad %s parameter: %s",
1044 @@ -173,6 +223,25 @@
1045 msg_warn("%s: bind %s: %m", myname, inet_ntoa(sin.sin_addr));
1047 msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
1049 + char hbufl[NI_MAXHOST];
1050 + struct addrinfo hints, *res;
1052 + memset(&hints, 0, sizeof(hints));
1053 + hints.ai_family = sa->sa_family;
1054 + hints.ai_socktype = SOCK_STREAM;
1055 + hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST;
1056 + snprintf(hbufl, sizeof(hbufl)-1, "%s", var_smtp_bind_addr);
1057 + if (getaddrinfo(hbufl, NULL, &hints, &res) == 0) {
1058 + (void)getnameinfo(res->ai_addr, res->ai_addrlen, hbufl,
1059 + sizeof(hbufl), NULL, 0, NI_NUMERICHOST);
1060 + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0)
1061 + msg_warn("%s: bind %s: %m", myname, hbufl);
1062 + freeaddrinfo(res);
1064 + msg_info("%s: bind %s", myname, hbufl);
1070 @@ -180,8 +249,17 @@
1071 * the mail appears to come from the "right" machine address.
1073 else if ((addr_list = own_inet_addr_list())->used == 1) {
1075 + struct sockaddr_in sin;
1076 + unsigned long inaddr; /*XXX BAD!*/
1078 + memset(&sin, 0, sizeof(sin));
1079 + sin.sin_family = AF_INET;
1081 + sin.sin_len = sizeof(sin);
1083 memcpy((char *) &sin.sin_addr, addr_list->addrs, sizeof(sin.sin_addr));
1084 - inaddr = ntohl(sin.sin_addr.s_addr);
1085 + inaddr = (unsigned long)ntohl(sin.sin_addr.s_addr);
1086 if (!IN_CLASSA(inaddr)
1087 || !(((inaddr & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)) {
1088 if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
1089 @@ -189,30 +267,85 @@
1091 msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
1094 + char hbufl[NI_MAXHOST];
1095 + struct addrinfo hints, *res = NULL, *loopback = NULL;
1097 + memset(&hints, 0, sizeof(hints));
1098 + hints.ai_family = sa->sa_family;
1099 + hints.ai_socktype = SOCK_STREAM;
1100 + if (getaddrinfo(NULL, "0", &hints, &loopback) != 0)
1104 + * getnameinfo -> getaddrinfo loop is here so that we can
1105 + * get rid of port.
1107 + (void)getnameinfo((struct sockaddr *)addr_list->addrs, SA_LEN((struct sockaddr *)addr_list->addrs),
1108 + hbufl, sizeof(hbufl), NULL, 0, NI_NUMERICHOST);
1109 + hbufl[sizeof(hbufl)-1] = 0;
1110 + memset(&hints, 0, sizeof(hints));
1111 + hints.ai_family = sa->sa_family;
1112 + hints.ai_socktype = SOCK_STREAM;
1113 + hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST;
1114 + if (getaddrinfo(hbufl, NULL, &hints, &res) == 0 &&
1115 + !(res->ai_addrlen == loopback->ai_addrlen &&
1116 + memcmp(res->ai_addr, loopback->ai_addr, res->ai_addrlen) == 0)) {
1117 + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0)
1118 + msg_warn("%s: bind %s: %m", myname, hbufl);
1120 + msg_info("%s: bind %s", myname, hbufl);
1123 + freeaddrinfo(res);
1125 + freeaddrinfo(loopback);
1130 * Connect to the SMTP server.
1132 - sin.sin_port = port;
1133 - memcpy((char *) &sin.sin_addr, addr->data, sizeof(sin.sin_addr));
1134 + switch (addr->type) {
1137 + /* XXX scope unfriendly */
1138 + memset(sin6, 0, sizeof(*sin6));
1139 + sin6->sin6_port = port;
1140 + sin6->sin6_family = AF_INET6;
1141 + salen = sizeof(*sin6);
1142 + memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr));
1143 + inet_ntop(AF_INET6, &sin6->sin6_addr, hbuf, sizeof(hbuf));
1146 + default: /* T_A */
1147 + memset(sin, 0, sizeof(*sin));
1148 + sin->sin_port = port;
1149 + sin->sin_family = AF_INET;
1150 + salen = sizeof(*sin);
1151 + memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr));
1152 + inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf));
1156 + sa->sa_len = salen;
1160 msg_info("%s: trying: %s[%s] port %d...",
1161 - myname, addr->name, inet_ntoa(sin.sin_addr), ntohs(port));
1162 + myname, addr->name, hbuf, ntohs(port));
1163 if (var_smtp_conn_tmout > 0) {
1164 non_blocking(sock, NON_BLOCKING);
1165 - conn_stat = timed_connect(sock, (struct sockaddr *) & sin,
1166 - sizeof(sin), var_smtp_conn_tmout);
1167 + conn_stat = timed_connect(sock, sa, salen, var_smtp_conn_tmout);
1168 saved_errno = errno;
1169 non_blocking(sock, BLOCKING);
1170 errno = saved_errno;
1172 - conn_stat = connect(sock, (struct sockaddr *) & sin, sizeof(sin));
1173 + conn_stat = connect(sock, sa, salen);
1175 if (conn_stat < 0) {
1176 vstring_sprintf(why, "connect to %s[%s]: %m",
1177 - addr->name, inet_ntoa(sin.sin_addr));
1178 + addr->name, hbuf);
1179 smtp_errno = SMTP_RETRY;
1183 * Skip this host if it takes no action within some time limit.
1185 if (read_wait(sock, var_smtp_helo_tmout) < 0) {
1186 - vstring_sprintf(why, "connect to %s[%s]: read timeout",
1187 - addr->name, inet_ntoa(sin.sin_addr));
1188 + vstring_sprintf(why, "connect to %s [%s]: read timeout",
1189 + addr->name, hbuf);
1190 smtp_errno = SMTP_RETRY;
1195 stream = vstream_fdopen(sock, O_RDWR);
1196 if ((ch = VSTREAM_GETC(stream)) == VSTREAM_EOF) {
1197 - vstring_sprintf(why, "connect to %s[%s]: server dropped connection",
1198 - addr->name, inet_ntoa(sin.sin_addr));
1199 + vstring_sprintf(why, "connect to %s [%s]: server dropped connection",
1200 + addr->name, hbuf);
1201 smtp_errno = SMTP_RETRY;
1202 vstream_fclose(stream);
1206 if (ch == '4' && var_smtp_skip_4xx_greeting) {
1207 vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
1208 - addr->name, inet_ntoa(sin.sin_addr));
1209 + addr->name, hbuf);
1210 smtp_errno = SMTP_RETRY;
1211 vstream_fclose(stream);
1213 @@ -258,12 +391,12 @@
1215 if (ch == '5' && var_smtp_skip_5xx_greeting) {
1216 vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
1217 - addr->name, inet_ntoa(sin.sin_addr));
1218 + addr->name, hbuf);
1219 smtp_errno = SMTP_RETRY;
1220 vstream_fclose(stream);
1223 - return (smtp_session_alloc(dest, stream, addr->name, inet_ntoa(sin.sin_addr)));
1224 + return (smtp_session_alloc(dest, stream, addr->name, hbuf));
1227 /* smtp_connect_host - direct connection to host */
1229 SMTP_SESSION *session = 0;
1235 * Try each address in the specified order until we find one that works.
1236 * The addresses belong to the same A record, so we have no information
1238 msg_fatal("unknown service: %s/%s", service, protocol);
1239 *portp = sp->s_port;
1245 diff -Nur snapshot-20010525.nov6/src/smtp/smtp_unalias.c snapshot-20010525/src/smtp/smtp_unalias.c
1246 --- snapshot-20010525.nov6/src/smtp/smtp_unalias.c Thu Sep 28 19:06:09 2000
1247 +++ snapshot-20010525/src/smtp/smtp_unalias.c Wed Oct 17 11:38:17 2001
1249 if ((result = htable_find(cache, name)) == 0) {
1250 fqdn = vstring_alloc(10);
1251 if (dns_lookup_types(name, smtp_unalias_flags, (DNS_RR **) 0,
1252 - fqdn, (VSTRING *) 0, T_MX, T_A, 0) != DNS_OK)
1253 + fqdn, (VSTRING *) 0, T_MX, T_A,
1258 vstring_strcpy(fqdn, name);
1259 htable_enter(cache, name, result = vstring_export(fqdn));
1261 diff -Nur snapshot-20010525.nov6/src/smtpd/smtpd_check.c snapshot-20010525/src/smtpd/smtpd_check.c
1262 --- snapshot-20010525.nov6/src/smtpd/smtpd_check.c Tue Oct 16 13:15:43 2001
1263 +++ snapshot-20010525/src/smtpd/smtpd_check.c Wed Oct 17 11:38:17 2001
1264 @@ -812,7 +812,11 @@
1265 msg_info("%s: %s", myname, name);
1267 dns_status = dns_lookup_types(name, 0, (DNS_RR **) 0, (VSTRING *) 0,
1268 - (VSTRING *) 0, T_A, T_MX, 0);
1269 + (VSTRING *) 0, T_A, T_MX,
1274 if (dns_status != DNS_OK)
1275 return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
1276 "%d <%s>: %s odrzucony/rejected: Host not found",
1277 @@ -834,7 +838,11 @@
1278 msg_info("%s: %s", myname, name);
1280 dns_status = dns_lookup_types(name, 0, (DNS_RR **) 0, (VSTRING *) 0,
1281 - (VSTRING *) 0, T_A, T_MX, 0);
1282 + (VSTRING *) 0, T_A, T_MX,
1287 if (dns_status != DNS_OK)
1288 return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
1289 "%d <%s>: %s odrzucony/rejected: Domain not found",
1290 @@ -1007,6 +1015,49 @@
1292 static int has_my_addr(char *host)
1295 + char *myname = "has_my_addr";
1296 + struct addrinfo hints, *res, *res0;
1298 + char hbuf[NI_MAXHOST];
1301 + msg_info("%s: host %s", myname, host);
1304 + * If we can't lookup the host, play safe and assume it is OK.
1309 + memset(&hints, 0, sizeof(hints));
1310 + hints.ai_family = PF_UNSPEC;
1311 + hints.ai_socktype = SOCK_DGRAM;
1312 + error = getaddrinfo(host, NULL, &hints, &res0);
1315 + msg_info("%s: host %s: %s", myname, host, gai_strerror(error));
1318 + for (res = res0; res; res = res->ai_next) {
1319 + if (msg_verbose) {
1320 + if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
1321 + NULL, 0, NI_NUMERICHOST)) {
1322 + strncpy(hbuf, "???", sizeof(hbuf));
1324 + msg_info("%s: addr %s", myname, hbuf);
1326 + if (own_inet_addr(res->ai_addr)) {
1327 + freeaddrinfo(res0);
1331 + freeaddrinfo(res0);
1333 + msg_info("%s: host %s: no match", myname, host);
1337 char *myname = "has_my_addr";
1338 struct in_addr addr;
1340 @@ -1042,6 +1093,7 @@
1341 msg_info("%s: host %s: no match", myname, host);
1347 /* permit_mx_backup - permit use of me as MX backup for recipient domain */
1348 @@ -1548,10 +1600,15 @@
1349 int dns_status = DNS_FAIL;
1355 msg_info("%s: %s", myname, state->addr);
1357 + /* IPv4 only for now */
1358 + if (inet_pton(AF_INET, state->addr, &a) != 1)
1359 + return SMTPD_CHECK_DUNNO;
1364 diff -Nur snapshot-20010525.nov6/src/smtpd/smtpd_peer.c snapshot-20010525/src/smtpd/smtpd_peer.c
1365 --- snapshot-20010525.nov6/src/smtpd/smtpd_peer.c Sun Jan 28 16:24:56 2001
1366 +++ snapshot-20010525/src/smtpd/smtpd_peer.c Wed Oct 17 11:38:17 2001
1371 +/* Utility library. */
1374 +#include <mymalloc.h>
1375 +#include <valid_hostname.h>
1376 +#include <stringops.h>
1378 +/* Global library. */
1381 * Older systems don't have h_errno. Even modern systems don't have
1387 -/* Utility library. */
1390 -#include <mymalloc.h>
1391 -#include <valid_hostname.h>
1392 -#include <stringops.h>
1394 -/* Global library. */
1398 +#define GAI_STRERROR(error) \
1399 + ((error = EAI_SYSTEM) ? gai_strerror(error) : strerror(errno))
1402 /* Application-specific. */
1405 @@ -102,16 +106,23 @@
1407 void smtpd_peer_init(SMTPD_STATE *state)
1409 - struct sockaddr_in sin;
1410 - SOCKADDR_SIZE len = sizeof(sin);
1412 + struct sockaddr_storage ss;
1414 + struct sockaddr ss;
1415 + struct in_addr *in;
1419 + struct sockaddr *sa;
1420 + SOCKADDR_SIZE len;
1422 + sa = (struct sockaddr *)&ss;
1426 * Look up the peer address information.
1428 - if (getpeername(vstream_fileno(state->client),
1429 - (struct sockaddr *) & sin, &len) >= 0) {
1430 + if (getpeername(vstream_fileno(state->client), sa, &len) >= 0) {
1434 @@ -128,18 +139,51 @@
1436 * Look up and "verify" the client hostname.
1438 - else if (errno == 0 && sin.sin_family == AF_INET) {
1439 - state->addr = mystrdup(inet_ntoa(sin.sin_addr));
1440 - hp = gethostbyaddr((char *) &(sin.sin_addr),
1441 - sizeof(sin.sin_addr), AF_INET);
1443 + else if (errno == 0 && (sa->sa_family == AF_INET
1445 + || sa->sa_family == AF_INET6
1449 + char hbuf[NI_MAXHOST];
1450 + char abuf[NI_MAXHOST];
1451 + struct addrinfo hints, *rnull = NULL;
1453 + char abuf[sizeof("255.255.255.255") + 1];
1459 + (void)getnameinfo(sa, len, abuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
1461 + in = &((struct sockaddr_in *)sa)->sin_addr;
1462 + inet_ntop(AF_INET, in, abuf, sizeof(hbuf));
1464 + state->addr = mystrdup(abuf);
1466 + error = getnameinfo(sa, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD);
1469 + hp = gethostbyaddr((char *)in, sizeof(*in), AF_INET);
1472 + hbuf = mystrdup(hp->h_name);
1477 state->name = mystrdup("unknown");
1479 + state->peer_code = (error == EAI_AGAIN ? 4 : 5);
1481 state->peer_code = (h_errno == TRY_AGAIN ? 4 : 5);
1482 - } else if (!valid_hostname(hp->h_name, DONT_GRIPE)) {
1484 + } else if (!valid_hostname(hbuf, DONT_GRIPE)) {
1485 state->name = mystrdup("unknown");
1486 state->peer_code = 5;
1488 - state->name = mystrdup(hp->h_name); /* hp->name is clobbered!! */
1489 + state->name = mystrdup(hbuf); /* hp->name is clobbered!! */
1490 state->peer_code = 2;
1493 @@ -151,16 +195,31 @@
1494 state->peer_code = code; \
1498 + memset(&hints, 0, sizeof(hints));
1499 + hints.ai_family = AF_UNSPEC;
1500 + hints.ai_socktype = SOCK_STREAM;
1501 + error = getaddrinfo(state->name, NULL, &hints, &rnull);
1503 + msg_warn("%s: hostname %s verification failed: %s",
1504 + state->addr, state->name, GAI_STRERROR(error));
1505 + REJECT_PEER_NAME(state, (error == EAI_AGAIN ? 4 : 5));
1507 + /* memcmp() isn't needed if we use getaddrinfo */
1509 + freeaddrinfo(rnull);
1511 hp = gethostbyname(state->name); /* clobbers hp->name!! */
1513 msg_warn("%s: hostname %s verification failed: %s",
1514 state->addr, state->name, HSTRERROR(h_errno));
1515 REJECT_PEER_NAME(state, (h_errno == TRY_AGAIN ? 4 : 5));
1516 - } else if (hp->h_length != sizeof(sin.sin_addr)) {
1517 + } else if (hp->h_length != sizeof(*in)) {
1518 msg_warn("%s: hostname %s verification failed: bad address size %d",
1519 state->addr, state->name, hp->h_length);
1520 REJECT_PEER_NAME(state, 5);
1523 for (i = 0; /* void */ ; i++) {
1524 if (hp->h_addr_list[i] == 0) {
1525 msg_warn("%s: address not listed for hostname %s",
1526 @@ -168,12 +227,11 @@
1527 REJECT_PEER_NAME(state, 5);
1530 - if (memcmp(hp->h_addr_list[i],
1531 - (char *) &sin.sin_addr,
1532 - sizeof(sin.sin_addr)) == 0)
1533 + if (memcmp(hp->h_addr_list[i], (char *)in, sizeof(*in)) == 0)
1534 break; /* keep peer name */
1541 diff -Nur snapshot-20010525.nov6/src/smtpstone/smtp-sink.c snapshot-20010525/src/smtpstone/smtp-sink.c
1542 --- snapshot-20010525.nov6/src/smtpstone/smtp-sink.c Thu Jan 25 01:26:07 2001
1543 +++ snapshot-20010525/src/smtpstone/smtp-sink.c Wed Oct 17 11:38:17 2001
1546 if (strncmp(argv[optind], "inet:", 5) == 0)
1548 - sock = inet_listen(argv[optind], backlog, BLOCKING);
1549 + sock = inet_listen(argv[optind], backlog, BLOCKING, 1);
1553 diff -Nur snapshot-20010525.nov6/src/util/Makefile.in snapshot-20010525/src/util/Makefile.in
1554 --- snapshot-20010525.nov6/src/util/Makefile.in Tue Oct 16 13:15:43 2001
1555 +++ snapshot-20010525/src/util/Makefile.in Wed Oct 17 11:38:17 2001
1557 dict_nisplus.c dict_open.c dir_forest.c doze.c environ.c \
1558 events.c exec_command.c fifo_listen.c fifo_trigger.c file_limit.c \
1559 find_inet.c fsspace.c fullname.c get_domainname.c get_hostname.c \
1561 htable.c inet_addr_host.c inet_addr_list.c inet_addr_local.c \
1562 inet_connect.c inet_listen.c inet_trigger.c inet_util.c \
1563 line_wrap.c lowercase.c lstat_as.c mac_parse.c make_dirs.c \
1565 dict_nisplus.o dict_open.o dir_forest.o doze.o environ.o \
1566 events.o exec_command.o fifo_listen.o fifo_trigger.o file_limit.o \
1567 find_inet.o fsspace.o fullname.o get_domainname.o get_hostname.o \
1569 htable.o inet_addr_host.o inet_addr_list.o inet_addr_local.o \
1570 inet_connect.o inet_listen.o inet_trigger.o inet_util.o \
1571 line_wrap.o lowercase.o lstat_as.o mac_parse.o make_dirs.o \
1573 dict_dbm.h dict_env.h dict_ht.h dict_ldap.h dict_mysql.h \
1574 dict_ni.h dict_nis.h dict_nisplus.h dir_forest.h events.h \
1575 exec_command.h find_inet.h fsspace.h fullname.h get_domainname.h \
1577 get_hostname.h htable.h inet_addr_host.h inet_addr_list.h \
1578 inet_addr_local.h inet_util.h iostuff.h line_wrap.h listen.h lstat_as.h \
1579 mac_parse.h make_dirs.h match_list.h match_ops.h msg.h msg_output.h \
1581 get_domainname.o: mymalloc.h
1582 get_domainname.o: get_hostname.h
1583 get_domainname.o: get_domainname.h
1584 +get_port.o: sys_defs.h
1585 get_hostname.o: get_hostname.c
1586 get_hostname.o: sys_defs.h
1587 get_hostname.o: mymalloc.h
1589 match_list.o: stringops.h
1590 match_list.o: argv.h
1591 match_list.o: dict.h
1592 +match_list.o: inet_util.h
1593 match_list.o: match_list.h
1594 match_ops.o: match_ops.c
1595 match_ops.o: sys_defs.h
1596 diff -Nur snapshot-20010525.nov6/src/util/get_port.c snapshot-20010525/src/util/get_port.c
1597 --- snapshot-20010525.nov6/src/util/get_port.c Thu Jan 1 01:00:00 1970
1598 +++ snapshot-20010525/src/util/get_port.c Wed Oct 17 11:38:17 2001
1604 +/* trivial host and port extracter
1606 +/* #include <get_port.h>
1608 +/* char *get_port(data)
1612 +/* get_port() extract host name or ip address from
1613 +/* strings such as [3ffe:902:12::10]:25, [::1]
1614 +/* or 192.168.0.1:25, and null-terminates the
1615 +/* \fIdata\fR at the first occurrence of port separator.
1617 +/* If port not found return null pointer.
1621 +/* BSD Style (or BSD like) license.
1623 +/* Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
1627 +/* System libraries */
1629 +#include <sys_defs.h>
1630 +#include <string.h>
1632 +/* Utility library. */
1634 +#include "get_port.h"
1636 +/* get_port - extract port number from string */
1638 +char *get_port(char *data)
1640 + const char *escl=strchr(data,'[');
1641 + const char *sepl=strchr(data,':');
1642 + char *escr=strrchr(data,']');
1643 + char *sepr=strrchr(data,':');
1645 + /* extract from "[address]:port" or "[address]"*/
1648 + memmove(data, data + 1, strlen(data) - strlen(escr));
1649 + data[strlen(data) - strlen(escr) - 1] = 0;
1653 + return (*escr ? escr : NULL);
1655 + /* extract from "address:port" or "address" */
1656 + if ((sepl == sepr) && sepr && sepl)
1662 + /* return empty string */
1665 diff -Nur snapshot-20010525.nov6/src/util/get_port.h snapshot-20010525/src/util/get_port.h
1666 --- snapshot-20010525.nov6/src/util/get_port.h Thu Jan 1 01:00:00 1970
1667 +++ snapshot-20010525/src/util/get_port.h Wed Oct 17 11:38:17 2001
1669 +#ifndef _GET_PORT_H_INCLUDED_
1670 +#define _GET_PORT_H_INCLUDED_
1676 +/* trivial host and port extracter
1678 +/* #include <get_port.h>
1682 + /* External interface. */
1684 +extern char *get_port(char *);
1690 +/* BSD Style (or BSD like) license.
1692 +/* Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
1697 diff -Nur snapshot-20010525.nov6/src/util/inet_addr_host.c snapshot-20010525/src/util/inet_addr_host.c
1698 --- snapshot-20010525.nov6/src/util/inet_addr_host.c Fri Dec 11 19:55:35 1998
1699 +++ snapshot-20010525/src/util/inet_addr_host.c Wed Oct 17 11:38:17 2001
1701 #include <sys_defs.h>
1702 #include <netinet/in.h>
1703 #include <arpa/inet.h>
1704 +#include <sys/socket.h>
1706 +#include <stdlib.h>
1707 +#include <string.h>
1710 #define INADDR_NONE 0xffffffff
1713 #include <inet_addr_list.h>
1714 #include <inet_addr_host.h>
1719 /* inet_addr_host - look up address list for host */
1721 int inet_addr_host(INET_ADDR_LIST *addr_list, const char *hostname)
1725 + struct addrinfo hints, *res0, *res;
1727 + char buforhosta[1024];
1732 struct in_addr addr;
1734 int initial_count = addr_list->used;
1737 + memset(&hints, 0, sizeof(hints));
1738 + hints.ai_family = PF_UNSPEC;
1739 + hints.ai_socktype = SOCK_DGRAM;
1740 + error = getaddrinfo(hostname, NULL, &hints, &res0);
1742 + for (res = res0; res; res = res->ai_next) {
1743 + if(res->ai_family != AF_INET && res->ai_family != AF_INET6)
1745 + /* filter out address families that are not supported */
1746 + s = socket(res->ai_family, SOCK_DGRAM, 0);
1751 + inet_addr_list_append(addr_list, res->ai_addr);
1753 + freeaddrinfo(res0);
1756 if ((addr.s_addr = inet_addr(hostname)) != INADDR_NONE) {
1757 inet_addr_list_append(addr_list, &addr);
1760 inet_addr_list_append(addr_list,
1761 (struct in_addr *) * hp->h_addr_list++);
1765 return (addr_list->used - initial_count);
1774 INET_ADDR_LIST addr_list;
1776 + struct sockaddr *sa;
1777 + char hbuf[NI_MAXHOST];
1779 msg_vstream_init(argv[0], VSTREAM_ERR);
1782 if (inet_addr_host(&addr_list, *argv) == 0)
1783 msg_fatal("not found: %s", *argv);
1785 - for (i = 0; i < addr_list.used; i++)
1786 - vstream_printf("%s\n", inet_ntoa(addr_list.addrs[i]));
1787 + for (i = 0; i < addr_list.used; i++) {
1788 + sa = (struct sockaddr *)&addr_list.addrs[i];
1789 + getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
1791 + vstream_printf("%s\n", hbuf);
1793 vstream_fflush(VSTREAM_OUT);
1795 inet_addr_list_free(&addr_list);
1796 diff -Nur snapshot-20010525.nov6/src/util/inet_addr_list.c snapshot-20010525/src/util/inet_addr_list.c
1797 --- snapshot-20010525.nov6/src/util/inet_addr_list.c Mon Nov 20 19:06:30 2000
1798 +++ snapshot-20010525/src/util/inet_addr_list.c Wed Oct 17 11:38:17 2001
1800 #include <netinet/in.h>
1801 #include <arpa/inet.h>
1806 +#include <string.h>
1807 +#include <sys/socket.h>
1810 /* Utility library. */
1818 + list->addrs = (struct sockaddr_storage *)
1820 list->addrs = (struct in_addr *)
1822 mymalloc(sizeof(*list->addrs) * list->size);
1825 /* inet_addr_list_append - append address to internet address list */
1828 +void inet_addr_list_append(INET_ADDR_LIST *list,
1829 + struct sockaddr * addr)
1831 + char *myname = "inet_addr_list_append";
1832 + char hbuf[NI_MAXHOST];
1834 + if (msg_verbose > 1) {
1835 + if (getnameinfo(addr, SA_LEN(addr), hbuf, sizeof(hbuf), NULL, 0,
1836 + NI_NUMERICHOST)) {
1837 + strncpy(hbuf, "??????", sizeof(hbuf));
1839 + msg_info("%s: %s", myname, hbuf);
1842 + if (list->used >= list->size)
1844 + list->addrs = (struct sockaddr_storage *)
1845 + myrealloc((char *) list->addrs,
1846 + sizeof(*list->addrs) * list->size);
1847 + memcpy(&list->addrs[list->used++], addr, SA_LEN(addr));
1850 void inet_addr_list_append(INET_ADDR_LIST *list, struct in_addr * addr)
1852 char *myname = "inet_addr_list_append";
1854 sizeof(*list->addrs) * list->size);
1855 list->addrs[list->used++] = *addr;
1859 /* inet_addr_list_free - destroy internet address list */
1861 diff -Nur snapshot-20010525.nov6/src/util/inet_addr_list.h snapshot-20010525/src/util/inet_addr_list.h
1862 --- snapshot-20010525.nov6/src/util/inet_addr_list.h Fri Dec 11 19:55:35 1998
1863 +++ snapshot-20010525/src/util/inet_addr_list.h Wed Oct 17 11:38:17 2001
1866 #include <netinet/in.h>
1870 +#define SA_LEN(x) (((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
1871 +#define SS_LEN(x) (((x).ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
1873 +#define SA_LEN(x) ((x)->sa_len)
1874 +#define SS_LEN(x) ((x).ss_len)
1879 * External interface.
1881 typedef struct INET_ADDR_LIST {
1882 int used; /* nr of elements in use */
1883 int size; /* actual list size */
1885 + struct sockaddr_storage *addrs; /* payload */
1887 struct in_addr *addrs; /* payload */
1891 extern void inet_addr_list_init(INET_ADDR_LIST *);
1892 extern void inet_addr_list_free(INET_ADDR_LIST *);
1895 +extern void inet_addr_list_append(INET_ADDR_LIST *, struct sockaddr *);
1897 extern void inet_addr_list_append(INET_ADDR_LIST *, struct in_addr *);
1902 diff -Nur snapshot-20010525.nov6/src/util/inet_addr_local.c snapshot-20010525/src/util/inet_addr_local.c
1903 --- snapshot-20010525.nov6/src/util/inet_addr_local.c Sun Feb 25 19:20:19 2001
1904 +++ snapshot-20010525/src/util/inet_addr_local.c Wed Oct 17 11:38:17 2001
1909 +#if defined(INET6) && (defined (LINUX) || defined (LINUX2))
1913 +#ifdef HAVE_GETIFADDRS
1914 +#include <ifaddrs.h>
1917 /* Utility library. */
1921 int inet_addr_local(INET_ADDR_LIST *addr_list, INET_ADDR_LIST *mask_list)
1923 +#ifdef HAVE_GETIFADDRS
1924 + char *myname = "inet_addr_local";
1925 + struct ifaddrs *ifap, *ifa;
1926 + int initial_count = addr_list->used;
1927 + struct sockaddr *sa;
1930 + struct sockaddr_in6 addr6;
1936 + if (getifaddrs(&ifap) < 0)
1937 + msg_fatal("%s: getifaddrs: %m", myname);
1939 + for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1940 + if (! (ifa->ifa_flags & IFF_RUNNING))
1942 + sa = ifa->ifa_addr;
1943 + switch (ifa->ifa_addr->sa_family) {
1946 + addr = (void *)&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
1952 + memcpy(&addr6, ifa->ifa_addr, ifa->ifa_addr->sa_len);
1953 + /* decode scoped address notation */
1954 + if ((IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) ||
1955 + IN6_IS_ADDR_SITELOCAL(&addr6.sin6_addr)) &&
1956 + addr6.sin6_scope_id == 0) {
1957 + addr6.sin6_scope_id = ntohs(addr6.sin6_addr.s6_addr[3] |
1958 + (unsigned int)addr6.sin6_addr.s6_addr[2] << 8);
1959 + addr6.sin6_addr.s6_addr[2] = addr6.sin6_addr.s6_addr[3] = 0;
1960 + sa = (struct sockaddr *)&addr6;
1970 + inet_addr_list_append(addr_list, sa);
1972 + inet_addr_list_append(addr_list, (struct in_addr *)addr);
1976 + freeifaddrs(ifap);
1977 + return (addr_list->used - initial_count);
1979 char *myname = "inet_addr_local";
1982 struct ifreq *the_end;
1984 - VSTRING *buf = vstring_alloc(1024);
1986 int initial_count = addr_list->used;
1987 struct in_addr addr;
1988 struct ifreq *ifr_mask;
1991 +#if defined (LINUX) || defined (LINUX2)
1992 +#define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"
1994 + char addr6p[8][5], addr6res[40], devname[20];
1995 + int plen, scope, dad_status, if_idx, gaierror;
1996 + struct addrinfo hints, *res, *res0;
1998 + struct sockaddr_in6 addr6;
2000 - if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
2003 + buf = vstring_alloc(1024);
2005 + if ((sock = socket(af, SOCK_DGRAM, 0)) < 0) {
2007 + if (af == AF_INET6)
2010 + msg_warn("%s: socket: %m", myname);
2015 msg_fatal("%s: socket: %m", myname);
2019 * Get the network interface list. XXX The socket API appears to have no
2020 @@ -126,10 +213,15 @@
2022 the_end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
2023 for (ifr = ifc.ifc_req; ifr < the_end;) {
2024 - if (ifr->ifr_addr.sa_family == AF_INET) { /* IP interface */
2025 + if ((ifr->ifr_addr.sa_family == AF_INET) &&
2026 + (ifr->ifr_addr.sa_family == af)) { /* IP interface */
2027 addr = ((struct sockaddr_in *) & ifr->ifr_addr)->sin_addr;
2028 if (addr.s_addr != INADDR_ANY) { /* has IP address */
2030 + inet_addr_list_append(addr_list, &ifr->ifr_addr);
2032 inet_addr_list_append(addr_list, &addr);
2035 ifr_mask = (struct ifreq *) mymalloc(IFREQ_SIZE(ifr));
2036 memcpy((char *) ifr_mask, (char *) ifr, IFREQ_SIZE(ifr));
2037 @@ -141,11 +233,61 @@
2042 + else if ((ifr->ifr_addr.sa_family == AF_INET6) &&
2043 + (ifr->ifr_addr.sa_family == af)) { /* IPv6 interface */
2044 + addr6 = *((struct sockaddr_in6 *) & ifr->ifr_addr);
2046 + /* decode scoped address notation */
2047 + if ((IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) ||
2048 + IN6_IS_ADDR_SITELOCAL(&addr6.sin6_addr)) &&
2049 + addr6.sin6_scope_id == 0) {
2050 + addr6.sin6_scope_id = ntohs(addr6.sin6_addr.s6_addr[3] |
2051 + (unsigned int)addr6.sin6_addr.s6_addr[2] << 8);
2052 + addr6.sin6_addr.s6_addr[2] = addr6.sin6_addr.s6_addr[3] = 0;
2055 + if (!(IN6_IS_ADDR_UNSPECIFIED(&addr6.sin6_addr)))
2056 + inet_addr_list_append(addr_list, (struct sockaddr *)&addr6);
2059 ifr = NEXT_INTERFACE(ifr);
2065 + if (af != AF_INET6) {
2067 + goto other_socket_type;
2069 +#if defined (LINUX) || defined (LINUX2)
2070 + if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) {
2071 + while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
2072 + addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4],
2073 + addr6p[5], addr6p[6], addr6p[7],
2074 + &if_idx, &plen, &scope, &dad_status, devname) != EOF) {
2075 + sprintf(addr6res, "%s:%s:%s:%s:%s:%s:%s:%s",
2076 + addr6p[0], addr6p[1], addr6p[2], addr6p[3],
2077 + addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
2078 + addr6res[sizeof(addr6res) - 1] = 0;
2079 + memset(&hints, 0, sizeof(hints));
2080 + hints.ai_flags = AI_NUMERICHOST;
2081 + hints.ai_family = AF_UNSPEC;
2082 + hints.ai_socktype = SOCK_DGRAM;
2083 + gaierror = getaddrinfo(addr6res, NULL, &hints, &res0);
2085 + for (res = res0; res; res = res->ai_next) {
2086 + inet_addr_list_append(addr_list, res->ai_addr);
2088 + freeaddrinfo(res0);
2094 return (addr_list->used - initial_count);
2100 INET_ADDR_LIST addr_list;
2101 INET_ADDR_LIST mask_list;
2103 + char abuf[NI_MAXHOST], mbuf[NI_MAXHOST];
2104 + struct sockaddr *sa;
2106 msg_vstream_init(argv[0], VSTREAM_ERR);
2108 @@ -172,8 +316,17 @@
2109 msg_warn("found only one active network interface");
2111 for (i = 0; i < addr_list.used; i++) {
2112 - vstream_printf("%s/", inet_ntoa(addr_list.addrs[i]));
2113 - vstream_printf("%s\n", inet_ntoa(mask_list.addrs[i]));
2114 + sa = (struct sockaddr *)&addr_list.addrs[i];
2115 + if (getnameinfo(sa, SA_LEN(sa), abuf, sizeof(abuf), NULL, 0,
2116 + NI_NUMERICHOST)) {
2117 + strncpy(abuf, "???", sizeof(abuf));
2119 + sa = (struct sockaddr *)&mask_list.addrs[i];
2120 + if (getnameinfo(sa, SA_LEN(sa), mbuf, sizeof(mbuf), NULL, 0,
2121 + NI_NUMERICHOST)) {
2122 + strncpy(mbuf, "???", sizeof(mbuf));
2124 + vstream_printf("%s/%s\n", abuf, mbuf);
2126 vstream_fflush(VSTREAM_OUT);
2127 inet_addr_list_free(&addr_list);
2128 diff -Nur snapshot-20010525.nov6/src/util/inet_connect.c snapshot-20010525/src/util/inet_connect.c
2129 --- snapshot-20010525.nov6/src/util/inet_connect.c Mon Nov 20 19:06:31 2000
2130 +++ snapshot-20010525/src/util/inet_connect.c Wed Oct 17 11:38:17 2001
2139 /* Utility library. */
2146 + struct addrinfo hints, *res, *res0;
2149 struct sockaddr_in sin;
2157 buf = inet_parse(addr, &host, &port);
2161 + memset(&hints, 0, sizeof(hints));
2162 + hints.ai_family = PF_UNSPEC;
2163 + hints.ai_socktype = SOCK_STREAM;
2164 + hints.ai_flags = AI_NUMERICHOST; /* find_inet_addr is numeric only */
2165 + if (getaddrinfo(host, port, &hints, &res0))
2166 + msg_fatal("host not found: %s", host);
2170 memset((char *) &sin, 0, sizeof(sin));
2171 sin.sin_family = AF_INET;
2172 sin.sin_addr.s_addr = find_inet_addr(host);
2173 sin.sin_port = find_inet_port(port, "tcp");
2179 + for (res = res0; res; res = res->ai_next) {
2180 + if ((res->ai_family != AF_INET) && (res->ai_family != AF_INET6))
2183 + sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
2186 + if (timeout > 0) {
2187 + non_blocking(sock, NON_BLOCKING);
2188 + if (timed_connect(sock, res->ai_addr, res->ai_addrlen, timeout) < 0) {
2193 + if (block_mode != NON_BLOCKING)
2194 + non_blocking(sock, block_mode);
2197 + non_blocking(sock, block_mode);
2198 + if (connect(sock, res->ai_addr, res->ai_addrlen) < 0
2199 + && errno != EINPROGRESS) {
2207 + freeaddrinfo(res0);
2211 * Create a client socket.
2219 diff -Nur snapshot-20010525.nov6/src/util/inet_listen.c snapshot-20010525/src/util/inet_listen.c
2220 --- snapshot-20010525.nov6/src/util/inet_listen.c Mon Nov 20 19:06:32 2000
2221 +++ snapshot-20010525/src/util/inet_listen.c Wed Oct 17 11:38:17 2001
2224 /* #include <listen.h>
2226 -/* int inet_listen(addr, backlog, block_mode)
2227 +/* int inet_listen(addr, backlog, block_mode, addinuse_fatal)
2228 /* const char *addr;
2232 #include <sys_defs.h>
2233 #include <sys/socket.h>
2234 #include <netinet/in.h>
2236 +#if (! __GLIBC__ >= 2 && __GLIBC_MINOR__ >=1 )
2237 +#include <netinet6/in6.h>
2240 #include <arpa/inet.h>
2242 #ifndef MAXHOSTNAMELEN
2243 #include <sys/param.h>
2249 @@ -77,35 +83,116 @@
2251 /* inet_listen - create inet-domain listener */
2253 -int inet_listen(const char *addr, int backlog, int block_mode)
2254 +int inet_listen(const char *addr, int backlog, int block_mode, int addrinuse_fatal)
2257 + struct addrinfo *res, *res0, hints;
2264 + struct sockaddr *ai_addr;
2265 + SOCKADDR_SIZE ai_addrlen;
2266 + struct ai *ai_next;
2267 + } *res, *res0, resbody;
2268 struct sockaddr_in sin;
2272 + int addrinuse = 0;
2277 + char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
2279 + char hbuf[sizeof("255.255.255.255") + 1];
2280 + char pbuf[sizeof("255.255.255.255") + 1];
2282 + char *cause = "unknown";
2285 * Translate address information to internal form.
2287 buf = inet_parse(addr, &host, &port);
2288 - memset((char *) &sin, 0, sizeof(sin));
2290 + memset(&hints, 0, sizeof(hints));
2291 + hints.ai_flags = AI_PASSIVE;
2292 + hints.ai_family = AF_UNSPEC;
2293 + hints.ai_socktype = SOCK_STREAM;
2294 + error = getaddrinfo(*host ? host : NULL, *port ? port : "0", &hints, &res0);
2296 + msg_fatal("getaddrinfo: %s", gai_strerror(error));
2300 + memset(&sin, 0, sizeof(sin));
2301 sin.sin_family = AF_INET;
2303 + sin.sin_len = sizeof(sin);
2305 sin.sin_port = find_inet_port(port, "tcp");
2306 sin.sin_addr.s_addr = (*host ? find_inet_addr(host) : INADDR_ANY);
2310 - * Create a listener socket.
2312 - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
2313 - msg_fatal("socket: %m");
2314 - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &t, sizeof(t)) < 0)
2315 - msg_fatal("setsockopt: %m");
2316 - if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
2317 - msg_fatal("bind %s port %d: %m", sin.sin_addr.s_addr == INADDR_ANY ?
2318 - "INADDR_ANY" : inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
2319 + memset(&resbody, 0, sizeof(resbody));
2320 + resbody.ai_socktype = SOCK_STREAM;
2321 + resbody.ai_family = AF_INET;
2322 + resbody.ai_addr = (struct sockaddr *)&sin;
2323 + resbody.ai_addrlen = sizeof(sin);
2329 + for (res = res0; res; res = res->ai_next) {
2330 + if ((res->ai_family != AF_INET) && (res->ai_family != AF_INET6))
2334 + * Create a listener socket.
2336 + if ((sock = socket(res->ai_family, res->ai_socktype, 0)) < 0) {
2341 + if (res->ai_family == AF_INET6 &&
2342 + setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &t, sizeof(t)) < 0) {
2343 + /* if kernel/libc don't support this simple ignore it
2344 + cause = "setsockopt(IPV6_V6ONLY)";
2352 + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &t, sizeof(t)) < 0) {
2353 + cause = "setsockopt(SO_REUSEADDR)";
2359 + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
2361 + if (errno == EADDRINUSE)
2369 + if (sock < 0 && (addrinuse_fatal || !addrinuse))
2370 + msg_fatal("%s: %m", cause);
2372 + freeaddrinfo(res0);
2376 non_blocking(sock, block_mode);
2377 if (listen(sock, backlog) < 0)
2378 msg_fatal("listen: %m");
2379 diff -Nur snapshot-20010525.nov6/src/util/listen.h snapshot-20010525/src/util/listen.h
2380 --- snapshot-20010525.nov6/src/util/listen.h Mon Mar 22 02:57:11 1999
2381 +++ snapshot-20010525/src/util/listen.h Wed Oct 17 11:38:17 2001
2383 * Listener external interface.
2385 extern int unix_listen(const char *, int, int);
2386 -extern int inet_listen(const char *, int, int);
2387 +extern int inet_listen(const char *, int, int, int);
2388 extern int fifo_listen(const char *, int, int);
2389 extern int stream_listen(const char *, int, int);
2391 diff -Nur snapshot-20010525.nov6/src/util/match_list.c snapshot-20010525/src/util/match_list.c
2392 --- snapshot-20010525.nov6/src/util/match_list.c Mon Nov 20 19:06:32 2000
2393 +++ snapshot-20010525/src/util/match_list.c Wed Oct 17 11:38:17 2001
2395 list = match_list_parse(list, vstring_str(buf));
2396 if (vstream_fclose(fp))
2397 msg_fatal("%s: read file %s: %m", myname, pattern);
2398 - } else if (strchr(pattern, ':') != 0) { /* type:table */
2399 + } else if ((strchr(pattern, ']') == 0) && (strchr(pattern, ':') != 0)) { /* type:table */
2400 for (cp = pattern; *cp == '!'; cp++)
2402 if (dict_handle(pattern) == 0)
2403 diff -Nur snapshot-20010525.nov6/src/util/match_ops.c snapshot-20010525/src/util/match_ops.c
2404 --- snapshot-20010525.nov6/src/util/match_ops.c Mon Sep 6 03:02:14 1999
2405 +++ snapshot-20010525/src/util/match_ops.c Wed Oct 17 11:38:17 2001
2407 #include <match_ops.h>
2408 #include <stringops.h>
2414 + * This program is free software; you can redistribute it and/or
2415 + * modify it under the terms of the GNU General Public License
2416 + * as published by the Free Software Foundation; either version
2417 + * 2 of the License, or (at your option) any later version.
2419 + * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
2422 + * Artur Frysiak <wiget@pld.org.pl>
2423 + * Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
2427 +#include <stdlib.h>
2428 +#include <unistd.h>
2429 +#include <syslog.h>
2431 +#include <sys/socket.h>
2432 +#include <netinet/in.h>
2433 +#include <string.h>
2435 +#include <arpa/inet.h>
2436 +#include <resolv.h>
2439 +#define AF_DECnet 12
2443 +#define PF_PACKET 17
2448 + unsigned char family;
2449 + unsigned char bytelen;
2450 + signed short bitlen;
2451 + unsigned int data[4];
2455 +int masked_match(char *, char *, char *);
2456 +int get_integer(int *, char *, int);
2457 +int get_addr_1(inet_prefix *, char *, int);
2458 +int get_prefix_1(inet_prefix *, char *, int);
2459 +int get_addr(inet_prefix *, char *, int);
2460 +int get_prefix(inet_prefix *, char *, int);
2461 +unsigned int get_addr32(char *);
2462 +int matches(char *, char *);
2463 +int inet_addr_match(inet_prefix *, inet_prefix *, int);
2464 +int mask_match(char *, char *, char *);
2466 +int get_integer(int *val, char *arg, int base)
2471 + if (!arg || !*arg)
2473 + res = strtol(arg, &ptr, base);
2474 + if (!ptr || ptr == arg || *ptr || res > INT_MAX || res < INT_MIN)
2480 +int get_addr_1(inet_prefix *addr, char *name, int family)
2483 + unsigned char *ap = (unsigned char*)addr->data;
2486 + memset(addr, 0, sizeof(*addr));
2488 + if (strcmp(name, "default") == 0 || strcmp(name, "any") == 0) {
2489 + if (family == AF_DECnet)
2491 + addr->family = family;
2492 + addr->bytelen = (family == AF_INET6 ? 16 : 4);
2493 + addr->bitlen = -1;
2497 + if (strchr(name, ':')) {
2498 + addr->family = AF_INET6;
2499 + if (family != AF_UNSPEC && family != AF_INET6)
2501 + if (inet_pton(AF_INET6, name, addr->data) <= 0)
2503 + addr->bytelen = 16;
2504 + addr->bitlen = -1;
2507 + addr->family = AF_INET;
2508 + if (family != AF_UNSPEC && family != AF_INET)
2510 + addr->bytelen = 4;
2511 + addr->bitlen = -1;
2512 + for (cp = name, i = 0; *cp; cp++) {
2513 + if (*cp <= '9' && *cp >= '0') {
2514 + ap[i] = 10*ap[i] + (*cp-'0');
2517 + if (*cp == '.' && ++i <= 3)
2524 +int get_prefix_1(inet_prefix *dst, char *arg, int family)
2530 + memset(dst, 0, sizeof(*dst));
2532 + if (strcmp(arg, "default") == 0 || strcmp(arg, "any") == 0) {
2533 + if (family == AF_DECnet)
2535 + dst->family = family;
2541 + slash = strchr(arg, '/');
2544 + err = get_addr_1(dst, arg, family);
2546 + switch(dst->family) {
2548 + dst->bitlen = 128;
2558 + if (get_integer(&plen, slash+1, 0) || plen > dst->bitlen) {
2562 + dst->bitlen = plen;
2571 +int get_addr(inet_prefix *dst, char *arg, int family)
2574 + if (family == AF_PACKET)
2577 + if (get_addr_1(dst, arg, family))
2582 +int get_prefix(inet_prefix *dst, char *arg, int family)
2585 + if (family == AF_PACKET)
2588 + if (get_prefix_1(dst, arg, family))
2593 +unsigned int get_addr32(char *name)
2596 + if (get_addr_1(&addr, name, AF_INET))
2598 + return addr.data[0];
2601 +int matches(char *cmd, char *pattern)
2603 + int len = strlen(cmd);
2604 + if (len > strlen(pattern))
2606 + return memcmp(pattern, cmd, len);
2609 +int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits)
2611 + unsigned int *a1 = a->data;
2612 + unsigned int *a2 = b->data;
2613 + int words = bits >> 0x05;
2618 + if (memcmp(a1, a2, words << 2))
2622 + unsigned int w1, w2;
2623 + unsigned int mask;
2628 + mask = htonl((0xffffffff) << (0x20 - bits));
2630 + if ((w1 ^ w2) & mask)
2637 +/* zero if matches */
2638 +int mask_match(char *network, char *cprefix, char *address)
2640 + inet_prefix *inetwork;
2641 + inet_prefix *iaddress;
2644 + if (!(network && address && cprefix))
2646 + prefix = strtol(cprefix, (char **)NULL, 10);
2647 + if ((prefix < 0) || (prefix > 128))
2649 + if ((strlen(network) == 0) || (strlen(address) == 0))
2652 + inetwork = malloc(sizeof(inet_prefix));
2653 + iaddress = malloc(sizeof(inet_prefix));
2655 + if ((get_addr(iaddress, address, AF_UNSPEC) >= 0)
2656 + && (get_addr(inetwork, network, AF_UNSPEC) >= 0))
2657 + ret = inet_addr_match(inetwork, iaddress, prefix);
2663 + /* 1 if matches */
2664 + /* return (!ret); */
2665 + /* 0 if matches */
2670 + * masked_match() - universal for IPv4 and IPv6
2672 +int masked_match(net_tok, mask_tok, string)
2678 + struct in6_addr in6[2];
2679 + char v4addr[2][INET_ADDRSTRLEN];
2684 + /* Check for NULL */
2685 + if (!(net_tok && mask_tok && string))
2688 + /* If IPv6 mapped convert to native-IPv4 */
2690 + if (inet_pton(AF_INET6, net_tok, &in6[0]) == 1 &&
2691 + inet_pton(AF_INET6, string, &in6[1]) == 1 &&
2692 + IN6_IS_ADDR_V4MAPPED(&in6[0]) && IN6_IS_ADDR_V4MAPPED(&in6[1])) {
2693 + plen = atoi(mask_tok);
2694 + if (32 < plen && plen < 129) {
2695 + sprintf(newmask, "%d", plen - 96);
2696 + mask_tok = newmask;
2699 + (void)inet_ntop(AF_INET, &in6[0].s6_addr[12], v4addr[0],
2700 + sizeof(v4addr[0]));
2701 + net_tok = v4addr[0];
2702 + (void)inet_ntop(AF_INET, &in6[1].s6_addr[12], v4addr[1],
2703 + sizeof(v4addr[1]));
2704 + string = v4addr[1];
2707 + return (!mask_match(net_tok, mask_tok, string));
2711 /* match_string - match a string literal */
2713 int match_string(const char *string, const char *pattern)
2719 /* match_parse_mask - parse net/mask pattern */
2721 static int match_parse_mask(const char *pattern, unsigned long *net_bits,
2722 @@ -178,28 +480,55 @@
2723 myfree(saved_pattern);
2728 /* match_hostaddr - match host by address */
2730 int match_hostaddr(const char *addr, const char *pattern)
2732 char *myname = "match_hostaddr";
2734 + char *network, *mask, *escl, *escr, *patternx;
2735 + struct in6_addr in6;
2736 + char v4addr[INET_ADDRSTRLEN];
2739 unsigned long mask_bits;
2740 unsigned long net_bits;
2741 unsigned long addr_bits;
2745 msg_info("%s: %s ~? %s", myname, addr, pattern);
2748 + if (addr[strspn(addr, "01234567890./:abcdef")] != 0)
2750 if (addr[strspn(addr, "01234567890./:")] != 0)
2755 + patternx = mystrdup(pattern);
2756 + escl = strchr(patternx,'[');
2757 + escr = strrchr(patternx,']');
2758 + if (escl && escr) {
2760 + sprintf(patternx, "%s%s", escl + 1, escr + 1);
2761 + pattern = patternx;
2766 * Try dictionary lookup. This can be case insensitive. XXX Probably
2767 * should also try again after stripping least significant octets.
2769 - if (strchr(pattern, ':') != 0) {
2771 + if (!(escl && escr) && strchr(pattern, ':') != 0)
2773 + if (strchr(pattern, ':') != 0)
2776 if (dict_lookup(pattern, addr) != 0)
2778 if (dict_errno != 0)
2779 @@ -210,6 +539,12 @@
2781 * Try an exact match with the host address.
2784 + if (inet_pton(AF_INET6, addr, &in6) == 1 && IN6_IS_ADDR_V4MAPPED(&in6)) {
2785 + (void)inet_ntop(AF_INET, &in6.s6_addr[12], v4addr, sizeof(v4addr));
2789 if (strcasecmp(addr, pattern) == 0) {
2792 @@ -218,6 +553,20 @@
2793 * In a net/mask pattern, the mask is specified as the number of bits of
2797 + network = mystrdup(patternx);
2798 + mask = split_at(network, '/');
2800 + if (masked_match(network, mask, (char *)addr)) {
2810 if (match_parse_mask(pattern, &net_bits, &mask_shift)) {
2811 addr_bits = inet_addr(addr);
2812 if (addr_bits == INADDR_NONE)
2814 mask_bits = htonl((0xffffffff) << (BITS_PER_ADDR - mask_shift));
2815 return ((addr_bits & mask_bits) == (net_bits & mask_bits));
2820 diff -Nur snapshot-20010525.nov6/src/util/sys_defs.h snapshot-20010525/src/util/sys_defs.h
2821 --- snapshot-20010525.nov6/src/util/sys_defs.h Tue Oct 16 13:15:43 2001
2822 +++ snapshot-20010525/src/util/sys_defs.h Wed Oct 17 11:38:17 2001
2824 #define DEF_MAILBOX_LOCK "flock, dotlock"
2827 +#if ((defined(__NetBSD_Version__) && __NetBSD_Version__ >= 105000000) || defined(USAGI_LIBINET6))
2828 +#define HAVE_GETIFADDRS
2834 diff -Nur snapshot-20010525.nov6/src/util/valid_hostname.c snapshot-20010525/src/util/valid_hostname.c
2835 --- snapshot-20010525.nov6/src/util/valid_hostname.c Sun Jan 28 15:10:18 2001
2836 +++ snapshot-20010525/src/util/valid_hostname.c Wed Oct 17 11:38:17 2001
2842 +#include <netinet/in.h>
2843 +#include <sys/socket.h>
2844 +#include <arpa/inet.h>
2848 /* Utility library. */
2851 @@ -103,7 +110,23 @@
2852 msg_warn("%s: misplaced hyphen: %.100s", myname, name);
2858 + else if (ch == ':') {
2859 + struct addrinfo hints, *res;
2861 + memset(&hints, 0, sizeof(hints));
2862 + hints.ai_family = AF_INET6;
2863 + hints.ai_socktype = SOCK_STREAM; /*dummy*/
2864 + hints.ai_flags = AI_NUMERICHOST;
2865 + if (getaddrinfo(name, "0", &hints, &res) == 0) {
2866 + freeaddrinfo(res);
2874 msg_warn("%s: invalid character %d(decimal): %.100s",
2881 + struct addrinfo hints, *res;
2884 #define BYTES_NEEDED 4
2886 @@ -147,6 +173,17 @@
2891 + memset(&hints, 0, sizeof(hints));
2892 + hints.ai_family = AF_INET6;
2893 + hints.ai_socktype = SOCK_STREAM; /*dummy*/
2894 + hints.ai_flags = AI_NUMERICHOST;
2895 + if (getaddrinfo(addr, "0", &hints, &res) == 0) {
2896 + freeaddrinfo(res);
2902 * Scary code to avoid sscanf() overflow nasties.