diff --git a/dependencies/tlibc b/dependencies/tlibc index 8999fda..ba7a81d 160000 --- a/dependencies/tlibc +++ b/dependencies/tlibc @@ -1 +1 @@ -Subproject commit 8999fda11c99717b2415c9d351a46d796c46c67b +Subproject commit ba7a81d205a7dfe49d64f0f9c6b8d97d693d5ec2 diff --git a/src/cryptography.c b/src/cryptography/AES.c similarity index 87% rename from src/cryptography.c rename to src/cryptography/AES.c index 5e05389..fb7c881 100755 --- a/src/cryptography.c +++ b/src/cryptography/AES.c @@ -1,26 +1,7 @@ #include "cryptography.h" #include "BearSSL/inc/bearssl_block.h" -#include "BearSSL/inc/bearssl_hash.h" -#include "BearSSL/inc/bearssl_rand.h" #include -Array hash_password(str password, i32 iterations){ - Array hash_buffer = Array_alloc(u8, br_sha256_SIZE); - Array_memset(&hash_buffer, 0); - br_sha256_context sha256_ctx; - br_sha256_init(&sha256_ctx); - - for(i32 i = 0; i < iterations; i++){ - br_sha256_update(&sha256_ctx, password.data, password.size); - br_sha256_out(&sha256_ctx, hash_buffer.data); - br_sha256_update(&sha256_ctx, hash_buffer.data, hash_buffer.size); - } - br_sha256_out(&sha256_ctx, hash_buffer.data); - - return hash_buffer; -} - - // size must be multiple of 16 #define __AES_BUFFER_SIZE 256 diff --git a/src/cryptography.h b/src/cryptography/cryptography.h similarity index 100% rename from src/cryptography.h rename to src/cryptography/cryptography.h diff --git a/src/cryptography/hash.c b/src/cryptography/hash.c new file mode 100755 index 0000000..af881b7 --- /dev/null +++ b/src/cryptography/hash.c @@ -0,0 +1,18 @@ +#include "cryptography.h" +#include "BearSSL/inc/bearssl_hash.h" + +Array hash_password(str password, i32 iterations){ + Array hash_buffer = Array_alloc(u8, br_sha256_SIZE); + Array_memset(&hash_buffer, 0); + br_sha256_context sha256_ctx; + br_sha256_init(&sha256_ctx); + + for(i32 i = 0; i < iterations; i++){ + br_sha256_update(&sha256_ctx, password.data, password.size); + br_sha256_out(&sha256_ctx, hash_buffer.data); + br_sha256_update(&sha256_ctx, hash_buffer.data, hash_buffer.size); + } + br_sha256_out(&sha256_ctx, hash_buffer.data); + + return hash_buffer; +} diff --git a/src/main.c b/src/main.c index 782b243..3341f6f 100755 --- a/src/main.c +++ b/src/main.c @@ -1,7 +1,8 @@ -#include "cryptography.h" -#include "tlibc/string/StringBuilder.h" +#include "cryptography/cryptography.h" +#include "network/network.h" +#include "network/socket.h" -int main(){ +void test_aes(){ const str password = STR("abobus"); const Array data = str_castTo_Array(STR("0123456789_hii_")); @@ -31,6 +32,18 @@ int main(){ str decrypted_str = str_copy(str_construct(buffer.data, decrypted_size, false)); printf("data decrypted (utf8): %s\n", decrypted_str.data); free(decrypted_str.data); +} +void test_server(){ + try_fatal(_10, network_init(), ); + try_fatal(main_socket, socket_open_TCP(), ); + EndpointIPv4 server_end = EndpointIPv4_create(AddressIPv4_LOOPBACK, 24500); + try_fatal(_20, socket_bind(main_socket.v_i64, server_end), ); + try_fatal(_30, socket_listen(main_socket.v_i64, 64), ); + try_fatal(_100, network_deinit(), ); +} + +int main(){ + test_server(); return 0; } diff --git a/src/network/endpoint.c b/src/network/endpoint.c new file mode 100755 index 0000000..8237092 --- /dev/null +++ b/src/network/endpoint.c @@ -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); + diff --git a/src/network/endpoint.h b/src/network/endpoint.h new file mode 100755 index 0000000..c06378c --- /dev/null +++ b/src/network/endpoint.h @@ -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); diff --git a/src/network/network.c b/src/network/network.c new file mode 100755 index 0000000..41b7c94 --- /dev/null +++ b/src/network/network.c @@ -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; +} diff --git a/src/network/network.h b/src/network/network.h new file mode 100755 index 0000000..3b73072 --- /dev/null +++ b/src/network/network.h @@ -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 +#else + #include + #include + #include + #include + #include + #include +#endif + +Result(void) network_init(); +Result(void) network_deinit(); diff --git a/src/network/socket.c b/src/network/socket.c new file mode 100755 index 0000000..0467be9 --- /dev/null +++ b/src/network/socket.c @@ -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); +} diff --git a/src/network/socket.h b/src/network/socket.h new file mode 100755 index 0000000..b057773 --- /dev/null +++ b/src/network/socket.h @@ -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); \ No newline at end of file