Browse Source

make A, AAAA and NS sets configurable in parkinglot
(SOA still fixed though)


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/jelte-datadef@395 e5f2f494-b856-4b98-b285-d166d9295462

Jelte Jansen 15 years ago
parent
commit
91d64d64b9

+ 19 - 8
src/bin/parkinglot/main.cc

@@ -49,7 +49,7 @@ const int DNSPORT = 5300;
 
 
 /* need global var for config/command handlers.
 /* need global var for config/command handlers.
  * todo: turn this around, and put handlers in the parkinglot
  * todo: turn this around, and put handlers in the parkinglot
- * class itself */
+ * class itself? */
 ParkingLot plot = ParkingLot(DNSPORT);
 ParkingLot plot = ParkingLot(DNSPORT);
 
 
 static void
 static void
@@ -72,6 +72,24 @@ my_config_handler(ISC::Data::ElementPtr config)
         // todo: what to do with port change. restart automatically?
         // todo: what to do with port change. restart automatically?
         // ignore atm
         // ignore atm
     }
     }
+    if (config->contains("a_records")) {
+        plot.clearARecords();
+        BOOST_FOREACH(ISC::Data::ElementPtr rel, config->get("a_records")->list_value()) {
+            plot.addARecord(rel->string_value());
+        }
+    }
+    if (config->contains("aaaa_records")) {
+        plot.clearAAAARecords();
+        BOOST_FOREACH(ISC::Data::ElementPtr rel, config->get("aaaa_records")->list_value()) {
+            plot.addAAAARecord(rel->string_value());
+        }
+    }
+    if (config->contains("ns_records")) {
+        plot.clearNSRecords();
+        BOOST_FOREACH(ISC::Data::ElementPtr rel, config->get("ns_records")->list_value()) {
+            plot.addNSRecord(rel->string_value());
+        }
+    }
     return ISC::Data::Element::create_from_string("{ \"result\": [0] }");
     return ISC::Data::Element::create_from_string("{ \"result\": [0] }");
 }
 }
 
 
@@ -114,16 +132,11 @@ main(int argc, char* argv[]) {
 
 
     // initialize command channel
     // initialize command channel
     CommandSession cs = CommandSession(PROGRAM, SPECFILE, my_config_handler, my_command_handler);
     CommandSession cs = CommandSession(PROGRAM, SPECFILE, my_config_handler, my_command_handler);
-    //cs.set_config_handler(my_config_handler);
-    //cs.set_command_handler(my_command_handler);
     
     
     // main server loop
     // main server loop
     fd_set fds;
     fd_set fds;
     int ps = plot.getSocket();
     int ps = plot.getSocket();
     int ss = cs.getSocket();
     int ss = cs.getSocket();
-    /*BOOST_FOREACH(std::string zone, cs.getZones()) {
-        plot.serve(zone);
-    }*/
     int nfds = max(ps, ss) + 1;
     int nfds = max(ps, ss) + 1;
     int counter = 0;
     int counter = 0;
 
 
@@ -145,8 +158,6 @@ main(int argc, char* argv[]) {
         /* isset not really necessary, but keep it for now */
         /* isset not really necessary, but keep it for now */
         if (FD_ISSET(ss, &fds)) {
         if (FD_ISSET(ss, &fds)) {
             cs.check_command();
             cs.check_command();
-            //pair<string, ISC::Data::ElementPtr> cmd = cs.getCommand(counter);
-            //plot.command(cmd);
         }
         }
     }
     }
 
 

+ 47 - 10
src/bin/parkinglot/parkinglot.cc

@@ -42,12 +42,46 @@ using namespace isc::dns::Rdata::IN;
 using namespace isc::dns::Rdata::Generic;
 using namespace isc::dns::Rdata::Generic;
 using namespace ISC::Data;
 using namespace ISC::Data;
 
 
