diff options
author | irungentoo <irungentoo@gmail.com> | 2014-05-17 12:33:22 -0400 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2014-05-17 12:33:22 -0400 |
commit | a5da6df1442f0615e727292ab58f90f169e090cf (patch) | |
tree | 17a53efdd3dc5675dcf11499c0aa59c0179ceaa8 | |
parent | 454cadb91c57eb689eddbf41d61d66af54aa1e0f (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.c | 5 | ||||
-rw-r--r-- | toxcore/net_crypto.c | 80 | ||||
-rw-r--r-- | toxcore/net_crypto.h | 5 | ||||
-rw-r--r-- | toxcore/network.h | 1 | ||||
-rw-r--r-- | toxcore/onion_client.c | 17 | ||||
-rw-r--r-- | toxcore/onion_client.h | 7 | ||||
-rw-r--r-- | toxcore/tox.c | 2 |
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 | */ | ||
244 | static 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 | */ |
1470 | int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key) | 1498 | int 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 | ||
1632 | static 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); | |||
186 | int new_crypto_connection(Net_Crypto *c, uint8_t *real_public_key); | 187 | int 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 | */ |
193 | int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key); | 196 | int 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 | ||
158 | typedef union __attribute__ ((__packed__)) | 159 | typedef 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 | */ |
820 | int onion_getfriend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key) | 821 | uint64_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 | */ |
183 | int onion_getfriend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key); | 184 | uint64_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 | */ |
722 | int tox_file_data_size(Tox *tox, int32_t friendnumber) | 722 | int 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. |