summaryrefslogtreecommitdiff
path: root/toxcore/net_crypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/net_crypto.c')
-rw-r--r--toxcore/net_crypto.c375
1 files changed, 372 insertions, 3 deletions
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index 41efc1b1..56ff1bdd 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -210,6 +210,28 @@ static int udp_handle_cookie_request(void *object, IP_Port source, uint8_t *pack
210 return 0; 210 return 0;
211} 211}
212 212
213/* Handle the cookie request packet (for TCP)
214 */
215static int tcp_handle_cookie_request(Net_Crypto *c, TCP_Client_Connection *TCP_con, uint8_t conn_id, uint8_t *packet,
216 uint32_t length)
217{
218 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
219 uint8_t shared_key[crypto_box_BEFORENMBYTES];
220
221 if (handle_cookie_request(c, request_plain, shared_key, packet, length) != 0)
222 return -1;
223
224 uint8_t data[COOKIE_RESPONSE_LENGTH];
225
226 if (create_cookie_response(c, data, request_plain, shared_key) != sizeof(data))
227 return -1;
228
229 if ((uint32_t)send_data(TCP_con, conn_id, data, sizeof(data)) != 1)
230 return -1;
231
232 return 0;
233}
234
213/* Handle a cookie response packet of length encrypted with shared_key. 235/* Handle a cookie response packet of length encrypted with shared_key.
214 * put the cookie in the response in cookie 236 * put the cookie in the response in cookie
215 * 237 *
@@ -352,10 +374,23 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, uint8_t *data,
352 if (conn == 0) 374 if (conn == 0)
353 return -1; 375 return -1;
354 376
355 if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) != length) 377 //TODO: on bad networks, direct connections might not last indefinitely.
356 return -1; 378 if (conn->ip_port.ip.family != 0) {
379 if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length)
380 return 0;
381 }
357 382
358 return 0; 383 //TODO: spread packets over many relays, detect and kill bad relays.
384 uint32_t i;
385
386 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
387 if (conn->status_tcp[i] == 2) {/* friend is connected to this relay. */
388 if (send_data(c->tcp_connections[i], conn->con_number_tcp[i], data, length) == 1)
389 return 0;
390 }
391 }
392
393 return -1;
359} 394}
360 395
361/** START: Array Related functions **/ 396/** START: Array Related functions **/
@@ -1187,6 +1222,24 @@ static int getcryptconnection_id(Net_Crypto *c, uint8_t *public_key)
1187 return -1; 1222 return -1;
1188} 1223}
1189 1224
1225/* Get crypto connection id from public key of peer.
1226 *
1227 * return -1 if there are no connections like we are looking for.
1228 * return id if it found it.
1229 */
1230static int getcryptconnection_id_dht_pubkey(Net_Crypto *c, uint8_t *dht_public_key)
1231{
1232 uint32_t i;
1233
1234 for (i = 0; i < c->crypto_connections_length; ++i) {
1235 if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION && c->crypto_connections[i].dht_public_key_set)
1236 if (memcmp(dht_public_key, c->crypto_connections[i].dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
1237 return i;
1238 }
1239
1240 return -1;
1241}
1242
1190/* Add a source to the crypto connection. 1243/* Add a source to the crypto connection.
1191 * This is to be used only when we have recieved a packet from that source. 1244 * This is to be used only when we have recieved a packet from that source.
1192 * 1245 *
@@ -1346,6 +1399,56 @@ int new_crypto_connection(Net_Crypto *c, uint8_t *real_public_key)
1346 return crypt_connection_id; 1399 return crypt_connection_id;
1347} 1400}
1348 1401
1402/* Disconnect peer from all associated TCP connections.
1403 *
1404 * return -1 on failure.
1405 * return 0 on success.
1406 */
1407static int disconnect_peer_tcp(Net_Crypto *c, int crypt_connection_id)
1408{
1409 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1410
1411 if (conn == 0)
1412 return -1;
1413
1414 uint32_t i;
1415
1416 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1417 if (conn->status_tcp[i]) {
1418 send_disconnect_request(c->tcp_connections[i], conn->con_number_tcp[i]);
1419 conn->status_tcp[i] = 0;
1420 conn->con_number_tcp[i] = 0;
1421 }
1422 }
1423
1424 return 0;
1425}
1426
1427/* Connect peer to all associated TCP connections.
1428 *
1429 * return -1 on failure.
1430 * return 0 on success.
1431 */
1432static int connect_peer_tcp(Net_Crypto *c, int crypt_connection_id)
1433{
1434 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1435
1436 if (conn == 0)
1437 return -1;
1438
1439 uint32_t i;
1440
1441 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1442 if (c->tcp_connections[i] == NULL)
1443 continue;
1444
1445 //TODO check function return?
1446 send_routing_request(c->tcp_connections[i], conn->dht_public_key);
1447 }
1448
1449 return 0;
1450}
1451
1349/* Set the DHT public key of the crypto connection. 1452/* Set the DHT public key of the crypto connection.
1350 * 1453 *
1351 * return -1 on failure. 1454 * return -1 on failure.
@@ -1361,6 +1464,10 @@ int set_conection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t
1361 if (conn->dht_public_key_set == 1 && memcmp(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0) 1464 if (conn->dht_public_key_set == 1 && memcmp(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
1362 return -1; 1465 return -1;
1363 1466
1467 if (conn->dht_public_key_set == 1) {
1468 disconnect_peer_tcp(c, crypt_connection_id);
1469 }
1470
1364 memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES); 1471 memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES);
1365 conn->dht_public_key_set = 1; 1472 conn->dht_public_key_set = 1;
1366 1473
@@ -1376,6 +1483,7 @@ int set_conection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t
1376 return -1; 1483 return -1;
1377 }//TODO 1484 }//TODO
1378 1485
1486 connect_peer_tcp(c, crypt_connection_id);
1379 return 0; 1487 return 0;
1380} 1488}
1381 1489
@@ -1399,6 +1507,264 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port)
1399 return 0; 1507 return 0;
1400} 1508}
1401 1509
1510static int tcp_response_callback(void *object, uint8_t connection_id, uint8_t *public_key)
1511{
1512 TCP_Client_Connection *TCP_con = object;
1513 Net_Crypto *c = TCP_con->net_crypto_pointer;
1514
1515 int crypt_connection_id = getcryptconnection_id_dht_pubkey(c, public_key);
1516
1517 if (crypt_connection_id == -1)
1518 return -1;
1519
1520 set_tcp_connection_number(TCP_con, connection_id, crypt_connection_id);
1521
1522 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1523
1524 if (conn == 0)
1525 return -1;
1526
1527 uint32_t location = TCP_con->net_crypto_location;
1528
1529 if (location >= MAX_TCP_CONNECTIONS)
1530 return -1;
1531
1532 if (c->tcp_connections[location] != TCP_con)
1533 return -1;
1534
1535 conn->status_tcp[location] = 1;
1536 conn->con_number_tcp[location] = connection_id;
1537 return 0;
1538}
1539
1540static int tcp_status_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t status)
1541{
1542 TCP_Client_Connection *TCP_con = object;
1543 Net_Crypto *c = TCP_con->net_crypto_pointer;
1544
1545 Crypto_Connection *conn = get_crypto_connection(c, number);
1546
1547 if (conn == 0)
1548 return -1;
1549
1550 uint32_t location = TCP_con->net_crypto_location;
1551
1552 if (location >= MAX_TCP_CONNECTIONS)
1553 return -1;
1554
1555 if (c->tcp_connections[location] != TCP_con)
1556 return -1;
1557
1558 conn->status_tcp[location] = status;
1559 conn->con_number_tcp[location] = connection_id;
1560 return 0;
1561}
1562
1563static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t *data, uint16_t length)
1564{
1565 if (length == 0)
1566 return -1;
1567
1568 TCP_Client_Connection *TCP_con = object;
1569 Net_Crypto *c = TCP_con->net_crypto_pointer;
1570
1571 if (data[0] == NET_PACKET_COOKIE_REQUEST) {
1572 return tcp_handle_cookie_request(c, TCP_con, connection_id, data, length);
1573 }
1574
1575 Crypto_Connection *conn = get_crypto_connection(c, number);
1576
1577 if (conn == 0)
1578 return -1;
1579
1580 if (handle_packet_connection(c, number, data, length) != 0)
1581 return -1;
1582
1583 //TODO detect and kill bad TCP connections.
1584 return 0;
1585}
1586
1587/* Check if tcp connection to public key can be created.
1588 *
1589 * return -1 if it can't.
1590 * return 0 if it can.
1591 */
1592static int tcp_connection_check(Net_Crypto *c, uint8_t *public_key)
1593{
1594 uint32_t i;
1595
1596 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1597 if (c->tcp_connections_new[i] == NULL)
1598 continue;
1599
1600 if (memcmp(c->tcp_connections_new[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0)
1601 return -1;
1602 }
1603
1604 uint32_t num = 0;
1605
1606 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1607 if (c->tcp_connections[i] == NULL)
1608 continue;
1609
1610 if (memcmp(c->tcp_connections[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0)
1611 return -1;
1612
1613 ++num;
1614 }
1615
1616 if (num == MAX_TCP_CONNECTIONS)
1617 return -1;
1618
1619 return 0;
1620}
1621
1622/* Add a tcp relay to the array.
1623 *
1624 * return 0 if it was added.
1625 * return -1 if it wasn't.
1626 */
1627int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key)
1628{
1629 if (tcp_connection_check(c, public_key) != 0)
1630 return -1;
1631
1632 uint32_t i;
1633
1634 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1635 if (c->tcp_connections_new[i] == NULL) {
1636 c->tcp_connections_new[i] = new_TCP_connection(ip_port, public_key, c->dht->self_public_key, c->dht->self_secret_key);
1637 return 0;
1638 }
1639 }
1640
1641 return -1;
1642}
1643
1644/* Add a connected tcp connection to the tcp_connections array.
1645 *
1646 * return 0 if it was added.
1647 * return -1 if it wasn't.
1648 */
1649static int add_tcp_connected(Net_Crypto *c, TCP_Client_Connection *tcp_con)
1650{
1651 uint32_t i;
1652
1653 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1654 if (c->tcp_connections[i] == NULL)
1655 break;
1656 }
1657
1658 if (i == MAX_TCP_CONNECTIONS)
1659 return -1;
1660
1661 uint32_t tcp_num = i;
1662
1663 for (i = 0; i < c->crypto_connections_length; ++i) {
1664 Crypto_Connection *conn = get_crypto_connection(c, i);
1665
1666 if (conn == 0)
1667 return -1;
1668
1669 if (conn->status == CRYPTO_CONN_NO_CONNECTION)
1670 continue;
1671
1672 if (conn->status == CRYPTO_CONN_TIMED_OUT)
1673 continue;
1674
1675 if (conn->dht_public_key_set)
1676 if (send_routing_request(tcp_con, conn->dht_public_key) != 1)
1677 return -1;
1678
1679 }
1680
1681 tcp_con->net_crypto_pointer = c;
1682 tcp_con->net_crypto_location = tcp_num;
1683 routing_response_handler(tcp_con, tcp_response_callback, tcp_con);
1684 routing_status_handler(tcp_con, tcp_status_callback, tcp_con);
1685 routing_data_handler(tcp_con, tcp_data_callback, tcp_con);
1686 c->tcp_connections[tcp_num] = tcp_con;
1687 return 0;
1688}
1689
1690static void do_tcp(Net_Crypto *c)
1691{
1692 uint32_t i;
1693
1694 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1695 if (c->tcp_connections_new[i] == NULL)
1696 continue;
1697
1698 do_TCP_connection(c->tcp_connections_new[i]);
1699
1700 if (c->tcp_connections_new[i]->status == TCP_CLIENT_CONFIRMED) {
1701 if (add_tcp_connected(c, c->tcp_connections_new[i]) == 0) {
1702 c->tcp_connections_new[i] = NULL;
1703 } else {
1704 kill_TCP_connection(c->tcp_connections_new[i]);
1705 c->tcp_connections_new[i] = NULL;
1706 }
1707 }
1708 }
1709
1710 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1711 if (c->tcp_connections[i] == NULL)
1712 continue;
1713
1714 do_TCP_connection(c->tcp_connections[i]);
1715 }
1716}
1717
1718static void clear_disconnected_tcp_peer(Crypto_Connection *conn, uint32_t number)
1719{
1720 if (conn->status == CRYPTO_CONN_NO_CONNECTION)
1721 return;
1722
1723 if (number >= MAX_TCP_CONNECTIONS)
1724 return;
1725
1726 conn->status_tcp[number] = 0;
1727 conn->con_number_tcp[number] = 0;
1728}
1729
1730static void clear_disconnected_tcp(Net_Crypto *c)
1731{
1732 uint32_t i, j;
1733
1734 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1735 if (c->tcp_connections_new[i] == NULL)
1736 continue;
1737
1738 if (c->tcp_connections_new[i]->status != TCP_CLIENT_DISCONNECTED)
1739 continue;
1740
1741 kill_TCP_connection(c->tcp_connections_new[i]);
1742 c->tcp_connections_new[i] = NULL;
1743 }
1744
1745 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1746 if (c->tcp_connections[i] == NULL)
1747 continue;
1748
1749 TCP_Client_Connection *tcp_con = c->tcp_connections[i];
1750
1751 if (tcp_con->status != TCP_CLIENT_DISCONNECTED)
1752 continue;
1753
1754 c->tcp_connections[i] = NULL;
1755 kill_TCP_connection(tcp_con);
1756
1757 for (j = 0; j < c->crypto_connections_length; ++j) {
1758 Crypto_Connection *conn = get_crypto_connection(c, j);
1759
1760 if (conn == 0)
1761 return;
1762
1763 clear_disconnected_tcp_peer(conn, i);
1764 }
1765 }
1766}
1767
1402/* Set function to be called when connection with crypt_connection_id goes connects/disconnects. 1768/* Set function to be called when connection with crypt_connection_id goes connects/disconnects.
1403 * 1769 *
1404 * The set function should return -1 on failure and 0 on success. 1770 * The set function should return -1 on failure and 0 on success.
@@ -1647,6 +2013,7 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id)
1647{ 2013{
1648 //TODO 2014 //TODO
1649 send_kill_packet(c, crypt_connection_id); 2015 send_kill_packet(c, crypt_connection_id);
2016 disconnect_peer_tcp(c, crypt_connection_id);
1650 return wipe_crypto_connection(c, crypt_connection_id); 2017 return wipe_crypto_connection(c, crypt_connection_id);
1651} 2018}
1652 2019
@@ -1764,6 +2131,8 @@ void do_net_crypto(Net_Crypto *c)
1764{ 2131{
1765 unix_time_update(); 2132 unix_time_update();
1766 kill_timedout(c); 2133 kill_timedout(c);
2134 do_tcp(c);
2135 clear_disconnected_tcp(c);
1767 send_crypto_packets(c); 2136 send_crypto_packets(c);
1768} 2137}
1769 2138