+void
+ParkingLot::addARecord(std::string data) {
+    a_records.push_back(Rdata::RdataPtr(new A(data)));
+}
+
+void
+ParkingLot::addAAAARecord(std::string data) {
+    aaaa_records.push_back(Rdata::RdataPtr(new AAAA(data)));
+}
+
+void
+ParkingLot::addNSRecord(std::string data) {
+    ns_records.push_back(Rdata::RdataPtr(new NS(data)));
+}
+
+void
+ParkingLot::setSOARecord(isc::dns::Rdata::RdataPtr soa_record) {
+}
+
+void
+ParkingLot::setDefaultZoneData() {
+    clearARecords();
+    clearAAAARecords();
+    clearNSRecords();
+
+    addARecord("127.0.0.1");
+    addAAAARecord("::1");
+    addNSRecord("ns1.parking.example");
+    addNSRecord("ns2.parking.example");
+    addNSRecord("ns3.parking.example");
+}
+
 ParkingLot::ParkingLot(int port) {
 ParkingLot::ParkingLot(int port) {
-    ns1 = Rdata::RdataPtr(new NS("ns1.parking.example"));
+    setDefaultZoneData();
+    /*ns1 = Rdata::RdataPtr(new NS("ns1.parking.example"));
     ns2 = Rdata::RdataPtr(new NS("ns2.parking.example"));
     ns2 = Rdata::RdataPtr(new NS("ns2.parking.example"));
     ns3 = Rdata::RdataPtr(new NS("ns3.parking.example"));
     ns3 = Rdata::RdataPtr(new NS("ns3.parking.example"));
     a = Rdata::RdataPtr(new A("127.0.0.1"));
     a = Rdata::RdataPtr(new A("127.0.0.1"));
     aaaa = Rdata::RdataPtr(new AAAA("::1"));
     aaaa = Rdata::RdataPtr(new AAAA("::1"));
+    */
     soa = Rdata::RdataPtr(new SOA("parking.example", "noc.parking.example",
     soa = Rdata::RdataPtr(new SOA("parking.example", "noc.parking.example",
                                         1, 1800, 900, 604800, TTL(86400)));
                                         1, 1800, 900, 604800, TTL(86400)));
 
 
@@ -154,23 +188,26 @@ ParkingLot::processMessage() {
             msg.setRcode(Message::RCODE_NOERROR);
             msg.setRcode(Message::RCODE_NOERROR);
             RRset* nsset = new RRset(query->getName(), RRClass::IN,
             RRset* nsset = new RRset(query->getName(), RRClass::IN,
                                      RRType::NS, TTL(3600));
                                      RRType::NS, TTL(3600));
-
-            nsset->addRdata(ns1);
-            nsset->addRdata(ns2);
-            nsset->addRdata(ns3);
+            BOOST_FOREACH(isc::dns::Rdata::RdataPtr ns, ns_records) {
+                nsset->addRdata(ns);
+            }
 
 
             if (query->getType() == RRType::NS)
             if (query->getType() == RRType::NS)
                 msg.addRRset(SECTION_ANSWER, RRsetPtr(nsset));
                 msg.addRRset(SECTION_ANSWER, RRsetPtr(nsset));
             else if (query->getType() == RRType::A) {
             else if (query->getType() == RRType::A) {
                 msg.addRRset(SECTION_AUTHORITY, RRsetPtr(nsset));
                 msg.addRRset(SECTION_AUTHORITY, RRsetPtr(nsset));
-                RR arr(query->getName(), RRClass::IN, RRType::A, TTL(3600), a);
 
 
-                msg.addRR(SECTION_ANSWER, arr);
+                BOOST_FOREACH(isc::dns::Rdata::RdataPtr a, a_records) {
+                    RR arr(query->getName(), RRClass::IN, RRType::A, TTL(3600), a);
+                    msg.addRR(SECTION_ANSWER, arr);
+                }
             } else if (query->getType() == RRType::AAAA) {
             } else if (query->getType() == RRType::AAAA) {
                 msg.addRRset(SECTION_AUTHORITY, RRsetPtr(nsset));
                 msg.addRRset(SECTION_AUTHORITY, RRsetPtr(nsset));
-                RR aaaarr(query->getName(), RRClass::IN, RRType::AAAA,
-                          TTL(3600), aaaa);
-                msg.addRR(SECTION_ANSWER, aaaarr);
+                BOOST_FOREACH(isc::dns::Rdata::RdataPtr aaaa, aaaa_records) {
+                    RR aaaarr(query->getName(), RRClass::IN, RRType::AAAA,
+                              TTL(3600), aaaa);
+                    msg.addRR(SECTION_ANSWER, aaaarr);
+                }
             } else {
             } else {
                 RR soarr(query->getName(), RRClass::IN, RRType::SOA,
                 RR soarr(query->getName(), RRClass::IN, RRType::SOA,
                          TTL(3600), soa);
                          TTL(3600), soa);

+ 15 - 2
src/bin/parkinglot/parkinglot.h

@@ -29,9 +29,22 @@ public:
     void command(std::pair<std::string,ISC::Data::ElementPtr>);
     void command(std::pair<std::string,ISC::Data::ElementPtr>);
     void serve(std::string zone_name);
     void serve(std::string zone_name);
     void clear_zones() { zones.clear_zones(); };
     void clear_zones() { zones.clear_zones(); };
-    
+
+    void clearARecords() { a_records.clear(); };
+    void clearAAAARecords() { aaaa_records.clear(); };
+    void clearNSRecords() { ns_records.clear(); };
+
+    void addARecord(std::string data);
+    void addAAAARecord(std::string data);
+    void addNSRecord(std::string data);
+
+    void setSOARecord(isc::dns::Rdata::RdataPtr soa_record);
+
 private:
 private:
-    isc::dns::Rdata::RdataPtr ns1, ns2, ns3, a, aaaa, soa;
+    void setDefaultZoneData();
+
+    std::vector<isc::dns::Rdata::RdataPtr> a_records, aaaa_records, ns_records;
+    isc::dns::Rdata::RdataPtr soa;
     ZoneSet zones;
     ZoneSet zones;
     int sock;
     int sock;
 };
 };

+ 36 - 0
src/bin/parkinglot/parkinglot.spec

@@ -19,6 +19,42 @@
           "item_optional": false,
           "item_optional": false,
           "item_default": ""
           "item_default": ""
         }
         }
+      },
+      {
+        "item_name": "a_records",
+        "item_type": "list",
+        "item_optional": false,
+        "item_default": [ "127.0.0.1" ],
+        "list_item_spec": {
+          "item_name": "address",
+          "item_type": "string",
+          "item_optional": false,
+          "item_default": ""
+        }
+      },
+      {
+        "item_name": "aaaa_records",
+        "item_type": "list",
+        "item_optional": false,
+        "item_default": [ "::1" ],
+        "list_item_spec": {
+          "item_name": "address",
+          "item_type": "string",
+          "item_optional": false,
+          "item_default": ""
+        }
+      },
+      {
+        "item_name": "ns_records",
+        "item_type": "list",
+        "item_optional": false,
+        "item_default": [ "ns1.parking.example", "ns2.parking.example" ],
+        "list_item_spec": {
+          "item_name": "address",
+          "item_type": "string",
+          "item_optional": false,
+          "item_default": ""
+        }
       }
       }
     ],
     ],
     "commands": [
     "commands": [

+ 10 - 2
src/lib/bind-cfgd/python/bind-cfgd.py

@@ -118,12 +118,20 @@ class ConfigManager:
                                 conf_part = data.set(self.config.data, cmd[1], "")
                                 conf_part = data.set(self.config.data, cmd[1], "")
                         else:
                         else:
                             conf_part = self.config.data
                             conf_part = self.config.data
-                        conf_part.update(cmd[2])
+                        data.merge(conf_part, cmd[2])
+                        print("[XX bind-cfgd] new config (part):")
+                        print(conf_part)
                         # send out changed info
                         # send out changed info
                         self.cc.group_sendmsg({ "config_update": conf_part }, cmd[1])
                         self.cc.group_sendmsg({ "config_update": conf_part }, cmd[1])
                         answer["result"] = [ 0 ]
                         answer["result"] = [ 0 ]
                     elif len(cmd) == 2:
                     elif len(cmd) == 2:
-                        self.config.data.update(cmd[1])
+                        print("[XX bind-cfgd] old config:")
+                        print(self.config.data)
+                        print("[XX bind-cfgd] updating with:")
+                        print(cmd[1])
+                        data.merge(self.config.data, cmd[1])
+                        print("[XX bind-cfgd] new config:")
+                        print(self.config.data)
                         # send out changed info
                         # send out changed info
                         for module in self.config.data:
                         for module in self.config.data:
                             self.cc.group_sendmsg({ "config_update": self.config.data[module] }, module)
                             self.cc.group_sendmsg({ "config_update": self.config.data[module] }, module)

+ 16 - 0
src/lib/cc/python/ISC/CC/data.py

@@ -5,6 +5,22 @@ import ast
 class DataNotFoundError(Exception): pass
 class DataNotFoundError(Exception): pass
 class DataTypeError(Exception): pass
 class DataTypeError(Exception): pass
 
 
+def merge(orig, new):
+    """Merges the contents of new into orig, think recursive update()
+       orig and new must both be dicts. If an element value is None in
+       new it will be removed in orig."""
+    for kn in new.keys():
+        if kn in orig:
+            if new[kn]:
+                if type(new[kn]) == dict:
+                    merge(orig[kn], new[kn])
+                else:
+                    orig[kn] = new[kn]
+            else:
+                orig.remove(kn)
+        else:
+            orig[kn] = new[kn]
+
 def find(element, identifier):
 def find(element, identifier):
     """Returns the subelement in the given data element, raises DataNotFoundError if not found"""
     """Returns the subelement in the given data element, raises DataNotFoundError if not found"""
     id_parts = identifier.split("/")
     id_parts = identifier.split("/")