Browse Source

[1288] catch exception from _check_xfrout_available and return SERVFAIL
in that case. also log that event. added a test case for it.

JINMEI Tatuya 13 years ago
parent
commit
6ddab5f4ea

+ 7 - 0
src/bin/xfrout/tests/xfrout_test.py.in

@@ -656,6 +656,13 @@ class TestXfroutSession(TestXfroutSessionBase):
         get_msg = self.sock.read_msg()
         get_msg = self.sock.read_msg()
         self.assertEqual(get_msg.get_rcode().to_text(), "NOTAUTH")
         self.assertEqual(get_msg.get_rcode().to_text(), "NOTAUTH")
 
 
+    def test_dns_xfrout_start_datasrc_servfail(self):
+        def internal_raise(x, y):
+            raise isc.datasrc.Error('exception for the sake of test')
+        self.xfrsess.ClientClass = internal_raise
+        self.xfrsess.dns_xfrout_start(self.sock, self.mdata)
+        self.assertEqual(self.sock.read_msg().get_rcode(), Rcode.SERVFAIL())
+
     def test_dns_xfrout_start_noerror(self):
     def test_dns_xfrout_start_noerror(self):
         self.xfrsess._get_query_zone_name = self.default
         self.xfrsess._get_query_zone_name = self.default
         def noerror(form):
         def noerror(form):

+ 6 - 1
src/bin/xfrout/xfrout.py.in

@@ -363,7 +363,12 @@ class XfroutSession():
         zone_str = format_zone_str(zone_name, zone_class) # for logging
         zone_str = format_zone_str(zone_name, zone_class) # for logging
 
 
         # TODO: we should also include class in the check
         # TODO: we should also include class in the check
-        rcode_ = self._check_xfrout_available(zone_name)
+        try:
+            rcode_ = self._check_xfrout_available(zone_name)
+        except Exception as ex:
+            logger.error(XFROUT_XFR_TRANSFER_CHECK_ERROR, self._request_type,
+                         format_addrinfo(self._remote), zone_str, ex)
+            rcode_ = Rcode.SERVFAIL()
         if rcode_ != Rcode.NOERROR():
         if rcode_ != Rcode.NOERROR():
             logger.info(XFROUT_AXFR_TRANSFER_FAILED, self._request_type,
             logger.info(XFROUT_AXFR_TRANSFER_FAILED, self._request_type,
                         format_addrinfo(self._remote), zone_str, rcode_)
                         format_addrinfo(self._remote), zone_str, rcode_)

+ 7 - 0
src/bin/xfrout/xfrout_messages.mes

@@ -25,6 +25,13 @@ an AXFR query. The error message of the exception is included in the
 log message, but this error most likely points to incomplete exception
 log message, but this error most likely points to incomplete exception
 handling in the code.
 handling in the code.
 
 
+% XFROUT_XFR_TRANSFER_CHECK_ERROR %1 client %2: check for transfer of %3 failed: %4
+Pre-response check for an incomding XFR request failed unexpectedly.
+The most likely cause of this is that some low level error in the data
+source, but it may also be other general (more unlikely) errors such
+as memory shortage.  Some detail of the error is also included in the
+message.  The xfrout server tries to return a SERVFAIL response in this case.
+
 % XFROUT_AXFR_TRANSFER_FAILED %1 client %2: transfer of %3 failed, rcode: %4
 % XFROUT_AXFR_TRANSFER_FAILED %1 client %2: transfer of %3 failed, rcode: %4
 A transfer out for the given zone failed. An error response is sent
 A transfer out for the given zone failed. An error response is sent
 to the client. The given rcode is the rcode that is set in the error
 to the client. The given rcode is the rcode that is set in the error