1 | /* Copyright (c) 2000, 2012, Oracle and/or its affiliates. |
2 | Copyright (c) 2012, 2017, MariaDB Corporation. |
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 as published by |
6 | the Free Software Foundation; version 2 of the License. |
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 | /* |
18 | * Vio Lite. |
19 | * Purpose: include file for Vio that will work with C and C++ |
20 | */ |
21 | |
22 | #ifndef vio_violite_h_ |
23 | #define vio_violite_h_ |
24 | |
25 | #include "my_net.h" /* needed because of struct in_addr */ |
26 | #include <mysql/psi/mysql_socket.h> |
27 | |
28 | /* Simple vio interface in C; The functions are implemented in violite.c */ |
29 | |
30 | #ifdef __cplusplus |
31 | extern "C" { |
32 | #endif /* __cplusplus */ |
33 | |
34 | #ifdef __cplusplus |
35 | typedef struct st_vio Vio; |
36 | #endif /* __cplusplus */ |
37 | |
38 | enum enum_vio_type |
39 | { |
40 | VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET, VIO_TYPE_NAMEDPIPE, |
41 | VIO_TYPE_SSL, VIO_TYPE_SHARED_MEMORY |
42 | }; |
43 | |
44 | /** |
45 | VIO I/O events. |
46 | */ |
47 | enum enum_vio_io_event |
48 | { |
49 | VIO_IO_EVENT_READ, |
50 | VIO_IO_EVENT_WRITE, |
51 | VIO_IO_EVENT_CONNECT |
52 | }; |
53 | |
54 | struct vio_keepalive_opts |
55 | { |
56 | int interval; |
57 | int idle; |
58 | int probes; |
59 | }; |
60 | |
61 | |
62 | #define VIO_LOCALHOST 1U /* a localhost connection */ |
63 | #define VIO_BUFFERED_READ 2U /* use buffered read */ |
64 | #define VIO_READ_BUFFER_SIZE 16384U /* size of read buffer */ |
65 | #define VIO_DESCRIPTION_SIZE 30 /* size of description */ |
66 | |
67 | Vio* vio_new(my_socket sd, enum enum_vio_type type, uint flags); |
68 | Vio* mysql_socket_vio_new(MYSQL_SOCKET mysql_socket, enum enum_vio_type type, uint flags); |
69 | #ifdef __WIN__ |
70 | Vio* vio_new_win32pipe(HANDLE hPipe); |
71 | Vio* vio_new_win32shared_memory(HANDLE handle_file_map, |
72 | HANDLE handle_map, |
73 | HANDLE event_server_wrote, |
74 | HANDLE event_server_read, |
75 | HANDLE event_client_wrote, |
76 | HANDLE event_client_read, |
77 | HANDLE event_conn_closed); |
78 | #else |
79 | #define HANDLE void * |
80 | #endif /* __WIN__ */ |
81 | |
82 | void vio_delete(Vio* vio); |
83 | int vio_close(Vio* vio); |
84 | my_bool vio_reset(Vio* vio, enum enum_vio_type type, |
85 | my_socket sd, void *ssl, uint flags); |
86 | size_t vio_read(Vio *vio, uchar * buf, size_t size); |
87 | size_t vio_read_buff(Vio *vio, uchar * buf, size_t size); |
88 | size_t vio_write(Vio *vio, const uchar * buf, size_t size); |
89 | int vio_blocking(Vio *vio, my_bool onoff, my_bool *old_mode); |
90 | my_bool vio_is_blocking(Vio *vio); |
91 | /* setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible */ |
92 | int vio_fastsend(Vio *vio); |
93 | /* setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible */ |
94 | int vio_keepalive(Vio *vio, my_bool onoff); |
95 | int vio_set_keepalive_options(Vio * vio, const struct vio_keepalive_opts *opts); |
96 | /* Whenever we should retry the last read/write operation. */ |
97 | my_bool vio_should_retry(Vio *vio); |
98 | /* Check that operation was timed out */ |
99 | my_bool vio_was_timeout(Vio *vio); |
100 | /* Short text description of the socket for those, who are curious.. */ |
101 | const char* vio_description(Vio *vio); |
102 | /* Return the type of the connection */ |
103 | enum enum_vio_type vio_type(Vio* vio); |
104 | /* Return last error number */ |
105 | int vio_errno(Vio*vio); |
106 | /* Get socket number */ |
107 | my_socket vio_fd(Vio*vio); |
108 | /* Remote peer's address and name in text form */ |
109 | my_bool vio_peer_addr(Vio *vio, char *buf, uint16 *port, size_t buflen); |
110 | /* Wait for an I/O event notification. */ |
111 | int vio_io_wait(Vio *vio, enum enum_vio_io_event event, int timeout); |
112 | my_bool vio_is_connected(Vio *vio); |
113 | #ifndef DBUG_OFF |
114 | ssize_t vio_pending(Vio *vio); |
115 | #endif |
116 | /* Set timeout for a network operation. */ |
117 | extern int vio_timeout(Vio *vio, uint which, int timeout_sec); |
118 | extern void vio_set_wait_callback(void (*before_wait)(void), |
119 | void (*after_wait)(void)); |
120 | /* Connect to a peer. */ |
121 | my_bool vio_socket_connect(Vio *vio, struct sockaddr *addr, socklen_t len, |
122 | int timeout); |
123 | |
124 | void vio_get_normalized_ip(const struct sockaddr *src, size_t src_length, struct sockaddr *dst); |
125 | |
126 | my_bool vio_get_normalized_ip_string(const struct sockaddr *addr, size_t addr_length, |
127 | char *ip_string, size_t ip_string_size); |
128 | |
129 | my_bool vio_is_no_name_error(int err_code); |
130 | |
131 | int vio_getnameinfo(const struct sockaddr *sa, |
132 | char *hostname, size_t hostname_size, |
133 | char *port, size_t port_size, |
134 | int flags); |
135 | |
136 | #ifdef HAVE_OPENSSL |
137 | /* apple deprecated openssl in MacOSX Lion */ |
138 | #ifdef __APPLE__ |
139 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" |
140 | #endif |
141 | |
142 | #define dummy_something |
143 | #define YASSL_MYSQL_COMPATIBLE |
144 | #ifndef YASSL_PREFIX |
145 | #define YASSL_PREFIX |
146 | #endif |
147 | /* Set yaSSL to use same type as MySQL do for socket handles */ |
148 | typedef my_socket YASSL_SOCKET_T; |
149 | #define YASSL_SOCKET_T_DEFINED |
150 | #include <openssl/ssl.h> |
151 | #include <openssl/err.h> |
152 | |
153 | enum enum_ssl_init_error |
154 | { |
155 | SSL_INITERR_NOERROR= 0, SSL_INITERR_CERT, SSL_INITERR_KEY, |
156 | SSL_INITERR_NOMATCH, SSL_INITERR_BAD_PATHS, SSL_INITERR_CIPHERS, |
157 | SSL_INITERR_MEMFAIL, SSL_INITERR_DH, SSL_INITERR_LASTERR |
158 | }; |
159 | const char* sslGetErrString(enum enum_ssl_init_error err); |
160 | |
161 | struct st_VioSSLFd |
162 | { |
163 | SSL_CTX *ssl_context; |
164 | }; |
165 | |
166 | int sslaccept(struct st_VioSSLFd*, Vio *, long timeout, unsigned long *errptr); |
167 | int sslconnect(struct st_VioSSLFd*, Vio *, long timeout, unsigned long *errptr); |
168 | |
169 | struct st_VioSSLFd |
170 | *new_VioSSLConnectorFd(const char *key_file, const char *cert_file, |
171 | const char *ca_file, const char *ca_path, |
172 | const char *cipher, enum enum_ssl_init_error *error, |
173 | const char *crl_file, const char *crl_path); |
174 | struct st_VioSSLFd |
175 | *new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, |
176 | const char *ca_file,const char *ca_path, |
177 | const char *cipher, enum enum_ssl_init_error *error, |
178 | const char *crl_file, const char *crl_path); |
179 | void free_vio_ssl_acceptor_fd(struct st_VioSSLFd *fd); |
180 | #endif /* HAVE_OPENSSL */ |
181 | |
182 | void vio_end(void); |
183 | |
184 | #ifdef __cplusplus |
185 | } |
186 | #endif |
187 | |
188 | #if !defined(DONT_MAP_VIO) |
189 | #define vio_delete(vio) (vio)->viodelete(vio) |
190 | #define vio_errno(vio) (vio)->vioerrno(vio) |
191 | #define vio_read(vio, buf, size) ((vio)->read)(vio,buf,size) |
192 | #define vio_write(vio, buf, size) ((vio)->write)(vio, buf, size) |
193 | #define vio_blocking(vio, set_blocking_mode, old_mode)\ |
194 | (vio)->vioblocking(vio, set_blocking_mode, old_mode) |
195 | #define vio_is_blocking(vio) (vio)->is_blocking(vio) |
196 | #define vio_fastsend(vio) (vio)->fastsend(vio) |
197 | #define vio_keepalive(vio, set_keep_alive) (vio)->viokeepalive(vio, set_keep_alive) |
198 | #define vio_should_retry(vio) (vio)->should_retry(vio) |
199 | #define vio_was_timeout(vio) (vio)->was_timeout(vio) |
200 | #define vio_close(vio) ((vio)->vioclose)(vio) |
201 | #define vio_shutdown(vio,how) ((vio)->shutdown)(vio,how) |
202 | #define vio_peer_addr(vio, buf, prt, buflen) (vio)->peer_addr(vio, buf, prt, buflen) |
203 | #define vio_io_wait(vio, event, timeout) (vio)->io_wait(vio, event, timeout) |
204 | #define vio_is_connected(vio) (vio)->is_connected(vio) |
205 | #endif /* !defined(DONT_MAP_VIO) */ |
206 | |
207 | #ifdef _WIN32 |
208 | |
209 | /* shutdown(2) flags */ |
210 | #ifndef SHUT_RD |
211 | #define SHUT_RD SD_RECEIVE |
212 | #endif |
213 | |
214 | #endif |
215 | |
216 | /* This enumerator is used in parser - should be always visible */ |
217 | enum SSL_type |
218 | { |
219 | SSL_TYPE_NOT_SPECIFIED= -1, |
220 | SSL_TYPE_NONE, |
221 | SSL_TYPE_ANY, |
222 | SSL_TYPE_X509, |
223 | SSL_TYPE_SPECIFIED |
224 | }; |
225 | |
226 | /* HFTODO - hide this if we don't want client in embedded server */ |
227 | /* This structure is for every connection on both sides */ |
228 | struct st_vio |
229 | { |
230 | MYSQL_SOCKET mysql_socket; /* Instrumented socket */ |
231 | my_bool localhost; /* Are we from localhost? */ |
232 | int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */ |
233 | struct sockaddr_storage local; /* Local internet address */ |
234 | struct sockaddr_storage remote; /* Remote internet address */ |
235 | enum enum_vio_type type; /* Type of connection */ |
236 | const char *desc; /* String description */ |
237 | char *read_buffer; /* buffer for vio_read_buff */ |
238 | char *read_pos; /* start of unfetched data in the |
239 | read buffer */ |
240 | char *read_end; /* end of unfetched data */ |
241 | struct mysql_async_context *async_context; /* For non-blocking API */ |
242 | int read_timeout; /* Timeout value (ms) for read ops. */ |
243 | int write_timeout; /* Timeout value (ms) for write ops. */ |
244 | /* function pointers. They are similar for socket/SSL/whatever */ |
245 | void (*viodelete)(Vio*); |
246 | int (*vioerrno)(Vio*); |
247 | size_t (*read)(Vio*, uchar *, size_t); |
248 | size_t (*write)(Vio*, const uchar *, size_t); |
249 | int (*timeout)(Vio*, uint, my_bool); |
250 | int (*vioblocking)(Vio*, my_bool, my_bool *); |
251 | my_bool (*is_blocking)(Vio*); |
252 | int (*viokeepalive)(Vio*, my_bool); |
253 | int (*fastsend)(Vio*); |
254 | my_bool (*peer_addr)(Vio*, char *, uint16*, size_t); |
255 | void (*in_addr)(Vio*, struct sockaddr_storage*); |
256 | my_bool (*should_retry)(Vio*); |
257 | my_bool (*was_timeout)(Vio*); |
258 | int (*vioclose)(Vio*); |
259 | my_bool (*is_connected)(Vio*); |
260 | int (*shutdown)(Vio *, int); |
261 | my_bool (*has_data) (Vio*); |
262 | int (*io_wait)(Vio*, enum enum_vio_io_event, int); |
263 | my_bool (*connect)(Vio*, struct sockaddr *, socklen_t, int); |
264 | #ifdef HAVE_OPENSSL |
265 | void *ssl_arg; |
266 | #endif |
267 | #ifdef HAVE_SMEM |
268 | HANDLE handle_file_map; |
269 | char *handle_map; |
270 | HANDLE event_server_wrote; |
271 | HANDLE event_server_read; |
272 | HANDLE event_client_wrote; |
273 | HANDLE event_client_read; |
274 | HANDLE event_conn_closed; |
275 | size_t shared_memory_remain; |
276 | char *shared_memory_pos; |
277 | #endif /* HAVE_SMEM */ |
278 | #ifdef _WIN32 |
279 | HANDLE hPipe; |
280 | OVERLAPPED overlapped; |
281 | DWORD read_timeout_ms; |
282 | DWORD write_timeout_ms; |
283 | #endif |
284 | }; |
285 | #endif /* vio_violite_h_ */ |
286 | |