| 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 | |