TCP and UDP sockets localEndpoint

This commit is contained in:
Timerix22 2024-04-12 21:32:09 +05:00
parent f2847a819d
commit c4e102b14c
7 changed files with 82 additions and 45 deletions

View File

@ -12,7 +12,7 @@ typedef u16 knPort;
typedef union knIPV4Address {
u32 UintBigEndian;
char bytes[4];
u8 bytes[4];
} knIPV4Address;
kt_declare(knIPV4Address);

View File

@ -15,7 +15,7 @@ Maybe knSocketTCP_open(bool allowReuse){
// set value of REUSEADDR socket option
int opt_val = allowReuse;
if(setsockopt(newSocket->socketfd, SOL_SOCKET, SO_REUSEADDR, (void*)&opt_val, sizeof(opt_val)) != 0)
safethrow("can't set socket options", free(newSocket));
safethrow("can't set socket options", knSocketTCP_close(newSocket));
return SUCCESS(UniHeapPtr(knSocketTCP, newSocket));
}
@ -31,54 +31,67 @@ Maybe knSocketTCP_close(knSocketTCP* socket){
return MaybeNull;
}
Maybe knSocketTCP_bindAndListen(knSocketTCP* socket, knIPV4Endpoint localEndp){
Maybe knSocketTCP_bind(knSocketTCP* socket, knIPV4Endpoint localEndp){
struct sockaddr_in servaddr = knIPV4Endpoint_toSockaddr(localEndp);
if(bind(socket->socketfd, (void*)&servaddr, sizeof(servaddr)) != 0)
safethrow("socket bind failed", ;);
if(listen(socket->socketfd, 1024) != 0)
safethrow("socket listen failed", ;);
socket->localEndpoint = localEndp;
return MaybeNull;
}
Maybe knSocketTCP_connect(knSocketTCP* socket, knIPV4Endpoint remoteEnd){
struct sockaddr_in servaddr = knIPV4Endpoint_toSockaddr(remoteEnd);
Maybe knSocketTCP_listen(knSocketTCP* socket){
if(listen(socket->socketfd, 1024) != 0)
safethrow("socket listen failed", ;);
return MaybeNull;
}
if(connect(socket->socketfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) !=0)
Maybe knSocketTCP_connect(knSocketTCP* socket, knIPV4Endpoint remoteEnd){
struct sockaddr_in localAddr = {0};
struct sockaddr_in remoteAddr = knIPV4Endpoint_toSockaddr(remoteEnd);
u64 sockaddr_size = sizeof(localAddr);
if(connect(socket->socketfd, (struct sockaddr*)&remoteAddr, sizeof(remoteAddr)) != 0)
safethrow("socket connect failed", ;);
if(getsockname(socket->socketfd, (struct sockaddr*)&localAddr, (void*)&sockaddr_size) != 0)
safethrow("can't get connected socket local address", ;);
socket->localEndpoint = knIPV4Endpoint_fromSockaddr(localAddr);
socket->remoteEndpoint = remoteEnd;
return MaybeNull;
}
Maybe knSocketTCP_accept(knSocketTCP* socket){
struct sockaddr_in localAddr = {0};
struct sockaddr_in remoteAddr = {0};
u64 remoteAddrSize = sizeof(remoteAddr);
u64 sockaddr_size = sizeof(localAddr);
i64 client_fd = accept(socket->socketfd, (struct sockaddr*)&remoteAddr, (void*)&remoteAddrSize);
i64 client_fd = accept(socket->socketfd, (struct sockaddr*)&remoteAddr, (void*)&sockaddr_size);
if(client_fd == -1 || client_fd == ~0)
safethrow("can't accept client connection", ;);
if(getsockname(client_fd, (struct sockaddr*)&localAddr, (void*)&sockaddr_size) != 0)
safethrow("can't get accepted socket local address", __kn_StdSocket_close(client_fd));
// if accept() didn't set remoteAddr for some reason
if(remoteAddr.sin_addr.s_addr == 0 && remoteAddr.sin_port == 0 && remoteAddr.sin_family == 0){
if(getpeername(client_fd, (struct sockaddr*)&remoteAddr, (void*)&remoteAddrSize) != 0)
safethrow("can't get connected client address", ;);
if(getpeername(client_fd, (struct sockaddr*)&remoteAddr, (void*)&sockaddr_size) != 0)
safethrow("can't get accepted socket remote address", __kn_StdSocket_close(client_fd));
}
knSocketTCP* clientSocket = malloc(sizeof(knSocketTCP));
clientSocket->socketfd = client_fd;
clientSocket->localEndpoint = socket->localEndpoint;
clientSocket->localEndpoint = knIPV4Endpoint_fromSockaddr(localAddr);
clientSocket->remoteEndpoint = knIPV4Endpoint_fromSockaddr(remoteAddr);
return SUCCESS(UniHeapPtr(knSocketTCP, clientSocket));
}
Maybe knSocketTCP_send(knSocketTCP* socket, char* buffer, u32 dataLength){
Maybe knSocketTCP_send(knSocketTCP* socket, void* _buf, u32 dataLength){
char* buf = _buf;
u32 sentTotal = 0;
while(sentTotal < dataLength){
int sentCount = send(socket->socketfd, buffer+sentTotal, dataLength-sentTotal, 0);
int sentCount = send(socket->socketfd, buf+sentTotal, dataLength-sentTotal, 0);
if(sentCount == -1){
safethrow(
cptr_concat("can't send ", toString_u64(dataLength-sentTotal,0,0),
@ -93,15 +106,17 @@ Maybe knSocketTCP_send(knSocketTCP* socket, char* buffer, u32 dataLength){
return MaybeNull;
}
Maybe knSocketTCP_receive(knSocketTCP* socket, char* buffer, u32 bufferLength){
int receivedCount = recv(socket->socketfd, buffer, bufferLength, 0);
Maybe knSocketTCP_receive(knSocketTCP* socket, void* _buf, u32 bufferLength){
char* buf = _buf;
int receivedCount = recv(socket->socketfd, buf, bufferLength, 0);
if(receivedCount == -1 || receivedCount == 0)
safethrow("can't receive data from socket", ;)
return SUCCESS(UniUInt64(receivedCount));
}
Maybe knSocketTCP_receiveN(knSocketTCP* socket, char* buf, u32 bufsize, u32 n){
Maybe knSocketTCP_receiveN(knSocketTCP* socket, void* _buf, u32 bufsize, u32 n){
char* buf = _buf;
if(bufsize < n)
safethrow(ERR_UNEXPECTEDVAL, ;);

View File

@ -27,9 +27,13 @@ Maybe knSocketTCP_shutdown(knSocketTCP* socket, knShutdownType direction);
///@return Maybe<void> error or nothing
Maybe knSocketTCP_close(knSocketTCP* socket);
/// binds socket to a local endpoint and starts listening for incoming TCP connections
/// binds socket to a local endpoint
///@return Maybe<void> error or nothing
Maybe knSocketTCP_bind(knSocketTCP* socket, knIPV4Endpoint localEndp);
/// begins listening for incoming TCP connections
Maybe knSocketTCP_listen(knSocketTCP* socket);
///@return Maybe<void> error or nothing
Maybe knSocketTCP_bindAndListen(knSocketTCP* socket, knIPV4Endpoint localEndp);
/// establishes TCP connection with a remote endpoint
///@return Maybe<void> error or nothing
@ -42,18 +46,18 @@ Maybe knSocketTCP_accept(knSocketTCP* socket);
///@param buffer buffer for receiving data
///@param dataLength 0-4294967295
///@return Maybe<void>
Maybe knSocketTCP_send(knSocketTCP* socket, char* buffer, u32 dataLength);
Maybe knSocketTCP_send(knSocketTCP* socket, void* buffer, u32 dataLength);
/// receives a package of any size
/// (by TCP 32 bytes han be sent as 32x1byte, 4x8byte, 32x1byte or in any other combination)
///@param buffer buffer for receiving data
///@param bufferLength 0-4294967295
///@return Maybe<u64> received bytes amount
Maybe knSocketTCP_receive(knSocketTCP* socket, char* buffer, u32 bufferLength);
Maybe knSocketTCP_receive(knSocketTCP* socket, void* buffer, u32 bufferLength);
/// receives a package of size n
///@return Maybe<void>
Maybe knSocketTCP_receiveN(knSocketTCP* socket, char* buf, u32 bufsize, u32 n);
Maybe knSocketTCP_receiveN(knSocketTCP* socket, void* buf, u32 bufsize, u32 n);
#if __cplusplus
}

View File

@ -14,7 +14,7 @@ Maybe knSocketUDP_open(bool allowReuse){
// set value of REUSEADDR socket option
int opt_val = allowReuse;
if(setsockopt(newSocket->socketfd, SOL_SOCKET, SO_REUSEADDR, (void*)&opt_val, sizeof(opt_val)) != 0)
safethrow("can't set socket options", free(newSocket));
safethrow("can't set socket options", knSocketUDP_close(newSocket));
return SUCCESS(UniHeapPtr(knSocketUDP, newSocket));
}
@ -63,6 +63,14 @@ Maybe knSocketUDP_sendTo(knSocketUDP* socket, char* buffer, u32 dataLength, knIP
;);
}
struct sockaddr_in localAddr = {0};
u64 sockaddr_size = sizeof(localAddr);
if(getsockname(socket->socketfd, (struct sockaddr*)&localAddr, (void*)&sockaddr_size) != 0)
safethrow("can't get implicitely bound socket local address", ;);
socket->localEndpoint = knIPV4Endpoint_fromSockaddr(localAddr);
return MaybeNull;
}

View File

@ -81,6 +81,7 @@ char* __unknownErr( );
#endif
#define tryLast(_funcCall, _result, ON_EXIT) Maybe _result=_funcCall; if(_result.errmsg){ \
ON_EXIT; \
_result.errmsg=__extendErrMsg(_result.errmsg, __FILE__,__LINE__,__func__); \
__EXIT(_result.errmsg); \
}

View File

@ -47,8 +47,12 @@ typedef struct {
void* tcp_client_connect_async(void* _data){
tcp_client_connect_async_data* data = _data;
tryLast(knSocketTCP_connect(data->socket_client, data->serverEnd), _m8531,;);
kprintf_safe("\e[92mclient socket connected to server\n");
char* adrstr = knIPV4Endpoint_toString(&data->socket_client->localEndpoint);
kprintf("\e[92mclient socket was implicitely bound to %s\n\e[94m", adrstr);
free(adrstr);
free(data);
return NULL;
}
@ -63,7 +67,8 @@ static void test_tcp(){
socket_server=m_socketS.value.VoidPtr;
kprintf("\e[92mTCP server socket created\n");
tryLast(knSocketTCP_bindAndListen(socket_server, serverEnd), _m81775, ;)
tryLast(knSocketTCP_bind(socket_server, serverEnd), _m81775, ;)
tryLast(knSocketTCP_listen(socket_server), _m88775, ;)
kprintf("\e[92mserver socket is listening\n");
}
// client
@ -161,6 +166,10 @@ void test_udp(){
const char client_msg[] = "ping";
tryLast(knSocketUDP_sendTo(socket_client, client_msg, sizeof(client_msg), serverEnd), _mu75q2, ;);
kprintf("\e[92mmessage sent to server\n\e[94m");
char* adrstr = knIPV4Endpoint_toString(&socket_client->localEndpoint);
kprintf("\e[92mclient socket was implicitely bound to %s\n\e[94m", adrstr);
free(adrstr);
}
// server
{

View File

@ -24,19 +24,19 @@ void test_network();
inline void test_all(){
kprintf("\e[97mkerep tests are starting!\n");
optime(__func__, 1,
test_cptr();
test_type_system();
test_string();
test_safethrow();
test_searchtree();
test_autoarr();
test_autoarrVsVector();
test_rng_algorithms();
test_kprint_colors();
test_kprint();
test_hash_functions();
test_hashtable();
test_dtsod();
// test_cptr();
// test_type_system();
// test_string();
// test_safethrow();
// test_searchtree();
// test_autoarr();
// test_autoarrVsVector();
// test_rng_algorithms();
// test_kprint_colors();
// test_kprint();
// test_hash_functions();
// test_hashtable();
// test_dtsod();
test_network();
kprintf("\e[96m--------------------------------------\e[0m\n");
);