Files
BearSSL-OG/socket_utility.cpp
2025-03-03 12:21:16 -07:00

149 lines
3.1 KiB
C++

#include "socket_utility.h"
#include <xtl.h>
#include <winsockx.h>
#include <stdint.h>
int socket_utility::connect_to_host(uint32_t host_ip, uint16_t port)
{
sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.S_un.S_addr = host_ip;
int32_t connect_socket = socket(AF_INET, SOCK_STREAM, 0);
if (connect_socket == INVALID_SOCKET)
{
return -1;
}
if (connect(connect_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
return -1;
}
return connect_socket;
}
int socket_utility::host_bind(uint16_t port)
{
int32_t bind_socket = socket(AF_INET, SOCK_STREAM, 0);
uint32_t reuse = 1;
if (setsockopt(bind_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse)) < 0)
{
return -1;
}
uint32_t non_blocking = 1;
if (ioctlsocket((SOCKET)bind_socket, FIONBIO, &non_blocking) == SOCKET_ERROR)
{
return -1;
}
SOCKADDR_IN address_in;
memset(&address_in, 0, sizeof(SOCKADDR_IN));
address_in.sin_addr.s_addr = INADDR_ANY;
address_in.sin_family = AF_INET;
address_in.sin_port = htons(port);
if (bind(bind_socket, (struct sockaddr *)&address_in, sizeof(address_in)) == SOCKET_ERROR)
{
return -1;
}
if (listen(bind_socket, 5) < 0)
{
return -1;
}
return bind_socket;
}
int socket_utility::get_read_status(int socket)
{
static const timeval instantSpeedPlease = { 0,0 };
fd_set a = { 1, {(SOCKET)socket} };
int result = select(0, &a, 0, 0, &instantSpeedPlease);
if (result == SOCKET_ERROR)
{
result = WSAGetLastError();
}
if (result != 0 && result != 1)
{
return SOCKET_ERROR;
}
return result;
}
int socket_utility::accept_client(int server_socket)
{
sockaddr sock_addr;
int sock_addr_length = sizeof(sock_addr);
int32_t socket = accept(server_socket, &sock_addr, &sock_addr_length);
if (socket == INVALID_SOCKET)
{
return -1;
}
return socket;
}
int socket_utility::socket_read(void *context, unsigned char *buffer, size_t length)
{
int socket = *(int *)context;
struct timeval tv;
fd_set read_fds;
while (true)
{
FD_ZERO(&read_fds );
FD_SET(socket, &read_fds );
tv.tv_sec = 2;
tv.tv_usec = 0;
int ret = select(socket, &read_fds, NULL, NULL, &tv );
if( ret == 0 )
{
return -1;
}
int bytes_read = recv(socket, (char *)buffer, length, 0);
if (bytes_read == SOCKET_ERROR)
{
if (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEWOULDBLOCK)
{
continue;
}
return -1;
}
if (bytes_read == 0)
{
return 0;
}
return bytes_read;
}
}
int socket_utility::socket_write(void *context, const unsigned char *buffer, size_t length)
{
while (true)
{
int socket = *(int *)context;
int bytes_written = send(socket, (const char *)buffer, length, 0);
if (bytes_written == SOCKET_ERROR)
{
if (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEWOULDBLOCK)
{
continue;
}
return -1;
}
return bytes_written;
}
}