BIND 10 trac3188, updated. e13edb9dcb01b4c161d270f87facc468258cca02 [3188] Update the Python interface to the socket creator to support raw filter sockets

BIND 10 source code commits bind10-changes at lists.isc.org
Wed Feb 12 09:47:41 UTC 2014


The branch, trac3188 has been updated
       via  e13edb9dcb01b4c161d270f87facc468258cca02 (commit)
      from  5db447677785a9e023fbbf3506f5a1d57856116b (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 e13edb9dcb01b4c161d270f87facc468258cca02
Author: Mukund Sivaraman <muks at isc.org>
Date:   Wed Feb 12 14:56:10 2014 +0530

    [3188] Update the Python interface to the socket creator to support raw filter sockets

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

Summary of changes:
 src/bin/bind10/init_messages.mes                   |    3 +
 src/lib/python/isc/bind10/sockcreator.py           |   95 ++++++++++++--------
 .../python/isc/bind10/tests/sockcreator_test.py    |   10 ++-
 3 files changed, 70 insertions(+), 38 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/bin/bind10/init_messages.mes b/src/bin/bind10/init_messages.mes
index 21cd142..b0f18c0 100644
--- a/src/bin/bind10/init_messages.mes
+++ b/src/bin/bind10/init_messages.mes
@@ -261,6 +261,9 @@ indicated OS API function with given error.
 % BIND10_SOCKET_GET requesting socket [%1]:%2 of type %3 from the creator
 The b10-init forwards a request for a socket to the socket creator.
 
+% BIND10_GET_FILTER_SOCKET requesting raw filter socket with port=%1, interface=%2 from the creator
+The b10-init forwards a request for a raw filter socket to the socket creator.
+
 % BIND10_STARTED_CC started configuration/command session
 Debug message given when BIND 10 has successfully started the object that
 handles configuration and commands.
diff --git a/src/lib/python/isc/bind10/sockcreator.py b/src/lib/python/isc/bind10/sockcreator.py
index bb4250a..52c8fbd 100644
--- a/src/lib/python/isc/bind10/sockcreator.py
+++ b/src/lib/python/isc/bind10/sockcreator.py
@@ -102,36 +102,7 @@ class Parser:
         else:
             return '[' + str(address) + ']:' + str(port)
 
-    def get_socket(self, address, port, socktype):
-        """
-        Asks the socket creator process to create a socket. Pass an address
-        (the isc.net.IPaddr object), port number and socket type (either
-        string "UDP", "TCP" or constant socket.SOCK_DGRAM or
-        socket.SOCK_STREAM.
-
-        Blocks until it is provided by the socket creator process (which
-        should be fast, as it is on localhost) and returns the file descriptor
-        number. It raises a CreatorError exception if the creation fails.
-        """
-        if self.__socket is None:
-            raise CreatorError('Socket requested on terminated creator', True)
-        # First, assemble the request from parts
-        logger.info(BIND10_SOCKET_GET, address, port, socktype)
-        data = b'S'
-        if socktype == 'UDP' or socktype == socket.SOCK_DGRAM:
-            data += b'U'
-        elif socktype == 'TCP' or socktype == socket.SOCK_STREAM:
-            data += b'T'
-        else:
-            raise ValueError('Unknown socket type: ' + str(socktype))
-        if address.family == socket.AF_INET:
-            data += b'4'
-        elif address.family == socket.AF_INET6:
-            data += b'6'
-        else:
-            raise ValueError('Unknown address family in address')
-        data += struct.pack('!H', port)
-        data += address.addr
+    def __get_socket_helper(self, data, sock_type, log_arg):
         try:
             # Send the request
             self.__socket.sendall(data)
@@ -148,9 +119,9 @@ class Parser:
                                           self.__read_all(len(struct.pack('i',
                                                                           0))))
                 if error == b'S':
-                    cause = 'socket'
+                    cause = 'socket() error'
                 elif error == b'B':
-                    cause = 'bind'
+                    cause = 'bind() error'
                 else:
                     self.__socket = None
                     logger.fatal(BIND10_SOCKCREATOR_BAD_CAUSE, error)
@@ -163,10 +134,10 @@ class Parser:
                 # trouble.  In particular, we are intentionally very verbose
                 # if it fails due to "permission denied" so the administrator
                 # can easily identify what is wrong and how to fix it.
