Skip to content

Commit

Permalink
Net_crypto can now handle packets sent as TCP OOB packets.
Browse files Browse the repository at this point in the history
Added timestamp to know which DHT public key is good in case
onion_client and net_crypto report different ones.
  • Loading branch information
irungentoo committed May 17, 2014
1 parent 454cadb commit a5da6df
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 20 deletions.
5 changes: 3 additions & 2 deletions toxcore/Messenger.c
Original file line number Diff line number Diff line change
Expand Up @@ -2202,8 +2202,9 @@ void do_friends(Messenger *m)
friend_new_connection(m, i, m->friendlist[i].client_id);
uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES];

if (onion_getfriend_DHT_pubkey(m->onion_c, m->friendlist[i].onion_friendnum, dht_public_key) == 0) {
set_connection_dht_public_key(m->net_crypto, m->friendlist[i].crypt_connection_id, dht_public_key);
uint64_t timestamp = onion_getfriend_DHT_pubkey(m->onion_c, m->friendlist[i].onion_friendnum, dht_public_key);
if (timestamp != 0) {
set_connection_dht_public_key(m->net_crypto, m->friendlist[i].crypt_connection_id, dht_public_key, timestamp);
}

uint8_t direct_connected;
Expand Down
80 changes: 75 additions & 5 deletions toxcore/net_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,33 @@ static int tcp_handle_cookie_request(Net_Crypto *c, TCP_Client_Connection *TCP_c
if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data))
return -1;

if ((uint32_t)send_data(TCP_con, conn_id, data, sizeof(data)) != 1)
if (send_data(TCP_con, conn_id, data, sizeof(data)) != 1)
return -1;

return 0;
}

/* Handle the cookie request packet (for TCP oob packets)
*/
static int tcp_oob_handle_cookie_request(Net_Crypto *c, TCP_Client_Connection *TCP_con, uint8_t *dht_public_key,
uint8_t *packet, uint32_t length)
{
uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
uint8_t shared_key[crypto_box_BEFORENMBYTES];
uint8_t dht_public_key_temp[crypto_box_PUBLICKEYBYTES];

if (handle_cookie_request(c, request_plain, shared_key, dht_public_key_temp, packet, length) != 0)
return -1;

if (memcmp(dht_public_key, dht_public_key_temp, crypto_box_PUBLICKEYBYTES) != 0)
return -1;

uint8_t data[COOKIE_RESPONSE_LENGTH];

if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data))
return -1;

if (send_oob_packet(TCP_con, dht_public_key, data, sizeof(data)) != 1)
return -1;

return 0;
Expand Down Expand Up @@ -1115,7 +1141,7 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, uint

conn->status = CRYPTO_CONN_NOT_CONFIRMED;
/* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */
set_connection_dht_public_key(c, crypt_connection_id, dht_public_key);
set_connection_dht_public_key(c, crypt_connection_id, dht_public_key, current_time_monotonic());
} else {
return -1;
}
Expand Down Expand Up @@ -1326,7 +1352,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, IP_Port source, uint8_
if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) == 0) {
conn->status = CRYPTO_CONN_NOT_CONFIRMED;
/* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */
set_connection_dht_public_key(c, crypt_connection_id, n_c.dht_public_key);
set_connection_dht_public_key(c, crypt_connection_id, n_c.dht_public_key, current_time_monotonic());
ret = 0;
}
}
Expand Down Expand Up @@ -1375,7 +1401,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)

conn->status = CRYPTO_CONN_NOT_CONFIRMED;
/* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */
set_connection_dht_public_key(c, crypt_connection_id, n_c->dht_public_key);
set_connection_dht_public_key(c, crypt_connection_id, n_c->dht_public_key, current_time_monotonic());
conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
crypto_connection_add_source(c, crypt_connection_id, n_c->source);
return crypt_connection_id;
Expand Down Expand Up @@ -1463,17 +1489,22 @@ static int connect_peer_tcp(Net_Crypto *c, int crypt_connection_id)
}

/* Set the DHT public key of the crypto connection.
* timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to
* the other peer.
*
* return -1 on failure.
* return 0 on success.
*/
int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key)
int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key, uint64_t timestamp)
{
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);

if (conn == 0)
return -1;

if (timestamp <= conn->dht_public_key_timestamp)
return -1;

if (conn->dht_public_key_set == 1 && memcmp(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
return -1;

Expand All @@ -1483,6 +1514,7 @@ int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_

memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES);
conn->dht_public_key_set = 1;
conn->dht_public_key_timestamp = timestamp;

if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) {
conn->cookie_request_number = random_64b();
Expand Down Expand Up @@ -1597,6 +1629,43 @@ static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_i
return 0;
}

static int tcp_oob_callback(void *object, uint8_t *public_key, uint8_t *data, uint16_t length)
{
if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE)
return -1;

TCP_Client_Connection *TCP_con = object;
Net_Crypto *c = TCP_con->net_crypto_pointer;
uint32_t location = TCP_con->net_crypto_location;

if (data[0] == NET_PACKET_COOKIE_REQUEST) {
return tcp_oob_handle_cookie_request(c, TCP_con, public_key, data, length);
}

int crypt_connection_id = getcryptconnection_id_dht_pubkey(c, public_key);

