From: Mark Wooding Date: Sat, 17 May 2014 12:17:07 +0000 (+0100) Subject: Make adns__sockaddr_ntop use a caller-supplied buffer. X-Git-Tag: wip.base.getaddrinfo~12 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/adns/commitdiff_plain/62e2764d90d496e46a62e6a2bc1ff1c5ecda908d Make adns__sockaddr_ntop use a caller-supplied buffer. Using an internal static buffer violates the (weak) thread-safety guarantees. --- diff --git a/src/event.c b/src/event.c index 7050ca8..43b9637 100644 --- a/src/event.c +++ b/src/event.c @@ -339,6 +339,7 @@ int adns__pollfds(adns_state ads, struct pollfd pollfds_buf[MAX_POLLFDS]) { int adns_processreadable(adns_state ads, int fd, const struct timeval *now) { int want, dgramlen, r, i, udpaddrlen, serv, old_skip; byte udpbuf[DNS_MAXUDP]; + char addrbuf[MAX_ADDRSTRLEN]; struct udpsocket *udp; adns_sockaddr udpaddr; @@ -414,7 +415,7 @@ int adns_processreadable(adns_state ads, int fd, const struct timeval *now) { serv++); if (serv >= ads->nservers) { adns__warn(ads,-1,0,"datagram received from unknown nameserver %s", - adns__sockaddr_ntoa(&udpaddr.sa, udpaddrlen)); + adns__sockaddr_ntoa(&udpaddr.sa, udpaddrlen, addrbuf)); continue; } adns__procdgram(ads,udpbuf,r,serv,0,*now); diff --git a/src/general.c b/src/general.c index cbe735a..7703254 100644 --- a/src/general.c +++ b/src/general.c @@ -38,12 +38,11 @@ /* Core diagnostic functions */ -const char *adns__sockaddr_ntoa(struct sockaddr *sa, size_t n) +const char *adns__sockaddr_ntoa(struct sockaddr *sa, size_t n, char *buf) { - static char buf[64]; int err; - err = getnameinfo(sa, n, buf, sizeof(buf), 0, 0, NI_NUMERICHOST); + err = getnameinfo(sa, n, buf, MAX_ADDRSTRLEN, 0, 0, NI_NUMERICHOST); assert(!err); return buf; } @@ -61,6 +60,7 @@ void adns__lprintf(adns_state ads, const char *fmt, ...) { void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent, int serv, adns_query qu, const char *fmt, va_list al) { + char buf[MAX_ADDRSTRLEN]; const char *bef, *aft; vbuf vb; @@ -96,7 +96,7 @@ void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent, if (serv>=0) { adns__lprintf(ads,"%sNS=%s",bef, adns__sockaddr_ntoa(&ads->servers[serv].addr.sa, - ads->servers[serv].len)); + ads->servers[serv].len, buf)); bef=", "; aft=")\n"; } diff --git a/src/internal.h b/src/internal.h index f8f34c7..bddb197 100644 --- a/src/internal.h +++ b/src/internal.h @@ -73,6 +73,7 @@ typedef unsigned char byte; #define DNS_IP6_ARPA "ip6", "arpa" #define ADDR_MAXRRTYPES 2 +#define MAX_ADDRSTRLEN 64 #define STRINGIFY(x) REALLY_STRINGIFY(x) #define REALLY_STRINGIFY(x) #x @@ -411,7 +412,9 @@ int adns__setnonblock(adns_state ads, int fd); /* => errno value */ /* From general.c: */ -const char *adns__sockaddr_ntoa(struct sockaddr *sa, size_t n); +const char *adns__sockaddr_ntoa(struct sockaddr *sa, size_t n, char *buf); +/* Buffer must be at least MAX_ADDRSTRLEN bytes long. */ + void adns__vlprintf(adns_state ads, const char *fmt, va_list al); void adns__lprintf(adns_state ads, const char *fmt, ...) PRINTFFORMAT(2,3); diff --git a/src/setup.c b/src/setup.c index 21db53c..267f3da 100644 --- a/src/setup.c +++ b/src/setup.c @@ -60,26 +60,27 @@ static void addserver(adns_state ads, struct sockaddr *sa, int n) { int i; adns_rr_addr *ss; const afinfo *ai; + char buf[MAX_ADDRSTRLEN]; ai = find_afinfo(sa->sa_family); if (!ai) { adns__diag(ads,-1,0, "nameserver %s for unknown address family %d ignored", - adns__sockaddr_ntoa(sa, n), sa->sa_family); + adns__sockaddr_ntoa(sa, n, buf), sa->sa_family); } for (i=0; inservers; i++) { if (ads->servers[i].addr.sa.sa_family == sa->sa_family && ai->sockaddr_equalp(sa, &ads->servers[i].addr.sa)) { adns__debug(ads,-1,0,"duplicate nameserver %s ignored", - adns__sockaddr_ntoa(sa, n)); + adns__sockaddr_ntoa(sa, n, buf)); return; } } if (ads->nservers>=MAXSERVERS) { adns__diag(ads,-1,0,"too many nameservers, ignoring %s", - adns__sockaddr_ntoa(sa, n)); + adns__sockaddr_ntoa(sa, n, buf)); return; } @@ -134,6 +135,7 @@ static int nextword(const char **bufp_io, const char **word_r, int *l_r) { static void ccf_nameserver(adns_state ads, const char *fn, int lno, const char *buf) { struct addrinfo *ai, ai_hint = { 0 }; + char addrbuf[MAX_ADDRSTRLEN]; int err; ai_hint.ai_family = AF_UNSPEC; @@ -148,7 +150,7 @@ static void ccf_nameserver(adns_state ads, const char *fn, } adns__debug(ads,-1,0,"using nameserver %s", - adns__sockaddr_ntoa(ai->ai_addr, ai->ai_addrlen)); + adns__sockaddr_ntoa(ai->ai_addr, ai->ai_addrlen, addrbuf)); addserver(ads, ai->ai_addr, ai->ai_addrlen); freeaddrinfo(ai); }