sockcreator.h 5.11 KB
Newer Older
1
// Copyright (C) 2011-2012, 2015  Internet Systems Consortium, Inc. ("ISC")
2
//
3 4 5
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6

7 8 9 10 11
/// \file sockcreator.h
/// \short Socket creator functionality.
///
/// This module holds the functionality of the socket creator. It is a separate
/// module from main to make testing easier.
12

13 14
#ifndef SOCKCREATOR_H
#define SOCKCREATOR_H 1
15

16
#include <util/io/fd_share.h>
Stephen Morris's avatar
Stephen Morris committed
17
#include <exceptions/exceptions.h>
18

19 20
#include <sys/types.h>
#include <sys/socket.h>
21
#include <unistd.h>
22 23 24 25

namespace isc {
namespace socket_creator {

Stephen Morris's avatar
Stephen Morris committed
26
// Exception classes - the base class exception SocketCreatorError is caught
27 28 29
// by main() and holds an exit code returned to the environment.  The code
// depends on the exact exception raised.
class SocketCreatorError : public isc::Exception {
Stephen Morris's avatar
Stephen Morris committed
30 31 32 33 34 35 36 37 38 39
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:
40
    const int exit_code_;   // Code returned to exit()
Stephen Morris's avatar
Stephen Morris committed
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
};

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) {}
};


68 69 70
// Type of the close() function, so it can be passed as a parameter.
// Argument is the same as that for close(2).
typedef int (*close_t)(int);
Stephen Morris's avatar
Stephen Morris committed
71

72 73 74 75 76 77 78 79
/// \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.
///
/// \param type The type of socket to create (SOCK_STREAM, SOCK_DGRAM, etc).
/// \param bind_addr The address to bind.
/// \param addr_len The actual length of bind_addr.
80
/// \param close_fun The function used to close a socket if there's an error
81
///     after the creation.
82 83 84 85 86
///
/// \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 left intact from socket() or bind()).
87
int
88 89
getSock(const int type, struct sockaddr* bind_addr, const socklen_t addr_len,
        const close_t close_fun);
90

91
// Define some types for functions used to perform socket-related operations.
Francis Dupont's avatar
Francis Dupont committed
92
// These are typedef'ed so that alternatives can be passed through to the
93 94
// main functions for testing purposes.

95 96
// Type of the function to get a socket and to pass it as parameter.
// Arguments are those described above for getSock().
97 98
typedef int (*get_sock_t)(const int, struct sockaddr *, const socklen_t,
                          const close_t close_fun);
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

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


/// \brief 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.
///
114
/// \param input_fd File number of the stream from which the input commands
115
///        are read.
116 117 118
/// \param output_fd File number of the stream to which the response is
///        written.  The socket is sent as part of a control message associated
///        with that stream.
119 120 121 122 123 124 125
/// \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.
/// \param close_fun The close function used to close sockets, coming from
Francis Dupont's avatar
Francis Dupont committed
126
///        unistd.h. It can be overridden in tests.
127 128 129
///
/// \exception isc::socket_creator::ReadError Error reading from input
/// \exception isc::socket_creator::WriteError Error writing to output
Francis Dupont's avatar
Francis Dupont committed
130
/// \exception isc::socket_creator::ProtocolError Unrecognized command received
131
/// \exception isc::socket_creator::InternalError Other error
Stephen Morris's avatar
Stephen Morris committed
132
void
133 134
run(const int input_fd, const int output_fd, get_sock_t get_sock_fun,
    send_fd_t send_fd_fun, close_t close_fun);
135

136 137
}   // namespace socket_creator
}   // NAMESPACE ISC
138

139
#endif // SOCKCREATOR_H