diff --git a/dependencies/tlibc b/dependencies/tlibc index ba7a81d..447c15b 160000 --- a/dependencies/tlibc +++ b/dependencies/tlibc @@ -1 +1 @@ -Subproject commit ba7a81d205a7dfe49d64f0f9c6b8d97d693d5ec2 +Subproject commit 447c15bc467546aa80245a7c5bc15d46d1349661 diff --git a/src/main.c b/src/main.c index 3341f6f..0338ad0 100755 --- a/src/main.c +++ b/src/main.c @@ -1,8 +1,11 @@ #include "cryptography/cryptography.h" #include "network/network.h" #include "network/socket.h" +#include +#include "tlibc/time.h" +#include "errno.h" -void test_aes(){ +Result(void) test_aes(){ const str password = STR("abobus"); const Array data = str_castTo_Array(STR("0123456789_hii_")); @@ -32,18 +35,100 @@ void test_aes(){ 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); + + return RESULT_VOID; } -void test_server(){ - try_fatal(_10, network_init(), ); + +static pthread_mutex_t stdout_mutex = {0}; + +// thread-safe print +#define printf_safe(ARGS...) {\ + pthread_mutex_lock(&stdout_mutex);\ + printf(ARGS);\ + fflush(stdout);\ + pthread_mutex_unlock(&stdout_mutex);\ +} + +void* test_server(void* data){ + printf_safe("[server]: opening main socket\n"); 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(), ); + try_fatal(_20, socket_bind(main_socket.v_i64, server_end), socket_close(main_socket.v_i64)); + try_fatal(_30, socket_listen(main_socket.v_i64, 64), socket_close(main_socket.v_i64)); + printf_safe("[server]: accepting client connection\n"); + try_fatal(client_conn, socket_accept(main_socket.v_i64), socket_close(main_socket.v_i64)); + + Array buf = Array_alloc(u8, 1024); + i32 read_n; + printf_safe("[server]: receiving data from client\n"); + while((read_n = recv(client_conn.v_i64, buf.data, buf.size - 1, 0)) != -1){ + if(read_n == 0){ + sleepMsec(20); + continue; + } + char* data_s = (char*)buf.data; + char last_char; + while((last_char = data_s[read_n - 1]) == '\n' + || last_char == '\r' || last_char == ' ' || last_char == ' ') + { + read_n--; + } + data_s[read_n] = '\0'; + printf_safe("[server/out]: %s\n", (char*)buf.data); + } + socket_close(client_conn.v_i64); + printf_safe("[server]: client socket closed\n"); + perror("errno:"); + socket_close(main_socket.v_i64); + return NULL; +} + +void* test_client(void* data){ + printf_safe("[client]: opening socket\n"); + try_fatal(client_socket, socket_open_TCP(), ); + printf_safe("[client]: connecting to server\n"); + EndpointIPv4 server_end = EndpointIPv4_create(AddressIPv4_LOOPBACK, 24500); + try_fatal(_20, socket_connect(client_socket.v_i64, server_end), socket_close(client_socket.v_i64)); + Array buf = Array_alloc(u8, 1024); + i32 read_n = 999; + printf_safe("[client]: reading stdin\n"); + while((read_n = read(STDIN_FILENO, buf.data, buf.size - 1)) > 0){ + if(send(client_socket.v_i64, buf.data, read_n, 0) < 0){ + socket_close(client_socket.v_i64); + printf_safe("[client]: can't send data to server\n"); + exit(20); + } + } + printf_safe("[client]: stdin end\n"); + socket_close(client_socket.v_i64); + return NULL; +} + +Result(void) test_network(){ + if(pthread_mutex_init(&stdout_mutex, NULL) != 0) + return RESULT_ERROR("can't init mutex", false); + + pthread_t server_thread = {0}; + if(pthread_create(&server_thread, NULL, test_server, NULL) != 0) + return RESULT_ERROR("can't create server thread", false); + + sleepMsec(100); + test_client(NULL); + + printf_safe("[main]: joining server thread\n"); + if(pthread_join(server_thread, NULL) != 0) + return RESULT_ERROR("can't join server thread", false); + if(pthread_mutex_destroy(&stdout_mutex) != 0) + return RESULT_ERROR("can't destroy mutex", false); + printf_safe("[main]: completed\n"); + return RESULT_VOID; } int main(){ - test_server(); + try_fatal(_10, network_init(), ); + // try_fatal(_20, test_aes(), ); + try_fatal(_30, test_network(), ); + try_fatal(_100, network_deinit(), ); return 0; } diff --git a/src/network/socket.c b/src/network/socket.c index 0467be9..5db672c 100755 --- a/src/network/socket.c +++ b/src/network/socket.c @@ -44,3 +44,10 @@ Result(Socket) socket_accept(Socket main_socket) { Socket user_connection = accept(main_socket, (struct sockaddr*)&remote_addr, (void*)&sockaddr_size); return RESULT_VALUE(i64, user_connection); } + +Result(void) socket_connect(Socket s, EndpointIPv4 remote_end){ + struct sockaddr_in sockaddr = EndpointIPv4_toSockaddr(remote_end); + if(connect(s, (void*)&sockaddr, sizeof(sockaddr)) != 0) + return RESULT_ERROR("connect() failed", false); + return RESULT_VOID; +} diff --git a/src/network/socket.h b/src/network/socket.h index b057773..dbe4c43 100755 --- a/src/network/socket.h +++ b/src/network/socket.h @@ -15,4 +15,5 @@ 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 +Result(Socket) socket_accept(Socket s); +Result(void) socket_connect(Socket s, EndpointIPv4 remote_end);