Parcourir la source

tests for cases of server initialization failure due to system level errors.

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac221b@2473 e5f2f494-b856-4b98-b285-d166d9295462
JINMEI Tatuya il y a 15 ans
Parent
commit
8f5c79badc
2 fichiers modifiés avec 50 ajouts et 11 suppressions
  1. 19 11
      src/bin/auth/asio_link.cc
  2. 31 0
      src/bin/auth/tests/asio_link_unittest.cc

+ 19 - 11
src/bin/auth/asio_link.cc

@@ -484,17 +484,25 @@ IOServiceImpl::IOServiceImpl(AuthSrv* auth_server, const char& port,
                   ex.what());
                   ex.what());
     }
     }
 
 
-    if (v4addr.is_v4()) {
-        udp4_server_ = UDPServerPtr(new UDPServer(auth_server, io_service_,
-                                                  v4addr, portnum));
-        tcp4_server_ = TCPServerPtr(new TCPServer(auth_server, io_service_,
-                                                  v4addr, portnum));
-    }
-    if (v6addr.is_v6()) {
-        udp6_server_ = UDPServerPtr(new UDPServer(auth_server, io_service_,
-                                                  v6addr, portnum));
-        tcp6_server_ = TCPServerPtr(new TCPServer(auth_server, io_service_,
-                                                  v6addr, portnum));
+    try {
+        if (v4addr.is_v4()) {
+            udp4_server_ = UDPServerPtr(new UDPServer(auth_server, io_service_,
+                                                      v4addr, portnum));
+            tcp4_server_ = TCPServerPtr(new TCPServer(auth_server, io_service_,
+                                                      v4addr, portnum));
+        }
+        if (v6addr.is_v6()) {
+            udp6_server_ = UDPServerPtr(new UDPServer(auth_server, io_service_,
+                                                      v6addr, portnum));
+            tcp6_server_ = TCPServerPtr(new TCPServer(auth_server, io_service_,
+                                                      v6addr, portnum));
+        }
+    } catch (const asio::system_error& err) {
+        // We need to catch and convert any ASIO level exceptions.
+        // This can happen for unavailable address, binding a privilege port
+        // without the privilege, etc.
+        isc_throw(IOError, "Failed to initialize network servers: " <<
+                  err.what());
     }
     }
 }
 }
 
 

+ 31 - 0
src/bin/auth/tests/asio_link_unittest.cc

@@ -105,6 +105,37 @@ TEST(IOServiceTest, badAddress) {
                  IOError);
                  IOError);
 }
 }
 
 
+TEST(IOServiceTest, unavailableAddress) {
+    // These addresses should generally be unavailable as a valid local
+    // address, although there's no guarantee in theory.
+    EXPECT_THROW(IOService(NULL, *TEST_PORT, *"ffff:ffff::"), IOError);
+    EXPECT_THROW(IOService(NULL, *TEST_PORT, *"255.255.255.255"), IOError);
+}
+
+TEST(IOServiceTest, duplicateBind) {
+    // In each sub test case, second attempt should fail due to duplicate bind
+
+    // IPv6, "any" address
+    IOService* io_service = new IOService(NULL, *TEST_PORT, false, true);
+    EXPECT_THROW(IOService(NULL, *TEST_PORT, false, true), IOError);
+    delete io_service;
+
+    // IPv6, specific address
+    io_service = new IOService(NULL, *TEST_PORT, *TEST_IPV6_ADDR);
+    EXPECT_THROW(IOService(NULL, *TEST_PORT, *TEST_IPV6_ADDR), IOError);
+    delete io_service;
+
+    // IPv4, "any" address
+    io_service = new IOService(NULL, *TEST_PORT, true, false);
+    EXPECT_THROW(IOService(NULL, *TEST_PORT, true, false), IOError);
+    delete io_service;
+
+    // IPv4, specific address
+    io_service = new IOService(NULL, *TEST_PORT, *TEST_IPV4_ADDR);
+    EXPECT_THROW(IOService(NULL, *TEST_PORT, *TEST_IPV4_ADDR), IOError);
+    delete io_service;
+}
+
 struct addrinfo*
 struct addrinfo*
 resolveAddress(const int family, const int sock_type, const int protocol) {
 resolveAddress(const int family, const int sock_type, const int protocol) {
     const char* const addr = (family == AF_INET6) ?
     const char* const addr = (family == AF_INET6) ?