if (crypt_connection_id == -1) {
IP_Port source;
source.ip.family = TCP_FAMILY;
source.ip.ip6.uint32[0] = location;

if (data[0] != NET_PACKET_CRYPTO_HS) {
fprintf(stderr, "tcp snhappen %u\n", data[0]);
return -1;
}

if (handle_new_connection_handshake(c, source, data, length) != 0)
return -1;

return 0;
}

if (handle_packet_connection(c, crypt_connection_id, data, length) != 0)
return -1;

return 0;
}

/* Check if tcp connection to public key can be created.
*
* return -1 if it can't.
Expand Down Expand Up @@ -1696,6 +1765,7 @@ static int add_tcp_connected(Net_Crypto *c, TCP_Client_Connection *tcp_con)
routing_response_handler(tcp_con, tcp_response_callback, tcp_con);
routing_status_handler(tcp_con, tcp_status_callback, tcp_con);
routing_data_handler(tcp_con, tcp_data_callback, tcp_con);
oob_data_handler(tcp_con, tcp_oob_callback, tcp_con);
c->tcp_connections[tcp_num] = tcp_con;
return 0;
}
Expand Down
5 changes: 4 additions & 1 deletion toxcore/net_crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ typedef struct {
uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */
uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; /* The dht public key of the peer */
uint8_t dht_public_key_set; /* True if the dht public key is set, false if it isn't. */
uint64_t dht_public_key_timestamp; /* Timestamp of the last time we confirmed the key was correct. */

uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */
uint16_t temp_packet_length;
Expand Down Expand Up @@ -186,11 +187,13 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c);
int new_crypto_connection(Net_Crypto *c, uint8_t *real_public_key);

/* Set the DHT public key of the crypto connection.
* timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to
* the other peer.
*
* return -1 on failure.
* return 0 on success.
*/
int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key);
int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key, uint64_t timestamp);

/* Set the direct ip of the crypto connection.
*
Expand Down
1 change: 1 addition & 0 deletions toxcore/network.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ typedef int sock_t;
#define TCP_ONION_FAMILY (AF_INET6 + 1)
#define TCP_INET (AF_INET6 + 2)
#define TCP_INET6 (AF_INET6 + 3)
#define TCP_FAMILY (AF_INET6 + 4)

typedef union __attribute__ ((__packed__))
{
Expand Down
17 changes: 9 additions & 8 deletions toxcore/onion_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,7 @@ static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t
}

onion_c->friends_list[friend_num].is_fake_clientid = 1;
onion_c->friends_list[friend_num].fake_client_id_timestamp = current_time_monotonic();
memcpy(onion_c->friends_list[friend_num].fake_client_id, data + 1 + sizeof(uint64_t), crypto_box_PUBLICKEYBYTES);
}

Expand Down Expand Up @@ -814,22 +815,22 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num)

/* Copy friends DHT public key into dht_key.
*
* return -1 on failure (no key copied).
* return 0 on success (key copied).
* return 0 on failure (no key copied).
* return timestamp on success (key copied).
*/
int onion_getfriend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key)
uint64_t onion_getfriend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key)
{
if ((uint32_t)friend_num >= onion_c->num_friends)
return -1;
return 0;

if (onion_c->friends_list[friend_num].status == 0)
return -1;
return 0;

if (!onion_c->friends_list[friend_num].is_fake_clientid)
return -1;
return 0;

memcpy(dht_key, onion_c->friends_list[friend_num].fake_client_id, crypto_box_PUBLICKEYBYTES);
return 0;
return onion_c->friends_list[friend_num].fake_client_id_timestamp;
}

/* Get the ip of friend friendnum and put it in ip_port
Expand All @@ -843,7 +844,7 @@ int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port)
{
uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES];

if (onion_getfriend_DHT_pubkey(onion_c, friend_num, dht_public_key) != 0)
if (onion_getfriend_DHT_pubkey(onion_c, friend_num, dht_public_key) == 0)
return -1;

return DHT_getfriendip(onion_c->dht, dht_public_key, ip_port);
Expand Down
7 changes: 4 additions & 3 deletions toxcore/onion_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ typedef struct {
uint8_t is_online; /* Set by the onion_set_friend_status function. */

uint8_t is_fake_clientid; /* 0 if we don't know the fake client id of the other 1 if we do. */
uint64_t fake_client_id_timestamp;
uint8_t fake_client_id[crypto_box_PUBLICKEYBYTES];
uint8_t real_client_id[crypto_box_PUBLICKEYBYTES];

Expand Down Expand Up @@ -177,10 +178,10 @@ int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port);

/* Copy friends DHT public key into dht_key.
*
* return -1 on failure (no key copied).
* return 0 on success (key copied).
* return 0 on failure (no key copied).
* return timestamp on success (key copied).
*/
int onion_getfriend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key);
uint64_t onion_getfriend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key);

#define ONION_DATA_IN_RESPONSE_MIN_SIZE (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
#define ONION_CLIENT_MAX_DATA_SIZE (MAX_DATA_REQUEST_SIZE - ONION_DATA_IN_RESPONSE_MIN_SIZE)
Expand Down
2 changes: 1 addition & 1 deletion toxcore/tox.c
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,7 @@ int tox_file_send_data(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8
*/
int tox_file_data_size(Tox *tox, int32_t friendnumber)
{
return MAX_CRYPTO_DATA_SIZE - 3;
return MAX_CRYPTO_DATA_SIZE - 2;
}

/* Give the number of bytes left to be sent/received.
Expand Down

0 comments on commit a5da6df

Please sign in to comment.