diff --git a/src/Network/network.c b/src/Network/network.c new file mode 100644 index 0000000..6a29d30 --- /dev/null +++ b/src/Network/network.c @@ -0,0 +1,41 @@ +#include "network.h" + +Maybe knIPV4Address_fromStr(char* addrStr){ + char* addrStr_src=addrStr; + char* errmsg_extra="wrong char"; + uint8 c; + knIPV4Address addr; + addr.address=0; + uint16 n=0; + for(uint8 i=0; i<4; ){ + c=*addrStr++; + switch (c){ + case '\0': + if(i<3) { + errmsg_extra="end of string"; + goto default_case; + } + case '.': + addr.bytes[i++]=n; + n=0; + break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + n=n*10+c-'0'; + if(n>255) { + errmsg_extra="one part of address > 255"; + goto default_case; + } + break; + default_case: + default: + uint32 errmsgL=cptr_length(addrStr) + 80; + char* errmsg=malloc(errmsgL); + IFWIN(sprintf_s(errmsg, errmsgL, "wrong ip address string: %s\n %s", addrStr_src, errmsg_extra), + sprintf( errmsg, "wrong ip address string: %s\n %s", addrStr_src, errmsg_extra)); + safethrow(errmsg,;); + break; + } + } + return SUCCESS(Uni(UInt64, (uint64)addr.address)); +} \ No newline at end of file diff --git a/src/Network/network.h b/src/Network/network.h index f877cac..d55b38d 100644 --- a/src/Network/network.h +++ b/src/Network/network.h @@ -6,7 +6,12 @@ extern "C" { #include "../Hashtable/Hashtable.h" -#if defined(_MSC_VER) || defined(_WIN64) || defined(_WIN32) + +#if defined(_MSC_VER) || defined(_WIN64) || defined(_WIN32) || 1 + #define KN_USE_WINSOCK 1 +#endif + +#if KN_USE_WINSOCK #include "winsock.h" #else #include "../Hashtable/Hashtable.h" @@ -16,28 +21,96 @@ extern "C" { #include #endif -#define KNPAC_MAX_DATA_SIZE 65503 +#define KNPAC_MAX_DATA_SIZE (65535-sizeof(knPackage)+sizeof(uint8*)) -typedef struct knPackage{ + +typedef enum __attribute__((__packed__)) knPacVersion { + knPac_V1 +} knPacVersion; + +typedef struct knPackage { char header[5]; // knpac - uint8 version; // protocol version - uint16 data_size; // size of data block in bytes (1-) + knPacVersion version; // protocol version + uint16 data_size; // size of data block in bytes (1-KNPAC_MAX_DATA_SIZE) uint32 package_num; // number in sequence of sent packages uint32 destination_hash; // hash32 of knDestination.name uint64 data_hash; // hash64 of data uint8* data; // ptr to data } knPackage; -typedef struct knDestination{ - char* name; +typedef struct knPackageQueueElem knPackageQueueElem; +struct knPackageQueueElem { + union{ + knPackage; + knPackage package; + }; + knPackageQueueElem* previousElem; + knPackageQueueElem* nextElem; +}; + +typedef struct knDestination { + knPackageQueueElem* queueStart; } knDestination; +typedef union knIPV4Address { + uint32 address; + char bytes[4]; +} knIPV4Address; + +#define knIPV4Address_fromBytes(A, B, C, D) (knIPV4Address){.bytes={A,B,C,D}} + +///@return Maybe as Maybe +Maybe knIPV4Address_fromStr(char* addrStr); + +typedef uint16 knPort; + +typedef struct __attribute__((__packed__)) knIPV4Endpoint { + knIPV4Address address; + knPort port; +} knIPV4Endpoint; + +#define knIPV4Endpoint_create(ADDR, PORT) (knIPV4Endpoint){ADDR, PORT} + +typedef enum __attribute__((__packed__)) knSockType { + knSockType_TCP, knSockType_UDP +} knSockType; + typedef struct knSocket { - Hashtable* destinations; + knDestination* destinations; int socketfd; + knSockType type; + knIPV4Endpoint localEndpoint; + knIPV4Endpoint remoteEndpoint; } knSocket; +///@returns Maybe new socket +Maybe knSocket_open(knSockType 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, uint8* data, uint32 dataLength); + +///@param buffer buffer for recieving data +///@param bufferLength 0-4294967295 +///@return Maybe recieved bytes amount +Maybe knSocket_recieve(knSocket* socket, uint8* buffer, uint32 bufferLength); + + #if __cplusplus } #endif \ No newline at end of file