Prop210: Refactor connection_get_* to produce lists and counts
[tor.git] / src / test / test_cell_formats.c
blobe86dc0934fed3dfbc12ca1c146e715ed2b9ea872
1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2015, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
6 #include "orconfig.h"
8 #define CONNECTION_EDGE_PRIVATE
9 #define RELAY_PRIVATE
10 #include "or.h"
11 #include "channel.h"
12 #include "connection_edge.h"
13 #include "connection_or.h"
14 #include "onion.h"
15 #include "onion_tap.h"
16 #include "onion_fast.h"
17 #include "onion_ntor.h"
18 #include "relay.h"
19 #include "test.h"
21 #include <stdlib.h>
22 #include <string.h>
24 static void
25 test_cfmt_relay_header(void *arg)
27 relay_header_t rh;
28 const uint8_t hdr_1[RELAY_HEADER_SIZE] =
29 "\x03" "\x00\x00" "\x21\x22" "ABCD" "\x01\x03";
30 uint8_t hdr_out[RELAY_HEADER_SIZE];
31 (void)arg;
33 tt_int_op(sizeof(hdr_1), OP_EQ, RELAY_HEADER_SIZE);
34 relay_header_unpack(&rh, hdr_1);
35 tt_int_op(rh.command, OP_EQ, 3);
36 tt_int_op(rh.recognized, OP_EQ, 0);
37 tt_int_op(rh.stream_id, OP_EQ, 0x2122);
38 tt_mem_op(rh.integrity, OP_EQ, "ABCD", 4);
39 tt_int_op(rh.length, OP_EQ, 0x103);
41 relay_header_pack(hdr_out, &rh);
42 tt_mem_op(hdr_out, OP_EQ, hdr_1, RELAY_HEADER_SIZE);
44 done:
48 static void
49 make_relay_cell(cell_t *out, uint8_t command,
50 const void *body, size_t bodylen)
52 relay_header_t rh;
54 memset(&rh, 0, sizeof(rh));
55 rh.stream_id = 5;
56 rh.command = command;
57 rh.length = bodylen;
59 out->command = CELL_RELAY;
60 out->circ_id = 10;
61 relay_header_pack(out->payload, &rh);
63 memcpy(out->payload + RELAY_HEADER_SIZE, body, bodylen);
66 static void
67 test_cfmt_begin_cells(void *arg)
69 cell_t cell;
70 begin_cell_t bcell;
71 uint8_t end_reason;
72 (void)arg;
74 /* Try begindir. */
75 memset(&bcell, 0x7f, sizeof(bcell));
76 make_relay_cell(&cell, RELAY_COMMAND_BEGIN_DIR, "", 0);
77 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
78 tt_ptr_op(NULL, OP_EQ, bcell.address);
79 tt_int_op(0, OP_EQ, bcell.flags);
80 tt_int_op(0, OP_EQ, bcell.port);
81 tt_int_op(5, OP_EQ, bcell.stream_id);
82 tt_int_op(1, OP_EQ, bcell.is_begindir);
84 /* A Begindir with extra stuff. */
85 memset(&bcell, 0x7f, sizeof(bcell));
86 make_relay_cell(&cell, RELAY_COMMAND_BEGIN_DIR, "12345", 5);
87 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
88 tt_ptr_op(NULL, OP_EQ, bcell.address);
89 tt_int_op(0, OP_EQ, bcell.flags);
90 tt_int_op(0, OP_EQ, bcell.port);
91 tt_int_op(5, OP_EQ, bcell.stream_id);
92 tt_int_op(1, OP_EQ, bcell.is_begindir);
94 /* A short but valid begin cell */
95 memset(&bcell, 0x7f, sizeof(bcell));
96 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:9", 6);
97 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
98 tt_str_op("a.b", OP_EQ, bcell.address);
99 tt_int_op(0, OP_EQ, bcell.flags);
100 tt_int_op(9, OP_EQ, bcell.port);
101 tt_int_op(5, OP_EQ, bcell.stream_id);
102 tt_int_op(0, OP_EQ, bcell.is_begindir);
103 tor_free(bcell.address);
105 /* A significantly loner begin cell */
106 memset(&bcell, 0x7f, sizeof(bcell));
108 const char c[] = "here-is-a-nice-long.hostname.com:65535";
109 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, strlen(c)+1);
111 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
112 tt_str_op("here-is-a-nice-long.hostname.com", OP_EQ, bcell.address);
113 tt_int_op(0, OP_EQ, bcell.flags);
114 tt_int_op(65535, OP_EQ, bcell.port);
115 tt_int_op(5, OP_EQ, bcell.stream_id);
116 tt_int_op(0, OP_EQ, bcell.is_begindir);
117 tor_free(bcell.address);
119 /* An IPv4 begin cell. */
120 memset(&bcell, 0x7f, sizeof(bcell));
121 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "18.9.22.169:80", 15);
122 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
123 tt_str_op("18.9.22.169", OP_EQ, bcell.address);
124 tt_int_op(0, OP_EQ, bcell.flags);
125 tt_int_op(80, OP_EQ, bcell.port);
126 tt_int_op(5, OP_EQ, bcell.stream_id);
127 tt_int_op(0, OP_EQ, bcell.is_begindir);
128 tor_free(bcell.address);
130 /* An IPv6 begin cell. Let's make sure we handle colons*/
131 memset(&bcell, 0x7f, sizeof(bcell));
132 make_relay_cell(&cell, RELAY_COMMAND_BEGIN,
133 "[2620::6b0:b:1a1a:0:26e5:480e]:80", 34);
134 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
135 tt_str_op("[2620::6b0:b:1a1a:0:26e5:480e]", OP_EQ, bcell.address);
136 tt_int_op(0, OP_EQ, bcell.flags);
137 tt_int_op(80, OP_EQ, bcell.port);
138 tt_int_op(5, OP_EQ, bcell.stream_id);
139 tt_int_op(0, OP_EQ, bcell.is_begindir);
140 tor_free(bcell.address);
142 /* a begin cell with extra junk but not enough for flags. */
143 memset(&bcell, 0x7f, sizeof(bcell));
145 const char c[] = "another.example.com:80\x00\x01\x02";
146 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
148 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
149 tt_str_op("another.example.com", OP_EQ, bcell.address);
150 tt_int_op(0, OP_EQ, bcell.flags);
151 tt_int_op(80, OP_EQ, bcell.port);
152 tt_int_op(5, OP_EQ, bcell.stream_id);
153 tt_int_op(0, OP_EQ, bcell.is_begindir);
154 tor_free(bcell.address);
156 /* a begin cell with flags. */
157 memset(&bcell, 0x7f, sizeof(bcell));
159 const char c[] = "another.example.com:443\x00\x01\x02\x03\x04";
160 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
162 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
163 tt_str_op("another.example.com", OP_EQ, bcell.address);
164 tt_int_op(0x1020304, OP_EQ, bcell.flags);
165 tt_int_op(443, OP_EQ, bcell.port);
166 tt_int_op(5, OP_EQ, bcell.stream_id);
167 tt_int_op(0, OP_EQ, bcell.is_begindir);
168 tor_free(bcell.address);
170 /* a begin cell with flags and even more cruft after that. */
171 memset(&bcell, 0x7f, sizeof(bcell));
173 const char c[] = "a-further.example.com:22\x00\xee\xaa\x00\xffHi mom";
174 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
176 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
177 tt_str_op("a-further.example.com", OP_EQ, bcell.address);
178 tt_int_op(0xeeaa00ff, OP_EQ, bcell.flags);
179 tt_int_op(22, OP_EQ, bcell.port);
180 tt_int_op(5, OP_EQ, bcell.stream_id);
181 tt_int_op(0, OP_EQ, bcell.is_begindir);
182 tor_free(bcell.address);
184 /* bad begin cell: impossible length. */
185 memset(&bcell, 0x7f, sizeof(bcell));
186 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:80", 7);
187 cell.payload[9] = 0x01; /* Set length to 510 */
188 cell.payload[10] = 0xfe;
190 relay_header_t rh;
191 relay_header_unpack(&rh, cell.payload);
192 tt_int_op(rh.length, OP_EQ, 510);
194 tt_int_op(-2, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
196 /* Bad begin cell: no body. */
197 memset(&bcell, 0x7f, sizeof(bcell));
198 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "", 0);
199 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
201 /* bad begin cell: no body. */
202 memset(&bcell, 0x7f, sizeof(bcell));
203 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "", 0);
204 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
206 /* bad begin cell: no colon */
207 memset(&bcell, 0x7f, sizeof(bcell));
208 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b", 4);
209 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
211 /* bad begin cell: no ports */
212 memset(&bcell, 0x7f, sizeof(bcell));
213 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:", 5);
214 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
216 /* bad begin cell: bad port */
217 memset(&bcell, 0x7f, sizeof(bcell));
218 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:xyz", 8);
219 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
220 memset(&bcell, 0x7f, sizeof(bcell));
221 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:100000", 11);
222 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
224 /* bad begin cell: no nul */
225 memset(&bcell, 0x7f, sizeof(bcell));
226 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:80", 6);
227 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
229 done:
230 tor_free(bcell.address);
233 static void
234 test_cfmt_connected_cells(void *arg)
236 relay_header_t rh;
237 cell_t cell;
238 tor_addr_t addr;
239 int ttl, r;
240 char *mem_op_hex_tmp = NULL;
241 (void)arg;
243 /* Let's try an oldschool one with nothing in it. */
244 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "", 0);
245 relay_header_unpack(&rh, cell.payload);
246 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
247 tt_int_op(r, OP_EQ, 0);
248 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_UNSPEC);
249 tt_int_op(ttl, OP_EQ, -1);
251 /* A slightly less oldschool one: only an IPv4 address */
252 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x20\x30\x40\x50", 4);
253 relay_header_unpack(&rh, cell.payload);
254 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
255 tt_int_op(r, OP_EQ, 0);
256 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
257 tt_str_op(fmt_addr(&addr), OP_EQ, "32.48.64.80");
258 tt_int_op(ttl, OP_EQ, -1);
260 /* Bogus but understandable: truncated TTL */
261 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x11\x12\x13\x14\x15", 5);
262 relay_header_unpack(&rh, cell.payload);
263 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
264 tt_int_op(r, OP_EQ, 0);
265 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
266 tt_str_op(fmt_addr(&addr), OP_EQ, "17.18.19.20");
267 tt_int_op(ttl, OP_EQ, -1);
269 /* Regular IPv4 one: address and TTL */
270 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
271 "\x02\x03\x04\x05\x00\x00\x0e\x10", 8);
272 relay_header_unpack(&rh, cell.payload);
273 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
274 tt_int_op(r, OP_EQ, 0);
275 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
276 tt_str_op(fmt_addr(&addr), OP_EQ, "2.3.4.5");
277 tt_int_op(ttl, OP_EQ, 3600);
279 /* IPv4 with too-big TTL */
280 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
281 "\x02\x03\x04\x05\xf0\x00\x00\x00", 8);
282 relay_header_unpack(&rh, cell.payload);
283 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
284 tt_int_op(r, OP_EQ, 0);
285 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
286 tt_str_op(fmt_addr(&addr), OP_EQ, "2.3.4.5");
287 tt_int_op(ttl, OP_EQ, -1);
289 /* IPv6 (ttl is mandatory) */
290 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
291 "\x00\x00\x00\x00\x06"
292 "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
293 "\x00\x00\x00\x00\x00\x00\x00\x68"
294 "\x00\x00\x02\x58", 25);
295 relay_header_unpack(&rh, cell.payload);
296 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
297 tt_int_op(r, OP_EQ, 0);
298 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET6);
299 tt_str_op(fmt_addr(&addr), OP_EQ, "2607:f8b0:400c:c02::68");
300 tt_int_op(ttl, OP_EQ, 600);
302 /* IPv6 (ttl too big) */
303 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
304 "\x00\x00\x00\x00\x06"
305 "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
306 "\x00\x00\x00\x00\x00\x00\x00\x68"
307 "\x90\x00\x02\x58", 25);
308 relay_header_unpack(&rh, cell.payload);
309 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
310 tt_int_op(r, OP_EQ, 0);
311 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET6);
312 tt_str_op(fmt_addr(&addr), OP_EQ, "2607:f8b0:400c:c02::68");
313 tt_int_op(ttl, OP_EQ, -1);
315 /* Bogus size: 3. */
316 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
317 "\x00\x01\x02", 3);
318 relay_header_unpack(&rh, cell.payload);
319 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
320 tt_int_op(r, OP_EQ, -1);
322 /* Bogus family: 7. */
323 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
324 "\x00\x00\x00\x00\x07"
325 "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
326 "\x00\x00\x00\x00\x00\x00\x00\x68"
327 "\x90\x00\x02\x58", 25);
328 relay_header_unpack(&rh, cell.payload);
329 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
330 tt_int_op(r, OP_EQ, -1);
332 /* Truncated IPv6. */
333 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
334 "\x00\x00\x00\x00\x06"
335 "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
336 "\x00\x00\x00\x00\x00\x00\x00\x68"
337 "\x00\x00\x02", 24);
338 relay_header_unpack(&rh, cell.payload);
339 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
340 tt_int_op(r, OP_EQ, -1);
342 /* Now make sure we can generate connected cells correctly. */
343 /* Try an IPv4 address */
344 memset(&rh, 0, sizeof(rh));
345 memset(&cell, 0, sizeof(cell));
346 tor_addr_parse(&addr, "30.40.50.60");
347 rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE,
348 &addr, 128);
349 tt_int_op(rh.length, OP_EQ, 8);
350 test_memeq_hex(cell.payload+RELAY_HEADER_SIZE, "1e28323c" "00000080");
352 /* Try parsing it. */
353 tor_addr_make_unspec(&addr);
354 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
355 tt_int_op(r, OP_EQ, 0);
356 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
357 tt_str_op(fmt_addr(&addr), OP_EQ, "30.40.50.60");
358 tt_int_op(ttl, OP_EQ, 128);
360 /* Try an IPv6 address */
361 memset(&rh, 0, sizeof(rh));
362 memset(&cell, 0, sizeof(cell));
363 tor_addr_parse(&addr, "2620::6b0:b:1a1a:0:26e5:480e");
364 rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE,
365 &addr, 3600);
366 tt_int_op(rh.length, OP_EQ, 25);
367 test_memeq_hex(cell.payload + RELAY_HEADER_SIZE,
368 "00000000" "06"
369 "2620000006b0000b1a1a000026e5480e" "00000e10");
371 /* Try parsing it. */
372 tor_addr_make_unspec(&addr);
373 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
374 tt_int_op(r, OP_EQ, 0);
375 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET6);
376 tt_str_op(fmt_addr(&addr), OP_EQ, "2620:0:6b0:b:1a1a:0:26e5:480e");
377 tt_int_op(ttl, OP_EQ, 3600);
379 done:
380 tor_free(mem_op_hex_tmp);
383 static void
384 test_cfmt_create_cells(void *arg)
386 uint8_t b[MAX_ONIONSKIN_CHALLENGE_LEN];
387 create_cell_t cc;
388 cell_t cell;
389 cell_t cell2;
391 (void)arg;
393 /* === Let's try parsing some good cells! */
395 /* A valid create cell. */
396 memset(&cell, 0, sizeof(cell));
397 memset(b, 0, sizeof(b));
398 crypto_rand((char*)b, TAP_ONIONSKIN_CHALLENGE_LEN);
399 cell.command = CELL_CREATE;
400 memcpy(cell.payload, b, TAP_ONIONSKIN_CHALLENGE_LEN);
401 tt_int_op(0, OP_EQ, create_cell_parse(&cc, &cell));
402 tt_int_op(CELL_CREATE, OP_EQ, cc.cell_type);
403 tt_int_op(ONION_HANDSHAKE_TYPE_TAP, OP_EQ, cc.handshake_type);
404 tt_int_op(TAP_ONIONSKIN_CHALLENGE_LEN, OP_EQ, cc.handshake_len);
405 tt_mem_op(cc.onionskin,OP_EQ, b, TAP_ONIONSKIN_CHALLENGE_LEN + 10);
406 tt_int_op(0, OP_EQ, create_cell_format(&cell2, &cc));
407 tt_int_op(cell.command, OP_EQ, cell2.command);
408 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
410 /* A valid create_fast cell. */
411 memset(&cell, 0, sizeof(cell));
412 memset(b, 0, sizeof(b));
413 crypto_rand((char*)b, CREATE_FAST_LEN);
414 cell.command = CELL_CREATE_FAST;
415 memcpy(cell.payload, b, CREATE_FAST_LEN);
416 tt_int_op(0, OP_EQ, create_cell_parse(&cc, &cell));
417 tt_int_op(CELL_CREATE_FAST, OP_EQ, cc.cell_type);
418 tt_int_op(ONION_HANDSHAKE_TYPE_FAST, OP_EQ, cc.handshake_type);
419 tt_int_op(CREATE_FAST_LEN, OP_EQ, cc.handshake_len);
420 tt_mem_op(cc.onionskin,OP_EQ, b, CREATE_FAST_LEN + 10);
421 tt_int_op(0, OP_EQ, create_cell_format(&cell2, &cc));
422 tt_int_op(cell.command, OP_EQ, cell2.command);
423 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
425 /* A valid create2 cell with a TAP payload */
426 memset(&cell, 0, sizeof(cell));
427 memset(b, 0, sizeof(b));
428 crypto_rand((char*)b, TAP_ONIONSKIN_CHALLENGE_LEN);
429 cell.command = CELL_CREATE2;
430 memcpy(cell.payload, "\x00\x00\x00\xBA", 4); /* TAP, 186 bytes long */
431 memcpy(cell.payload+4, b, TAP_ONIONSKIN_CHALLENGE_LEN);
432 tt_int_op(0, OP_EQ, create_cell_parse(&cc, &cell));
433 tt_int_op(CELL_CREATE2, OP_EQ, cc.cell_type);
434 tt_int_op(ONION_HANDSHAKE_TYPE_TAP, OP_EQ, cc.handshake_type);
435 tt_int_op(TAP_ONIONSKIN_CHALLENGE_LEN, OP_EQ, cc.handshake_len);
436 tt_mem_op(cc.onionskin,OP_EQ, b, TAP_ONIONSKIN_CHALLENGE_LEN + 10);
437 tt_int_op(0, OP_EQ, create_cell_format(&cell2, &cc));
438 tt_int_op(cell.command, OP_EQ, cell2.command);
439 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
441 /* A valid create2 cell with an ntor payload */
442 memset(&cell, 0, sizeof(cell));
443 memset(b, 0, sizeof(b));
444 crypto_rand((char*)b, NTOR_ONIONSKIN_LEN);
445 cell.command = CELL_CREATE2;
446 memcpy(cell.payload, "\x00\x02\x00\x54", 4); /* ntor, 84 bytes long */
447 memcpy(cell.payload+4, b, NTOR_ONIONSKIN_LEN);
448 tt_int_op(0, OP_EQ, create_cell_parse(&cc, &cell));
449 tt_int_op(CELL_CREATE2, OP_EQ, cc.cell_type);
450 tt_int_op(ONION_HANDSHAKE_TYPE_NTOR, OP_EQ, cc.handshake_type);
451 tt_int_op(NTOR_ONIONSKIN_LEN, OP_EQ, cc.handshake_len);
452 tt_mem_op(cc.onionskin,OP_EQ, b, NTOR_ONIONSKIN_LEN + 10);
453 tt_int_op(0, OP_EQ, create_cell_format(&cell2, &cc));
454 tt_int_op(cell.command, OP_EQ, cell2.command);
455 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
457 /* A valid create cell with an ntor payload, in legacy format. */
458 memset(&cell, 0, sizeof(cell));
459 memset(b, 0, sizeof(b));
460 crypto_rand((char*)b, NTOR_ONIONSKIN_LEN);
461 cell.command = CELL_CREATE;
462 memcpy(cell.payload, "ntorNTORntorNTOR", 16);
463 memcpy(cell.payload+16, b, NTOR_ONIONSKIN_LEN);
464 tt_int_op(0, OP_EQ, create_cell_parse(&cc, &cell));
465 tt_int_op(CELL_CREATE, OP_EQ, cc.cell_type);
466 tt_int_op(ONION_HANDSHAKE_TYPE_NTOR, OP_EQ, cc.handshake_type);
467 tt_int_op(NTOR_ONIONSKIN_LEN, OP_EQ, cc.handshake_len);
468 tt_mem_op(cc.onionskin,OP_EQ, b, NTOR_ONIONSKIN_LEN + 10);
469 tt_int_op(0, OP_EQ, create_cell_format(&cell2, &cc));
470 tt_int_op(cell.command, OP_EQ, cell2.command);
471 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
473 /* == Okay, now let's try to parse some impossible stuff. */
475 /* It has to be some kind of a create cell! */
476 cell.command = CELL_CREATED;
477 tt_int_op(-1, OP_EQ, create_cell_parse(&cc, &cell));
479 /* You can't acutally make an unparseable CREATE or CREATE_FAST cell. */
481 /* Try some CREATE2 cells. First with a bad type. */
482 cell.command = CELL_CREATE2;
483 memcpy(cell.payload, "\x00\x50\x00\x99", 4); /* Type 0x50???? */
484 tt_int_op(-1, OP_EQ, create_cell_parse(&cc, &cell));
485 /* Now a good type with an incorrect length. */
486 memcpy(cell.payload, "\x00\x00\x00\xBC", 4); /* TAP, 187 bytes.*/
487 tt_int_op(-1, OP_EQ, create_cell_parse(&cc, &cell));
488 /* Now a good type with a ridiculous length. */
489 memcpy(cell.payload, "\x00\x00\x02\x00", 4); /* TAP, 512 bytes.*/
490 tt_int_op(-1, OP_EQ, create_cell_parse(&cc, &cell));
492 /* == Time to try formatting bad cells. The important thing is that
493 we reject big lengths, so just check that for now. */
494 cc.handshake_len = 512;
495 tt_int_op(-1, OP_EQ, create_cell_format(&cell2, &cc));
497 /* == Try formatting a create2 cell we don't understand. XXXX */
499 done:
503 static void
504 test_cfmt_created_cells(void *arg)
506 uint8_t b[512];
507 created_cell_t cc;
508 cell_t cell;
509 cell_t cell2;
511 (void)arg;
513 /* A good CREATED cell */
514 memset(&cell, 0, sizeof(cell));
515 memset(b, 0, sizeof(b));
516 crypto_rand((char*)b, TAP_ONIONSKIN_REPLY_LEN);
517 cell.command = CELL_CREATED;
518 memcpy(cell.payload, b, TAP_ONIONSKIN_REPLY_LEN);
519 tt_int_op(0, OP_EQ, created_cell_parse(&cc, &cell));
520 tt_int_op(CELL_CREATED, OP_EQ, cc.cell_type);
521 tt_int_op(TAP_ONIONSKIN_REPLY_LEN, OP_EQ, cc.handshake_len);
522 tt_mem_op(cc.reply,OP_EQ, b, TAP_ONIONSKIN_REPLY_LEN + 10);
523 tt_int_op(0, OP_EQ, created_cell_format(&cell2, &cc));
524 tt_int_op(cell.command, OP_EQ, cell2.command);
525 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
527 /* A good CREATED_FAST cell */
528 memset(&cell, 0, sizeof(cell));
529 memset(b, 0, sizeof(b));
530 crypto_rand((char*)b, CREATED_FAST_LEN);
531 cell.command = CELL_CREATED_FAST;
532 memcpy(cell.payload, b, CREATED_FAST_LEN);
533 tt_int_op(0, OP_EQ, created_cell_parse(&cc, &cell));
534 tt_int_op(CELL_CREATED_FAST, OP_EQ, cc.cell_type);
535 tt_int_op(CREATED_FAST_LEN, OP_EQ, cc.handshake_len);
536 tt_mem_op(cc.reply,OP_EQ, b, CREATED_FAST_LEN + 10);
537 tt_int_op(0, OP_EQ, created_cell_format(&cell2, &cc));
538 tt_int_op(cell.command, OP_EQ, cell2.command);
539 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
541 /* A good CREATED2 cell with short reply */
542 memset(&cell, 0, sizeof(cell));
543 memset(b, 0, sizeof(b));
544 crypto_rand((char*)b, 64);
545 cell.command = CELL_CREATED2;
546 memcpy(cell.payload, "\x00\x40", 2);
547 memcpy(cell.payload+2, b, 64);
548 tt_int_op(0, OP_EQ, created_cell_parse(&cc, &cell));
549 tt_int_op(CELL_CREATED2, OP_EQ, cc.cell_type);
550 tt_int_op(64, OP_EQ, cc.handshake_len);
551 tt_mem_op(cc.reply,OP_EQ, b, 80);
552 tt_int_op(0, OP_EQ, created_cell_format(&cell2, &cc));
553 tt_int_op(cell.command, OP_EQ, cell2.command);
554 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
556 /* A good CREATED2 cell with maximal reply */
557 memset(&cell, 0, sizeof(cell));
558 memset(b, 0, sizeof(b));
559 crypto_rand((char*)b, 496);
560 cell.command = CELL_CREATED2;
561 memcpy(cell.payload, "\x01\xF0", 2);
562 memcpy(cell.payload+2, b, 496);
563 tt_int_op(0, OP_EQ, created_cell_parse(&cc, &cell));
564 tt_int_op(CELL_CREATED2, OP_EQ, cc.cell_type);
565 tt_int_op(496, OP_EQ, cc.handshake_len);
566 tt_mem_op(cc.reply,OP_EQ, b, 496);
567 tt_int_op(0, OP_EQ, created_cell_format(&cell2, &cc));
568 tt_int_op(cell.command, OP_EQ, cell2.command);
569 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
571 /* Bogus CREATED2 cell: too long! */
572 memset(&cell, 0, sizeof(cell));
573 memset(b, 0, sizeof(b));
574 crypto_rand((char*)b, 496);
575 cell.command = CELL_CREATED2;
576 memcpy(cell.payload, "\x01\xF1", 2);
577 tt_int_op(-1, OP_EQ, created_cell_parse(&cc, &cell));
579 /* Unformattable CREATED2 cell: too long! */
580 cc.handshake_len = 497;
581 tt_int_op(-1, OP_EQ, created_cell_format(&cell2, &cc));
583 done:
587 static void
588 test_cfmt_extend_cells(void *arg)
590 cell_t cell;
591 uint8_t b[512];
592 extend_cell_t ec;
593 create_cell_t *cc = &ec.create_cell;
594 uint8_t p[RELAY_PAYLOAD_SIZE];
595 uint8_t p2[RELAY_PAYLOAD_SIZE];
596 uint8_t p2_cmd;
597 uint16_t p2_len;
598 char *mem_op_hex_tmp = NULL;
600 (void) arg;
602 /* Let's start with a simple EXTEND cell. */
603 memset(p, 0, sizeof(p));
604 memset(b, 0, sizeof(b));
605 crypto_rand((char*)b, TAP_ONIONSKIN_CHALLENGE_LEN);
606 memcpy(p, "\x12\xf4\x00\x01\x01\x02", 6); /* 18 244 0 1 : 258 */
607 memcpy(p+6,b,TAP_ONIONSKIN_CHALLENGE_LEN);
608 memcpy(p+6+TAP_ONIONSKIN_CHALLENGE_LEN, "electroencephalogram", 20);
609 tt_int_op(0, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND,
610 p, 26+TAP_ONIONSKIN_CHALLENGE_LEN));
611 tt_int_op(RELAY_COMMAND_EXTEND, OP_EQ, ec.cell_type);
612 tt_str_op("18.244.0.1", OP_EQ, fmt_addr(&ec.orport_ipv4.addr));
613 tt_int_op(258, OP_EQ, ec.orport_ipv4.port);
614 tt_int_op(AF_UNSPEC, OP_EQ, tor_addr_family(&ec.orport_ipv6.addr));
615 tt_mem_op(ec.node_id,OP_EQ, "electroencephalogram", 20);
616 tt_int_op(cc->cell_type, OP_EQ, CELL_CREATE);
617 tt_int_op(cc->handshake_type, OP_EQ, ONION_HANDSHAKE_TYPE_TAP);
618 tt_int_op(cc->handshake_len, OP_EQ, TAP_ONIONSKIN_CHALLENGE_LEN);
619 tt_mem_op(cc->onionskin,OP_EQ, b, TAP_ONIONSKIN_CHALLENGE_LEN+20);
620 tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
621 tt_int_op(p2_cmd, OP_EQ, RELAY_COMMAND_EXTEND);
622 tt_int_op(p2_len, OP_EQ, 26+TAP_ONIONSKIN_CHALLENGE_LEN);
623 tt_mem_op(p2,OP_EQ, p, RELAY_PAYLOAD_SIZE);
625 /* Let's do an ntor stuffed in a legacy EXTEND cell */
626 memset(p, 0, sizeof(p));
627 memset(b, 0, sizeof(b));
628 crypto_rand((char*)b, NTOR_ONIONSKIN_LEN);
629 memcpy(p, "\x12\xf4\x00\x01\x01\x02", 6); /* 18 244 0 1 : 258 */
630 memcpy(p+6,"ntorNTORntorNTOR", 16);
631 memcpy(p+22, b, NTOR_ONIONSKIN_LEN);
632 memcpy(p+6+TAP_ONIONSKIN_CHALLENGE_LEN, "electroencephalogram", 20);
633 tt_int_op(0, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND,
634 p, 26+TAP_ONIONSKIN_CHALLENGE_LEN));
635 tt_int_op(RELAY_COMMAND_EXTEND, OP_EQ, ec.cell_type);
636 tt_str_op("18.244.0.1", OP_EQ, fmt_addr(&ec.orport_ipv4.addr));
637 tt_int_op(258, OP_EQ, ec.orport_ipv4.port);
638 tt_int_op(AF_UNSPEC, OP_EQ, tor_addr_family(&ec.orport_ipv6.addr));
639 tt_mem_op(ec.node_id,OP_EQ, "electroencephalogram", 20);
640 tt_int_op(cc->cell_type, OP_EQ, CELL_CREATE2);
641 tt_int_op(cc->handshake_type, OP_EQ, ONION_HANDSHAKE_TYPE_NTOR);
642 tt_int_op(cc->handshake_len, OP_EQ, NTOR_ONIONSKIN_LEN);
643 tt_mem_op(cc->onionskin,OP_EQ, b, NTOR_ONIONSKIN_LEN+20);
644 tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
645 tt_int_op(p2_cmd, OP_EQ, RELAY_COMMAND_EXTEND);
646 tt_int_op(p2_len, OP_EQ, 26+TAP_ONIONSKIN_CHALLENGE_LEN);
647 tt_mem_op(p2,OP_EQ, p, RELAY_PAYLOAD_SIZE);
648 tt_int_op(0, OP_EQ, create_cell_format_relayed(&cell, cc));
650 /* Now let's do a minimal ntor EXTEND2 cell. */
651 memset(&ec, 0xff, sizeof(ec));
652 memset(p, 0, sizeof(p));
653 memset(b, 0, sizeof(b));
654 crypto_rand((char*)b, NTOR_ONIONSKIN_LEN);
655 /* 2 items; one 18.244.0.1:61681 */
656 memcpy(p, "\x02\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
657 /* The other is a digest. */
658 memcpy(p+9, "\x02\x14" "anarchoindividualist", 22);
659 /* Prep for the handshake: type and length */
660 memcpy(p+31, "\x00\x02\x00\x54", 4);
661 memcpy(p+35, b, NTOR_ONIONSKIN_LEN);
662 tt_int_op(0, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
663 p, 35+NTOR_ONIONSKIN_LEN));
664 tt_int_op(RELAY_COMMAND_EXTEND2, OP_EQ, ec.cell_type);
665 tt_str_op("18.244.0.1", OP_EQ, fmt_addr(&ec.orport_ipv4.addr));
666 tt_int_op(61681, OP_EQ, ec.orport_ipv4.port);
667 tt_int_op(AF_UNSPEC, OP_EQ, tor_addr_family(&ec.orport_ipv6.addr));
668 tt_mem_op(ec.node_id,OP_EQ, "anarchoindividualist", 20);
669 tt_int_op(cc->cell_type, OP_EQ, CELL_CREATE2);
670 tt_int_op(cc->handshake_type, OP_EQ, ONION_HANDSHAKE_TYPE_NTOR);
671 tt_int_op(cc->handshake_len, OP_EQ, NTOR_ONIONSKIN_LEN);
672 tt_mem_op(cc->onionskin,OP_EQ, b, NTOR_ONIONSKIN_LEN+20);
673 tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
674 tt_int_op(p2_cmd, OP_EQ, RELAY_COMMAND_EXTEND2);
675 tt_int_op(p2_len, OP_EQ, 35+NTOR_ONIONSKIN_LEN);
676 tt_mem_op(p2,OP_EQ, p, RELAY_PAYLOAD_SIZE);
678 /* Now let's do a fanciful EXTEND2 cell. */
679 memset(&ec, 0xff, sizeof(ec));
680 memset(p, 0, sizeof(p));
681 memset(b, 0, sizeof(b));
682 crypto_rand((char*)b, 99);
683 /* 4 items; one 18 244 0 1 61681 */
684 memcpy(p, "\x04\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
685 /* One is a digest. */
686 memcpy(p+9, "\x02\x14" "anthropomorphization", 22);
687 /* One is an ipv6 address */
688 memcpy(p+31, "\x01\x12\x20\x02\x00\x00\x00\x00\x00\x00"
689 "\x00\x00\x00\x00\x00\xf0\xc5\x1e\x11\x12", 20);
690 /* One is the Konami code. */
691 memcpy(p+51, "\xf0\x20upupdowndownleftrightleftrightba", 34);
692 /* Prep for the handshake: weird type and length */
693 memcpy(p+85, "\x01\x05\x00\x63", 4);
694 memcpy(p+89, b, 99);
695 tt_int_op(0, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2, p, 89+99));
696 tt_int_op(RELAY_COMMAND_EXTEND2, OP_EQ, ec.cell_type);
697 tt_str_op("18.244.0.1", OP_EQ, fmt_addr(&ec.orport_ipv4.addr));
698 tt_int_op(61681, OP_EQ, ec.orport_ipv4.port);
699 tt_str_op("2002::f0:c51e", OP_EQ, fmt_addr(&ec.orport_ipv6.addr));
700 tt_int_op(4370, OP_EQ, ec.orport_ipv6.port);
701 tt_mem_op(ec.node_id,OP_EQ, "anthropomorphization", 20);
702 tt_int_op(cc->cell_type, OP_EQ, CELL_CREATE2);
703 tt_int_op(cc->handshake_type, OP_EQ, 0x105);
704 tt_int_op(cc->handshake_len, OP_EQ, 99);
705 tt_mem_op(cc->onionskin,OP_EQ, b, 99+20);
706 tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
707 tt_int_op(p2_cmd, OP_EQ, RELAY_COMMAND_EXTEND2);
708 /* We'll generate it minus the IPv6 address and minus the konami code */
709 tt_int_op(p2_len, OP_EQ, 89+99-34-20);
710 test_memeq_hex(p2,
711 /* Two items: one that same darn IP address. */
712 "02000612F40001F0F1"
713 /* The next is a digest : anthropomorphization */
714 "0214616e7468726f706f6d6f727068697a6174696f6e"
715 /* Now the handshake prologue */
716 "01050063");
717 tt_mem_op(p2+1+8+22+4,OP_EQ, b, 99+20);
718 tt_int_op(0, OP_EQ, create_cell_format_relayed(&cell, cc));
720 /* == Now try parsing some junk */
722 /* Try a too-long handshake */
723 memset(p, 0, sizeof(p));
724 memcpy(p, "\x02\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
725 memcpy(p+9, "\x02\x14" "anarchoindividualist", 22);
726 memcpy(p+31, "\xff\xff\x01\xd0", 4);
727 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
728 p, sizeof(p)));
730 /* Try two identities. */
731 memset(p, 0, sizeof(p));
732 memcpy(p, "\x03\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
733 memcpy(p+9, "\x02\x14" "anarchoindividualist", 22);
734 memcpy(p+31, "\x02\x14" "autodepolymerization", 22);
735 memcpy(p+53, "\xff\xff\x00\x10", 4);
736 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
737 p, sizeof(p)));
739 /* No identities. */
740 memset(p, 0, sizeof(p));
741 memcpy(p, "\x01\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
742 memcpy(p+53, "\xff\xff\x00\x10", 4);
743 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
744 p, sizeof(p)));
746 /* Try a bad IPv4 address (too long, too short)*/
747 memset(p, 0, sizeof(p));
748 memcpy(p, "\x02\x00\x07\x12\xf4\x00\x01\xf0\xf1\xff", 10);
749 memcpy(p+10, "\x02\x14" "anarchoindividualist", 22);
750 memcpy(p+32, "\xff\xff\x00\x10", 4);
751 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
752 p, sizeof(p)));
753 memset(p, 0, sizeof(p));
754 memcpy(p, "\x02\x00\x05\x12\xf4\x00\x01\xf0", 8);
755 memcpy(p+8, "\x02\x14" "anarchoindividualist", 22);
756 memcpy(p+30, "\xff\xff\x00\x10", 4);
757 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
758 p, sizeof(p)));
760 /* IPv6 address (too long, too short, no IPv4)*/
761 memset(p, 0, sizeof(p));
762 memcpy(p, "\x03\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
763 memcpy(p+9, "\x02\x14" "anarchoindividualist", 22);
764 memcpy(p+31, "\x01\x13" "xxxxxxxxxxxxxxxxYYZ", 19);
765 memcpy(p+50, "\xff\xff\x00\x20", 4);
766 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
767 p, sizeof(p)));
768 memset(p, 0, sizeof(p));
769 memcpy(p, "\x03\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
770 memcpy(p+9, "\x02\x14" "anarchoindividualist", 22);
771 memcpy(p+31, "\x01\x11" "xxxxxxxxxxxxxxxxY", 17);
772 memcpy(p+48, "\xff\xff\x00\x20", 4);
773 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
774 p, sizeof(p)));
775 memset(p, 0, sizeof(p));
776 memcpy(p, "\x02", 1);
777 memcpy(p+1, "\x02\x14" "anarchoindividualist", 22);
778 memcpy(p+23, "\x01\x12" "xxxxxxxxxxxxxxxxYY", 18);
779 memcpy(p+41, "\xff\xff\x00\x20", 4);
780 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
781 p, sizeof(p)));
783 /* Running out of space in specifiers */
784 memset(p,0,sizeof(p));
785 memcpy(p, "\x05\x0a\xff", 3);
786 memcpy(p+3+255, "\x0a\xff", 2);
787 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
788 p, sizeof(p)));
790 /* Fuzz, because why not. */
791 memset(&ec, 0xff, sizeof(ec));
793 int i;
794 memset(p, 0, sizeof(p));
795 for (i = 0; i < 10000; ++i) {
796 int n = crypto_rand_int(sizeof(p));
797 crypto_rand((char *)p, n);
798 extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2, p, n);
802 done:
803 tor_free(mem_op_hex_tmp);
806 static void
807 test_cfmt_extended_cells(void *arg)
809 uint8_t b[512];
810 extended_cell_t ec;
811 created_cell_t *cc = &ec.created_cell;
812 uint8_t p[RELAY_PAYLOAD_SIZE];
813 uint8_t p2[RELAY_PAYLOAD_SIZE];
814 uint8_t p2_cmd;
815 uint16_t p2_len;
816 char *mem_op_hex_tmp = NULL;
818 (void) arg;
820 /* Try a regular EXTENDED cell. */
821 memset(&ec, 0xff, sizeof(ec));
822 memset(p, 0, sizeof(p));
823 memset(b, 0, sizeof(b));
824 crypto_rand((char*)b, TAP_ONIONSKIN_REPLY_LEN);
825 memcpy(p,b,TAP_ONIONSKIN_REPLY_LEN);
826 tt_int_op(0, OP_EQ, extended_cell_parse(&ec, RELAY_COMMAND_EXTENDED, p,
827 TAP_ONIONSKIN_REPLY_LEN));
828 tt_int_op(RELAY_COMMAND_EXTENDED, OP_EQ, ec.cell_type);
829 tt_int_op(cc->cell_type, OP_EQ, CELL_CREATED);
830 tt_int_op(cc->handshake_len, OP_EQ, TAP_ONIONSKIN_REPLY_LEN);
831 tt_mem_op(cc->reply,OP_EQ, b, TAP_ONIONSKIN_REPLY_LEN);
832 tt_int_op(0, OP_EQ, extended_cell_format(&p2_cmd, &p2_len, p2, &ec));
833 tt_int_op(RELAY_COMMAND_EXTENDED, OP_EQ, p2_cmd);
834 tt_int_op(TAP_ONIONSKIN_REPLY_LEN, OP_EQ, p2_len);
835 tt_mem_op(p2,OP_EQ, p, sizeof(p2));
837 /* Try an EXTENDED2 cell */
838 memset(&ec, 0xff, sizeof(ec));
839 memset(p, 0, sizeof(p));
840 memset(b, 0, sizeof(b));
841 crypto_rand((char*)b, 42);
842 memcpy(p,"\x00\x2a",2);
843 memcpy(p+2,b,42);
844 tt_int_op(0, OP_EQ,
845 extended_cell_parse(&ec, RELAY_COMMAND_EXTENDED2, p, 2+42));
846 tt_int_op(RELAY_COMMAND_EXTENDED2, OP_EQ, ec.cell_type);
847 tt_int_op(cc->cell_type, OP_EQ, CELL_CREATED2);
848 tt_int_op(cc->handshake_len, OP_EQ, 42);
849 tt_mem_op(cc->reply,OP_EQ, b, 42+10);
850 tt_int_op(0, OP_EQ, extended_cell_format(&p2_cmd, &p2_len, p2, &ec));
851 tt_int_op(RELAY_COMMAND_EXTENDED2, OP_EQ, p2_cmd);
852 tt_int_op(2+42, OP_EQ, p2_len);
853 tt_mem_op(p2,OP_EQ, p, sizeof(p2));
855 /* Try an almost-too-long EXTENDED2 cell */
856 memcpy(p, "\x01\xf0", 2);
857 tt_int_op(0, OP_EQ,
858 extended_cell_parse(&ec, RELAY_COMMAND_EXTENDED2, p, sizeof(p)));
860 /* Now try a too-long extended2 cell. That's the only misparse I can think
861 * of. */
862 memcpy(p, "\x01\xf1", 2);
863 tt_int_op(-1, OP_EQ,
864 extended_cell_parse(&ec, RELAY_COMMAND_EXTENDED2, p, sizeof(p)));
866 done:
867 tor_free(mem_op_hex_tmp);
870 static void
871 test_cfmt_resolved_cells(void *arg)
873 smartlist_t *addrs = smartlist_new();
874 relay_header_t rh;
875 cell_t cell;
876 int r, errcode;
877 address_ttl_t *a;
879 (void)arg;
880 #define CLEAR_CELL() do { \
881 memset(&cell, 0, sizeof(cell)); \
882 memset(&rh, 0, sizeof(rh)); \
883 } while (0)
884 #define CLEAR_ADDRS() do { \
885 SMARTLIST_FOREACH(addrs, address_ttl_t *, a, \
886 address_ttl_free(a); ); \
887 smartlist_clear(addrs); \
888 } while (0)
889 #define SET_CELL(s) do { \
890 CLEAR_CELL(); \
891 memcpy(cell.payload + RELAY_HEADER_SIZE, (s), sizeof((s))-1); \
892 rh.length = sizeof((s))-1; \
893 rh.command = RELAY_COMMAND_RESOLVED; \
894 errcode = -1; \
895 } while (0)
897 /* The cell format is one or more answers; each of the form
898 * type [1 byte---0:hostname, 4:ipv4, 6:ipv6, f0:err-transient, f1:err]
899 * length [1 byte]
900 * body [length bytes]
901 * ttl [4 bytes]
904 /* Let's try an empty cell */
905 SET_CELL("");
906 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
907 tt_int_op(errcode, OP_EQ, 0);
908 tt_int_op(r, OP_EQ, 0);
909 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
910 CLEAR_ADDRS(); /* redundant but let's be consistent */
912 /* Cell with one ipv4 addr */
913 SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00");
914 tt_int_op(rh.length, OP_EQ, 10);
915 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
916 tt_int_op(errcode, OP_EQ, 0);
917 tt_int_op(r, OP_EQ, 0);
918 tt_int_op(smartlist_len(addrs), OP_EQ, 1);
919 a = smartlist_get(addrs, 0);
920 tt_str_op(fmt_addr(&a->addr), OP_EQ, "127.0.2.10");
921 tt_ptr_op(a->hostname, OP_EQ, NULL);
922 tt_int_op(a->ttl, OP_EQ, 256);
923 CLEAR_ADDRS();
925 /* Cell with one ipv6 addr */
926 SET_CELL("\x06\x10"
927 "\x20\x02\x90\x90\x00\x00\x00\x00"
928 "\x00\x00\x00\x00\xf0\xf0\xab\xcd"
929 "\x02\00\x00\x01");
930 tt_int_op(rh.length, OP_EQ, 22);
931 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
932 tt_int_op(errcode, OP_EQ, 0);
933 tt_int_op(r, OP_EQ, 0);
934 tt_int_op(smartlist_len(addrs), OP_EQ, 1);
935 a = smartlist_get(addrs, 0);
936 tt_str_op(fmt_addr(&a->addr), OP_EQ, "2002:9090::f0f0:abcd");
937 tt_ptr_op(a->hostname, OP_EQ, NULL);
938 tt_int_op(a->ttl, OP_EQ, 0x2000001);
939 CLEAR_ADDRS();
941 /* Cell with one hostname */
942 SET_CELL("\x00\x11"
943 "motherbrain.zebes"
944 "\x00\00\x00\x00");
945 tt_int_op(rh.length, OP_EQ, 23);
946 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
947 tt_int_op(errcode, OP_EQ, 0);
948 tt_int_op(r, OP_EQ, 0);
949 tt_int_op(smartlist_len(addrs), OP_EQ, 1);
950 a = smartlist_get(addrs, 0);
951 tt_assert(tor_addr_is_null(&a->addr));
952 tt_str_op(a->hostname, OP_EQ, "motherbrain.zebes");
953 tt_int_op(a->ttl, OP_EQ, 0);
954 CLEAR_ADDRS();
956 #define LONG_NAME \
957 "this-hostname-has-255-characters.in-order-to-test-whether-very-long.ho" \
958 "stnames-are-accepted.i-am-putting-it-in-a-macro-because-although.this-" \
959 "function-is-already-very-full.of-copy-and-pasted-stuff.having-this-app" \
960 "ear-more-than-once-would-bother-me-somehow.is"
962 tt_int_op(strlen(LONG_NAME), OP_EQ, 255);
963 SET_CELL("\x00\xff"
964 LONG_NAME
965 "\x00\01\x00\x00");
966 tt_int_op(rh.length, OP_EQ, 261);
967 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
968 tt_int_op(errcode, OP_EQ, 0);
969 tt_int_op(r, OP_EQ, 0);
970 tt_int_op(smartlist_len(addrs), OP_EQ, 1);
971 a = smartlist_get(addrs, 0);
972 tt_assert(tor_addr_is_null(&a->addr));
973 tt_str_op(a->hostname, OP_EQ, LONG_NAME);
974 tt_int_op(a->ttl, OP_EQ, 65536);
975 CLEAR_ADDRS();
977 /* Cells with an error */
978 SET_CELL("\xf0\x2b"
979 "I'm sorry, Dave. I'm afraid I can't do that"
980 "\x00\x11\x22\x33");
981 tt_int_op(rh.length, OP_EQ, 49);
982 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
983 tt_int_op(errcode, OP_EQ, RESOLVED_TYPE_ERROR_TRANSIENT);
984 tt_int_op(r, OP_EQ, 0);
985 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
986 CLEAR_ADDRS();
988 SET_CELL("\xf1\x40"
989 "This hostname is too important for me to allow you to resolve it"
990 "\x00\x00\x00\x00");
991 tt_int_op(rh.length, OP_EQ, 70);
992 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
993 tt_int_op(errcode, OP_EQ, RESOLVED_TYPE_ERROR);
994 tt_int_op(r, OP_EQ, 0);
995 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
996 CLEAR_ADDRS();
998 /* Cell with an unrecognized type */
999 SET_CELL("\xee\x16"
1000 "fault in the AE35 unit"
1001 "\x09\x09\x01\x01");
1002 tt_int_op(rh.length, OP_EQ, 28);
1003 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1004 tt_int_op(errcode, OP_EQ, 0);
1005 tt_int_op(r, OP_EQ, 0);
1006 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1007 CLEAR_ADDRS();
1009 /* Cell with one of each */
1010 SET_CELL(/* unrecognized: */
1011 "\xee\x16"
1012 "fault in the AE35 unit"
1013 "\x09\x09\x01\x01"
1014 /* error: */
1015 "\xf0\x2b"
1016 "I'm sorry, Dave. I'm afraid I can't do that"
1017 "\x00\x11\x22\x33"
1018 /* IPv6: */
1019 "\x06\x10"
1020 "\x20\x02\x90\x90\x00\x00\x00\x00"
1021 "\x00\x00\x00\x00\xf0\xf0\xab\xcd"
1022 "\x02\00\x00\x01"
1023 /* IPv4: */
1024 "\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00"
1025 /* Hostname: */
1026 "\x00\x11"
1027 "motherbrain.zebes"
1028 "\x00\00\x00\x00"
1030 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1031 tt_int_op(errcode, OP_EQ, 0); /* no error reported; we got answers */
1032 tt_int_op(r, OP_EQ, 0);
1033 tt_int_op(smartlist_len(addrs), OP_EQ, 3);
1034 a = smartlist_get(addrs, 0);
1035 tt_str_op(fmt_addr(&a->addr), OP_EQ, "2002:9090::f0f0:abcd");
1036 tt_ptr_op(a->hostname, OP_EQ, NULL);
1037 tt_int_op(a->ttl, OP_EQ, 0x2000001);
1038 a = smartlist_get(addrs, 1);
1039 tt_str_op(fmt_addr(&a->addr), OP_EQ, "127.0.2.10");
1040 tt_ptr_op(a->hostname, OP_EQ, NULL);
1041 tt_int_op(a->ttl, OP_EQ, 256);
1042 a = smartlist_get(addrs, 2);
1043 tt_assert(tor_addr_is_null(&a->addr));
1044 tt_str_op(a->hostname, OP_EQ, "motherbrain.zebes");
1045 tt_int_op(a->ttl, OP_EQ, 0);
1046 CLEAR_ADDRS();
1048 /* Cell with several of similar type */
1049 SET_CELL(/* IPv4 */
1050 "\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00"
1051 "\x04\x04" "\x08\x08\x08\x08" "\x00\00\x01\x05"
1052 "\x04\x04" "\x7f\xb0\x02\xb0" "\x00\01\xff\xff"
1053 /* IPv6 */
1054 "\x06\x10"
1055 "\x20\x02\x90\x00\x00\x00\x00\x00"
1056 "\x00\x00\x00\x00\xca\xfe\xf0\x0d"
1057 "\x00\00\x00\x01"
1058 "\x06\x10"
1059 "\x20\x02\x90\x01\x00\x00\x00\x00"
1060 "\x00\x00\x00\x00\x00\xfa\xca\xde"
1061 "\x00\00\x00\x03");
1062 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1063 tt_int_op(errcode, OP_EQ, 0);
1064 tt_int_op(r, OP_EQ, 0);
1065 tt_int_op(smartlist_len(addrs), OP_EQ, 5);
1066 a = smartlist_get(addrs, 0);
1067 tt_str_op(fmt_addr(&a->addr), OP_EQ, "127.0.2.10");
1068 tt_ptr_op(a->hostname, OP_EQ, NULL);
1069 tt_int_op(a->ttl, OP_EQ, 256);
1070 a = smartlist_get(addrs, 1);
1071 tt_str_op(fmt_addr(&a->addr), OP_EQ, "8.8.8.8");
1072 tt_ptr_op(a->hostname, OP_EQ, NULL);
1073 tt_int_op(a->ttl, OP_EQ, 261);
1074 a = smartlist_get(addrs, 2);
1075 tt_str_op(fmt_addr(&a->addr), OP_EQ, "127.176.2.176");
1076 tt_ptr_op(a->hostname, OP_EQ, NULL);
1077 tt_int_op(a->ttl, OP_EQ, 131071);
1078 a = smartlist_get(addrs, 3);
1079 tt_str_op(fmt_addr(&a->addr), OP_EQ, "2002:9000::cafe:f00d");
1080 tt_ptr_op(a->hostname, OP_EQ, NULL);
1081 tt_int_op(a->ttl, OP_EQ, 1);
1082 a = smartlist_get(addrs, 4);
1083 tt_str_op(fmt_addr(&a->addr), OP_EQ, "2002:9001::fa:cade");
1084 tt_ptr_op(a->hostname, OP_EQ, NULL);
1085 tt_int_op(a->ttl, OP_EQ, 3);
1086 CLEAR_ADDRS();
1088 /* Full cell */
1089 #define LONG_NAME2 \
1090 "this-name-has-231-characters.so-that-it-plus-LONG_NAME-can-completely-" \
1091 "fill-up-the-payload-of-a-cell.its-important-to-check-for-the-full-thin" \
1092 "g-case.to-avoid-off-by-one-errors.where-full-things-are-misreported-as" \
1093 ".overflowing-by-one.z"
1095 tt_int_op(strlen(LONG_NAME2), OP_EQ, 231);
1096 SET_CELL("\x00\xff"
1097 LONG_NAME
1098 "\x00\01\x00\x00"
1099 "\x00\xe7"
1100 LONG_NAME2
1101 "\x00\01\x00\x00");
1102 tt_int_op(rh.length, OP_EQ, RELAY_PAYLOAD_SIZE);
1103 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1104 tt_int_op(errcode, OP_EQ, 0);
1105 tt_int_op(r, OP_EQ, 0);
1106 tt_int_op(smartlist_len(addrs), OP_EQ, 2);
1107 a = smartlist_get(addrs, 0);
1108 tt_str_op(a->hostname, OP_EQ, LONG_NAME);
1109 a = smartlist_get(addrs, 1);
1110 tt_str_op(a->hostname, OP_EQ, LONG_NAME2);
1111 CLEAR_ADDRS();
1113 /* BAD CELLS */
1115 /* Invalid length on an IPv4 */
1116 SET_CELL("\x04\x03zzz1234");
1117 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1118 tt_int_op(errcode, OP_EQ, 0);
1119 tt_int_op(r, OP_EQ, -1);
1120 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1121 SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00"
1122 "\x04\x05zzzzz1234");
1123 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1124 tt_int_op(errcode, OP_EQ, 0);
1125 tt_int_op(r, OP_EQ, -1);
1126 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1128 /* Invalid length on an IPv6 */
1129 SET_CELL("\x06\x03zzz1234");
1130 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1131 tt_int_op(errcode, OP_EQ, 0);
1132 tt_int_op(r, OP_EQ, -1);
1133 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1134 SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00"
1135 "\x06\x17wwwwwwwwwwwwwwwww1234");
1136 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1137 tt_int_op(errcode, OP_EQ, 0);
1138 tt_int_op(r, OP_EQ, -1);
1139 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1140 SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00"
1141 "\x06\x10xxxx");
1142 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1143 tt_int_op(errcode, OP_EQ, 0);
1144 tt_int_op(r, OP_EQ, -1);
1145 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1147 /* Empty hostname */
1148 SET_CELL("\x00\x00xxxx");
1149 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1150 tt_int_op(errcode, OP_EQ, 0);
1151 tt_int_op(r, OP_EQ, -1);
1152 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1154 /* rh.length out of range */
1155 CLEAR_CELL();
1156 rh.length = 499;
1157 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1158 tt_int_op(errcode, OP_EQ, 0);
1159 tt_int_op(r, OP_EQ, -1);
1160 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1162 /* Item length extends beyond rh.length */
1163 CLEAR_CELL();
1164 SET_CELL("\x00\xff"
1165 LONG_NAME
1166 "\x00\01\x00\x00");
1167 rh.length -= 1;
1168 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1169 tt_int_op(r, OP_EQ, -1);
1170 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1171 rh.length -= 5;
1172 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1173 tt_int_op(r, OP_EQ, -1);
1174 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1176 SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00");
1177 rh.length -= 1;
1178 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1179 tt_int_op(r, OP_EQ, -1);
1180 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1182 SET_CELL("\xee\x10"
1183 "\x20\x02\x90\x01\x00\x00\x00\x00"
1184 "\x00\x00\x00\x00\x00\xfa\xca\xde"
1185 "\x00\00\x00\x03");
1186 rh.length -= 1;
1187 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1188 tt_int_op(r, OP_EQ, -1);
1189 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1191 /* Truncated item after first character */
1192 SET_CELL("\x04");
1193 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1194 tt_int_op(r, OP_EQ, -1);
1195 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1197 SET_CELL("\xee");
1198 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1199 tt_int_op(r, OP_EQ, -1);
1200 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1202 done:
1203 CLEAR_ADDRS();
1204 CLEAR_CELL();
1205 smartlist_free(addrs);
1206 #undef CLEAR_ADDRS
1207 #undef CLEAR_CELL
1210 static void
1211 test_cfmt_is_destroy(void *arg)
1213 cell_t cell;
1214 packed_cell_t packed;
1215 circid_t circid = 0;
1216 channel_t *chan;
1217 (void)arg;
1219 chan = tor_malloc_zero(sizeof(channel_t));
1221 memset(&cell, 0xff, sizeof(cell));
1222 cell.circ_id = 3003;
1223 cell.command = CELL_RELAY;
1225 cell_pack(&packed, &cell, 0);
1226 chan->wide_circ_ids = 0;
1227 tt_assert(! packed_cell_is_destroy(chan, &packed, &circid));
1228 tt_int_op(circid, OP_EQ, 0);
1230 cell_pack(&packed, &cell, 1);
1231 chan->wide_circ_ids = 1;
1232 tt_assert(! packed_cell_is_destroy(chan, &packed, &circid));
1233 tt_int_op(circid, OP_EQ, 0);
1235 cell.command = CELL_DESTROY;
1237 cell_pack(&packed, &cell, 0);
1238 chan->wide_circ_ids = 0;
1239 tt_assert(packed_cell_is_destroy(chan, &packed, &circid));
1240 tt_int_op(circid, OP_EQ, 3003);
1242 circid = 0;
1243 cell_pack(&packed, &cell, 1);
1244 chan->wide_circ_ids = 1;
1245 tt_assert(packed_cell_is_destroy(chan, &packed, &circid));
1247 done:
1248 tor_free(chan);
1251 #define TEST(name, flags) \
1252 { #name, test_cfmt_ ## name, flags, 0, NULL }
1254 struct testcase_t cell_format_tests[] = {
1255 TEST(relay_header, 0),
1256 TEST(begin_cells, 0),
1257 TEST(connected_cells, 0),
1258 TEST(create_cells, 0),
1259 TEST(created_cells, 0),
1260 TEST(extend_cells, 0),
1261 TEST(extended_cells, 0),
1262 TEST(resolved_cells, 0),
1263 TEST(is_destroy, 0),
1264 END_OF_TESTCASES