test_cell_formats.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. /* Copyright (c) 2001-2004, Roger Dingledine.
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2012, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. #include "orconfig.h"
  6. #define CONNECTION_EDGE_PRIVATE
  7. #define RELAY_PRIVATE
  8. #include "or.h"
  9. #include "connection_edge.h"
  10. #include "relay.h"
  11. #include "test.h"
  12. #include <stdlib.h>
  13. #include <string.h>
  14. static void
  15. test_cfmt_relay_header(void *arg)
  16. {
  17. relay_header_t rh;
  18. const uint8_t hdr_1[RELAY_HEADER_SIZE] =
  19. "\x03" "\x00\x00" "\x21\x22" "ABCD" "\x01\x03";
  20. uint8_t hdr_out[RELAY_HEADER_SIZE];
  21. (void)arg;
  22. tt_int_op(sizeof(hdr_1), ==, RELAY_HEADER_SIZE);
  23. relay_header_unpack(&rh, hdr_1);
  24. tt_int_op(rh.command, ==, 3);
  25. tt_int_op(rh.recognized, ==, 0);
  26. tt_int_op(rh.stream_id, ==, 0x2122);
  27. test_mem_op(rh.integrity, ==, "ABCD", 4);
  28. tt_int_op(rh.length, ==, 0x103);
  29. relay_header_pack(hdr_out, &rh);
  30. test_mem_op(hdr_out, ==, hdr_1, RELAY_HEADER_SIZE);
  31. done:
  32. ;
  33. }
  34. static void
  35. make_relay_cell(cell_t *out, uint8_t command,
  36. const void *body, size_t bodylen)
  37. {
  38. relay_header_t rh;
  39. memset(&rh, 0, sizeof(rh));
  40. rh.stream_id = 5;
  41. rh.command = command;
  42. rh.length = bodylen;
  43. out->command = CELL_RELAY;
  44. out->circ_id = 10;
  45. relay_header_pack(out->payload, &rh);
  46. memcpy(out->payload + RELAY_HEADER_SIZE, body, bodylen);
  47. }
  48. static void
  49. test_cfmt_begin_cells(void *arg)
  50. {
  51. cell_t cell;
  52. begin_cell_t bcell;
  53. uint8_t end_reason;
  54. (void)arg;
  55. /* Try begindir. */
  56. memset(&bcell, 0x7f, sizeof(bcell));
  57. make_relay_cell(&cell, RELAY_COMMAND_BEGIN_DIR, "", 0);
  58. tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  59. tt_ptr_op(NULL, ==, bcell.address);
  60. tt_int_op(0, ==, bcell.flags);
  61. tt_int_op(0, ==, bcell.port);
  62. tt_int_op(5, ==, bcell.stream_id);
  63. tt_int_op(1, ==, bcell.is_begindir);
  64. /* A Begindir with extra stuff. */
  65. memset(&bcell, 0x7f, sizeof(bcell));
  66. make_relay_cell(&cell, RELAY_COMMAND_BEGIN_DIR, "12345", 5);
  67. tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  68. tt_ptr_op(NULL, ==, bcell.address);
  69. tt_int_op(0, ==, bcell.flags);
  70. tt_int_op(0, ==, bcell.port);
  71. tt_int_op(5, ==, bcell.stream_id);
  72. tt_int_op(1, ==, bcell.is_begindir);
  73. /* A short but valid begin cell */
  74. memset(&bcell, 0x7f, sizeof(bcell));
  75. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:9", 6);
  76. tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  77. tt_str_op("a.b", ==, bcell.address);
  78. tt_int_op(0, ==, bcell.flags);
  79. tt_int_op(9, ==, bcell.port);
  80. tt_int_op(5, ==, bcell.stream_id);
  81. tt_int_op(0, ==, bcell.is_begindir);
  82. tor_free(bcell.address);
  83. /* A significantly loner begin cell */
  84. memset(&bcell, 0x7f, sizeof(bcell));
  85. {
  86. const char c[] = "here-is-a-nice-long.hostname.com:65535";
  87. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, strlen(c)+1);
  88. }
  89. tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  90. tt_str_op("here-is-a-nice-long.hostname.com", ==, bcell.address);
  91. tt_int_op(0, ==, bcell.flags);
  92. tt_int_op(65535, ==, bcell.port);
  93. tt_int_op(5, ==, bcell.stream_id);
  94. tt_int_op(0, ==, bcell.is_begindir);
  95. tor_free(bcell.address);
  96. /* An IPv4 begin cell. */
  97. memset(&bcell, 0x7f, sizeof(bcell));
  98. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "18.9.22.169:80", 15);
  99. tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  100. tt_str_op("18.9.22.169", ==, bcell.address);
  101. tt_int_op(0, ==, bcell.flags);
  102. tt_int_op(80, ==, bcell.port);
  103. tt_int_op(5, ==, bcell.stream_id);
  104. tt_int_op(0, ==, bcell.is_begindir);
  105. tor_free(bcell.address);
  106. /* An IPv6 begin cell. Let's make sure we handle colons*/
  107. memset(&bcell, 0x7f, sizeof(bcell));
  108. make_relay_cell(&cell, RELAY_COMMAND_BEGIN,
  109. "[2620::6b0:b:1a1a:0:26e5:480e]:80", 34);
  110. tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  111. tt_str_op("[2620::6b0:b:1a1a:0:26e5:480e]", ==, bcell.address);
  112. tt_int_op(0, ==, bcell.flags);
  113. tt_int_op(80, ==, bcell.port);
  114. tt_int_op(5, ==, bcell.stream_id);
  115. tt_int_op(0, ==, bcell.is_begindir);
  116. tor_free(bcell.address);
  117. /* a begin cell with extra junk but not enough for flags. */
  118. memset(&bcell, 0x7f, sizeof(bcell));
  119. {
  120. const char c[] = "another.example.com:80\x00\x01\x02";
  121. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
  122. }
  123. tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  124. tt_str_op("another.example.com", ==, bcell.address);
  125. tt_int_op(0, ==, bcell.flags);
  126. tt_int_op(80, ==, bcell.port);
  127. tt_int_op(5, ==, bcell.stream_id);
  128. tt_int_op(0, ==, bcell.is_begindir);
  129. tor_free(bcell.address);
  130. /* a begin cell with flags. */
  131. memset(&bcell, 0x7f, sizeof(bcell));
  132. {
  133. const char c[] = "another.example.com:443\x00\x01\x02\x03\x04";
  134. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
  135. }
  136. tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  137. tt_str_op("another.example.com", ==, bcell.address);
  138. tt_int_op(0x1020304, ==, bcell.flags);
  139. tt_int_op(443, ==, bcell.port);
  140. tt_int_op(5, ==, bcell.stream_id);
  141. tt_int_op(0, ==, bcell.is_begindir);
  142. tor_free(bcell.address);
  143. /* a begin cell with flags and even more cruft after that. */
  144. memset(&bcell, 0x7f, sizeof(bcell));
  145. {
  146. const char c[] = "a-further.example.com:22\x00\xee\xaa\x00\xffHi mom";
  147. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
  148. }
  149. tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  150. tt_str_op("a-further.example.com", ==, bcell.address);
  151. tt_int_op(0xeeaa00ff, ==, bcell.flags);
  152. tt_int_op(22, ==, bcell.port);
  153. tt_int_op(5, ==, bcell.stream_id);
  154. tt_int_op(0, ==, bcell.is_begindir);
  155. tor_free(bcell.address);
  156. /* bad begin cell: impossible length. */
  157. memset(&bcell, 0x7f, sizeof(bcell));
  158. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:80", 7);
  159. cell.payload[9] = 0x01; /* Set length to 510 */
  160. cell.payload[10] = 0xfe;
  161. {
  162. relay_header_t rh;
  163. relay_header_unpack(&rh, cell.payload);
  164. tt_int_op(rh.length, ==, 510);
  165. }
  166. tt_int_op(-2, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  167. /* Bad begin cell: no body. */
  168. memset(&bcell, 0x7f, sizeof(bcell));
  169. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "", 0);
  170. tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  171. /* bad begin cell: no body. */
  172. memset(&bcell, 0x7f, sizeof(bcell));
  173. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "", 0);
  174. tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  175. /* bad begin cell: no colon */
  176. memset(&bcell, 0x7f, sizeof(bcell));
  177. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b", 4);
  178. tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  179. /* bad begin cell: no ports */
  180. memset(&bcell, 0x7f, sizeof(bcell));
  181. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:", 5);
  182. tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  183. /* bad begin cell: bad port */
  184. memset(&bcell, 0x7f, sizeof(bcell));
  185. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:xyz", 8);
  186. tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  187. memset(&bcell, 0x7f, sizeof(bcell));
  188. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:100000", 11);
  189. tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  190. /* bad begin cell: no nul */
  191. memset(&bcell, 0x7f, sizeof(bcell));
  192. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:80", 6);
  193. tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  194. done:
  195. tor_free(bcell.address);
  196. }
  197. static void
  198. test_cfmt_connected_cells(void *arg)
  199. {
  200. relay_header_t rh;
  201. cell_t cell;
  202. tor_addr_t addr;
  203. int ttl, r;
  204. char *mem_op_hex_tmp = NULL;
  205. (void)arg;
  206. /* Let's try an oldschool one with nothing in it. */
  207. make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "", 0);
  208. relay_header_unpack(&rh, cell.payload);
  209. r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  210. tt_int_op(r, ==, 0);
  211. tt_int_op(tor_addr_family(&addr), ==, AF_UNSPEC);
  212. tt_int_op(ttl, ==, -1);
  213. /* A slightly less oldschool one: only an IPv4 address */
  214. make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x20\x30\x40\x50", 4);
  215. relay_header_unpack(&rh, cell.payload);
  216. r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  217. tt_int_op(r, ==, 0);
  218. tt_int_op(tor_addr_family(&addr), ==, AF_INET);
  219. tt_str_op(fmt_addr(&addr), ==, "32.48.64.80");
  220. tt_int_op(ttl, ==, -1);
  221. /* Bogus but understandable: truncated TTL */
  222. make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x11\x12\x13\x14\x15", 5);
  223. relay_header_unpack(&rh, cell.payload);
  224. r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  225. tt_int_op(r, ==, 0);
  226. tt_int_op(tor_addr_family(&addr), ==, AF_INET);
  227. tt_str_op(fmt_addr(&addr), ==, "17.18.19.20");
  228. tt_int_op(ttl, ==, -1);
  229. /* Regular IPv4 one: address and TTL */
  230. make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
  231. "\x02\x03\x04\x05\x00\x00\x0e\x10", 8);
  232. relay_header_unpack(&rh, cell.payload);
  233. r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  234. tt_int_op(r, ==, 0);
  235. tt_int_op(tor_addr_family(&addr), ==, AF_INET);
  236. tt_str_op(fmt_addr(&addr), ==, "2.3.4.5");
  237. tt_int_op(ttl, ==, 3600);
  238. /* IPv4 with too-big TTL */
  239. make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
  240. "\x02\x03\x04\x05\xf0\x00\x00\x00", 8);
  241. relay_header_unpack(&rh, cell.payload);
  242. r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  243. tt_int_op(r, ==, 0);
  244. tt_int_op(tor_addr_family(&addr), ==, AF_INET);
  245. tt_str_op(fmt_addr(&addr), ==, "2.3.4.5");
  246. tt_int_op(ttl, ==, -1);
  247. /* IPv6 (ttl is mandatory) */
  248. make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
  249. "\x00\x00\x00\x00\x06"
  250. "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
  251. "\x00\x00\x00\x00\x00\x00\x00\x68"
  252. "\x00\x00\x02\x58", 25);
  253. relay_header_unpack(&rh, cell.payload);
  254. r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  255. tt_int_op(r, ==, 0);
  256. tt_int_op(tor_addr_family(&addr), ==, AF_INET6);
  257. tt_str_op(fmt_addr(&addr), ==, "2607:f8b0:400c:c02::68");
  258. tt_int_op(ttl, ==, 600);
  259. /* IPv6 (ttl too big) */
  260. make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
  261. "\x00\x00\x00\x00\x06"
  262. "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
  263. "\x00\x00\x00\x00\x00\x00\x00\x68"
  264. "\x90\x00\x02\x58", 25);
  265. relay_header_unpack(&rh, cell.payload);
  266. r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  267. tt_int_op(r, ==, 0);
  268. tt_int_op(tor_addr_family(&addr), ==, AF_INET6);
  269. tt_str_op(fmt_addr(&addr), ==, "2607:f8b0:400c:c02::68");
  270. tt_int_op(ttl, ==, -1);
  271. /* Bogus size: 3. */
  272. make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
  273. "\x00\x01\x02", 3);
  274. relay_header_unpack(&rh, cell.payload);
  275. r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  276. tt_int_op(r, ==, -1);
  277. /* Bogus family: 7. */
  278. make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
  279. "\x00\x00\x00\x00\x07"
  280. "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
  281. "\x00\x00\x00\x00\x00\x00\x00\x68"
  282. "\x90\x00\x02\x58", 25);
  283. relay_header_unpack(&rh, cell.payload);
  284. r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  285. tt_int_op(r, ==, -1);
  286. /* Truncated IPv6. */
  287. make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
  288. "\x00\x00\x00\x00\x06"
  289. "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
  290. "\x00\x00\x00\x00\x00\x00\x00\x68"
  291. "\x00\x00\x02", 24);
  292. relay_header_unpack(&rh, cell.payload);
  293. r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  294. tt_int_op(r, ==, -1);
  295. /* Now make sure we can generate connected cells correctly. */
  296. /* Try an IPv4 address */
  297. memset(&rh, 0, sizeof(rh));
  298. memset(&cell, 0, sizeof(cell));
  299. tor_addr_parse(&addr, "30.40.50.60");
  300. rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE,
  301. &addr, 128);
  302. tt_int_op(rh.length, ==, 8);
  303. test_memeq_hex(cell.payload+RELAY_HEADER_SIZE, "1e28323c" "00000080");
  304. /* Try parsing it. */
  305. tor_addr_make_unspec(&addr);
  306. r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  307. tt_int_op(r, ==, 0);
  308. tt_int_op(tor_addr_family(&addr), ==, AF_INET);
  309. tt_str_op(fmt_addr(&addr), ==, "30.40.50.60");
  310. tt_int_op(ttl, ==, 128);
  311. /* Try an IPv6 address */
  312. memset(&rh, 0, sizeof(rh));
  313. memset(&cell, 0, sizeof(cell));
  314. tor_addr_parse(&addr, "2620::6b0:b:1a1a:0:26e5:480e");
  315. rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE,
  316. &addr, 3600);
  317. tt_int_op(rh.length, ==, 25);
  318. test_memeq_hex(cell.payload + RELAY_HEADER_SIZE,
  319. "00000000" "06"
  320. "2620000006b0000b1a1a000026e5480e" "00000e10");
  321. /* Try parsing it. */
  322. tor_addr_make_unspec(&addr);
  323. r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  324. tt_int_op(r, ==, 0);
  325. tt_int_op(tor_addr_family(&addr), ==, AF_INET6);
  326. tt_str_op(fmt_addr(&addr), ==, "2620:0:6b0:b:1a1a:0:26e5:480e");
  327. tt_int_op(ttl, ==, 3600);
  328. done:
  329. tor_free(mem_op_hex_tmp);
  330. }
  331. #define TEST(name, flags) \
  332. { #name, test_cfmt_ ## name, flags, 0, NULL }
  333. struct testcase_t cell_format_tests[] = {
  334. TEST(relay_header, 0),
  335. TEST(begin_cells, 0),
  336. TEST(connected_cells, 0),
  337. END_OF_TESTCASES
  338. };