diff --git a/dependencies/tlibc b/dependencies/tlibc index 447c15b..a9fa42c 160000 --- a/dependencies/tlibc +++ b/dependencies/tlibc @@ -1 +1 @@ -Subproject commit 447c15bc467546aa80245a7c5bc15d46d1349661 +Subproject commit a9fa42c23f8419ef80f7b74074030d54388cf410 diff --git a/src/main.c b/src/main.c index 0338ad0..1c52b9b 100755 --- a/src/main.c +++ b/src/main.c @@ -4,6 +4,7 @@ #include #include "tlibc/time.h" #include "errno.h" +#include Result(void) test_aes(){ const str password = STR("abobus"); @@ -54,33 +55,45 @@ 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), socket_close(main_socket.v_i64)); - try_fatal(_30, socket_listen(main_socket.v_i64, 64), socket_close(main_socket.v_i64)); + try_fatal(_20, socket_bind(main_socket.i, server_end), socket_close(main_socket.i)); + try_fatal(_30, socket_listen(main_socket.i, 64), socket_close(main_socket.i)); printf_safe("[server]: accepting client connection\n"); - try_fatal(client_conn, socket_accept(main_socket.v_i64), socket_close(main_socket.v_i64)); + try_fatal(client_conn, socket_accept(main_socket.i, NULL), socket_close(main_socket.i)); - Array buf = Array_alloc(u8, 1024); - i32 read_n; + // last byte is reserved for '\0' + Array buf = Array_construct(malloc(1024), u8, 1023); 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){ + while(true){ + try_fatal(read_n, + socket_recv(client_conn.i, buf), + socket_close(client_conn.i)); + if(read_n.i == 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 == ' ') + bool stop = false; + while(read_n.i > 0 && !stop) { - read_n--; + last_char = data_s[read_n.i - 1]; + switch(last_char){ + case '\0': case '\r': case '\n': + case '\t': case ' ': + read_n.i--; + break; + default: + stop = true; + break; + } } - data_s[read_n] = '\0'; - printf_safe("[server/out]: %s\n", (char*)buf.data); + data_s[read_n.i] = '\0'; + printf_safe("[server]: got '%s'\n", data_s); } - socket_close(client_conn.v_i64); + socket_close(client_conn.i); printf_safe("[server]: client socket closed\n"); perror("errno:"); - socket_close(main_socket.v_i64); + socket_close(main_socket.i); return NULL; } @@ -89,19 +102,20 @@ void* test_client(void* data){ 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)); + try_fatal(_20, + socket_connect(client_socket.i, server_end), + socket_close(client_socket.i)); Array buf = Array_alloc(u8, 1024); - i32 read_n = 999; + i32 read_n; 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); - } + while(fgets(buf.data, buf.size, stdin) != NULL){ + read_n = strlen(buf.data) + 1; + try_fatal(_50, + socket_send(client_socket.i, Array_construct_size(buf.data, read_n)), + socket_close(client_socket.i)); } printf_safe("[client]: stdin end\n"); - socket_close(client_socket.v_i64); + socket_close(client_socket.i); return NULL; } diff --git a/src/network/endpoint.c b/src/network/endpoint.c index 8237092..a3b0d38 100755 --- a/src/network/endpoint.c +++ b/src/network/endpoint.c @@ -1,5 +1,5 @@ +#include "std_includes.h" #include "endpoint.h" -#include "network.h" struct sockaddr_in EndpointIPv4_toSockaddr(EndpointIPv4 end){ struct sockaddr_in saddr = {0}; @@ -18,6 +18,7 @@ EndpointIPv4 EndpointIPv4_fromSockaddr(struct sockaddr_in saddr){ return end; } +//TODO Endpoint functions AddressIPv4 AddressIPv4_fromStr(cstr); str AddressIPv4_toStr(AddressIPv4 address); diff --git a/src/network/endpoint.h b/src/network/endpoint.h index c06378c..4bcd427 100755 --- a/src/network/endpoint.h +++ b/src/network/endpoint.h @@ -1,7 +1,6 @@ #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) diff --git a/src/network/network.c b/src/network/network.c index 41b7c94..c4190ca 100755 --- a/src/network/network.c +++ b/src/network/network.c @@ -1,5 +1,5 @@ #include "network.h" -#include "network.h" +#include "std_includes.h" Result(void) network_init(){ #if _WIN32 diff --git a/src/network/network.h b/src/network/network.h index 3b73072..7134aaf 100755 --- a/src/network/network.h +++ b/src/network/network.h @@ -1,22 +1,5 @@ #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 index 5db672c..2cf3195 100755 --- a/src/network/socket.c +++ b/src/network/socket.c @@ -1,14 +1,15 @@ -#include "network.h" -#include "network.h" +#include "std_includes.h" #include "socket.h" +#include "errno.h" +#include "assert.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_ERROR(strerror(errno), false); } - return RESULT_VALUE(i64, s); + return RESULT_VALUE(i, s); } void socket_close(Socket s){ @@ -21,33 +22,79 @@ void socket_close(Socket s){ Result(void) socket_shutdown(Socket s, SocketShutdownType direction){ if(shutdown(s, (int)direction) == -1) - return RESULT_ERROR("shutdown() failed", false); + return RESULT_ERROR(strerror(errno), 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_ERROR(strerror(errno), 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_ERROR(strerror(errno), false); return RESULT_VOID; } -Result(Socket) socket_accept(Socket main_socket) { +Result(Socket) socket_accept(Socket main_socket, NULLABLE(EndpointIPv4*) remote_end) { 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); + Socket user_connection = accept(main_socket, (void*)&remote_addr, (void*)&sockaddr_size); + if(user_connection == -1) + return RESULT_ERROR(strerror(errno), false); + + //TODO: add IPV6 support (struct sockaddr_in6) + assert(sockaddr_size == sizeof(remote_addr)); + if(remote_end) + *remote_end = EndpointIPv4_fromSockaddr(remote_addr); + return RESULT_VALUE(i, 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_ERROR(strerror(errno), false); return RESULT_VOID; } + +Result(void) socket_send(Socket s, Array buffer){ + i32 r = send(s, buffer.data, buffer.size, 0); + if(r < 0) + return RESULT_ERROR(strerror(errno), false); + return RESULT_VOID; +} + +Result(void) socket_sendto(Socket s, Array buffer, EndpointIPv4 dst){ + struct sockaddr_in sockaddr = EndpointIPv4_toSockaddr(dst); + i32 r = sendto(s, buffer.data, buffer.size, 0, (void*)&sockaddr, sizeof(sockaddr)); + if(r < 0) + return RESULT_ERROR(strerror(errno), false); + return RESULT_VOID; +} + +Result(i32) socket_recv(Socket s, Array buffer){ + i32 r = recv(s, buffer.data, buffer.size, 0); + if(r < 0) + return RESULT_ERROR(strerror(errno), false); + return RESULT_VALUE(i, r); +} + + +Result(i32) socket_recvfrom(Socket s, Array buffer, NULLABLE(EndpointIPv4*) remote_end){ + struct sockaddr_in remote_addr = {0}; + i32 sockaddr_size = sizeof(remote_addr); + i32 r = recvfrom(s, buffer.data, buffer.size, 0, + (struct sockaddr*)&remote_addr, (void*)&sockaddr_size); + if(r < 0) + return RESULT_ERROR(strerror(errno), false); + + //TODO: add IPV6 support (struct sockaddr_in6) + assert(sockaddr_size == sizeof(remote_addr)); + + if(remote_end) + *remote_end = EndpointIPv4_fromSockaddr(remote_addr); + return RESULT_VALUE(i, r); +} \ No newline at end of file diff --git a/src/network/socket.h b/src/network/socket.h index dbe4c43..f4fabee 100755 --- a/src/network/socket.h +++ b/src/network/socket.h @@ -1,6 +1,7 @@ #pragma once #include "endpoint.h" #include "tlibc/errors.h" +#include "tlibc/collections/Array.h" typedef enum SocketShutdownType { SocketShutdownType_Receive = 0, @@ -10,10 +11,14 @@ typedef enum 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 s); -Result(void) socket_connect(Socket s, EndpointIPv4 remote_end); +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 s, NULLABLE(EndpointIPv4*) remote_end); +Result(void) socket_connect(Socket s, EndpointIPv4 remote_end); +Result(void) socket_send(Socket s, Array buffer); +Result(void) socket_sendto(Socket s, Array buffer, EndpointIPv4 dst); +Result(i32) socket_recv(Socket s, Array buffer); +Result(i32) socket_recvfrom(Socket s, Array buffer, NULLABLE(EndpointIPv4*) remote_end); diff --git a/src/network/std_includes.h b/src/network/std_includes.h new file mode 100644 index 0000000..17501f3 --- /dev/null +++ b/src/network/std_includes.h @@ -0,0 +1,18 @@ +#pragma once + +#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