This commit is contained in:
2026-07-16 19:08:32 -05:00
parent dcf5f434c5
commit d4a17bd98d
32 changed files with 2410 additions and 4 deletions
+1
View File
@@ -6,4 +6,5 @@
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
networklinux.c
networksocketlinux.c
)
+102
View File
@@ -0,0 +1,102 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "networksocketlinux.h"
#include "util/memory.h"
#include "util/string.h"
#include "assert/assert.h"
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <unistd.h>
errorret_t networkSocketLinuxConnect(
networksocketlinux_t *sock,
const char_t *host,
const uint16_t port
) {
assertNotNull(sock, "sock must not be NULL");
assertNotNull(host, "host must not be NULL");
char_t portStr[8];
stringFormat(portStr, sizeof(portStr) - 1, "%u", port);
struct addrinfo hints;
memoryZero(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
struct addrinfo *result = NULL;
const int_t gaiRet = getaddrinfo(host, portStr, &hints, &result);
if(gaiRet != 0) {
errorThrow("Failed to resolve host %s: %s", host, gai_strerror(gaiRet));
}
int_t fd = -1;
for(struct addrinfo *addr = result; addr != NULL; addr = addr->ai_next) {
fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if(fd < 0) continue;
if(connect(fd, addr->ai_addr, addr->ai_addrlen) == 0) break;
close(fd);
fd = -1;
}
freeaddrinfo(result);
if(fd < 0) errorThrow("Failed to connect to %s:%u", host, port);
struct timeval timeout;
timeout.tv_sec = NETWORK_SOCKET_LINUX_TIMEOUT_SECONDS;
timeout.tv_usec = 0;
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
sock->fd = fd;
errorOk();
}
errorret_t networkSocketLinuxSend(
networksocketlinux_t *sock,
const uint8_t *data,
const size_t length,
size_t *outSent
) {
assertNotNull(sock, "sock must not be NULL");
assertNotNull(data, "data must not be NULL");
assertNotNull(outSent, "outSent must not be NULL");
const ssize_t sent = send(sock->fd, data, length, 0);
if(sent < 0) errorThrow("Failed to send data: %s", strerror(errno));
*outSent = (size_t)sent;
errorOk();
}
errorret_t networkSocketLinuxReceive(
networksocketlinux_t *sock,
uint8_t *buffer,
const size_t bufferSize,
size_t *outReceived
) {
assertNotNull(sock, "sock must not be NULL");
assertNotNull(buffer, "buffer must not be NULL");
assertNotNull(outReceived, "outReceived must not be NULL");
const ssize_t received = recv(sock->fd, buffer, bufferSize, 0);
if(received < 0) errorThrow("Failed to receive data: %s", strerror(errno));
*outReceived = (size_t)received;
errorOk();
}
void networkSocketLinuxClose(networksocketlinux_t *sock) {
assertNotNull(sock, "sock must not be NULL");
if(sock->fd >= 0) close(sock->fd);
sock->fd = -1;
}
@@ -0,0 +1,70 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "error/error.h"
#define NETWORK_SOCKET_LINUX_TIMEOUT_SECONDS 10
typedef struct {
int_t fd;
} networksocketlinux_t;
/**
* Resolves host and opens a blocking TCP connection to host:port.
*
* @param sock The socket structure to initialize.
* @param host The hostname or IP address to connect to.
* @param port The port to connect to.
* @return An error if resolution or connection failed.
*/
errorret_t networkSocketLinuxConnect(
networksocketlinux_t *sock,
const char_t *host,
const uint16_t port
);
/**
* Sends data over the socket. May write fewer bytes than requested; the
* caller is responsible for looping until all data is sent.
*
* @param sock The connected socket.
* @param data The data to send.
* @param length The number of bytes in data.
* @param outSent The number of bytes actually sent is written here.
* @return An error if the send failed.
*/
errorret_t networkSocketLinuxSend(
networksocketlinux_t *sock,
const uint8_t *data,
const size_t length,
size_t *outSent
);
/**
* Receives data from the socket.
*
* @param sock The connected socket.
* @param buffer The buffer to receive into.
* @param bufferSize The size of buffer.
* @param outReceived The number of bytes actually received is written
* here; 0 means the peer closed the connection.
* @return An error if the receive failed.
*/
errorret_t networkSocketLinuxReceive(
networksocketlinux_t *sock,
uint8_t *buffer,
const size_t bufferSize,
size_t *outReceived
);
/**
* Closes the socket.
*
* @param sock The socket to close.
*/
void networkSocketLinuxClose(networksocketlinux_t *sock);
@@ -0,0 +1,16 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "networksocketlinux.h"
typedef networksocketlinux_t networksocketplatform_t;
#define networkSocketPlatformConnect networkSocketLinuxConnect
#define networkSocketPlatformSend networkSocketLinuxSend
#define networkSocketPlatformReceive networkSocketLinuxReceive
#define networkSocketPlatformClose networkSocketLinuxClose