END_TEST START_TEST(test_dht_state_saveloadsave) { /* validate that: * a) saving stays within the confined space * b) a save()d state can be load()ed back successfully * c) a second save() is of equal size * d) the second save() is of equal content */ size_t i, extra = 64; size_t size = DHT_size(m->dht); uint8_t buffer[size + 2 * extra]; memset(buffer, 0xCD, extra); memset(buffer + extra + size, 0xCD, extra); DHT_save(m->dht, buffer + extra); for (i = 0; i < extra; i++) { ck_assert_msg(buffer[i] == 0xCD, "Buffer underwritten from DHT_save() @%u", i); ck_assert_msg(buffer[extra + size + i] == 0xCD, "Buffer overwritten from DHT_save() @%u", i); } int res = DHT_load(m->dht, buffer + extra, size); if (res == -1) ck_assert_msg(res == 0, "Failed to load back stored buffer: res == -1"); else { char msg[128]; size_t offset = res >> 4; uint8_t *ptr = buffer + extra + offset; sprintf(msg, "Failed to load back stored buffer: 0x%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx @%zu/%zu, code %d", ptr[-2], ptr[-1], ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], offset, size, res & 0x0F); ck_assert_msg(res == 0, msg); } size_t size2 = DHT_size(m->dht); ck_assert_msg(size == size2, "Messenger \"grew\" in size from a store/load cycle: %u -> %u", size, size2); uint8_t buffer2[size2]; DHT_save(m->dht, buffer2); ck_assert_msg(!memcmp(buffer + extra, buffer2, size), "DHT state changed by store/load/store cycle"); }
/* returns the size of the messenger data (for saving) */ uint32_t Messenger_size(Messenger *m) { return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) // nospam + sizeof(uint32_t) // DHT size + DHT_size() // DHT itself + sizeof(uint32_t) // Friendlist size + sizeof(Friend) * m->numfriends // Friendlist itself + sizeof(uint16_t) // Own nickname length + m->name_length // Own nickname ; }
/* save the messenger in data of size Messenger_size() */ void Messenger_save(uint8_t *data) { save_keys(data); data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; uint32_t size = DHT_size(); memcpy(data, &size, sizeof(size)); data += sizeof(size); DHT_save(data); data += size; size = sizeof(Friend) * numfriends; memcpy(data, &size, sizeof(size)); data += sizeof(size); memcpy(data, friendlist, sizeof(Friend) * numfriends); }
/* save the messenger in data of size Messenger_size() */ void Messenger_save(Messenger *m, uint8_t *data) { save_keys(data); data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; uint32_t nospam = get_nospam(); memcpy(data, &nospam, sizeof(nospam)); data += sizeof(nospam); uint32_t size = DHT_size(); memcpy(data, &size, sizeof(size)); data += sizeof(size); DHT_save(data); data += size; size = sizeof(Friend) * m->numfriends; memcpy(data, &size, sizeof(size)); data += sizeof(size); memcpy(data, m->friendlist, sizeof(Friend) * m->numfriends); data += size; uint16_t small_size = m->name_length; memcpy(data, &small_size, sizeof(small_size)); data += sizeof(small_size); memcpy(data, m->name, small_size); }
/* returns the size of the messenger data (for saving) */ uint32_t Messenger_size(void) { return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) + DHT_size() + sizeof(uint32_t) + sizeof(Friend) * numfriends; }