Parcourir la source

Revert "maintenance commit"
This reverts commit a669db434d32bb5e348ee8c2cc008c271f8e6f1f.

The reverted commit was introduced due to misoperation possibly with
git-new-workdir, and actually reverted previous changes made on master.
By reverting it we now recover these lost changes.

JINMEI Tatuya il y a 14 ans
Parent
commit
901c9eed83

+ 4 - 5
src/bin/auth/main.cc

@@ -57,11 +57,10 @@ using namespace asiolink;
 
 namespace {
 
-static bool verbose_mode = false;
+bool verbose_mode = false;
 
 // Default port current 5300 for testing purposes
-static const string PROGRAM = "Auth";
-static const char* DNSPORT = "5300";
+const char* DNSPORT = "5300";
 
 // Note: this value must be greater than 0.
 // TODO: make it configurable via command channel.
@@ -70,9 +69,9 @@ const uint32_t STATISTICS_SEND_INTERVAL_SEC = 60;
 /* need global var for config/command handlers.
  * todo: turn this around, and put handlers in the authserver
  * class itself? */
-static AuthSrv *auth_server;
+AuthSrv *auth_server;
 
-static IOService io_service;
+IOService io_service;
 
 ConstElementPtr
 my_config_handler(ConstElementPtr new_config) {

+ 17 - 7
src/bin/bindctl/bindcmd.py

@@ -217,16 +217,24 @@ class BindCmdInterpreter(Cmd):
         for module_name in self.config_data.get_config_item_list():
             self._prepare_module_commands(self.config_data.get_module_spec(module_name))
 
+    def _send_message(self, url, body):
+        headers = {"cookie" : self.session_id}
+        self.conn.request('GET', url, body, headers)
+        res = self.conn.getresponse()
+        return res.status, res.read()
+
     def send_GET(self, url, body = None):
         '''Send GET request to cmdctl, session id is send with the name
         'cookie' in header.
         '''
-        headers = {"cookie" : self.session_id}
-        self.conn.request('GET', url, body, headers)
-        res = self.conn.getresponse()
-        reply_msg = res.read()
+        status, reply_msg = self._send_message(url, body)
+        if status == http.client.UNAUTHORIZED:
+            if self.login_to_cmdctl():
+                # successful, so try send again
+                status, reply_msg = self._send_message(url, body)
+            
         if reply_msg:
-           return json.loads(reply_msg.decode())
+            return json.loads(reply_msg.decode())
         else:
             return {}
        
@@ -622,9 +630,11 @@ class BindCmdInterpreter(Cmd):
         if (len(cmd.params) != 0):
             cmd_params = json.dumps(cmd.params)
 
-        print("send the command to cmd-ctrld")        
         reply = self.send_POST(url, cmd.params)
         data = reply.read().decode()
-        print("received reply:", data)
+        # The reply is a string containing JSON data,
+        # parse it, then prettyprint
+        if data != "" and data != "{}":
+            print(json.dumps(json.loads(data), sort_keys=True, indent=4))
 
 

+ 1 - 0
src/bin/resolver/resolver.cc

@@ -260,6 +260,7 @@ public:
                 Message incoming(Message::PARSE);
                 InputBuffer ibuf(buffer->getData(), buffer->getLength());
                 incoming.fromWire(ibuf);
+                message->setRcode(incoming.getRcode());
                 for_each(incoming.beginSection(Message::SECTION_ANSWER),
                          incoming.endSection(Message::SECTION_ANSWER),
                          SectionInserter(message, Message::SECTION_ANSWER));

+ 12 - 10
src/bin/xfrout/tests/xfrout_test.py

@@ -215,36 +215,38 @@ class TestXfroutSession(unittest.TestCase):
         rrset_soa = self.xfrsess._create_rrset_from_db_record(self.soa_record)
         self.assertEqual(82, get_rrset_len(rrset_soa))
 
-    def test_zone_is_empty(self):
+    def test_zone_has_soa(self):
         global sqlite3_ds
         def mydb1(zone, file):
             return True
         sqlite3_ds.get_zone_soa = mydb1
-        self.assertEqual(self.xfrsess._zone_is_empty(""), False)
+        self.assertTrue(self.xfrsess._zone_has_soa(""))
         def mydb2(zone, file):
             return False
         sqlite3_ds.get_zone_soa = mydb2
-        self.assertEqual(self.xfrsess._zone_is_empty(""), True)
+        self.assertFalse(self.xfrsess._zone_has_soa(""))
 
     def test_zone_exist(self):
         global sqlite3_ds
-        def zone_soa(zone, file):
+        def zone_exist(zone, file):
             return zone
-        sqlite3_ds.get_zone_soa = zone_soa
-        self.assertEqual(self.xfrsess._zone_exist(True), True)
-        self.assertEqual(self.xfrsess._zone_exist(False), False)
+        sqlite3_ds.zone_exist = zone_exist
+        self.assertTrue(self.xfrsess._zone_exist(True))
+        self.assertFalse(self.xfrsess._zone_exist(False))
 
     def test_check_xfrout_available(self):
         def zone_exist(zone):
             return zone
+        def zone_has_soa(zone):
+            return (not zone)
         self.xfrsess._zone_exist = zone_exist
-        self.xfrsess._zone_is_empty = zone_exist
+        self.xfrsess._zone_has_soa = zone_has_soa
         self.assertEqual(self.xfrsess._check_xfrout_available(False).to_text(), "NOTAUTH")
         self.assertEqual(self.xfrsess._check_xfrout_available(True).to_text(), "SERVFAIL")
 
         def zone_empty(zone):
-            return not zone
-        self.xfrsess._zone_is_empty = zone_empty
+            return zone
+        self.xfrsess._zone_has_soa = zone_empty
         def false_func():
             return False
         self.xfrsess.server.increase_transfers_counter = false_func

+ 22 - 11
src/bin/xfrout/xfrout.py.in

@@ -193,30 +193,41 @@ class XfroutSession(BaseRequestHandler):
         self._send_message(sock_fd, msg)
 
 
-    def _zone_is_empty(self, zone):
+    def _zone_has_soa(self, zone):
+        '''Judge if the zone has an SOA record.'''
+        # In some sense, the SOA defines a zone.
+        # If the current name server has authority for the
+        # specific zone, we need to judge if the zone has an SOA record;
+        # if not, we consider the zone has incomplete data, so xfrout can't
+        # serve for it.
         if sqlite3_ds.get_zone_soa(zone, self.server.get_db_file()):
-            return False
-
-        return True
-
-    def _zone_exist(self, zonename):
-        # Find zone in datasource, should this works? maybe should ask
-        # config manager.
-        soa = sqlite3_ds.get_zone_soa(zonename, self.server.get_db_file())
-        if soa:
             return True
+
         return False
 
+    def _zone_exist(self, zonename):
+        '''Judge if the zone is configured by config manager.'''
+        # Currently, if we find the zone in datasource successfully, we
+        # consider the zone is configured, and the current name server has
+        # authority for the specific zone.
+        # TODO: should get zone's configuration from cfgmgr or other place
+        # in future.
+        return sqlite3_ds.zone_exist(zonename, self.server.get_db_file())
 
     def _check_xfrout_available(self, zone_name):
         '''Check if xfr request can be responsed.
            TODO, Get zone's configuration from cfgmgr or some other place
            eg. check allow_transfer setting,
         '''
+        # If the current name server does not have authority for the
+        # zone, xfrout can't serve for it, return rcode NOTAUTH.
         if not self._zone_exist(zone_name):
             return Rcode.NOTAUTH()
 
-        if self._zone_is_empty(zone_name):
+        # If we are an authoritative name server for the zone, but fail
+        # to find the zone's SOA record in datasource, xfrout can't
+        # provide zone transfer for it.
+        if not self._zone_has_soa(zone_name):
             return Rcode.SERVFAIL()
 
         #TODO, check allow_transfer

+ 1 - 1
src/bin/xfrout/xfrout.spec.pre.in

@@ -48,4 +48,4 @@
       ]
   }
 }
