BIND 10 trac805-merged, updated. ca3cc561237dde1fac32c592056051eb339bea03 [805] Abort when can't send or close

BIND 10 source code commits bind10-changes at lists.isc.org
Fri Jan 6 14:59:02 UTC 2012


The branch, trac805-merged has been updated
       via  ca3cc561237dde1fac32c592056051eb339bea03 (commit)
       via  d66d0cc215a2436ddf91343f266c47a73d0993f2 (commit)
       via  f786ba4251dac7a4feb71a604cfdf27003305ddf (commit)
      from  01d2bc6d797953339d3d99cdb6fdba7ff76f83d0 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit ca3cc561237dde1fac32c592056051eb339bea03
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Fri Jan 6 15:46:36 2012 +0100

    [805] Abort when can't send or close

commit d66d0cc215a2436ddf91343f266c47a73d0993f2
Author: JINMEI Tatuya <jinmei at isc.org>
Date:   Fri Jan 6 15:27:23 2012 +0100

    [805] Run sockcreator from source
    
    If it is run from the source code, all programs should be run from
    there.

commit f786ba4251dac7a4feb71a604cfdf27003305ddf
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Fri Jan 6 15:25:23 2012 +0100

    [805] Socket options and tests for them
    
    Added the v6 only flag for IPv6 sockets. Both reuse address and this
    flags get tested.

-----------------------------------------------------------------------

Summary of changes:
 src/bin/bind10/bind10_src.py.in                |    6 +--
 src/bin/sockcreator/sockcreator.cc             |   14 ++++++--
 src/bin/sockcreator/sockcreator.h              |   11 ++++++-
 src/bin/sockcreator/tests/sockcreator_tests.cc |   41 ++++++++++++++++++++++-
 src/lib/python/bind10_config.py.in             |   41 ++++++++++++++++++------
 src/lib/python/isc/bind10/special_component.py |    4 +-
 6 files changed, 95 insertions(+), 22 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/bin/bind10/bind10_src.py.in b/src/bin/bind10/bind10_src.py.in
index 62ad74f..c202e24 100755
--- a/src/bin/bind10/bind10_src.py.in
+++ b/src/bin/bind10/bind10_src.py.in
@@ -44,12 +44,10 @@ import os
 # installed on the system
 if "B10_FROM_SOURCE" in os.environ:
     SPECFILE_LOCATION = os.environ["B10_FROM_SOURCE"] + "/src/bin/bind10/bob.spec"
-    ADD_LIBEXEC_PATH = False
 else:
     PREFIX = "@prefix@"
     DATAROOTDIR = "@datarootdir@"
     SPECFILE_LOCATION = "@datadir@/@PACKAGE@/bob.spec".replace("${datarootdir}", DATAROOTDIR).replace("${prefix}", PREFIX)
-    ADD_LIBEXEC_PATH = True
     
 import subprocess
 import signal
@@ -65,6 +63,7 @@ import pwd
 import posix
 import copy
 
+from bind10_config import LIBEXECPATH
 import isc.cc
 import isc.util.process
 import isc.net.parse
@@ -151,8 +150,7 @@ class ProcessInfo:
         # on construction (self.env).
         spawn_env = copy.deepcopy(os.environ)
         spawn_env.update(self.env)
-        if ADD_LIBEXEC_PATH:
-            spawn_env['PATH'] = "@@LIBEXECDIR@@:" + spawn_env['PATH']
+        spawn_env['PATH'] = LIBEXECPATH + spawn_env['PATH']
         self.process = subprocess.Popen(self.args,
                                         stdin=subprocess.PIPE,
                                         stdout=spawn_stdout,
diff --git a/src/bin/sockcreator/sockcreator.cc b/src/bin/sockcreator/sockcreator.cc
index 420fde7..523cbfb 100644
--- a/src/bin/sockcreator/sockcreator.cc
+++ b/src/bin/sockcreator/sockcreator.cc
@@ -39,6 +39,10 @@ get_sock(const int type, struct sockaddr *bind_addr, const socklen_t addr_len)
     if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
         return -2; // This is part of the binding process, so it's a bind error
     }
+    if (bind_addr->sa_family == AF_INET6 &&
+        setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1) {
+        return -2; // This is part of the binding process, so it's a bind error
+    }
     if (bind(sock, bind_addr, addr_len) == -1) {
         return -2;
     }
