/work/auto_tests/TCP_test.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include <errno.h> |
2 | | #include <stdlib.h> |
3 | | #include <string.h> |
4 | | |
5 | | #include "../testing/misc_tools.h" |
6 | | #include "../toxcore/TCP_client.h" |
7 | | #include "../toxcore/TCP_common.h" |
8 | | #include "../toxcore/TCP_server.h" |
9 | | #include "../toxcore/crypto_core.h" |
10 | | #include "../toxcore/mono_time.h" |
11 | | #include "../toxcore/util.h" |
12 | | #include "auto_test_support.h" |
13 | | |
14 | 21 | #define NUM_PORTS 3 |
15 | | |
16 | | #ifndef USE_IPV6 |
17 | | #define USE_IPV6 1 |
18 | | #endif |
19 | | |
20 | | #if !USE_IPV6 |
21 | 6 | #define net_family_ipv6 net_family_ipv4 |
22 | | #endif |
23 | | |
24 | | static IP get_loopback(void) |
25 | 96 | { |
26 | 96 | IP ip; |
27 | | #if USE_IPV6 |
28 | | ip.family = net_family_ipv6(); |
29 | | ip.ip.v6 = get_ip6_loopback(); |
30 | | #else |
31 | 96 | ip.family = net_family_ipv4(); |
32 | 96 | ip.ip.v4 = get_ip4_loopback(); |
33 | 96 | #endif |
34 | 96 | return ip; |
35 | 96 | } |
36 | | |
37 | | static void do_tcp_server_delay(TCP_Server *tcp_s, Mono_Time *mono_time, int delay) |
38 | 29 | { |
39 | 29 | c_sleep(delay); |
40 | 29 | mono_time_update(mono_time); |
41 | 29 | do_tcp_server(tcp_s, mono_time); |
42 | 29 | c_sleep(delay); |
43 | 29 | } |
44 | | static uint16_t ports[NUM_PORTS] = {13215, 33445, 25643}; |
45 | | |
46 | | static void test_basic(void) |
47 | 1 | { |
48 | 1 | const Random *rng = os_random(); |
49 | 1 | ck_assert(rng != nullptr); |
50 | 1 | const Network *ns = os_network(); |
51 | 1 | ck_assert(ns != nullptr); |
52 | 1 | const Memory *mem = os_memory(); |
53 | 1 | ck_assert(mem != nullptr); |
54 | | |
55 | 1 | Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); |
56 | 1 | Logger *logger = logger_new(); |
57 | 1 | logger_callback_log(logger, print_debug_logger, nullptr, nullptr); |
58 | | |
59 | | // Attempt to create a new TCP_Server instance. |
60 | 1 | uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; |
61 | 1 | uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; |
62 | 1 | crypto_new_keypair(rng, self_public_key, self_secret_key); |
63 | 1 | TCP_Server *tcp_s = new_tcp_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); |
64 | 1 | ck_assert_msg(tcp_s != nullptr, "Failed to create a TCP relay server."); |
65 | 1 | ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, |
66 | 1 | "Failed to bind a TCP relay server to all %d attempted ports.", NUM_PORTS); |
67 | | |
68 | 1 | Socket sock = {0}; |
69 | 1 | IP_Port localhost; |
70 | 1 | localhost.ip = get_loopback(); |
71 | 1 | localhost.port = 0; |
72 | | |
73 | | // Check all opened ports for connectivity. |
74 | 4 | for (uint8_t i = 0; i < NUM_PORTS; i++) { |
75 | 3 | sock = net_socket(ns, net_family_ipv6(), TOX_SOCK_STREAM, TOX_PROTO_TCP); |
76 | 3 | localhost.port = net_htons(ports[i]); |
77 | 3 | bool ret = net_connect(mem, logger, sock, &localhost); |
78 | 3 | ck_assert_msg(ret, "Failed to connect to created TCP relay server on port %d (%d).", ports[i], errno); |
79 | | |
80 | | // Leave open one connection for the next test. |
81 | 3 | if (i + 1 < NUM_PORTS) { |
82 | 2 | kill_sock(ns, sock); |
83 | 2 | } |
84 | 3 | } |
85 | | |
86 | | // Key creation. |
87 | 1 | uint8_t f_public_key[CRYPTO_PUBLIC_KEY_SIZE]; |
88 | 1 | uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE]; |
89 | 1 | uint8_t f_nonce[CRYPTO_NONCE_SIZE]; |
90 | 1 | crypto_new_keypair(rng, f_public_key, f_secret_key); |
91 | 1 | random_nonce(rng, f_nonce); |
92 | | |
93 | | // Generation of the initial handshake. |
94 | 1 | uint8_t t_secret_key[CRYPTO_SECRET_KEY_SIZE]; |
95 | 1 | uint8_t *handshake_plain = (uint8_t *)malloc(TCP_HANDSHAKE_PLAIN_SIZE); |
96 | 1 | ck_assert(handshake_plain != nullptr); |
97 | 1 | crypto_new_keypair(rng, handshake_plain, t_secret_key); |
98 | 1 | memcpy(handshake_plain + CRYPTO_PUBLIC_KEY_SIZE, f_nonce, CRYPTO_NONCE_SIZE); |
99 | 1 | uint8_t *handshake = (uint8_t *)malloc(TCP_CLIENT_HANDSHAKE_SIZE); |
100 | 1 | ck_assert(handshake != nullptr); |
101 | 1 | memcpy(handshake, f_public_key, CRYPTO_PUBLIC_KEY_SIZE); |
102 | 1 | random_nonce(rng, handshake + CRYPTO_PUBLIC_KEY_SIZE); |
103 | | |
104 | | // Encrypting handshake |
105 | 1 | int ret = encrypt_data(self_public_key, f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain, |
106 | 1 | TCP_HANDSHAKE_PLAIN_SIZE, handshake + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); |
107 | 1 | ck_assert_msg(ret == TCP_CLIENT_HANDSHAKE_SIZE - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE), |
108 | 1 | "encrypt_data() call failed."); |
109 | | |
110 | 1 | free(handshake_plain); |
111 | | |
112 | | // Sending the handshake |
113 | 1 | ck_assert_msg(net_send(ns, logger, sock, handshake, TCP_CLIENT_HANDSHAKE_SIZE - 1, |
114 | 1 | &localhost) == TCP_CLIENT_HANDSHAKE_SIZE - 1, |
115 | 1 | "An attempt to send the initial handshake minus last byte failed."); |
116 | | |
117 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
118 | | |
119 | 1 | ck_assert_msg(net_send(ns, logger, sock, handshake + (TCP_CLIENT_HANDSHAKE_SIZE - 1), 1, &localhost) == 1, |
120 | 1 | "The attempt to send the last byte of handshake failed."); |
121 | | |
122 | 1 | free(handshake); |
123 | | |
124 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
125 | | |
126 | | // Receiving server response and decrypting it |
127 | 1 | uint8_t response[TCP_SERVER_HANDSHAKE_SIZE]; |
128 | 1 | uint8_t response_plain[TCP_HANDSHAKE_PLAIN_SIZE]; |
129 | 1 | ck_assert_msg(net_recv(ns, logger, sock, response, TCP_SERVER_HANDSHAKE_SIZE, &localhost) == TCP_SERVER_HANDSHAKE_SIZE, |
130 | 1 | "Could/did not receive a server response to the initial handshake."); |
131 | 1 | ret = decrypt_data(self_public_key, f_secret_key, response, response + CRYPTO_NONCE_SIZE, |
132 | 1 | TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, response_plain); |
133 | 1 | ck_assert_msg(ret == TCP_HANDSHAKE_PLAIN_SIZE, "Failed to decrypt handshake response."); |
134 | 1 | uint8_t f_nonce_r[CRYPTO_NONCE_SIZE]; |
135 | 1 | uint8_t f_shared_key[CRYPTO_SHARED_KEY_SIZE]; |
136 | 1 | encrypt_precompute(response_plain, t_secret_key, f_shared_key); |
137 | 1 | memcpy(f_nonce_r, response_plain + CRYPTO_SHARED_KEY_SIZE, CRYPTO_NONCE_SIZE); |
138 | | |
139 | | // Building a request |
140 | 1 | uint8_t r_req_p[1 + CRYPTO_PUBLIC_KEY_SIZE]; |
141 | 1 | r_req_p[0] = TCP_PACKET_ROUTING_REQUEST; |
142 | 1 | memcpy(r_req_p + 1, f_public_key, CRYPTO_PUBLIC_KEY_SIZE); |
143 | 1 | uint8_t r_req[2 + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE]; |
144 | 1 | uint16_t size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE; |
145 | 1 | size = net_htons(size); |
146 | 1 | encrypt_data_symmetric(f_shared_key, f_nonce, r_req_p, 1 + CRYPTO_PUBLIC_KEY_SIZE, r_req + 2); |
147 | 1 | increment_nonce(f_nonce); |
148 | 1 | memcpy(r_req, &size, 2); |
149 | | |
150 | | // Sending the request at random intervals in random pieces. |
151 | 20 | for (uint32_t i = 0; i < sizeof(r_req);) { |
152 | 19 | uint8_t msg_length = rand() % 5 + 1; // msg_length = 1 to 5 |
153 | | |
154 | 19 | if (i + msg_length >= sizeof(r_req)) { |
155 | 1 | msg_length = sizeof(r_req) - i; |
156 | 1 | } |
157 | | |
158 | 19 | ck_assert_msg(net_send(ns, logger, sock, r_req + i, msg_length, &localhost) == msg_length, |
159 | 19 | "Failed to send request after completing the handshake."); |
160 | 19 | i += msg_length; |
161 | | |
162 | 19 | c_sleep(50); |
163 | 19 | mono_time_update(mono_time); |
164 | 19 | do_tcp_server(tcp_s, mono_time); |
165 | 19 | } |
166 | | |
167 | | // Receiving the second response and verifying its validity |
168 | 1 | uint8_t packet_resp[4096]; |
169 | 1 | int recv_data_len = net_recv(ns, logger, sock, packet_resp, 2 + 2 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, &localhost); |
170 | 1 | ck_assert_msg(recv_data_len == 2 + 2 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, |
171 | 1 | "Failed to receive server response to request. %d", recv_data_len); |
172 | 1 | memcpy(&size, packet_resp, 2); |
173 | 1 | ck_assert_msg(net_ntohs(size) == 2 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, |
174 | 1 | "Wrong packet size for request response."); |
175 | | |
176 | 1 | uint8_t packet_resp_plain[4096]; |
177 | 1 | ret = decrypt_data_symmetric(f_shared_key, f_nonce_r, packet_resp + 2, recv_data_len - 2, packet_resp_plain); |
178 | 1 | ck_assert_msg(ret != -1, "Failed to decrypt the TCP server's response."); |
179 | 1 | increment_nonce(f_nonce_r); |
180 | | |
181 | 1 | ck_assert_msg(packet_resp_plain[0] == TCP_PACKET_ROUTING_RESPONSE, "Server sent the wrong packet id: %u", |
182 | 1 | packet_resp_plain[0]); |
183 | 1 | ck_assert_msg(packet_resp_plain[1] == 0, "Server did not refuse the connection."); |
184 | 1 | ck_assert_msg(pk_equal(packet_resp_plain + 2, f_public_key), "Server sent the wrong public key."); |
185 | | |
186 | | // Closing connections. |
187 | 1 | kill_sock(ns, sock); |
188 | 1 | kill_tcp_server(tcp_s); |
189 | | |
190 | 1 | logger_kill(logger); |
191 | 1 | mono_time_free(mem, mono_time); |
192 | 1 | } |
193 | | |
194 | | struct sec_TCP_con { |
195 | | Socket sock; |
196 | | const Network *ns; |
197 | | const Memory *mem; |
198 | | uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; |
199 | | uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; |
200 | | uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; |
201 | | uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; |
202 | | }; |
203 | | |
204 | | static struct sec_TCP_con *new_tcp_con(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns, TCP_Server *tcp_s, Mono_Time *mono_time) |
205 | 3 | { |
206 | 3 | struct sec_TCP_con *sec_c = (struct sec_TCP_con *)malloc(sizeof(struct sec_TCP_con)); |
207 | 3 | ck_assert(sec_c != nullptr); |
208 | 3 | sec_c->ns = ns; |
209 | 3 | sec_c->mem = mem; |
210 | 3 | Socket sock = net_socket(ns, net_family_ipv6(), TOX_SOCK_STREAM, TOX_PROTO_TCP); |
211 | | |
212 | 3 | IP_Port localhost; |
213 | 3 | localhost.ip = get_loopback(); |
214 | 3 | localhost.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); |
215 | | |
216 | 3 | bool ok = net_connect(mem, logger, sock, &localhost); |
217 | 3 | ck_assert_msg(ok, "Failed to connect to the test TCP relay server."); |
218 | | |
219 | 3 | uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE]; |
220 | 3 | crypto_new_keypair(rng, sec_c->public_key, f_secret_key); |
221 | 3 | random_nonce(rng, sec_c->sent_nonce); |
222 | | |
223 | 3 | uint8_t t_secret_key[CRYPTO_SECRET_KEY_SIZE]; |
224 | 3 | uint8_t handshake_plain[TCP_HANDSHAKE_PLAIN_SIZE]; |
225 | 3 | crypto_new_keypair(rng, handshake_plain, t_secret_key); |
226 | 3 | memcpy(handshake_plain + CRYPTO_PUBLIC_KEY_SIZE, sec_c->sent_nonce, CRYPTO_NONCE_SIZE); |
227 | 3 | uint8_t handshake[TCP_CLIENT_HANDSHAKE_SIZE]; |
228 | 3 | memcpy(handshake, sec_c->public_key, CRYPTO_PUBLIC_KEY_SIZE); |
229 | 3 | random_nonce(rng, handshake + CRYPTO_PUBLIC_KEY_SIZE); |
230 | | |
231 | 3 | int ret = encrypt_data(tcp_server_public_key(tcp_s), f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain, |
232 | 3 | TCP_HANDSHAKE_PLAIN_SIZE, handshake + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); |
233 | 3 | ck_assert_msg(ret == TCP_CLIENT_HANDSHAKE_SIZE - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE), |
234 | 3 | "Failed to encrypt the outgoing handshake."); |
235 | | |
236 | 3 | ck_assert_msg(net_send(ns, logger, sock, handshake, TCP_CLIENT_HANDSHAKE_SIZE - 1, |
237 | 3 | &localhost) == TCP_CLIENT_HANDSHAKE_SIZE - 1, |
238 | 3 | "Failed to send the first portion of the handshake to the TCP relay server."); |
239 | | |
240 | 3 | do_tcp_server_delay(tcp_s, mono_time, 50); |
241 | | |
242 | 3 | ck_assert_msg(net_send(ns, logger, sock, handshake + (TCP_CLIENT_HANDSHAKE_SIZE - 1), 1, &localhost) == 1, |
243 | 3 | "Failed to send last byte of handshake."); |
244 | | |
245 | 3 | do_tcp_server_delay(tcp_s, mono_time, 50); |
246 | | |
247 | 3 | uint8_t response[TCP_SERVER_HANDSHAKE_SIZE]; |
248 | 3 | uint8_t response_plain[TCP_HANDSHAKE_PLAIN_SIZE]; |
249 | 3 | ck_assert_msg(net_recv(sec_c->ns, logger, sock, response, TCP_SERVER_HANDSHAKE_SIZE, &localhost) == TCP_SERVER_HANDSHAKE_SIZE, |
250 | 3 | "Failed to receive server handshake response."); |
251 | 3 | ret = decrypt_data(tcp_server_public_key(tcp_s), f_secret_key, response, response + CRYPTO_NONCE_SIZE, |
252 | 3 | TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, response_plain); |
253 | 3 | ck_assert_msg(ret == TCP_HANDSHAKE_PLAIN_SIZE, "Failed to decrypt server handshake response."); |
254 | 3 | encrypt_precompute(response_plain, t_secret_key, sec_c->shared_key); |
255 | 3 | memcpy(sec_c->recv_nonce, response_plain + CRYPTO_SHARED_KEY_SIZE, CRYPTO_NONCE_SIZE); |
256 | 3 | sec_c->sock = sock; |
257 | 3 | return sec_c; |
258 | 3 | } |
259 | | |
260 | | static void kill_tcp_con(struct sec_TCP_con *con) |
261 | 3 | { |
262 | 3 | kill_sock(con->ns, con->sock); |
263 | 3 | free(con); |
264 | 3 | } |
265 | | |
266 | | static int write_packet_tcp_test_connection(const Logger *logger, struct sec_TCP_con *con, const uint8_t *data, |
267 | | uint16_t length) |
268 | 9 | { |
269 | 9 | const uint16_t packet_size = sizeof(uint16_t) + length + CRYPTO_MAC_SIZE; |
270 | 9 | VLA(uint8_t, packet, packet_size); |
271 | | |
272 | 9 | uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE); |
273 | 9 | memcpy(packet, &c_length, sizeof(uint16_t)); |
274 | 9 | int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); |
275 | | |
276 | 9 | if ((unsigned int)len != (packet_size - sizeof(uint16_t))) { |
277 | 0 | return -1; |
278 | 0 | } |
279 | | |
280 | 9 | increment_nonce(con->sent_nonce); |
281 | | |
282 | 9 | IP_Port localhost; |
283 | 9 | localhost.ip = get_loopback(); |
284 | 9 | localhost.port = 0; |
285 | | |
286 | 9 | ck_assert_msg(net_send(con->ns, logger, con->sock, packet, packet_size, &localhost) == packet_size, |
287 | 9 | "Failed to send a packet."); |
288 | 9 | return 0; |
289 | 9 | } |
290 | | |
291 | | static int read_packet_sec_tcp(const Logger *logger, struct sec_TCP_con *con, uint8_t *data, uint16_t length) |
292 | 11 | { |
293 | 11 | IP_Port localhost; |
294 | 11 | localhost.ip = get_loopback(); |
295 | 11 | localhost.port = 0; |
296 | | |
297 | 11 | int rlen = net_recv(con->ns, logger, con->sock, data, length, &localhost); |
298 | 11 | ck_assert_msg(rlen == length, "Did not receive packet of correct length. Wanted %i, instead got %i", length, rlen); |
299 | 11 | rlen = decrypt_data_symmetric(con->shared_key, con->recv_nonce, data + 2, length - 2, data); |
300 | 11 | ck_assert_msg(rlen != -1, "Failed to decrypt a received packet from the Relay server."); |
301 | 11 | increment_nonce(con->recv_nonce); |
302 | 11 | return rlen; |
303 | 11 | } |
304 | | |
305 | | static void test_some(void) |
306 | 1 | { |
307 | 1 | const Random *rng = os_random(); |
308 | 1 | ck_assert(rng != nullptr); |
309 | 1 | const Network *ns = os_network(); |
310 | 1 | ck_assert(ns != nullptr); |
311 | 1 | const Memory *mem = os_memory(); |
312 | 1 | ck_assert(mem != nullptr); |
313 | | |
314 | 1 | Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); |
315 | 1 | Logger *logger = logger_new(); |
316 | | |
317 | 1 | uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; |
318 | 1 | uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; |
319 | 1 | crypto_new_keypair(rng, self_public_key, self_secret_key); |
320 | 1 | TCP_Server *tcp_s = new_tcp_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); |
321 | 1 | ck_assert_msg(tcp_s != nullptr, "Failed to create TCP relay server"); |
322 | 1 | ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind to all ports."); |
323 | | |
324 | 1 | struct sec_TCP_con *con1 = new_tcp_con(logger, mem, rng, ns, tcp_s, mono_time); |
325 | 1 | struct sec_TCP_con *con2 = new_tcp_con(logger, mem, rng, ns, tcp_s, mono_time); |
326 | 1 | struct sec_TCP_con *con3 = new_tcp_con(logger, mem, rng, ns, tcp_s, mono_time); |
327 | | |
328 | 1 | uint8_t requ_p[1 + CRYPTO_PUBLIC_KEY_SIZE]; |
329 | 1 | requ_p[0] = TCP_PACKET_ROUTING_REQUEST; |
330 | | |
331 | | // Sending wrong public keys to test server response. |
332 | 1 | memcpy(requ_p + 1, con3->public_key, CRYPTO_PUBLIC_KEY_SIZE); |
333 | 1 | write_packet_tcp_test_connection(logger, con1, requ_p, sizeof(requ_p)); |
334 | 1 | memcpy(requ_p + 1, con1->public_key, CRYPTO_PUBLIC_KEY_SIZE); |
335 | 1 | write_packet_tcp_test_connection(logger, con3, requ_p, sizeof(requ_p)); |
336 | | |
337 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
338 | | |
339 | | // Testing response from connection 1 |
340 | 1 | uint8_t data[2048]; |
341 | 1 | int len = read_packet_sec_tcp(logger, con1, data, 2 + 1 + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); |
342 | 1 | ck_assert_msg(len == 1 + 1 + CRYPTO_PUBLIC_KEY_SIZE, "Wrong response packet length of %d.", len); |
343 | 1 | ck_assert_msg(data[0] == TCP_PACKET_ROUTING_RESPONSE, "Wrong response packet id of %d.", data[0]); |
344 | 1 | ck_assert_msg(data[1] == 16, "Server didn't refuse connection using wrong public key."); |
345 | 1 | ck_assert_msg(pk_equal(data + 2, con3->public_key), "Key in response packet wrong."); |
346 | | |
347 | | // Connection 3 |
348 | 1 | len = read_packet_sec_tcp(logger, con3, data, 2 + 1 + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); |
349 | 1 | ck_assert_msg(len == 1 + 1 + CRYPTO_PUBLIC_KEY_SIZE, "Wrong response packet length of %d.", len); |
350 | 1 | ck_assert_msg(data[0] == TCP_PACKET_ROUTING_RESPONSE, "Wrong response packet id of %d.", data[0]); |
351 | 1 | ck_assert_msg(data[1] == 16, "Server didn't refuse connection using wrong public key."); |
352 | 1 | ck_assert_msg(pk_equal(data + 2, con1->public_key), "Key in response packet wrong."); |
353 | | |
354 | 1 | uint8_t test_packet[512] = {16, 17, 16, 86, 99, 127, 255, 189, 78}; // What is this packet???? |
355 | | |
356 | 1 | write_packet_tcp_test_connection(logger, con3, test_packet, sizeof(test_packet)); |
357 | 1 | write_packet_tcp_test_connection(logger, con3, test_packet, sizeof(test_packet)); |
358 | 1 | write_packet_tcp_test_connection(logger, con3, test_packet, sizeof(test_packet)); |
359 | | |
360 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
361 | | |
362 | 1 | len = read_packet_sec_tcp(logger, con1, data, 2 + 2 + CRYPTO_MAC_SIZE); |
363 | 1 | ck_assert_msg(len == 2, "wrong len %d", len); |
364 | 1 | ck_assert_msg(data[0] == TCP_PACKET_CONNECTION_NOTIFICATION, "wrong packet id %u", data[0]); |
365 | 1 | ck_assert_msg(data[1] == 16, "wrong peer id %u", data[1]); |
366 | 1 | len = read_packet_sec_tcp(logger, con3, data, 2 + 2 + CRYPTO_MAC_SIZE); |
367 | 1 | ck_assert_msg(len == 2, "wrong len %d", len); |
368 | 1 | ck_assert_msg(data[0] == TCP_PACKET_CONNECTION_NOTIFICATION, "wrong packet id %u", data[0]); |
369 | 1 | ck_assert_msg(data[1] == 16, "wrong peer id %u", data[1]); |
370 | 1 | len = read_packet_sec_tcp(logger, con1, data, 2 + sizeof(test_packet) + CRYPTO_MAC_SIZE); |
371 | 1 | ck_assert_msg(len == sizeof(test_packet), "wrong len %d", len); |
372 | 1 | ck_assert_msg(memcmp(data, test_packet, sizeof(test_packet)) == 0, "packet is wrong %u %u %u %u", data[0], data[1], |
373 | 1 | data[sizeof(test_packet) - 2], data[sizeof(test_packet) - 1]); |
374 | 1 | len = read_packet_sec_tcp(logger, con1, data, 2 + sizeof(test_packet) + CRYPTO_MAC_SIZE); |
375 | 1 | ck_assert_msg(len == sizeof(test_packet), "wrong len %d", len); |
376 | 1 | ck_assert_msg(memcmp(data, test_packet, sizeof(test_packet)) == 0, "packet is wrong %u %u %u %u", data[0], data[1], |
377 | 1 | data[sizeof(test_packet) - 2], data[sizeof(test_packet) - 1]); |
378 | 1 | len = read_packet_sec_tcp(logger, con1, data, 2 + sizeof(test_packet) + CRYPTO_MAC_SIZE); |
379 | 1 | ck_assert_msg(len == sizeof(test_packet), "wrong len %d", len); |
380 | 1 | ck_assert_msg(memcmp(data, test_packet, sizeof(test_packet)) == 0, "packet is wrong %u %u %u %u", data[0], data[1], |
381 | 1 | data[sizeof(test_packet) - 2], data[sizeof(test_packet) - 1]); |
382 | 1 | write_packet_tcp_test_connection(logger, con1, test_packet, sizeof(test_packet)); |
383 | 1 | write_packet_tcp_test_connection(logger, con1, test_packet, sizeof(test_packet)); |
384 | 1 | write_packet_tcp_test_connection(logger, con1, test_packet, sizeof(test_packet)); |
385 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
386 | 1 | len = read_packet_sec_tcp(logger, con3, data, 2 + sizeof(test_packet) + CRYPTO_MAC_SIZE); |
387 | 1 | ck_assert_msg(len == sizeof(test_packet), "wrong len %d", len); |
388 | 1 | ck_assert_msg(memcmp(data, test_packet, sizeof(test_packet)) == 0, "packet is wrong %u %u %u %u", data[0], data[1], |
389 | 1 | data[sizeof(test_packet) - 2], data[sizeof(test_packet) - 1]); |
390 | 1 | len = read_packet_sec_tcp(logger, con3, data, 2 + sizeof(test_packet) + CRYPTO_MAC_SIZE); |
391 | 1 | ck_assert_msg(len == sizeof(test_packet), "wrong len %d", len); |
392 | 1 | ck_assert_msg(memcmp(data, test_packet, sizeof(test_packet)) == 0, "packet is wrong %u %u %u %u", data[0], data[1], |
393 | 1 | data[sizeof(test_packet) - 2], data[sizeof(test_packet) - 1]); |
394 | 1 | len = read_packet_sec_tcp(logger, con3, data, 2 + sizeof(test_packet) + CRYPTO_MAC_SIZE); |
395 | 1 | ck_assert_msg(len == sizeof(test_packet), "wrong len %d", len); |
396 | 1 | ck_assert_msg(memcmp(data, test_packet, sizeof(test_packet)) == 0, "packet is wrong %u %u %u %u", data[0], data[1], |
397 | 1 | data[sizeof(test_packet) - 2], data[sizeof(test_packet) - 1]); |
398 | | |
399 | 1 | uint8_t ping_packet[1 + sizeof(uint64_t)] = {TCP_PACKET_PING, 8, 6, 9, 67}; |
400 | 1 | write_packet_tcp_test_connection(logger, con1, ping_packet, sizeof(ping_packet)); |
401 | | |
402 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
403 | | |
404 | 1 | len = read_packet_sec_tcp(logger, con1, data, 2 + sizeof(ping_packet) + CRYPTO_MAC_SIZE); |
405 | 1 | ck_assert_msg(len == sizeof(ping_packet), "wrong len %d", len); |
406 | 1 | ck_assert_msg(data[0] == TCP_PACKET_PONG, "wrong packet id %u", data[0]); |
407 | 1 | ck_assert_msg(memcmp(ping_packet + 1, data + 1, sizeof(uint64_t)) == 0, "wrong packet data"); |
408 | | |
409 | | // Kill off the connections |
410 | 1 | kill_tcp_server(tcp_s); |
411 | 1 | kill_tcp_con(con1); |
412 | 1 | kill_tcp_con(con2); |
413 | 1 | kill_tcp_con(con3); |
414 | | |
415 | 1 | logger_kill(logger); |
416 | 1 | mono_time_free(mem, mono_time); |
417 | 1 | } |
418 | | |
419 | | static int response_callback_good; |
420 | | static uint8_t response_callback_connection_id; |
421 | | static uint8_t response_callback_public_key[CRYPTO_PUBLIC_KEY_SIZE]; |
422 | | static int response_callback(void *object, uint8_t connection_id, const uint8_t *public_key) |
423 | 1 | { |
424 | 1 | if (set_tcp_connection_number((TCP_Client_Connection *)(void *)((char *)object - 2), connection_id, 7) != 0) { |
425 | 0 | return 1; |
426 | 0 | } |
427 | | |
428 | 1 | response_callback_connection_id = connection_id; |
429 | 1 | memcpy(response_callback_public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE); |
430 | 1 | response_callback_good++; |
431 | 1 | return 0; |
432 | 1 | } |
433 | | static int status_callback_good; |
434 | | static uint8_t status_callback_connection_id; |
435 | | static uint8_t status_callback_status; |
436 | | static int status_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t status) |
437 | 2 | { |
438 | 2 | if (object != (void *)2) { |
439 | 0 | return 1; |
440 | 0 | } |
441 | | |
442 | 2 | if (number != 7) { |
443 | 0 | return 1; |
444 | 0 | } |
445 | | |
446 | 2 | status_callback_connection_id = connection_id; |
447 | 2 | status_callback_status = status; |
448 | 2 | status_callback_good++; |
449 | 2 | return 0; |
450 | 2 | } |
451 | | static int data_callback_good; |
452 | | static int data_callback(void *object, uint32_t number, uint8_t connection_id, const uint8_t *data, uint16_t length, |
453 | | void *userdata) |
454 | 1 | { |
455 | 1 | if (object != (void *)3) { |
456 | 0 | return 1; |
457 | 0 | } |
458 | | |
459 | 1 | if (number != 7) { |
460 | 0 | return 1; |
461 | 0 | } |
462 | | |
463 | 1 | if (length != 5) { |
464 | 0 | return 1; |
465 | 0 | } |
466 | | |
467 | 1 | if (data[0] == 1 && data[1] == 2 && data[2] == 3 && data[3] == 4 && data[4] == 5) { |
468 | 1 | data_callback_good++; |
469 | 1 | return 0; |
470 | 1 | } |
471 | | |
472 | 0 | return 1; |
473 | 1 | } |
474 | | |
475 | | static int oob_data_callback_good; |
476 | | static uint8_t oob_pubkey[CRYPTO_PUBLIC_KEY_SIZE]; |
477 | | static int oob_data_callback(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length, |
478 | | void *userdata) |
479 | 1 | { |
480 | 1 | if (object != (void *)4) { |
481 | 0 | return 1; |
482 | 0 | } |
483 | | |
484 | 1 | if (length != 5) { |
485 | 0 | return 1; |
486 | 0 | } |
487 | | |
488 | 1 | if (!pk_equal(public_key, oob_pubkey)) { |
489 | 0 | return 1; |
490 | 0 | } |
491 | | |
492 | 1 | if (data[0] == 1 && data[1] == 2 && data[2] == 3 && data[3] == 4 && data[4] == 5) { |
493 | 1 | oob_data_callback_good++; |
494 | 1 | return 0; |
495 | 1 | } |
496 | | |
497 | 0 | return 1; |
498 | 1 | } |
499 | | |
500 | | static void test_client(void) |
501 | 1 | { |
502 | 1 | const Random *rng = os_random(); |
503 | 1 | ck_assert(rng != nullptr); |
504 | 1 | const Network *ns = os_network(); |
505 | 1 | ck_assert(ns != nullptr); |
506 | 1 | const Memory *mem = os_memory(); |
507 | 1 | ck_assert(mem != nullptr); |
508 | | |
509 | 1 | Logger *logger = logger_new(); |
510 | 1 | Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); |
511 | | |
512 | 1 | uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; |
513 | 1 | uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; |
514 | 1 | crypto_new_keypair(rng, self_public_key, self_secret_key); |
515 | 1 | TCP_Server *tcp_s = new_tcp_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); |
516 | 1 | ck_assert_msg(tcp_s != nullptr, "Failed to create a TCP relay server."); |
517 | 1 | ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind the relay server to all ports."); |
518 | | |
519 | 1 | uint8_t f_public_key[CRYPTO_PUBLIC_KEY_SIZE]; |
520 | 1 | uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE]; |
521 | 1 | crypto_new_keypair(rng, f_public_key, f_secret_key); |
522 | 1 | IP_Port ip_port_tcp_s; |
523 | | |
524 | 1 | ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); |
525 | 1 | ip_port_tcp_s.ip = get_loopback(); |
526 | | |
527 | 1 | TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, nullptr); |
528 | 1 | do_tcp_connection(logger, mono_time, conn, nullptr); |
529 | 1 | c_sleep(50); |
530 | | |
531 | | // The connection status should be unconfirmed here because we have finished |
532 | | // sending our data and are awaiting a response. |
533 | 1 | ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_UNCONFIRMED, "Wrong connection status. Expected: %d, is: %d.", |
534 | 1 | TCP_CLIENT_UNCONFIRMED, tcp_con_status(conn)); |
535 | | |
536 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); // Now let the server handle requests... |
537 | | |
538 | 1 | const uint8_t loop_size = 3; |
539 | | |
540 | 4 | for (uint8_t i = 0; i < loop_size; i++) { |
541 | 3 | mono_time_update(mono_time); |
542 | 3 | do_tcp_connection(logger, mono_time, conn, nullptr); // Run the connection loop. |
543 | | |
544 | | // The status of the connection should continue to be TCP_CLIENT_CONFIRMED after multiple subsequent do_tcp_connection() calls. |
545 | 3 | ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_CONFIRMED, "Wrong connection status. Expected: %d, is: %d", |
546 | 3 | TCP_CLIENT_CONFIRMED, tcp_con_status(conn)); |
547 | | |
548 | 3 | c_sleep(i == loop_size - 1 ? 0 : 500); // Sleep for 500ms on all except third loop. |
549 | 3 | } |
550 | | |
551 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
552 | | |
553 | | // And still after the server runs again. |
554 | 1 | ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_CONFIRMED, "Wrong status. Expected: %d, is: %d", TCP_CLIENT_CONFIRMED, |
555 | 1 | tcp_con_status(conn)); |
556 | | |
557 | 1 | uint8_t f2_public_key[CRYPTO_PUBLIC_KEY_SIZE]; |
558 | 1 | uint8_t f2_secret_key[CRYPTO_SECRET_KEY_SIZE]; |
559 | 1 | crypto_new_keypair(rng, f2_public_key, f2_secret_key); |
560 | 1 | ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); |
561 | 1 | TCP_Client_Connection *conn2 = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f2_public_key, |
562 | 1 | f2_secret_key, nullptr); |
563 | | |
564 | | // The client should call this function (defined earlier) during the routing process. |
565 | 1 | routing_response_handler(conn, response_callback, (char *)conn + 2); |
566 | | // The client should call this function when it receives a connection notification. |
567 | 1 | routing_status_handler(conn, status_callback, (void *)2); |
568 | | // The client should call this function when |
569 | 1 | routing_data_handler(conn, data_callback, (void *)3); |
570 | | // The client should call this function when sending out of band packets. |
571 | 1 | oob_data_handler(conn, oob_data_callback, (void *)4); |
572 | | |
573 | | // These integers will increment per successful callback. |
574 | 1 | oob_data_callback_good = response_callback_good = status_callback_good = data_callback_good = 0; |
575 | | |
576 | 1 | do_tcp_connection(logger, mono_time, conn, nullptr); |
577 | 1 | do_tcp_connection(logger, mono_time, conn2, nullptr); |
578 | | |
579 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
580 | | |
581 | 1 | do_tcp_connection(logger, mono_time, conn, nullptr); |
582 | 1 | do_tcp_connection(logger, mono_time, conn2, nullptr); |
583 | 1 | c_sleep(50); |
584 | | |
585 | 1 | const uint8_t data[5] = {1, 2, 3, 4, 5}; |
586 | 1 | memcpy(oob_pubkey, f2_public_key, CRYPTO_PUBLIC_KEY_SIZE); |
587 | 1 | send_oob_packet(logger, conn2, f_public_key, data, 5); |
588 | 1 | send_routing_request(logger, conn, f2_public_key); |
589 | 1 | send_routing_request(logger, conn2, f_public_key); |
590 | | |
591 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
592 | | |
593 | 1 | do_tcp_connection(logger, mono_time, conn, nullptr); |
594 | 1 | do_tcp_connection(logger, mono_time, conn2, nullptr); |
595 | | |
596 | | // All callback methods save data should have run during the above network prodding. |
597 | 1 | ck_assert_msg(oob_data_callback_good == 1, "OOB callback not called"); |
598 | 1 | ck_assert_msg(response_callback_good == 1, "Response callback not called."); |
599 | 1 | ck_assert_msg(pk_equal(response_callback_public_key, f2_public_key), "Wrong public key."); |
600 | 1 | ck_assert_msg(status_callback_good == 1, "Status callback not called."); |
601 | 1 | ck_assert_msg(status_callback_status == 2, "Wrong status callback status."); |
602 | 1 | ck_assert_msg(status_callback_connection_id == response_callback_connection_id, |
603 | 1 | "Status and response callback connection IDs are not equal."); |
604 | | |
605 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
606 | | |
607 | 1 | ck_assert_msg(send_data(logger, conn2, 0, data, 5) == 1, "Failed a send_data() call."); |
608 | | |
609 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
610 | | |
611 | 1 | do_tcp_connection(logger, mono_time, conn, nullptr); |
612 | 1 | do_tcp_connection(logger, mono_time, conn2, nullptr); |
613 | 1 | ck_assert_msg(data_callback_good == 1, "Data callback was not called."); |
614 | 1 | status_callback_good = 0; |
615 | 1 | send_disconnect_request(logger, conn2, 0); |
616 | | |
617 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
618 | | |
619 | 1 | do_tcp_connection(logger, mono_time, conn, nullptr); |
620 | 1 | do_tcp_connection(logger, mono_time, conn2, nullptr); |
621 | 1 | ck_assert_msg(status_callback_good == 1, "Status callback not called"); |
622 | 1 | ck_assert_msg(status_callback_status == 1, "Wrong status callback status."); |
623 | | |
624 | | // Kill off all connections and servers. |
625 | 1 | kill_tcp_server(tcp_s); |
626 | 1 | kill_tcp_connection(conn); |
627 | 1 | kill_tcp_connection(conn2); |
628 | | |
629 | 1 | logger_kill(logger); |
630 | 1 | mono_time_free(mem, mono_time); |
631 | 1 | } |
632 | | |
633 | | // Test how the client handles servers that don't respond. |
634 | | static void test_client_invalid(void) |
635 | 1 | { |
636 | 1 | const Random *rng = os_random(); |
637 | 1 | ck_assert(rng != nullptr); |
638 | 1 | const Network *ns = os_network(); |
639 | 1 | ck_assert(ns != nullptr); |
640 | 1 | const Memory *mem = os_memory(); |
641 | 1 | ck_assert(mem != nullptr); |
642 | | |
643 | 1 | Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); |
644 | 1 | Logger *logger = logger_new(); |
645 | | |
646 | 1 | uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; |
647 | 1 | uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; |
648 | 1 | crypto_new_keypair(rng, self_public_key, self_secret_key); |
649 | | |
650 | 1 | uint8_t f_public_key[CRYPTO_PUBLIC_KEY_SIZE]; |
651 | 1 | uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE]; |
652 | 1 | crypto_new_keypair(rng, f_public_key, f_secret_key); |
653 | 1 | IP_Port ip_port_tcp_s; |
654 | | |
655 | 1 | ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); |
656 | 1 | ip_port_tcp_s.ip = get_loopback(); |
657 | 1 | TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, |
658 | 1 | self_public_key, f_public_key, f_secret_key, nullptr); |
659 | | |
660 | | // Run the client's main loop but not the server. |
661 | 1 | mono_time_update(mono_time); |
662 | 1 | do_tcp_connection(logger, mono_time, conn, nullptr); |
663 | 1 | c_sleep(50); |
664 | | |
665 | | // After 50ms of no response... |
666 | 1 | ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_CONNECTING, "Wrong status. Expected: %d, is: %d.", |
667 | 1 | TCP_CLIENT_CONNECTING, tcp_con_status(conn)); |
668 | | // After 5s... |
669 | 1 | c_sleep(5000); |
670 | 1 | mono_time_update(mono_time); |
671 | 1 | do_tcp_connection(logger, mono_time, conn, nullptr); |
672 | 1 | ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_CONNECTING, "Wrong status. Expected: %d, is: %d.", |
673 | 1 | TCP_CLIENT_CONNECTING, tcp_con_status(conn)); |
674 | | // 11s... (Should wait for 10 before giving up.) |
675 | 1 | c_sleep(6000); |
676 | 1 | mono_time_update(mono_time); |
677 | 1 | do_tcp_connection(logger, mono_time, conn, nullptr); |
678 | 1 | ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_DISCONNECTED, "Wrong status. Expected: %d, is: %d.", |
679 | 1 | TCP_CLIENT_DISCONNECTED, tcp_con_status(conn)); |
680 | | |
681 | 1 | kill_tcp_connection(conn); |
682 | | |
683 | 1 | logger_kill(logger); |
684 | 1 | mono_time_free(mem, mono_time); |
685 | 1 | } |
686 | | |
687 | | #include "../toxcore/TCP_connection.h" |
688 | | |
689 | | static bool tcp_data_callback_called; |
690 | | static int tcp_data_callback(void *object, int id, const uint8_t *data, uint16_t length, void *userdata) |
691 | 2 | { |
692 | 2 | if (object != (void *)120397) { |
693 | 0 | return -1; |
694 | 0 | } |
695 | | |
696 | 2 | if (id != 123) { |
697 | 0 | return -1; |
698 | 0 | } |
699 | | |
700 | 2 | if (length != 6) { |
701 | 0 | return -1; |
702 | 0 | } |
703 | | |
704 | 2 | if (memcmp(data, "Gentoo", length) != 0) { |
705 | 0 | return -1; |
706 | 0 | } |
707 | | |
708 | 2 | tcp_data_callback_called = 1; |
709 | 2 | return 0; |
710 | 2 | } |
711 | | |
712 | | |
713 | | static void test_tcp_connection(void) |
714 | 1 | { |
715 | 1 | const Random *rng = os_random(); |
716 | 1 | ck_assert(rng != nullptr); |
717 | 1 | const Network *ns = os_network(); |
718 | 1 | ck_assert(ns != nullptr); |
719 | 1 | const Memory *mem = os_memory(); |
720 | 1 | ck_assert(mem != nullptr); |
721 | | |
722 | 1 | Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); |
723 | 1 | Logger *logger = logger_new(); |
724 | | |
725 | 1 | tcp_data_callback_called = 0; |
726 | 1 | uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; |
727 | 1 | uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; |
728 | 1 | crypto_new_keypair(rng, self_public_key, self_secret_key); |
729 | 1 | TCP_Server *tcp_s = new_tcp_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); |
730 | 1 | ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key"); |
731 | | |
732 | 1 | TCP_Proxy_Info proxy_info; |
733 | 1 | proxy_info.proxy_type = TCP_PROXY_NONE; |
734 | 1 | crypto_new_keypair(rng, self_public_key, self_secret_key); |
735 | 1 | TCP_Connections *tc_1 = new_tcp_connections(logger, mem, rng, ns, mono_time, self_secret_key, &proxy_info); |
736 | 1 | ck_assert_msg(pk_equal(tcp_connections_public_key(tc_1), self_public_key), "Wrong public key"); |
737 | | |
738 | 1 | crypto_new_keypair(rng, self_public_key, self_secret_key); |
739 | 1 | TCP_Connections *tc_2 = new_tcp_connections(logger, mem, rng, ns, mono_time, self_secret_key, &proxy_info); |
740 | 1 | ck_assert_msg(pk_equal(tcp_connections_public_key(tc_2), self_public_key), "Wrong public key"); |
741 | | |
742 | 1 | IP_Port ip_port_tcp_s; |
743 | | |
744 | 1 | ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); |
745 | 1 | ip_port_tcp_s.ip = get_loopback(); |
746 | | |
747 | 1 | int connection = new_tcp_connection_to(tc_1, tcp_connections_public_key(tc_2), 123); |
748 | 1 | ck_assert_msg(connection == 0, "Connection id wrong"); |
749 | 1 | ck_assert_msg(add_tcp_relay_connection(tc_1, connection, &ip_port_tcp_s, tcp_server_public_key(tcp_s)) == 0, |
750 | 1 | "Could not add tcp relay to connection\n"); |
751 | | |
752 | 1 | ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); |
753 | 1 | connection = new_tcp_connection_to(tc_2, tcp_connections_public_key(tc_1), 123); |
754 | 1 | ck_assert_msg(connection == 0, "Connection id wrong"); |
755 | 1 | ck_assert_msg(add_tcp_relay_connection(tc_2, connection, &ip_port_tcp_s, tcp_server_public_key(tcp_s)) == 0, |
756 | 1 | "Could not add tcp relay to connection\n"); |
757 | | |
758 | 1 | ck_assert_msg(new_tcp_connection_to(tc_2, tcp_connections_public_key(tc_1), 123) == -1, |
759 | 1 | "Managed to read same connection\n"); |
760 | | |
761 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
762 | | |
763 | 1 | do_tcp_connections(logger, tc_1, nullptr); |
764 | 1 | do_tcp_connections(logger, tc_2, nullptr); |
765 | | |
766 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
767 | | |
768 | 1 | do_tcp_connections(logger, tc_1, nullptr); |
769 | 1 | do_tcp_connections(logger, tc_2, nullptr); |
770 | | |
771 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
772 | | |
773 | 1 | do_tcp_connections(logger, tc_1, nullptr); |
774 | 1 | do_tcp_connections(logger, tc_2, nullptr); |
775 | | |
776 | 1 | int ret = send_packet_tcp_connection(tc_1, 0, (const uint8_t *)"Gentoo", 6); |
777 | 1 | ck_assert_msg(ret == 0, "could not send packet."); |
778 | 1 | set_packet_tcp_connection_callback(tc_2, &tcp_data_callback, (void *) 120397); |
779 | | |
780 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
781 | | |
782 | 1 | do_tcp_connections(logger, tc_1, nullptr); |
783 | 1 | do_tcp_connections(logger, tc_2, nullptr); |
784 | | |
785 | 1 | ck_assert_msg(tcp_data_callback_called, "could not recv packet."); |
786 | 1 | ck_assert_msg(tcp_connection_to_online_tcp_relays(tc_1, 0) == 1, "Wrong number of connected relays"); |
787 | 1 | ck_assert_msg(kill_tcp_connection_to(tc_1, 0) == 0, "could not kill connection to\n"); |
788 | | |
789 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
790 | | |
791 | 1 | do_tcp_connections(logger, tc_1, nullptr); |
792 | 1 | do_tcp_connections(logger, tc_2, nullptr); |
793 | | |
794 | 1 | ck_assert_msg(send_packet_tcp_connection(tc_1, 0, (const uint8_t *)"Gentoo", 6) == -1, "could send packet."); |
795 | 1 | ck_assert_msg(kill_tcp_connection_to(tc_2, 0) == 0, "could not kill connection to\n"); |
796 | | |
797 | 1 | kill_tcp_server(tcp_s); |
798 | 1 | kill_tcp_connections(tc_1); |
799 | 1 | kill_tcp_connections(tc_2); |
800 | | |
801 | 1 | logger_kill(logger); |
802 | 1 | mono_time_free(mem, mono_time); |
803 | 1 | } |
804 | | |
805 | | static bool tcp_oobdata_callback_called; |
806 | | static int tcp_oobdata_callback(void *object, const uint8_t *public_key, unsigned int id, const uint8_t *data, |
807 | | uint16_t length, void *userdata) |
808 | 1 | { |
809 | 1 | const TCP_Connections *tcp_c = (const TCP_Connections *)object; |
810 | | |
811 | 1 | if (length != 6) { |
812 | 0 | return -1; |
813 | 0 | } |
814 | | |
815 | 1 | if (memcmp(data, "Gentoo", length) != 0) { |
816 | 0 | return -1; |
817 | 0 | } |
818 | | |
819 | 1 | if (tcp_send_oob_packet(tcp_c, id, public_key, data, length) == 0) { |
820 | 1 | tcp_oobdata_callback_called = 1; |
821 | 1 | } |
822 | | |
823 | 1 | return 0; |
824 | 1 | } |
825 | | |
826 | | static void test_tcp_connection2(void) |
827 | 1 | { |
828 | 1 | const Random *rng = os_random(); |
829 | 1 | ck_assert(rng != nullptr); |
830 | 1 | const Network *ns = os_network(); |
831 | 1 | ck_assert(ns != nullptr); |
832 | 1 | const Memory *mem = os_memory(); |
833 | 1 | ck_assert(mem != nullptr); |
834 | | |
835 | 1 | Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); |
836 | 1 | Logger *logger = logger_new(); |
837 | | |
838 | 1 | tcp_oobdata_callback_called = 0; |
839 | 1 | tcp_data_callback_called = 0; |
840 | | |
841 | 1 | uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; |
842 | 1 | uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; |
843 | 1 | crypto_new_keypair(rng, self_public_key, self_secret_key); |
844 | 1 | TCP_Server *tcp_s = new_tcp_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); |
845 | 1 | ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key"); |
846 | | |
847 | 1 | TCP_Proxy_Info proxy_info; |
848 | 1 | proxy_info.proxy_type = TCP_PROXY_NONE; |
849 | 1 | crypto_new_keypair(rng, self_public_key, self_secret_key); |
850 | 1 | TCP_Connections *tc_1 = new_tcp_connections(logger, mem, rng, ns, mono_time, self_secret_key, &proxy_info); |
851 | 1 | ck_assert_msg(pk_equal(tcp_connections_public_key(tc_1), self_public_key), "Wrong public key"); |
852 | | |
853 | 1 | crypto_new_keypair(rng, self_public_key, self_secret_key); |
854 | 1 | TCP_Connections *tc_2 = new_tcp_connections(logger, mem, rng, ns, mono_time, self_secret_key, &proxy_info); |
855 | 1 | ck_assert_msg(pk_equal(tcp_connections_public_key(tc_2), self_public_key), "Wrong public key"); |
856 | | |
857 | 1 | IP_Port ip_port_tcp_s; |
858 | | |
859 | 1 | ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); |
860 | 1 | ip_port_tcp_s.ip = get_loopback(); |
861 | | |
862 | 1 | int connection = new_tcp_connection_to(tc_1, tcp_connections_public_key(tc_2), 123); |
863 | 1 | ck_assert_msg(connection == 0, "Connection id wrong"); |
864 | 1 | ck_assert_msg(add_tcp_relay_connection(tc_1, connection, &ip_port_tcp_s, tcp_server_public_key(tcp_s)) == 0, |
865 | 1 | "Could not add tcp relay to connection\n"); |
866 | | |
867 | 1 | ck_assert_msg(add_tcp_relay_global(tc_2, &ip_port_tcp_s, tcp_server_public_key(tcp_s)) == 0, |
868 | 1 | "Could not add global relay"); |
869 | | |
870 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
871 | | |
872 | 1 | do_tcp_connections(logger, tc_1, nullptr); |
873 | 1 | do_tcp_connections(logger, tc_2, nullptr); |
874 | | |
875 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
876 | | |
877 | 1 | do_tcp_connections(logger, tc_1, nullptr); |
878 | 1 | do_tcp_connections(logger, tc_2, nullptr); |
879 | | |
880 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
881 | | |
882 | 1 | do_tcp_connections(logger, tc_1, nullptr); |
883 | 1 | do_tcp_connections(logger, tc_2, nullptr); |
884 | | |
885 | 1 | int ret = send_packet_tcp_connection(tc_1, 0, (const uint8_t *)"Gentoo", 6); |
886 | 1 | ck_assert_msg(ret == 0, "could not send packet."); |
887 | 1 | set_oob_packet_tcp_connection_callback(tc_2, &tcp_oobdata_callback, tc_2); |
888 | 1 | set_packet_tcp_connection_callback(tc_1, &tcp_data_callback, (void *) 120397); |
889 | | |
890 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
891 | | |
892 | 1 | do_tcp_connections(logger, tc_1, nullptr); |
893 | 1 | do_tcp_connections(logger, tc_2, nullptr); |
894 | | |
895 | 1 | ck_assert_msg(tcp_oobdata_callback_called, "could not recv packet."); |
896 | | |
897 | 1 | do_tcp_server_delay(tcp_s, mono_time, 50); |
898 | | |
899 | 1 | do_tcp_connections(logger, tc_1, nullptr); |
900 | 1 | do_tcp_connections(logger, tc_2, nullptr); |
901 | | |
902 | 1 | ck_assert_msg(tcp_data_callback_called, "could not recv packet."); |
903 | 1 | ck_assert_msg(kill_tcp_connection_to(tc_1, 0) == 0, "could not kill connection to\n"); |
904 | | |
905 | 1 | kill_tcp_server(tcp_s); |
906 | 1 | kill_tcp_connections(tc_1); |
907 | 1 | kill_tcp_connections(tc_2); |
908 | | |
909 | 1 | logger_kill(logger); |
910 | 1 | mono_time_free(mem, mono_time); |
911 | 1 | } |
912 | | |
913 | | static void tcp_suite(void) |
914 | 1 | { |
915 | 1 | test_basic(); |
916 | 1 | test_some(); |
917 | 1 | test_client(); |
918 | 1 | test_client_invalid(); |
919 | 1 | test_tcp_connection(); |
920 | 1 | test_tcp_connection2(); |
921 | 1 | } |
922 | | |
923 | | int main(void) |
924 | 721 | { |
925 | 721 | setvbuf(stdout, nullptr, _IONBF, 0); |
926 | 721 | tcp_suite(); |
927 | 721 | return 0; |
928 | 721 | } |