-     
+

+ 102 - 68
src/lib/python/isc/datasrc/sqlite3_ds.py

@@ -25,25 +25,24 @@ RR_NAME_INDEX = 2
 RR_TTL_INDEX = 4
 RR_RDATA_INDEX = 7
 
-#########################################################################
-# define exceptions
-#########################################################################
 class Sqlite3DSError(Exception):
+    """ Define exceptions."""
     pass
 
-#########################################################################
-# create: set up schema for a newly created zones/records database
-#########################################################################
 def create(cur):
-    """Create new zone database"""
+    """ Set up schema for a newly created zones/records database.
+
+    Arguments:
+        cur - sqlite3 cursor.
+    """
     cur.execute("CREATE TABLE schema_version (version INTEGER NOT NULL)")
     cur.execute("INSERT INTO schema_version VALUES (1)")
-    cur.execute("""CREATE TABLE zones (id INTEGER PRIMARY KEY, 
+    cur.execute("""CREATE TABLE zones (id INTEGER PRIMARY KEY,
                    name STRING NOT NULL COLLATE NOCASE,
-                   rdclass STRING NOT NULL COLLATE NOCASE DEFAULT 'IN', 
+                   rdclass STRING NOT NULL COLLATE NOCASE DEFAULT 'IN',
                    dnssec BOOLEAN NOT NULL DEFAULT 0)""")
     cur.execute("CREATE INDEX zones_byname ON zones (name)")
-    cur.execute("""CREATE TABLE records (id INTEGER PRIMARY KEY, 
+    cur.execute("""CREATE TABLE records (id INTEGER PRIMARY KEY,
                    zone_id INTEGER NOT NULL,
                    name STRING NOT NULL COLLATE NOCASE,
                    rname STRING NOT NULL COLLATE NOCASE,
@@ -53,7 +52,7 @@ def create(cur):
                    rdata STRING NOT NULL)""")
     cur.execute("CREATE INDEX records_byname ON records (name)")
     cur.execute("CREATE INDEX records_byrname ON records (rname)")
-    cur.execute("""CREATE TABLE nsec3 (id INTEGER PRIMARY KEY, 
+    cur.execute("""CREATE TABLE nsec3 (id INTEGER PRIMARY KEY,
                    zone_id INTEGER NOT NULL,
                    hash STRING NOT NULL COLLATE NOCASE,
                    owner STRING NOT NULL COLLATE NOCASE,
@@ -62,17 +61,17 @@ def create(cur):
                    rdata STRING NOT NULL)""")
     cur.execute("CREATE INDEX nsec3_byhash ON nsec3 (hash)")
 
-#########################################################################
-# open: open a database.  if the database is not yet set up, 
-# call create to do so.
-# input:
-#   dbfile - the filename for the sqlite3 database
-# returns:
-#   sqlite3 connection, sqlite3 cursor
-#########################################################################
 def open(dbfile):
-    """Open the database file.  If necessary, set it up"""
-    try: 
+    """ Open a database, if the database is not yet set up, call create
+    to do so. It may raise Sqlite3DSError if failed to open sqlite3
+    database file or find bad database schema version in the database.
+
+    Arguments:
+        dbfile - the filename for the sqlite3 database.
+
+    Return sqlite3 connection, sqlite3 cursor.
+    """
+    try:
         conn = sqlite3.connect(dbfile)
         cur = conn.cursor()
     except Exception as e:
@@ -93,12 +92,15 @@ def open(dbfile):
 
     return conn, cur
 
-#########################################################################
-# get_zone_datas
-#   a generator function producing an iterable set of 
-#   the records in the zone with the given zone name.
-#########################################################################
+
 def get_zone_datas(zonename, dbfile):
+    """ A generator function producing an iterable set of
+    the records in the zone with the given zone name.
+
+    Arguments:
+        zonename - the zone's origin name.
+        dbfile - the filename for the sqlite3 database.
+    """
     conn, cur = open(dbfile)
     zone_id = get_zoneid(zonename, cur)
 
@@ -112,12 +114,14 @@ def get_zone_datas(zonename, dbfile):
     conn.close()
 
 
-#########################################################################
-# get_zone_soa
-#   returns the soa record of the zone with the given zone name. 
-#   If the zone doesn't exist, return None. 
-#########################################################################
 def get_zone_soa(zonename, dbfile):
+    """Return the soa record of the zone with the given zone name.
+    If the zone doesn't exist, return None.
+
+    Arguments:
+        zonename - the zone's origin name.
+        dbfile - the filename for the sqlite3 database.
+    """
     conn, cur = open(dbfile)
     id = get_zoneid(zonename, cur)
     cur.execute("SELECT * FROM records WHERE zone_id = ? and rdtype = ?", [id, 'SOA'])
@@ -128,16 +132,20 @@ def get_zone_soa(zonename, dbfile):
     return datas
 
 
-#########################################################################
-# get_zone_rrset
-#   returns the rrset of the zone with the given zone name, rrset name 
-#   and given rd type. 
-#   If the zone doesn't exist or rd type doesn't exist, return an empty list. 
-#########################################################################
 def get_zone_rrset(zonename, rr_name, rdtype, dbfile):
+    """Return the rrset of the zone with the given zone name, rrset
+    name and given RR type. If the zone doesn't exist or RR type
+    doesn't exist, return an empty list.
+
+    Arguments:
+        zonename - the zone's origin name.
+        rr_name - rr name.
+        rdtype - RR type.
+        dbfile - the filename for the sqlite3 database.
+    """
     conn, cur = open(dbfile)
     id = get_zoneid(zonename, cur)
-    cur.execute("SELECT * FROM records WHERE name = ? and zone_id = ? and rdtype = ?", 
+    cur.execute("SELECT * FROM records WHERE name = ? and zone_id = ? and rdtype = ?",
                 [rr_name, id, rdtype])
     datas = cur.fetchall()
     cur.close()
@@ -145,12 +153,13 @@ def get_zone_rrset(zonename, rr_name, rdtype, dbfile):
     return datas
 
 
-#########################################################################
-# get_zones_info:
-#   returns all the zones' information.
-#########################################################################
-def get_zones_info(db_file):
-    conn, cur = open(db_file)
+def get_zones_info(dbfile):
+    """ Return all the zones' information in the database.
+
+    Arguments:
+        dbfile - the filename for the sqlite3 database.
+    """
+    conn, cur = open(dbfile)
     cur.execute("SELECT name, rdclass FROM zones")
     info = cur.fetchone()
     while info:
@@ -160,44 +169,69 @@ def get_zones_info(db_file):
     cur.close()
     conn.close()
 
-#########################################################################
-# get_zoneid:
-#   returns the zone_id for a given zone name, or an empty
-#   string if the zone is not found
-#########################################################################
-def get_zoneid(zone, cur):
-    cur.execute("SELECT id FROM zones WHERE name = ?", [zone])
+
+def get_zoneid(zonename, cur):
+    """ Get the zone_id for a given zone name.
+
+    Arguments:
+        zonename - the zone's origin name.
+        cur - sqlite3 cursor.
+
+    Return zone id for the given zone name, or an empty string if the
+    zone is not found.
+    """
+    cur.execute("SELECT id FROM zones WHERE name = ?", [zonename])
     row = cur.fetchone()
     if row:
         return row[0]
     else:
         return ''
-    
-#########################################################################
-# reverse_name:
-#   reverse the labels of a DNS name.  (for example,
-#   "bind10.isc.org." would become "org.isc.bind10.")
-#########################################################################
+
+
+def zone_exist(zonename, dbfile):
+    """ Search for the zone with the given zone name in databse. This
+    method may throw a Sqlite3DSError exception because its underlying
+    method open() can throw that exception.
+
+    Arguments:
+        zonename - the zone's origin name.
+        dbfile - the filename for the sqlite3 database.
+
+    Return True if the zone is found, otherwise False.
+    """
+    conn, cur = open(dbfile)
+    zoneid = get_zoneid(zonename, cur)
+    cur.close()
+    conn.close()
+    if zoneid:
+        return True
+    return False
+
+
 def reverse_name(name):
     """Reverse the labels of a domain name; for example,
-    given 'www.isc.org.', return 'org.isc.www.'  This is needed
-    for DNSSEC sort order."""
+    given 'www.example.org.', return 'org.example.www.'  This is needed
+    for DNSSEC sort order.
+
+    Arguments:
+        name - the DNS name will be reversed.
+    """
     new = name.split('.')
     new.reverse()
     if new[0] == '':
         new.pop(0)
     return '.'.join(new)+'.'
 
-#########################################################################
-# load:
-#   load a zone into the SQL database.
-# input:
-#   dbfile: the sqlite3 database fileanme
-#   zone: the zone origin
-#   reader: a generator function producing an iterable set of
-#           name/ttl/class/rrtype/rdata-text tuples
-#########################################################################
+
 def load(dbfile, zone, reader):
+    """  Load a zone into the SQL database.
+
+    Arguments:
+        dbfile - the sqlite3 database filename
+        zone - the zone origin
+        reader - a generator function producing an iterable set of
+        name/ttl/class/rrtype/rdata-text tuples.
+    """
     # if the zone name doesn't contain the trailing dot, automatically add it.
     if zone[-1] != '.':
         zone += '.'

+ 6 - 2
src/lib/python/isc/datasrc/tests/Makefile.am

@@ -1,16 +1,20 @@
 PYCOVERAGE_RUN = @PYCOVERAGE_RUN@
-PYTESTS = master_test.py
+PYTESTS = master_test.py sqlite3_ds_test.py
 EXTRA_DIST = $(PYTESTS)
 
+EXTRA_DIST += testdata/brokendb.sqlite3
+EXTRA_DIST += testdata/example.com.sqlite3
+
 # test using command-line arguments, so use check-local target instead of TESTS
 check-local:
 if ENABLE_PYTHON_COVERAGE
-	touch $(abs_top_srcdir)/.coverage 
+	touch $(abs_top_srcdir)/.coverage
 	rm -f .coverage
 	${LN_S} $(abs_top_srcdir)/.coverage .coverage
 endif
 	for pytest in $(PYTESTS) ; do \
 	echo Running test: $$pytest ; \
 	env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/python/isc/log \
+	TESTDATA_PATH=$(abs_srcdir)/testdata \
 	$(PYCOVERAGE_RUN) $(abs_srcdir)/$$pytest || exit ; \
 	done

+ 43 - 0
src/lib/python/isc/datasrc/tests/sqlite3_ds_test.py

@@ -0,0 +1,43 @@
+# Copyright (C) 2011  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+from isc.datasrc import sqlite3_ds
+import os
+import socket
+import unittest
+
+TESTDATA_PATH = os.environ['TESTDATA_PATH'] + os.sep
+
+class TestSqlite3_ds(unittest.TestCase):
+    def test_zone_exist(self):
+        # The following file must be non existent and must be non
+        # "creatable"; the sqlite3 library will try to create a new
+        # DB file if it doesn't exist, so to test a failure case the
+        # create operation should also fail. The "nodir", a non
+        # existent directory, is inserted for this purpose.
+        nodir = "/nodir/notexist"
+        self.assertRaises(sqlite3_ds.Sqlite3DSError,
+                          sqlite3_ds.zone_exist, "example.com", nodir)
+        # Open a broken database file
+        self.assertRaises(sqlite3_ds.Sqlite3DSError,
+                          sqlite3_ds.zone_exist, "example.com",
+                          TESTDATA_PATH + "brokendb.sqlite3")
+        self.assertTrue(sqlite3_ds.zone_exist("example.com.",
+                            TESTDATA_PATH + "example.com.sqlite3"))
+        self.assertFalse(sqlite3_ds.zone_exist("example.org.",
+                            TESTDATA_PATH + "example.com.sqlite3"))
+
+if __name__ == '__main__':
+    unittest.main()

BIN
src/lib/python/isc/datasrc/tests/testdata/brokendb.sqlite3


BIN
src/lib/python/isc/datasrc/tests/testdata/example.com.sqlite3