diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c index df56f490..15212d84 100644 --- a/toxcore/TCP_server.c +++ b/toxcore/TCP_server.c @@ -115,12 +115,17 @@ static int bind_to_port(sock_t sock, int family, uint16_t port) */ static uint16_t read_length(sock_t sock) { - int count; +#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) + unsigned long count = 0; + ioctlsocket(sock, FIONREAD, &count); +#else + int count = 0; ioctl(sock, FIONREAD, &count); +#endif if ((unsigned int)count >= sizeof(uint16_t)) { uint16_t length; - int len = recv(sock, &length, sizeof(uint16_t), 0); + int len = recv(sock, (uint8_t *)&length, sizeof(uint16_t), 0); if (len != sizeof(uint16_t)) { fprintf(stderr, "FAIL recv packet\n"); @@ -144,8 +149,13 @@ static uint16_t read_length(sock_t sock) */ static int read_TCP_packet(sock_t sock, uint8_t *data, uint16_t length) { - int count; +#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) + unsigned long count = 0; + ioctlsocket(sock, FIONREAD, &count); +#else + int count = 0; ioctl(sock, FIONREAD, &count); +#endif if (count >= length) { int len = recv(sock, data, length, 0); @@ -155,12 +165,82 @@ static int read_TCP_packet(sock_t sock, uint8_t *data, uint16_t length) return -1; } - return length; + return len; } return -1; } +/* return length of recieved packet on success. + * return 0 if could not read any packet. + * return -1 on failure (connection must be killed). + */ +static int read_packet_TCP_secure_connection(TCP_Secure_Connection *con, uint8_t *data, uint16_t max_len) +{ + if (con->next_packet_length == 0) { + uint16_t len = read_length(con->sock); + + if (len == (uint16_t)~0) + return -1; + + if (len == 0) + return 0; + + con->next_packet_length = len; + } + + if (max_len + crypto_box_MACBYTES < con->next_packet_length) + return -1; + + uint8_t data_encrypted[con->next_packet_length]; + int len_packet = read_TCP_packet(con->sock, data_encrypted, con->next_packet_length); + + if (len_packet != con->next_packet_length) + return 0; + + con->next_packet_length = 0; + + int len = decrypt_data_fast(con->shared_key, con->recv_nonce, data_encrypted, len_packet, data); + + if (len + crypto_box_MACBYTES != len_packet) + return -1; + + increment_nonce(con->recv_nonce); + + return len; +} + +/* return 1 on success. + * return 0 if could not send packet. + * return -1 on failure (connection must be killed). + */ +static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, uint8_t *data, uint16_t length) +{ + if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE) + return -1; + + uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES]; + + length = htons(length); + memcpy(packet, &length, sizeof(uint16_t)); + uint32_t len = encrypt_data_fast(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); + + if (len != (sizeof(packet) - sizeof(uint16_t))) + return -1; + + increment_nonce(con->sent_nonce); + + len = send(con->sock, packet, sizeof(packet), 0); + + if (len == sizeof(packet)) + return 1; + + if (len <= 0) + return 0; + + return -1; +} + /* Kill a TCP_Secure_Connection */ static void kill_TCP_connection(TCP_Secure_Connection *con) @@ -228,6 +308,13 @@ static int read_connection_handshake(TCP_Secure_Connection *con, uint8_t *self_s return 0; } + +static int confirm_TCP_connection(TCP_Secure_Connection *con, uint8_t *data, uint16_t length) +{ + + return 0; +} + /* return 1 on success * return 0 on failure */ @@ -368,8 +455,24 @@ static void do_TCP_unconfirmed(TCP_Server *TCP_server) uint32_t i; for (i = 0; i < MAX_INCOMMING_CONNECTIONS; ++i) { - if (TCP_server->incomming_connection_queue[i].status != TCP_STATUS_CONNECTED) + TCP_Secure_Connection *conn = &TCP_server->unconfirmed_connection_queue[i]; + + if (conn->status != TCP_STATUS_UNCONFIRMED) continue; + + uint8_t packet[MAX_PACKET_SIZE]; + int len = read_packet_TCP_secure_connection(conn, packet, sizeof(packet)); + + if (len == 0) { + continue; + } else if (len == -1) { + kill_TCP_connection(conn); + continue; + } else { + //TODO + confirm_TCP_connection(conn, packet, len); + kill_TCP_connection(conn); + } } } void do_TCP_server(TCP_Server *TCP_server) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index d2dbc90f..17d2e8ff 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -159,7 +159,7 @@ int decrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *encrypt } /* Increment the given nonce by 1. */ -static void increment_nonce(uint8_t *nonce) +void increment_nonce(uint8_t *nonce) { uint32_t i; diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 74c3326a..da776527 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -132,6 +132,9 @@ int encrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *plain, */ int decrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *encrypted, uint32_t length, uint8_t *plain); +/* Increment the given nonce by 1. */ +void increment_nonce(uint8_t *nonce); + /* Fill the given nonce with random bytes. */ void random_nonce(uint8_t *nonce); diff --git a/toxcore/network.c b/toxcore/network.c index d7ea2bf0..64f0af2f 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -36,10 +36,6 @@ #include "network.h" #include "util.h" -#ifndef IPV6_V6ONLY -#define IPV6_V6ONLY 27 -#endif - #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) static const char *inet_ntop(sa_family_t family, void *addr, char *buf, size_t bufsize) diff --git a/toxcore/network.h b/toxcore/network.h index b0d306e4..5e434c1a 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -44,6 +44,10 @@ #include #include +#ifndef IPV6_V6ONLY +#define IPV6_V6ONLY 27 +#endif + typedef unsigned int sock_t; /* sa_family_t is the sockaddr_in / sockaddr_in6 family field */ typedef short sa_family_t;