TCP and UDP sockets localEndpoint

This commit is contained in:
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,8 +15,8 @@ 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)
safethrow("socket connect failed",;);
socket->remoteEndpoint=remoteEnd;
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); \
}