Line data Source code
1 : // Copyright (c) 2012-2019 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // This program is free software; you can redistribute it and/or modify
4 : // it under the terms of the GNU General Public License as published by
5 : // the Free Software Foundation; either version 2 of the License, or
6 : // (at your option) any later version.
7 : //
8 : // This program is distributed in the hope that it will be useful,
9 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 : // GNU General Public License for more details.
12 : //
13 : // You should have received a copy of the GNU General Public License
14 : // along with this program; if not, write to the Free Software
15 : // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 :
17 : /** \file
18 : * \brief Implementation of the Snap Communicator class.
19 : *
20 : * This class wraps the C poll() interface in a C++ object with many types
21 : * of objects:
22 : *
23 : * \li Server Connections; for software that want to offer a port to
24 : * which clients can connect to; the server will call accept()
25 : * once a new client connection is ready; this results in a
26 : * Server/Client connection object
27 : * \li Client Connections; for software that want to connect to
28 : * a server; these expect the IP address and port to connect to
29 : * \li Server/Client Connections; for the server when it accepts a new
30 : * connection; in this case the server gets a socket from accept()
31 : * and creates one of these objects to handle the connection
32 : *
33 : * Using the poll() function is the easiest and allows us to listen
34 : * on pretty much any number of sockets (on my server it is limited
35 : * at 16,768 and frankly over 1,000 we probably will start to have
36 : * real slowness issues on small VPN servers.)
37 : */
38 :
39 : // to get the POLLRDHUP definition
40 : #ifndef _GNU_SOURCE
41 : #define _GNU_SOURCE
42 : #endif
43 :
44 :
45 : // self
46 : //
47 : #include "eventdispatcher/tcp_client_connection.h"
48 :
49 : //#include "eventdispatcher/snap_communicator_dispatcher.h"
50 : //
51 : //
52 : //// snaplogger lib
53 : ////
54 : //#include "snaplogger/message.h"
55 : //
56 : //
57 : //// snapdev lib
58 : ////
59 : //#include "snapdev/not_reached.h"
60 : //#include "snapdev/not_used.h"
61 : //#include "snapdev/string_replace_many.h"
62 : //
63 : //
64 : //// libaddr lib
65 : ////
66 : //#include "libaddr/addr_parser.h"
67 : //
68 : //
69 : //// C++ lib
70 : ////
71 : //#include <sstream>
72 : //#include <limits>
73 : //#include <atomic>
74 : //
75 : //
76 : //// C lib
77 : ////
78 : //#include <fcntl.h>
79 : //#include <poll.h>
80 : //#include <unistd.h>
81 : //#include <sys/eventfd.h>
82 : //#include <sys/inotify.h>
83 : //#include <sys/ioctl.h>
84 : //#include <sys/resource.h>
85 : //#include <sys/syscall.h>
86 : //#include <sys/time.h>
87 :
88 :
89 : // last include
90 : //
91 : #include <snapdev/poison.h>
92 :
93 :
94 :
95 : namespace ed
96 : {
97 :
98 :
99 :
100 : /** \brief Initializes the client connection.
101 : *
102 : * This function creates a connection using the address, port, and mode
103 : * parameters. This is very similar to using the bio_client class to
104 : * create a connection, only the resulting connection can be used with
105 : * the snap_communicator object.
106 : *
107 : * \note
108 : * The function also saves the remote address and port used to open
109 : * the connection which can later be retrieved using the
110 : * get_remote_address() function. That address will remain valid
111 : * even after the socket is closed.
112 : *
113 : * \todo
114 : * If the remote address is an IPv6, we need to put it between [...]
115 : * (i.e. [::1]:4040) so we can extract the port safely.
116 : *
117 : * \param[in] communicator The snap communicator controlling this connection.
118 : * \param[in] addr The address of the server to connect to.
119 : * \param[in] port The port to connect to.
120 : * \param[in] mode Type of connection: plain or secure.
121 : */
122 0 : tcp_client_connection::tcp_client_connection(std::string const & addr, int port, mode_t mode)
123 : : tcp_bio_client(addr, port, mode)
124 0 : , f_remote_address(get_client_addr() + ":" + std::to_string(get_client_port()))
125 : {
126 0 : }
127 :
128 :
129 : /** \brief Retrieve the remote address information.
130 : *
131 : * This function can be used to retrieve the remove address and port
132 : * information as was specified on the constructor. These can be used
133 : * to find this specific connection at a later time or create another
134 : * connection.
135 : *
136 : * For example, you may get 192.168.2.17:4040.
137 : *
138 : * The function works even after the socket gets closed as we save
139 : * the remote address and port in a string just after the connection
140 : * was established.
141 : *
142 : * \note
143 : * These parameters are the same as what was passed to the constructor,
144 : * only both will have been converted to numbers. So for example when
145 : * you used "localhost", here you get "::1" or "127.0.0.1" for the
146 : * address.
147 : *
148 : * \return The remote host address and connection port.
149 : */
150 0 : std::string const & tcp_client_connection::get_remote_address() const
151 : {
152 0 : return f_remote_address;
153 : }
154 :
155 :
156 : /** \brief Read from the client socket.
157 : *
158 : * This function reads data from the client socket and copy it in
159 : * \p buf. A maximum of \p count bytes are read.
160 : *
161 : * \param[in,out] buf The buffer where the data is read.
162 : * \param[in] count The maximum number of bytes to read.
163 : *
164 : * \return -1 if an error occurs, zero if no data gets read, a positive
165 : * number representing the number of bytes read otherwise.
166 : */
167 0 : ssize_t tcp_client_connection::read(void * buf, size_t count)
168 : {
169 0 : if(get_socket() == -1)
170 : {
171 0 : errno = EBADF;
172 0 : return -1;
173 : }
174 0 : return tcp_bio_client::read(reinterpret_cast<char *>(buf), count);
175 : }
176 :
177 :
178 : /** \brief Write to the client socket.
179 : *
180 : * This function writes \p count bytes from \p buf to this
181 : * client socket.
182 : *
183 : * The function can safely be called after the socket was closed, although
184 : * it will return -1 and set errno to EBADF in tha case.
185 : *
186 : * \param[in] buf The buffer to write to the client connection socket.
187 : * \param[in] count The maximum number of bytes to write on this connection.
188 : *
189 : * \return -1 if an error occurs, zero if nothing was written, a positive
190 : * number representing the number of bytes successfully written.
191 : */
192 0 : ssize_t tcp_client_connection::write(void const * buf, size_t count)
193 : {
194 0 : if(get_socket() == -1)
195 : {
196 0 : errno = EBADF;
197 0 : return -1;
198 : }
199 0 : return tcp_bio_client::write(reinterpret_cast<char const *>(buf), count);
200 : }
201 :
202 :
203 : /** \brief Check whether this connection is a reader.
204 : *
205 : * We change the default to true since TCP sockets are generally
206 : * always readers. You can still overload this function and
207 : * return false if necessary.
208 : *
209 : * However, we do not overload the is_writer() because that is
210 : * much more dynamic (i.e. you do not want to advertise as
211 : * being a writer unless you have data to write to the
212 : * socket.)
213 : *
214 : * \return The events to listen to for this connection.
215 : */
216 0 : bool tcp_client_connection::is_reader() const
217 : {
218 0 : return true;
219 : }
220 :
221 :
222 : /** \brief Retrieve the socket of this client connection.
223 : *
224 : * This function retrieves the socket this client connection. In this case
225 : * the socket is defined in the bio_client class.
226 : *
227 : * \return The socket of this client connection.
228 : */
229 0 : int tcp_client_connection::get_socket() const
230 : {
231 0 : return tcp_bio_client::get_socket();
232 : }
233 :
234 :
235 :
236 : } // namespace ed
237 : // vim: ts=4 sw=4 et
|