@@ -66,7 +70,7 @@ get_sock(const int type, struct sockaddr *bind_addr, const socklen_t addr_len)
 
 int
 run(const int input_fd, const int output_fd, const get_sock_t get_sock,
-    const send_fd_t send_fd)
+    const send_fd_t send_fd, const close_t close)
 {
     for (;;) {
         // Read the command
@@ -127,9 +131,13 @@ run(const int input_fd, const int output_fd, const get_sock_t get_sock,
                 if (result >= 0) { // We got the socket
                     WRITE("S", 1);
                     // FIXME: Check the output and write a test for it
-                    send_fd(output_fd, result);
+                    if(send_fd(output_fd, result) == FD_SYSTEM_ERROR) {
+                        return 3;
+                    }
                     // Don't leak the socket
-                    close(result);
+                    if (close(result) == -1) {
+                        return 4;
+                    }
                 } else {
                     WRITE("E", 1);
                     switch (result) {
diff --git a/src/bin/sockcreator/sockcreator.h b/src/bin/sockcreator/sockcreator.h
index ddf9a09..bbac27a 100644
--- a/src/bin/sockcreator/sockcreator.h
+++ b/src/bin/sockcreator/sockcreator.h
@@ -27,6 +27,7 @@
 
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <unistd.h>
 
 namespace isc {
 namespace socket_creator {
@@ -62,6 +63,11 @@ typedef
 int
 (*send_fd_t)(const int, const int);
 
+/// \brief Type of the close() function, so it can be passed as a parameter.
+typedef
+int
+(*close_t)(int);
+
 /**
  * \short Infinite loop parsing commands and returning the sockets.
  *
@@ -88,11 +94,14 @@ int
  * \param send_fd_fun The function that is used to send the socket over
  *     a file descriptor. This should be left on the default value, it is
  *     here for testing purposes.
+ * \param close The close function used to close sockets, coming from
+ *     unistd.h. It can be overriden in tests.
  */
 int
 run(const int input_fd, const int output_fd,
     const get_sock_t get_sock_fun = get_sock,
-    const send_fd_t send_fd_fun = isc::util::io::send_fd);
+    const send_fd_t send_fd_fun = isc::util::io::send_fd,
+    const close_t close = close);
 
 } // End of the namespaces
 }
diff --git a/src/bin/sockcreator/tests/sockcreator_tests.cc b/src/bin/sockcreator/tests/sockcreator_tests.cc
index 73cbf48..7593061 100644
--- a/src/bin/sockcreator/tests/sockcreator_tests.cc
+++ b/src/bin/sockcreator/tests/sockcreator_tests.cc
@@ -59,6 +59,15 @@ namespace {
             #SOCK_TYPE " and family " #ADDR_FAMILY ", failed with " \
             << socket << " and error " << strerror(errno); \
         CHECK_SOCK(ADDR_TYPE, socket); \
+        int on; \
+        socklen_t len(sizeof(on)); \
+        ASSERT_EQ(0, getsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &on, &len));\
+        ASSERT_EQ(1, on); \
+        if (ADDR_FAMILY == AF_INET6) { \
+            ASSERT_EQ(0, getsockopt(socket, IPPROTO_IPV6, IPV6_V6ONLY, &on, \
+                                    &len)); \
+            ASSERT_EQ(1, on); \
+        } \
         EXPECT_EQ(0, close(socket)); \
     } while (0)
 
@@ -190,6 +199,12 @@ send_fd_dummy(const int destination, const int what)
     }
 }
 
+// Just ignore the fd and pretend success. We close invalid fds in the tests.
+int
+close_ignore(int) {
+    return (0);
+}
+
 /*
  * Generic test that it works, with various inputs and outputs.
  * It uses different functions to create the socket and send it and pass
@@ -198,7 +213,8 @@ send_fd_dummy(const int destination, const int what)
  */
 void run_test(const char *input_data, const size_t input_size,
     const char *output_data, const size_t output_size,
-    bool should_succeed = true)
+    bool should_succeed = true, const close_t test_close = close_ignore,
+    const send_fd_t send_fd = send_fd_dummy)
 {
     // Prepare the input feeder and output checker processes
     int input_fd(0), output_fd(0);
@@ -207,7 +223,7 @@ void run_test(const char *input_data, const size_t input_size,
     ASSERT_NE(-1, input) << "Couldn't start input feeder";
     ASSERT_NE(-1, output) << "Couldn't start output checker";
     // Run the body
-    int result(run(input_fd, output_fd, get_sock_dummy, send_fd_dummy));
+    int result(run(input_fd, output_fd, get_sock_dummy, send_fd, test_close));
     // Close the pipes
     close(input_fd);
     close(output_fd);
@@ -270,4 +286,25 @@ TEST(run, bad_sockets) {
         result, result_len);
 }
 
+// A close that fails
+int
+close_fail(int) {
+    return (-1);
+}
+
+TEST(run, cant_close) {
+    run_test("SU4\xff\xff\0\0\0\0", // This has 9 bytes
+             9, "S\x07", 2, false, close_fail);
+}
+
+int
+send_fd_fail(const int, const int) {
+    return (FD_SYSTEM_ERROR);
+}
+
+TEST(run, cant_send_fd) {
+    run_test("SU4\xff\xff\0\0\0\0", // This has 9 bytes
+             9, "S", 1, false, close_ignore, send_fd_fail);
+}
+
 }
diff --git a/src/lib/python/bind10_config.py.in b/src/lib/python/bind10_config.py.in
index e54b1a8..b8975cf 100644
--- a/src/lib/python/bind10_config.py.in
+++ b/src/lib/python/bind10_config.py.in
@@ -23,24 +23,37 @@ def reload():
     global DATA_PATH
     global PLUGIN_PATHS
     global PREFIX
