sockcreator.h 5.42 KB
Newer Older
1
// Copyright (C) 2011-2012  Internet Systems Consortium, Inc. ("ISC")
2
3
4
5
6
7
8
9
10
11
12
13
14
//
// 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.

15
16
17
18
19
/// \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.
20
21
22
23

#ifndef __SOCKCREATOR_H
#define __SOCKCREATOR_H 1

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

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

namespace isc {
namespace socket_creator {

Stephen Morris's avatar
Stephen Morris committed
34
// Exception classes - the base class exception SocketCreatorError is caught
35
36
37
// 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
38
39
40
41
42
43
44
45
46
47
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:
48
    const int exit_code_;   // Code returned to exit()
Stephen Morris's avatar
Stephen Morris committed
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
};

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



77
78
79
80
81
82
83
84
85
86
87
88
89
/// \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.
///
/// \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()).
90
int
91
getSock(const int type, struct sockaddr* bind_addr, const socklen_t addr_len);
92

93
94
95
96
// Define some types for functions used to perform socket-related operations.
// These are typedefed so that alternatives can be passed through to the
// main functions for testing purposes.

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

// 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);

// 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);


/// \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.
///
119
/// \param input_fd File number of the stream from which the input commands
120
///        are read.
121
122
123
/// \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.
124
125
126
127
128
129
130
131
132
133
134
135
136
/// \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
///        unistd.h. It can be overriden in tests.
///
/// \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
Stephen Morris's avatar
Stephen Morris committed
137
void
138
139
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);
140

141
142
}   // namespace socket_creator
}   // NAMESPACE ISC
143
144

#endif // __SOCKCREATOR_H