chiark / gitweb /
Make adns__sockaddr_ntop use a caller-supplied buffer.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 17 May 2014 12:17:07 +0000 (13:17 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 17 May 2014 12:17:07 +0000 (13:17 +0100)
Using an internal static buffer violates the (weak) thread-safety
guarantees.

src/event.c
src/general.c
src/internal.h
src/setup.c

index 7050ca8287a50a02089825207c664d564cd4a1cb..43b9637c47d7ec0e63d31defdacbd8d23c65402d 100644 (file)
@@ -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);
index cbe735a29040b2bc634a20c3373085ce052241db..7703254500c51b87bea4af19056f4f14e6f16a88 100644 (file)
 
 /* 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";
   }
 
index f8f34c7cd3ade2deaea86dea414e04fdd0967e65..bddb1979025d03d14b681e2c862fe194eaf8281b 100644 (file)
@@ -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);
index 21db53cd1db95d80c2b968ab9dedb7ada4c00a7d..267f3dad3df10b8cbe5e334ec8b808ce3a7ad37a 100644 (file)
@@ -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; i<ads->nservers; 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);
 }