-                addrport = self.__addrport_str(address, port)
-                error_text = 'Error creating socket on ' + cause + \
-                    ' to be bound to ' + addrport + ': ' + \
-                    os.strerror(rcv_errno[0])
+                error_text = 'Error creating ' + sock_type + \
+                             ' to be bound to ' + \
+                             log_arg + ': ' + cause + ': ' + \
+                             os.strerror(rcv_errno[0])
                 if rcv_errno[0] == errno.EACCES:
                     error_text += ' - probably need to restart BIND 10 ' + \
                         'as a super user'
@@ -180,6 +151,58 @@ class Parser:
             logger.fatal(BIND10_SOCKCREATOR_TRANSPORT_ERROR, str(se))
             raise CreatorError(str(se), True)
 
+    def get_socket(self, address, port, socktype):
+        """
+        Asks the socket creator process to create a socket. Pass an address
+        (the isc.net.IPaddr object), port number and socket type (either
+        string "UDP", "TCP" or constant socket.SOCK_DGRAM or
+        socket.SOCK_STREAM.
+
+        Blocks until it is provided by the socket creator process (which
+        should be fast, as it is on localhost) and returns the file descriptor
+        number. It raises a CreatorError exception if the creation fails.
+        """
+        if self.__socket is None:
+            raise CreatorError('Socket requested on terminated creator', True)
+        # First, assemble the request from parts
+        logger.info(BIND10_SOCKET_GET, address, port, socktype)
+        data = b'S'
+        if socktype == 'UDP' or socktype == socket.SOCK_DGRAM:
+            data += b'U'
+        elif socktype == 'TCP' or socktype == socket.SOCK_STREAM:
+            data += b'T'
+        else:
+            raise ValueError('Unknown socket type: ' + str(socktype))
+        if address.family == socket.AF_INET:
+            data += b'4'
+        elif address.family == socket.AF_INET6:
+            data += b'6'
+        else:
+            raise ValueError('Unknown address family in address')
+        data += struct.pack('!H', port)
+        data += address.addr
+        log_arg = self.__addrport_str(address, port)
+        return self.__get_socket_helper(data, 'socket', log_arg)
+
+    def get_filter_socket(self, port, iface):
+        """
+        Asks the socket creator process to create a raw filter socket. Pass a
+        port number and interface number.
+
+        Blocks until it is provided by the socket creator process (which
+        should be fast, as it is on localhost) and returns the file descriptor
+        number. It raises a CreatorError exception if the creation fails.
+        """
+        if self.__socket is None:
+            raise CreatorError('Socket requested on terminated creator', True)
+        # First, assemble the request from parts
+        logger.info(BIND10_GET_FILTER_SOCKET, port, iface)
+        data = b'F'
+        data += struct.pack('!H', port)
+        data += struct.pack('!I', iface)
+        log_arg = 'port=%hu interface=%u' % (port, iface)
+        return self.__get_socket_helper(data, 'raw filter socket', log_arg)
+
     def __read_all(self, length):
         """
         Keeps reading until length data is read or EOF or error happens.
diff --git a/src/lib/python/isc/bind10/tests/sockcreator_test.py b/src/lib/python/isc/bind10/tests/sockcreator_test.py
index e87387c..e3fb2fa 100644
--- a/src/lib/python/isc/bind10/tests/sockcreator_test.py
+++ b/src/lib/python/isc/bind10/tests/sockcreator_test.py
@@ -105,8 +105,8 @@ class FakeCreator:
         dlen = len(data)
         prefix, rest = planned[:dlen], planned[dlen:]
         if prefix != data:
-            raise InvalidData('Expected "' + str(prefix)+ '", got "' +
-                str(data) + '"')
+            raise self.InvalidData('Expected "' + str(prefix)+ '", got "' +
+                                   str(data) + '"')
         if len(rest) > 0:
             self.__plan[0] = ('s', rest)
         else:
@@ -253,6 +253,12 @@ class ParserTests(unittest.TestCase):
         self.__create('2001:db8::', socket.SOCK_STREAM,
             b'T6\0\x2A\x20\x01\x0d\xb8\0\0\0\0\0\0\0\0\0\0\0\0')
 
+    def test_create_filter(self):
+        creator = FakeCreator([('s', b'F\0\x2A\0\0\0\x01'),
+                               ('r', b'S'), ('f', 42)])
+        parser = Parser(creator)
+        self.assertEqual(42, parser.get_filter_socket(42, 1))
+
     def test_create_terminated(self):
         """
         Test we can't request sockets after it was terminated.



More information about the bind10-changes mailing list