1 diff -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
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
13 + if [ -f /usr/local/v6/lib/libinet6.a ]; then
20 +if [ -z "$INET6" -a -f /usr/include/netinet/ip6.h -a -f /usr/include/linux/icmpv6.h ]; then
25 dcosx*) SYSTEM=$VERSION;;
29 : ${CC='gcc $(WARN)'} ${OPT='-O'} ${DEBUG='-g'} ${AWK=awk}
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"
39 + CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len"
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"
51 export SYSTYPE AR ARFL RANLIB SYSLIBS CC OPT DEBUG AWK OPTS
53 diff -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
59 #define INET_ADDR_LEN 4 /* XXX */
61 +#define INET6_ADDR_LEN 16
64 /* dns_query - query name server and pre-parse the reply */
67 memcpy(temp, pos, fixed->length);
68 data_len = fixed->length;
72 + if (fixed->length != INET6_ADDR_LEN) {
73 + msg_warn("extract_answer: bad IPv6 address length: %d", fixed->length);
76 + if (fixed->length > sizeof(temp))
77 + msg_panic("dns_get_rr: length %d > DNS_NAME_LEN",
79 + memcpy(temp, pos, fixed->length);
80 + data_len = fixed->length;
84 data_len = MIN2(pos[0] + 1, MIN2(fixed->length + 1, sizeof(temp)));
85 for (src = pos + 1, dst = (unsigned char *) (temp);
86 diff -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
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 \
93 - verp_sender.c match_parent_style.c pfixtls.c
94 + verp_sender.c match_parent_style.c pfixtls.c wildcard_inet_addr.c
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 \
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 \
102 - verp_sender.o match_parent_style.o pfixtls.o
103 + verp_sender.o match_parent_style.o pfixtls.o wildcard_inet_addr.o
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 \
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 \
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
113 TESTSRC = rec2stream.c stream2rec.c recdump.c
114 WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
115 -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
116 diff -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
121 #include <inet_addr_list.h>
122 #include <name_mask.h>
124 +#include <sys/socket.h>
125 +#include <netinet/in.h>
129 /* Global library. */
132 const char *mynetworks(void)
134 static VSTRING *result;
136 + char hbuf[NI_MAXHOST];
140 char *myname = "mynetworks";
146 + struct sockaddr *sa;
149 mask_style = name_mask("mynetworks mask style", mask_styles,
150 var_mynetworks_style);
152 my_mask_list = own_inet_mask_list();
154 for (i = 0; i < my_addr_list->used; i++) {
156 + sa = (struct sockaddr *)&my_addr_list->addrs[i];
157 + if (sa->sa_family != AF_INET) {
158 + if (sa->sa_family == AF_INET6)
159 + vstring_sprintf_append(result, "XAATODOmynetworks ");
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);
165 addr = ntohl(my_addr_list->addrs[i].s_addr);
166 mask = ntohl(my_mask_list->addrs[i].s_addr);
169 switch (mask_style) {
172 mask = IN_CLASSD_NET;
173 shift = IN_CLASSD_NSHIFT;
176 + if (getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
178 + strncpy(hbuf, "???", sizeof(hbuf));
179 + msg_fatal("%s: bad address class: %s", myname, hbuf);
181 msg_fatal("%s: bad address class: %s",
182 myname, inet_ntoa(my_addr_list->addrs[i]));
187 diff -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
191 #include <netinet/in.h>
192 #include <arpa/inet.h>
195 +#include <sys/socket.h>
199 #ifdef STRCASECMP_IN_STRINGS_H
201 @@ -101,10 +105,11 @@
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);
214 @@ -121,15 +126,39 @@
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) {
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);
229 msg_fatal("parameter %s: no local interface found for %s",
231 inet_ntoa(addr_list->addrs[nvirtual]));
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]);
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]);
254 inet_addr_list_free(&local_addrs);
257 /* own_inet_addr - is this my own internet address */
260 +int own_inet_addr(struct sockaddr * addr)
265 + struct sockaddr *sa;
267 + if (addr_list.used == 0)
268 + own_inet_addr_init(&addr_list, &mask_list);
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)
274 + switch (addr->sa_family) {
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);
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);
289 + if (memcmp(p, q, l) == 0)
295 int own_inet_addr(struct in_addr * addr)
299 for (i = 0; i < addr_list.used; i++)
300 if (addr->s_addr == addr_list.addrs[i].s_addr)
306 /* own_inet_addr_list - return list of addresses */
308 diff -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
314 #include <netinet/in.h>
316 +#include <sys/socket.h>
320 * External interface.
323 +extern int own_inet_addr(struct sockaddr *);
325 extern int own_inet_addr(struct in_addr *);
327 extern struct INET_ADDR_LIST *own_inet_addr_list(void);
328 extern struct INET_ADDR_LIST *own_inet_mask_list(void);
330 diff -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
334 PEER_NAME *peer_name(int sock)
336 static PEER_NAME peer;
337 - struct sockaddr_in sin;
338 - SOCKADDR_SIZE len = sizeof(sin);
345 + struct sockaddr peer_un;
346 + struct sockaddr_in peer_un4;
348 + struct sockaddr_in6 peer_un6;
351 +#define sun p_un.peer_un
352 +#define sin p_un.peer_un4
354 +#define sin6 p_un.peer_un6
355 + static char hbuf[NI_MAXHOST];
356 + static char abuf[NI_MAXHOST];
360 + SOCKADDR_SIZE len = sizeof(p_un);
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) {
368 peer.type = PEER_TYPE_INET;
369 hp = gethostbyaddr((char *) &(sin.sin_addr),
371 hp->h_name : "unknown");
372 peer.addr = inet_ntoa(sin.sin_addr);
376 + peer.type = PEER_TYPE_INET;
377 + if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
378 + peer.name = "unknown";
384 + peer.type = PEER_TYPE_INET6;
385 + if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
386 + peer.name = "unknown";
394 peer.type = PEER_TYPE_LOCAL;
395 diff -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
399 #define PEER_TYPE_UNKNOWN 0
400 #define PEER_TYPE_INET 1
401 #define PEER_TYPE_LOCAL 2
403 +#define PEER_TYPE_INET6 3
406 extern PEER_NAME *peer_name(int);
408 diff -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
412 #include <netinet/in.h>
413 #include <arpa/inet.h>
418 #define INADDR_NONE 0xffffffff
421 char *saved_addr = mystrdup(addr);
424 + struct addrinfo hints, *res, *res0;
427 struct in_addr ipaddr;
431 #define RETURN(x) { myfree(saved_addr); return(x); }
433 if (*dest == '[' && dest[len - 1] == ']') {
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);
442 + for (res = res0; res; res = res->ai_next) {
443 + if (own_inet_addr(res->ai_addr)) {
444 + freeaddrinfo(res0);
448 + freeaddrinfo(res0);
451 if ((ipaddr.s_addr = inet_addr(dest)) != INADDR_NONE
452 && own_inet_addr(&ipaddr))
458 diff -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
462 +/* System library. */
464 +#include <sys_defs.h>
465 +#include <netinet/in.h>
466 +#include <arpa/inet.h>
469 +#include <sys/socket.h>
473 +#ifdef STRCASECMP_IN_STRINGS_H
474 +#include <strings.h>
477 +/* Utility library. */
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>
486 +/* Global library. */
488 +#include <mail_params.h>
489 +#include <wildcard_inet_addr.h>
491 +/* Application-specific. */
492 +static INET_ADDR_LIST addr_list;
494 +/* wildcard_inet_addr_init - initialize my own address list */
496 +static void wildcard_inet_addr_init(INET_ADDR_LIST *addr_list)
499 + struct addrinfo hints, *res, *res0;
500 + char hbuf[NI_MAXHOST];
502 +#ifdef NI_WITHSCOPEID
503 + const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
505 + const int niflags = NI_NUMERICHOST;
508 + inet_addr_list_init(addr_list);
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);
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)
520 + if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
521 + NULL, 0, niflags) != 0)
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); */
527 + freeaddrinfo(res0);
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");
535 +/* wildcard_inet_addr_list - return list of addresses */
537 +INET_ADDR_LIST *wildcard_inet_addr_list(void)
539 + if (addr_list.used == 0)
540 + wildcard_inet_addr_init(&addr_list);
542 + return (&addr_list);
544 diff -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
548 +#ifndef _WILDCARD_INET_ADDR_H_INCLUDED_
549 +#define _WILDCARD_INET_ADDR_H_INCLUDED_
553 +/* wildcard_inet_addr_list 3h
555 +/* grab the list of wildcard IP addresses.
557 +/* #include <own_inet_addr.h>
565 +#include <netinet/in.h>
567 +#include <sys/socket.h>
571 + * External interface.
573 +extern struct INET_ADDR_LIST *wildcard_inet_addr_list(void);
580 +/* Jun-ichiro itojun Hagino
584 diff -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
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) {
592 + MASTER_INET_ADDRLIST(serv) = wildcard_inet_addr_list();
593 + serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
595 MASTER_INET_ADDRLIST(serv) = 0; /* wild-card */
596 serv->listen_fd_count = 1;
599 MASTER_INET_ADDRLIST(serv) = own_inet_addr_list(); /* virtual */
600 serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
601 diff -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
613 /* master_listen_init - enable connection requests */
615 void master_listen_init(MASTER_SERV *serv)
617 char *myname = "master_listen_init";
622 + char hbuf[NI_MAXHOST];
623 + SOCKADDR_SIZE salen;
627 * Find out what transport we should use, then create one or more
628 @@ -111,18 +120,31 @@
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);
634 close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
635 } else { /* virtual or host:port */
636 - for (n = 0; n < serv->listen_fd_count; n++) {
637 + for (m = n = 0; n < serv->listen_fd_count; n++) {
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));
644 + end_point = concatenate(hbuf, ":", MASTER_INET_PORT(serv), (char *) 0);
646 end_point = concatenate(inet_ntoa(MASTER_INET_ADDRLIST(serv)->addrs[n]),
647 ":", MASTER_INET_PORT(serv), (char *) 0);
651 = inet_listen(end_point, serv->max_proc > var_proc_limit ?
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);
656 + serv->listen_fd[m] = tmpfd;
657 + close_on_exec(serv->listen_fd[m++], CLOSE_ON_EXEC);
661 + serv->listen_fd_count=m;
665 diff -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
669 * every front-ent program.
671 if ((at = strrchr(recipient->address, '@')) != 0
673 + && (at + 1)[strspn(at + 1, "[]0123456789.:abcdef")] != 0
675 && (at + 1)[strspn(at + 1, "[]0123456789.")] != 0
677 && valid_hostname(at + 1, DONT_GRIPE) == 0) {
678 qmgr_bounce_recipient(message, recipient,
679 "bad host/domain syntax: \"%s\"", at + 1);
680 diff -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
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
691 diff -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
694 @@ -134,18 +134,68 @@
695 static void smtp_print_addr(char *what, DNS_RR *addr_list)
698 - struct in_addr in_addr;
700 + struct sockaddr_storage ss;
702 + struct sockaddr ss;
704 + struct sockaddr_in *sin;
706 + struct sockaddr_in6 *sin6;
707 + char hbuf[NI_MAXHOST];
709 + char hbuf[sizeof("255.255.255.255") + 1];
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);
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);
725 + switch (addr->type) {
727 + if (addr->data_len != sizeof(sin->sin_addr)) {
728 + msg_warn("skipping invalid address (AAAA, len=%u)",
732 + sin = (struct sockaddr_in *)&ss;
733 + memset(sin, 0, sizeof(*sin));
734 + sin->sin_family = AF_INET;
736 + sin->sin_len = sizeof(*sin);
738 + memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr));
742 + if (addr->data_len != sizeof(sin6->sin6_addr)) {
743 + msg_warn("skipping invalid address (AAAA, len=%u)",
747 + sin6 = (struct sockaddr_in6 *)&ss;
748 + memset(sin6, 0, sizeof(*sin6));
749 + sin6->sin6_family = AF_INET6;
751 + sin6->sin6_len = sizeof(*sin6);
753 + memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr));
757 + msg_warn("skipping unsupported address (type=%u)", addr->type);
762 + (void)getnameinfo((struct sockaddr *)&ss, SS_LEN(ss),
763 + hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
765 + (void)inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf));
767 + msg_info("pref %4d host %s/%s", addr->pref, addr->name, hbuf);
769 msg_info("end %s address list", what);
771 @@ -155,15 +205,23 @@
772 static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRING *why)
774 char *myname = "smtp_addr_one";
776 struct in_addr inaddr;
782 + struct addrinfo hints, *res0, *res;
790 msg_info("%s: host %s", myname, host);
794 * Interpret a numerical name as an address.
797 smtp_errno = SMTP_FAIL;
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);
808 + smtp_errno = SMTP_RETRY;
811 + vstring_sprintf(why, "[%s]: %s",host,gai_strerror(error));
812 + smtp_errno = SMTP_FAIL;
815 + return (addr_list);
817 + for (res = res0; res; res = res->ai_next) {
818 + memset((char *) &fixed, 0, sizeof(fixed));
819 + switch(res->ai_family) {
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);
828 + addr = (char *)&((struct sockaddr_in *)res->ai_addr)->sin_addr;
829 + addrlen = sizeof(struct in_addr);
832 + msg_warn("%s: unknown address family %d for %s",
833 + myname, res->ai_family, host);
836 + addr_list = dns_rr_append(addr_list,
837 + dns_rr_create(host, &fixed, pref, addr, addrlen));
840 + freeaddrinfo(res0);
846 INET_ADDR_LIST *self;
850 + struct sockaddr *sa;
854 * Find the first address that lists any address that this mail system is
855 @@ -260,12 +363,36 @@
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++) {
862 + sa = (struct sockaddr *)&self->addrs[i];
863 + switch(addr->type) {
866 + if (sa->sa_family != AF_INET6)
868 + if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr,
869 + addr->data, sizeof(struct in6_addr)) == 0) {
874 + if (sa->sa_family != AF_INET)
876 + if (memcmp(&((struct sockaddr_in *)sa)->sin_addr,
877 + addr->data, sizeof(struct in_addr)) == 0) {
883 if (INADDRP(addr->data)->s_addr == self->addrs[i].s_addr) {
885 msg_info("%s: found at pref %d", myname, addr->pref);
893 diff -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
897 /* System library. */
899 #include <sys_defs.h>
901 #include <sys/socket.h>
902 #include <netinet/in.h>
903 #include <arpa/inet.h>
905 #include <inet_addr_list.h>
907 #include <timed_connect.h>
908 +#include <get_port.h>
909 #include <stringops.h>
911 /* Global library. */
912 @@ -133,19 +135,45 @@
915 char *myname = "smtp_connect_addr";
916 - struct sockaddr_in sin;
919 + struct sockaddr_storage ss;
921 + struct sockaddr ss;
923 + struct sockaddr *sa;
924 + struct sockaddr_in *sin;
926 + struct sockaddr_in6 *sin6;
928 + SOCKADDR_SIZE salen;
930 + char hbuf[NI_MAXHOST];
932 + char hbuf[sizeof("255.255.255.255") + 1];
935 INET_ADDR_LIST *addr_list;
940 - unsigned long inaddr;
942 + sa = (struct sockaddr *)&ss;
943 + sin = (struct sockaddr_in *)&ss;
945 + sin6 = (struct sockaddr_in6 *)&ss;
951 - if (addr->data_len > sizeof(sin.sin_addr)) {
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))))
956 + if (addr->data_len > sizeof(sin->sin_addr))
959 msg_warn("%s: skip address with length %d", myname, addr->data_len);
960 smtp_errno = SMTP_RETRY;
962 @@ -154,17 +182,39 @@
966 - memset((char *) &sin, 0, sizeof(sin));
967 - sin.sin_family = AF_INET;
969 - if ((sock = socket(sin.sin_family, SOCK_STREAM, 0)) < 0)
970 - msg_fatal("%s: socket: %m", myname);
972 + switch (addr->type) {
975 + memset(sin6, 0, sizeof(*sin6));
976 + sin6->sin6_family = AF_INET6;
977 + salen = sizeof(*sin6);
980 + default: /* T_A: */
981 + memset(sin, 0, sizeof(*sin));
982 + sin->sin_family = AF_INET;
983 + salen = sizeof(*sin);
987 + sa->sa_len = salen;
989 + if ((sock = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
990 + msg_warn("%s: socket: %m", myname);
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.
996 if (*var_smtp_bind_addr) {
998 + struct sockaddr_in sin;
1000 + memset(&sin, 0, sizeof(sin));
1001 + sin.sin_family = AF_INET;
1003 + sin.sin_len = sizeof(sin);
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));
1011 msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
1013 + char hbufl[NI_MAXHOST];
1014 + struct addrinfo hints, *res;
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);
1028 + msg_info("%s: bind %s", myname, hbufl);
1034 @@ -180,8 +249,17 @@
1035 * the mail appears to come from the "right" machine address.
1037 else if ((addr_list = own_inet_addr_list())->used == 1) {
1039 + struct sockaddr_in sin;
1040 + unsigned long inaddr; /*XXX BAD!*/
1042 + memset(&sin, 0, sizeof(sin));
1043 + sin.sin_family = AF_INET;
1045 + sin.sin_len = sizeof(sin);
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 @@
1055 msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
1058 + char hbufl[NI_MAXHOST];
1059 + struct addrinfo hints, *res = NULL, *loopback = NULL;
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)
1068 + * getnameinfo -> getaddrinfo loop is here so that we can
1069 + * get rid of port.
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);
1084 + msg_info("%s: bind %s", myname, hbufl);
1087 + freeaddrinfo(res);
1089 + freeaddrinfo(loopback);
1094 * Connect to the SMTP server.
1096 - sin.sin_port = port;
1097 - memcpy((char *) &sin.sin_addr, addr->data, sizeof(sin.sin_addr));
1098 + switch (addr->type) {
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));
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));
1120 + sa->sa_len = salen;
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;
1136 - conn_stat = connect(sock, (struct sockaddr *) & sin, sizeof(sin));
1137 + conn_stat = connect(sock, sa, salen);
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;
1147 * Skip this host if it takes no action within some time limit.
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;
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);
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);
1177 @@ -258,12 +391,12 @@
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);
1187 - return (smtp_session_alloc(dest, stream, addr->name, inet_ntoa(sin.sin_addr)));
1188 + return (smtp_session_alloc(dest, stream, addr->name, hbuf));
1191 /* smtp_connect_host - direct connection to host */
1193 SMTP_SESSION *session = 0;
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
1202 msg_fatal("unknown service: %s/%s", service, protocol);
1203 *portp = sp->s_port;
1209 diff -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
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,
1222 vstring_strcpy(fqdn, name);
1223 htable_enter(cache, name, result = vstring_export(fqdn));
1225 diff -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
1228 @@ -916,7 +916,11 @@
1229 msg_info("%s: %s", myname, name);
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,
1238 if (dns_status != DNS_OK)
1239 return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
1240 "%d <%s>: %s odrzucony/rejected: Host not found",
1241 @@ -938,7 +942,11 @@
1242 msg_info("%s: %s", myname, name);
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,
1251 if (dns_status != DNS_OK)
1252 return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
1253 "%d <%s>: %s odrzucony/rejected: Domain not found",
1254 @@ -1167,6 +1175,49 @@
1256 static int has_my_addr(const char *host)
1259 + char *myname = "has_my_addr";
1260 + struct addrinfo hints, *res, *res0;
1262 + char hbuf[NI_MAXHOST];
1265 + msg_info("%s: host %s", myname, host);
1268 + * If we can't lookup the host, play safe and assume it is OK.
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);
1279 + msg_info("%s: host %s: %s", myname, host, gai_strerror(error));
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));
1288 + msg_info("%s: addr %s", myname, hbuf);
1290 + if (own_inet_addr(res->ai_addr)) {
1291 + freeaddrinfo(res0);
1295 + freeaddrinfo(res0);
1297 + msg_info("%s: host %s: no match", myname, host);
1301 char *myname = "has_my_addr";
1302 struct in_addr addr;
1304 @@ -1202,6 +1253,7 @@
1305 msg_info("%s: host %s: no match", myname, host);
1311 /* i_am_mx - is this machine listed as MX relay */
1312 @@ -1794,7 +1846,7 @@
1313 static int reject_maps_rbl(SMTPD_STATE *state)
1315 char *myname = "reject_maps_rbl";
1316 - ARGV *octets = argv_split(state->addr, ".");
1318 VSTRING *query = vstring_alloc(100);
1319 char *saved_domains = mystrdup(var_maps_rbl_domains);
1320 char *bp = saved_domains;
1321 @@ -1806,17 +1858,29 @@
1322 int dns_status = DNS_FAIL;
1329 msg_info("%s: %s", myname, state->addr);
1332 - * IPv4 only for now
1336 + /* IPv4 only for now */
1337 if (inet_pton(AF_INET, state->addr, &a) != 1)
1338 return SMTPD_CHECK_DUNNO;
1339 + octets = argv_split(state->addr, ".");
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, ".");
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, ".");
1355 diff -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
1362 +/* Utility library. */
1365 +#include <mymalloc.h>
1366 +#include <valid_hostname.h>
1367 +#include <stringops.h>
1369 +/* Global library. */
1372 * Older systems don't have h_errno. Even modern systems don't have
1378 -/* Utility library. */
1381 -#include <mymalloc.h>
1382 -#include <valid_hostname.h>
1383 -#include <stringops.h>
1385 -/* Global library. */
1389 +#define GAI_STRERROR(error) \
1390 + ((error = EAI_SYSTEM) ? gai_strerror(error) : strerror(errno))
1393 /* Application-specific. */
1396 @@ -102,16 +106,23 @@
1398 void smtpd_peer_init(SMTPD_STATE *state)
1400 - struct sockaddr_in sin;
1401 - SOCKADDR_SIZE len = sizeof(sin);
1403 + struct sockaddr_storage ss;
1405 + struct sockaddr ss;
1406 + struct in_addr *in;
1410 + struct sockaddr *sa;
1411 + SOCKADDR_SIZE len;
1413 + sa = (struct sockaddr *)&ss;
1417 * Look up the peer address information.
1419 - if (getpeername(vstream_fileno(state->client),
1420 - (struct sockaddr *) & sin, &len) >= 0) {
1421 + if (getpeername(vstream_fileno(state->client), sa, &len) >= 0) {
1425 @@ -127,18 +138,51 @@
1427 * Look up and "verify" the client hostname.
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);
1434 + else if (errno == 0 && (sa->sa_family == AF_INET
1436 + || sa->sa_family == AF_INET6
1440 + char hbuf[NI_MAXHOST];
1441 + char abuf[NI_MAXHOST];
1442 + struct addrinfo hints, *rnull = NULL;
1444 + char abuf[sizeof("255.255.255.255") + 1];
1450 + (void)getnameinfo(sa, len, abuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
1452 + in = &((struct sockaddr_in *)sa)->sin_addr;
1453 + inet_ntop(AF_INET, in, abuf, sizeof(hbuf));
1455 + state->addr = mystrdup(abuf);
1457 + error = getnameinfo(sa, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD);
1460 + hp = gethostbyaddr((char *)in, sizeof(*in), AF_INET);
1463 + hbuf = mystrdup(hp->h_name);
1468 state->name = mystrdup("unknown");
1470 + state->peer_code = (error == EAI_AGAIN ? 4 : 5);
1472 state->peer_code = (h_errno == TRY_AGAIN ? 4 : 5);
1473 - } else if (!valid_hostname(hp->h_name, DONT_GRIPE)) {
1475 + } else if (!valid_hostname(hbuf, DONT_GRIPE)) {
1476 state->name = mystrdup("unknown");
1477 state->peer_code = 5;
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;
1484 @@ -150,16 +194,31 @@
1485 state->peer_code = code; \
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);
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));
1498 + /* memcmp() isn't needed if we use getaddrinfo */
1500 + freeaddrinfo(rnull);
1502 hp = gethostbyname(state->name); /* clobbers hp->name!! */
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);
1514 for (i = 0; /* void */ ; i++) {
1515 if (hp->h_addr_list[i] == 0) {
1516 msg_warn("%s: address not listed for hostname %s",
1517 @@ -167,12 +226,11 @@
1518 REJECT_PEER_NAME(state, 5);
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 */
1532 diff -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
1537 if (strncmp(argv[optind], "inet:", 5) == 0)
1539 - sock = inet_listen(argv[optind], backlog, BLOCKING);
1540 + sock = inet_listen(argv[optind], backlog, BLOCKING, 1);
1544 diff -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
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 \
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 \
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 \
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 \
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 \
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 \
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
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
1584 match_list.o: match_ops.h
1585 match_list.o: match_list.h
1586 match_ops.o: match_ops.c
1587 diff -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
1595 +/* trivial host and port extracter
1597 +/* #include <get_port.h>
1599 +/* char *get_port(data)
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.
1608 +/* If port not found return null pointer.
1612 +/* BSD Style (or BSD like) license.
1614 +/* Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
1618 +/* System libraries */
1620 +#include <sys_defs.h>
1621 +#include <string.h>
1623 +/* Utility library. */
1625 +#include "get_port.h"
1627 +/* get_port - extract port number from string */
1629 +char *get_port(char *data)
1631 + const char *escl=strchr(data,'[');
1632 + const char *sepl=strchr(data,':');
1633 + char *escr=strrchr(data,']');
1634 + char *sepr=strrchr(data,':');
1636 + /* extract from "[address]:port" or "[address]"*/
1639 + memmove(data, data + 1, strlen(data) - strlen(escr));
1640 + data[strlen(data) - strlen(escr) - 1] = 0;
1644 + return (*escr ? escr : NULL);
1646 + /* extract from "address:port" or "address" */
1647 + if ((sepl == sepr) && sepr && sepl)
1653 + /* return empty string */
1656 diff -Nur snapshot-20011127.orig/src/util/get_port.h snapshot-20011127/src/util/get_port.h
1657 --- snapshot-20011127.orig/src/util/get_port.h Thu Jan 1 01:00:00 1970
1658 +++ snapshot-20011127/src/util/get_port.h Mon Dec 3 14:16:39 2001
1660 +#ifndef _GET_PORT_H_INCLUDED_
1661 +#define _GET_PORT_H_INCLUDED_
1667 +/* trivial host and port extracter
1669 +/* #include <get_port.h>
1673 + /* External interface. */
1675 +extern char *get_port(char *);
1681 +/* BSD Style (or BSD like) license.
1683 +/* Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
1688 diff -Nur snapshot-20011127.orig/src/util/inet_addr_host.c snapshot-20011127/src/util/inet_addr_host.c
1689 --- snapshot-20011127.orig/src/util/inet_addr_host.c Fri Dec 11 19:55:35 1998
1690 +++ snapshot-20011127/src/util/inet_addr_host.c Mon Dec 3 14:16:39 2001
1692 #include <sys_defs.h>
1693 #include <netinet/in.h>
1694 #include <arpa/inet.h>
1695 +#include <sys/socket.h>
1697 +#include <stdlib.h>
1698 +#include <string.h>
1701 #define INADDR_NONE 0xffffffff
1704 #include <inet_addr_list.h>
1705 #include <inet_addr_host.h>
1710 /* inet_addr_host - look up address list for host */
1712 int inet_addr_host(INET_ADDR_LIST *addr_list, const char *hostname)
1716 + struct addrinfo hints, *res0, *res;
1718 + char buforhosta[1024];
1723 struct in_addr addr;
1725 int initial_count = addr_list->used;
1728 + memset(&hints, 0, sizeof(hints));
1729 + hints.ai_family = PF_UNSPEC;
1730 + hints.ai_socktype = SOCK_DGRAM;
1731 + error = getaddrinfo(hostname, NULL, &hints, &res0);
1733 + for (res = res0; res; res = res->ai_next) {
1734 + if(res->ai_family != AF_INET && res->ai_family != AF_INET6)
1736 + /* filter out address families that are not supported */
1737 + s = socket(res->ai_family, SOCK_DGRAM, 0);
1742 + inet_addr_list_append(addr_list, res->ai_addr);
1744 + freeaddrinfo(res0);
1747 if ((addr.s_addr = inet_addr(hostname)) != INADDR_NONE) {
1748 inet_addr_list_append(addr_list, &addr);
1751 inet_addr_list_append(addr_list,
1752 (struct in_addr *) * hp->h_addr_list++);
1756 return (addr_list->used - initial_count);
1765 INET_ADDR_LIST addr_list;
1767 + struct sockaddr *sa;
1768 + char hbuf[NI_MAXHOST];
1770 msg_vstream_init(argv[0], VSTREAM_ERR);
1773 if (inet_addr_host(&addr_list, *argv) == 0)
1774 msg_fatal("not found: %s", *argv);
1776 - for (i = 0; i < addr_list.used; i++)
1777 - vstream_printf("%s\n", inet_ntoa(addr_list.addrs[i]));
1778 + for (i = 0; i < addr_list.used; i++) {
1779 + sa = (struct sockaddr *)&addr_list.addrs[i];
1780 + getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0,
1782 + vstream_printf("%s\n", hbuf);
1784 vstream_fflush(VSTREAM_OUT);
1786 inet_addr_list_free(&addr_list);
1787 diff -Nur snapshot-20011127.orig/src/util/inet_addr_list.c snapshot-20011127/src/util/inet_addr_list.c
1788 --- snapshot-20011127.orig/src/util/inet_addr_list.c Tue Jul 31 20:13:41 2001
1789 +++ snapshot-20011127/src/util/inet_addr_list.c Mon Dec 3 14:21:19 2001
1791 #include <arpa/inet.h>
1797 +#include <string.h>
1798 +#include <sys/socket.h>
1801 /* Utility library. */
1809 + list->addrs = (struct sockaddr_storage *)
1811 list->addrs = (struct in_addr *)
1813 mymalloc(sizeof(*list->addrs) * list->size);
1816 /* inet_addr_list_append - append address to internet address list */
1819 +void inet_addr_list_append(INET_ADDR_LIST *list,
1820 + struct sockaddr * addr)
1822 + char *myname = "inet_addr_list_append";
1823 + char hbuf[NI_MAXHOST];
1825 + if (msg_verbose > 1) {
1826 + if (getnameinfo(addr, SA_LEN(addr), hbuf, sizeof(hbuf), NULL, 0,
1827 + NI_NUMERICHOST)) {
1828 + strncpy(hbuf, "??????", sizeof(hbuf));
1830 + msg_info("%s: %s", myname, hbuf);
1833 + if (list->used >= list->size)
1835 + list->addrs = (struct sockaddr_storage *)
1836 + myrealloc((char *) list->addrs,
1837 + sizeof(*list->addrs) * list->size);
1838 + memcpy(&list->addrs[list->used++], addr, SA_LEN(addr));
1841 void inet_addr_list_append(INET_ADDR_LIST *list, struct in_addr * addr)
1843 char *myname = "inet_addr_list_append";
1844 @@ -83,15 +117,22 @@
1845 sizeof(*list->addrs) * list->size);
1846 list->addrs[list->used++] = *addr;
1850 /* inet_addr_list_comp - compare addresses */
1852 static int inet_addr_list_comp(const void *a, const void *b)
1855 + if(((struct sockaddr*)a)->sa_family != ((struct sockaddr*)b)->sa_family)
1856 + return ( ((struct sockaddr*)a)->sa_family - ((struct sockaddr*)b)->sa_family );
1857 + return memcmp(a,b,SA_LEN((struct sockaddr*)a));
1859 const struct in_addr *a_addr = (const struct in_addr *) a;
1860 const struct in_addr *b_addr = (const struct in_addr *) b;
1862 return (a_addr->s_addr - b_addr->s_addr);
1866 /* inet_addr_list_uniq - weed out duplicates */
1867 diff -Nur snapshot-20011127.orig/src/util/inet_addr_list.h snapshot-20011127/src/util/inet_addr_list.h
1868 --- snapshot-20011127.orig/src/util/inet_addr_list.h Tue Jul 31 19:56:47 2001
1869 +++ snapshot-20011127/src/util/inet_addr_list.h Mon Dec 3 14:16:39 2001
1872 #include <netinet/in.h>
1876 +#define SA_LEN(x) (((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
1877 +#define SS_LEN(x) (((x).ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
1879 +#define SA_LEN(x) ((x)->sa_len)
1880 +#define SS_LEN(x) ((x).ss_len)
1885 * External interface.
1887 typedef struct INET_ADDR_LIST {
1888 int used; /* nr of elements in use */
1889 int size; /* actual list size */
1891 + struct sockaddr_storage *addrs; /* payload */
1893 struct in_addr *addrs; /* payload */
1897 extern void inet_addr_list_init(INET_ADDR_LIST *);
1898 extern void inet_addr_list_free(INET_ADDR_LIST *);
1899 extern void inet_addr_list_uniq(INET_ADDR_LIST *);
1902 +extern void inet_addr_list_append(INET_ADDR_LIST *, struct sockaddr *);
1904 extern void inet_addr_list_append(INET_ADDR_LIST *, struct in_addr *);
1909 diff -Nur snapshot-20011127.orig/src/util/inet_addr_local.c snapshot-20011127/src/util/inet_addr_local.c
1910 --- snapshot-20011127.orig/src/util/inet_addr_local.c Sun Feb 25 19:20:19 2001
1911 +++ snapshot-20011127/src/util/inet_addr_local.c Mon Dec 3 14:16:39 2001
1916 +#if defined(INET6) && (defined (LINUX) || defined (LINUX2))
1920 +#ifdef HAVE_GETIFADDRS
1921 +#include <ifaddrs.h>
1924 /* Utility library. */
1926 @@ -78,18 +85,104 @@
1928 int inet_addr_local(INET_ADDR_LIST *addr_list, INET_ADDR_LIST *mask_list)
1930 +#ifdef HAVE_GETIFADDRS
1931 + char *myname = "inet_addr_local";
1932 + struct ifaddrs *ifap, *ifa;
1933 + int initial_count = addr_list->used;
1934 + struct sockaddr *sa, *sam;
1937 + struct sockaddr_in6 addr6;
1940 + void *addr, *addrm;
1943 + if (getifaddrs(&ifap) < 0)
1944 + msg_fatal("%s: getifaddrs: %m", myname);
1946 + for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1947 + if (! (ifa->ifa_flags & IFF_RUNNING) || ifa->ifa_addr==NULL)
1949 + sa = ifa->ifa_addr;
1950 + sam = ifa->ifa_netmask;
1951 + switch (ifa->ifa_addr->sa_family) {
1954 + addr = (void *)&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
1955 + addrm = (void *)&((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
1961 + memcpy(&addr6, ifa->ifa_addr, ifa->ifa_addr->sa_len);
1962 + /* decode scoped address notation */
1963 + if ((IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) ||
1964 + IN6_IS_ADDR_SITELOCAL(&addr6.sin6_addr)) &&
1965 + addr6.sin6_scope_id == 0) {
1966 + addr6.sin6_scope_id = ntohs(addr6.sin6_addr.s6_addr[3] |
1967 + (unsigned int)addr6.sin6_addr.s6_addr[2] << 8);
1968 + addr6.sin6_addr.s6_addr[2] = addr6.sin6_addr.s6_addr[3] = 0;
1969 + sa = (struct sockaddr *)&addr6;
1979 + inet_addr_list_append(addr_list, sa);
1980 + if (mask_list != NULL)
1981 + inet_addr_list_append(mask_list, sam);
1983 + inet_addr_list_append(addr_list, (struct in_addr *)addr);
1984 + if (mask_list != NULL)
1985 + inet_addr_list_append(mask_list, (struct in_addr *)addrm);
1989 + freeifaddrs(ifap);
1990 + return (addr_list->used - initial_count);
1992 char *myname = "inet_addr_local";
1995 struct ifreq *the_end;
1997 - VSTRING *buf = vstring_alloc(1024);
1999 int initial_count = addr_list->used;
2000 struct in_addr addr;
2001 struct ifreq *ifr_mask;
2004 +#if defined (LINUX) || defined (LINUX2)
2005 +#define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"
2007 + char addr6p[8][5], addr6res[40], devname[20];
2008 + int plen, scope, dad_status, if_idx, gaierror;
2009 + struct addrinfo hints, *res, *res0;
2011 + struct sockaddr_in6 addr6;
2013 - if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
2016 + buf = vstring_alloc(1024);
2018 + if ((sock = socket(af, SOCK_DGRAM, 0)) < 0) {
2020 + if (af == AF_INET6)
2023 + msg_warn("%s: socket: %m", myname);
2028 msg_fatal("%s: socket: %m", myname);
2032 * Get the network interface list. XXX The socket API appears to have no
2033 @@ -126,10 +213,15 @@
2035 the_end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
2036 for (ifr = ifc.ifc_req; ifr < the_end;) {
2037 - if (ifr->ifr_addr.sa_family == AF_INET) { /* IP interface */
2038 + if ((ifr->ifr_addr.sa_family == AF_INET) &&
2039 + (ifr->ifr_addr.sa_family == af)) { /* IP interface */
2040 addr = ((struct sockaddr_in *) & ifr->ifr_addr)->sin_addr;
2041 if (addr.s_addr != INADDR_ANY) { /* has IP address */
2043 + inet_addr_list_append(addr_list, &ifr->ifr_addr);
2045 inet_addr_list_append(addr_list, &addr);
2048 ifr_mask = (struct ifreq *) mymalloc(IFREQ_SIZE(ifr));
2049 memcpy((char *) ifr_mask, (char *) ifr, IFREQ_SIZE(ifr));
2050 @@ -141,11 +233,61 @@
2055 + else if ((ifr->ifr_addr.sa_family == AF_INET6) &&
2056 + (ifr->ifr_addr.sa_family == af)) { /* IPv6 interface */
2057 + addr6 = *((struct sockaddr_in6 *) & ifr->ifr_addr);
2059 + /* decode scoped address notation */
2060 + if ((IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) ||
2061 + IN6_IS_ADDR_SITELOCAL(&addr6.sin6_addr)) &&
2062 + addr6.sin6_scope_id == 0) {
2063 + addr6.sin6_scope_id = ntohs(addr6.sin6_addr.s6_addr[3] |
2064 + (unsigned int)addr6.sin6_addr.s6_addr[2] << 8);
2065 + addr6.sin6_addr.s6_addr[2] = addr6.sin6_addr.s6_addr[3] = 0;
2068 + if (!(IN6_IS_ADDR_UNSPECIFIED(&addr6.sin6_addr)))
2069 + inet_addr_list_append(addr_list, (struct sockaddr *)&addr6);
2072 ifr = NEXT_INTERFACE(ifr);
2078 + if (af != AF_INET6) {
2080 + goto other_socket_type;
2082 +#if defined (LINUX) || defined (LINUX2)
2083 + if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) {
2084 + while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
2085 + addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4],
2086 + addr6p[5], addr6p[6], addr6p[7],
2087 + &if_idx, &plen, &scope, &dad_status, devname) != EOF) {
2088 + sprintf(addr6res, "%s:%s:%s:%s:%s:%s:%s:%s",
2089 + addr6p[0], addr6p[1], addr6p[2], addr6p[3],
2090 + addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
2091 + addr6res[sizeof(addr6res) - 1] = 0;
2092 + memset(&hints, 0, sizeof(hints));
2093 + hints.ai_flags = AI_NUMERICHOST;
2094 + hints.ai_family = AF_UNSPEC;
2095 + hints.ai_socktype = SOCK_DGRAM;
2096 + gaierror = getaddrinfo(addr6res, NULL, &hints, &res0);
2098 + for (res = res0; res; res = res->ai_next) {
2099 + inet_addr_list_append(addr_list, res->ai_addr);
2101 + freeaddrinfo(res0);
2107 return (addr_list->used - initial_count);
2113 INET_ADDR_LIST addr_list;
2114 INET_ADDR_LIST mask_list;
2116 + char abuf[NI_MAXHOST], mbuf[NI_MAXHOST];
2117 + struct sockaddr *sa;
2119 msg_vstream_init(argv[0], VSTREAM_ERR);
2121 @@ -172,8 +316,17 @@
2122 msg_warn("found only one active network interface");
2124 for (i = 0; i < addr_list.used; i++) {
2125 - vstream_printf("%s/", inet_ntoa(addr_list.addrs[i]));
2126 - vstream_printf("%s\n", inet_ntoa(mask_list.addrs[i]));
2127 + sa = (struct sockaddr *)&addr_list.addrs[i];
2128 + if (getnameinfo(sa, SA_LEN(sa), abuf, sizeof(abuf), NULL, 0,
2129 + NI_NUMERICHOST)) {
2130 + strncpy(abuf, "???", sizeof(abuf));
2132 + sa = (struct sockaddr *)&mask_list.addrs[i];
2133 + if (getnameinfo(sa, SA_LEN(sa), mbuf, sizeof(mbuf), NULL, 0,
2134 + NI_NUMERICHOST)) {
2135 + strncpy(mbuf, "???", sizeof(mbuf));
2137 + vstream_printf("%s/%s\n", abuf, mbuf);
2139 vstream_fflush(VSTREAM_OUT);
2140 inet_addr_list_free(&addr_list);
2141 diff -Nur snapshot-20011127.orig/src/util/inet_connect.c snapshot-20011127/src/util/inet_connect.c
2142 --- snapshot-20011127.orig/src/util/inet_connect.c Mon Nov 20 19:06:31 2000
2143 +++ snapshot-20011127/src/util/inet_connect.c Mon Dec 3 14:16:39 2001
2152 /* Utility library. */
2159 + struct addrinfo hints, *res, *res0;
2162 struct sockaddr_in sin;
2170 buf = inet_parse(addr, &host, &port);
2174 + memset(&hints, 0, sizeof(hints));
2175 + hints.ai_family = PF_UNSPEC;
2176 + hints.ai_socktype = SOCK_STREAM;
2177 + hints.ai_flags = AI_NUMERICHOST; /* find_inet_addr is numeric only */
2178 + if (getaddrinfo(host, port, &hints, &res0))
2179 + msg_fatal("host not found: %s", host);
2183 memset((char *) &sin, 0, sizeof(sin));
2184 sin.sin_family = AF_INET;
2185 sin.sin_addr.s_addr = find_inet_addr(host);
2186 sin.sin_port = find_inet_port(port, "tcp");
2192 + for (res = res0; res; res = res->ai_next) {
2193 + if ((res->ai_family != AF_INET) && (res->ai_family != AF_INET6))
2196 + sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
2199 + if (timeout > 0) {
2200 + non_blocking(sock, NON_BLOCKING);
2201 + if (timed_connect(sock, res->ai_addr, res->ai_addrlen, timeout) < 0) {
2206 + if (block_mode != NON_BLOCKING)
2207 + non_blocking(sock, block_mode);
2210 + non_blocking(sock, block_mode);
2211 + if (connect(sock, res->ai_addr, res->ai_addrlen) < 0
2212 + && errno != EINPROGRESS) {
2220 + freeaddrinfo(res0);
2224 * Create a client socket.
2232 diff -Nur snapshot-20011127.orig/src/util/inet_listen.c snapshot-20011127/src/util/inet_listen.c
2233 --- snapshot-20011127.orig/src/util/inet_listen.c Mon Nov 20 19:06:32 2000
2234 +++ snapshot-20011127/src/util/inet_listen.c Mon Dec 3 14:16:39 2001
2237 /* #include <listen.h>
2239 -/* int inet_listen(addr, backlog, block_mode)
2240 +/* int inet_listen(addr, backlog, block_mode, addinuse_fatal)
2241 /* const char *addr;
2245 #include <sys_defs.h>
2246 #include <sys/socket.h>
2247 #include <netinet/in.h>
2249 +#if (! __GLIBC__ >= 2 && __GLIBC_MINOR__ >=1 )
2250 +#include <netinet6/in6.h>
2253 #include <arpa/inet.h>
2255 #ifndef MAXHOSTNAMELEN
2256 #include <sys/param.h>
2262 @@ -77,35 +83,116 @@
2264 /* inet_listen - create inet-domain listener */
2266 -int inet_listen(const char *addr, int backlog, int block_mode)
2267 +int inet_listen(const char *addr, int backlog, int block_mode, int addrinuse_fatal)
2270 + struct addrinfo *res, *res0, hints;
2277 + struct sockaddr *ai_addr;
2278 + SOCKADDR_SIZE ai_addrlen;
2279 + struct ai *ai_next;
2280 + } *res, *res0, resbody;
2281 struct sockaddr_in sin;
2285 + int addrinuse = 0;
2290 + char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
2292 + char hbuf[sizeof("255.255.255.255") + 1];
2293 + char pbuf[sizeof("255.255.255.255") + 1];
2295 + char *cause = "unknown";
2298 * Translate address information to internal form.
2300 buf = inet_parse(addr, &host, &port);
2301 - memset((char *) &sin, 0, sizeof(sin));
2303 + memset(&hints, 0, sizeof(hints));
2304 + hints.ai_flags = AI_PASSIVE;
2305 + hints.ai_family = AF_UNSPEC;
2306 + hints.ai_socktype = SOCK_STREAM;
2307 + error = getaddrinfo(*host ? host : NULL, *port ? port : "0", &hints, &res0);
2309 + msg_fatal("getaddrinfo: %s", gai_strerror(error));
2313 + memset(&sin, 0, sizeof(sin));
2314 sin.sin_family = AF_INET;
2316 + sin.sin_len = sizeof(sin);
2318 sin.sin_port = find_inet_port(port, "tcp");
2319 sin.sin_addr.s_addr = (*host ? find_inet_addr(host) : INADDR_ANY);
2323 - * Create a listener socket.
2325 - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
2326 - msg_fatal("socket: %m");
2327 - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &t, sizeof(t)) < 0)
2328 - msg_fatal("setsockopt: %m");
2329 - if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
2330 - msg_fatal("bind %s port %d: %m", sin.sin_addr.s_addr == INADDR_ANY ?
2331 - "INADDR_ANY" : inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
2332 + memset(&resbody, 0, sizeof(resbody));
2333 + resbody.ai_socktype = SOCK_STREAM;
2334 + resbody.ai_family = AF_INET;
2335 + resbody.ai_addr = (struct sockaddr *)&sin;
2336 + resbody.ai_addrlen = sizeof(sin);
2342 + for (res = res0; res; res = res->ai_next) {
2343 + if ((res->ai_family != AF_INET) && (res->ai_family != AF_INET6))
2347 + * Create a listener socket.
2349 + if ((sock = socket(res->ai_family, res->ai_socktype, 0)) < 0) {
2354 + if (res->ai_family == AF_INET6 &&
2355 + setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &t, sizeof(t)) < 0) {
2356 + /* if kernel/libc don't support this simple ignore it
2357 + cause = "setsockopt(IPV6_V6ONLY)";
2365 + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &t, sizeof(t)) < 0) {
2366 + cause = "setsockopt(SO_REUSEADDR)";
2372 + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
2374 + if (errno == EADDRINUSE)
2382 + if (sock < 0 && (addrinuse_fatal || !addrinuse))
2383 + msg_fatal("%s: %m", cause);
2385 + freeaddrinfo(res0);
2389 non_blocking(sock, block_mode);
2390 if (listen(sock, backlog) < 0)
2391 msg_fatal("listen: %m");
2392 diff -Nur snapshot-20011127.orig/src/util/listen.h snapshot-20011127/src/util/listen.h
2393 --- snapshot-20011127.orig/src/util/listen.h Mon Mar 22 02:57:11 1999
2394 +++ snapshot-20011127/src/util/listen.h Mon Dec 3 14:16:39 2001
2396 * Listener external interface.
2398 extern int unix_listen(const char *, int, int);
2399 -extern int inet_listen(const char *, int, int);
2400 +extern int inet_listen(const char *, int, int, int);
2401 extern int fifo_listen(const char *, int, int);
2402 extern int stream_listen(const char *, int, int);
2404 diff -Nur snapshot-20011127.orig/src/util/match_list.c snapshot-20011127/src/util/match_list.c
2405 --- snapshot-20011127.orig/src/util/match_list.c Tue Nov 20 21:07:15 2001
2406 +++ snapshot-20011127/src/util/match_list.c Mon Dec 3 14:16:39 2001
2408 list = match_list_parse(list, vstring_str(buf));
2409 if (vstream_fclose(fp))
2410 msg_fatal("%s: read file %s: %m", myname, pattern);
2411 - } else if (strchr(pattern, ':') != 0) { /* type:table */
2412 + } else if ((strchr(pattern, ']') == 0) && (strchr(pattern, ':') != 0)) { /* type:table */
2413 for (cp = pattern; *cp == '!'; cp++)
2415 if (dict_handle(pattern) == 0)
2416 diff -Nur snapshot-20011127.orig/src/util/match_ops.c snapshot-20011127/src/util/match_ops.c
2417 --- snapshot-20011127.orig/src/util/match_ops.c Tue Nov 20 21:16:10 2001
2418 +++ snapshot-20011127/src/util/match_ops.c Mon Dec 3 14:16:39 2001
2420 #include <match_ops.h>
2421 #include <stringops.h>
2427 + * This program is free software; you can redistribute it and/or
2428 + * modify it under the terms of the GNU General Public License
2429 + * as published by the Free Software Foundation; either version
2430 + * 2 of the License, or (at your option) any later version.
2432 + * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
2435 + * Artur Frysiak <wiget@pld.org.pl>
2436 + * Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
2440 +#include <stdlib.h>
2441 +#include <unistd.h>
2442 +#include <syslog.h>
2444 +#include <sys/socket.h>
2445 +#include <netinet/in.h>
2446 +#include <string.h>
2448 +#include <arpa/inet.h>
2449 +#include <resolv.h>
2452 +#define AF_DECnet 12
2456 +#define PF_PACKET 17
2461 + unsigned char family;
2462 + unsigned char bytelen;
2463 + signed short bitlen;
2464 + unsigned int data[4];
2468 +int masked_match(char *, char *, char *);
2469 +int get_integer(int *, char *, int);
2470 +int get_addr_1(inet_prefix *, char *, int);
2471 +int get_prefix_1(inet_prefix *, char *, int);
2472 +int get_addr(inet_prefix *, char *, int);
2473 +int get_prefix(inet_prefix *, char *, int);
2474 +unsigned int get_addr32(char *);
2475 +int matches(char *, char *);
2476 +int inet_addr_match(inet_prefix *, inet_prefix *, int);
2477 +int mask_match(char *, char *, char *);
2479 +int get_integer(int *val, char *arg, int base)
2484 + if (!arg || !*arg)
2486 + res = strtol(arg, &ptr, base);
2487 + if (!ptr || ptr == arg || *ptr || res > INT_MAX || res < INT_MIN)
2493 +int get_addr_1(inet_prefix *addr, char *name, int family)
2496 + unsigned char *ap = (unsigned char*)addr->data;
2499 + memset(addr, 0, sizeof(*addr));
2501 + if (strcmp(name, "default") == 0 || strcmp(name, "any") == 0) {
2502 + if (family == AF_DECnet)
2504 + addr->family = family;
2505 + addr->bytelen = (family == AF_INET6 ? 16 : 4);
2506 + addr->bitlen = -1;
2510 + if (strchr(name, ':')) {
2511 + addr->family = AF_INET6;
2512 + if (family != AF_UNSPEC && family != AF_INET6)
2514 + if (inet_pton(AF_INET6, name, addr->data) <= 0)
2516 + addr->bytelen = 16;
2517 + addr->bitlen = -1;
2520 + addr->family = AF_INET;
2521 + if (family != AF_UNSPEC && family != AF_INET)
2523 + addr->bytelen = 4;
2524 + addr->bitlen = -1;
2525 + for (cp = name, i = 0; *cp; cp++) {
2526 + if (*cp <= '9' && *cp >= '0') {
2527 + ap[i] = 10*ap[i] + (*cp-'0');
2530 + if (*cp == '.' && ++i <= 3)
2537 +int get_prefix_1(inet_prefix *dst, char *arg, int family)
2543 + memset(dst, 0, sizeof(*dst));
2545 + if (strcmp(arg, "default") == 0 || strcmp(arg, "any") == 0) {
2546 + if (family == AF_DECnet)
2548 + dst->family = family;
2554 + slash = strchr(arg, '/');
2557 + err = get_addr_1(dst, arg, family);
2559 + switch(dst->family) {
2561 + dst->bitlen = 128;
2571 + if (get_integer(&plen, slash+1, 0) || plen > dst->bitlen) {
2575 + dst->bitlen = plen;
2584 +int get_addr(inet_prefix *dst, char *arg, int family)
2587 + if (family == AF_PACKET)
2590 + if (get_addr_1(dst, arg, family))
2595 +int get_prefix(inet_prefix *dst, char *arg, int family)
2598 + if (family == AF_PACKET)
2601 + if (get_prefix_1(dst, arg, family))
2606 +unsigned int get_addr32(char *name)
2609 + if (get_addr_1(&addr, name, AF_INET))
2611 + return addr.data[0];
2614 +int matches(char *cmd, char *pattern)
2616 + int len = strlen(cmd);
2617 + if (len > strlen(pattern))
2619 + return memcmp(pattern, cmd, len);
2622 +int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits)
2624 + unsigned int *a1 = a->data;
2625 + unsigned int *a2 = b->data;
2626 + int words = bits >> 0x05;
2631 + if (memcmp(a1, a2, words << 2))
2635 + unsigned int w1, w2;
2636 + unsigned int mask;
2641 + mask = htonl((0xffffffff) << (0x20 - bits));
2643 + if ((w1 ^ w2) & mask)
2650 +/* zero if matches */
2651 +int mask_match(char *network, char *cprefix, char *address)
2653 + inet_prefix *inetwork;
2654 + inet_prefix *iaddress;
2657 + if (!(network && address && cprefix))
2659 + prefix = strtol(cprefix, (char **)NULL, 10);
2660 + if ((prefix < 0) || (prefix > 128))
2662 + if ((strlen(network) == 0) || (strlen(address) == 0))
2665 + inetwork = malloc(sizeof(inet_prefix));
2666 + iaddress = malloc(sizeof(inet_prefix));
2668 + if ((get_addr(iaddress, address, AF_UNSPEC) >= 0)
2669 + && (get_addr(inetwork, network, AF_UNSPEC) >= 0))
2670 + ret = inet_addr_match(inetwork, iaddress, prefix);
2676 + /* 1 if matches */
2677 + /* return (!ret); */
2678 + /* 0 if matches */
2683 + * masked_match() - universal for IPv4 and IPv6 - 1 if matches
2685 +int masked_match(net_tok, mask_tok, string)
2691 + struct in6_addr in6[2];
2692 + char v4addr[2][INET_ADDRSTRLEN];
2697 + /* Check for NULL */
2698 + if (!(net_tok && mask_tok && string))
2699 + return 0; /* doesn't match!!! */
2701 + /* If IPv6 mapped convert to native-IPv4 */
2703 + if (inet_pton(AF_INET6, net_tok, &in6[0]) == 1 &&
2704 + inet_pton(AF_INET6, string, &in6[1]) == 1 &&
2705 + IN6_IS_ADDR_V4MAPPED(&in6[0]) && IN6_IS_ADDR_V4MAPPED(&in6[1])) {
2706 + plen = atoi(mask_tok);
2707 + if (32 < plen && plen < 129) {
2708 + sprintf(newmask, "%d", plen - 96);
2709 + mask_tok = newmask;
2712 + (void)inet_ntop(AF_INET, &in6[0].s6_addr[12], v4addr[0],
2713 + sizeof(v4addr[0]));
2714 + net_tok = v4addr[0];
2715 + (void)inet_ntop(AF_INET, &in6[1].s6_addr[12], v4addr[1],
2716 + sizeof(v4addr[1]));
2717 + string = v4addr[1];
2720 + return (!mask_match(net_tok, mask_tok, string));
2724 /* match_string - match a string literal */
2726 int match_string(int unused_flags, const char *string, const char *pattern)
2732 /* match_parse_mask - parse net/mask pattern */
2734 static int match_parse_mask(const char *pattern, unsigned long *net_bits,
2735 @@ -198,27 +500,55 @@
2741 /* match_hostaddr - match host by address */
2743 int match_hostaddr(int unused_flags, const char *addr, const char *pattern)
2745 char *myname = "match_hostaddr";
2747 + char *network, *mask, *escl, *escr, *patternx;
2748 + struct in6_addr in6;
2749 + char v4addr[INET_ADDRSTRLEN];
2752 unsigned long mask_bits;
2753 unsigned long net_bits;
2754 unsigned long addr_bits;
2758 msg_info("%s: %s ~? %s", myname, addr, pattern);
2761 + if (addr[strspn(addr, "01234567890./:abcdef")] != 0)
2763 if (addr[strspn(addr, "01234567890./:")] != 0)
2768 + patternx = mystrdup(pattern);
2769 + escl = strchr(patternx,'[');
2770 + escr = strrchr(patternx,']');
2771 + if (escl && escr) {
2773 + sprintf(patternx, "%s%s", escl + 1, escr + 1);
2774 + pattern = patternx;
2779 * Try dictionary lookup. This can be case insensitive. XXX Probably
2780 * should also try again after stripping least significant octets.
2782 - if (strchr(pattern, ':') != 0) {
2784 + if (!(escl && escr) && strchr(pattern, ':') != 0)
2786 + if (strchr(pattern, ':') != 0)
2789 if (dict_lookup(pattern, addr) != 0)
2791 if (dict_errno != 0)
2792 @@ -229,6 +559,12 @@
2794 * Try an exact match with the host address.
2797 + if (inet_pton(AF_INET6, addr, &in6) == 1 && IN6_IS_ADDR_V4MAPPED(&in6)) {
2798 + (void)inet_ntop(AF_INET, &in6.s6_addr[12], v4addr, sizeof(v4addr));
2802 if (strcasecmp(addr, pattern) == 0) {
2805 @@ -237,6 +573,20 @@
2806 * In a net/mask pattern, the mask is specified as the number of bits of
2810 + network = mystrdup(patternx);
2811 + mask = split_at(network, '/');
2813 + if (masked_match(network, mask, (char *)addr)) {
2823 if (match_parse_mask(pattern, &net_bits, &mask_shift)) {
2824 addr_bits = inet_addr(addr);
2825 if (addr_bits == INADDR_NONE)
2827 mask_bits = htonl((0xffffffff) << (BITS_PER_ADDR - mask_shift));
2828 return ((addr_bits & mask_bits) == (net_bits & mask_bits));
2833 diff -Nur snapshot-20011127.orig/src/util/sys_defs.h snapshot-20011127/src/util/sys_defs.h
2834 --- snapshot-20011127.orig/src/util/sys_defs.h Mon Dec 3 14:15:12 2001
2835 +++ snapshot-20011127/src/util/sys_defs.h Mon Dec 3 14:16:39 2001
2837 #define DEF_MAILBOX_LOCK "flock, dotlock"
2840 +#if ((defined(__NetBSD_Version__) && __NetBSD_Version__ >= 105000000) || defined(USAGI_LIBINET6))
2841 +#define HAVE_GETIFADDRS
2847 diff -Nur snapshot-20011127.orig/src/util/valid_hostname.c snapshot-20011127/src/util/valid_hostname.c
2848 --- snapshot-20011127.orig/src/util/valid_hostname.c Sun Jan 28 15:10:18 2001
2849 +++ snapshot-20011127/src/util/valid_hostname.c Mon Dec 3 14:16:39 2001
2855 +#include <netinet/in.h>
2856 +#include <sys/socket.h>
2857 +#include <arpa/inet.h>
2861 /* Utility library. */
2864 @@ -103,7 +110,23 @@
2865 msg_warn("%s: misplaced hyphen: %.100s", myname, name);
2871 + else if (ch == ':') {
2872 + struct addrinfo hints, *res;
2874 + memset(&hints, 0, sizeof(hints));
2875 + hints.ai_family = AF_INET6;
2876 + hints.ai_socktype = SOCK_STREAM; /*dummy*/
2877 + hints.ai_flags = AI_NUMERICHOST;
2878 + if (getaddrinfo(name, "0", &hints, &res) == 0) {
2879 + freeaddrinfo(res);
2887 msg_warn("%s: invalid character %d(decimal): %.100s",
2894 + struct addrinfo hints, *res;
2897 #define BYTES_NEEDED 4
2899 @@ -146,6 +172,17 @@
2900 msg_warn("%s: empty address", myname);
2905 + memset(&hints, 0, sizeof(hints));
2906 + hints.ai_family = AF_INET6;
2907 + hints.ai_socktype = SOCK_STREAM; /*dummy*/
2908 + hints.ai_flags = AI_NUMERICHOST;
2909 + if (getaddrinfo(addr, "0", &hints, &res) == 0) {
2910 + freeaddrinfo(res);
2916 * Scary code to avoid sscanf() overflow nasties.