diff options
Diffstat (limited to 'toxcore')
-rw-r--r-- | toxcore/DHT.c | 129 | ||||
-rw-r--r-- | toxcore/DHT.h | 4 | ||||
-rw-r--r-- | toxcore/Messenger.c | 180 | ||||
-rw-r--r-- | toxcore/util.c | 41 | ||||
-rw-r--r-- | toxcore/util.h | 4 |
5 files changed, 335 insertions, 23 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). */ |
1460 | uint32_t DHT_size(DHT *dht) | 1460 | uint32_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(). */ |
1466 | void DHT_save(DHT *dht, uint8_t *data) | 1466 | void 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 | */ |
1477 | int DHT_load(DHT *dht, uint8_t *data, uint32_t size) | 1477 | int 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). */ | ||
1531 | uint32_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 | |||
1544 | static 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(). */ | ||
1554 | void 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 | |||
1585 | static 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 | */ | ||
1632 | int 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 | */ |
diff --git a/toxcore/DHT.h b/toxcore/DHT.h index ff20c892..e6f227f7 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h | |||
@@ -226,11 +226,13 @@ DHT *new_DHT(Net_Crypto *c); | |||
226 | void kill_DHT(DHT *dht); | 226 | void kill_DHT(DHT *dht); |
227 | 227 | ||
228 | /* Load the DHT from data of size size. | 228 | /* Load the DHT from data of size size. |
229 | * old/new: version of config file | ||
229 | * | 230 | * |
230 | * return -1 if failure. | 231 | * return -1 if failure. |
231 | * return 0 if success. | 232 | * return 0 if success. |
232 | */ | 233 | */ |
233 | int DHT_load(DHT *dht, uint8_t *data, uint32_t size); | 234 | int DHT_load_old(DHT *dht, uint8_t *data, uint32_t size); |
235 | int DHT_load_new(DHT *dht, uint8_t *data, uint32_t size); | ||
234 | 236 | ||
235 | /* return 0 if we are not connected to the DHT. | 237 | /* return 0 if we are not connected to the DHT. |
236 | * return 1 if we are. | 238 | * return 1 if we are. |
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index c46e3938..f2be6008 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -1331,7 +1331,7 @@ void doMessenger(Messenger *m) | |||
1331 | } | 1331 | } |
1332 | 1332 | ||
1333 | /* return size of the messenger data (for saving) */ | 1333 | /* return size of the messenger data (for saving) */ |
1334 | uint32_t Messenger_size(Messenger *m) | 1334 | uint32_t Messenger_size_old(Messenger *m) |
1335 | { | 1335 | { |
1336 | return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES | 1336 | return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES |
1337 | + sizeof(uint32_t) // nospam. | 1337 | + sizeof(uint32_t) // nospam. |
@@ -1344,8 +1344,8 @@ uint32_t Messenger_size(Messenger *m) | |||
1344 | ; | 1344 | ; |
1345 | } | 1345 | } |
1346 | 1346 | ||
1347 | /* Save the messenger in data of size Messenger_size(). */ | 1347 | /* Save the messenger in data of size Messenger_size(). Old version without cookies. */ |
1348 | void Messenger_save(Messenger *m, uint8_t *data) | 1348 | static void Messenger_save_old(Messenger *m, uint8_t *data) |
1349 | { | 1349 | { |
1350 | save_keys(m->net_crypto, data); | 1350 | save_keys(m->net_crypto, data); |
1351 | data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; | 1351 | data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; |
@@ -1372,8 +1372,8 @@ void Messenger_save(Messenger *m, uint8_t *data) | |||
1372 | memcpy(data, m->name, small_size); | 1372 | memcpy(data, m->name, small_size); |
1373 | } | 1373 | } |
1374 | 1374 | ||
1375 | /* Load the messenger from data of size length. */ | 1375 | /* Load the messenger from data of size length. Old version without cookies. */ |
1376 | int Messenger_load(Messenger *m, uint8_t *data, uint32_t length) | 1376 | static int Messenger_load_old(Messenger *m, uint8_t *data, uint32_t length) |
1377 | { | 1377 | { |
1378 | if (length == ~((uint32_t)0)) | 1378 | if (length == ~((uint32_t)0)) |
1379 | return -1; | 1379 | return -1; |
@@ -1393,6 +1393,9 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length) | |||
1393 | length -= sizeof(nospam); | 1393 | length -= sizeof(nospam); |
1394 | 1394 | ||
1395 | uint32_t size; | 1395 | uint32_t size; |
1396 | if (length < sizeof(size)) | ||
1397 | return -1; | ||
1398 | |||
1396 | memcpy(&size, data, sizeof(size)); | 1399 | memcpy(&size, data, sizeof(size)); |
1397 | data += sizeof(size); | 1400 | data += sizeof(size); |
1398 | length -= sizeof(size); | 1401 | length -= sizeof(size); |
@@ -1400,10 +1403,9 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length) | |||
1400 | if (length < size) | 1403 | if (length < size) |
1401 | return -1; | 1404 | return -1; |
1402 | 1405 | ||
1403 | if (DHT_load(m->dht, data, size) == -1) | 1406 | if (DHT_load_old(m->dht, data, size) == -1) |
1404 | fprintf(stderr, "Data file: Something wicked happened to the stored connections...\n"); | 1407 | fprintf(stderr, "Data file: Something wicked happened to the stored connections...\n"); |
1405 | 1408 | /* DO go on, friends/name still might be intact */ | |
1406 | /* go on, friends still might be intact */ | ||
1407 | 1409 | ||
1408 | data += size; | 1410 | data += size; |
1409 | length -= size; | 1411 | length -= size; |
@@ -1420,24 +1422,22 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length) | |||
1420 | 1422 | ||
1421 | if (!(size % sizeof(Friend))) { | 1423 | if (!(size % sizeof(Friend))) { |
1422 | uint16_t num = size / sizeof(Friend); | 1424 | uint16_t num = size / sizeof(Friend); |
1423 | Friend temp[num]; | 1425 | Friend *friend_list = (Friend *)data; |
1424 | memcpy(temp, data, size); | ||
1425 | 1426 | ||
1426 | uint32_t i; | 1427 | uint32_t i; |
1427 | |||
1428 | for (i = 0; i < num; ++i) { | 1428 | for (i = 0; i < num; ++i) { |
1429 | if (temp[i].status >= 3) { | 1429 | if (friend_list[i].status >= 3) { |
1430 | int fnum = m_addfriend_norequest(m, temp[i].client_id); | 1430 | int fnum = m_addfriend_norequest(m, friend_list[i].client_id); |
1431 | setfriendname(m, fnum, temp[i].name, temp[i].name_length); | 1431 | setfriendname(m, fnum, friend_list[i].name, friend_list[i].name_length); |
1432 | /* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */ | 1432 | /* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */ |
1433 | } else if (temp[i].status != 0) { | 1433 | } else if (friend_list[i].status != 0) { |
1434 | /* TODO: This is not a good way to do this. */ | 1434 | /* TODO: This is not a good way to do this. */ |
1435 | uint8_t address[FRIEND_ADDRESS_SIZE]; | 1435 | uint8_t address[FRIEND_ADDRESS_SIZE]; |
1436 | memcpy(address, temp[i].client_id, crypto_box_PUBLICKEYBYTES); | 1436 | memcpy(address, friend_list[i].client_id, crypto_box_PUBLICKEYBYTES); |
1437 | memcpy(address + crypto_box_PUBLICKEYBYTES, &(temp[i].friendrequest_nospam), sizeof(uint32_t)); | 1437 | memcpy(address + crypto_box_PUBLICKEYBYTES, &(friend_list[i].friendrequest_nospam), sizeof(uint32_t)); |
1438 | uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); | 1438 | uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); |
1439 | memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), &checksum, sizeof(checksum)); | 1439 | memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), &checksum, sizeof(checksum)); |
1440 | m_addfriend(m, address, temp[i].info, temp[i].info_size); | 1440 | m_addfriend(m, address, friend_list[i].info, friend_list[i].info_size); |
1441 | } | 1441 | } |
1442 | } | 1442 | } |
1443 | } | 1443 | } |
@@ -1454,7 +1454,7 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length) | |||
1454 | data += sizeof(small_size); | 1454 | data += sizeof(small_size); |
1455 | length -= sizeof(small_size); | 1455 | length -= sizeof(small_size); |
1456 | 1456 | ||
1457 | if (length != small_size) | 1457 | if (length < small_size) |
1458 | return -1; | 1458 | return -1; |
1459 | 1459 | ||
1460 | setname(m, data, small_size); | 1460 | setname(m, data, small_size); |
@@ -1462,6 +1462,148 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length) | |||
1462 | return 0; | 1462 | return 0; |
1463 | } | 1463 | } |
1464 | 1464 | ||
1465 | |||
1466 | /* new messenger format for load/save, more robust and forward compatible */ | ||
1467 | |||
1468 | #define MESSENGER_STATE_COOKIE_GLOBAL 0x15ed1b1e | ||
1469 | |||
1470 | #define MESSENGER_STATE_COOKIE_TYPE 0x01ce | ||
1471 | #define MESSENGER_STATE_TYPE_NOSPAMKEYS 1 | ||
1472 | #define MESSENGER_STATE_TYPE_DHT 2 | ||
1473 | #define MESSENGER_STATE_TYPE_FRIENDS 3 | ||
1474 | #define MESSENGER_STATE_TYPE_NAME 4 | ||
1475 | |||
1476 | /* return size of the messenger data (for saving) */ | ||
1477 | uint32_t Messenger_size(Messenger *m) | ||
1478 | { | ||
1479 | uint32_t size32 = sizeof(uint32_t), sizesubhead = size32 * 2; | ||
1480 | return size32 * 2 // global cookie | ||
1481 | + sizesubhead + sizeof(uint32_t) + crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES | ||
1482 | + sizesubhead + DHT_size(m->dht) // DHT | ||
1483 | + sizesubhead + sizeof(Friend) * m->numfriends // Friendlist itself. | ||
1484 | + sizesubhead + m->name_length // Own nickname. | ||
1485 | ; | ||
1486 | } | ||
1487 | |||
1488 | static uint8_t *z_state_save_subheader(uint8_t *data, uint32_t len, uint16_t type) | ||
1489 | { | ||
1490 | uint32_t *data32 = (uint32_t *)data; | ||
1491 | data32[0] = len; | ||
1492 | data32[1] = (MESSENGER_STATE_COOKIE_TYPE << 16) | type; | ||
1493 | data += sizeof(uint32_t) * 2; | ||
1494 | return data; | ||
1495 | } | ||
1496 | |||
1497 | /* Save the messenger in data of size Messenger_size(). */ | ||
1498 | void Messenger_save(Messenger *m, uint8_t *data) | ||
1499 | { | ||
1500 | uint32_t len; | ||
1501 | uint16_t type; | ||
1502 | uint32_t *data32, size32 = sizeof(uint32_t); | ||
1503 | |||
1504 | data32 = (uint32_t *)data; | ||
1505 | data32[0] = 0; | ||
1506 | data32[1] = MESSENGER_STATE_COOKIE_GLOBAL; | ||
1507 | data += size32 * 2; | ||
1508 | |||
1509 | #ifdef DEBUG | ||
1510 | assert(sizeof(get_nospam(&(m->fr))) == sizeof(uint32_t)); | ||
1511 | #endif | ||
1512 | len = size32 + crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; | ||
1513 | type = MESSENGER_STATE_TYPE_NOSPAMKEYS; | ||
1514 | data = z_state_save_subheader(data, len, type); | ||
1515 | *(uint32_t *)data = get_nospam(&(m->fr)); | ||
1516 | save_keys(m->net_crypto, data + size32); | ||
1517 | data += len; | ||
1518 | |||
1519 | len = DHT_size(m->dht); | ||
1520 | type = MESSENGER_STATE_TYPE_DHT; | ||
1521 | data = z_state_save_subheader(data, len, type); | ||
1522 | DHT_save(m->dht, data); | ||
1523 | data += len; | ||
1524 | |||
1525 | len = sizeof(Friend) * m->numfriends; | ||
1526 | type = MESSENGER_STATE_TYPE_FRIENDS; | ||
1527 | data = z_state_save_subheader(data, len, type); | ||
1528 | memcpy(data, m->friendlist, len); | ||
1529 | data += len; | ||
1530 | |||
1531 | len = m->name_length; | ||
1532 | type = MESSENGER_STATE_TYPE_NAME; | ||
1533 | data = z_state_save_subheader(data, len, type); | ||
1534 | memcpy(data, m->name, len); | ||
1535 | data += len; | ||
1536 | } | ||
1537 | |||
1538 | static int messenger_load_state_callback(void *outer, uint8_t *data, uint32_t length, uint16_t type) | ||
1539 | { | ||
1540 | Messenger *m = outer; | ||
1541 | switch(type) { | ||
1542 | case MESSENGER_STATE_TYPE_NOSPAMKEYS: | ||
1543 | if (length == crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t)) { | ||
1544 | set_nospam(&(m->fr), *(uint32_t *)data); | ||
1545 | load_keys(m->net_crypto, &data[sizeof(uint32_t)]); | ||
1546 | } | ||
1547 | else | ||
1548 | return -1; /* critical */ | ||
1549 | break; | ||
1550 | |||
1551 | case MESSENGER_STATE_TYPE_DHT: | ||
1552 | DHT_load_new(m->dht, data, length); | ||
1553 | break; | ||
1554 | |||
1555 | case MESSENGER_STATE_TYPE_FRIENDS: | ||
1556 | if (!(length % sizeof(Friend))) { | ||
1557 | uint16_t num = length / sizeof(Friend); | ||
1558 | Friend *friends = (Friend *)data; | ||
1559 | uint32_t i; | ||
1560 | for (i = 0; i < num; ++i) { | ||
1561 | if (friends[i].status >= 3) { | ||
1562 | int fnum = m_addfriend_norequest(m, friends[i].client_id); | ||
1563 | setfriendname(m, fnum, friends[i].name, friends[i].name_length); | ||
1564 | /* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */ | ||
1565 | } else if (friends[i].status != 0) { | ||
1566 | /* TODO: This is not a good way to do this. */ | ||
1567 | uint8_t address[FRIEND_ADDRESS_SIZE]; | ||
1568 | memcpy(address, friends[i].client_id, crypto_box_PUBLICKEYBYTES); | ||
1569 | memcpy(address + crypto_box_PUBLICKEYBYTES, &(friends[i].friendrequest_nospam), sizeof(uint32_t)); | ||
1570 | uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); | ||
1571 | memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), &checksum, sizeof(checksum)); | ||
1572 | m_addfriend(m, address, friends[i].info, friends[i].info_size); | ||
1573 | } | ||
1574 | } | ||
1575 | } | ||
1576 | break; | ||
1577 | |||
1578 | case MESSENGER_STATE_TYPE_NAME: | ||
1579 | if ((length > 0) && (length < MAX_NAME_LENGTH)) { | ||
1580 | setname(m, data, length); | ||
1581 | } | ||
1582 | break; | ||
1583 | |||
1584 | default: | ||
1585 | fprintf(stderr, "Load state: contains unrecognized part (len %u, type %u)\n", | ||
1586 | length, type); | ||
1587 | } | ||
1588 | |||
1589 | return 0; | ||
1590 | } | ||
1591 | |||
1592 | /* Load the messenger from data of size length. */ | ||
1593 | int Messenger_load(Messenger *m, uint8_t *data, uint32_t length) | ||
1594 | { | ||
1595 | uint32_t cookie_len = 2 * sizeof(uint32_t); | ||
1596 | if (length < cookie_len) | ||
1597 | return -1; | ||
1598 | |||
1599 | uint32_t *data32 = (uint32_t *)data; | ||
1600 | if (!data32[0] && (data32[1] == MESSENGER_STATE_COOKIE_GLOBAL)) | ||
1601 | return load_state(messenger_load_state_callback, m, data + cookie_len, | ||
1602 | length - cookie_len, MESSENGER_STATE_COOKIE_TYPE); | ||
1603 | else /* old state file */ | ||
1604 | return Messenger_load_old(m, data, length); | ||
1605 | } | ||
1606 | |||
1465 | /* Allocate and return a list of valid friend id's. List must be freed by the | 1607 | /* Allocate and return a list of valid friend id's. List must be freed by the |
1466 | * caller. | 1608 | * caller. |
1467 | * | 1609 | * |
diff --git a/toxcore/util.c b/toxcore/util.c index e1c46ee5..28f7d26e 100644 --- a/toxcore/util.c +++ b/toxcore/util.c | |||
@@ -43,6 +43,47 @@ void id_cpy(uint8_t *dest, uint8_t *src) | |||
43 | memcpy(dest, src, CLIENT_ID_SIZE); | 43 | memcpy(dest, src, CLIENT_ID_SIZE); |
44 | } | 44 | } |
45 | 45 | ||
46 | int load_state(load_state_callback_func load_state_callback, void *outer, | ||
47 | uint8_t *data, uint32_t length, uint16_t cookie_inner) | ||
48 | { | ||
49 | if (!load_state_callback || !data) { | ||
50 | fprintf(stderr, "load_state() called with invalid args.\n"); | ||
51 | return -1; | ||
52 | } | ||
53 | |||
54 | |||
55 | uint16_t type; | ||
56 | uint32_t length_sub, cookie_type; | ||
57 | uint32_t size32 = sizeof(uint32_t), size_head = size32 * 2; | ||
58 | while (length > size_head) { | ||
59 | length_sub = *(uint32_t *)data; | ||
60 | cookie_type = *(uint32_t *)(data + size32); | ||
61 | data += size_head; | ||
62 | length -= size_head; | ||
63 | |||
64 | if (length < length_sub) { | ||
65 | /* file truncated */ | ||
66 | fprintf(stderr, "state file too short: %u < %u\n", length, length_sub); | ||
67 | return -1; | ||
68 | } | ||
69 | |||
70 | if ((cookie_type >> 16) != cookie_inner) { | ||
71 | /* something is not matching up in a bad way, give up */ | ||
72 | fprintf(stderr, "state file garbeled: %04hx != %04hx\n", (cookie_type >> 16), cookie_inner); | ||
73 | return -1; | ||
74 | } | ||
75 | |||
76 | type = cookie_type & 0xFFFF; | ||
77 | if (-1 == load_state_callback(outer, data, length_sub, type)) | ||
78 | return -1; | ||
79 | |||
80 | data += length_sub; | ||
81 | length -= length_sub; | ||
82 | } | ||
83 | |||
84 | return length == 0 ? 0 : - 1; | ||
85 | }; | ||
86 | |||
46 | #ifdef LOGGING | 87 | #ifdef LOGGING |
47 | time_t starttime = 0; | 88 | time_t starttime = 0; |
48 | char logbuffer[512]; | 89 | char logbuffer[512]; |
diff --git a/toxcore/util.h b/toxcore/util.h index 71be84ca..6937f7d4 100644 --- a/toxcore/util.h +++ b/toxcore/util.h | |||
@@ -16,6 +16,10 @@ uint64_t random_64b(); | |||
16 | bool id_eq(uint8_t *dest, uint8_t *src); | 16 | bool id_eq(uint8_t *dest, uint8_t *src); |
17 | void id_cpy(uint8_t *dest, uint8_t *src); | 17 | void id_cpy(uint8_t *dest, uint8_t *src); |
18 | 18 | ||
19 | typedef int (*load_state_callback_func)(void *outer, uint8_t *data, uint32_t len, uint16_t type); | ||
20 | int load_state(load_state_callback_func load_state_callback, void *outer, | ||
21 | uint8_t *data, uint32_t length, uint16_t cookie_inner); | ||
22 | |||
19 | #undef LOGGING | 23 | #undef LOGGING |
20 | /* #define LOGGING */ | 24 | /* #define LOGGING */ |
21 | #ifdef LOGGING | 25 | #ifdef LOGGING |