47#include <umock/sys_socket.hpp>
48#include <umock/ssl.hpp>
58#ifdef UPnPsdk_HAVE_OPENSSL
85 [[maybe_unused]]
const char* a_writebuf,
87 const size_t a_bufsize,
91 time_t start_time{time(NULL)};
92 TRACE(
"Executing sock_read_unprotected()")
95 if (a_info ==
nullptr || a_readbuf ==
nullptr || a_bufsize > INT_MAX)
100 SOCKET sockfd{a_info->
socket};
106 FD_SET(sockfd, &readSet);
109 int timeout_secs = (a_timeoutSecs ==
nullptr) ? UPnPsdk::g_response_timeout
117 timeout.tv_sec = timeout_secs;
121 int retCode = umock::sys_socket_h.select(
122 static_cast<int>(sockfd + 1), &readSet, &writeSet,
nullptr,
123 (timeout_secs < 0) ?
nullptr : &timeout);
127 if (retCode == SOCKET_ERROR) {
129 if (sockerrObj == EINTRP)
138 TRACE(
"Read data with syscall ::recv().")
139 SSIZEP_T numBytes = umock::sys_socket_h.recv(
140 sockfd, a_readbuf,
static_cast<SIZEP_T
>(a_bufsize), 0);
143 if (numBytes < 0 || numBytes > INT_MAX)
147 if (a_timeoutSecs !=
nullptr && timeout_secs != 0)
148 *a_timeoutSecs -=
static_cast<int>(time(NULL) - start_time);
150 return static_cast<int>(numBytes);
168 [[maybe_unused]]
char* a_readbuf,
170 const char* a_writebuf,
172 const size_t a_bufsize,
175 int* a_timeoutSecs) {
176 time_t start_time{time(NULL)};
177 TRACE(
"Executing sock_write_unprotected()")
180 if (a_info ==
nullptr || a_writebuf ==
nullptr || a_bufsize > INT_MAX)
185 SOCKET sockfd{a_info->
socket};
191 FD_SET(sockfd, &writeSet);
194 int timeout_secs = (a_timeoutSecs ==
nullptr) ? UPnPsdk::g_response_timeout
202 timeout.tv_sec = timeout_secs;
206 int retCode = umock::sys_socket_h.select(
207 static_cast<int>(sockfd + 1), &readSet, &writeSet,
nullptr,
208 (timeout_secs < 0) ?
nullptr : &timeout);
212 if (retCode == SOCKET_ERROR) {
214 if (sockerrObj == EINTRP)
224 ssize_t byte_left{
static_cast<ssize_t
>(a_bufsize)};
225 ssize_t bytes_sent{};
227 TRACE(
"Write data with syscall ::send().")
228 UPNPLIB_SCOPED_NO_SIGPIPE
229 while (byte_left != 0) {
230 ssize_t num_written = umock::sys_socket_h.send(
231 sockfd, a_writebuf + bytes_sent,
static_cast<SIZEP_T
>(byte_left),
233 if (num_written == -1 || num_written > INT_MAX) {
236 byte_left -= num_written;
237 bytes_sent += num_written;
241 if (bytes_sent < 0 || bytes_sent > INT_MAX)
245 if (a_timeoutSecs !=
nullptr && timeout_secs != 0)
246 *a_timeoutSecs -=
static_cast<int>(time(NULL) - start_time);
248 return static_cast<int>(bytes_sent);
252#ifdef UPnPsdk_HAVE_OPENSSL
270 [[maybe_unused]]
const char* a_writebuf,
272 const size_t a_bufsize,
275 int* a_timeoutSecs) {
276 time_t start_time{time(NULL)};
277 TRACE(
"Executing sock_read_ssl()")
280 if (a_info ==
nullptr || a_readbuf ==
nullptr || a_bufsize > INT_MAX)
285 SOCKET sockfd{a_info->
socket};
291 FD_SET(sockfd, &readSet);
294 int timeout_secs = (a_timeoutSecs ==
nullptr) ? UPnPsdk::g_response_timeout
302 timeout.tv_sec = timeout_secs;
306 int retCode = umock::sys_socket_h.select(
307 static_cast<int>(sockfd + 1), &readSet, &writeSet,
nullptr,
308 (timeout_secs < 0) ?
nullptr : &timeout);
312 if (retCode == SOCKET_ERROR) {
314 if (sockerrObj == EINTRP)
323 TRACE(
"Read data with syscall ::SSL_read().")
325 int numBytes = umock::ssl_h.SSL_read(a_info->
ssl, a_readbuf,
326 static_cast<int>(a_bufsize));
332 if (a_timeoutSecs !=
nullptr && timeout_secs != 0)
333 *a_timeoutSecs -=
static_cast<int>(time(NULL) - start_time);
355 [[maybe_unused]]
char* a_readbuf,
357 const char* a_writebuf,
359 const size_t a_bufsize,
362 int* a_timeoutSecs) {
363 time_t start_time{time(NULL)};
364 TRACE(
"Executing sock_write_ssl()")
367 if (a_info ==
nullptr || a_writebuf ==
nullptr || a_bufsize > INT_MAX)
372 SOCKET sockfd{a_info->
socket};
378 FD_SET(sockfd, &writeSet);
381 int timeout_secs = (a_timeoutSecs ==
nullptr) ? UPnPsdk::g_response_timeout
389 timeout.tv_sec = timeout_secs;
393 int retCode = umock::sys_socket_h.select(
394 static_cast<int>(sockfd + 1), &readSet, &writeSet,
nullptr,
395 (timeout_secs < 0) ?
nullptr : &timeout);
399 if (retCode == SOCKET_ERROR) {
401 if (sockerrObj == EINTRP)
410 int byte_left{
static_cast<int>(a_bufsize)};
413 UPNPLIB_SCOPED_NO_SIGPIPE
414 while (byte_left != 0) {
415 TRACE(
"Write data with syscall ::SSL_write().")
416 int num_written = umock::ssl_h.SSL_write(
417 a_info->
ssl, a_writebuf + bytes_sent, byte_left);
418 if (num_written == -1) {
421 byte_left -= num_written;
422 bytes_sent += num_written;
429 if (a_timeoutSecs !=
nullptr && timeout_secs != 0)
430 *a_timeoutSecs -=
static_cast<int>(time(NULL) - start_time);
441 TRACE(
"Executing sock_init()")
452 sockaddr* foreign_sockaddr) {
453 TRACE(
"Executing sock_init_with_ip()")
455 if (foreign_sockaddr ==
nullptr)
468#ifdef UPnPsdk_HAVE_OPENSSL
470 TRACE(
"Executing sock_ssl_connect()");
476 int status = SSL_set_fd(info->
ssl,
static_cast<int>(info->
socket));
480 UPNPLIB_SCOPED_NO_SIGPIPE;
481 status = SSL_connect(info->
ssl);
490 TRACE(
"Executing sock_destroy()")
493 if (info->
socket != INVALID_SOCKET) {
494#ifdef UPnPsdk_HAVE_OPENSSL
496 SSL_shutdown(info->
ssl);
502 if (umock::sys_socket_h.shutdown(info->
socket, ShutdownMethod) ==
505 std::string msg =
"syscall ::shutdown() returned \"" +
507 if (sockerrObj == ENOTCONNP) {
509 UPnPsdk_LOGINFO(
"MSG1010") << msg;
511 UPnPsdk_LOGERR(
"MSG1089") << msg;
518 info->
socket = INVALID_SOCKET;
526 TRACE(
"Executing sock_read()")
527 if (info ==
nullptr) {
530#ifdef UPnPsdk_HAVE_OPENSSL
533 nullptr , bufsize, timeoutSecs);
543 TRACE(
"Executing sock_write()")
546#ifdef UPnPsdk_HAVE_OPENSSL
549 buffer , bufsize, timeoutSecs);
559 TRACE(
"Executing sock_make_blocking()")
563 return ioctlsocket(sock, FIONBIO, &val);
565 int val = fcntl(sock, F_GETFL, 0);
566 if (fcntl(sock, F_SETFL, val & ~O_NONBLOCK) == -1) {
575 TRACE(
"Executing sock_make_no_blocking()")
579 return ioctlsocket(sock, FIONBIO, &val);
581 int val = fcntl(sock, F_GETFL, 0);
582 if (fcntl(sock, F_SETFL, val | O_NONBLOCK) == -1) {
589#ifdef UPnPsdk_HAVE_OPENSSL
591 const SSL_METHOD* sslMethod) {
597 if (initOpenSslLib) {
598 SSL_load_error_strings();
600 OpenSSL_add_all_algorithms();
603 gSslCtx = SSL_CTX_new(sslMethod);
Class for portable handling of network socket errors.
void catch_error()
Catch error for later use.
std::string error_str() const
Get human readable error description of the catched error.
Declaration of common used classes and free functions for network connections.
int UpnpInitSslContext(int initOpenSslLib, const SSL_METHOD *sslMethod)
Initializes the OpenSSL library, and the OpenSSL context.
#define UPNP_E_SOCKET_ERROR
Generic socket error code for conditions not covered by other error codes.
#define UPNP_E_TIMEDOUT
Too much time elapsed before the required number of bytes were sent or received over a socket.
#define UPNP_E_SUCCESS
The operation completed successfully.
#define UPNP_E_SOCKET_WRITE
An error happened while writing to a socket.
#define UPNP_E_INIT_FAILED
UpnpInit2 cannot complete.
#define UPNP_E_INVALID_PARAM
One or more of the parameters passed to the function is not valid.
#define UPNP_E_INIT
The SDK has already been initialized.
int sock_write_ssl(const SOCKINFO *a_info, char *a_readbuf, const char *a_writebuf, const size_t a_bufsize, int *a_timeoutSecs)
Write to an SSL protected socket.
int sock_write_unprotected(const SOCKINFO *a_info, char *a_readbuf, const char *a_writebuf, const size_t a_bufsize, int *a_timeoutSecs)
Write to a not SSL protected socket.
int sock_read_ssl(const SOCKINFO *a_info, char *a_readbuf, const char *a_writebuf, const size_t a_bufsize, int *a_timeoutSecs)
Read from an SSL protected socket.
int sock_read_unprotected(const SOCKINFO *a_info, char *a_readbuf, const char *a_writebuf, const size_t a_bufsize, int *a_timeoutSecs)
Read from a not SSL protected socket.
SSL_CTX * gSslCtx
Pointer to an SSL Context.
int sock_make_blocking(SOCKET sock)
Make socket blocking.
int sock_ssl_connect(SOCKINFO *info)
Associates an SSL object with the socket and begins the client-side SSL/TLS handshake.
int sock_make_no_blocking(SOCKET sock)
Make socket non-blocking.
int sock_destroy(SOCKINFO *info, int ShutdownMethod)
Shutsdown the socket using the ShutdownMethod to indicate whether sends and receives on the socket wi...
void freeSslCtx()
Free the OpenSSL context.
int sock_read(SOCKINFO *info, char *buffer, size_t bufsize, int *timeoutSecs)
Reads data on socket in sockinfo.
int sock_write(SOCKINFO *info, const char *buffer, size_t bufsize, int *timeoutSecs)
Writes data on the socket in sockinfo.
int sock_init_with_ip(SOCKINFO *info, SOCKET sockfd, sockaddr *foreign_sockaddr)
Calls the sock_init function and assigns the passed in IP address and port to the IP address and port...
int sock_init(SOCKINFO *info, SOCKET sockfd)
Assign the passed in socket descriptor to socket descriptor in the SOCKINFO structure.
Manage network sockets and connections.
SOCKET socket
Handle/descriptor to a socket.
SSL * ssl
Information about an ssl connection only filled in incoming requests.
sockaddr_storage foreign_sockaddr
Socket address of the remote node only filled in incoming requests.
int sock_close(SOCKET sock)
Closes the socket if it is different from -1.
Additional socket information for connections and ssl.
Socket Module: manage properties and methods but not connections of ONE network socket to handle IPv4...