test_extorport.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /* Copyright (c) 2013, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. #define CONNECTION_PRIVATE
  4. #define EXT_ORPORT_PRIVATE
  5. #include "or.h"
  6. #include "buffers.h"
  7. #include "connection.h"
  8. #include "ext_orport.h"
  9. #include "test.h"
  10. /* Test connection_or_remove_from_ext_or_id_map and
  11. * connection_or_set_ext_or_identifier */
  12. static void
  13. test_ext_or_id_map(void *arg)
  14. {
  15. or_connection_t *c1 = NULL, *c2 = NULL, *c3 = NULL;
  16. char *idp = NULL, *idp2 = NULL;
  17. (void)arg;
  18. /* pre-initialization */
  19. tt_ptr_op(NULL, ==, connection_or_get_by_ext_or_id("xxxxxxxxxxxxxxxxxxxx"));
  20. c1 = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
  21. c2 = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
  22. c3 = or_connection_new(CONN_TYPE_OR, AF_INET);
  23. tt_ptr_op(c1->ext_or_conn_id, !=, NULL);
  24. tt_ptr_op(c2->ext_or_conn_id, !=, NULL);
  25. tt_ptr_op(c3->ext_or_conn_id, ==, NULL);
  26. tt_ptr_op(c1, ==, connection_or_get_by_ext_or_id(c1->ext_or_conn_id));
  27. tt_ptr_op(c2, ==, connection_or_get_by_ext_or_id(c2->ext_or_conn_id));
  28. tt_ptr_op(NULL, ==, connection_or_get_by_ext_or_id("xxxxxxxxxxxxxxxxxxxx"));
  29. idp = tor_memdup(c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN);
  30. /* Give c2 a new ID. */
  31. connection_or_set_ext_or_identifier(c2);
  32. test_mem_op(idp, !=, c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN);
  33. idp2 = tor_memdup(c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN);
  34. tt_assert(!tor_digest_is_zero(idp2));
  35. tt_ptr_op(NULL, ==, connection_or_get_by_ext_or_id(idp));
  36. tt_ptr_op(c2, ==, connection_or_get_by_ext_or_id(idp2));
  37. /* Now remove it. */
  38. connection_or_remove_from_ext_or_id_map(c2);
  39. tt_ptr_op(NULL, ==, connection_or_get_by_ext_or_id(idp));
  40. tt_ptr_op(NULL, ==, connection_or_get_by_ext_or_id(idp2));
  41. done:
  42. if (c1)
  43. connection_free_(TO_CONN(c1));
  44. if (c2)
  45. connection_free_(TO_CONN(c2));
  46. if (c3)
  47. connection_free_(TO_CONN(c3));
  48. tor_free(idp);
  49. tor_free(idp2);
  50. connection_or_clear_ext_or_id_map();
  51. }
  52. /* Simple connection_write_to_buf_impl_ replacement that unconditionally
  53. * writes to outbuf. */
  54. static void
  55. connection_write_to_buf_impl_replacement(const char *string, size_t len,
  56. connection_t *conn, int zlib)
  57. {
  58. (void) zlib;
  59. tor_assert(string);
  60. tor_assert(conn);
  61. write_to_buf(string, len, conn->outbuf);
  62. }
  63. static char *
  64. buf_get_contents(buf_t *buf, size_t *sz_out)
  65. {
  66. char *out;
  67. *sz_out = buf_datalen(buf);
  68. if (*sz_out >= ULONG_MAX)
  69. return NULL; /* C'mon, really? */
  70. out = tor_malloc(*sz_out + 1);
  71. if (fetch_from_buf(out, (unsigned long)*sz_out, buf) != 0) {
  72. tor_free(out);
  73. return NULL;
  74. }
  75. out[*sz_out] = '\0'; /* Hopefully gratuitous. */
  76. return out;
  77. }
  78. static void
  79. test_ext_or_write_command(void *arg)
  80. {
  81. or_connection_t *c1;
  82. char *cp = NULL;
  83. char *buf = NULL;
  84. size_t sz;
  85. (void) arg;
  86. MOCK(connection_write_to_buf_impl_,
  87. connection_write_to_buf_impl_replacement);
  88. c1 = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
  89. tt_assert(c1);
  90. /* Length too long */
  91. tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 100, "X", 100000),
  92. <, 0);
  93. /* Empty command */
  94. tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 0x99, NULL, 0),
  95. ==, 0);
  96. cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz);
  97. tt_int_op(sz, ==, 4);
  98. test_mem_op(cp, ==, "\x00\x99\x00\x00", 4);
  99. tor_free(cp);
  100. /* Medium command. */
  101. tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 0x99,
  102. "Wai\0Hello", 9), ==, 0);
  103. cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz);
  104. tt_int_op(sz, ==, 13);
  105. test_mem_op(cp, ==, "\x00\x99\x00\x09Wai\x00Hello", 13);
  106. tor_free(cp);
  107. /* Long command */
  108. buf = tor_malloc(65535);
  109. memset(buf, 'x', 65535);
  110. tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 0xf00d,
  111. buf, 65535), ==, 0);
  112. cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz);
  113. tt_int_op(sz, ==, 65539);
  114. test_mem_op(cp, ==, "\xf0\x0d\xff\xff", 4);
  115. test_mem_op(cp+4, ==, buf, 65535);
  116. tor_free(cp);
  117. done:
  118. if (c1)
  119. connection_free_(TO_CONN(c1));
  120. tor_free(cp);
  121. tor_free(buf);
  122. UNMOCK(connection_write_to_buf_impl_);
  123. }
  124. struct testcase_t extorport_tests[] = {
  125. { "id_map", test_ext_or_id_map, TT_FORK, NULL, NULL },
  126. { "write_command", test_ext_or_write_command, TT_FORK, NULL, NULL },
  127. END_OF_TESTCASES
  128. };