[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