diff options
author | Gilles Chehade <gilles@cvs.openbsd.org> | 2010-11-29 15:25:57 +0000 |
---|---|---|
committer | Gilles Chehade <gilles@cvs.openbsd.org> | 2010-11-29 15:25:57 +0000 |
commit | 71b46ba7782a17d5727aef137f7891f6c027471f (patch) | |
tree | bd40aa6c1666b74792d58e2bf86604345ccec3f9 /usr.sbin/smtpd/util.c | |
parent | 369cb22a97518580876a431f325eae15f50be5df (diff) |
replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)
diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)
Diffstat (limited to 'usr.sbin/smtpd/util.c')
-rw-r--r-- | usr.sbin/smtpd/util.c | 133 |
1 files changed, 128 insertions, 5 deletions
diff --git a/usr.sbin/smtpd/util.c b/usr.sbin/smtpd/util.c index 1021848f1b5..4d06eb3d5cc 100644 --- a/usr.sbin/smtpd/util.c +++ b/usr.sbin/smtpd/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.37 2010/11/28 13:56:43 gilles Exp $ */ +/* $OpenBSD: util.c,v 1.38 2010/11/29 15:25:56 gilles Exp $ */ /* * Copyright (c) 2000,2001 Markus Friedl. All rights reserved. @@ -26,6 +26,8 @@ #include <sys/stat.h> #include <sys/resource.h> +#include <netinet/in.h> + #include <ctype.h> #include <err.h> #include <errno.h> @@ -45,6 +47,9 @@ #include "smtpd.h" #include "log.h" +const char *log_in6addr(const struct in6_addr *); +const char *log_sockaddr(struct sockaddr *); + int bsnprintf(char *str, size_t size, const char *format, ...) { @@ -190,18 +195,101 @@ ss_to_text(struct sockaddr_storage *ss) buf[0] = '\0'; p = buf; + if (ss->ss_family == PF_INET) { + in_addr_t addr; + + addr = ((struct sockaddr_in *)ss)->sin_addr.s_addr; + bsnprintf(p, NI_MAXHOST, + "%d.%d.%d.%d", + addr & 0xff, + (addr >> 8) & 0xff, + (addr >> 16) & 0xff, + (addr >> 24) & 0xff); + } + if (ss->ss_family == PF_INET6) { + struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)ss; + struct in6_addr *in6_addr; + strlcpy(buf, "IPv6:", sizeof(buf)); p = buf + 5; + in6_addr = &in6->sin6_addr; + bsnprintf(p, NI_MAXHOST, "%s", log_in6addr(in6_addr)); } - if (getnameinfo((struct sockaddr *)ss, ss->ss_len, p, - NI_MAXHOST, NULL, 0, NI_NUMERICHOST)) - fatalx("ss_to_text: getnameinfo"); - return (buf); } +char * +ss_to_ptr(struct sockaddr_storage *ss) +{ + static char buffer[1024]; + + /* we need to construct a PTR query */ + switch (ss->ss_family) { + case AF_INET: { + in_addr_t addr; + + addr = ((struct sockaddr_in *)ss)->sin_addr.s_addr; + + bsnprintf(buffer, sizeof (buffer), + "%d.%d.%d.%d.in-addr.arpa", + (addr >> 24) & 0xff, + (addr >> 16) & 0xff, + (addr >> 8) & 0xff, + addr & 0xff); + break; + } + case AF_INET6: { + struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)ss; + struct in6_addr *in6_addr; + + in6_addr = &in6->sin6_addr; + bsnprintf(buffer, sizeof (buffer), + "%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d." + "%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d." + "ip6.arpa", + in6_addr->s6_addr[15] & 0xf, + (in6_addr->s6_addr[15] >> 4) & 0xf, + in6_addr->s6_addr[14] & 0xf, + (in6_addr->s6_addr[14] >> 4) & 0xf, + in6_addr->s6_addr[13] & 0xf, + (in6_addr->s6_addr[13] >> 4) & 0xf, + in6_addr->s6_addr[12] & 0xf, + (in6_addr->s6_addr[12] >> 4) & 0xf, + in6_addr->s6_addr[11] & 0xf, + (in6_addr->s6_addr[11] >> 4) & 0xf, + in6_addr->s6_addr[10] & 0xf, + (in6_addr->s6_addr[10] >> 4) & 0xf, + in6_addr->s6_addr[9] & 0xf, + (in6_addr->s6_addr[9] >> 4) & 0xf, + in6_addr->s6_addr[8] & 0xf, + (in6_addr->s6_addr[8] >> 4) & 0xf, + in6_addr->s6_addr[7] & 0xf, + (in6_addr->s6_addr[7] >> 4) & 0xf, + in6_addr->s6_addr[6] & 0xf, + (in6_addr->s6_addr[6] >> 4) & 0xf, + in6_addr->s6_addr[5] & 0xf, + (in6_addr->s6_addr[5] >> 4) & 0xf, + in6_addr->s6_addr[4] & 0xf, + (in6_addr->s6_addr[4] >> 4) & 0xf, + in6_addr->s6_addr[3] & 0xf, + (in6_addr->s6_addr[3] >> 4) & 0xf, + in6_addr->s6_addr[2] & 0xf, + (in6_addr->s6_addr[2] >> 4) & 0xf, + in6_addr->s6_addr[1] & 0xf, + (in6_addr->s6_addr[1] >> 4) & 0xf, + in6_addr->s6_addr[0] & 0xf, + (in6_addr->s6_addr[0] >> 4) & 0xf); + break; + } + default: + fatalx("dns_query_ptr"); + } + + return buffer; +} + int valid_message_id(char *mid) { @@ -519,3 +607,38 @@ session_socket_error(int fd) return (error); } + +const char * +log_in6addr(const struct in6_addr *addr) +{ + struct sockaddr_in6 sa_in6; + u_int16_t tmp16; + + bzero(&sa_in6, sizeof(sa_in6)); + sa_in6.sin6_len = sizeof(sa_in6); + sa_in6.sin6_family = AF_INET6; + memcpy(&sa_in6.sin6_addr, addr, sizeof(sa_in6.sin6_addr)); + + /* XXX thanks, KAME, for this ugliness... adopted from route/show.c */ + if (IN6_IS_ADDR_LINKLOCAL(&sa_in6.sin6_addr) || + IN6_IS_ADDR_MC_LINKLOCAL(&sa_in6.sin6_addr)) { + memcpy(&tmp16, &sa_in6.sin6_addr.s6_addr[2], sizeof(tmp16)); + sa_in6.sin6_scope_id = ntohs(tmp16); + sa_in6.sin6_addr.s6_addr[2] = 0; + sa_in6.sin6_addr.s6_addr[3] = 0; + } + + return (log_sockaddr((struct sockaddr *)&sa_in6)); +} + +const char * +log_sockaddr(struct sockaddr *sa) +{ + static char buf[NI_MAXHOST]; + + if (getnameinfo(sa, sa->sa_len, buf, sizeof(buf), NULL, 0, + NI_NUMERICHOST)) + return ("(unknown)"); + else + return (buf); +} |