diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | other/monolith.h | 1 | ||||
-rw-r--r-- | toxcore/BUILD.bazel | 13 | ||||
-rw-r--r-- | toxcore/DHT.c | 7 | ||||
-rw-r--r-- | toxcore/Makefile.inc | 2 | ||||
-rw-r--r-- | toxcore/Messenger.c | 15 | ||||
-rw-r--r-- | toxcore/state.c | 90 | ||||
-rw-r--r-- | toxcore/state.h | 49 | ||||
-rw-r--r-- | toxcore/util.c | 79 | ||||
-rw-r--r-- | toxcore/util.h | 11 |
10 files changed, 168 insertions, 101 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 502a6172..d3266e2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
@@ -173,6 +173,8 @@ set(toxcore_SOURCES ${toxcore_SOURCES} | |||
173 | toxcore/logger.h | 173 | toxcore/logger.h |
174 | toxcore/network.c | 174 | toxcore/network.c |
175 | toxcore/network.h | 175 | toxcore/network.h |
176 | toxcore/state.c | ||
177 | toxcore/state.h | ||
176 | toxcore/util.c | 178 | toxcore/util.c |
177 | toxcore/util.h) | 179 | toxcore/util.h) |
178 | 180 | ||
diff --git a/other/monolith.h b/other/monolith.h index 42b6b6be..426ba0d9 100644 --- a/other/monolith.h +++ b/other/monolith.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #include "../toxcore/onion_client.c" | 20 | #include "../toxcore/onion_client.c" |
21 | #include "../toxcore/ping.c" | 21 | #include "../toxcore/ping.c" |
22 | #include "../toxcore/ping_array.c" | 22 | #include "../toxcore/ping_array.c" |
23 | #include "../toxcore/state.c" | ||
23 | #include "../toxcore/tox_api.c" | 24 | #include "../toxcore/tox_api.c" |
24 | #include "../toxcore/util.c" | 25 | #include "../toxcore/util.c" |
25 | 26 | ||
diff --git a/toxcore/BUILD.bazel b/toxcore/BUILD.bazel index 1d43d828..381a1255 100644 --- a/toxcore/BUILD.bazel +++ b/toxcore/BUILD.bazel | |||
@@ -52,6 +52,13 @@ cc_library( | |||
52 | ) | 52 | ) |
53 | 53 | ||
54 | cc_library( | 54 | cc_library( |
55 | name = "state", | ||
56 | srcs = ["state.c"], | ||
57 | hdrs = ["state.h"], | ||
58 | deps = [":logger"], | ||
59 | ) | ||
60 | |||
61 | cc_library( | ||
55 | name = "network", | 62 | name = "network", |
56 | srcs = [ | 63 | srcs = [ |
57 | "network.c", | 64 | "network.c", |
@@ -106,6 +113,7 @@ cc_library( | |||
106 | ":crypto_core", | 113 | ":crypto_core", |
107 | ":logger", | 114 | ":logger", |
108 | ":ping_array", | 115 | ":ping_array", |
116 | ":state", | ||
109 | ], | 117 | ], |
110 | ) | 118 | ) |
111 | 119 | ||
@@ -190,7 +198,10 @@ cc_library( | |||
190 | srcs = ["Messenger.c"], | 198 | srcs = ["Messenger.c"], |
191 | hdrs = ["Messenger.h"], | 199 | hdrs = ["Messenger.h"], |
192 | visibility = ["//c-toxcore/toxav:__pkg__"], | 200 | visibility = ["//c-toxcore/toxav:__pkg__"], |
193 | deps = [":friend_requests"], | 201 | deps = [ |
202 | ":friend_requests", | ||
203 | ":state", | ||
204 | ], | ||
194 | ) | 205 | ) |
195 | 206 | ||
196 | cc_library( | 207 | cc_library( |
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 6c104a73..fe3c1159 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "logger.h" | 31 | #include "logger.h" |
32 | #include "network.h" | 32 | #include "network.h" |
33 | #include "ping.h" | 33 | #include "ping.h" |
34 | #include "state.h" | ||
34 | #include "util.h" | 35 | #include "util.h" |
35 | 36 | ||
36 | #include <assert.h> | 37 | #include <assert.h> |
@@ -2887,7 +2888,7 @@ int dht_connect_after_load(DHT *dht) | |||
2887 | return 0; | 2888 | return 0; |
2888 | } | 2889 | } |
2889 | 2890 | ||
2890 | static int dht_load_state_callback(void *outer, const uint8_t *data, uint32_t length, uint16_t type) | 2891 | static State_Load_Status dht_load_state_callback(void *outer, const uint8_t *data, uint32_t length, uint16_t type) |
2891 | { | 2892 | { |
2892 | DHT *dht = (DHT *)outer; | 2893 | DHT *dht = (DHT *)outer; |
2893 | 2894 | ||
@@ -2918,7 +2919,7 @@ static int dht_load_state_callback(void *outer, const uint8_t *data, uint32_t le | |||
2918 | break; | 2919 | break; |
2919 | } | 2920 | } |
2920 | 2921 | ||
2921 | return 0; | 2922 | return STATE_LOAD_STATUS_CONTINUE; |
2922 | } | 2923 | } |
2923 | 2924 | ||
2924 | /* Load the DHT from data of size size. | 2925 | /* Load the DHT from data of size size. |
@@ -2935,7 +2936,7 @@ int dht_load(DHT *dht, const uint8_t *data, uint32_t length) | |||
2935 | lendian_to_host32(&data32, data); | 2936 | lendian_to_host32(&data32, data); |
2936 | 2937 | ||
2937 | if (data32 == DHT_STATE_COOKIE_GLOBAL) { | 2938 | if (data32 == DHT_STATE_COOKIE_GLOBAL) { |
2938 | return load_state(dht_load_state_callback, dht->log, dht, data + cookie_len, | 2939 | return state_load(dht->log, dht_load_state_callback, dht, data + cookie_len, |
2939 | length - cookie_len, DHT_STATE_COOKIE_TYPE); | 2940 | length - cookie_len, DHT_STATE_COOKIE_TYPE); |
2940 | } | 2941 | } |
2941 | } | 2942 | } |
diff --git a/toxcore/Makefile.inc b/toxcore/Makefile.inc index 2ca25650..4a007a66 100644 --- a/toxcore/Makefile.inc +++ b/toxcore/Makefile.inc | |||
@@ -27,6 +27,8 @@ libtoxcore_la_SOURCES = ../toxcore/ccompat.h \ | |||
27 | ../toxcore/Messenger.c \ | 27 | ../toxcore/Messenger.c \ |
28 | ../toxcore/ping.h \ | 28 | ../toxcore/ping.h \ |
29 | ../toxcore/ping.c \ | 29 | ../toxcore/ping.c \ |
30 | ../toxcore/state.h \ | ||
31 | ../toxcore/state.c \ | ||
30 | ../toxcore/tox.h \ | 32 | ../toxcore/tox.h \ |
31 | ../toxcore/tox.c \ | 33 | ../toxcore/tox.c \ |
32 | ../toxcore/tox_api.c \ | 34 | ../toxcore/tox_api.c \ |
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 9014d56d..404827c6 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #include "logger.h" | 36 | #include "logger.h" |
37 | #include "network.h" | 37 | #include "network.h" |
38 | #include "state.h" | ||
38 | #include "util.h" | 39 | #include "util.h" |
39 | 40 | ||
40 | static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_t packet_id, const uint8_t *data, | 41 | static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_t packet_id, const uint8_t *data, |
@@ -3075,7 +3076,7 @@ void messenger_save(const Messenger *m, uint8_t *data) | |||
3075 | messenger_save_subheader(data, 0, MESSENGER_STATE_TYPE_END); | 3076 | messenger_save_subheader(data, 0, MESSENGER_STATE_TYPE_END); |
3076 | } | 3077 | } |
3077 | 3078 | ||
3078 | static int messenger_load_state_callback(void *outer, const uint8_t *data, uint32_t length, uint16_t type) | 3079 | static State_Load_Status messenger_load_state_callback(void *outer, const uint8_t *data, uint32_t length, uint16_t type) |
3079 | { | 3080 | { |
3080 | Messenger *m = (Messenger *)outer; | 3081 | Messenger *m = (Messenger *)outer; |
3081 | 3082 | ||
@@ -3086,10 +3087,10 @@ static int messenger_load_state_callback(void *outer, const uint8_t *data, uint3 | |||
3086 | load_secret_key(m->net_crypto, (&data[sizeof(uint32_t)]) + CRYPTO_PUBLIC_KEY_SIZE); | 3087 | load_secret_key(m->net_crypto, (&data[sizeof(uint32_t)]) + CRYPTO_PUBLIC_KEY_SIZE); |
3087 | 3088 | ||
3088 | if (public_key_cmp((&data[sizeof(uint32_t)]), nc_get_self_public_key(m->net_crypto)) != 0) { | 3089 | if (public_key_cmp((&data[sizeof(uint32_t)]), nc_get_self_public_key(m->net_crypto)) != 0) { |
3089 | return -1; | 3090 | return STATE_LOAD_STATUS_ERROR; |
3090 | } | 3091 | } |
3091 | } else { | 3092 | } else { |
3092 | return -1; /* critical */ | 3093 | return STATE_LOAD_STATUS_ERROR; /* critical */ |
3093 | } | 3094 | } |
3094 | 3095 | ||
3095 | break; | 3096 | break; |
@@ -3152,10 +3153,10 @@ static int messenger_load_state_callback(void *outer, const uint8_t *data, uint3 | |||
3152 | 3153 | ||
3153 | case MESSENGER_STATE_TYPE_END: { | 3154 | case MESSENGER_STATE_TYPE_END: { |
3154 | if (length != 0) { | 3155 | if (length != 0) { |
3155 | return -1; | 3156 | return STATE_LOAD_STATUS_ERROR; |
3156 | } | 3157 | } |
3157 | 3158 | ||
3158 | return -2; | 3159 | return STATE_LOAD_STATUS_END; |
3159 | } | 3160 | } |
3160 | 3161 | ||
3161 | default: | 3162 | default: |
@@ -3164,7 +3165,7 @@ static int messenger_load_state_callback(void *outer, const uint8_t *data, uint3 | |||
3164 | break; | 3165 | break; |
3165 | } | 3166 | } |
3166 | 3167 | ||
3167 | return 0; | 3168 | return STATE_LOAD_STATUS_CONTINUE; |
3168 | } | 3169 | } |
3169 | 3170 | ||
3170 | /* Load the messenger from data of size length. */ | 3171 | /* Load the messenger from data of size length. */ |
@@ -3181,7 +3182,7 @@ int messenger_load(Messenger *m, const uint8_t *data, uint32_t length) | |||
3181 | lendian_to_host32(data32 + 1, data + sizeof(uint32_t)); | 3182 | lendian_to_host32(data32 + 1, data + sizeof(uint32_t)); |
3182 | 3183 | ||
3183 | if (!data32[0] && (data32[1] == MESSENGER_STATE_COOKIE_GLOBAL)) { | 3184 | if (!data32[0] && (data32[1] == MESSENGER_STATE_COOKIE_GLOBAL)) { |
3184 | return load_state(messenger_load_state_callback, m->log, m, data + cookie_len, | 3185 | return state_load(m->log, messenger_load_state_callback, m, data + cookie_len, |
3185 | length - cookie_len, MESSENGER_STATE_COOKIE_TYPE); | 3186 | length - cookie_len, MESSENGER_STATE_COOKIE_TYPE); |
3186 | } | 3187 | } |
3187 | 3188 | ||
diff --git a/toxcore/state.c b/toxcore/state.c new file mode 100644 index 00000000..8da061f4 --- /dev/null +++ b/toxcore/state.c | |||
@@ -0,0 +1,90 @@ | |||
1 | #include "state.h" | ||
2 | |||
3 | #include <string.h> | ||
4 | |||
5 | /* state load/save */ | ||
6 | int state_load(const Logger *log, state_load_cb *state_load_callback, void *outer, | ||
7 | const uint8_t *data, uint32_t length, uint16_t cookie_inner) | ||
8 | { | ||
9 | if (state_load_callback == nullptr || data == nullptr) { | ||
10 | LOGGER_ERROR(log, "state_load() called with invalid args.\n"); | ||
11 | return -1; | ||
12 | } | ||
13 | |||
14 | |||
15 | const uint32_t size_head = sizeof(uint32_t) * 2; | ||
16 | |||
17 | while (length >= size_head) { | ||
18 | uint32_t length_sub; | ||
19 | lendian_to_host32(&length_sub, data); | ||
20 | |||
21 | uint32_t cookie_type; | ||
22 | lendian_to_host32(&cookie_type, data + sizeof(uint32_t)); | ||
23 | |||
24 | data += size_head; | ||
25 | length -= size_head; | ||
26 | |||
27 | if (length < length_sub) { | ||
28 | /* file truncated */ | ||
29 | LOGGER_ERROR(log, "state file too short: %u < %u\n", length, length_sub); | ||
30 | return -1; | ||
31 | } | ||
32 | |||
33 | if (lendian_to_host16((cookie_type >> 16)) != cookie_inner) { | ||
34 | /* something is not matching up in a bad way, give up */ | ||
35 | LOGGER_ERROR(log, "state file garbled: %04x != %04x\n", cookie_type >> 16, cookie_inner); | ||
36 | return -1; | ||
37 | } | ||
38 | |||
39 | const uint16_t type = lendian_to_host16(cookie_type & 0xFFFF); | ||
40 | |||
41 | switch (state_load_callback(outer, data, length_sub, type)) { | ||
42 | case STATE_LOAD_STATUS_CONTINUE: | ||
43 | data += length_sub; | ||
44 | length -= length_sub; | ||
45 | break; | ||
46 | |||
47 | case STATE_LOAD_STATUS_ERROR: | ||
48 | return -1; | ||
49 | |||
50 | case STATE_LOAD_STATUS_END: | ||
51 | return 0; | ||
52 | } | ||
53 | } | ||
54 | |||
55 | if (length != 0) { | ||
56 | LOGGER_ERROR(log, "unparsed data in state file of length %u\n", length); | ||
57 | return -1; | ||
58 | } | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | uint16_t lendian_to_host16(uint16_t lendian) | ||
64 | { | ||
65 | #ifdef WORDS_BIGENDIAN | ||
66 | return (lendian << 8) | (lendian >> 8); | ||
67 | #else | ||
68 | return lendian; | ||
69 | #endif | ||
70 | } | ||
71 | |||
72 | void host_to_lendian32(uint8_t *dest, uint32_t num) | ||
73 | { | ||
74 | #ifdef WORDS_BIGENDIAN | ||
75 | num = ((num << 8) & 0xFF00FF00) | ((num >> 8) & 0xFF00FF); | ||
76 | num = (num << 16) | (num >> 16); | ||
77 | #endif | ||
78 | memcpy(dest, &num, sizeof(uint32_t)); | ||
79 | } | ||
80 | |||
81 | void lendian_to_host32(uint32_t *dest, const uint8_t *lendian) | ||
82 | { | ||
83 | uint32_t d; | ||
84 | memcpy(&d, lendian, sizeof(uint32_t)); | ||
85 | #ifdef WORDS_BIGENDIAN | ||
86 | d = ((d << 8) & 0xFF00FF00) | ((d >> 8) & 0xFF00FF); | ||
87 | d = (d << 16) | (d >> 16); | ||
88 | #endif | ||
89 | *dest = d; | ||
90 | } | ||
diff --git a/toxcore/state.h b/toxcore/state.h new file mode 100644 index 00000000..3f7ff043 --- /dev/null +++ b/toxcore/state.h | |||
@@ -0,0 +1,49 @@ | |||
1 | /** | ||
2 | * The state module is responsible for parsing the Tox save data format and for | ||
3 | * saving state in that format. | ||
4 | * | ||
5 | * This module provides functions for iterating over serialised data sections | ||
6 | * and reading/writing numbers in the correct format (little endian). | ||
7 | * | ||
8 | * Note that unlike the Tox network protocol, the save data stores its values in | ||
9 | * little endian, which is native to most desktop and server architectures in | ||
10 | * 2018. | ||
11 | */ | ||
12 | #ifndef C_TOXCORE_TOXCORE_STATE_H | ||
13 | #define C_TOXCORE_TOXCORE_STATE_H | ||
14 | |||
15 | #include "logger.h" | ||
16 | |||
17 | #ifdef __cplusplus | ||
18 | extern "C" { | ||
19 | #endif | ||
20 | |||
21 | // Returned by the state_load_cb to instruct the loader on what to do next. | ||
22 | typedef enum State_Load_Status { | ||
23 | // Continue loading state data sections. | ||
24 | STATE_LOAD_STATUS_CONTINUE, | ||
25 | // An error occurred. Stop loading sections. | ||
26 | STATE_LOAD_STATUS_ERROR, | ||
27 | // We're at the end of the save data, terminate loading successfully. | ||
28 | STATE_LOAD_STATUS_END, | ||
29 | } State_Load_Status; | ||
30 | |||
31 | typedef State_Load_Status state_load_cb(void *outer, const uint8_t *data, uint32_t len, uint16_t type); | ||
32 | |||
33 | // state load/save | ||
34 | int state_load(const Logger *log, state_load_cb *state_load_callback, void *outer, | ||
35 | const uint8_t *data, uint32_t length, uint16_t cookie_inner); | ||
36 | |||
37 | // Utilities for state data serialisation. | ||
38 | |||
39 | uint16_t lendian_to_host16(uint16_t lendian); | ||
40 | #define host_tolendian16(x) lendian_to_host16(x) | ||
41 | |||
42 | void host_to_lendian32(uint8_t *dest, uint32_t num); | ||
43 | void lendian_to_host32(uint32_t *dest, const uint8_t *lendian); | ||
44 | |||
45 | #ifdef __cplusplus | ||
46 | } // extern "C" | ||
47 | #endif | ||
48 | |||
49 | #endif // C_TOXCORE_TOXCORE_STATE_H | ||
diff --git a/toxcore/util.c b/toxcore/util.c index 57d1762e..aa2786dd 100644 --- a/toxcore/util.c +++ b/toxcore/util.c | |||
@@ -92,85 +92,6 @@ void host_to_net(uint8_t *num, uint16_t numbytes) | |||
92 | #endif | 92 | #endif |
93 | } | 93 | } |
94 | 94 | ||
95 | uint16_t lendian_to_host16(uint16_t lendian) | ||
96 | { | ||
97 | #ifdef WORDS_BIGENDIAN | ||
98 | return (lendian << 8) | (lendian >> 8); | ||
99 | #else | ||
100 | return lendian; | ||
101 | #endif | ||
102 | } | ||
103 | |||
104 | void host_to_lendian32(uint8_t *dest, uint32_t num) | ||
105 | { | ||
106 | #ifdef WORDS_BIGENDIAN | ||
107 | num = ((num << 8) & 0xFF00FF00) | ((num >> 8) & 0xFF00FF); | ||
108 | num = (num << 16) | (num >> 16); | ||
109 | #endif | ||
110 | memcpy(dest, &num, sizeof(uint32_t)); | ||
111 | } | ||
112 | |||
113 | void lendian_to_host32(uint32_t *dest, const uint8_t *lendian) | ||
114 | { | ||
115 | uint32_t d; | ||
116 | memcpy(&d, lendian, sizeof(uint32_t)); | ||
117 | #ifdef WORDS_BIGENDIAN | ||
118 | d = ((d << 8) & 0xFF00FF00) | ((d >> 8) & 0xFF00FF); | ||
119 | d = (d << 16) | (d >> 16); | ||
120 | #endif | ||
121 | *dest = d; | ||
122 | } | ||
123 | |||
124 | /* state load/save */ | ||
125 | int load_state(load_state_callback_func load_state_callback, const Logger *log, void *outer, | ||
126 | const uint8_t *data, uint32_t length, uint16_t cookie_inner) | ||
127 | { | ||
128 | if (!load_state_callback || !data) { | ||
129 | LOGGER_ERROR(log, "load_state() called with invalid args.\n"); | ||
130 | return -1; | ||
131 | } | ||
132 | |||
133 | |||
134 | uint32_t length_sub, cookie_type; | ||
135 | uint32_t size_head = sizeof(uint32_t) * 2; | ||
136 | |||
137 | while (length >= size_head) { | ||
138 | lendian_to_host32(&length_sub, data); | ||
139 | lendian_to_host32(&cookie_type, data + sizeof(length_sub)); | ||
140 | data += size_head; | ||
141 | length -= size_head; | ||
142 | |||
143 | if (length < length_sub) { | ||
144 | /* file truncated */ | ||
145 | LOGGER_ERROR(log, "state file too short: %u < %u\n", length, length_sub); | ||
146 | return -1; | ||
147 | } | ||
148 | |||
149 | if (lendian_to_host16((cookie_type >> 16)) != cookie_inner) { | ||
150 | /* something is not matching up in a bad way, give up */ | ||
151 | LOGGER_ERROR(log, "state file garbled: %04x != %04x\n", (cookie_type >> 16), cookie_inner); | ||
152 | return -1; | ||
153 | } | ||
154 | |||
155 | const uint16_t type = lendian_to_host16(cookie_type & 0xFFFF); | ||
156 | const int ret = load_state_callback(outer, data, length_sub, type); | ||
157 | |||
158 | if (ret == -1) { | ||
159 | return -1; | ||
160 | } | ||
161 | |||
162 | /* -2 means end of save. */ | ||
163 | if (ret == -2) { | ||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | data += length_sub; | ||
168 | length -= length_sub; | ||
169 | } | ||
170 | |||
171 | return length == 0 ? 0 : -1; | ||
172 | } | ||
173 | |||
174 | int create_recursive_mutex(pthread_mutex_t *mutex) | 95 | int create_recursive_mutex(pthread_mutex_t *mutex) |
175 | { | 96 | { |
176 | pthread_mutexattr_t attr; | 97 | pthread_mutexattr_t attr; |
diff --git a/toxcore/util.h b/toxcore/util.h index 3979cefe..c4d55f12 100644 --- a/toxcore/util.h +++ b/toxcore/util.h | |||
@@ -51,17 +51,6 @@ uint32_t id_copy(uint8_t *dest, const uint8_t *src); /* return value is CLIENT_I | |||
51 | void host_to_net(uint8_t *num, uint16_t numbytes); | 51 | void host_to_net(uint8_t *num, uint16_t numbytes); |
52 | #define net_to_host(x, y) host_to_net(x, y) | 52 | #define net_to_host(x, y) host_to_net(x, y) |
53 | 53 | ||
54 | uint16_t lendian_to_host16(uint16_t lendian); | ||
55 | #define host_tolendian16(x) lendian_to_host16(x) | ||
56 | |||
57 | void host_to_lendian32(uint8_t *dest, uint32_t num); | ||
58 | void lendian_to_host32(uint32_t *dest, const uint8_t *lendian); | ||
59 | |||
60 | /* state load/save */ | ||
61 | typedef int (*load_state_callback_func)(void *outer, const uint8_t *data, uint32_t len, uint16_t type); | ||
62 | int load_state(load_state_callback_func load_state_callback, const Logger *log, void *outer, | ||
63 | const uint8_t *data, uint32_t length, uint16_t cookie_inner); | ||
64 | |||
65 | /* Returns -1 if failed or 0 if success */ | 54 | /* Returns -1 if failed or 0 if success */ |
66 | int create_recursive_mutex(pthread_mutex_t *mutex); | 55 | int create_recursive_mutex(pthread_mutex_t *mutex); |
67 | 56 | ||