Browse Source

[1539] log socket forward failure

JINMEI Tatuya 13 years ago
parent
commit
58be95ac3f
3 changed files with 50 additions and 13 deletions
  1. 11 0
      src/bin/auth/auth_messages.mes
  2. 36 11
      src/bin/auth/auth_srv.cc
  3. 3 2
      src/bin/auth/tests/auth_srv_unittest.cc

+ 11 - 0
src/bin/auth/auth_messages.mes

@@ -277,3 +277,14 @@ This is a debug message output during the processing of a NOTIFY
 request. The zone manager component has been informed of the request,
 but has returned an error response (which is included in the message). The
 NOTIFY request will not be honored.
+
+% AUTH_UPDATE_FORWARD_ERROR failed to forward update request from %1: %2
+The authoritative server receives a dynamic update request, tried to
+forward it to a separate process (which is usually b10-ddns) to handle it,
+but it failed.  It could be configuration mismatch between b10-auth and
+b10-ddns, or it may because update requests are coming too fast and b10-ddns
+cannot keep up with the rate, or some system level failure.  In either case
+this means the BIND 10 system is not working as expected, so the administrator
+should look into the cause and address the issue.  The log message
+includes the client's address (and port), and the error message sent
+from the lower layer that detects the failure.

+ 36 - 11
src/bin/auth/auth_srv.cc

@@ -14,17 +14,6 @@
 
 #include <config.h>
 
-#include <sys/types.h>
-#include <netinet/in.h>
-
-#include <algorithm>
-#include <cassert>
-#include <iostream>
-#include <vector>
-#include <memory>
-
-#include <boost/bind.hpp>
-
 #include <util/io/socketsession.h>
 
 #include <asiolink/asiolink.h>
@@ -66,6 +55,18 @@
 #include <auth/statistics.h>
 #include <auth/auth_log.h>
 
+#include <boost/bind.hpp>
+#include <boost/lexical_cast.hpp>
+
+#include <algorithm>
+#include <cassert>
+#include <iostream>
+#include <vector>
+#include <memory>
+
+#include <sys/types.h>
+#include <netinet/in.h>
+
 using namespace std;
 
 using namespace isc;
@@ -171,6 +172,23 @@ private:
         }
     }
 };
+
+// A helper function to log an address/port in the form of IOEndpoint
+// in our preferred format: [<ipv6_addr>]:port or <ipv4_addr>:port
+string
+formatEndpoint(const IOEndpoint& ep) {
+    string addr_port;
+    if (ep.getFamily() == AF_INET6) {
+        addr_port = "[" + ep.getAddress().toText() + "]";
+    } else if (ep.getFamily() == AF_INET) {
+        addr_port = ep.getAddress().toText();
+    } else {
+        addr_port = "(unknown address)";
+    }
+    addr_port += ":" + boost::lexical_cast<string>(ep.getPort());
+
+    return (addr_port);
+}
 }
 
 class AuthSrvImpl {
@@ -827,10 +845,17 @@ AuthSrvImpl::processUpdate(const IOMessage& io_message,
         ddns_forwarder_.connect();
         ddns_forwarder_.push(io_message);
     } catch (const SocketSessionError& ex) {
+        // If either connect or push fails, the forwarder object should throw
+        // an exception.  We log the event, and propagate the exception to
+        // the caller, which will result in SERVFAIL.
+        LOG_ERROR(auth_logger, AUTH_UPDATE_FORWARD_ERROR).
+            arg(formatEndpoint(io_message.getRemoteEndpoint())).
+            arg(ex.what());
         ddns_forwarder_.close();
         throw;
     }
 
+    // On successful push, the request shouldn't be responded from b10-auth.
     return (false);
 }
 

+ 3 - 2
src/bin/auth/tests/auth_srv_unittest.cc

@@ -1506,9 +1506,10 @@ TEST_F(AuthSrvTest, DDNSForwardPushFail) {
     EXPECT_TRUE(ddns_forwarder.isConnected());
 
     // make connect attempt fail.  It should result in SERVFAIL.  The
-    // connection should be closed.
+    // connection should be closed.  Use IPv6 address for varying log output.
     ddns_forwarder.disablePush();
-    createAndSendRequest(RRType::SOA(), Opcode::UPDATE());
+    createAndSendRequest(RRType::SOA(), Opcode::UPDATE(), Name("example.com"),
+                         RRClass::IN(), IPPROTO_UDP, "2001:db8::2");
     EXPECT_TRUE(dnsserv.hasAnswer());
     headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
                 Opcode::UPDATE().getCode(), QR_FLAG, 0, 0, 0, 0);