Merge branch 'maint-0.4.8'
[tor.git] / src / test / test_cell_formats.c
blobb7b149cd668ae52d509b6df69b30fc4bbc2a7923
1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2021, 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 "core/or/or.h"
11 #include "core/or/channel.h"
12 #include "core/or/connection_edge.h"
13 #include "core/or/connection_or.h"
14 #include "app/config/config.h"
15 #include "lib/crypt_ops/crypto_rand.h"
16 #include "core/or/onion.h"
17 #include "core/crypto/onion_tap.h"
18 #include "core/crypto/onion_fast.h"
19 #include "core/crypto/onion_ntor.h"
20 #include "core/or/relay.h"
22 #include "core/or/cell_st.h"
23 #include "core/or/cell_queue_st.h"
24 #include "core/or/var_cell_st.h"
26 #include "test/test.h"
28 #include <stdlib.h>
29 #include <string.h>
31 static void
32 test_cfmt_relay_header(void *arg)
34 relay_header_t rh;
35 const uint8_t hdr_1[RELAY_HEADER_SIZE] =
36 "\x03" "\x00\x00" "\x21\x22" "ABCD" "\x01\x03";
37 uint8_t hdr_out[RELAY_HEADER_SIZE];
38 (void)arg;
40 tt_int_op(sizeof(hdr_1), OP_EQ, RELAY_HEADER_SIZE);
41 relay_header_unpack(&rh, hdr_1);
42 tt_int_op(rh.command, OP_EQ, 3);
43 tt_int_op(rh.recognized, OP_EQ, 0);
44 tt_int_op(rh.stream_id, OP_EQ, 0x2122);
45 tt_mem_op(rh.integrity, OP_EQ, "ABCD", 4);
46 tt_int_op(rh.length, OP_EQ, 0x103);
48 relay_header_pack(hdr_out, &rh);
49 tt_mem_op(hdr_out, OP_EQ, hdr_1, RELAY_HEADER_SIZE);
51 done:
55 static void
56 make_relay_cell(cell_t *out, uint8_t command,
57 const void *body, size_t bodylen)
59 relay_header_t rh;
61 memset(&rh, 0, sizeof(rh));
62 rh.stream_id = 5;
63 rh.command = command;
64 rh.length = bodylen;
66 out->command = CELL_RELAY;
67 out->circ_id = 10;
68 relay_header_pack(out->payload, &rh);
70 memcpy(out->payload + RELAY_HEADER_SIZE, body, bodylen);
73 static void
74 test_cfmt_begin_cells(void *arg)
76 cell_t cell;
77 begin_cell_t bcell;
78 uint8_t end_reason;
79 (void)arg;
81 /* Try begindir. */
82 memset(&bcell, 0x7f, sizeof(bcell));
83 make_relay_cell(&cell, RELAY_COMMAND_BEGIN_DIR, "", 0);
84 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
85 tt_ptr_op(NULL, OP_EQ, bcell.address);
86 tt_int_op(0, OP_EQ, bcell.flags);
87 tt_int_op(0, OP_EQ, bcell.port);
88 tt_int_op(5, OP_EQ, bcell.stream_id);
89 tt_int_op(1, OP_EQ, bcell.is_begindir);
91 /* A Begindir with extra stuff. */
92 memset(&bcell, 0x7f, sizeof(bcell));
93 make_relay_cell(&cell, RELAY_COMMAND_BEGIN_DIR, "12345", 5);
94 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
95 tt_ptr_op(NULL, OP_EQ, bcell.address);
96 tt_int_op(0, OP_EQ, bcell.flags);
97 tt_int_op(0, OP_EQ, bcell.port);
98 tt_int_op(5, OP_EQ, bcell.stream_id);
99 tt_int_op(1, OP_EQ, bcell.is_begindir);
101 /* A short but valid begin cell */
102 memset(&bcell, 0x7f, sizeof(bcell));
103 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:9", 6);
104 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
105 tt_str_op("a.b", OP_EQ, bcell.address);
106 tt_int_op(0, OP_EQ, bcell.flags);
107 tt_int_op(9, OP_EQ, bcell.port);
108 tt_int_op(5, OP_EQ, bcell.stream_id);
109 tt_int_op(0, OP_EQ, bcell.is_begindir);
110 tor_free(bcell.address);
112 /* A significantly loner begin cell */
113 memset(&bcell, 0x7f, sizeof(bcell));
115 const char c[] = "here-is-a-nice-long.hostname.com:65535";
116 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, strlen(c)+1);
118 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
119 tt_str_op("here-is-a-nice-long.hostname.com", OP_EQ, bcell.address);
120 tt_int_op(0, OP_EQ, bcell.flags);
121 tt_int_op(65535, OP_EQ, bcell.port);
122 tt_int_op(5, OP_EQ, bcell.stream_id);
123 tt_int_op(0, OP_EQ, bcell.is_begindir);
124 tor_free(bcell.address);
126 /* An IPv4 begin cell. */
127 memset(&bcell, 0x7f, sizeof(bcell));
128 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "18.9.22.169:80", 15);
129 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
130 tt_str_op("18.9.22.169", OP_EQ, bcell.address);
131 tt_int_op(0, OP_EQ, bcell.flags);
132 tt_int_op(80, OP_EQ, bcell.port);
133 tt_int_op(5, OP_EQ, bcell.stream_id);
134 tt_int_op(0, OP_EQ, bcell.is_begindir);
135 tor_free(bcell.address);
137 /* An IPv6 begin cell. Let's make sure we handle colons*/
138 memset(&bcell, 0x7f, sizeof(bcell));
139 make_relay_cell(&cell, RELAY_COMMAND_BEGIN,
140 "[2620::6b0:b:1a1a:0:26e5:480e]:80", 34);
141 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
142 tt_str_op("[2620::6b0:b:1a1a:0:26e5:480e]", OP_EQ, bcell.address);
143 tt_int_op(0, OP_EQ, bcell.flags);
144 tt_int_op(80, OP_EQ, bcell.port);
145 tt_int_op(5, OP_EQ, bcell.stream_id);
146 tt_int_op(0, OP_EQ, bcell.is_begindir);
147 tor_free(bcell.address);
149 /* a begin cell with extra junk but not enough for flags. */
150 memset(&bcell, 0x7f, sizeof(bcell));
152 const char c[] = "another.example.com:80\x00\x01\x02";
153 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
155 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
156 tt_str_op("another.example.com", OP_EQ, bcell.address);
157 tt_int_op(0, OP_EQ, bcell.flags);
158 tt_int_op(80, OP_EQ, bcell.port);
159 tt_int_op(5, OP_EQ, bcell.stream_id);
160 tt_int_op(0, OP_EQ, bcell.is_begindir);
161 tor_free(bcell.address);
163 /* a begin cell with flags. */
164 memset(&bcell, 0x7f, sizeof(bcell));
166 const char c[] = "another.example.com:443\x00\x01\x02\x03\x04";
167 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
169 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
170 tt_str_op("another.example.com", OP_EQ, bcell.address);
171 tt_int_op(0x1020304, OP_EQ, bcell.flags);
172 tt_int_op(443, OP_EQ, bcell.port);
173 tt_int_op(5, OP_EQ, bcell.stream_id);
174 tt_int_op(0, OP_EQ, bcell.is_begindir);
175 tor_free(bcell.address);
177 /* a begin cell with flags and even more cruft after that. */
178 memset(&bcell, 0x7f, sizeof(bcell));
180 const char c[] = "a-further.example.com:22\x00\xee\xaa\x00\xffHi mom";
181 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
183 tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
184 tt_str_op("a-further.example.com", OP_EQ, bcell.address);
185 tt_int_op(0xeeaa00ff, OP_EQ, bcell.flags);
186 tt_int_op(22, OP_EQ, bcell.port);
187 tt_int_op(5, OP_EQ, bcell.stream_id);
188 tt_int_op(0, OP_EQ, bcell.is_begindir);
189 tor_free(bcell.address);
191 /* bad begin cell: impossible length. */
192 memset(&bcell, 0x7f, sizeof(bcell));
193 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:80", 7);
194 cell.payload[9] = 0x01; /* Set length to 510 */
195 cell.payload[10] = 0xfe;
197 relay_header_t rh;
198 relay_header_unpack(&rh, cell.payload);
199 tt_int_op(rh.length, OP_EQ, 510);
201 tt_int_op(-2, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
203 /* Bad begin cell: no body. */
204 memset(&bcell, 0x7f, sizeof(bcell));
205 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "", 0);
206 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
208 /* bad begin cell: no body. */
209 memset(&bcell, 0x7f, sizeof(bcell));
210 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "", 0);
211 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
213 /* bad begin cell: no colon */
214 memset(&bcell, 0x7f, sizeof(bcell));
215 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b", 4);
216 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
218 /* bad begin cell: no ports */
219 memset(&bcell, 0x7f, sizeof(bcell));
220 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:", 5);
221 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
223 /* bad begin cell: bad port */
224 memset(&bcell, 0x7f, sizeof(bcell));
225 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:xyz", 8);
226 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
227 memset(&bcell, 0x7f, sizeof(bcell));
228 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:100000", 11);
229 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
231 /* bad begin cell: no nul */
232 memset(&bcell, 0x7f, sizeof(bcell));
233 make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:80", 6);
234 tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
236 done:
237 tor_free(bcell.address);
240 static void
241 test_cfmt_connected_cells(void *arg)
243 relay_header_t rh;
244 cell_t cell;
245 tor_addr_t addr;
246 int ttl, r;
247 char *mem_op_hex_tmp = NULL;
248 (void)arg;
250 /* Let's try an oldschool one with nothing in it. */
251 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "", 0);
252 relay_header_unpack(&rh, cell.payload);
253 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
254 tt_int_op(r, OP_EQ, 0);
255 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_UNSPEC);
256 tt_int_op(ttl, OP_EQ, -1);
258 /* A slightly less oldschool one: only an IPv4 address */
259 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x20\x30\x40\x50", 4);
260 relay_header_unpack(&rh, cell.payload);
261 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
262 tt_int_op(r, OP_EQ, 0);
263 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
264 tt_str_op(fmt_addr(&addr), OP_EQ, "32.48.64.80");
265 tt_int_op(ttl, OP_EQ, -1);
267 /* Bogus but understandable: truncated TTL */
268 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x11\x12\x13\x14\x15", 5);
269 relay_header_unpack(&rh, cell.payload);
270 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
271 tt_int_op(r, OP_EQ, 0);
272 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
273 tt_str_op(fmt_addr(&addr), OP_EQ, "17.18.19.20");
274 tt_int_op(ttl, OP_EQ, -1);
276 /* Regular IPv4 one: address and TTL */
277 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
278 "\x02\x03\x04\x05\x00\x00\x0e\x10", 8);
279 relay_header_unpack(&rh, cell.payload);
280 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
281 tt_int_op(r, OP_EQ, 0);
282 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
283 tt_str_op(fmt_addr(&addr), OP_EQ, "2.3.4.5");
284 tt_int_op(ttl, OP_EQ, 3600);
286 /* IPv4 with too-big TTL */
287 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
288 "\x02\x03\x04\x05\xf0\x00\x00\x00", 8);
289 relay_header_unpack(&rh, cell.payload);
290 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
291 tt_int_op(r, OP_EQ, 0);
292 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
293 tt_str_op(fmt_addr(&addr), OP_EQ, "2.3.4.5");
294 tt_int_op(ttl, OP_EQ, -1);
296 /* IPv6 (ttl is mandatory) */
297 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
298 "\x00\x00\x00\x00\x06"
299 "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
300 "\x00\x00\x00\x00\x00\x00\x00\x68"
301 "\x00\x00\x02\x58", 25);
302 relay_header_unpack(&rh, cell.payload);
303 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
304 tt_int_op(r, OP_EQ, 0);
305 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET6);
306 tt_str_op(fmt_addr(&addr), OP_EQ, "2607:f8b0:400c:c02::68");
307 tt_int_op(ttl, OP_EQ, 600);
309 /* IPv6 (ttl too big) */
310 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
311 "\x00\x00\x00\x00\x06"
312 "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
313 "\x00\x00\x00\x00\x00\x00\x00\x68"
314 "\x90\x00\x02\x58", 25);
315 relay_header_unpack(&rh, cell.payload);
316 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
317 tt_int_op(r, OP_EQ, 0);
318 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET6);
319 tt_str_op(fmt_addr(&addr), OP_EQ, "2607:f8b0:400c:c02::68");
320 tt_int_op(ttl, OP_EQ, -1);
322 /* Bogus size: 3. */
323 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
324 "\x00\x01\x02", 3);
325 relay_header_unpack(&rh, cell.payload);
326 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
327 tt_int_op(r, OP_EQ, -1);
329 /* Bogus family: 7. */
330 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
331 "\x00\x00\x00\x00\x07"
332 "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
333 "\x00\x00\x00\x00\x00\x00\x00\x68"
334 "\x90\x00\x02\x58", 25);
335 relay_header_unpack(&rh, cell.payload);
336 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
337 tt_int_op(r, OP_EQ, -1);
339 /* Truncated IPv6. */
340 make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
341 "\x00\x00\x00\x00\x06"
342 "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
343 "\x00\x00\x00\x00\x00\x00\x00\x68"
344 "\x00\x00\x02", 24);
345 relay_header_unpack(&rh, cell.payload);
346 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
347 tt_int_op(r, OP_EQ, -1);
349 /* Now make sure we can generate connected cells correctly. */
350 /* Try an IPv4 address */
351 memset(&rh, 0, sizeof(rh));
352 memset(&cell, 0, sizeof(cell));
353 tor_addr_parse(&addr, "30.40.50.60");
354 rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE,
355 &addr, 1024);
356 tt_int_op(rh.length, OP_EQ, 8);
357 test_memeq_hex(cell.payload+RELAY_HEADER_SIZE, "1e28323c" "00000400");
359 /* Try parsing it. */
360 tor_addr_make_unspec(&addr);
361 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
362 tt_int_op(r, OP_EQ, 0);
363 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
364 tt_str_op(fmt_addr(&addr), OP_EQ, "30.40.50.60");
365 tt_int_op(ttl, OP_EQ, 1024);
367 /* Try an IPv6 address */
368 memset(&rh, 0, sizeof(rh));
369 memset(&cell, 0, sizeof(cell));
370 tor_addr_parse(&addr, "2620::6b0:b:1a1a:0:26e5:480e");
371 rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE,
372 &addr, 3600);
373 tt_int_op(rh.length, OP_EQ, 25);
374 test_memeq_hex(cell.payload + RELAY_HEADER_SIZE,
375 "00000000" "06"
376 "2620000006b0000b1a1a000026e5480e" "00000e10");
378 /* Try parsing it. */
379 tor_addr_make_unspec(&addr);
380 r = connected_cell_parse(&rh, &cell, &addr, &ttl);
381 tt_int_op(r, OP_EQ, 0);
382 tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET6);
383 tt_str_op(fmt_addr(&addr), OP_EQ, "2620:0:6b0:b:1a1a:0:26e5:480e");
384 tt_int_op(ttl, OP_EQ, 3600);
386 done:
387 tor_free(mem_op_hex_tmp);
390 static void
391 test_cfmt_create_cells(void *arg)
393 uint8_t b[MAX_ONIONSKIN_CHALLENGE_LEN];
394 create_cell_t cc;
395 cell_t cell;
396 cell_t cell2;
398 (void)arg;
400 /* === Let's try parsing some good cells! */
402 /* A valid create cell. */
403 memset(&cell, 0, sizeof(cell));
404 memset(b, 0, sizeof(b));
405 crypto_rand((char*)b, TAP_ONIONSKIN_CHALLENGE_LEN);
406 cell.command = CELL_CREATE;
407 memcpy(cell.payload, b, TAP_ONIONSKIN_CHALLENGE_LEN);
408 tt_int_op(0, OP_EQ, create_cell_parse(&cc, &cell));
409 tt_int_op(CELL_CREATE, OP_EQ, cc.cell_type);
410 tt_int_op(ONION_HANDSHAKE_TYPE_TAP, OP_EQ, cc.handshake_type);
411 tt_int_op(TAP_ONIONSKIN_CHALLENGE_LEN, OP_EQ, cc.handshake_len);
412 tt_mem_op(cc.onionskin,OP_EQ, b, TAP_ONIONSKIN_CHALLENGE_LEN + 10);
413 tt_int_op(0, OP_EQ, create_cell_format(&cell2, &cc));
414 tt_int_op(cell.command, OP_EQ, cell2.command);
415 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
417 /* A valid create_fast cell. */
418 memset(&cell, 0, sizeof(cell));
419 memset(b, 0, sizeof(b));
420 crypto_rand((char*)b, CREATE_FAST_LEN);
421 cell.command = CELL_CREATE_FAST;
422 memcpy(cell.payload, b, CREATE_FAST_LEN);
423 tt_int_op(0, OP_EQ, create_cell_parse(&cc, &cell));
424 tt_int_op(CELL_CREATE_FAST, OP_EQ, cc.cell_type);
425 tt_int_op(ONION_HANDSHAKE_TYPE_FAST, OP_EQ, cc.handshake_type);
426 tt_int_op(CREATE_FAST_LEN, OP_EQ, cc.handshake_len);
427 tt_mem_op(cc.onionskin,OP_EQ, b, CREATE_FAST_LEN + 10);
428 tt_int_op(0, OP_EQ, create_cell_format(&cell2, &cc));
429 tt_int_op(cell.command, OP_EQ, cell2.command);
430 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
432 /* A valid create2 cell with a TAP payload */
433 memset(&cell, 0, sizeof(cell));
434 memset(b, 0, sizeof(b));
435 crypto_rand((char*)b, TAP_ONIONSKIN_CHALLENGE_LEN);
436 cell.command = CELL_CREATE2;
437 memcpy(cell.payload, "\x00\x00\x00\xBA", 4); /* TAP, 186 bytes long */
438 memcpy(cell.payload+4, b, TAP_ONIONSKIN_CHALLENGE_LEN);
439 tt_int_op(0, OP_EQ, create_cell_parse(&cc, &cell));
440 tt_int_op(CELL_CREATE2, OP_EQ, cc.cell_type);
441 tt_int_op(ONION_HANDSHAKE_TYPE_TAP, OP_EQ, cc.handshake_type);
442 tt_int_op(TAP_ONIONSKIN_CHALLENGE_LEN, OP_EQ, cc.handshake_len);
443 tt_mem_op(cc.onionskin,OP_EQ, b, TAP_ONIONSKIN_CHALLENGE_LEN + 10);
444 tt_int_op(0, OP_EQ, create_cell_format(&cell2, &cc));
445 tt_int_op(cell.command, OP_EQ, cell2.command);
446 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
448 /* A valid create2 cell with an ntor payload */
449 memset(&cell, 0, sizeof(cell));
450 memset(b, 0, sizeof(b));
451 crypto_rand((char*)b, NTOR_ONIONSKIN_LEN);
452 cell.command = CELL_CREATE2;
453 memcpy(cell.payload, "\x00\x02\x00\x54", 4); /* ntor, 84 bytes long */
454 memcpy(cell.payload+4, b, NTOR_ONIONSKIN_LEN);
455 tt_int_op(0, OP_EQ, create_cell_parse(&cc, &cell));
456 tt_int_op(CELL_CREATE2, OP_EQ, cc.cell_type);
457 tt_int_op(ONION_HANDSHAKE_TYPE_NTOR, OP_EQ, cc.handshake_type);
458 tt_int_op(NTOR_ONIONSKIN_LEN, OP_EQ, cc.handshake_len);
459 tt_mem_op(cc.onionskin,OP_EQ, b, NTOR_ONIONSKIN_LEN + 10);
460 tt_int_op(0, OP_EQ, create_cell_format(&cell2, &cc));
461 tt_int_op(cell.command, OP_EQ, cell2.command);
462 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
464 /* A valid create cell with an ntor payload, in legacy format. */
465 memset(&cell, 0, sizeof(cell));
466 memset(b, 0, sizeof(b));
467 crypto_rand((char*)b, NTOR_ONIONSKIN_LEN);
468 cell.command = CELL_CREATE;
469 memcpy(cell.payload, "ntorNTORntorNTOR", 16);
470 memcpy(cell.payload+16, b, NTOR_ONIONSKIN_LEN);
471 tt_int_op(0, OP_EQ, create_cell_parse(&cc, &cell));
472 tt_int_op(CELL_CREATE, OP_EQ, cc.cell_type);
473 tt_int_op(ONION_HANDSHAKE_TYPE_NTOR, OP_EQ, cc.handshake_type);
474 tt_int_op(NTOR_ONIONSKIN_LEN, OP_EQ, cc.handshake_len);
475 tt_mem_op(cc.onionskin,OP_EQ, b, NTOR_ONIONSKIN_LEN + 10);
476 tt_int_op(0, OP_EQ, create_cell_format(&cell2, &cc));
477 tt_int_op(cell.command, OP_EQ, cell2.command);
478 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
480 /* == Okay, now let's try to parse some impossible stuff. */
482 /* It has to be some kind of a create cell! */
483 cell.command = CELL_CREATED;
484 tt_int_op(-1, OP_EQ, create_cell_parse(&cc, &cell));
486 /* You can't actually make an unparseable CREATE or CREATE_FAST cell. */
488 /* Try some CREATE2 cells. First with a bad type. */
489 cell.command = CELL_CREATE2;
490 memcpy(cell.payload, "\x00\x50\x00\x99", 4); /* Type 0x50???? */
491 tt_int_op(-1, OP_EQ, create_cell_parse(&cc, &cell));
492 /* Now a good type with an incorrect length. */
493 memcpy(cell.payload, "\x00\x00\x00\xBC", 4); /* TAP, 187 bytes.*/
494 tt_int_op(-1, OP_EQ, create_cell_parse(&cc, &cell));
495 /* Now a good type with a ridiculous length. */
496 memcpy(cell.payload, "\x00\x00\x02\x00", 4); /* TAP, 512 bytes.*/
497 tt_int_op(-1, OP_EQ, create_cell_parse(&cc, &cell));
499 /* == Time to try formatting bad cells. The important thing is that
500 we reject big lengths, so just check that for now. */
501 cc.handshake_len = 512;
502 tt_int_op(-1, OP_EQ, create_cell_format(&cell2, &cc));
504 /* == Try formatting a create2 cell we don't understand. XXXX */
506 done:
510 static void
511 test_cfmt_created_cells(void *arg)
513 uint8_t b[512];
514 created_cell_t cc;
515 cell_t cell;
516 cell_t cell2;
518 (void)arg;
520 /* A good CREATED cell */
521 memset(&cell, 0, sizeof(cell));
522 memset(b, 0, sizeof(b));
523 crypto_rand((char*)b, TAP_ONIONSKIN_REPLY_LEN);
524 cell.command = CELL_CREATED;
525 memcpy(cell.payload, b, TAP_ONIONSKIN_REPLY_LEN);
526 tt_int_op(0, OP_EQ, created_cell_parse(&cc, &cell));
527 tt_int_op(CELL_CREATED, OP_EQ, cc.cell_type);
528 tt_int_op(TAP_ONIONSKIN_REPLY_LEN, OP_EQ, cc.handshake_len);
529 tt_mem_op(cc.reply,OP_EQ, b, TAP_ONIONSKIN_REPLY_LEN + 10);
530 tt_int_op(0, OP_EQ, created_cell_format(&cell2, &cc));
531 tt_int_op(cell.command, OP_EQ, cell2.command);
532 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
534 /* A good CREATED_FAST cell */
535 memset(&cell, 0, sizeof(cell));
536 memset(b, 0, sizeof(b));
537 crypto_rand((char*)b, CREATED_FAST_LEN);
538 cell.command = CELL_CREATED_FAST;
539 memcpy(cell.payload, b, CREATED_FAST_LEN);
540 tt_int_op(0, OP_EQ, created_cell_parse(&cc, &cell));
541 tt_int_op(CELL_CREATED_FAST, OP_EQ, cc.cell_type);
542 tt_int_op(CREATED_FAST_LEN, OP_EQ, cc.handshake_len);
543 tt_mem_op(cc.reply,OP_EQ, b, CREATED_FAST_LEN + 10);
544 tt_int_op(0, OP_EQ, created_cell_format(&cell2, &cc));
545 tt_int_op(cell.command, OP_EQ, cell2.command);
546 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
548 /* A good CREATED2 cell with short reply */
549 memset(&cell, 0, sizeof(cell));
550 memset(b, 0, sizeof(b));
551 crypto_rand((char*)b, 64);
552 cell.command = CELL_CREATED2;
553 memcpy(cell.payload, "\x00\x40", 2);
554 memcpy(cell.payload+2, b, 64);
555 tt_int_op(0, OP_EQ, created_cell_parse(&cc, &cell));
556 tt_int_op(CELL_CREATED2, OP_EQ, cc.cell_type);
557 tt_int_op(64, OP_EQ, cc.handshake_len);
558 tt_mem_op(cc.reply,OP_EQ, b, 80);
559 tt_int_op(0, OP_EQ, created_cell_format(&cell2, &cc));
560 tt_int_op(cell.command, OP_EQ, cell2.command);
561 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
563 /* A good CREATED2 cell with maximal reply */
564 memset(&cell, 0, sizeof(cell));
565 memset(b, 0, sizeof(b));
566 crypto_rand((char*)b, 496);
567 cell.command = CELL_CREATED2;
568 memcpy(cell.payload, "\x01\xF0", 2);
569 memcpy(cell.payload+2, b, 496);
570 tt_int_op(0, OP_EQ, created_cell_parse(&cc, &cell));
571 tt_int_op(CELL_CREATED2, OP_EQ, cc.cell_type);
572 tt_int_op(496, OP_EQ, cc.handshake_len);
573 tt_mem_op(cc.reply,OP_EQ, b, 496);
574 tt_int_op(0, OP_EQ, created_cell_format(&cell2, &cc));
575 tt_int_op(cell.command, OP_EQ, cell2.command);
576 tt_mem_op(cell.payload,OP_EQ, cell2.payload, CELL_PAYLOAD_SIZE);
578 /* Bogus CREATED2 cell: too long! */
579 memset(&cell, 0, sizeof(cell));
580 memset(b, 0, sizeof(b));
581 crypto_rand((char*)b, 496);
582 cell.command = CELL_CREATED2;
583 memcpy(cell.payload, "\x01\xF1", 2);
584 tt_int_op(-1, OP_EQ, created_cell_parse(&cc, &cell));
586 /* Unformattable CREATED2 cell: too long! */
587 cc.handshake_len = 497;
588 tt_int_op(-1, OP_EQ, created_cell_format(&cell2, &cc));
590 done:
594 static void
595 test_cfmt_extend_cells(void *arg)
597 cell_t cell;
598 uint8_t b[512];
599 extend_cell_t ec;
600 create_cell_t *cc = &ec.create_cell;
601 uint8_t p[RELAY_PAYLOAD_SIZE];
602 uint8_t p2[RELAY_PAYLOAD_SIZE];
603 uint8_t p2_cmd;
604 uint16_t p2_len;
605 char *mem_op_hex_tmp = NULL;
607 (void) arg;
609 /* Let's start with a simple EXTEND cell. */
610 memset(p, 0, sizeof(p));
611 memset(b, 0, sizeof(b));
612 crypto_rand((char*)b, TAP_ONIONSKIN_CHALLENGE_LEN);
613 memcpy(p, "\x12\xf4\x00\x01\x01\x02", 6); /* 18 244 0 1 : 258 */
614 memcpy(p+6,b,TAP_ONIONSKIN_CHALLENGE_LEN);
615 memcpy(p+6+TAP_ONIONSKIN_CHALLENGE_LEN, "electroencephalogram", 20);
616 tt_int_op(0, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND,
617 p, 26+TAP_ONIONSKIN_CHALLENGE_LEN));
618 tt_int_op(RELAY_COMMAND_EXTEND, OP_EQ, ec.cell_type);
619 tt_str_op("18.244.0.1", OP_EQ, fmt_addr(&ec.orport_ipv4.addr));
620 tt_int_op(258, OP_EQ, ec.orport_ipv4.port);
621 tt_int_op(AF_UNSPEC, OP_EQ, tor_addr_family(&ec.orport_ipv6.addr));
622 tt_mem_op(ec.node_id,OP_EQ, "electroencephalogram", 20);
623 tt_int_op(cc->cell_type, OP_EQ, CELL_CREATE);
624 tt_int_op(cc->handshake_type, OP_EQ, ONION_HANDSHAKE_TYPE_TAP);
625 tt_int_op(cc->handshake_len, OP_EQ, TAP_ONIONSKIN_CHALLENGE_LEN);
626 tt_mem_op(cc->onionskin,OP_EQ, b, TAP_ONIONSKIN_CHALLENGE_LEN+20);
627 tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
628 tt_int_op(p2_cmd, OP_EQ, RELAY_COMMAND_EXTEND);
629 tt_int_op(p2_len, OP_EQ, 26+TAP_ONIONSKIN_CHALLENGE_LEN);
630 tt_mem_op(p2,OP_EQ, p, RELAY_PAYLOAD_SIZE);
632 /* Let's do an ntor stuffed in a legacy EXTEND cell */
633 memset(p, 0, sizeof(p));
634 memset(b, 0, sizeof(b));
635 crypto_rand((char*)b, NTOR_ONIONSKIN_LEN);
636 memcpy(p, "\x12\xf4\x00\x01\x01\x02", 6); /* 18 244 0 1 : 258 */
637 memcpy(p+6,"ntorNTORntorNTOR", 16);
638 memcpy(p+22, b, NTOR_ONIONSKIN_LEN);
639 memcpy(p+6+TAP_ONIONSKIN_CHALLENGE_LEN, "electroencephalogram", 20);
640 tt_int_op(0, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND,
641 p, 26+TAP_ONIONSKIN_CHALLENGE_LEN));
642 tt_int_op(RELAY_COMMAND_EXTEND, OP_EQ, ec.cell_type);
643 tt_str_op("18.244.0.1", OP_EQ, fmt_addr(&ec.orport_ipv4.addr));
644 tt_int_op(258, OP_EQ, ec.orport_ipv4.port);
645 tt_int_op(AF_UNSPEC, OP_EQ, tor_addr_family(&ec.orport_ipv6.addr));
646 tt_mem_op(ec.node_id,OP_EQ, "electroencephalogram", 20);
647 tt_int_op(cc->cell_type, OP_EQ, CELL_CREATE2);
648 tt_int_op(cc->handshake_type, OP_EQ, ONION_HANDSHAKE_TYPE_NTOR);
649 tt_int_op(cc->handshake_len, OP_EQ, NTOR_ONIONSKIN_LEN);
650 tt_mem_op(cc->onionskin,OP_EQ, b, NTOR_ONIONSKIN_LEN+20);
651 tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
652 tt_int_op(p2_cmd, OP_EQ, RELAY_COMMAND_EXTEND);
653 tt_int_op(p2_len, OP_EQ, 26+TAP_ONIONSKIN_CHALLENGE_LEN);
654 tt_mem_op(p2,OP_EQ, p, RELAY_PAYLOAD_SIZE);
655 tt_int_op(0, OP_EQ, create_cell_format_relayed(&cell, cc));
657 /* Now let's do a minimal ntor EXTEND2 cell. */
658 memset(&ec, 0xff, sizeof(ec));
659 memset(p, 0, sizeof(p));
660 memset(b, 0, sizeof(b));
661 crypto_rand((char*)b, NTOR_ONIONSKIN_LEN);
662 /* 2 items; one 18.244.0.1:61681 */
663 memcpy(p, "\x02\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
664 /* The other is a digest. */
665 memcpy(p+9, "\x02\x14" "anarchoindividualist", 22);
666 /* Prep for the handshake: type and length */
667 memcpy(p+31, "\x00\x02\x00\x54", 4);
668 memcpy(p+35, b, NTOR_ONIONSKIN_LEN);
669 tt_int_op(0, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
670 p, 35+NTOR_ONIONSKIN_LEN));
671 tt_int_op(RELAY_COMMAND_EXTEND2, OP_EQ, ec.cell_type);
672 tt_str_op("18.244.0.1", OP_EQ, fmt_addr(&ec.orport_ipv4.addr));
673 tt_int_op(61681, OP_EQ, ec.orport_ipv4.port);
674 tt_int_op(AF_UNSPEC, OP_EQ, tor_addr_family(&ec.orport_ipv6.addr));
675 tt_mem_op(ec.node_id,OP_EQ, "anarchoindividualist", 20);
676 tt_int_op(cc->cell_type, OP_EQ, CELL_CREATE2);
677 tt_int_op(cc->handshake_type, OP_EQ, ONION_HANDSHAKE_TYPE_NTOR);
678 tt_int_op(cc->handshake_len, OP_EQ, NTOR_ONIONSKIN_LEN);
679 tt_mem_op(cc->onionskin,OP_EQ, b, NTOR_ONIONSKIN_LEN+20);
680 tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
681 tt_int_op(p2_cmd, OP_EQ, RELAY_COMMAND_EXTEND2);
682 tt_int_op(p2_len, OP_EQ, 35+NTOR_ONIONSKIN_LEN);
683 tt_mem_op(p2,OP_EQ, p, RELAY_PAYLOAD_SIZE);
685 /* Now let's do a fanciful EXTEND2 cell. */
686 memset(&ec, 0xff, sizeof(ec));
687 memset(p, 0, sizeof(p));
688 memset(b, 0, sizeof(b));
689 crypto_rand((char*)b, 99);
690 /* 4 items; one 18 244 0 1 61681 */
691 memcpy(p, "\x04\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
692 /* One is a digest. */
693 memcpy(p+9, "\x02\x14" "anthropomorphization", 22);
694 /* One is an ipv6 address */
695 memcpy(p+31, "\x01\x12\x20\x02\x00\x00\x00\x00\x00\x00"
696 "\x00\x00\x00\x00\x00\xf0\xc5\x1e\x11\x12", 20);
697 /* One is the Konami code. */
698 memcpy(p+51, "\xf0\x20upupdowndownleftrightleftrightba", 34);
699 /* Prep for the handshake: weird type and length */
700 memcpy(p+85, "\x01\x05\x00\x63", 4);
701 memcpy(p+89, b, 99);
702 tt_int_op(0, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2, p, 89+99));
703 tt_int_op(RELAY_COMMAND_EXTEND2, OP_EQ, ec.cell_type);
704 tt_str_op("18.244.0.1", OP_EQ, fmt_addr(&ec.orport_ipv4.addr));
705 tt_int_op(61681, OP_EQ, ec.orport_ipv4.port);
706 tt_str_op("2002::f0:c51e", OP_EQ, fmt_addr(&ec.orport_ipv6.addr));
707 tt_int_op(4370, OP_EQ, ec.orport_ipv6.port);
708 tt_assert(ed25519_public_key_is_zero(&ec.ed_pubkey));
709 tt_mem_op(ec.node_id,OP_EQ, "anthropomorphization", 20);
710 tt_int_op(cc->cell_type, OP_EQ, CELL_CREATE2);
711 tt_int_op(cc->handshake_type, OP_EQ, 0x105);
712 tt_int_op(cc->handshake_len, OP_EQ, 99);
713 tt_mem_op(cc->onionskin,OP_EQ, b, 99+20);
714 tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
715 tt_int_op(p2_cmd, OP_EQ, RELAY_COMMAND_EXTEND2);
716 /* We'll generate it minus the konami code */
717 tt_int_op(p2_len, OP_EQ, 89+99-34);
718 test_memeq_hex(p2,
719 /* Three items */
720 "03"
721 /* IPv4 address */
722 "0006" "12F40001" "F0F1"
723 /* The next is an RSA digest: anthropomorphization */
724 "0214" "616e7468726f706f6d6f727068697a6174696f6e"
725 /*IPv6 address */
726 "0112" "20020000000000000000000000f0c51e" "1112"
727 /* Now the handshake prologue */
728 "01050063");
729 tt_mem_op(p2+1+8+22+20+4, OP_EQ, b, 99+20);
730 tt_int_op(0, OP_EQ, create_cell_format_relayed(&cell, cc));
732 /* Now let's add an ed25519 key to that extend2 cell. */
733 memcpy(ec.ed_pubkey.pubkey,
734 "brownshoesdontmakeit/brownshoesd", 32);
736 /* As before, since we aren't extending by ed25519. */
737 get_options_mutable()->ExtendByEd25519ID = 0;
738 tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
739 tt_int_op(p2_len, OP_EQ, 89+99-34);
740 test_memeq_hex(p2,
741 "03"
742 "000612F40001F0F1"
743 "0214616e7468726f706f6d6f727068697a6174696f6e"
744 "011220020000000000000000000000f0c51e1112"
745 "01050063");
747 /* Now try with the ed25519 ID. */
748 get_options_mutable()->ExtendByEd25519ID = 1;
749 tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
750 tt_int_op(p2_len, OP_EQ, 89+99);
751 test_memeq_hex(p2,
752 /* Four items */
753 "04"
754 /* IPv4 address */
755 "0006" "12F40001" "F0F1"
756 /* The next is an RSA digest: anthropomorphization */
757 "0214616e7468726f706f6d6f727068697a6174696f6e"
758 /* Then an ed public key: brownshoesdontmakeit/brownshoesd */
759 "0320" "62726f776e73686f6573646f6e746d616b656"
760 "9742f62726f776e73686f657364"
761 /*IPv6 address */
762 "0112" "20020000000000000000000000f0c51e" "1112"
763 /* Now the handshake prologue */
764 "01050063");
765 /* Can we parse that? Did the key come through right? */
766 memset(&ec, 0, sizeof(ec));
767 tt_int_op(0, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
768 p2, p2_len));
769 tt_mem_op("brownshoesdontmakeit/brownshoesd", OP_EQ,
770 ec.ed_pubkey.pubkey, 32);
772 /* Now try IPv6 without IPv4 */
773 memset(p, 0, sizeof(p));
774 memcpy(p, "\x02", 1);
775 memcpy(p+1, "\x02\x14" "anthropomorphization", 22);
776 memcpy(p+23, "\x01\x12" "xxxxxxxxxxxxxxxxYY", 20);
777 memcpy(p+43, "\xff\xff\x00\x20", 4);
778 tt_int_op(0, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
779 p, sizeof(p)));
780 tt_int_op(RELAY_COMMAND_EXTEND2, OP_EQ, ec.cell_type);
781 tt_assert(fast_mem_is_zero((const char *)&ec.orport_ipv4.addr,
782 sizeof(tor_addr_t)));
783 tt_int_op(0, OP_EQ, ec.orport_ipv4.port);
784 tt_str_op("7878:7878:7878:7878:7878:7878:7878:7878",
785 OP_EQ, fmt_addr(&ec.orport_ipv6.addr));
786 tt_int_op(22873, OP_EQ, ec.orport_ipv6.port);
787 tt_assert(ed25519_public_key_is_zero(&ec.ed_pubkey));
788 tt_mem_op(ec.node_id,OP_EQ, "anthropomorphization", 20);
789 tt_int_op(cc->cell_type, OP_EQ, CELL_CREATE2);
790 tt_int_op(cc->handshake_type, OP_EQ, 0xffff);
791 tt_int_op(cc->handshake_len, OP_EQ, 32);
792 tt_int_op(0, OP_EQ, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
793 tt_int_op(p2_cmd, OP_EQ, RELAY_COMMAND_EXTEND2);
794 tt_int_op(p2_len, OP_EQ, 47+32);
795 test_memeq_hex(p2,
796 /* Two items */
797 "02"
798 /* The next is an RSA digest: anthropomorphization */
799 "0214" "616e7468726f706f6d6f727068697a6174696f6e"
800 /*IPv6 address */
801 "0112" "78787878787878787878787878787878" "5959"
802 /* Now the handshake prologue */
803 "ffff0020");
804 tt_int_op(0, OP_EQ, create_cell_format_relayed(&cell, cc));
806 /* == Now try parsing some junk */
808 /* Try a too-long handshake */
809 memset(p, 0, sizeof(p));
810 memcpy(p, "\x02\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
811 memcpy(p+9, "\x02\x14" "anarchoindividualist", 22);
812 memcpy(p+31, "\xff\xff\x01\xd0", 4);
813 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
814 p, sizeof(p)));
816 /* Try two identities. */
817 memset(p, 0, sizeof(p));
818 memcpy(p, "\x03\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
819 memcpy(p+9, "\x02\x14" "anarchoindividualist", 22);
820 memcpy(p+31, "\x02\x14" "autodepolymerization", 22);
821 memcpy(p+53, "\xff\xff\x00\x10", 4);
822 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
823 p, sizeof(p)));
825 /* No identities. */
826 memset(p, 0, sizeof(p));
827 memcpy(p, "\x01\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
828 memcpy(p+53, "\xff\xff\x00\x10", 4);
829 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
830 p, sizeof(p)));
832 /* Try a bad IPv4 address (too long, too short)*/
833 memset(p, 0, sizeof(p));
834 memcpy(p, "\x02\x00\x07\x12\xf4\x00\x01\xf0\xf1\xff", 10);
835 memcpy(p+10, "\x02\x14" "anarchoindividualist", 22);
836 memcpy(p+32, "\xff\xff\x00\x10", 4);
837 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
838 p, sizeof(p)));
839 memset(p, 0, sizeof(p));
840 memcpy(p, "\x02\x00\x05\x12\xf4\x00\x01\xf0", 8);
841 memcpy(p+8, "\x02\x14" "anarchoindividualist", 22);
842 memcpy(p+30, "\xff\xff\x00\x10", 4);
843 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
844 p, sizeof(p)));
846 /* IPv6 address (too long, too short, no IPv4)*/
847 memset(p, 0, sizeof(p));
848 memcpy(p, "\x03\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
849 memcpy(p+9, "\x02\x14" "anarchoindividualist", 22);
850 memcpy(p+31, "\x01\x13" "xxxxxxxxxxxxxxxxYYZ", 19);
851 memcpy(p+50, "\xff\xff\x00\x20", 4);
852 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
853 p, sizeof(p)));
854 memset(p, 0, sizeof(p));
855 memcpy(p, "\x03\x00\x06\x12\xf4\x00\x01\xf0\xf1", 9);
856 memcpy(p+9, "\x02\x14" "anarchoindividualist", 22);
857 memcpy(p+31, "\x01\x11" "xxxxxxxxxxxxxxxxY", 17);
858 memcpy(p+48, "\xff\xff\x00\x20", 4);
859 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
860 p, sizeof(p)));
862 /* Running out of space in specifiers */
863 memset(p,0,sizeof(p));
864 memcpy(p, "\x05\x0a\xff", 3);
865 memcpy(p+3+255, "\x0a\xff", 2);
866 tt_int_op(-1, OP_EQ, extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2,
867 p, sizeof(p)));
869 /* Fuzz, because why not. */
870 memset(&ec, 0xff, sizeof(ec));
872 int i;
873 memset(p, 0, sizeof(p));
874 for (i = 0; i < 10000; ++i) {
875 int n = crypto_rand_int(sizeof(p));
876 crypto_rand((char *)p, n);
877 extend_cell_parse(&ec, RELAY_COMMAND_EXTEND2, p, n);
881 done:
882 tor_free(mem_op_hex_tmp);
885 static void
886 test_cfmt_extended_cells(void *arg)
888 uint8_t b[512];
889 extended_cell_t ec;
890 created_cell_t *cc = &ec.created_cell;
891 uint8_t p[RELAY_PAYLOAD_SIZE];
892 uint8_t p2[RELAY_PAYLOAD_SIZE];
893 uint8_t p2_cmd;
894 uint16_t p2_len;
895 char *mem_op_hex_tmp = NULL;
897 (void) arg;
899 /* Try a regular EXTENDED cell. */
900 memset(&ec, 0xff, sizeof(ec));
901 memset(p, 0, sizeof(p));
902 memset(b, 0, sizeof(b));
903 crypto_rand((char*)b, TAP_ONIONSKIN_REPLY_LEN);
904 memcpy(p,b,TAP_ONIONSKIN_REPLY_LEN);
905 tt_int_op(0, OP_EQ, extended_cell_parse(&ec, RELAY_COMMAND_EXTENDED, p,
906 TAP_ONIONSKIN_REPLY_LEN));
907 tt_int_op(RELAY_COMMAND_EXTENDED, OP_EQ, ec.cell_type);
908 tt_int_op(cc->cell_type, OP_EQ, CELL_CREATED);
909 tt_int_op(cc->handshake_len, OP_EQ, TAP_ONIONSKIN_REPLY_LEN);
910 tt_mem_op(cc->reply,OP_EQ, b, TAP_ONIONSKIN_REPLY_LEN);
911 tt_int_op(0, OP_EQ, extended_cell_format(&p2_cmd, &p2_len, p2, &ec));
912 tt_int_op(RELAY_COMMAND_EXTENDED, OP_EQ, p2_cmd);
913 tt_int_op(TAP_ONIONSKIN_REPLY_LEN, OP_EQ, p2_len);
914 tt_mem_op(p2,OP_EQ, p, sizeof(p2));
916 /* Try an EXTENDED2 cell */
917 memset(&ec, 0xff, sizeof(ec));
918 memset(p, 0, sizeof(p));
919 memset(b, 0, sizeof(b));
920 crypto_rand((char*)b, 42);
921 memcpy(p,"\x00\x2a",2);
922 memcpy(p+2,b,42);
923 tt_int_op(0, OP_EQ,
924 extended_cell_parse(&ec, RELAY_COMMAND_EXTENDED2, p, 2+42));
925 tt_int_op(RELAY_COMMAND_EXTENDED2, OP_EQ, ec.cell_type);
926 tt_int_op(cc->cell_type, OP_EQ, CELL_CREATED2);
927 tt_int_op(cc->handshake_len, OP_EQ, 42);
928 tt_mem_op(cc->reply,OP_EQ, b, 42+10);
929 tt_int_op(0, OP_EQ, extended_cell_format(&p2_cmd, &p2_len, p2, &ec));
930 tt_int_op(RELAY_COMMAND_EXTENDED2, OP_EQ, p2_cmd);
931 tt_int_op(2+42, OP_EQ, p2_len);
932 tt_mem_op(p2,OP_EQ, p, sizeof(p2));
934 /* Try an almost-too-long EXTENDED2 cell */
935 memcpy(p, "\x01\xf0", 2);
936 tt_int_op(0, OP_EQ,
937 extended_cell_parse(&ec, RELAY_COMMAND_EXTENDED2, p, sizeof(p)));
939 /* Now try a too-long extended2 cell. That's the only misparse I can think
940 * of. */
941 memcpy(p, "\x01\xf1", 2);
942 tt_int_op(-1, OP_EQ,
943 extended_cell_parse(&ec, RELAY_COMMAND_EXTENDED2, p, sizeof(p)));
945 done:
946 tor_free(mem_op_hex_tmp);
949 static void
950 test_cfmt_resolved_cells(void *arg)
952 smartlist_t *addrs = smartlist_new();
953 relay_header_t rh;
954 cell_t cell;
955 int r, errcode;
956 address_ttl_t *a;
958 (void)arg;
959 #define CLEAR_CELL() do { \
960 memset(&cell, 0, sizeof(cell)); \
961 memset(&rh, 0, sizeof(rh)); \
962 } while (0)
963 #define CLEAR_ADDRS() do { \
964 SMARTLIST_FOREACH(addrs, address_ttl_t *, aa_, \
965 address_ttl_free(aa_); ); \
966 smartlist_clear(addrs); \
967 } while (0)
968 #define SET_CELL(s) do { \
969 CLEAR_CELL(); \
970 memcpy(cell.payload + RELAY_HEADER_SIZE, (s), sizeof((s))-1); \
971 rh.length = sizeof((s))-1; \
972 rh.command = RELAY_COMMAND_RESOLVED; \
973 errcode = -1; \
974 } while (0)
976 /* The cell format is one or more answers; each of the form
977 * type [1 byte---0:hostname, 4:ipv4, 6:ipv6, f0:err-transient, f1:err]
978 * length [1 byte]
979 * body [length bytes]
980 * ttl [4 bytes]
983 /* Let's try an empty cell */
984 SET_CELL("");
985 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
986 tt_int_op(errcode, OP_EQ, 0);
987 tt_int_op(r, OP_EQ, 0);
988 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
989 CLEAR_ADDRS(); /* redundant but let's be consistent */
991 /* Cell with one ipv4 addr */
992 SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00");
993 tt_int_op(rh.length, OP_EQ, 10);
994 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
995 tt_int_op(errcode, OP_EQ, 0);
996 tt_int_op(r, OP_EQ, 0);
997 tt_int_op(smartlist_len(addrs), OP_EQ, 1);
998 a = smartlist_get(addrs, 0);
999 tt_str_op(fmt_addr(&a->addr), OP_EQ, "127.0.2.10");
1000 tt_ptr_op(a->hostname, OP_EQ, NULL);
1001 tt_int_op(a->ttl, OP_EQ, 256);
1002 CLEAR_ADDRS();
1004 /* Cell with one ipv6 addr */
1005 SET_CELL("\x06\x10"
1006 "\x20\x02\x90\x90\x00\x00\x00\x00"
1007 "\x00\x00\x00\x00\xf0\xf0\xab\xcd"
1008 "\x02\00\x00\x01");
1009 tt_int_op(rh.length, OP_EQ, 22);
1010 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1011 tt_int_op(errcode, OP_EQ, 0);
1012 tt_int_op(r, OP_EQ, 0);
1013 tt_int_op(smartlist_len(addrs), OP_EQ, 1);
1014 a = smartlist_get(addrs, 0);
1015 tt_str_op(fmt_addr(&a->addr), OP_EQ, "2002:9090::f0f0:abcd");
1016 tt_ptr_op(a->hostname, OP_EQ, NULL);
1017 tt_int_op(a->ttl, OP_EQ, 0x2000001);
1018 CLEAR_ADDRS();
1020 /* Cell with one hostname */
1021 SET_CELL("\x00\x11"
1022 "motherbrain.zebes"
1023 "\x00\00\x00\x00");
1024 tt_int_op(rh.length, OP_EQ, 23);
1025 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1026 tt_int_op(errcode, OP_EQ, 0);
1027 tt_int_op(r, OP_EQ, 0);
1028 tt_int_op(smartlist_len(addrs), OP_EQ, 1);
1029 a = smartlist_get(addrs, 0);
1030 tt_assert(tor_addr_is_null(&a->addr));
1031 tt_str_op(a->hostname, OP_EQ, "motherbrain.zebes");
1032 tt_int_op(a->ttl, OP_EQ, 0);
1033 CLEAR_ADDRS();
1035 #define LONG_NAME \
1036 "this-hostname-has-255-characters.in-order-to-test-whether-very-long.ho" \
1037 "stnames-are-accepted.i-am-putting-it-in-a-macro-because-although.this-" \
1038 "function-is-already-very-full.of-copy-and-pasted-stuff.having-this-app" \
1039 "ear-more-than-once-would-bother-me-somehow.is"
1041 tt_int_op(strlen(LONG_NAME), OP_EQ, 255);
1042 SET_CELL("\x00\xff"
1043 LONG_NAME
1044 "\x00\01\x00\x00");
1045 tt_int_op(rh.length, OP_EQ, 261);
1046 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1047 tt_int_op(errcode, OP_EQ, 0);
1048 tt_int_op(r, OP_EQ, 0);
1049 tt_int_op(smartlist_len(addrs), OP_EQ, 1);
1050 a = smartlist_get(addrs, 0);
1051 tt_assert(tor_addr_is_null(&a->addr));
1052 tt_str_op(a->hostname, OP_EQ, LONG_NAME);
1053 tt_int_op(a->ttl, OP_EQ, 65536);
1054 CLEAR_ADDRS();
1056 /* Cells with an error */
1057 SET_CELL("\xf0\x2b"
1058 "I'm sorry, Dave. I'm afraid I can't do that"
1059 "\x00\x11\x22\x33");
1060 tt_int_op(rh.length, OP_EQ, 49);
1061 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1062 tt_int_op(errcode, OP_EQ, RESOLVED_TYPE_ERROR_TRANSIENT);
1063 tt_int_op(r, OP_EQ, 0);
1064 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1065 CLEAR_ADDRS();
1067 SET_CELL("\xf1\x40"
1068 "This hostname is too important for me to allow you to resolve it"
1069 "\x00\x00\x00\x00");
1070 tt_int_op(rh.length, OP_EQ, 70);
1071 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1072 tt_int_op(errcode, OP_EQ, RESOLVED_TYPE_ERROR);
1073 tt_int_op(r, OP_EQ, 0);
1074 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1075 CLEAR_ADDRS();
1077 /* Cell with an unrecognized type */
1078 SET_CELL("\xee\x16"
1079 "fault in the AE35 unit"
1080 "\x09\x09\x01\x01");
1081 tt_int_op(rh.length, OP_EQ, 28);
1082 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1083 tt_int_op(errcode, OP_EQ, 0);
1084 tt_int_op(r, OP_EQ, 0);
1085 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1086 CLEAR_ADDRS();
1088 /* Cell with one of each */
1089 SET_CELL(/* unrecognized: */
1090 "\xee\x16"
1091 "fault in the AE35 unit"
1092 "\x09\x09\x01\x01"
1093 /* error: */
1094 "\xf0\x2b"
1095 "I'm sorry, Dave. I'm afraid I can't do that"
1096 "\x00\x11\x22\x33"
1097 /* IPv6: */
1098 "\x06\x10"
1099 "\x20\x02\x90\x90\x00\x00\x00\x00"
1100 "\x00\x00\x00\x00\xf0\xf0\xab\xcd"
1101 "\x02\00\x00\x01"
1102 /* IPv4: */
1103 "\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00"
1104 /* Hostname: */
1105 "\x00\x11"
1106 "motherbrain.zebes"
1107 "\x00\00\x00\x00"
1109 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1110 tt_int_op(errcode, OP_EQ, 0); /* no error reported; we got answers */
1111 tt_int_op(r, OP_EQ, 0);
1112 tt_int_op(smartlist_len(addrs), OP_EQ, 3);
1113 a = smartlist_get(addrs, 0);
1114 tt_str_op(fmt_addr(&a->addr), OP_EQ, "2002:9090::f0f0:abcd");
1115 tt_ptr_op(a->hostname, OP_EQ, NULL);
1116 tt_int_op(a->ttl, OP_EQ, 0x2000001);
1117 a = smartlist_get(addrs, 1);
1118 tt_str_op(fmt_addr(&a->addr), OP_EQ, "127.0.2.10");
1119 tt_ptr_op(a->hostname, OP_EQ, NULL);
1120 tt_int_op(a->ttl, OP_EQ, 256);
1121 a = smartlist_get(addrs, 2);
1122 tt_assert(tor_addr_is_null(&a->addr));
1123 tt_str_op(a->hostname, OP_EQ, "motherbrain.zebes");
1124 tt_int_op(a->ttl, OP_EQ, 0);
1125 CLEAR_ADDRS();
1127 /* Cell with several of similar type */
1128 SET_CELL(/* IPv4 */
1129 "\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00"
1130 "\x04\x04" "\x08\x08\x08\x08" "\x00\00\x01\x05"
1131 "\x04\x04" "\x7f\xb0\x02\xb0" "\x00\01\xff\xff"
1132 /* IPv6 */
1133 "\x06\x10"
1134 "\x20\x02\x90\x00\x00\x00\x00\x00"
1135 "\x00\x00\x00\x00\xca\xfe\xf0\x0d"
1136 "\x00\00\x00\x01"
1137 "\x06\x10"
1138 "\x20\x02\x90\x01\x00\x00\x00\x00"
1139 "\x00\x00\x00\x00\x00\xfa\xca\xde"
1140 "\x00\00\x00\x03");
1141 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1142 tt_int_op(errcode, OP_EQ, 0);
1143 tt_int_op(r, OP_EQ, 0);
1144 tt_int_op(smartlist_len(addrs), OP_EQ, 5);
1145 a = smartlist_get(addrs, 0);
1146 tt_str_op(fmt_addr(&a->addr), OP_EQ, "127.0.2.10");
1147 tt_ptr_op(a->hostname, OP_EQ, NULL);
1148 tt_int_op(a->ttl, OP_EQ, 256);
1149 a = smartlist_get(addrs, 1);
1150 tt_str_op(fmt_addr(&a->addr), OP_EQ, "8.8.8.8");
1151 tt_ptr_op(a->hostname, OP_EQ, NULL);
1152 tt_int_op(a->ttl, OP_EQ, 261);
1153 a = smartlist_get(addrs, 2);
1154 tt_str_op(fmt_addr(&a->addr), OP_EQ, "127.176.2.176");
1155 tt_ptr_op(a->hostname, OP_EQ, NULL);
1156 tt_int_op(a->ttl, OP_EQ, 131071);
1157 a = smartlist_get(addrs, 3);
1158 tt_str_op(fmt_addr(&a->addr), OP_EQ, "2002:9000::cafe:f00d");
1159 tt_ptr_op(a->hostname, OP_EQ, NULL);
1160 tt_int_op(a->ttl, OP_EQ, 1);
1161 a = smartlist_get(addrs, 4);
1162 tt_str_op(fmt_addr(&a->addr), OP_EQ, "2002:9001::fa:cade");
1163 tt_ptr_op(a->hostname, OP_EQ, NULL);
1164 tt_int_op(a->ttl, OP_EQ, 3);
1165 CLEAR_ADDRS();
1167 /* Full cell */
1168 #define LONG_NAME2 \
1169 "this-name-has-231-characters.so-that-it-plus-LONG_NAME-can-completely-" \
1170 "fill-up-the-payload-of-a-cell.its-important-to-check-for-the-full-thin" \
1171 "g-case.to-avoid-off-by-one-errors.where-full-things-are-misreported-as" \
1172 ".overflowing-by-one.z"
1174 tt_int_op(strlen(LONG_NAME2), OP_EQ, 231);
1175 SET_CELL("\x00\xff"
1176 LONG_NAME
1177 "\x00\01\x00\x00"
1178 "\x00\xe7"
1179 LONG_NAME2
1180 "\x00\01\x00\x00");
1181 tt_int_op(rh.length, OP_EQ, RELAY_PAYLOAD_SIZE);
1182 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1183 tt_int_op(errcode, OP_EQ, 0);
1184 tt_int_op(r, OP_EQ, 0);
1185 tt_int_op(smartlist_len(addrs), OP_EQ, 2);
1186 a = smartlist_get(addrs, 0);
1187 tt_str_op(a->hostname, OP_EQ, LONG_NAME);
1188 a = smartlist_get(addrs, 1);
1189 tt_str_op(a->hostname, OP_EQ, LONG_NAME2);
1190 CLEAR_ADDRS();
1192 /* BAD CELLS */
1194 /* Invalid length on an IPv4 */
1195 SET_CELL("\x04\x03zzz1234");
1196 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1197 tt_int_op(errcode, OP_EQ, 0);
1198 tt_int_op(r, OP_EQ, -1);
1199 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1200 SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00"
1201 "\x04\x05zzzzz1234");
1202 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1203 tt_int_op(errcode, OP_EQ, 0);
1204 tt_int_op(r, OP_EQ, -1);
1205 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1207 /* Invalid length on an IPv6 */
1208 SET_CELL("\x06\x03zzz1234");
1209 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1210 tt_int_op(errcode, OP_EQ, 0);
1211 tt_int_op(r, OP_EQ, -1);
1212 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1213 SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00"
1214 "\x06\x17wwwwwwwwwwwwwwwww1234");
1215 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1216 tt_int_op(errcode, OP_EQ, 0);
1217 tt_int_op(r, OP_EQ, -1);
1218 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1219 SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00"
1220 "\x06\x10xxxx");
1221 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1222 tt_int_op(errcode, OP_EQ, 0);
1223 tt_int_op(r, OP_EQ, -1);
1224 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1226 /* Empty hostname */
1227 SET_CELL("\x00\x00xxxx");
1228 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1229 tt_int_op(errcode, OP_EQ, 0);
1230 tt_int_op(r, OP_EQ, -1);
1231 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1233 /* rh.length out of range */
1234 CLEAR_CELL();
1235 rh.length = 499;
1236 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1237 tt_int_op(errcode, OP_EQ, 0);
1238 tt_int_op(r, OP_EQ, -1);
1239 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1241 /* Item length extends beyond rh.length */
1242 CLEAR_CELL();
1243 SET_CELL("\x00\xff"
1244 LONG_NAME
1245 "\x00\01\x00\x00");
1246 rh.length -= 1;
1247 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1248 tt_int_op(r, OP_EQ, -1);
1249 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1250 rh.length -= 5;
1251 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1252 tt_int_op(r, OP_EQ, -1);
1253 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1255 SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00");
1256 rh.length -= 1;
1257 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1258 tt_int_op(r, OP_EQ, -1);
1259 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1261 SET_CELL("\xee\x10"
1262 "\x20\x02\x90\x01\x00\x00\x00\x00"
1263 "\x00\x00\x00\x00\x00\xfa\xca\xde"
1264 "\x00\00\x00\x03");
1265 rh.length -= 1;
1266 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1267 tt_int_op(r, OP_EQ, -1);
1268 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1270 /* Truncated item after first character */
1271 SET_CELL("\x04");
1272 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1273 tt_int_op(r, OP_EQ, -1);
1274 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1276 SET_CELL("\xee");
1277 r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
1278 tt_int_op(r, OP_EQ, -1);
1279 tt_int_op(smartlist_len(addrs), OP_EQ, 0);
1281 done:
1282 CLEAR_ADDRS();
1283 CLEAR_CELL();
1284 smartlist_free(addrs);
1285 #undef CLEAR_ADDRS
1286 #undef CLEAR_CELL
1289 static void
1290 test_cfmt_is_destroy(void *arg)
1292 cell_t cell;
1293 packed_cell_t packed;
1294 circid_t circid = 0;
1295 channel_t *chan;
1296 (void)arg;
1298 chan = tor_malloc_zero(sizeof(channel_t));
1300 memset(&cell, 0xff, sizeof(cell));
1301 cell.circ_id = 3003;
1302 cell.command = CELL_RELAY;
1304 cell_pack(&packed, &cell, 0);
1305 chan->wide_circ_ids = 0;
1306 tt_assert(! packed_cell_is_destroy(chan, &packed, &circid));
1307 tt_int_op(circid, OP_EQ, 0);
1309 cell_pack(&packed, &cell, 1);
1310 chan->wide_circ_ids = 1;
1311 tt_assert(! packed_cell_is_destroy(chan, &packed, &circid));
1312 tt_int_op(circid, OP_EQ, 0);
1314 cell.command = CELL_DESTROY;
1316 cell_pack(&packed, &cell, 0);
1317 chan->wide_circ_ids = 0;
1318 tt_assert(packed_cell_is_destroy(chan, &packed, &circid));
1319 tt_int_op(circid, OP_EQ, 3003);
1321 circid = 0;
1322 cell_pack(&packed, &cell, 1);
1323 chan->wide_circ_ids = 1;
1324 tt_assert(packed_cell_is_destroy(chan, &packed, &circid));
1326 done:
1327 tor_free(chan);
1330 #define TEST(name, flags) \
1331 { #name, test_cfmt_ ## name, flags, 0, NULL }
1333 struct testcase_t cell_format_tests[] = {
1334 TEST(relay_header, 0),
1335 TEST(begin_cells, 0),
1336 TEST(connected_cells, 0),
1337 TEST(create_cells, 0),
1338 TEST(created_cells, 0),
1339 TEST(extend_cells, TT_FORK),
1340 TEST(extended_cells, 0),
1341 TEST(resolved_cells, 0),
1342 TEST(is_destroy, 0),
1343 END_OF_TESTCASES