[Pdns-dev] query-local-address configuration option (patch included)

mark at nedworks.org mark at nedworks.org
Mon Feb 24 14:23:01 CET 2003


As Bert pointed out on IRC, a bind() with sin_port set to 0 will
allocate a free local port itself, so there is no need to search for a
random free local port in pdns. Updated patch included.

-- 
Mark

<mark at nedworks.org>
-------------- next part --------------
diff -ur pdns-2.9.6/pdns/common_startup.cc pdns-2.9.6-mark2/pdns/common_startup.cc
--- pdns-2.9.6/pdns/common_startup.cc	Mon Jan 20 14:09:42 2003
+++ pdns-2.9.6-mark2/pdns/common_startup.cc	Mon Feb 24 14:06:52 2003
@@ -46,6 +46,7 @@
   arg().set("smtpredirector","Our smtpredir MX host")="a.misconfigured.powerdns.smtp.server";
   arg().set("local-address","Local IP address to which we bind")="0.0.0.0";
   arg().set("local-ipv6","Local IP address to which we bind")="";
+  arg().set("query-local-address","Source IP address for sending queries")="";
   arg().set("max-queue-length","Maximum queuelength before considering situation lost")="5000";
   arg().set("soa-serial-offset","Make sure that no SOA serial is less than this number")="0";
   arg().set("only-soa","Make sure that no SOA serial is less than this number")="org";
diff -ur pdns-2.9.6/pdns/communicator.cc pdns-2.9.6-mark2/pdns/communicator.cc
--- pdns-2.9.6/pdns/communicator.cc	Mon Feb 10 14:36:10 2003
+++ pdns-2.9.6-mark2/pdns/communicator.cc	Mon Feb 24 14:07:12 2003
@@ -345,7 +345,25 @@
   memset((char *)&sin,0, sizeof(sin));
   
   sin.sin_family = AF_INET;
-  sin.sin_addr.s_addr = INADDR_ANY;
+
+  // Bind to a specific IP (query-local-address) if specified
+  string querylocaladdress(arg()["query-local-address"]);
+  if (querylocaladdress=="") {
+    sin.sin_addr.s_addr = INADDR_ANY;
+  }
+  else
+  {
+    struct hostent *h=0;
+    h=gethostbyname(querylocaladdress.c_str());
+    if(!h) {
+      Utility::closesocket(d_nsock);
+      d_nsock=-1;	
+      throw AhuException("Unable to resolve query local address");
+    }
+
+    sin.sin_addr.s_addr = *(int*)h->h_addr;
+  }
+  
   int n=0;
   for(;n<10;n++) {
     sin.sin_port = htons(10000+(Utility::random()%50000));
@@ -356,7 +374,7 @@
   if(n==10) {
     Utility::closesocket(d_nsock);
     d_nsock=-1;
-    throw AhuException(string("binding dnsproxy socket: ")+strerror(errno));
+    throw AhuException(string("binding notify socket: ")+strerror(errno));
   }
   if( !Utility::setNonBlocking( d_nsock ))
     throw AhuException(string("error getting or setting notify socket non-blocking: ")+strerror(errno));
diff -ur pdns-2.9.6/pdns/resolver.cc pdns-2.9.6-mark2/pdns/resolver.cc
--- pdns-2.9.6/pdns/resolver.cc	Tue Feb 11 08:55:33 2003
+++ pdns-2.9.6-mark2/pdns/resolver.cc	Mon Feb 24 14:07:38 2003
@@ -216,7 +216,31 @@
   d_sock=socket(AF_INET,SOCK_STREAM,0);
   if(d_sock<0)
     throw ResolverException("Unable to make a TCP socket for resolver: "+stringerror());
-  
+
+  // Use query-local-address as source IP for queries, if specified.
+  string querylocaladdress(arg()["query-local-address"]);
+  if (querylocaladdress!="") {
+    struct sockaddr_in fromaddr;
+    struct hostent *h=0;
+
+    h = gethostbyname(querylocaladdress.c_str());
+    if(!h) {
+      Utility::closesocket(d_sock);
+      d_sock=-1;
+      throw ResolverException("Unable to resolve query local address");
+    }
+
+    fromaddr.sin_family = AF_INET;
+    fromaddr.sin_addr.s_addr = *(int*)h->h_addr;
+    fromaddr.sin_port = 0;
+
+    if (bind(d_sock, (struct sockaddr *)&fromaddr, sizeof(fromaddr)) < 0) {
+      Utility::closesocket(d_sock);
+      d_sock=-1;
+      throw ResolverException("Binding to query-local-address: "+stringerror());
+    }
+  }  
+    
   Utility::setNonBlocking( d_sock );
 
   int err;


More information about the Pdns-dev mailing list