summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-05-17 12:33:22 -0400
committerirungentoo <irungentoo@gmail.com>2014-05-17 12:33:22 -0400
commita5da6df1442f0615e727292ab58f90f169e090cf (patch)
tree17a53efdd3dc5675dcf11499c0aa59c0179ceaa8
parent454cadb91c57eb689eddbf41d61d66af54aa1e0f (diff)
Net_crypto can now handle packets sent as TCP OOB packets.
Added timestamp to know which DHT public key is good in case onion_client and net_crypto report different ones.
-rw-r--r--toxcore/Messenger.c5
-rw-r--r--toxcore/net_crypto.c80
-rw-r--r--toxcore/net_crypto.h5
-rw-r--r--toxcore/network.h1
-rw-r--r--toxcore/onion_client.c17
-rw-r--r--toxcore/onion_client.h7
-rw-r--r--toxcore/tox.c2
7 files changed, 97 insertions, 20 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index b5ce2e7e..2c7dcdee 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -2202,8 +2202,9 @@ void do_friends(Messenger *m)
2202 friend_new_connection(m, i, m->friendlist[i].client_id); 2202 friend_new_connection(m, i, m->friendlist[i].client_id);
2203 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; 2203 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES];
2204 2204
2205 if (onion_getfriend_DHT_pubkey(m->onion_c, m->friendlist[i].onion_friendnum, dht_public_key) == 0) { 2205 uint64_t timestamp = onion_getfriend_DHT_pubkey(m->onion_c, m->friendlist[i].onion_friendnum, dht_public_key);
2206 set_connection_dht_public_key(m->net_crypto, m->friendlist[i].crypt_connection_id, dht_public_key); 2206 if (timestamp != 0) {
2207 set_connection_dht_public_key(m->net_crypto, m->friendlist[i].crypt_connection_id, dht_public_key, timestamp);
2207 } 2208 }
2208 2209
2209 uint8_t direct_connected; 2210 uint8_t direct_connected;
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index 35cf21cd..2f01bc83 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -233,7 +233,33 @@ static int tcp_handle_cookie_request(Net_Crypto *c, TCP_Client_Connection *TCP_c
233 if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) 233 if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data))
234 return -1; 234 return -1;
235 235
236 if ((uint32_t)send_data(TCP_con, conn_id, data, sizeof(data)) != 1) 236 if (send_data(TCP_con, conn_id, data, sizeof(data)) != 1)
237 return -1;
238
239 return 0;
240}
241
242/* Handle the cookie request packet (for TCP oob packets)
243 */
244static int tcp_oob_handle_cookie_request(Net_Crypto *c, TCP_Client_Connection *TCP_con, uint8_t *dht_public_key,
245 uint8_t *packet, uint32_t length)
246{
247 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
248 uint8_t shared_key[crypto_box_BEFORENMBYTES];
249 uint8_t dht_public_key_temp[crypto_box_PUBLICKEYBYTES];
250
251 if (handle_cookie_request(c, request_plain, shared_key, dht_public_key_temp, packet, length) != 0)
252 return -1;
253
254 if (memcmp(dht_public_key, dht_public_key_temp, crypto_box_PUBLICKEYBYTES) != 0)
255 return -1;
256
257 uint8_t data[COOKIE_RESPONSE_LENGTH];
258
259 if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data))
260 return -1;
261
262 if (send_oob_packet(TCP_con, dht_public_key, data, sizeof(data)) != 1)
237 return -1; 263 return -1;
238 264
239 return 0; 265 return 0;
@@ -1115,7 +1141,7 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, uint
1115 1141
1116 conn->status = CRYPTO_CONN_NOT_CONFIRMED; 1142 conn->status = CRYPTO_CONN_NOT_CONFIRMED;
1117 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */ 1143 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */
1118 set_connection_dht_public_key(c, crypt_connection_id, dht_public_key); 1144 set_connection_dht_public_key(c, crypt_connection_id, dht_public_key, current_time_monotonic());
1119 } else { 1145 } else {
1120 return -1; 1146 return -1;
1121 } 1147 }
@@ -1326,7 +1352,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, IP_Port source, uint8_
1326 if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) == 0) { 1352 if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) == 0) {
1327 conn->status = CRYPTO_CONN_NOT_CONFIRMED; 1353 conn->status = CRYPTO_CONN_NOT_CONFIRMED;
1328 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */ 1354 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */
1329 set_connection_dht_public_key(c, crypt_connection_id, n_c.dht_public_key); 1355 set_connection_dht_public_key(c, crypt_connection_id, n_c.dht_public_key, current_time_monotonic());
1330 ret = 0; 1356 ret = 0;
1331 } 1357 }
1332 } 1358 }
@@ -1375,7 +1401,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
1375 1401
1376 conn->status = CRYPTO_CONN_NOT_CONFIRMED; 1402 conn->status = CRYPTO_CONN_NOT_CONFIRMED;
1377 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */ 1403 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */
1378 set_connection_dht_public_key(c, crypt_connection_id, n_c->dht_public_key); 1404 set_connection_dht_public_key(c, crypt_connection_id, n_c->dht_public_key, current_time_monotonic());
1379 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; 1405 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
1380 crypto_connection_add_source(c, crypt_connection_id, n_c->source); 1406 crypto_connection_add_source(c, crypt_connection_id, n_c->source);
1381 return crypt_connection_id; 1407 return crypt_connection_id;
@@ -1463,17 +1489,22 @@ static int connect_peer_tcp(Net_Crypto *c, int crypt_connection_id)
1463} 1489}
1464 1490
1465/* Set the DHT public key of the crypto connection. 1491/* Set the DHT public key of the crypto connection.
1492 * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to
1493 * the other peer.
1466 * 1494 *
1467 * return -1 on failure. 1495 * return -1 on failure.
1468 * return 0 on success. 1496 * return 0 on success.
1469 */ 1497 */
1470int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key) 1498int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key, uint64_t timestamp)
1471{ 1499{
1472 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1500 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1473 1501
1474 if (conn == 0) 1502 if (conn == 0)
1475 return -1; 1503 return -1;
1476 1504
1505 if (timestamp <= conn->dht_public_key_timestamp)
1506 return -1;
1507
1477 if (conn->dht_public_key_set == 1 && memcmp(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0) 1508 if (conn->dht_public_key_set == 1 && memcmp(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
1478 return -1; 1509 return -1;
1479 1510
@@ -1483,6 +1514,7 @@ int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_
1483 1514
1484 memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES); 1515 memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES);
1485 conn->dht_public_key_set = 1; 1516 conn->dht_public_key_set = 1;
1517 conn->dht_public_key_timestamp = timestamp;
1486 1518
1487 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { 1519 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) {
1488 conn->cookie_request_number = random_64b(); 1520 conn->cookie_request_number = random_64b();
@@ -1597,6 +1629,43 @@ static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_i
1597 return 0; 1629 return 0;
1598} 1630}
1599 1631
1632static int tcp_oob_callback(void *object, uint8_t *public_key, uint8_t *data, uint16_t length)
1633{
1634 if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE)
1635 return -1;
1636
1637 TCP_Client_Connection *TCP_con = object;
1638 Net_Crypto *c = TCP_con->net_crypto_pointer;
1639 uint32_t location = TCP_con->net_crypto_location;
1640
1641 if (data[0] == NET_PACKET_COOKIE_REQUEST) {
1642 return tcp_oob_handle_cookie_request(c, TCP_con, public_key, data, length);
1643 }
1644
1645 int crypt_connection_id = getcryptconnection_id_dht_pubkey(c, public_key);
1646
1647 if (crypt_connection_id == -1) {
1648 IP_Port source;
1649 source.ip.family = TCP_FAMILY;
1650 source.ip.ip6.uint32[0] = location;
1651
1652 if (data[0] != NET_PACKET_CRYPTO_HS) {
1653 fprintf(stderr, "tcp snhappen %u\n", data[0]);
1654 return -1;
1655 }
1656
1657 if (handle_new_connection_handshake(c, source, data, length) != 0)
1658 return -1;
1659
1660 return 0;
1661 }
1662
1663 if (handle_packet_connection(c, crypt_connection_id, data, length) != 0)
1664 return -1;
1665
1666 return 0;
1667}
1668
1600/* Check if tcp connection to public key can be created. 1669/* Check if tcp connection to public key can be created.
1601 * 1670 *
1602 * return -1 if it can't. 1671 * return -1 if it can't.
@@ -1696,6 +1765,7 @@ static int add_tcp_connected(Net_Crypto *c, TCP_Client_Connection *tcp_con)
1696 routing_response_handler(tcp_con, tcp_response_callback, tcp_con); 1765 routing_response_handler(tcp_con, tcp_response_callback, tcp_con);
1697 routing_status_handler(tcp_con, tcp_status_callback, tcp_con); 1766 routing_status_handler(tcp_con, tcp_status_callback, tcp_con);
1698 routing_data_handler(tcp_con, tcp_data_callback, tcp_con); 1767 routing_data_handler(tcp_con, tcp_data_callback, tcp_con);
1768 oob_data_handler(tcp_con, tcp_oob_callback, tcp_con);
1699 c->tcp_connections[tcp_num] = tcp_con; 1769 c->tcp_connections[tcp_num] = tcp_con;
1700 return 0; 1770 return 0;
1701} 1771}
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h
index e2e0fffb..dbbb295c 100644
--- a/toxcore/net_crypto.h
+++ b/toxcore/net_crypto.h
@@ -92,6 +92,7 @@ typedef struct {
92 uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ 92 uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */
93 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; /* The dht public key of the peer */ 93 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; /* The dht public key of the peer */
94 uint8_t dht_public_key_set; /* True if the dht public key is set, false if it isn't. */ 94 uint8_t dht_public_key_set; /* True if the dht public key is set, false if it isn't. */
95 uint64_t dht_public_key_timestamp; /* Timestamp of the last time we confirmed the key was correct. */
95 96
96 uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */ 97 uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */
97 uint16_t temp_packet_length; 98 uint16_t temp_packet_length;
@@ -186,11 +187,13 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c);
186int new_crypto_connection(Net_Crypto *c, uint8_t *real_public_key); 187int new_crypto_connection(Net_Crypto *c, uint8_t *real_public_key);
187 188
188/* Set the DHT public key of the crypto connection. 189/* Set the DHT public key of the crypto connection.
190 * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to
191 * the other peer.
189 * 192 *
190 * return -1 on failure. 193 * return -1 on failure.
191 * return 0 on success. 194 * return 0 on success.
192 */ 195 */
193int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key); 196int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key, uint64_t timestamp);
194 197
195/* Set the direct ip of the crypto connection. 198/* Set the direct ip of the crypto connection.
196 * 199 *
diff --git a/toxcore/network.h b/toxcore/network.h
index e268df74..f907b9b5 100644
--- a/toxcore/network.h
+++ b/toxcore/network.h
@@ -154,6 +154,7 @@ typedef int sock_t;
154#define TCP_ONION_FAMILY (AF_INET6 + 1) 154#define TCP_ONION_FAMILY (AF_INET6 + 1)
155#define TCP_INET (AF_INET6 + 2) 155#define TCP_INET (AF_INET6 + 2)
156#define TCP_INET6 (AF_INET6 + 3) 156#define TCP_INET6 (AF_INET6 + 3)
157#define TCP_FAMILY (AF_INET6 + 4)
157 158
158typedef union __attribute__ ((__packed__)) 159typedef union __attribute__ ((__packed__))
159{ 160{
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c
index 73cb1f75..16333e0c 100644
--- a/toxcore/onion_client.c
+++ b/toxcore/onion_client.c
@@ -509,6 +509,7 @@ static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t
509 } 509 }
510 510
511 onion_c->friends_list[friend_num].is_fake_clientid = 1; 511 onion_c->friends_list[friend_num].is_fake_clientid = 1;
512 onion_c->friends_list[friend_num].fake_client_id_timestamp = current_time_monotonic();
512 memcpy(onion_c->friends_list[friend_num].fake_client_id, data + 1 + sizeof(uint64_t), crypto_box_PUBLICKEYBYTES); 513 memcpy(onion_c->friends_list[friend_num].fake_client_id, data + 1 + sizeof(uint64_t), crypto_box_PUBLICKEYBYTES);
513 } 514 }
514 515
@@ -814,22 +815,22 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num)
814 815
815/* Copy friends DHT public key into dht_key. 816/* Copy friends DHT public key into dht_key.
816 * 817 *
817 * return -1 on failure (no key copied). 818 * return 0 on failure (no key copied).
818 * return 0 on success (key copied). 819 * return timestamp on success (key copied).
819 */ 820 */
820int onion_getfriend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key) 821uint64_t onion_getfriend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key)
821{ 822{
822 if ((uint32_t)friend_num >= onion_c->num_friends) 823 if ((uint32_t)friend_num >= onion_c->num_friends)
823 return -1; 824 return 0;
824 825
825 if (onion_c->friends_list[friend_num].status == 0) 826 if (onion_c->friends_list[friend_num].status == 0)
826 return -1; 827 return 0;
827 828
828 if (!onion_c->friends_list[friend_num].is_fake_clientid) 829 if (!onion_c->friends_list[friend_num].is_fake_clientid)
829 return -1; 830 return 0;
830 831
831 memcpy(dht_key, onion_c->friends_list[friend_num].fake_client_id, crypto_box_PUBLICKEYBYTES); 832 memcpy(dht_key, onion_c->friends_list[friend_num].fake_client_id, crypto_box_PUBLICKEYBYTES);
832 return 0; 833 return onion_c->friends_list[friend_num].fake_client_id_timestamp;
833} 834}
834 835
835/* Get the ip of friend friendnum and put it in ip_port 836/* Get the ip of friend friendnum and put it in ip_port
@@ -843,7 +844,7 @@ int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port)
843{ 844{
844 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; 845 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES];
845 846
846 if (onion_getfriend_DHT_pubkey(onion_c, friend_num, dht_public_key) != 0) 847 if (onion_getfriend_DHT_pubkey(onion_c, friend_num, dht_public_key) == 0)
847 return -1; 848 return -1;
848 849
849 return DHT_getfriendip(onion_c->dht, dht_public_key, ip_port); 850 return DHT_getfriendip(onion_c->dht, dht_public_key, ip_port);
diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h
index 06909380..1d56333a 100644
--- a/toxcore/onion_client.h
+++ b/toxcore/onion_client.h
@@ -82,6 +82,7 @@ typedef struct {
82 uint8_t is_online; /* Set by the onion_set_friend_status function. */ 82 uint8_t is_online; /* Set by the onion_set_friend_status function. */
83 83
84 uint8_t is_fake_clientid; /* 0 if we don't know the fake client id of the other 1 if we do. */ 84 uint8_t is_fake_clientid; /* 0 if we don't know the fake client id of the other 1 if we do. */
85 uint64_t fake_client_id_timestamp;
85 uint8_t fake_client_id[crypto_box_PUBLICKEYBYTES]; 86 uint8_t fake_client_id[crypto_box_PUBLICKEYBYTES];
86 uint8_t real_client_id[crypto_box_PUBLICKEYBYTES]; 87 uint8_t real_client_id[crypto_box_PUBLICKEYBYTES];
87 88
@@ -177,10 +178,10 @@ int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port);
177 178
178/* Copy friends DHT public key into dht_key. 179/* Copy friends DHT public key into dht_key.
179 * 180 *
180 * return -1 on failure (no key copied). 181 * return 0 on failure (no key copied).
181 * return 0 on success (key copied). 182 * return timestamp on success (key copied).
182 */ 183 */
183int onion_getfriend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key); 184uint64_t onion_getfriend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key);
184 185
185#define ONION_DATA_IN_RESPONSE_MIN_SIZE (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) 186#define ONION_DATA_IN_RESPONSE_MIN_SIZE (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
186#define ONION_CLIENT_MAX_DATA_SIZE (MAX_DATA_REQUEST_SIZE - ONION_DATA_IN_RESPONSE_MIN_SIZE) 187#define ONION_CLIENT_MAX_DATA_SIZE (MAX_DATA_REQUEST_SIZE - ONION_DATA_IN_RESPONSE_MIN_SIZE)
diff --git a/toxcore/tox.c b/toxcore/tox.c
index d49e2241..d86f1a17 100644
--- a/toxcore/tox.c
+++ b/toxcore/tox.c
@@ -721,7 +721,7 @@ int tox_file_send_data(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8
721 */ 721 */
722int tox_file_data_size(Tox *tox, int32_t friendnumber) 722int tox_file_data_size(Tox *tox, int32_t friendnumber)
723{ 723{
724 return MAX_CRYPTO_DATA_SIZE - 3; 724 return MAX_CRYPTO_DATA_SIZE - 2;
725} 725}
726 726
727/* Give the number of bytes left to be sent/received. 727/* Give the number of bytes left to be sent/received.