sockcreator.h 4.92 KB
Newer Older
1
// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

/**
 * \file sockcreator.h
 * \short Socket creator functionality.
 *
 * This module holds the functionality of the socket creator. It is
 * a separate module from main to ease up the tests.
 */

#ifndef __SOCKCREATOR_H
#define __SOCKCREATOR_H 1

26
#include <util/io/fd_share.h>
Stephen Morris's avatar
Stephen Morris committed
27
#include <exceptions/exceptions.h>
28

29 30
#include <sys/types.h>
#include <sys/socket.h>
31
#include <unistd.h>
32 33 34 35

namespace isc {
namespace socket_creator {

Stephen Morris's avatar
Stephen Morris committed
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
// Exception classes - the base class exception SocketCreatorError is caught
// by main(), and holds a reason code returned to the environment.  The code
// depends on the exception raised.
class SocketCreatorError : public Exception {
public:
    SocketCreatorError(const char* file, size_t line, const char* what,
                       int exit_code) :
        isc::Exception(file, line, what), exit_code_(exit_code) {}

    int getExitCode() const {
        return (exit_code_);
    }

private:
    int     exit_code_;     // Code returned to exit()
};

class ReadError : public SocketCreatorError {
public:
    ReadError(const char* file, size_t line, const char* what) :
        SocketCreatorError(file, line, what, 1) {}
};

class WriteError : public SocketCreatorError {
public:
    WriteError(const char* file, size_t line, const char* what) :
        SocketCreatorError(file, line, what, 2) {}
};

class ProtocolError : public SocketCreatorError {
public:
    ProtocolError(const char* file, size_t line, const char* what) :
        SocketCreatorError(file, line, what, 3) {}
};

class InternalError : public SocketCreatorError {
public:
    InternalError(const char* file, size_t line, const char* what) :
        SocketCreatorError(file, line, what, 4) {}
};



79 80 81 82 83 84 85 86 87 88 89 90
/**
 * \short Create a socket and bind it.
 *
 * This is just a bundle of socket() and bind() calls. The sa_family of
 * bind_addr is used to determine the domain of the socket.
 *
 * \return The file descriptor of the newly created socket, if everything
 *     goes well. A negative number is returned if an error occurs -
 *     -1 if the socket() call fails or -2 if bind() fails. In case of error,
 *     errno is set (or better, left intact from socket() or bind()).
 * \param type The type of socket to create (SOCK_STREAM, SOCK_DGRAM, etc).
 * \param bind_addr The address to bind.
91
 * \param addr_len The actual length of bind_addr.
92 93
 */
int
94
get_sock(const int type, struct sockaddr *bind_addr, const socklen_t addr_len);
95 96 97 98 99 100

/**
 * Type of the get_sock function, to pass it as parameter.
 */
typedef
int
101
(*get_sock_t)(const int, struct sockaddr *, const socklen_t);
102 103 104 105 106 107 108 109

/**
 * Type of the send_fd() function, so it can be passed as a parameter.
 */
typedef
int
(*send_fd_t)(const int, const int);

110 111 112 113 114
/// \brief Type of the close() function, so it can be passed as a parameter.
typedef
int
(*close_t)(int);

115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
/**
 * \short Infinite loop parsing commands and returning the sockets.
 *
 * This reads commands and socket descriptions from the input_fd
 * file descriptor, creates sockets and writes the results (socket or
 * error) to output_fd.
 *
 * It terminates either if a command asks it to or when unrecoverable
 * error happens.
 *
 * \param input_fd Here is where it reads the commads.
 * \param output_fd Here is where it writes the results.
 * \param get_sock_fun The function that is used to create the sockets.
 *     This should be left on the default value, the parameter is here
 *     for testing purposes.
 * \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.
133
 * \param close_fun The close function used to close sockets, coming from
134
 *     unistd.h. It can be overriden in tests.
Stephen Morris's avatar
Stephen Morris committed
135 136 137 138 139
 *
 * \exception isc::socket_creator::ReadError Error reading from input
 * \exception isc::socket_creator::WriteError Error writing to output
 * \exception isc::socket_creator::ProtocolError Unrecognised command received
 * \exception isc::socket_creator::InternalError Other error
140
 */
Stephen Morris's avatar
Stephen Morris committed
141
void
142 143
run(const int input_fd, const int output_fd,
    const get_sock_t get_sock_fun = get_sock,
144
    const send_fd_t send_fd_fun = isc::util::io::send_fd,
145
    const close_t close_fun = close);
146

147
} // End of the namespaces
148 149 150
}

#endif // __SOCKCREATOR_H