From 85d6ba2216bb0acab10e4d7181f165fc350b6166 Mon Sep 17 00:00:00 2001 From: timerix Date: Sun, 15 Jan 2023 21:34:04 +0600 Subject: [PATCH] different socket structs instead of universal --- src/Network/knAddress.c | 4 +- src/Network/knAddress.h | 7 +- src/Network/knSocket.c | 5 - src/Network/knSocket.h | 53 ---------- src/Network/knSocketChanneled.c | 96 ------------------- src/Network/network.h | 7 +- src/Network/sockets/knSocketChanneled.c | 59 ++++++++++++ src/Network/{ => sockets}/knSocketChanneled.h | 14 ++- src/Network/sockets/knSocketTCP.c | 73 ++++++++++++++ src/Network/sockets/knSocketTCP.h | 45 +++++++++ src/Network/sockets/knSocketUDP.c | 29 ++++++ src/Network/sockets/knSocketUDP.h | 40 ++++++++ tests/test_network.c | 8 +- 13 files changed, 268 insertions(+), 172 deletions(-) delete mode 100644 src/Network/knSocket.c delete mode 100644 src/Network/knSocket.h delete mode 100644 src/Network/knSocketChanneled.c create mode 100644 src/Network/sockets/knSocketChanneled.c rename src/Network/{ => sockets}/knSocketChanneled.h (88%) create mode 100644 src/Network/sockets/knSocketTCP.c create mode 100644 src/Network/sockets/knSocketTCP.h create mode 100644 src/Network/sockets/knSocketUDP.c create mode 100644 src/Network/sockets/knSocketUDP.h diff --git a/src/Network/knAddress.c b/src/Network/knAddress.c index a7f8e3a..06b0f9e 100644 --- a/src/Network/knAddress.c +++ b/src/Network/knAddress.c @@ -8,7 +8,7 @@ Maybe knIPV4Address_fromStr(char* addrStr){ char* errmsg_extra="wrong char"; uint8 c; knIPV4Address addr; - addr.address=0; + addr.u32=0; uint16 n=0; for(uint8 i=0; i<4; ){ c=*addrStr++; @@ -41,5 +41,5 @@ Maybe knIPV4Address_fromStr(char* addrStr){ } } //TODO UniStack for generic structs - return SUCCESS(UniUInt64(addr.address)); + return SUCCESS(UniUInt64(addr.u32)); } diff --git a/src/Network/knAddress.h b/src/Network/knAddress.h index ea867a1..ce95a39 100644 --- a/src/Network/knAddress.h +++ b/src/Network/knAddress.h @@ -10,7 +10,7 @@ extern "C" { typedef uint16 knPort; typedef union knIPV4Address { - uint32 address; + uint32 u32; char bytes[4]; } knIPV4Address; ktid_declare(knIPV4Address); @@ -20,6 +20,11 @@ ktid_declare(knIPV4Address); ///@return Maybe as Maybe Maybe knIPV4Address_fromStr(char* addrStr); +#define IPV4_NONE knIPV4Address_fromBytes(255,255,255,255) +#define IPV4_ANY knIPV4Address_fromBytes(0,0,0,0) +#define IPV4_LOOPBACK knIPV4Address_fromBytes(127,0,0,1) + + typedef struct knIPV4Endpoint { knIPV4Address address; knPort port; diff --git a/src/Network/knSocket.c b/src/Network/knSocket.c deleted file mode 100644 index 9c32aeb..0000000 --- a/src/Network/knSocket.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "network.h" -#include "stdSocketHeaders.h" - -ktid_define(knSocketProtocol); -ktid_define(knSocket); diff --git a/src/Network/knSocket.h b/src/Network/knSocket.h deleted file mode 100644 index 71d2f89..0000000 --- a/src/Network/knSocket.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#if __cplusplus -extern "C" { -#endif - -#include "../base/base.h" -#include "knAddress.h" - - -typedef enum __attribute__((__packed__)) knSocketProtocol { - knSocketProtocol_TCP, knSocketProtocol_UDP, knSocket_Channeled -} knSocketProtocol; -ktid_declare(knSocketProtocol); - -typedef struct knSocket { - knSocketProtocol type; - int64 socketfd; - knIPV4Endpoint localEndpoint; - knIPV4Endpoint remoteEndpoint; -} knSocket; -ktid_declare(knSocket); - -///@return Maybe new socket -Maybe knSocket_open(knSocketProtocol sockType); - -///@return Maybe error or nothing -Maybe knSocket_close(knSocket* socket); - -///sets socket local endpoint -///@return Maybe error or nothing -Maybe knSocket_bind(knSocket* socket, knIPV4Endpoint localEndp); - -///sets socket remote endpoint -///@return Maybe error or nothing -Maybe knSocket_connect(knSocket* socket, knIPV4Endpoint remoteEndp); - -///@return Maybe new socket connected to client -Maybe knSocket_accept(knSocket* socket); - -///@param dataLength 0-4294967295 -///@return Maybe -Maybe knSocket_send(knSocket* socket, uint16 destinationIndex, uint8* data, uint32 dataLength); - -///@param buffer buffer for recieving data -///@param bufferLength 0-4294967295 -///@return Maybe recieved bytes amount -Maybe knSocket_recieve(knSocket* socket, uint16 destinationIndex, uint8* buffer, uint32 bufferLength); - - -#if __cplusplus -} -#endif \ No newline at end of file diff --git a/src/Network/knSocketChanneled.c b/src/Network/knSocketChanneled.c deleted file mode 100644 index 65bb240..0000000 --- a/src/Network/knSocketChanneled.c +++ /dev/null @@ -1,96 +0,0 @@ -#include "network.h" -#include "stdSocketHeaders.h" - -ktid_define(knPacVersion); -ktid_define(knPackage); -ktid_define(knPackageQueueElem); -ktid_define(knChannel); -ktid_define(knSocketChanneled); - -Maybe knSocketChanneled_open(knSocketProtocol sockType){ - knSocketChanneled* newSocket=malloc(sizeof(knSocketChanneled)); - newSocket->type=sockType; - newSocket->channels=NULL; - newSocket->channelsAmount=0; - newSocket->localEndpoint=knIPV4Endpoint_create(knIPV4Address_fromBytes(0,0,0,0),0); - newSocket->remoteEndpoint=newSocket->localEndpoint; - switch(sockType){ - default: - safethrow("unknown socket type", free(newSocket)); - break; - case knSocketProtocol_TCP: - newSocket->socketfd=socket(AF_INET, SOCK_STREAM, 0); - if(newSocket->socketfd==-1) - safethrow("can't create TCP socket", free(newSocket)); - break; - case knSocketProtocol_UDP: - newSocket->socketfd=socket(AF_INET, SOCK_DGRAM, 0); - if(newSocket->socketfd==-1) - safethrow("can't create UDP socket", free(newSocket)); - break; - } - return SUCCESS(UniHeapPtr(knSocketChanneled, newSocket)); -} - -Maybe knSocketChanneled_close(knSocketChanneled* knsocket){ - int rezult= -#if KN_USE_WINSOCK - closesocket -#else - close -#endif - (knsocket->socketfd); - if(rezult==-1) { - safethrow("can't close socket",;); - } - else return MaybeNull; -} - -knChannel* __createChannel(){ - knChannel* ch=malloc(sizeof(knChannel)); - ch->queueStart=NULL; - return ch; -} - -Maybe knSocketChanneled_createChannel(knSocketChanneled* sock){ - if(sock->channelsAmount == 65535) - safethrow("max amount of channels",;); - uint16 channelsAmountPrev=sock->channelsAmount; - sock->channelsAmount++; - if(channelsAmountPrev==0) - sock->channels=malloc(sizeof(knChannel*)); - else - sock->channels=realloc(sock->channels, sock->channelsAmount*sizeof(knChannel*)); - sock->channels[channelsAmountPrev]=__createChannel(); - return SUCCESS(UniUInt64(channelsAmountPrev)); -} - -/*Maybe knSocketChanneled_bind(knSocketChanneled* sock, knIPV4Endpoint localEndp){ - if(sock->localEndpoint.address.address!=0) - safethrow("socket is bound already",;); - struct sockaddr_in addr; - addr.sin_family= - bind(sock->socketfd); - sock->localEndpoint=localEndp; - return MaybeNull; -} - -Maybe knSocketChanneled_connect(knSocketChanneled* sock, knIPV4Endpoint remoteEndp){ - if(sock->remoteEndpoint.address.address!=0) - safethrow("socket is connected already",;); - - sock->remoteEndpoint=remoteEndp; - return MaybeNull; -} - -Maybe knSocketChanneled_accept(knSocketChanneled* sock){ - -} - -Maybe knSocketChanneled_send(knSocketChanneled* sock, uint16 destinationIndex, uint8* data, uint32 dataLength){ - -} - -Maybe knSocketChanneled_recieve(knSocketChanneled* sock, uint16 destinationIndex, uint8* buffer, uint32 bufferLength){ - -}*/ diff --git a/src/Network/network.h b/src/Network/network.h index 8f6d999..6581b35 100644 --- a/src/Network/network.h +++ b/src/Network/network.h @@ -6,13 +6,14 @@ extern "C" { #include "../base/base.h" -#if defined(_MSC_VER) || defined(_WIN64) || defined(_WIN32) +#if defined(_WIN64) || defined(_WIN32) #define KN_USE_WINSOCK 1 #endif #include "knAddress.h" -#include "knSocket.h" -#include "knSocketChanneled.h" +#include "sockets/knSocketTCP.h" +#include "sockets/knSocketUDP.h" +#include "sockets/knSocketChanneled.h" #if __cplusplus } diff --git a/src/Network/sockets/knSocketChanneled.c b/src/Network/sockets/knSocketChanneled.c new file mode 100644 index 0000000..55e576c --- /dev/null +++ b/src/Network/sockets/knSocketChanneled.c @@ -0,0 +1,59 @@ +#include "../network.h" +#include "../stdSocketHeaders.h" + +ktid_define(knPackage); +ktid_define(knPackageQueueElem); +ktid_define(knChannel); +ktid_define(knSocketChanneled); + +Maybe knSocketChanneled_open(){ + knSocketChanneled* newSocket=malloc(sizeof(knSocketChanneled)); + newSocket->localEndpoint=knIPV4Endpoint_create(knIPV4Address_fromBytes(0,0,0,0),0); + newSocket->remoteEndpoint=newSocket->localEndpoint; + newSocket->channels=NULL; + newSocket->channelsAmount=0; + return SUCCESS(UniHeapPtr(knSocketChanneled, newSocket)); +} + +Maybe knSocketChanneled_close(knSocketChanneled* socket){ + int rezult= +#if KN_USE_WINSOCK + closesocket +#else + close +#endif + (socket->socketfd); + if(rezult==-1) { + safethrow("can't close socket",;); + } + else return MaybeNull; +} + +knChannel* __createChannel(){ + knChannel* ch=malloc(sizeof(knChannel)); + ch->queueStart=NULL; + return ch; +} + +Maybe knSocketChanneled_createChannel(knSocketChanneled* socket){ + if(socket->channelsAmount == 65535) + safethrow("max amount of channels",;); + uint16 channelsAmountPrev=socket->channelsAmount; + socket->channelsAmount++; + if(channelsAmountPrev==0) + socket->channels=malloc(sizeof(knChannel*)); + else + socket->channels=realloc(socket->channels, socket->channelsAmount*sizeof(knChannel*)); + socket->channels[channelsAmountPrev]=__createChannel(); + return SUCCESS(UniUInt64(channelsAmountPrev)); +} + +Maybe knSocketChanneled_listen(knSocketChanneled* socket, knIPV4Endpoint localEndp); + +Maybe knSocketChanneled_connect(knSocketChanneled* socket, knIPV4Endpoint remoteEndp); + +Maybe knSocketChanneled_accept(knSocketChanneled* socket); + +Maybe knSocketChanneled_send(knSocketChanneled* socket, uint16 destinationIndex, uint8* data, uint32 dataLength); + +Maybe knSocketChanneled_recieve(knSocketChanneled* socket, uint16 destinationIndex, uint8* buffer, uint32 bufferLength); \ No newline at end of file diff --git a/src/Network/knSocketChanneled.h b/src/Network/sockets/knSocketChanneled.h similarity index 88% rename from src/Network/knSocketChanneled.h rename to src/Network/sockets/knSocketChanneled.h index dbf8d34..3ba8d39 100644 --- a/src/Network/knSocketChanneled.h +++ b/src/Network/sockets/knSocketChanneled.h @@ -4,16 +4,15 @@ extern "C" { #endif -#include "../base/base.h" -#include "knSocket.h" +#include "../../base/base.h" +#include "../knAddress.h" #define KNPAC_MAX_DATA_SIZE (65535-sizeof(knPackage)+sizeof(uint8*)) typedef enum __attribute__((__packed__)) knPacVersion { - knPac_V1 + knPac_V1=1 } knPacVersion; -ktid_declare(knPacVersion); static const char knPacHeader[5]={'k','n','p','a','c'}; @@ -42,7 +41,6 @@ typedef struct knChannel { ktid_declare(knChannel); typedef struct knSocketChanneled{ - knSocketProtocol type; int64 socketfd; knIPV4Endpoint localEndpoint; knIPV4Endpoint remoteEndpoint; @@ -53,7 +51,7 @@ ktid_declare(knSocketChanneled); ///@return Maybe new socket -Maybe knSocketChanneled_open(knSocketProtocol sockType); +Maybe knSocketChanneled_open(); ///@return Maybe error or nothing Maybe knSocketChanneled_close(knSocketChanneled* socket); @@ -61,9 +59,9 @@ Maybe knSocketChanneled_close(knSocketChanneled* socket); ///@return Maybe channel index Maybe knSocketChanneled_createChannel(knSocketChanneled* socket); -///sets socket local endpoint +///start listening at local endpoint ///@return Maybe error or nothing -Maybe knSocketChanneled_bind(knSocketChanneled* socket, knIPV4Endpoint localEndp); +Maybe knSocketChanneled_listen(knSocketChanneled* socket, knIPV4Endpoint localEndp); ///sets socket remote endpoint ///@return Maybe error or nothing diff --git a/src/Network/sockets/knSocketTCP.c b/src/Network/sockets/knSocketTCP.c new file mode 100644 index 0000000..4e55d27 --- /dev/null +++ b/src/Network/sockets/knSocketTCP.c @@ -0,0 +1,73 @@ +#include "../network.h" +#include "../stdSocketHeaders.h" +ktid_define(knSocketTCP); + +///@return Maybe new socket +Maybe knSocketTCP_open(){ + knSocketTCP* newSocket=malloc(sizeof(knSocketTCP)); + newSocket->localEndpoint=knIPV4Endpoint_create({.u32=INADDR_NONE},0); + newSocket->remoteEndpoint=newSocket->localEndpoint; + newSocket->socketfd=socket(AF_INET, SOCK_STREAM, 0); + if(newSocket->socketfd==-1) + safethrow("can't create TCP socket", free(newSocket)); + return SUCCESS(UniHeapPtr(knSocketTCP, newSocket)); +} + +///@return Maybe error or nothing +Maybe knSocketTCP_close(knSocketTCP* socket){ + int rezult= +#if KN_USE_WINSOCK + closesocket +#else + close +#endif + (socket->socketfd); + if(rezult==-1) { + safethrow("can't close socket",;); + } + else return MaybeNull; +} + +///sets socket local endpoint +///@return Maybe error or nothing +Maybe knSocketTCP_listen(knSocketTCP* socket, knIPV4Endpoint localEndp){ + if(socket->localEndpoint.address.u32!=INADDR_NONE) + safethrow("socket is bound already",;); + struct sockaddr_in servaddr; + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(localEndp.address.u32); + servaddr.sin_port = htons(localEndp.port); + if(bind(socket->socketfd,(struct sockaddr*)&servaddr, sizeof(servaddr)) !=0) + safethrow("socket bind failed",;); + socket->localEndpoint=localEndp; + if(listen(socket->socketfd, 256) !=0) + safethrow("socket listen failed",;); + return MaybeNull; +} + +///sets socket remote endpoint +///@return Maybe error or nothing +Maybe knSocketTCP_connect(knSocketTCP* socket, knIPV4Endpoint remoteEndp){ + if(socket->remoteEndpoint.address.u32!=0) + safethrow("socket is connected already",;); + struct sockaddr_in servaddr; + servaddr.sin_family=AF_INET; + servaddr.sin_addr.s_addr = htonl(remoteEndp.address.u32); + servaddr.sin_port = htons(remoteEndp.port); + if(connect(socket->socketfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) !=0) + safethrow("socket connect failed",;); + socket->remoteEndpoint=remoteEndp; + return MaybeNull; +} + +///@return Maybe new socket connected to client +Maybe knSocketTCP_accept(knSocketTCP* socket); + +///@param dataLength 0-4294967295 +///@return Maybe +Maybe knSocketTCP_send(knSocketTCP* socket, char* data, uint32 dataLength); + +///@param buffer buffer for recieving data +///@param bufferLength 0-4294967295 +///@return Maybe recieved bytes amount +Maybe knSocketTCP_recieve(knSocketTCP* socket, char* buffer, uint32 bufferLength); diff --git a/src/Network/sockets/knSocketTCP.h b/src/Network/sockets/knSocketTCP.h new file mode 100644 index 0000000..8635e9e --- /dev/null +++ b/src/Network/sockets/knSocketTCP.h @@ -0,0 +1,45 @@ +#pragma once + +#if __cplusplus +extern "C" { +#endif + +#include "../../base/base.h" +#include "../knAddress.h" + +typedef struct knSocketTCP { + int64 socketfd; + knIPV4Endpoint localEndpoint; + knIPV4Endpoint remoteEndpoint; +} knSocketTCP; +ktid_declare(knSocketTCP); + +///@return Maybe new socket +Maybe knSocketTCP_open(); + +///@return Maybe error or nothing +Maybe knSocketTCP_close(knSocketTCP* socket); + +///start listening at local endpoint +///@return Maybe error or nothing +Maybe knSocketTCP_listen(knSocketTCP* socket, knIPV4Endpoint localEndp); + +///sets socket remote endpoint +///@return Maybe error or nothing +Maybe knSocketTCP_connect(knSocketTCP* socket, knIPV4Endpoint remoteEndp); + +///@return Maybe new socket connected to client +Maybe knSocketTCP_accept(knSocketTCP* socket); + +///@param dataLength 0-4294967295 +///@return Maybe +Maybe knSocketTCP_send(knSocketTCP* socket, char* data, uint32 dataLength); + +///@param buffer buffer for recieving data +///@param bufferLength 0-4294967295 +///@return Maybe recieved bytes amount +Maybe knSocketTCP_recieve(knSocketTCP* socket, char* buffer, uint32 bufferLength); + +#if __cplusplus +} +#endif \ No newline at end of file diff --git a/src/Network/sockets/knSocketUDP.c b/src/Network/sockets/knSocketUDP.c new file mode 100644 index 0000000..93a34d8 --- /dev/null +++ b/src/Network/sockets/knSocketUDP.c @@ -0,0 +1,29 @@ +#include "../network.h" +#include "../stdSocketHeaders.h" +ktid_define(knSocketUDP); + +///@return Maybe new socket +Maybe knSocketUDP_open(){ + knSocketUDP* newSocket=malloc(sizeof(knSocketUDP)); + newSocket->localEndpoint=knIPV4Endpoint_create(knIPV4Address_fromBytes(0,0,0,0),0); + newSocket->socketfd=socket(AF_INET, SOCK_DGRAM, 0); + if(newSocket->socketfd==-1) + safethrow("can't create UDP socket", free(newSocket)); + return SUCCESS(UniHeapPtr(knSocketUDP, newSocket)); +} + +///start listening at local endpoint +///@return Maybe error or nothing +Maybe knSocketUDP_listen(knSocketUDP* socket, knIPV4Endpoint localEndp); + +///@return Maybe new socket connected to client +Maybe knSocketUDP_accept(knSocketUDP* socket); + +///@param dataLength 0-4294967295 +///@return Maybe +Maybe knSocketUDP_sendto(knSocketUDP* socket, char* data, uint32 dataLength, knIPV4Endpoint destination); + +///@param buffer buffer for recieving data +///@param bufferLength 0-4294967295 +///@return Maybe recieved bytes amount +Maybe knSocketUDP_recieve(knSocketUDP* socket, char* buffer, uint32 bufferLength); diff --git a/src/Network/sockets/knSocketUDP.h b/src/Network/sockets/knSocketUDP.h new file mode 100644 index 0000000..eb3bfe1 --- /dev/null +++ b/src/Network/sockets/knSocketUDP.h @@ -0,0 +1,40 @@ +#pragma once + +#if __cplusplus +extern "C" { +#endif + +#include "knSocketUDP.h" + +typedef struct knSocketUDP { + int64 socketfd; + knIPV4Endpoint localEndpoint; +} knSocketUDP; +ktid_declare(knSocketUDP); + +///@return Maybe new socket +Maybe knSocketUDP_open(); + +///@return Maybe error or nothing +Maybe knSocketUDP_close(knSocketUDP* socket); + +///start listening at local endpoint +///@return Maybe error or nothing +Maybe knSocketUDP_listen(knSocketUDP* socket, knIPV4Endpoint localEndp); + +///@return Maybe new socket connected to client +Maybe knSocketUDP_accept(knSocketUDP* socket); + +///@param dataLength 0-4294967295 +///@return Maybe +Maybe knSocketUDP_sendto(knSocketUDP* socket, char* data, uint32 dataLength, knIPV4Endpoint destination); + +///@param buffer buffer for recieving data +///@param bufferLength 0-4294967295 +///@return Maybe recieved bytes amount +Maybe knSocketUDP_recieve(knSocketUDP* socket, char* buffer, uint32 bufferLength); + + +#if __cplusplus +} +#endif \ No newline at end of file diff --git a/tests/test_network.c b/tests/test_network.c index f2a2239..a59f0e0 100644 --- a/tests/test_network.c +++ b/tests/test_network.c @@ -4,9 +4,9 @@ void __test_knIPV4Address_fromStr(char* addrStr, uint8 a, uint8 b, uint8 c, uint8 d){ tryLast(knIPV4Address_fromStr(addrStr), maybeAddr){ knIPV4Address addr; - addr.address=(uint32)maybeAddr.value.UInt64; + addr.u32=(uint32)maybeAddr.value.UInt64; printf("\e[94mknIPV4Address_fromStr(\e[96m%s\e[94m) -> ", addrStr); - if(maybeAddr.value.UInt64!=knIPV4Address_fromBytes(a,b,c,d).address){ + if(maybeAddr.value.UInt64!=knIPV4Address_fromBytes(a,b,c,d).u32){ printf("\e[91m%u.%u.%u.%u\n", (uint8)addr.bytes[0], (uint8)addr.bytes[1], (uint8)addr.bytes[2], (uint8)addr.bytes[3]); throw("knIPV4Address_fromStr returned wrong value"); @@ -26,13 +26,13 @@ void test_network(){ PRINT_SIZEOF(knIPV4Endpoint); PRINT_SIZEOF(knPackage); PRINT_SIZEOF(knChannel); - PRINT_SIZEOF(knSocket); + PRINT_SIZEOF(knSocketTCP); test_knIPV4Address_fromStr(127,0,0,1); test_knIPV4Address_fromStr(34,255,45,0); test_knIPV4Address_fromStr(3,3,3,128); /* - knSocket* s; + knSocketTCP* s; tryLast(knSocket_open(knSocketProtocol_TCP), maybeS) s=maybeS.value.VoidPtr; printf("\e[92mTCP socket created\n");