-    global LIBEXECDIR
-    LIBEXECDIR = ("@libexecdir@/@PACKAGE@"). \
-        replace("${exec_prefix}", "@exec_prefix@"). \
-        replace("${prefix}", "@prefix@")
+    global LIBEXECPATH
     BIND10_MSGQ_SOCKET_FILE = os.path.join("@localstatedir@",
                                            "@PACKAGE_NAME@",
                                            "msgq_socket").replace("${prefix}",
                                                                   "@prefix@")
     PREFIX = "@prefix@"
 
-    # If B10_FROM_SOURCE is set in the environment, we use data files
-    # from a directory relative to the value of that variable, or, if defined,
-    # relative to the value of B10_FROM_SOURCE_LOCALSTATEDIR.  Otherwise
-    # we use the ones installed on the system.
+    # B10_FROM_SOURCE is set in the environment for internal tests and
+    # an experimental run without installagion.  In that case we need to
+    # specialize some configuration variables, generally so that they refer
+    # to somewhere in the source tree instead of the appropriate places
+    # after installation.
+    #
+    # DATA_PATH: used by the config manager to find configuration files.
+    #  When "FROM_SOURCE", we use data files from a directory relative to the
+    #  value of that variable, or, if defined, relative to the value of
+    #  B10_FROM_SOURCE_LOCALSTATEDIR.  Otherwise we use the ones installed on
+    #  the system.
+    # PLUGIN_PATHS: configuration modules that are not associated to specific
+    #  process
+    # LIBEXECPATH: Paths to programs invoked by the boss process
+    #  The boss process (directly or via a helper module) uses this as
+    #  the prefererred PATH before starting a child process.
+    #  When "FROM_SOURCE", it lists the directories where the programs are
+    #  built so that when BIND 10 is experimentally started on the source
+    #  tree the programs in the tree (not installed ones) will be used.
+    #
     # B10_FROM_SOURCE_LOCALSTATEDIR is specifically intended to be used for
     # tests where we want to use variuos types of configuration within the test
-    # environment.  (We may want to make it even more generic so that the path is
-    # passed from the boss process)
+    # environment.  (We may want to make it even more generic so that the path
+    # is passed from the boss process)
     if "B10_FROM_SOURCE" in os.environ:
         if "B10_FROM_SOURCE_LOCALSTATEDIR" in os.environ:
             DATA_PATH = os.environ["B10_FROM_SOURCE_LOCALSTATEDIR"]
@@ -48,9 +61,17 @@ def reload():
             DATA_PATH = os.environ["B10_FROM_SOURCE"]
         PLUGIN_PATHS = [os.environ["B10_FROM_SOURCE"] +
                             '/src/bin/cfgmgr/plugins']
+        programdirs = ['auth', 'cfgmgr', 'cmdctl', 'ddns', 'dhcp6', 'msgq',
+                       'resolver', 'sockcreator', 'stats', 'xfrin', 'xfrout',
+                       'zonemgr']
+        LIBEXECPATH = ':'.join(['@abs_top_builddir@/src/bin/' + p for p in
+                                programdirs])
     else:
         DATA_PATH = "@localstatedir@/@PACKAGE@".replace("${prefix}", PREFIX)
         PLUGIN_PATHS = ["@prefix@/share/@PACKAGE@/config_plugins"]
+        LIBEXECPATH = ("@libexecdir@/@PACKAGE@"). \
+            replace("${exec_prefix}", "@exec_prefix@"). \
+            replace("${prefix}", "@prefix@")
     # For testing the plugins so they can find their own spec files
     if "B10_TEST_PLUGIN_DIR" in os.environ:
         PLUGIN_PATHS = os.environ["B10_TEST_PLUGIN_DIR"].split(':')
diff --git a/src/lib/python/isc/bind10/special_component.py b/src/lib/python/isc/bind10/special_component.py
index c9c7683..29cdf62 100644
--- a/src/lib/python/isc/bind10/special_component.py
+++ b/src/lib/python/isc/bind10/special_component.py
@@ -15,7 +15,7 @@
 
 from isc.bind10.component import Component, BaseComponent
 import isc.bind10.sockcreator
-from bind10_config import LIBEXECDIR
+from bind10_config import LIBEXECPATH
 import os
 import posix
 import isc.log
@@ -39,7 +39,7 @@ class SockCreator(BaseComponent):
 
     def _start_internal(self):
         self._boss.curproc = 'b10-sockcreator'
-        self.__creator = isc.bind10.sockcreator.Creator(LIBEXECDIR + ':' +
+        self.__creator = isc.bind10.sockcreator.Creator(LIBEXECPATH + ':' +
                                                         os.environ['PATH'])
         self._boss.register_process(self.pid(), self)
         self._boss.set_creator(self.__creator)




More information about the bind10-changes mailing list