cdk/foundation/socket_detail.h (81 lines of code) (raw):
/*
* Copyright (c) 2015, 2024, Oracle and/or its affiliates.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is designed to work with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms, as
* designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an additional
* permission to link the program and your derivative works with the
* separately licensed software that they have either included with
* the program or referenced in the documentation.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* https://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef CDK_FOUNDATION_SOCKET_DETAIL_H
#define CDK_FOUNDATION_SOCKET_DETAIL_H
#include <mysql/cdk/foundation/types.h>
#include <forward_list>
#include <string>
PUSH_SYS_WARNINGS_CDK
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <netdb.h>
// Note: this is required on Solaris for FIONREAD ioctl constant
#if defined(__sun) || defined(__SCO_VERSION__)
#include <sys/filio.h>
#endif
#endif
POP_SYS_WARNINGS_CDK
namespace cdk {
namespace foundation {
namespace connection {
namespace detail {
#ifdef _WIN32
typedef SOCKET Socket;
const Socket NULL_SOCKET = INVALID_SOCKET;
#else
typedef int Socket;
const Socket NULL_SOCKET = -1;
#endif
enum Shutdown_mode
{
SHUTDOWN_MODE_READ,
SHUTDOWN_MODE_WRITE,
SHUTDOWN_MODE_BOTH
};
enum Poll_mode
{
POLL_MODE_CONNECT,
POLL_MODE_READ,
POLL_MODE_WRITE
};
/**
Changes socket's blocking mode.
Changes blocking mode of an existing TCP/IP socket.
@param[in] socket
Socket being modified.
@param[in] nonblocking
If `true`, sets socket mode to non-blocking. Otherwise, socket is set to
block.
@throw cdk::foundation::Error
Blocking mode change failed.
*/
void set_nonblocking(Socket socket, bool nonblocking);
/**
Initialize socket system.
Initializes socket system (e.g. Winsock), if it is required by a given
platform. Should be called once, before any socket-related operations are
performed.
@throw cdk::foundation::Error
Socket system initialization failed.
*/
void initialize_socket_system();
/**
Uninitialize socket system.
Uninitializes socket system. Should be always called if previous call to
`initialize_socket_system` succeeded.
@throw cdk::foundation::Error
Socket system unintialization failed.
*/
void uninitialize_socket_system();
/**
Create a TCP/IP socket.
Creates a new blocking or non-blocking TCP/IP socket.
@param[in] nonblocking
If `true`, creates a non-blocking socket. Otherwise, a blocking socket is
created.
@param[in] hints
Optional hints for creating a socket.
@throw cdk::foundation::Error
Socket creation failed.
*/
Socket socket(bool nonblocking, addrinfo* hints = 0);
#ifndef _WIN32
/**
Create a Unix domain socket.
Creates a new blocking or non-blocking Unix domain socket.
@param[in] nonblocking
If `true`, creates a non-blocking socket. Otherwise, a blocking socket is
created.
@throw cdk::foundation::Error
Socket creation failed.
*/
Socket unix_socket(bool nonblocking);
#endif //_WIN32
/**
Close a socket.
Closes a socket.
@param[in] socket
Socket to be closed.
@throw cdk::foundation::Error
Socket closing failed.
*/
void close(Socket socket);
/**
Shutdown socket.
Shuts down socket's operations.
@param[in] socket
Socket to be shut down.
@param[in] mode
Shutdown mode.
@throw cdk::foundation::Error
Socket shutdown failed.
*/
void shutdown(Socket socket, Shutdown_mode mode);
/**
Create a `addrinfo` structure from a string.
Creates a `addrinfo` structure from a string address representation and port.
@param[in] host_name
Host name.
@param[in] port
Host port.
@return
`addrinfo` structure.
@throw cdk::foundation::Error
Failed to create a `addrinfo` structure.
@note
This function always blocks.
Result pointer needs to be released with `freeaddrinfo`.
*/
addrinfo* addrinfo_from_string(const char* host_name, unsigned short port);
/**
Create and connect socket.
Creates and connects a socket to a TCP/IP host.
@param[in] host
Destination host name.
@param[in] port
Destination host port.
@param[in] timeout_usec
Timeout in microseconds. 0 means wait indefinitely.
@return
Connected socket.
@throw cdk::foundation::Error
Connection failed.
@note
This function always blocks.
*/
Socket connect(const char *host, unsigned short port,
uint64_t timeout_usec);
#ifndef _WIN32
/**
Create and connect socket.
Creates and connects a socket to a Unix domain socket.
@param[in] path
Destination socket path.
@param[in] timeout_usec
Timeout in microseconds. 0 means wait indefinitely.
@return
Connected socket.
@throw cdk::foundation::Error
Connection failed.
@note
This function always blocks.
*/
Socket connect(const char *path, uint64_t timeout_usec);
#endif //_WIN32
/**
Listen for incoming connections and accept them.
Creates a new socket, binds it to a TCP source port, and listens for
incoming connections. After connection is successfully accepted, a new socket
is created. Listening socket is always closed, even if function fails.
@param[in] port
Source TCP port.
@return
Accepted socket.
@throw cdk::foundation::Error
Either creation of listening socket or accepting of incoming socket failed.
@note
This function always blocks.
*/
Socket listen_and_accept(unsigned short port);
/**
Test socket's I/O state.
Tests if data can be read from or written to a socket without blocking.
@param[in] socket
Socket to be tested.
@param[in] mode
I/O mode.
@param[in] wait
If `true`, function will block. Otherwise, it will return immediately.
@param[in] timeout_usec
Timeout in microsedonds
@return
Same as POSIX `poll` function.
@throw cdk::foundation::Error
If after testing socket is in an erroneous state, function throws.
*/
int poll_one(Socket socket, Poll_mode mode, bool wait,
uint64_t timeout_usec = 0);
/**
Get the number of bytes pending read.
Get the number of bytes available for read in a socket.
@param[in] socket
Socket to be tested.
@return
Number of bytes available for read.
@throw cdk::foundation::Error
Socket testing failed.
*/
size_t bytes_available(Socket socket);
/**
Receives data from a socket.
Receives the exact number of bytes from a socket. This function doesn't
return until all bytes are read or until an error is encountered.
@param[in] socket
Socket used for reading.
@param[out] buffer
Data buffer.
@param[in] buffer_size
Number of bytes that will be read from a socket. May not be larger than
the size of `buffer`.
@throw cdk::foundation::connection::Error_eos
End-of-stream encountered.
@throw cdk::foundation::Error
Socket read failed.
@note
This function always blocks.
*/
void recv(Socket socket, byte *buffer, size_t buffer_size);
/**
Sends data to a socket.
Sends the exact number of bytes to a socket. This function doesn't return
until all bytes are sent or until an error is encountered.
@param[in] socket
Socket used for sending.
@param[in] buffer
Data buffer.
@param[in] buffer_size
Number of bytes that will be sent to a socket. May not be larger than
the size of `buffer`.
@throw cdk::foundation::Error
Socket write failed.
@note
This function always blocks.
*/
void send(Socket socket, const byte *buffer, size_t buffer_size);
/**
Receives some data from a socket.
Receives at most `buffer_size` bytes from a socket.
@param[in] socket
Socket used for reading.
@param[out] buffer
Data buffer.
@param[in] buffer_size
Maximum number of bytes that will be read from a socket. May not be larger
than the size of `buffer`.
@param[in] wait
If `true`, operation will block. Otherwise, data is immediately available.
@return
The number of bytes read from a socket.
@throw cdk::foundation::connection::Error_eos
End-of-stream encountered.
@throw cdk::foundation::Error
Socket read failed.
*/
size_t recv_some(Socket socket, byte *buffer, size_t buffer_size, bool wait);
/**
Sends some data to a socket.
Sends at most `buffer_size` bytes to a socket.
@param[in] socket
Socket used for sending.
@param[in] buffer
Data buffer.
@param[in] buffer_size
Maximum number of bytes that will be sent to a socket. May not be larger
than the size of `buffer`.
@param[in] wait
If `true`, operation will block. Otherwise, it will return immediately.
@return
The number of bytes sent to a socket.
@throw cdk::foundation::Error
Socket write failed.
*/
size_t send_some(Socket socket, const byte *buffer, size_t buffer_size, bool wait);
/**
@brief get_local_hostname returns hostname of the current machine
*/
std::string get_local_hostname();
/*
Retrieve host SRV record (target:port) list for specified service and protocol
*/
struct Srv_host_detail
{
uint16_t prio;
uint16_t weight;
uint16_t port;
string name;
};
std::forward_list<Srv_host_detail> srv_list(const std::string &host_name);
}}}} // cdk::foundation::connection::detail
#endif // CDK_FOUNDATION_SOCKET_DETAIL_H