1 /*
2  * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License, version 2.0,
6  * as published by the Free Software Foundation.
7  *
8  * This program is also distributed with certain software (including
9  * but not limited to OpenSSL) that is licensed under separate terms,
10  * as designated in a particular file or component or in included license
11  * documentation.  The authors of MySQL hereby grant you an additional
12  * permission to link the program and your derivative works with the
13  * separately licensed software that they have included with MySQL.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License, version 2.0, for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23  */
24 
25 // MySQL DB access module, for use by plugins and others
26 // For the module that implements interactive DB functionality see mod_db
27 
28 #ifndef PLUGIN_X_CLIENT_MYSQLXCLIENT_XCONNECTION_H_
29 #define PLUGIN_X_CLIENT_MYSQLXCLIENT_XCONNECTION_H_
30 
31 #include <string>
32 
33 #include "mysql.h"
34 #include "mysqlxclient/xerror.h"
35 
36 namespace xcl {
37 
38 /**
39   'Enum' that defines allowed version of Internet Protocol.
40 
41   The value defines which "socket-proto" must be used by implementer
42   of XConnection interface also tell the resolver which IP addresses
43   are allowed when resolving hostname to IP address.
44 */
45 enum class Internet_protocol {
46   Any = 0,
47   V4,
48   V6,
49 };
50 
51 /** 'Enum' that defines how the network connection should be closed. */
52 enum class Shutdown_type { Send, Recv, Both };
53 
54 /** 'Enum' that defines the connection type. */
55 enum class Connection_type { Unix_socket, Tcp };
56 
57 /**
58  Interface defining network layer.
59 
60  This is the lowest layer on which XSession or XProtocol implementers
61  can operate on. It defines basic blocking I/O operations on a connection.
62  Additionally it handles all data stream encoding/decoding (for example SSL).
63 */
64 class XConnection {
65  public:
66   /** Interface describing the connection state. */
67   class State {
68    public:
69     virtual ~State() = default;
70 
71     /** Check if SSL was configured */
72     virtual bool is_ssl_configured() const = 0;
73 
74     /** Check if SSL layer works */
75     virtual bool is_ssl_activated() const = 0;
76 
77     /** Check connection state */
78     virtual bool is_connected() const = 0;
79 
80     /** Get version of the SSL protocol used */
81     virtual std::string get_ssl_version() const = 0;
82 
83     /** Get cipher used by SSL layer */
84     virtual std::string get_ssl_cipher() const = 0;
85 
86     /** Get connection type */
87     virtual Connection_type get_connection_type() const = 0;
88 
89     /** Returns true if there is more data in TCP or SSL layers pending */
90     virtual bool has_data() const = 0;
91   };
92 
93  public:
94   virtual ~XConnection() = default;
95 
96   /**
97     Connect to UNIX socket.
98 
99     Connect is going to block until:
100 
101     * operation completed successfully
102     * I/O error occurred
103     * timeout occurred (@ref XSession::Mysqlx_option::Connect_timeout)
104 
105     @param unix_socket   UNIX socket file created by X Plugin
106 
107     @return Object holding result of the operation
108       @retval == true   error occurred
109       @retval == false  operation successful
110   */
111   virtual XError connect_to_localhost(const std::string &unix_socket) = 0;
112 
113   /**
114     Connect to host through TCP/IP.
115 
116     Connect is going to block until:
117 
118     * operation completed successfully
119     * I/O error occurred
120     * timeout occurred
121 
122     @param host     hostname or IPv4 or IPv6 address
123     @param port     TCP port used by X Plugin (running with X Protocol)
124     @param ip_mode  defines allowed IP version
125 
126     @return Object holding result of the operation
127       @retval == true   error occurred
128       @retval == false  operation successful
129   */
130   virtual XError connect(const std::string &host, const uint16_t port,
131                          const Internet_protocol ip_mode) = 0;
132 
133   /**
134     Get the connections file descriptor (socket).
135 
136     Please be aware that after enabling SSL the data could be fetched inside
137     SSLs buffers. Thus checking for activity by executing 'select'
138     could lead to infinite wait. Similar problem can occur after enabling
139     'timeouts' by calling 'set_read_timeout' or 'set_write_timeout'.
140 
141     @return Socket - file descriptor
142   */
143   virtual my_socket get_socket_fd() = 0;
144 
145   /**
146     Activate TLS on the lowest layer.
147 
148     This method activates SSL and validates certificate authority when
149     "SSL mode" is set to:
150 
151     * VERIFY_CA
152     * VERIFY_IDENTITY
153 
154     Other SSL checks are going to be done by layer that calls this method.
155 
156     @return Object holding result of the operation
157       @retval == true   error occurred
158       @retval == false  operation successful
159     */
160   virtual XError activate_tls() = 0;
161 
162   /**
163     Shutdown the connection.
164 
165     @param how_to_shutdown   define which part of the socket
166                              should be closed (sending/receiving)
167 
168     @return Object holding result of the operation
169       @retval == true   error occurred
170       @retval == false  operation successful
171    */
172   virtual XError shutdown(const Shutdown_type how_to_shutdown) = 0;
173 
174   /**
175     Write the data.
176 
177     Write operation is going to block until expected number of bytes has been
178     send on TCP stack. In case when the write-timeout was set, the operation
179     can block at most the given number of seconds.
180 
181     If the SSL is enabled the data is first encoded and then sent.
182 
183     @param data          payload to be sent
184     @param data_length   size of the payload
185 
186     @return Object holding result of the operation
187       @retval == true   error occurred
188       @retval == false  operation successful
189    */
190   virtual XError write(const uint8_t *data, const std::size_t data_length) = 0;
191 
192   /**
193     Read the data.
194 
195     Read operation is going to block until expected number of bytes has been
196     received. In case when the read-timeout was set, the operation can block
197     at most the given number of seconds.
198 
199     If the SSL is enabled the data is first decoded and then put into receive
200     buffer.
201 
202     @param data          buffer which should receive/get data
203     @param data_length   number of bytes which must be read from the
204                          connection
205 
206     @return Object holding result of the operation
207       @retval == true   error occurred
208       @retval == false  operation successful
209    */
210   virtual XError read(uint8_t *data, const std::size_t data_length) = 0;
211 
212   /** Define timeout behavior when reading from the connection:
213 
214   @param deadline_seconds - values greater than 0, set number of seconds which
215                             read operation can block
216                           - value set to zero, do non blocking op
217                           - value less than 0, do blocking op */
218   virtual XError set_read_timeout(const int deadline_seconds) = 0;
219 
220   /** Define timeout behavior when writing from the connection:
221 
222   @param deadline_seconds - values greater than 0, set number of seconds which
223                             write operation can block
224                           - value set to zero, do non blocking op
225                           - value less than 0, do blocking op */
226   virtual XError set_write_timeout(const int deadline_seconds) = 0;
227 
228   /** Close connection. */
229   virtual void close() = 0;
230 
231   /** Get state of the connection. */
232   virtual const State &state() = 0;
233 };
234 
235 }  // namespace xcl
236 
237 #endif  // PLUGIN_X_CLIENT_MYSQLXCLIENT_XCONNECTION_H_
238