[svn] commit: r3162 - in /branches/vorner-sockcreator/src/bin/sockcreator: sockcreator.cc sockcreator.h

BIND 10 source code commits bind10-changes at lists.isc.org
Sun Oct 10 08:02:42 UTC 2010


Author: vorner
Date: Sun Oct 10 08:02:42 2010
New Revision: 3162

Log:
The run function

Modified:
    branches/vorner-sockcreator/src/bin/sockcreator/sockcreator.cc
    branches/vorner-sockcreator/src/bin/sockcreator/sockcreator.h

Modified: branches/vorner-sockcreator/src/bin/sockcreator/sockcreator.cc
==============================================================================
--- branches/vorner-sockcreator/src/bin/sockcreator/sockcreator.cc (original)
+++ branches/vorner-sockcreator/src/bin/sockcreator/sockcreator.cc Sun Oct 10 08:02:42 2010
@@ -16,6 +16,10 @@
 
 #include <unistd.h>
 #include <cerrno>
+#include <cstring>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
 
 namespace isc {
 namespace socket_creator {
@@ -42,7 +46,103 @@
 run(const int input_fd, const int output_fd, const get_sock_t get_sock,
     const send_fd_t send_fd)
 {
-    // TODO Implement
+// These are macros so they can exit the function
+#define READ(WHERE, HOW_MANY) do { \
+        size_t how_many = (HOW_MANY); \
+        if (read_data(input_fd, (WHERE), how_many) < how_many) { \
+            return 1; \
+        } \
+    } while (0)
+#define WRITE(WHAT, HOW_MANY) do { \
+        size_t how_many = (HOW_MANY); \
+        if (!write_data(output_fd, (WHAT), (HOW_MANY))) { \
+            return 2; \
+        } \
+    } while (0)
+#define DEFAULT \
+    default: /* Unrecognized part of protocol */ \
+        WRITE("FI", 2); \
+        return 3;
+    for (;;) {
+        // Read the command
+        char command;
+        READ(&command, 1);
+        switch (command) {
+            case 'T': // The "terminate" command
+                return 0;
+            case 'S': { // Create a socket
+                // Read what type of socket they want
+                char type[2];
+                READ(type, 2);
+                // Read the address they ask for
+                struct sockaddr *addr(NULL);
+                size_t addr_len(0);
+                struct sockaddr_in addr_in;
+                struct sockaddr_in6 addr_in6;
+                switch (type[1]) { // The address family
+                    /*
+                     * Here are some casts. They are required by C++ and
+                     * the low-level interface (they are implicit in C).
+                     */
+                    case '4':
+                        addr = static_cast<struct sockaddr *>(
+                            static_cast<void *>(&addr_in));
+                        addr_len = sizeof addr_in;
+                        memset(&addr_in, 0, sizeof addr_in);
+                        addr_in.sin_family = AF_INET;
+                        READ(static_cast<char *>(static_cast<void *>(
+                            &addr_in.sin_port)), 2);
+                        READ(static_cast<char *>(static_cast<void *>(
+                            &addr_in.sin_addr.s_addr)), 4);
+                        break;
+                    case '6':
+                        addr = static_cast<struct sockaddr *>(
+                            static_cast<void *>(&addr_in6));
+                        addr_len = sizeof addr_in6;
+                        memset(&addr_in6, 0, sizeof addr_in6);
+                        addr_in6.sin6_family = AF_INET6;
+                        READ(static_cast<char *>(static_cast<void *>(
+                            &addr_in6.sin6_port)), 2);
+                        READ(static_cast<char *>(static_cast<void *>(
+                            &addr_in6.sin6_addr.s6_addr)), 16);
+                        break;
+                    DEFAULT
+                }
+                int sock_type;
+                switch (type[0]) { // Translate the type
+                    case 'T':
+                        sock_type = SOCK_STREAM;
+                        break;
+                    case 'U':
+                        sock_type = SOCK_DGRAM;
+                        break;
+                    DEFAULT
+                }
+                int result(get_sock(sock_type, addr, addr_len));
+                if (result >= 0) { // We got the socket
+                    WRITE("S", 1);
+                    send_fd(output_fd, result);
+                } else {
+                    WRITE("E", 1);
+                    switch (result) {
+                        case -1:
+                            WRITE("S", 1);
+                            break;
+                        case -2:
+                            WRITE("B", 1);
+                            break;
+                        default:
+                            return 4;
+                    }
+                    int error(errno);
+                    WRITE(static_cast<char *>(static_cast<void *>(&error)),
+                        sizeof error);
+                }
+                break;
+            }
+            DEFAULT
+        }
+    }
 }
 
 bool

Modified: branches/vorner-sockcreator/src/bin/sockcreator/sockcreator.h
==============================================================================
--- branches/vorner-sockcreator/src/bin/sockcreator/sockcreator.h (original)
+++ branches/vorner-sockcreator/src/bin/sockcreator/sockcreator.h Sun Oct 10 08:02:42 2010
@@ -81,6 +81,7 @@
  * - 1: Read error
  * - 2: Write error
  * - 3: Protocol error (unknown command, etc)
+ * - 4: Some internal inconsistency detected
  *
  * It terminates either if a command asks it to or when unrecoverable
  * error happens.




More information about the bind10-changes mailing list