summaryrefslogtreecommitdiff
path: root/toxcore/DHT.c
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2013-09-16 08:11:56 -0700
committerirungentoo <irungentoo@gmail.com>2013-09-16 08:11:56 -0700
commit98fb06c1b75a3bd5ad674daf5c0496a712bc0551 (patch)
treee36833b55b522251b3cc5d0734d62196eb6ac0b0 /toxcore/DHT.c
parentd17249a65d64c90c79ba6e2a7bcf914d1441cb4e (diff)
parenta069f67ab30c24d9ab0df61814941a12e5e0da34 (diff)
Merge pull request #576 from FullName/MessengerLoadSave
State loading/saving: Instead of a blob, segment into sections marked with tags.
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r--toxcore/DHT.c129
1 files changed, 126 insertions, 3 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index db9bfe3c..bb746fb0 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -1457,13 +1457,13 @@ void kill_DHT(DHT *dht)
1457} 1457}
1458 1458
1459/* Get the size of the DHT (for saving). */ 1459/* Get the size of the DHT (for saving). */
1460uint32_t DHT_size(DHT *dht) 1460uint32_t DHT_size_old(DHT *dht)
1461{ 1461{
1462 return sizeof(dht->close_clientlist) + sizeof(DHT_Friend) * dht->num_friends; 1462 return sizeof(dht->close_clientlist) + sizeof(DHT_Friend) * dht->num_friends;
1463} 1463}
1464 1464
1465/* Save the DHT in data where data is an array of size DHT_size(). */ 1465/* Save the DHT in data where data is an array of size DHT_size(). */
1466void DHT_save(DHT *dht, uint8_t *data) 1466void DHT_save_old(DHT *dht, uint8_t *data)
1467{ 1467{
1468 memcpy(data, dht->close_clientlist, sizeof(dht->close_clientlist)); 1468 memcpy(data, dht->close_clientlist, sizeof(dht->close_clientlist));
1469 memcpy(data + sizeof(dht->close_clientlist), dht->friends_list, sizeof(DHT_Friend) * dht->num_friends); 1469 memcpy(data + sizeof(dht->close_clientlist), dht->friends_list, sizeof(DHT_Friend) * dht->num_friends);
@@ -1474,7 +1474,7 @@ void DHT_save(DHT *dht, uint8_t *data)
1474 * return -1 if failure. 1474 * return -1 if failure.
1475 * return 0 if success. 1475 * return 0 if success.
1476 */ 1476 */
1477int DHT_load(DHT *dht, uint8_t *data, uint32_t size) 1477int DHT_load_old(DHT *dht, uint8_t *data, uint32_t size)
1478{ 1478{
1479 if (size < sizeof(dht->close_clientlist)) { 1479 if (size < sizeof(dht->close_clientlist)) {
1480 fprintf(stderr, "DHT_load: Expected at least %u bytes, got %u.\n", sizeof(dht->close_clientlist), size); 1480 fprintf(stderr, "DHT_load: Expected at least %u bytes, got %u.\n", sizeof(dht->close_clientlist), size);
@@ -1518,6 +1518,129 @@ int DHT_load(DHT *dht, uint8_t *data, uint32_t size)
1518 return 0; 1518 return 0;
1519} 1519}
1520 1520
1521
1522/* new DHT format for load/save, more robust and forward compatible */
1523
1524#define DHT_STATE_COOKIE_GLOBAL 0x159000d
1525
1526#define DHT_STATE_COOKIE_TYPE 0x11ce
1527#define DHT_STATE_TYPE_FRIENDS 1
1528#define DHT_STATE_TYPE_CLIENTS 2
1529
1530/* Get the size of the DHT (for saving). */
1531uint32_t DHT_size(DHT *dht)
1532{
1533 uint32_t num = 0, i;
1534 for (i = 0; i < LCLIENT_LIST; ++i)
1535 if (dht->close_clientlist[i].timestamp != 0)
1536 num++;
1537
1538 uint32_t size32 = sizeof(uint32_t), sizesubhead = size32 * 2;
1539 return size32
1540 + sizesubhead + sizeof(DHT_Friend) * dht->num_friends
1541 + sizesubhead + sizeof(Client_data) * num;
1542}
1543
1544static uint8_t *z_state_save_subheader(uint8_t *data, uint32_t len, uint16_t type)
1545{
1546 uint32_t *data32 = (uint32_t *)data;
1547 data32[0] = len;
1548 data32[1] = (DHT_STATE_COOKIE_TYPE << 16) | type;
1549 data += sizeof(uint32_t) * 2;
1550 return data;
1551}
1552
1553/* Save the DHT in data where data is an array of size DHT_size(). */
1554void DHT_save(DHT *dht, uint8_t *data)
1555{
1556 uint32_t len;
1557 uint16_t type;
1558 *(uint32_t *)data = DHT_STATE_COOKIE_GLOBAL;
1559 data += sizeof(uint32_t);
1560
1561 len = sizeof(DHT_Friend) * dht->num_friends;
1562 type = DHT_STATE_TYPE_FRIENDS;
1563 data = z_state_save_subheader(data, len, type);
1564 memcpy(data, dht->friends_list, len);
1565 data += len;
1566
1567 uint32_t num = 0, i;
1568 for (i = 0; i < LCLIENT_LIST; ++i)
1569 if (dht->close_clientlist[i].timestamp != 0)
1570 num++;
1571
1572 if (!num)
1573 return;
1574
1575 len = num * sizeof(Client_data);
1576 type = DHT_STATE_TYPE_CLIENTS;
1577 data = z_state_save_subheader(data, len, type);
1578 Client_data *clients = (Client_data *)data;
1579 for (num = 0, i = 0; i < LCLIENT_LIST; ++i)
1580 if (dht->close_clientlist[i].timestamp != 0)
1581 memcpy(&clients[num++], &dht->close_clientlist[i], sizeof(Client_data));
1582 data += len;
1583}
1584
1585static int dht_load_state_callback(void *outer, uint8_t *data, uint32_t length, uint16_t type)
1586{
1587 DHT *dht = outer;
1588 uint32_t num, i, j;
1589 switch(type) {
1590 case DHT_STATE_TYPE_FRIENDS:
1591 if (length % sizeof(DHT_Friend) != 0)
1592 break;
1593
1594 DHT_Friend *friend_list = (DHT_Friend *)data;
1595 num = length / sizeof(DHT_Friend);
1596 for (i = 0; i < num; ++i) {
1597 DHT_addfriend(dht, friend_list[i].client_id);
1598 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1599 Client_data *client = &friend_list[i].client_list[j];
1600 if (client->timestamp != 0)
1601 getnodes(dht, client->ip_port, client->client_id, friend_list[i].client_id);
1602 }
1603 }
1604
1605 break;
1606
1607 case DHT_STATE_TYPE_CLIENTS:
1608 if ((length % sizeof(Client_data)) != 0)
1609 break;
1610
1611 num = length / sizeof(Client_data);
1612 Client_data *client_list = (Client_data *)data;
1613 for (i = 0; i < num; ++i)
1614 if (client_list[i].timestamp != 0)
1615 DHT_bootstrap(dht, client_list[i].ip_port, client_list[i].client_id);
1616
1617 break;
1618
1619 default:
1620 fprintf(stderr, "Load state (DHT): contains unrecognized part (len %u, type %u)\n",
1621 length, type);
1622 }
1623
1624 return 0;
1625}
1626
1627/* Load the DHT from data of size size.
1628 *
1629 * return -1 if failure.
1630 * return 0 if success.
1631 */
1632int DHT_load_new(DHT *dht, uint8_t *data, uint32_t length)
1633{
1634 uint32_t cookie_len = sizeof(uint32_t);
1635 if (length > cookie_len) {
1636 uint32_t *data32 = (uint32_t *)data;
1637 if (data32[0] == DHT_STATE_COOKIE_GLOBAL)
1638 return load_state(dht_load_state_callback, dht, data + cookie_len,
1639 length - cookie_len, DHT_STATE_COOKIE_TYPE);
1640 }
1641
1642 return DHT_load_old(dht, data, length);
1643}
1521/* return 0 if we are not connected to the DHT. 1644/* return 0 if we are not connected to the DHT.
1522 * return 1 if we are. 1645 * return 1 if we are.
1523 */ 1646 */