diff options
author | zugz (tox) <mbays+tox@sdf.org> | 2018-09-09 23:21:20 +0200 |
---|---|---|
committer | zugz (tox) <mbays+tox@sdf.org> | 2018-10-20 11:03:10 +0200 |
commit | 744dc2f5da2c54ad1e4d7d6ce229bc1756d81263 (patch) | |
tree | 35f6590fe3150118bc6b1336fbb0a7db06543668 /toxcore | |
parent | aa5c7828802b3fcaedfd8d6fe9a08ca714b9aa2b (diff) |
Make saving and loading the responsibility of Tox rather than Messenger
Diffstat (limited to 'toxcore')
-rw-r--r-- | toxcore/DHT.c | 4 | ||||
-rw-r--r-- | toxcore/Messenger.c | 139 | ||||
-rw-r--r-- | toxcore/Messenger.h | 29 | ||||
-rw-r--r-- | toxcore/group.c | 16 | ||||
-rw-r--r-- | toxcore/group.h | 15 | ||||
-rw-r--r-- | toxcore/state.c | 32 | ||||
-rw-r--r-- | toxcore/state.h | 25 | ||||
-rw-r--r-- | toxcore/tox.c | 82 |
8 files changed, 207 insertions, 135 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 8208052d..4908de32 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -2831,7 +2831,7 @@ uint32_t dht_size(const DHT *dht) | |||
2831 | /* Save the DHT in data where data is an array of size dht_size(). */ | 2831 | /* Save the DHT in data where data is an array of size dht_size(). */ |
2832 | void dht_save(const DHT *dht, uint8_t *data) | 2832 | void dht_save(const DHT *dht, uint8_t *data) |
2833 | { | 2833 | { |
2834 | host_to_lendian32(data, DHT_STATE_COOKIE_GLOBAL); | 2834 | host_to_lendian_bytes32(data, DHT_STATE_COOKIE_GLOBAL); |
2835 | data += sizeof(uint32_t); | 2835 | data += sizeof(uint32_t); |
2836 | 2836 | ||
2837 | uint8_t *const old_data = data; | 2837 | uint8_t *const old_data = data; |
@@ -2960,7 +2960,7 @@ int dht_load(DHT *dht, const uint8_t *data, uint32_t length) | |||
2960 | 2960 | ||
2961 | if (length > cookie_len) { | 2961 | if (length > cookie_len) { |
2962 | uint32_t data32; | 2962 | uint32_t data32; |
2963 | lendian_to_host32(&data32, data); | 2963 | lendian_bytes_to_host32(&data32, data); |
2964 | 2964 | ||
2965 | if (data32 == DHT_STATE_COOKIE_GLOBAL) { | 2965 | if (data32 == DHT_STATE_COOKIE_GLOBAL) { |
2966 | return state_load(dht->log, dht_load_state_callback, dht, data + cookie_len, | 2966 | return state_load(dht->log, dht_load_state_callback, dht, data + cookie_len, |
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index e092a9f2..ae2d1d3b 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -2739,10 +2739,6 @@ void do_messenger(Messenger *m, void *userdata) | |||
2739 | 2739 | ||
2740 | /* new messenger format for load/save, more robust and forward compatible */ | 2740 | /* new messenger format for load/save, more robust and forward compatible */ |
2741 | 2741 | ||
2742 | #define MESSENGER_STATE_COOKIE_GLOBAL 0x15ed1b1f | ||
2743 | |||
2744 | #define MESSENGER_STATE_COOKIE_TYPE 0x01ce | ||
2745 | |||
2746 | #define SAVED_FRIEND_REQUEST_SIZE 1024 | 2742 | #define SAVED_FRIEND_REQUEST_SIZE 1024 |
2747 | #define NUM_SAVED_PATH_NODES 8 | 2743 | #define NUM_SAVED_PATH_NODES 8 |
2748 | 2744 | ||
@@ -2881,7 +2877,7 @@ static uint32_t m_state_plugins_size(const Messenger *m) | |||
2881 | * returns true on success | 2877 | * returns true on success |
2882 | * returns false on failure | 2878 | * returns false on failure |
2883 | */ | 2879 | */ |
2884 | bool m_register_state_plugin(Messenger *m, Messenger_State_Type type, m_state_size_cb size_callback, | 2880 | bool m_register_state_plugin(Messenger *m, State_Type type, m_state_size_cb size_callback, |
2885 | m_state_load_cb load_callback, | 2881 | m_state_load_cb load_callback, |
2886 | m_state_save_cb save_callback) | 2882 | m_state_save_cb save_callback) |
2887 | { | 2883 | { |
@@ -2904,7 +2900,7 @@ bool m_register_state_plugin(Messenger *m, Messenger_State_Type type, m_state_si | |||
2904 | return true; | 2900 | return true; |
2905 | } | 2901 | } |
2906 | 2902 | ||
2907 | static uint32_t m_plugin_size(const Messenger *m, Messenger_State_Type type) | 2903 | static uint32_t m_plugin_size(const Messenger *m, State_Type type) |
2908 | { | 2904 | { |
2909 | for (uint8_t i = 0; i < m->options.state_plugins_length; ++i) { | 2905 | for (uint8_t i = 0; i < m->options.state_plugins_length; ++i) { |
2910 | const Messenger_State_Plugin plugin = m->options.state_plugins[i]; | 2906 | const Messenger_State_Plugin plugin = m->options.state_plugins[i]; |
@@ -2922,30 +2918,18 @@ static uint32_t m_plugin_size(const Messenger *m, Messenger_State_Type type) | |||
2922 | /* return size of the messenger data (for saving) */ | 2918 | /* return size of the messenger data (for saving) */ |
2923 | uint32_t messenger_size(const Messenger *m) | 2919 | uint32_t messenger_size(const Messenger *m) |
2924 | { | 2920 | { |
2925 | const uint32_t size32 = sizeof(uint32_t); | 2921 | return m_state_plugins_size(m); |
2926 | const uint32_t sizesubhead = size32 * 2; | ||
2927 | return size32 * 2 // global cookie | ||
2928 | + m_state_plugins_size(m) | ||
2929 | + sizesubhead; | ||
2930 | } | 2922 | } |
2931 | 2923 | ||
2932 | /* Save the messenger in data of size Messenger_size(). */ | 2924 | /* Save the messenger in data of size messenger_size(). */ |
2933 | void messenger_save(const Messenger *m, uint8_t *data) | 2925 | uint8_t *messenger_save(const Messenger *m, uint8_t *data) |
2934 | { | 2926 | { |
2935 | memset(data, 0, messenger_size(m)); | ||
2936 | |||
2937 | const uint32_t size32 = sizeof(uint32_t); | ||
2938 | |||
2939 | // write cookie | ||
2940 | memset(data, 0, size32); | ||
2941 | data += size32; | ||
2942 | host_to_lendian32(data, MESSENGER_STATE_COOKIE_GLOBAL); | ||
2943 | data += size32; | ||
2944 | |||
2945 | for (uint8_t i = 0; i < m->options.state_plugins_length; ++i) { | 2927 | for (uint8_t i = 0; i < m->options.state_plugins_length; ++i) { |
2946 | const Messenger_State_Plugin plugin = m->options.state_plugins[i]; | 2928 | const Messenger_State_Plugin plugin = m->options.state_plugins[i]; |
2947 | data = plugin.save(m, data); | 2929 | data = plugin.save(m, data); |
2948 | } | 2930 | } |
2931 | |||
2932 | return data; | ||
2949 | } | 2933 | } |
2950 | 2934 | ||
2951 | // nospam state plugin | 2935 | // nospam state plugin |
@@ -2956,12 +2940,12 @@ static uint32_t nospam_keys_size(const Messenger *m) | |||
2956 | 2940 | ||
2957 | static State_Load_Status load_nospam_keys(Messenger *m, const uint8_t *data, uint32_t length) | 2941 | static State_Load_Status load_nospam_keys(Messenger *m, const uint8_t *data, uint32_t length) |
2958 | { | 2942 | { |
2959 | if (length != m_plugin_size(m, MESSENGER_STATE_TYPE_NOSPAMKEYS)) { | 2943 | if (length != m_plugin_size(m, STATE_TYPE_NOSPAMKEYS)) { |
2960 | return STATE_LOAD_STATUS_ERROR; | 2944 | return STATE_LOAD_STATUS_ERROR; |
2961 | } | 2945 | } |
2962 | 2946 | ||
2963 | uint32_t nospam; | 2947 | uint32_t nospam; |
2964 | lendian_to_host32(&nospam, data); | 2948 | lendian_bytes_to_host32(&nospam, data); |
2965 | set_nospam(m->fr, nospam); | 2949 | set_nospam(m->fr, nospam); |
2966 | load_secret_key(m->net_crypto, data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE); | 2950 | load_secret_key(m->net_crypto, data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE); |
2967 | 2951 | ||
@@ -2974,11 +2958,11 @@ static State_Load_Status load_nospam_keys(Messenger *m, const uint8_t *data, uin | |||
2974 | 2958 | ||
2975 | static uint8_t *save_nospam_keys(const Messenger *m, uint8_t *data) | 2959 | static uint8_t *save_nospam_keys(const Messenger *m, uint8_t *data) |
2976 | { | 2960 | { |
2977 | const uint32_t len = m_plugin_size(m, MESSENGER_STATE_TYPE_NOSPAMKEYS); | 2961 | const uint32_t len = m_plugin_size(m, STATE_TYPE_NOSPAMKEYS); |
2978 | assert(sizeof(get_nospam(m->fr)) == sizeof(uint32_t)); | 2962 | assert(sizeof(get_nospam(m->fr)) == sizeof(uint32_t)); |
2979 | data = state_write_section_header(data, MESSENGER_STATE_COOKIE_TYPE, len, MESSENGER_STATE_TYPE_NOSPAMKEYS); | 2963 | data = state_write_section_header(data, STATE_COOKIE_TYPE, len, STATE_TYPE_NOSPAMKEYS); |
2980 | uint32_t nospam = get_nospam(m->fr); | 2964 | uint32_t nospam = get_nospam(m->fr); |
2981 | host_to_lendian32(data, nospam); | 2965 | host_to_lendian_bytes32(data, nospam); |
2982 | save_keys(m->net_crypto, data + sizeof(uint32_t)); | 2966 | save_keys(m->net_crypto, data + sizeof(uint32_t)); |
2983 | data += len; | 2967 | data += len; |
2984 | return data; | 2968 | return data; |
@@ -2992,8 +2976,8 @@ static uint32_t m_dht_size(const Messenger *m) | |||
2992 | 2976 | ||
2993 | static uint8_t *save_dht(const Messenger *m, uint8_t *data) | 2977 | static uint8_t *save_dht(const Messenger *m, uint8_t *data) |
2994 | { | 2978 | { |
2995 | const uint32_t len = m_plugin_size(m, MESSENGER_STATE_TYPE_DHT); | 2979 | const uint32_t len = m_plugin_size(m, STATE_TYPE_DHT); |
2996 | data = state_write_section_header(data, MESSENGER_STATE_COOKIE_TYPE, len, MESSENGER_STATE_TYPE_DHT); | 2980 | data = state_write_section_header(data, STATE_COOKIE_TYPE, len, STATE_TYPE_DHT); |
2997 | dht_save(m->dht, data); | 2981 | dht_save(m->dht, data); |
2998 | data += len; | 2982 | data += len; |
2999 | return data; | 2983 | return data; |
@@ -3013,8 +2997,8 @@ static uint32_t saved_friendslist_size(const Messenger *m) | |||
3013 | 2997 | ||
3014 | static uint8_t *friends_list_save(const Messenger *m, uint8_t *data) | 2998 | static uint8_t *friends_list_save(const Messenger *m, uint8_t *data) |
3015 | { | 2999 | { |
3016 | const uint32_t len = m_plugin_size(m, MESSENGER_STATE_TYPE_FRIENDS); | 3000 | const uint32_t len = m_plugin_size(m, STATE_TYPE_FRIENDS); |
3017 | data = state_write_section_header(data, MESSENGER_STATE_COOKIE_TYPE, len, MESSENGER_STATE_TYPE_FRIENDS); | 3001 | data = state_write_section_header(data, STATE_COOKIE_TYPE, len, STATE_TYPE_FRIENDS); |
3018 | 3002 | ||
3019 | uint32_t num = 0; | 3003 | uint32_t num = 0; |
3020 | uint8_t *cur_data = data; | 3004 | uint8_t *cur_data = data; |
@@ -3119,8 +3103,8 @@ static uint32_t name_size(const Messenger *m) | |||
3119 | 3103 | ||
3120 | static uint8_t *save_name(const Messenger *m, uint8_t *data) | 3104 | static uint8_t *save_name(const Messenger *m, uint8_t *data) |
3121 | { | 3105 | { |
3122 | const uint32_t len = m_plugin_size(m, MESSENGER_STATE_TYPE_NAME); | 3106 | const uint32_t len = m_plugin_size(m, STATE_TYPE_NAME); |
3123 | data = state_write_section_header(data, MESSENGER_STATE_COOKIE_TYPE, len, MESSENGER_STATE_TYPE_NAME); | 3107 | data = state_write_section_header(data, STATE_COOKIE_TYPE, len, STATE_TYPE_NAME); |
3124 | memcpy(data, m->name, len); | 3108 | memcpy(data, m->name, len); |
3125 | data += len; | 3109 | data += len; |
3126 | return data; | 3110 | return data; |
@@ -3143,8 +3127,8 @@ static uint32_t status_message_size(const Messenger *m) | |||
3143 | 3127 | ||
3144 | static uint8_t *save_status_message(const Messenger *m, uint8_t *data) | 3128 | static uint8_t *save_status_message(const Messenger *m, uint8_t *data) |
3145 | { | 3129 | { |
3146 | const uint32_t len = m_plugin_size(m, MESSENGER_STATE_TYPE_STATUSMESSAGE); | 3130 | const uint32_t len = m_plugin_size(m, STATE_TYPE_STATUSMESSAGE); |
3147 | data = state_write_section_header(data, MESSENGER_STATE_COOKIE_TYPE, len, MESSENGER_STATE_TYPE_STATUSMESSAGE); | 3131 | data = state_write_section_header(data, STATE_COOKIE_TYPE, len, STATE_TYPE_STATUSMESSAGE); |
3148 | memcpy(data, m->statusmessage, len); | 3132 | memcpy(data, m->statusmessage, len); |
3149 | data += len; | 3133 | data += len; |
3150 | return data; | 3134 | return data; |
@@ -3167,8 +3151,8 @@ static uint32_t status_size(const Messenger *m) | |||
3167 | 3151 | ||
3168 | static uint8_t *save_status(const Messenger *m, uint8_t *data) | 3152 | static uint8_t *save_status(const Messenger *m, uint8_t *data) |
3169 | { | 3153 | { |
3170 | const uint32_t len = m_plugin_size(m, MESSENGER_STATE_TYPE_STATUS); | 3154 | const uint32_t len = m_plugin_size(m, STATE_TYPE_STATUS); |
3171 | data = state_write_section_header(data, MESSENGER_STATE_COOKIE_TYPE, len, MESSENGER_STATE_TYPE_STATUS); | 3155 | data = state_write_section_header(data, STATE_COOKIE_TYPE, len, STATE_TYPE_STATUS); |
3172 | *data = m->userstatus; | 3156 | *data = m->userstatus; |
3173 | data += len; | 3157 | data += len; |
3174 | return data; | 3158 | return data; |
@@ -3193,7 +3177,7 @@ static uint8_t *save_tcp_relays(const Messenger *m, uint8_t *data) | |||
3193 | { | 3177 | { |
3194 | Node_format relays[NUM_SAVED_TCP_RELAYS]; | 3178 | Node_format relays[NUM_SAVED_TCP_RELAYS]; |
3195 | uint8_t *temp_data = data; | 3179 | uint8_t *temp_data = data; |
3196 | data = state_write_section_header(temp_data, MESSENGER_STATE_COOKIE_TYPE, 0, MESSENGER_STATE_TYPE_TCP_RELAY); | 3180 | data = state_write_section_header(temp_data, STATE_COOKIE_TYPE, 0, STATE_TYPE_TCP_RELAY); |
3197 | uint32_t num = copy_connected_tcp_relays(m->net_crypto, relays, NUM_SAVED_TCP_RELAYS); | 3181 | uint32_t num = copy_connected_tcp_relays(m->net_crypto, relays, NUM_SAVED_TCP_RELAYS); |
3198 | 3182 | ||
3199 | if (m->num_loaded_relays > 0) { | 3183 | if (m->num_loaded_relays > 0) { |
@@ -3205,7 +3189,7 @@ static uint8_t *save_tcp_relays(const Messenger *m, uint8_t *data) | |||
3205 | 3189 | ||
3206 | if (l > 0) { | 3190 | if (l > 0) { |
3207 | const uint32_t len = l; | 3191 | const uint32_t len = l; |
3208 | data = state_write_section_header(temp_data, MESSENGER_STATE_COOKIE_TYPE, len, MESSENGER_STATE_TYPE_TCP_RELAY); | 3192 | data = state_write_section_header(temp_data, STATE_COOKIE_TYPE, len, STATE_TYPE_TCP_RELAY); |
3209 | data += len; | 3193 | data += len; |
3210 | } | 3194 | } |
3211 | 3195 | ||
@@ -3232,14 +3216,14 @@ static uint8_t *save_path_nodes(const Messenger *m, uint8_t *data) | |||
3232 | { | 3216 | { |
3233 | Node_format nodes[NUM_SAVED_PATH_NODES]; | 3217 | Node_format nodes[NUM_SAVED_PATH_NODES]; |
3234 | uint8_t *temp_data = data; | 3218 | uint8_t *temp_data = data; |
3235 | data = state_write_section_header(data, MESSENGER_STATE_COOKIE_TYPE, 0, MESSENGER_STATE_TYPE_PATH_NODE); | 3219 | data = state_write_section_header(data, STATE_COOKIE_TYPE, 0, STATE_TYPE_PATH_NODE); |
3236 | memset(nodes, 0, sizeof(nodes)); | 3220 | memset(nodes, 0, sizeof(nodes)); |
3237 | const unsigned int num = onion_backup_nodes(m->onion_c, nodes, NUM_SAVED_PATH_NODES); | 3221 | const unsigned int num = onion_backup_nodes(m->onion_c, nodes, NUM_SAVED_PATH_NODES); |
3238 | const int l = pack_nodes(data, NUM_SAVED_PATH_NODES * packed_node_size(net_family_tcp_ipv6), nodes, num); | 3222 | const int l = pack_nodes(data, NUM_SAVED_PATH_NODES * packed_node_size(net_family_tcp_ipv6), nodes, num); |
3239 | 3223 | ||
3240 | if (l > 0) { | 3224 | if (l > 0) { |
3241 | const uint32_t len = l; | 3225 | const uint32_t len = l; |
3242 | data = state_write_section_header(temp_data, MESSENGER_STATE_COOKIE_TYPE, len, MESSENGER_STATE_TYPE_PATH_NODE); | 3226 | data = state_write_section_header(temp_data, STATE_COOKIE_TYPE, len, STATE_TYPE_PATH_NODE); |
3243 | data += len; | 3227 | data += len; |
3244 | } | 3228 | } |
3245 | 3229 | ||
@@ -3261,77 +3245,32 @@ static State_Load_Status load_path_nodes(Messenger *m, const uint8_t *data, uint | |||
3261 | return STATE_LOAD_STATUS_CONTINUE; | 3245 | return STATE_LOAD_STATUS_CONTINUE; |
3262 | } | 3246 | } |
3263 | 3247 | ||
3264 | // end state plugin | ||
3265 | static uint32_t end_size(const Messenger *m) | ||
3266 | { | ||
3267 | return 0; | ||
3268 | } | ||
3269 | |||
3270 | static uint8_t *save_end(const Messenger *m, uint8_t *data) | ||
3271 | { | ||
3272 | return state_write_section_header(data, MESSENGER_STATE_COOKIE_TYPE, 0, MESSENGER_STATE_TYPE_END); | ||
3273 | } | ||
3274 | |||
3275 | static State_Load_Status load_end(Messenger *m, const uint8_t *data, uint32_t length) | ||
3276 | { | ||
3277 | if (length != 0) { | ||
3278 | return STATE_LOAD_STATUS_ERROR; | ||
3279 | } | ||
3280 | |||
3281 | return STATE_LOAD_STATUS_END; | ||
3282 | } | ||
3283 | |||
3284 | static void m_register_default_plugins(Messenger *m) | 3248 | static void m_register_default_plugins(Messenger *m) |
3285 | { | 3249 | { |
3286 | m_register_state_plugin(m, MESSENGER_STATE_TYPE_NOSPAMKEYS, nospam_keys_size, load_nospam_keys, save_nospam_keys); | 3250 | m_register_state_plugin(m, STATE_TYPE_NOSPAMKEYS, nospam_keys_size, load_nospam_keys, save_nospam_keys); |
3287 | m_register_state_plugin(m, MESSENGER_STATE_TYPE_DHT, m_dht_size, m_dht_load, save_dht); | 3251 | m_register_state_plugin(m, STATE_TYPE_DHT, m_dht_size, m_dht_load, save_dht); |
3288 | m_register_state_plugin(m, MESSENGER_STATE_TYPE_FRIENDS, saved_friendslist_size, friends_list_load, friends_list_save); | 3252 | m_register_state_plugin(m, STATE_TYPE_FRIENDS, saved_friendslist_size, friends_list_load, friends_list_save); |
3289 | m_register_state_plugin(m, MESSENGER_STATE_TYPE_NAME, name_size, load_name, save_name); | 3253 | m_register_state_plugin(m, STATE_TYPE_NAME, name_size, load_name, save_name); |
3290 | m_register_state_plugin(m, MESSENGER_STATE_TYPE_STATUSMESSAGE, status_message_size, load_status_message, | 3254 | m_register_state_plugin(m, STATE_TYPE_STATUSMESSAGE, status_message_size, load_status_message, |
3291 | save_status_message); | 3255 | save_status_message); |
3292 | m_register_state_plugin(m, MESSENGER_STATE_TYPE_STATUS, status_size, load_status, save_status); | 3256 | m_register_state_plugin(m, STATE_TYPE_STATUS, status_size, load_status, save_status); |
3293 | m_register_state_plugin(m, MESSENGER_STATE_TYPE_TCP_RELAY, tcp_relay_size, load_tcp_relays, save_tcp_relays); | 3257 | m_register_state_plugin(m, STATE_TYPE_TCP_RELAY, tcp_relay_size, load_tcp_relays, save_tcp_relays); |
3294 | m_register_state_plugin(m, MESSENGER_STATE_TYPE_PATH_NODE, path_node_size, load_path_nodes, save_path_nodes); | 3258 | m_register_state_plugin(m, STATE_TYPE_PATH_NODE, path_node_size, load_path_nodes, save_path_nodes); |
3295 | m_register_state_plugin(m, MESSENGER_STATE_TYPE_END, end_size, load_end, save_end); | ||
3296 | } | 3259 | } |
3297 | 3260 | ||
3298 | static State_Load_Status messenger_load_state_callback(void *outer, const uint8_t *data, uint32_t length, uint16_t type) | 3261 | bool messenger_load_state_section(Messenger *m, const uint8_t *data, uint32_t length, uint16_t type, |
3262 | State_Load_Status *status) | ||
3299 | { | 3263 | { |
3300 | Messenger *m = (Messenger *)outer; | ||
3301 | |||
3302 | for (uint8_t i = 0; i < m->options.state_plugins_length; ++i) { | 3264 | for (uint8_t i = 0; i < m->options.state_plugins_length; ++i) { |
3303 | const Messenger_State_Plugin *const plugin = &m->options.state_plugins[i]; | 3265 | const Messenger_State_Plugin *const plugin = &m->options.state_plugins[i]; |
3304 | 3266 | ||
3305 | if (plugin->type == type) { | 3267 | if (plugin->type == type) { |
3306 | return plugin->load(m, data, length); | 3268 | *status = plugin->load(m, data, length); |
3269 | return true; | ||
3307 | } | 3270 | } |
3308 | } | 3271 | } |
3309 | 3272 | ||
3310 | LOGGER_ERROR(m->log, "Load state: contains unrecognized part (len %u, type %u)\n", | 3273 | return false; |
3311 | length, type); | ||
3312 | |||
3313 | return STATE_LOAD_STATUS_CONTINUE; | ||
3314 | } | ||
3315 | |||
3316 | /* Load the messenger from data of size length. */ | ||
3317 | int messenger_load(Messenger *m, const uint8_t *data, uint32_t length) | ||
3318 | { | ||
3319 | uint32_t data32[2]; | ||
3320 | uint32_t cookie_len = sizeof(data32); | ||
3321 | |||
3322 | if (length < cookie_len) { | ||
3323 | return -1; | ||
3324 | } | ||
3325 | |||
3326 | memcpy(data32, data, sizeof(uint32_t)); | ||
3327 | lendian_to_host32(data32 + 1, data + sizeof(uint32_t)); | ||
3328 | |||
3329 | if (!data32[0] && (data32[1] == MESSENGER_STATE_COOKIE_GLOBAL)) { | ||
3330 | return state_load(m->log, messenger_load_state_callback, m, data + cookie_len, | ||
3331 | length - cookie_len, MESSENGER_STATE_COOKIE_TYPE); | ||
3332 | } | ||
3333 | |||
3334 | return -1; | ||
3335 | } | 3274 | } |
3336 | 3275 | ||
3337 | /* Return the number of friends in the instance m. | 3276 | /* Return the number of friends in the instance m. |
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 0d80bd0d..1651315e 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h | |||
@@ -62,20 +62,8 @@ typedef uint8_t *m_state_save_cb(const Messenger *m, uint8_t *data); | |||
62 | // Returns if there were any erros during loading | 62 | // Returns if there were any erros during loading |
63 | typedef State_Load_Status m_state_load_cb(Messenger *m, const uint8_t *data, uint32_t length); | 63 | typedef State_Load_Status m_state_load_cb(Messenger *m, const uint8_t *data, uint32_t length); |
64 | 64 | ||
65 | typedef enum Messenger_State_Type { | ||
66 | MESSENGER_STATE_TYPE_NOSPAMKEYS = 1, | ||
67 | MESSENGER_STATE_TYPE_DHT = 2, | ||
68 | MESSENGER_STATE_TYPE_FRIENDS = 3, | ||
69 | MESSENGER_STATE_TYPE_NAME = 4, | ||
70 | MESSENGER_STATE_TYPE_STATUSMESSAGE = 5, | ||
71 | MESSENGER_STATE_TYPE_STATUS = 6, | ||
72 | MESSENGER_STATE_TYPE_TCP_RELAY = 10, | ||
73 | MESSENGER_STATE_TYPE_PATH_NODE = 11, | ||
74 | MESSENGER_STATE_TYPE_END = 255, | ||
75 | } Messenger_State_Type; | ||
76 | |||
77 | typedef struct Messenger_State_Plugin { | 65 | typedef struct Messenger_State_Plugin { |
78 | Messenger_State_Type type; | 66 | State_Type type; |
79 | m_state_size_cb *size; | 67 | m_state_size_cb *size; |
80 | m_state_save_cb *save; | 68 | m_state_save_cb *save; |
81 | m_state_load_cb *load; | 69 | m_state_load_cb *load; |
@@ -797,17 +785,22 @@ uint32_t messenger_run_interval(const Messenger *m); | |||
797 | * returns true on success | 785 | * returns true on success |
798 | * returns false on error | 786 | * returns false on error |
799 | */ | 787 | */ |
800 | bool m_register_state_plugin(Messenger *m, Messenger_State_Type type, m_state_size_cb size_callback, | 788 | bool m_register_state_plugin(Messenger *m, State_Type type, m_state_size_cb size_callback, |
801 | m_state_load_cb load_callback, m_state_save_cb save_callback); | 789 | m_state_load_cb load_callback, m_state_save_cb save_callback); |
802 | 790 | ||
803 | /* return size of the messenger data (for saving). */ | 791 | /* return size of the messenger data (for saving). */ |
804 | uint32_t messenger_size(const Messenger *m); | 792 | uint32_t messenger_size(const Messenger *m); |
805 | 793 | ||
806 | /* Save the messenger in data (must be allocated memory of size Messenger_size()) */ | 794 | /* Save the messenger in data (must be allocated memory of size at least Messenger_size()) */ |
807 | void messenger_save(const Messenger *m, uint8_t *data); | 795 | uint8_t *messenger_save(const Messenger *m, uint8_t *data); |
808 | 796 | ||
809 | /* Load the messenger from data of size length. */ | 797 | /* Load a state section. |
810 | int messenger_load(Messenger *m, const uint8_t *data, uint32_t length); | 798 | * |
799 | * @param status Result of loading section is stored here if the section is handled. | ||
800 | * @return true iff section handled. | ||
801 | */ | ||
802 | bool messenger_load_state_section(Messenger *m, const uint8_t *data, uint32_t length, uint16_t type, | ||
803 | State_Load_Status *status); | ||
811 | 804 | ||
812 | /* Return the number of friends in the instance m. | 805 | /* Return the number of friends in the instance m. |
813 | * You should use this to determine how much memory to allocate | 806 | * You should use this to determine how much memory to allocate |
diff --git a/toxcore/group.c b/toxcore/group.c index 5feb483b..ee9548a1 100644 --- a/toxcore/group.c +++ b/toxcore/group.c | |||
@@ -2875,6 +2875,22 @@ void send_name_all_groups(Group_Chats *g_c) | |||
2875 | } | 2875 | } |
2876 | } | 2876 | } |
2877 | 2877 | ||
2878 | uint32_t conferences_size(const Group_Chats *g_c) | ||
2879 | { | ||
2880 | return 0; | ||
2881 | } | ||
2882 | |||
2883 | uint8_t *conferences_save(const Group_Chats *g_c, uint8_t *data) | ||
2884 | { | ||
2885 | return data; | ||
2886 | } | ||
2887 | |||
2888 | bool conferences_load_state_section(Group_Chats *g_c, const uint8_t *data, uint32_t length, uint16_t type, | ||
2889 | State_Load_Status *status) | ||
2890 | { | ||
2891 | return false; | ||
2892 | } | ||
2893 | |||
2878 | /* Create new groupchat instance. */ | 2894 | /* Create new groupchat instance. */ |
2879 | Group_Chats *new_groupchats(Mono_Time *mono_time, Messenger *m) | 2895 | Group_Chats *new_groupchats(Mono_Time *mono_time, Messenger *m) |
2880 | { | 2896 | { |
diff --git a/toxcore/group.h b/toxcore/group.h index 7acd4637..8673abdb 100644 --- a/toxcore/group.h +++ b/toxcore/group.h | |||
@@ -448,6 +448,21 @@ int callback_groupchat_peer_delete(Group_Chats *g_c, uint32_t groupnumber, peer_ | |||
448 | */ | 448 | */ |
449 | int callback_groupchat_delete(Group_Chats *g_c, uint32_t groupnumber, group_on_delete_cb *function); | 449 | int callback_groupchat_delete(Group_Chats *g_c, uint32_t groupnumber, group_on_delete_cb *function); |
450 | 450 | ||
451 | /* Return size of the conferences data (for saving). */ | ||
452 | uint32_t conferences_size(const Group_Chats *g_c); | ||
453 | |||
454 | /* Save the conferences in data (must be allocated memory of size at least conferences_size()) */ | ||
455 | uint8_t *conferences_save(const Group_Chats *g_c, uint8_t *data); | ||
456 | |||
457 | /** | ||
458 | * Load a section. | ||
459 | * | ||
460 | * @param status Result of loading section is stored here if the section is handled. | ||
461 | * @return true iff section handled. | ||
462 | */ | ||
463 | bool conferences_load_state_section(Group_Chats *g_c, const uint8_t *data, uint32_t length, uint16_t type, | ||
464 | State_Load_Status *status); | ||
465 | |||
451 | /* Create new groupchat instance. */ | 466 | /* Create new groupchat instance. */ |
452 | Group_Chats *new_groupchats(Mono_Time *mono_time, Messenger *m); | 467 | Group_Chats *new_groupchats(Mono_Time *mono_time, Messenger *m); |
453 | 468 | ||
diff --git a/toxcore/state.c b/toxcore/state.c index 29b4af88..919c2e8c 100644 --- a/toxcore/state.c +++ b/toxcore/state.c | |||
@@ -16,10 +16,10 @@ int state_load(const Logger *log, state_load_cb *state_load_callback, void *oute | |||
16 | 16 | ||
17 | while (length >= size_head) { | 17 | while (length >= size_head) { |
18 | uint32_t length_sub; | 18 | uint32_t length_sub; |
19 | lendian_to_host32(&length_sub, data); | 19 | lendian_bytes_to_host32(&length_sub, data); |
20 | 20 | ||
21 | uint32_t cookie_type; | 21 | uint32_t cookie_type; |
22 | lendian_to_host32(&cookie_type, data + sizeof(uint32_t)); | 22 | lendian_bytes_to_host32(&cookie_type, data + sizeof(uint32_t)); |
23 | 23 | ||
24 | data += size_head; | 24 | data += size_head; |
25 | length -= size_head; | 25 | length -= size_head; |
@@ -63,9 +63,9 @@ int state_load(const Logger *log, state_load_cb *state_load_callback, void *oute | |||
63 | 63 | ||
64 | uint8_t *state_write_section_header(uint8_t *data, uint16_t cookie_type, uint32_t len, uint32_t section_type) | 64 | uint8_t *state_write_section_header(uint8_t *data, uint16_t cookie_type, uint32_t len, uint32_t section_type) |
65 | { | 65 | { |
66 | host_to_lendian32(data, len); | 66 | host_to_lendian_bytes32(data, len); |
67 | data += sizeof(uint32_t); | 67 | data += sizeof(uint32_t); |
68 | host_to_lendian32(data, (host_tolendian16(cookie_type) << 16) | host_tolendian16(section_type)); | 68 | host_to_lendian_bytes32(data, (host_to_lendian16(cookie_type) << 16) | host_to_lendian16(section_type)); |
69 | data += sizeof(uint32_t); | 69 | data += sizeof(uint32_t); |
70 | return data; | 70 | return data; |
71 | } | 71 | } |
@@ -79,12 +79,12 @@ uint16_t lendian_to_host16(uint16_t lendian) | |||
79 | #endif | 79 | #endif |
80 | } | 80 | } |
81 | 81 | ||
82 | uint16_t host_tolendian16(uint16_t host) | 82 | uint16_t host_to_lendian16(uint16_t host) |
83 | { | 83 | { |
84 | return lendian_to_host16(host); | 84 | return lendian_to_host16(host); |
85 | } | 85 | } |
86 | 86 | ||
87 | void host_to_lendian32(uint8_t *dest, uint32_t num) | 87 | void host_to_lendian_bytes32(uint8_t *dest, uint32_t num) |
88 | { | 88 | { |
89 | #ifdef WORDS_BIGENDIAN | 89 | #ifdef WORDS_BIGENDIAN |
90 | num = ((num << 8) & 0xFF00FF00) | ((num >> 8) & 0xFF00FF); | 90 | num = ((num << 8) & 0xFF00FF00) | ((num >> 8) & 0xFF00FF); |
@@ -93,7 +93,7 @@ void host_to_lendian32(uint8_t *dest, uint32_t num) | |||
93 | memcpy(dest, &num, sizeof(uint32_t)); | 93 | memcpy(dest, &num, sizeof(uint32_t)); |
94 | } | 94 | } |
95 | 95 | ||
96 | void lendian_to_host32(uint32_t *dest, const uint8_t *lendian) | 96 | void lendian_bytes_to_host32(uint32_t *dest, const uint8_t *lendian) |
97 | { | 97 | { |
98 | uint32_t d; | 98 | uint32_t d; |
99 | memcpy(&d, lendian, sizeof(uint32_t)); | 99 | memcpy(&d, lendian, sizeof(uint32_t)); |
@@ -103,3 +103,21 @@ void lendian_to_host32(uint32_t *dest, const uint8_t *lendian) | |||
103 | #endif | 103 | #endif |
104 | *dest = d; | 104 | *dest = d; |
105 | } | 105 | } |
106 | |||
107 | void host_to_lendian_bytes16(uint8_t *dest, uint16_t num) | ||
108 | { | ||
109 | #ifdef WORDS_BIGENDIAN | ||
110 | num = (num << 8) | (num >> 8); | ||
111 | #endif | ||
112 | memcpy(dest, &num, sizeof(uint16_t)); | ||
113 | } | ||
114 | |||
115 | void lendian_bytes_to_host16(uint16_t *dest, const uint8_t *lendian) | ||
116 | { | ||
117 | uint16_t d; | ||
118 | memcpy(&d, lendian, sizeof(uint16_t)); | ||
119 | #ifdef WORDS_BIGENDIAN | ||
120 | d = (d << 8) | (d >> 8); | ||
121 | #endif | ||
122 | *dest = d; | ||
123 | } | ||
diff --git a/toxcore/state.h b/toxcore/state.h index 2d1f62c3..872b1e9d 100644 --- a/toxcore/state.h +++ b/toxcore/state.h | |||
@@ -18,6 +18,22 @@ | |||
18 | extern "C" { | 18 | extern "C" { |
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | #define STATE_COOKIE_GLOBAL 0x15ed1b1f | ||
22 | |||
23 | #define STATE_COOKIE_TYPE 0x01ce | ||
24 | |||
25 | typedef enum State_Type { | ||
26 | STATE_TYPE_NOSPAMKEYS = 1, | ||
27 | STATE_TYPE_DHT = 2, | ||
28 | STATE_TYPE_FRIENDS = 3, | ||
29 | STATE_TYPE_NAME = 4, | ||
30 | STATE_TYPE_STATUSMESSAGE = 5, | ||
31 | STATE_TYPE_STATUS = 6, | ||
32 | STATE_TYPE_TCP_RELAY = 10, | ||
33 | STATE_TYPE_PATH_NODE = 11, | ||
34 | STATE_TYPE_END = 255, | ||
35 | } State_Type; | ||
36 | |||
21 | // Returned by the state_load_cb to instruct the loader on what to do next. | 37 | // Returned by the state_load_cb to instruct the loader on what to do next. |
22 | typedef enum State_Load_Status { | 38 | typedef enum State_Load_Status { |
23 | // Continue loading state data sections. | 39 | // Continue loading state data sections. |
@@ -39,10 +55,13 @@ uint8_t *state_write_section_header(uint8_t *data, uint16_t cookie_type, uint32_ | |||
39 | // Utilities for state data serialisation. | 55 | // Utilities for state data serialisation. |
40 | 56 | ||
41 | uint16_t lendian_to_host16(uint16_t lendian); | 57 | uint16_t lendian_to_host16(uint16_t lendian); |
42 | uint16_t host_tolendian16(uint16_t host); | 58 | uint16_t host_to_lendian16(uint16_t host); |
59 | |||
60 | void host_to_lendian_bytes32(uint8_t *dest, uint32_t num); | ||
61 | void lendian_bytes_to_host32(uint32_t *dest, const uint8_t *lendian); | ||
43 | 62 | ||
44 | void host_to_lendian32(uint8_t *dest, uint32_t num); | 63 | void host_to_lendian_bytes16(uint8_t *dest, uint16_t num); |
45 | void lendian_to_host32(uint32_t *dest, const uint8_t *lendian); | 64 | void lendian_bytes_to_host16(uint16_t *dest, const uint8_t *lendian); |
46 | 65 | ||
47 | #ifdef __cplusplus | 66 | #ifdef __cplusplus |
48 | } // extern "C" | 67 | } // extern "C" |
diff --git a/toxcore/tox.c b/toxcore/tox.c index e679a168..629cc1c5 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c | |||
@@ -328,6 +328,51 @@ bool tox_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch) | |||
328 | return TOX_VERSION_IS_API_COMPATIBLE(major, minor, patch); | 328 | return TOX_VERSION_IS_API_COMPATIBLE(major, minor, patch); |
329 | } | 329 | } |
330 | 330 | ||
331 | static State_Load_Status state_load_callback(void *outer, const uint8_t *data, uint32_t length, uint16_t type) | ||
332 | { | ||
333 | Tox *tox = (Tox *)outer; | ||
334 | State_Load_Status status = STATE_LOAD_STATUS_CONTINUE; | ||
335 | |||
336 | if (messenger_load_state_section(tox->m, data, length, type, &status) | ||
337 | || conferences_load_state_section(tox->m->conferences_object, data, length, type, &status)) { | ||
338 | return status; | ||
339 | } | ||
340 | |||
341 | if (type == STATE_TYPE_END) { | ||
342 | if (length != 0) { | ||
343 | return STATE_LOAD_STATUS_ERROR; | ||
344 | } | ||
345 | |||
346 | return STATE_LOAD_STATUS_END; | ||
347 | } | ||
348 | |||
349 | LOGGER_ERROR(tox->m->log, "Load state: contains unrecognized part (len %u, type %u)\n", | ||
350 | length, type); | ||
351 | |||
352 | return STATE_LOAD_STATUS_CONTINUE; | ||
353 | } | ||
354 | |||
355 | /* Load tox from data of size length. */ | ||
356 | static int tox_load(Tox *tox, const uint8_t *data, uint32_t length) | ||
357 | { | ||
358 | uint32_t data32[2]; | ||
359 | uint32_t cookie_len = sizeof(data32); | ||
360 | |||
361 | if (length < cookie_len) { | ||
362 | return -1; | ||
363 | } | ||
364 | |||
365 | memcpy(data32, data, sizeof(uint32_t)); | ||
366 | lendian_bytes_to_host32(data32 + 1, data + sizeof(uint32_t)); | ||
367 | |||
368 | if (data32[0] != 0 || data32[1] != STATE_COOKIE_GLOBAL) { | ||
369 | return -1; | ||
370 | } | ||
371 | |||
372 | return state_load(tox->m->log, state_load_callback, tox, data + cookie_len, | ||
373 | length - cookie_len, STATE_COOKIE_TYPE); | ||
374 | } | ||
375 | |||
331 | 376 | ||
332 | Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) | 377 | Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) |
333 | { | 378 | { |
@@ -488,7 +533,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) | |||
488 | } | 533 | } |
489 | 534 | ||
490 | if (load_savedata_tox | 535 | if (load_savedata_tox |
491 | && messenger_load(m, tox_options_get_savedata_data(opts), tox_options_get_savedata_length(opts)) == -1) { | 536 | && tox_load(tox, tox_options_get_savedata_data(opts), tox_options_get_savedata_length(opts)) == -1) { |
492 | SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); | 537 | SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); |
493 | } else if (load_savedata_sk) { | 538 | } else if (load_savedata_sk) { |
494 | load_secret_key(m->net_crypto, tox_options_get_savedata_data(opts)); | 539 | load_secret_key(m->net_crypto, tox_options_get_savedata_data(opts)); |
@@ -537,18 +582,45 @@ void tox_kill(Tox *tox) | |||
537 | free(tox); | 582 | free(tox); |
538 | } | 583 | } |
539 | 584 | ||
585 | static uint32_t end_size(void) | ||
586 | { | ||
587 | return 2 * sizeof(uint32_t); | ||
588 | } | ||
589 | |||
590 | static void end_save(uint8_t *data) | ||
591 | { | ||
592 | state_write_section_header(data, STATE_COOKIE_TYPE, 0, STATE_TYPE_END); | ||
593 | } | ||
594 | |||
540 | size_t tox_get_savedata_size(const Tox *tox) | 595 | size_t tox_get_savedata_size(const Tox *tox) |
541 | { | 596 | { |
542 | const Messenger *m = tox->m; | 597 | const Messenger *m = tox->m; |
543 | return messenger_size(m); | 598 | return 2 * sizeof(uint32_t) |
599 | + messenger_size(m) | ||
600 | + conferences_size(m->conferences_object) | ||
601 | + end_size(); | ||
544 | } | 602 | } |
545 | 603 | ||
546 | void tox_get_savedata(const Tox *tox, uint8_t *savedata) | 604 | void tox_get_savedata(const Tox *tox, uint8_t *savedata) |
547 | { | 605 | { |
548 | if (savedata) { | 606 | if (savedata == nullptr) { |
549 | const Messenger *m = tox->m; | 607 | return; |
550 | messenger_save(m, savedata); | ||
551 | } | 608 | } |
609 | |||
610 | memset(savedata, 0, tox_get_savedata_size(tox)); | ||
611 | |||
612 | const uint32_t size32 = sizeof(uint32_t); | ||
613 | |||
614 | // write cookie | ||
615 | memset(savedata, 0, size32); | ||
616 | savedata += size32; | ||
617 | host_to_lendian_bytes32(savedata, STATE_COOKIE_GLOBAL); | ||
618 | savedata += size32; | ||
619 | |||
620 | const Messenger *m = tox->m; | ||
621 | savedata = messenger_save(m, savedata); | ||
622 | savedata = conferences_save(m->conferences_object, savedata); | ||
623 | end_save(savedata); | ||
552 | } | 624 | } |
553 | 625 | ||
554 | bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *public_key, Tox_Err_Bootstrap *error) | 626 | bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *public_key, Tox_Err_Bootstrap *error) |