Net
This commit is contained in:
@@ -6,4 +6,5 @@
|
||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||
PUBLIC
|
||||
networklinux.c
|
||||
networksocketlinux.c
|
||||
)
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user