]> granicus.if.org Git - pdns/commitdiff
make sure that we can bind to IPv6 link-local addresses. Feature suggested by Darren...
authorBert Hubert <bert.hubert@netherlabs.nl>
Tue, 25 May 2010 20:26:23 +0000 (20:26 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Tue, 25 May 2010 20:26:23 +0000 (20:26 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1620 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/iputils.hh
pdns/misc.cc
pdns/misc.hh
pdns/pdns_recursor.cc

index ff0709bb42a929ad36419358d441c53493f565fb..5b9ecb302b255c16fa45f2fe71e5a69782bfb520 100644 (file)
@@ -115,7 +115,7 @@ union ComboAddress {
     sin4.sin_port=htons(port);
     if(!IpToU32(str, (uint32_t*)&sin4.sin_addr.s_addr)) {
       sin6.sin6_family = AF_INET6;
-      if(Utility::inet_pton(AF_INET6, str.c_str(), &sin6.sin6_addr) <= 0)
+      if(makeIPv6sockaddr(str, &sin6) < 0)
         throw AhuException("Unable to convert presentation address '"+ str +"'"); 
     }
   }
@@ -186,7 +186,7 @@ inline ComboAddress makeComboAddress(const string& str)
   address.sin4.sin_family=AF_INET;
   if(Utility::inet_pton(AF_INET, str.c_str(), &address.sin4.sin_addr) <= 0) {
     address.sin4.sin_family=AF_INET6;
-    if(Utility::inet_pton(AF_INET6, str.c_str(), &address.sin6.sin6_addr) <= 0)
+    if(makeIPv6sockaddr(str, &address.sin6) < 0)
       throw NetmaskException("Unable to convert '"+str+"' to a netmask");        
   }
   return address;
index 586f4a8d55495019bfcbf7ec10dee465bf2b0b9c..36daa8a6c189b84183ad91e024418cc22c98f25d 100644 (file)
@@ -665,3 +665,23 @@ string dotConcat(const std::string& a, const std::string &b)
   else 
     return a+"."+b;
 }
+
+int makeIPv6sockaddr(const std::string& addr, struct sockaddr_in6* ret)
+{
+  struct addrinfo* res;
+  struct addrinfo hints;
+  memset(&hints, 0, sizeof(hints));
+  
+  hints.ai_family = AF_INET6;
+  hints.ai_flags = AI_NUMERICHOST;
+  
+  if(getaddrinfo(addr.c_str(), 0, &hints, &res) < 0) {
+    perror("getaddrinfo");
+    return -1;
+  }
+  
+  memcpy(ret, res->ai_addr, sizeof(*ret));
+  
+  freeaddrinfo(res);
+  return 0;
+}
index 010c21a11de168b214641a2f6a7570e4034f3c59..ce83248eb3737e30b7e81e196042b1611aa0a0c1 100644 (file)
@@ -383,5 +383,5 @@ void seedRandom(const string& source);
 string makeRelative(const std::string& fqdn, const std::string& zone);
 string labelReverse(const std::string& qname);
 std::string dotConcat(const std::string& a, const std::string &b);
-
+int makeIPv6sockaddr(const std::string& addr, struct sockaddr_in6* ret);
 #endif
index ac9d7d44d21d12ea0bea4f0dc7b4d428d4147bc1..7b8191a9d1f1f45d86d207744e7ba60ea2b38bf3 100644 (file)
@@ -903,7 +903,7 @@ void makeTCPServerSockets()
     sin.sin4.sin_family = AF_INET;
     if(!IpToU32(st.host, (uint32_t*)&sin.sin4.sin_addr.s_addr)) {
       sin.sin6.sin6_family = AF_INET6;
-      if(Utility::inet_pton(AF_INET6, st.host.c_str(), &sin.sin6.sin6_addr) <= 0)
+      if(makeIPv6sockaddr(st.host, &sin.sin6) < 0)
         throw AhuException("Unable to resolve local address for TCP server on '"+ st.host +"'"); 
     }
 
@@ -967,7 +967,7 @@ void makeUDPServerSockets()
     sin.sin4.sin_family = AF_INET;
     if(!IpToU32(st.host.c_str() , (uint32_t*)&sin.sin4.sin_addr.s_addr)) {
       sin.sin6.sin6_family = AF_INET6;
-      if(Utility::inet_pton(AF_INET6, st.host.c_str(), &sin.sin6.sin6_addr) <= 0)
+      if(makeIPv6sockaddr(st.host, &sin.sin6) < 0)
         throw AhuException("Unable to resolve local address for UDP server on '"+ st.host +"'"); 
     }