Commit 66bb0f76 authored by Michal Vaner's avatar Michal Vaner

The run function

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/vorner-sockcreator@3162 e5f2f494-b856-4b98-b285-d166d9295462
parent 26b876a0
......@@ -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 @@ int
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
......
......@@ -81,6 +81,7 @@ int
* - 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.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment