]> granicus.if.org Git - pdns/commitdiff
further work
authorBert Hubert <bert.hubert@netherlabs.nl>
Wed, 1 Aug 2007 19:51:30 +0000 (19:51 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Wed, 1 Aug 2007 19:51:30 +0000 (19:51 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1077 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/nproxy.cc

index 143dfb9ee9ca910a4e18ce49cebc6893dd040efd..a4a569219a5716a4b35e9c39a3a777a388e155cc 100644 (file)
@@ -25,15 +25,20 @@ int g_pdnssocket;
 struct NotificationInFlight
 {
   ComboAddress source;
-  time_t sentAt;
+  time_t resentTime;
   string domain;
+  uint16_t origID, resentID;
+  int origSocket;
 };
 
+map<uint16_t, NotificationInFlight> g_nifs;
+
 void handleOutsideUDPPacket(int fd, boost::any&)
 try
 {
   char buffer[1500];
   struct NotificationInFlight nif;
+  nif.origSocket = fd;
 
   socklen_t socklen=sizeof(nif.source);
 
@@ -46,8 +51,10 @@ try
     
   string packet(buffer, res);
   MOADNSParser mdp(packet);
+  nif.domain = mdp.d_qname;
+  nif.origID = mdp.d_header.id;
 
-  cerr<<"Packet for: "<<mdp.d_qname<<endl;
+  cerr<<"Packet for: "<< nif.domain << endl;
 
   if(mdp.d_header.opcode != Opcode::Notify || mdp.d_qtype != QType::SOA) {
     cerr<<"Opcode: "<<mdp.d_header.opcode<<", != notify\n";
@@ -56,7 +63,55 @@ try
   
   vector<uint8_t> outpacket;
   DNSPacketWriter pw(outpacket, mdp.d_qname, mdp.d_qtype, 1, Opcode::Notify);
-  pw.getHeader()->id = random();
+
+  static uint16_t s_idpool;
+  pw.getHeader()->id = nif.resentID = s_idpool++;
+  
+  if(send(g_pdnssocket, &outpacket[0], outpacket.size(), 0) < 0) {
+    throw runtime_error("Unable to send notify to PowerDNS: "+stringerror());
+  }
+  nif.resentTime=time(0);
+  g_nifs[nif.resentID] = nif;
+
+}
+catch(exception &e)
+{
+  cerr<<"Error parsing incoming packet: "<<e.what()<<endl;
+}
+
+
+void handleInsideUDPPacket(int fd, boost::any&)
+try
+{
+  char buffer[1500];
+  struct NotificationInFlight nif;
+
+  socklen_t socklen=sizeof(nif.source);
+
+  int res=recvfrom(fd, buffer, sizeof(buffer), 0, (struct sockaddr*)&nif.source, &socklen);
+  if(!res)
+    return;
+
+  if(res < 0) 
+    throw runtime_error("reading packet from remote: "+stringerror());
+    
+  string packet(buffer, res);
+  MOADNSParser mdp(packet);
+
+  cerr<<"Inside packet for: "<<mdp.d_qname<<endl;
+
+  if(!g_nifs.count(mdp.d_header.id)) {
+    cerr<<"Response from inner PowerDNS with unknown ID "<<mdp.d_header.id<<endl;
+    return;
+  }
+  
+  nif=g_nifs[mdp.d_header.id];
+
+  vector<uint8_t> outpacket;
+  DNSPacketWriter pw(outpacket, mdp.d_qname, mdp.d_qtype, 1, Opcode::Notify);
+
+  static uint16_t s_idpool;
+  pw.getHeader()->id = nif.resentID = s_idpool++;
   
   if(send(g_pdnssocket, &outpacket[0], outpacket.size(), 0) < 0) {
     throw runtime_error("Unable to send notify to PowerDNS: "+stringerror());
@@ -68,6 +123,8 @@ catch(exception &e)
   cerr<<"Error parsing incoming packet: "<<e.what()<<endl;
 }
 
+
+
 int main(int argc, char** argv)
 try
 {
@@ -108,11 +165,11 @@ try
     if(::bind(sock,(sockaddr*) &local, local.getSocklen()) < 0)
       throw runtime_error("Binding socket for incoming packets: "+stringerror());
 
-    // add to fdmultiplexer for each socket
-
-    g_fdm.addReadFD(sock, handleOutsideUDPPacket);
+    g_fdm.addReadFD(sock, handleOutsideUDPPacket); // add to fdmultiplexer for each socket
   }
 
+  // create socket that talks to inner PowerDNS
+
   g_pdnssocket=socket(AF_INET, SOCK_DGRAM, 0);
   if(g_pdnssocket < 0)
     throw runtime_error("Creating socket for packets to PowerDNS: "+stringerror());
@@ -121,6 +178,8 @@ try
   if(connect(g_pdnssocket, (struct sockaddr*) &pdns, pdns.getSocklen()) < 0) 
     throw runtime_error("Failed to connect PowerDNS socket to address "+pdns.toString()+": "+stringerror());
 
+  g_fdm.addReadFD(g_pdnssocket, handleInsideUDPPacket);
+
   if(g_vm.count("chroot")) {
     if(chroot(g_vm["chroot"].as<string>().c_str()) < 0)
       throw runtime_error("while chrooting to "+g_vm["chroot"].as<string>());