implemented some socket functions

This commit is contained in:
2025-07-21 18:55:40 +03:00
parent bce385a4b5
commit 1e41ab49e5
11 changed files with 213 additions and 23 deletions

28
src/network/endpoint.c Executable file
View File

@@ -0,0 +1,28 @@
#include "endpoint.h"
#include "network.h"
struct sockaddr_in EndpointIPv4_toSockaddr(EndpointIPv4 end){
struct sockaddr_in saddr = {0};
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = end.address.UintBigEndian;
/* transforms port number to big endian (network order) */
saddr.sin_port = htons(end.port);
return saddr;
}
EndpointIPv4 EndpointIPv4_fromSockaddr(struct sockaddr_in saddr){
EndpointIPv4 end;
end.address = AddressIPv4_fromU32(saddr.sin_addr.s_addr);
/* transforms port number to little endian (normal order) */
end.port = ntohs(saddr.sin_port);
return end;
}
AddressIPv4 AddressIPv4_fromStr(cstr);
str AddressIPv4_toStr(AddressIPv4 address);
EndpointIPv4 EndpointIPv4_fromStr(cstr s);
str EndpointIPv4_toStr(EndpointIPv4 end);

39
src/network/endpoint.h Executable file
View File

@@ -0,0 +1,39 @@
#pragma once
#include "tlibc/std.h"
#include "tlibc/string/str.h"
#include "network.h"
#define port_INVALID ((port)~0)
#define port_is_invalid(PORT) (PORT == port_INVALID)
typedef union AddressIPv4 {
u32 UintBigEndian;
u8 bytes[4];
} AddressIPv4;
#define AddressIPv4_ANY AddressIPv4_fromBytes(0,0,0,0)
#define AddressIPv4_LOOPBACK AddressIPv4_fromBytes(127,0,0,1)
#define AddressIPv4_INVALID AddressIPv4_fromBytes(255,255,255,255)
#define AddressIPv4_is_invalid(ADDR) (ADDR.UintBigEndian == (u32)~0)
#define AddressIPv4_fromBytes(A, B, C, D) ((AddressIPv4){.bytes={A,B,C,D}})
#define AddressIPv4_fromU32(N) ((AddressIPv4){.UintBigEndian=N})
AddressIPv4 AddressIPv4_fromStr(cstr);
str AddressIPv4_toStr(AddressIPv4 address);
typedef struct EndpointIPv4 {
AddressIPv4 address;
u16 port;
} EndpointIPv4;
#define EndpointIPv4_INVALID EndpointIPv4_create(AddressIPv4_INVALID, port_INVALID)
#define EndpointIPv4_is_invalid(ENDP) (AddressIPv4_is_invalid(ENDP.address) || port_is_invalid(ENDP.port))
#define EndpointIPv4_create(ADDR, PORT) ((EndpointIPv4){ADDR, PORT})
EndpointIPv4 EndpointIPv4_fromStr(cstr s);
str EndpointIPv4_toStr(EndpointIPv4 end);
struct sockaddr_in EndpointIPv4_toSockaddr(EndpointIPv4 end);
EndpointIPv4 EndpointIPv4_fromSockaddr(struct sockaddr_in saddr);

25
src/network/network.c Executable file
View File

@@ -0,0 +1,25 @@
#include "network.h"
#include "network.h"
Result(void) network_init(){
#if _WIN32
// Initialize Winsock
WSADATA wsaData = {0};
int result = WSAStartup(MAKEWORD(2,2), &wsaData);
if (result != 0) {
return RESULT_ERROR(sprintf_malloc(64, "WSAStartup failed with error code 0x%X", result), true);
}
#endif
return RESULT_VOID;
}
Result(void) network_deinit(){
#if _WIN32
// Deinitialize Winsock
int result = WSACleanup();
if (result != 0) {
return RESULT_ERROR(sprintf_malloc(64, "WSACleanup failed with error code 0x%X", result), true);
}
#endif
return RESULT_VOID;
}

22
src/network/network.h Executable file
View File

@@ -0,0 +1,22 @@
#pragma once
#include "tlibc/errors.h"
#if defined(_WIN64) || defined(_WIN32)
#define KN_USE_WINSOCK 1
#else
#define KN_USE_WINSOCK 0
#endif
#if KN_USE_WINSOCK
#include <winsock2.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#endif
Result(void) network_init();
Result(void) network_deinit();

46
src/network/socket.c Executable file
View File

@@ -0,0 +1,46 @@
#include "network.h"
#include "network.h"
#include "socket.h"
Result(Socket) socket_open_TCP(){
Socket s = socket(AF_INET, SOCK_STREAM, 0);
if(s == -1){
return RESULT_ERROR("can't create socket", false);
}
return RESULT_VALUE(i64, s);
}
void socket_close(Socket s){
#if KN_USE_WINSOCK
closesocket(s);
#else
close(s);
#endif
}
Result(void) socket_shutdown(Socket s, SocketShutdownType direction){
if(shutdown(s, (int)direction) == -1)
return RESULT_ERROR("shutdown() failed", false);
return RESULT_VOID;
}
Result(void) socket_bind(Socket s, EndpointIPv4 local_end){
struct sockaddr_in sockaddr = EndpointIPv4_toSockaddr(local_end);
if(bind(s, (void*)&sockaddr, sizeof(sockaddr)) != 0)
return RESULT_ERROR("bind() failed", false);
return RESULT_VOID;
}
Result(void) socket_listen(Socket s, i32 backlog){
if(listen(s, backlog) != 0)
return RESULT_ERROR("listen() failed", false);
return RESULT_VOID;
}
Result(Socket) socket_accept(Socket main_socket) {
struct sockaddr_in remote_addr = {0};
i32 sockaddr_size = sizeof(remote_addr);
Socket user_connection = accept(main_socket, (struct sockaddr*)&remote_addr, (void*)&sockaddr_size);
return RESULT_VALUE(i64, user_connection);
}

18
src/network/socket.h Executable file
View File

@@ -0,0 +1,18 @@
#pragma once
#include "endpoint.h"
#include "tlibc/errors.h"
typedef enum SocketShutdownType {
SocketShutdownType_Receive = 0,
SocketShutdownType_Send = 1,
SocketShutdownType_Both = 2,
} SocketShutdownType;
typedef i64 Socket;
Result(Socket) socket_open_TCP();
void socket_close(Socket s);
Result(void) socket_shutdown(Socket s, SocketShutdownType direction);
Result(void) socket_bind(Socket s, EndpointIPv4 local_end);
Result(void) socket_listen(Socket s, i32 backlog);
Result(Socket) socket_accept(Socket main_socket);