test_cell_formats.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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. #include "or.h"
  8. #include "connection_edge.h"
  9. #include "relay.h"
  10. #include "test.h"
  11. #include <stdlib.h>
  12. #include <string.h>
  13. static void
  14. test_cfmt_relay_header(void *arg)
  15. {
  16. relay_header_t rh;
  17. const uint8_t hdr_1[RELAY_HEADER_SIZE] =
  18. "\x03" "\x00\x00" "\x21\x22" "ABCD" "\x01\x03";
  19. uint8_t hdr_out[RELAY_HEADER_SIZE];
  20. (void)arg;
  21. tt_int_op(sizeof(hdr_1), ==, RELAY_HEADER_SIZE);
  22. relay_header_unpack(&rh, hdr_1);
  23. tt_int_op(rh.command, ==, 3);
  24. tt_int_op(rh.recognized, ==, 0);
  25. tt_int_op(rh.stream_id, ==, 0x2122);
  26. test_mem_op(rh.integrity, ==, "ABCD", 4);
  27. tt_int_op(rh.length, ==, 0x103);
  28. relay_header_pack(hdr_out, &rh);
  29. test_mem_op(hdr_out, ==, hdr_1, RELAY_HEADER_SIZE);
  30. done:
  31. ;
  32. }
  33. static void
  34. make_relay_cell(cell_t *out, uint8_t command,
  35. const void *body, size_t bodylen)
  36. {
  37. relay_header_t rh;
  38. memset(&rh, 0, sizeof(rh));
  39. rh.stream_id = 5;
  40. rh.command = command;
  41. rh.length = bodylen;
  42. out->command = CELL_RELAY;
  43. out->circ_id = 10;
  44. relay_header_pack(out->payload, &rh);
  45. memcpy(out->payload + RELAY_HEADER_SIZE, body, bodylen);
  46. }
  47. static void
  48. test_cfmt_begin_cells(void *arg)
  49. {
  50. cell_t cell;
  51. begin_cell_t bcell;
  52. uint8_t end_reason;
  53. (void)arg;
  54. /* Try begindir. */
  55. memset(&bcell, 0x7f, sizeof(bcell));
  56. make_relay_cell(&cell, RELAY_COMMAND_BEGIN_DIR, "", 0);
  57. tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  58. tt_ptr_op(NULL, ==, bcell.address);
  59. tt_int_op(0, ==, bcell.flags);
  60. tt_int_op(0, ==, bcell.port);
  61. tt_int_op(5, ==, bcell.stream_id);
  62. tt_int_op(1, ==, bcell.is_begindir);
  63. /* A Begindir with extra stuff. */
  64. memset(&bcell, 0x7f, sizeof(bcell));
  65. make_relay_cell(&cell, RELAY_COMMAND_BEGIN_DIR, "12345", 5);
  66. tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  67. tt_ptr_op(NULL, ==, bcell.address);
  68. tt_int_op(0, ==, bcell.flags);
  69. tt_int_op(0, ==, bcell.port);
  70. tt_int_op(5, ==, bcell.stream_id);
  71. tt_int_op(1, ==, bcell.is_begindir);
  72. /* A short but valid begin cell */
  73. memset(&bcell, 0x7f, sizeof(bcell));
  74. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:9", 6);
  75. tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  76. tt_str_op("a.b", ==, bcell.address);
  77. tt_int_op(0, ==, bcell.flags);
  78. tt_int_op(9, ==, bcell.port);
  79. tt_int_op(5, ==, bcell.stream_id);
  80. tt_int_op(0, ==, bcell.is_begindir);
  81. tor_free(bcell.address);
  82. /* A significantly loner begin cell */
  83. memset(&bcell, 0x7f, sizeof(bcell));
  84. {
  85. const char c[] = "here-is-a-nice-long.hostname.com:65535";
  86. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, strlen(c)+1);
  87. }
  88. tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  89. tt_str_op("here-is-a-nice-long.hostname.com", ==, bcell.address);
  90. tt_int_op(0, ==, bcell.flags);
  91. tt_int_op(65535, ==, bcell.port);
  92. tt_int_op(5, ==, bcell.stream_id);
  93. tt_int_op(0, ==, bcell.is_begindir);
  94. tor_free(bcell.address);
  95. /* An IPv4 begin cell. */
  96. memset(&bcell, 0x7f, sizeof(bcell));
  97. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "18.9.22.169:80", 15);
  98. tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  99. tt_str_op("18.9.22.169", ==, bcell.address);
  100. tt_int_op(0, ==, bcell.flags);
  101. tt_int_op(80, ==, bcell.port);
  102. tt_int_op(5, ==, bcell.stream_id);
  103. tt_int_op(0, ==, bcell.is_begindir);
  104. tor_free(bcell.address);
  105. /* An IPv6 begin cell. Let's make sure we handle colons*/
  106. memset(&bcell, 0x7f, sizeof(bcell));
  107. make_relay_cell(&cell, RELAY_COMMAND_BEGIN,
  108. "[2620::6b0:b:1a1a:0:26e5:480e]:80", 34);
  109. tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  110. tt_str_op("[2620::6b0:b:1a1a:0:26e5:480e]", ==, bcell.address);
  111. tt_int_op(0, ==, bcell.flags);
  112. tt_int_op(80, ==, bcell.port);
  113. tt_int_op(5, ==, bcell.stream_id);
  114. tt_int_op(0, ==, bcell.is_begindir);
  115. tor_free(bcell.address);
  116. /* a begin cell with extra junk but not enough for flags. */
  117. memset(&bcell, 0x7f, sizeof(bcell));
  118. {
  119. const char c[] = "another.example.com:80\x00\x01\x02";
  120. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
  121. }
  122. tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  123. tt_str_op("another.example.com", ==, bcell.address);
  124. tt_int_op(0, ==, bcell.flags);
  125. tt_int_op(80, ==, bcell.port);
  126. tt_int_op(5, ==, bcell.stream_id);
  127. tt_int_op(0, ==, bcell.is_begindir);
  128. tor_free(bcell.address);
  129. /* a begin cell with flags. */
  130. memset(&bcell, 0x7f, sizeof(bcell));
  131. {
  132. const char c[] = "another.example.com:443\x00\x01\x02\x03\x04";
  133. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
  134. }
  135. tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  136. tt_str_op("another.example.com", ==, bcell.address);
  137. tt_int_op(0x1020304, ==, bcell.flags);
  138. tt_int_op(443, ==, bcell.port);
  139. tt_int_op(5, ==, bcell.stream_id);
  140. tt_int_op(0, ==, bcell.is_begindir);
  141. tor_free(bcell.address);
  142. /* a begin cell with flags and even more cruft after that. */
  143. memset(&bcell, 0x7f, sizeof(bcell));
  144. {
  145. const char c[] = "a-further.example.com:22\x00\xee\xaa\x00\xffHi mom";
  146. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
  147. }
  148. tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  149. tt_str_op("a-further.example.com", ==, bcell.address);
  150. tt_int_op(0xeeaa00ff, ==, bcell.flags);
  151. tt_int_op(22, ==, bcell.port);
  152. tt_int_op(5, ==, bcell.stream_id);
  153. tt_int_op(0, ==, bcell.is_begindir);
  154. tor_free(bcell.address);
  155. /* bad begin cell: impossible length. */
  156. memset(&bcell, 0x7f, sizeof(bcell));
  157. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:80", 7);
  158. cell.payload[9] = 0x01; /* Set length to 510 */
  159. cell.payload[10] = 0xfe;
  160. {
  161. relay_header_t rh;
  162. relay_header_unpack(&rh, cell.payload);
  163. tt_int_op(rh.length, ==, 510);
  164. }
  165. tt_int_op(-2, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  166. /* Bad begin cell: no body. */
  167. memset(&bcell, 0x7f, sizeof(bcell));
  168. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "", 0);
  169. tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  170. /* bad begin cell: no body. */
  171. memset(&bcell, 0x7f, sizeof(bcell));
  172. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "", 0);
  173. tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  174. /* bad begin cell: no colon */
  175. memset(&bcell, 0x7f, sizeof(bcell));
  176. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b", 4);
  177. tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  178. /* bad begin cell: no ports */
  179. memset(&bcell, 0x7f, sizeof(bcell));
  180. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:", 5);
  181. tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  182. /* bad begin cell: bad port */
  183. memset(&bcell, 0x7f, sizeof(bcell));
  184. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:xyz", 8);
  185. tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  186. memset(&bcell, 0x7f, sizeof(bcell));
  187. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:100000", 11);
  188. tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  189. /* bad begin cell: no nul */
  190. memset(&bcell, 0x7f, sizeof(bcell));
  191. make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:80", 6);
  192. tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason));
  193. done:
  194. tor_free(bcell.address);
  195. }
  196. #define TEST(name, flags) \
  197. { #name, test_cfmt_ ## name, flags, 0, NULL }
  198. struct testcase_t cell_format_tests[] = {
  199. TEST(relay_header, 0),
  200. TEST(begin_cells, 0),
  201. END_OF_TESTCASES
  202. };