Some code written for the TCP part.

This commit is contained in:
irungentoo 2014-04-11 22:09:04 -04:00
parent 736f5f8034
commit 881e95671a
No known key found for this signature in database
GPG Key ID: 10349DC9BED89E98
3 changed files with 165 additions and 14 deletions

View File

@ -130,6 +130,103 @@ static int send_pending_data(TCP_Client_Connection *con)
return -1;
}
/* 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_Client_Connection *con, uint8_t *data, uint16_t length)
{
if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE)
return -1;
if (send_pending_data(con) == -1)
return 0;
uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES];
uint16_t c_length = htons(length + crypto_box_MACBYTES);
memcpy(packet, &c_length, sizeof(uint16_t));
int len = encrypt_data_fast(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t)))
return -1;
increment_nonce(con->sent_nonce);
len = send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL);
if ((unsigned int)len == sizeof(packet))
return 1;
if (len <= 0)
return 0;
memcpy(con->last_packet, packet, length);
con->last_packet_length = sizeof(packet);
con->last_packet_sent = len;
return 1;
}
/* return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
static int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key)
{
uint8_t packet[1 + crypto_box_PUBLICKEYBYTES];
packet[0] = TCP_PACKET_ROUTING_REQUEST;
memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES);
return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
}
/* return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
static int send_disconnect_notification(TCP_Client_Connection *con, uint8_t id)
{
uint8_t packet[1 + 1];
packet[0] = TCP_PACKET_DISCONNECT_NOTIFICATION;
packet[1] = id;
return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
}
/* return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
static int send_ping_request(TCP_Client_Connection *con, uint64_t ping_id)
{
uint8_t packet[1 + sizeof(uint64_t)];
packet[0] = TCP_PACKET_PING;
memcpy(packet + 1, &ping_id, sizeof(uint64_t));
return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
}
/* return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
static int send_ping_response(TCP_Client_Connection *con, uint64_t ping_id)
{
uint8_t packet[1 + sizeof(uint64_t)];
packet[0] = TCP_PACKET_PONG;
memcpy(packet + 1, &ping_id, sizeof(uint64_t));
return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
}
/* return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
static int send_onion_request(TCP_Client_Connection *con, uint8_t *data, uint16_t length)
{
uint8_t packet[1 + length];
packet[0] = TCP_PACKET_ONION_REQUEST;
memcpy(packet + 1, data, length);
return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
}
/* Create new TCP connection to ip_port/public_key
*/
TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, uint8_t *public_key, uint8_t *self_public_key,
@ -176,8 +273,51 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, uint8_t *public_key,
return temp;
}
static int do_confirmed_TCP(TCP_Client_Connection *TCP_connection)
/* return 0 on success
* return -1 on failure
*/
static int handle_TCP_packet(TCP_Client_Connection *conn, uint8_t *data, uint16_t length)
{
if (length == 0)
return -1;
switch (data[0]) {
case TCP_PACKET_PING: {
if (length != 1 + sizeof(uint64_t))
return -1;
uint64_t ping_id;
memcpy(&ping_id, data + 1, sizeof(uint64_t));
send_ping_response(conn, ping_id);
return 0;
}
default: {
}
}
return 0;
}
static int do_confirmed_TCP(TCP_Client_Connection *conn)
{
send_pending_data(conn);
uint8_t packet[MAX_PACKET_SIZE];
int len;
while ((len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key,
conn->recv_nonce, packet, sizeof(packet)))) {
if (len == -1) {
conn->status = TCP_CLIENT_DISCONNECTED;
break;
}
if (handle_TCP_packet(conn, packet, len) == -1) {
conn->status = TCP_CLIENT_DISCONNECTED;
break;
}
}
return 0;
}

View File

@ -228,10 +228,11 @@ int read_TCP_packet(sock_t sock, uint8_t *data, uint16_t length)
* 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)
int read_packet_TCP_secure_connection(sock_t sock, uint16_t *next_packet_length, uint8_t *shared_key,
uint8_t *recv_nonce, uint8_t *data, uint16_t max_len)
{
if (con->next_packet_length == 0) {
uint16_t len = read_TCP_length(con->sock);
if (*next_packet_length == 0) {
uint16_t len = read_TCP_length(sock);
if (len == (uint16_t)~0)
return -1;
@ -239,26 +240,26 @@ static int read_packet_TCP_secure_connection(TCP_Secure_Connection *con, uint8_t
if (len == 0)
return 0;
con->next_packet_length = len;
*next_packet_length = len;
}
if (max_len + crypto_box_MACBYTES < con->next_packet_length)
if (max_len + crypto_box_MACBYTES < *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);
uint8_t data_encrypted[*next_packet_length];
int len_packet = read_TCP_packet(sock, data_encrypted, *next_packet_length);
if (len_packet != con->next_packet_length)
if (len_packet != *next_packet_length)
return 0;
con->next_packet_length = 0;
*next_packet_length = 0;
int len = decrypt_data_fast(con->shared_key, con->recv_nonce, data_encrypted, len_packet, data);
int len = decrypt_data_fast(shared_key, recv_nonce, data_encrypted, len_packet, data);
if (len + crypto_box_MACBYTES != len_packet)
return -1;
increment_nonce(con->recv_nonce);
increment_nonce(recv_nonce);
return len;
}
@ -848,7 +849,8 @@ static void do_TCP_unconfirmed(TCP_Server *TCP_server)
continue;
uint8_t packet[MAX_PACKET_SIZE];
int len = read_packet_TCP_secure_connection(conn, packet, sizeof(packet));
int len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key, conn->recv_nonce,
packet, sizeof(packet));
if (len == 0) {
continue;
@ -902,7 +904,8 @@ static void do_TCP_confirmed(TCP_Server *TCP_server)
uint8_t packet[MAX_PACKET_SIZE];
int len;
while ((len = read_packet_TCP_secure_connection(conn, packet, sizeof(packet)))) {
while ((len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key,
conn->recv_nonce, packet, sizeof(packet)))) {
if (len == -1) {
kill_TCP_connection(conn);
del_accepted(TCP_server, i);

View File

@ -140,4 +140,12 @@ uint16_t read_TCP_length(sock_t sock);
*/
int read_TCP_packet(sock_t sock, uint8_t *data, uint16_t length);
/* return length of recieved packet on success.
* return 0 if could not read any packet.
* return -1 on failure (connection must be killed).
*/
int read_packet_TCP_secure_connection(sock_t sock, uint16_t *next_packet_length, uint8_t *shared_key,
uint8_t *recv_nonce, uint8_t *data, uint16_t max_len);
#endif