summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--other/monolith.h1
-rw-r--r--toxcore/BUILD.bazel13
-rw-r--r--toxcore/DHT.c7
-rw-r--r--toxcore/Makefile.inc2
-rw-r--r--toxcore/Messenger.c15
-rw-r--r--toxcore/state.c90
-rw-r--r--toxcore/state.h49
-rw-r--r--toxcore/util.c79
-rw-r--r--toxcore/util.h11
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
54cc_library( 54cc_library(
55 name = "state",
56 srcs = ["state.c"],
57 hdrs = ["state.h"],
58 deps = [":logger"],
59)
60
61cc_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
196cc_library( 207cc_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
2890static int dht_load_state_callback(void *outer, const uint8_t *data, uint32_t length, uint16_t type) 2891static 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
40static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_t packet_id, const uint8_t *data, 41static 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
3078static int messenger_load_state_callback(void *outer, const uint8_t *data, uint32_t length, uint16_t type) 3079static 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 */
6int 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
63uint16_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
72void 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
81void 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
18extern "C" {
19#endif
20
21// Returned by the state_load_cb to instruct the loader on what to do next.
22typedef 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
31typedef State_Load_Status state_load_cb(void *outer, const uint8_t *data, uint32_t len, uint16_t type);
32
33// state load/save
34int 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
39uint16_t lendian_to_host16(uint16_t lendian);
40#define host_tolendian16(x) lendian_to_host16(x)
41
42void host_to_lendian32(uint8_t *dest, uint32_t num);
43void 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
95uint16_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
104void 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
113void 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 */
125int 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
174int create_recursive_mutex(pthread_mutex_t *mutex) 95int 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
51void host_to_net(uint8_t *num, uint16_t numbytes); 51void 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
54uint16_t lendian_to_host16(uint16_t lendian);
55#define host_tolendian16(x) lendian_to_host16(x)
56
57void host_to_lendian32(uint8_t *dest, uint32_t num);
58void lendian_to_host32(uint32_t *dest, const uint8_t *lendian);
59
60/* state load/save */
61typedef int (*load_state_callback_func)(void *outer, const uint8_t *data, uint32_t len, uint16_t type);
62int 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 */
66int create_recursive_mutex(pthread_mutex_t *mutex); 55int create_recursive_mutex(pthread_mutex_t *mutex);
67 56