test_channeltls.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /* Copyright (c) 2014, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. #include <math.h>
  4. #define TOR_CHANNEL_INTERNAL_
  5. #include "or.h"
  6. #include "address.h"
  7. #include "channel.h"
  8. #include "channeltls.h"
  9. #include "connection_or.h"
  10. #include "config.h"
  11. /* For init/free stuff */
  12. #include "scheduler.h"
  13. #include "tortls.h"
  14. /* Test suite stuff */
  15. #include "test.h"
  16. #include "fakechans.h"
  17. /* The channeltls unit tests */
  18. static void test_channeltls_create(void *arg);
  19. static void test_channeltls_overhead_estimate(void *arg);
  20. /* Mocks used by channeltls unit tests */
  21. static or_connection_t * tlschan_connection_or_connect_mock(
  22. const tor_addr_t *addr,
  23. uint16_t port,
  24. const char *digest,
  25. channel_tls_t *tlschan);
  26. static int tlschan_is_local_addr_mock(const tor_addr_t *addr);
  27. /* Fake close method */
  28. static void tlschan_fake_close_method(channel_t *chan);
  29. /* Flags controlling behavior of channeltls unit test mocks */
  30. static int tlschan_local = 0;
  31. /* Thing to cast to fake tor_tls_t * to appease assert_connection_ok() */
  32. static int fake_tortls = 0; /* Bleh... */
  33. static void
  34. test_channeltls_create(void *arg)
  35. {
  36. tor_addr_t test_addr;
  37. channel_t *ch = NULL;
  38. const char test_digest[DIGEST_LEN] = {
  39. 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
  40. 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14 };
  41. (void)arg;
  42. /* Set up a fake address to fake-connect to */
  43. test_addr.family = AF_INET;
  44. test_addr.addr.in_addr.s_addr = htonl(0x01020304);
  45. /* For this test we always want the address to be treated as non-local */
  46. tlschan_local = 0;
  47. /* Install is_local_addr() mock */
  48. MOCK(is_local_addr, tlschan_is_local_addr_mock);
  49. /* Install mock for connection_or_connect() */
  50. MOCK(connection_or_connect, tlschan_connection_or_connect_mock);
  51. /* Try connecting */
  52. ch = channel_tls_connect(&test_addr, 567, test_digest);
  53. test_assert(ch != NULL);
  54. done:
  55. if (ch) {
  56. MOCK(scheduler_release_channel, scheduler_release_channel_mock);
  57. /*
  58. * Use fake close method that doesn't try to do too much to fake
  59. * orconn
  60. */
  61. ch->close = tlschan_fake_close_method;
  62. channel_mark_for_close(ch);
  63. tor_free(ch);
  64. UNMOCK(scheduler_release_channel);
  65. }
  66. UNMOCK(connection_or_connect);
  67. UNMOCK(is_local_addr);
  68. return;
  69. }
  70. static void
  71. test_channeltls_overhead_estimate(void *arg)
  72. {
  73. tor_addr_t test_addr;
  74. channel_t *ch = NULL;
  75. const char test_digest[DIGEST_LEN] = {
  76. 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
  77. 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14 };
  78. float r;
  79. channel_tls_t *tlschan = NULL;
  80. (void)arg;
  81. /* Set up a fake address to fake-connect to */
  82. test_addr.family = AF_INET;
  83. test_addr.addr.in_addr.s_addr = htonl(0x01020304);
  84. /* For this test we always want the address to be treated as non-local */
  85. tlschan_local = 0;
  86. /* Install is_local_addr() mock */
  87. MOCK(is_local_addr, tlschan_is_local_addr_mock);
  88. /* Install mock for connection_or_connect() */
  89. MOCK(connection_or_connect, tlschan_connection_or_connect_mock);
  90. /* Try connecting */
  91. ch = channel_tls_connect(&test_addr, 567, test_digest);
  92. test_assert(ch != NULL);
  93. /* First case: silly low ratios should get clamped to 1.0f */
  94. tlschan = BASE_CHAN_TO_TLS(ch);
  95. test_assert(tlschan != NULL);
  96. tlschan->conn->bytes_xmitted = 128;
  97. tlschan->conn->bytes_xmitted_by_tls = 64;
  98. r = ch->get_overhead_estimate(ch);
  99. test_assert(fabsf(r - 1.0f) < 1E-12);
  100. tlschan->conn->bytes_xmitted_by_tls = 127;
  101. r = ch->get_overhead_estimate(ch);
  102. test_assert(fabsf(r - 1.0f) < 1E-12);
  103. /* Now middle of the range */
  104. tlschan->conn->bytes_xmitted_by_tls = 192;
  105. r = ch->get_overhead_estimate(ch);
  106. test_assert(fabsf(r - 1.5f) < 1E-12);
  107. /* Now above the 2.0f clamp */
  108. tlschan->conn->bytes_xmitted_by_tls = 257;
  109. r = ch->get_overhead_estimate(ch);
  110. test_assert(fabsf(r - 2.0f) < 1E-12);
  111. tlschan->conn->bytes_xmitted_by_tls = 512;
  112. r = ch->get_overhead_estimate(ch);
  113. test_assert(fabsf(r - 2.0f) < 1E-12);
  114. done:
  115. if (ch) {
  116. MOCK(scheduler_release_channel, scheduler_release_channel_mock);
  117. /*
  118. * Use fake close method that doesn't try to do too much to fake
  119. * orconn
  120. */
  121. ch->close = tlschan_fake_close_method;
  122. channel_mark_for_close(ch);
  123. tor_free(ch);
  124. UNMOCK(scheduler_release_channel);
  125. }
  126. UNMOCK(connection_or_connect);
  127. UNMOCK(is_local_addr);
  128. return;
  129. }
  130. static or_connection_t *
  131. tlschan_connection_or_connect_mock(const tor_addr_t *addr,
  132. uint16_t port,
  133. const char *digest,
  134. channel_tls_t *tlschan)
  135. {
  136. or_connection_t *result = NULL;
  137. test_assert(addr != NULL);
  138. test_assert(port != 0);
  139. test_assert(digest != NULL);
  140. test_assert(tlschan != NULL);
  141. /* Make a fake orconn */
  142. result = tor_malloc_zero(sizeof(*result));
  143. result->base_.magic = OR_CONNECTION_MAGIC;
  144. result->base_.state = OR_CONN_STATE_OPEN;
  145. result->base_.type = CONN_TYPE_OR;
  146. result->base_.socket_family = addr->family;
  147. result->base_.address = tor_strdup("<fake>");
  148. memcpy(&(result->base_.addr), addr, sizeof(tor_addr_t));
  149. result->base_.port = port;
  150. memcpy(result->identity_digest, digest, DIGEST_LEN);
  151. result->chan = tlschan;
  152. memcpy(&(result->real_addr), addr, sizeof(tor_addr_t));
  153. result->tls = (tor_tls_t *)((void *)(&fake_tortls));
  154. done:
  155. return result;
  156. }
  157. static void
  158. tlschan_fake_close_method(channel_t *chan)
  159. {
  160. channel_tls_t *tlschan = NULL;
  161. test_assert(chan != NULL);
  162. test_eq(chan->magic, TLS_CHAN_MAGIC);
  163. tlschan = BASE_CHAN_TO_TLS(chan);
  164. test_assert(tlschan != NULL);
  165. /* Just free the fake orconn */
  166. tor_free(tlschan->conn);
  167. channel_closed(chan);
  168. done:
  169. return;
  170. }
  171. static int
  172. tlschan_is_local_addr_mock(const tor_addr_t *addr)
  173. {
  174. test_assert(addr != NULL);
  175. done:
  176. return tlschan_local;
  177. }
  178. struct testcase_t channeltls_tests[] = {
  179. { "create", test_channeltls_create, TT_FORK, NULL, NULL },
  180. { "overhead_estimate", test_channeltls_overhead_estimate,
  181. TT_FORK, NULL, NULL },
  182. END_OF_TESTCASES
  183. };