btrack_orconn_cevent.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /* Copyright (c) 2007-2019, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file btrack_orconn_cevent.c
  5. * \brief Emit bootstrap status events for OR connections
  6. *
  7. * We do some decoding of the raw OR_CONN_STATE_* values. For
  8. * example, OR_CONN_STATE_CONNECTING means the first TCP connect()
  9. * completing, regardless of whether it's directly to a relay instead
  10. * of a proxy or a PT.
  11. **/
  12. #include <stdbool.h>
  13. #include "core/or/or.h"
  14. #define BTRACK_ORCONN_PRIVATE
  15. #include "core/or/orconn_event.h"
  16. #include "feature/control/btrack_orconn.h"
  17. #include "feature/control/btrack_orconn_cevent.h"
  18. #include "feature/control/control_events.h"
  19. /**
  20. * Have we completed our first OR connection?
  21. *
  22. * Block display of application circuit progress until we do, to avoid
  23. * some misleading behavior of jumping to high progress.
  24. **/
  25. static bool bto_first_orconn = false;
  26. /** Is the ORCONN using a pluggable transport? */
  27. static bool
  28. using_pt(const bt_orconn_t *bto)
  29. {
  30. return bto->proxy_type == PROXY_PLUGGABLE;
  31. }
  32. /** Is the ORCONN using a non-PT proxy? */
  33. static bool
  34. using_proxy(const bt_orconn_t *bto)
  35. {
  36. switch (bto->proxy_type) {
  37. case PROXY_CONNECT:
  38. case PROXY_SOCKS4:
  39. case PROXY_SOCKS5:
  40. return true;
  41. default:
  42. return false;
  43. }
  44. }
  45. /**
  46. * Emit control events when we have updated our idea of the best state
  47. * that any OR connection has reached.
  48. *
  49. * Do some decoding of the ORCONN states depending on whether a PT or
  50. * a proxy is in use.
  51. **/
  52. void
  53. bto_cevent_anyconn(const bt_orconn_t *bto)
  54. {
  55. switch (bto->state) {
  56. case OR_CONN_STATE_CONNECTING:
  57. /* Exactly what kind of thing we're connecting to isn't
  58. * information we directly get from the states in connection_or.c,
  59. * so decode it here. */
  60. if (using_pt(bto))
  61. control_event_bootstrap(BOOTSTRAP_STATUS_CONN_PT, 0);
  62. else if (using_proxy(bto))
  63. control_event_bootstrap(BOOTSTRAP_STATUS_CONN_PROXY, 0);
  64. else
  65. control_event_bootstrap(BOOTSTRAP_STATUS_CONN, 0);
  66. break;
  67. case OR_CONN_STATE_PROXY_HANDSHAKING:
  68. /* Similarly, starting a proxy handshake means the TCP connect()
  69. * succeeded to the proxy. Let's be specific about what kind of
  70. * proxy. */
  71. if (using_pt(bto))
  72. control_event_bootstrap(BOOTSTRAP_STATUS_CONN_DONE_PT, 0);
  73. else if (using_proxy(bto))
  74. control_event_bootstrap(BOOTSTRAP_STATUS_CONN_DONE_PROXY, 0);
  75. break;
  76. case OR_CONN_STATE_TLS_HANDSHAKING:
  77. control_event_bootstrap(BOOTSTRAP_STATUS_CONN_DONE, 0);
  78. break;
  79. case OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING:
  80. case OR_CONN_STATE_OR_HANDSHAKING_V2:
  81. case OR_CONN_STATE_OR_HANDSHAKING_V3:
  82. control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE, 0);
  83. break;
  84. case OR_CONN_STATE_OPEN:
  85. control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE_DONE, 0);
  86. /* Unblock directory progress display */
  87. control_event_boot_first_orconn();
  88. /* Unblock apconn progress display */
  89. bto_first_orconn = true;
  90. break;
  91. default:
  92. break;
  93. }
  94. }
  95. /**
  96. * Emit control events when we have updated our idea of the best state
  97. * that any application circuit OR connection has reached.
  98. *
  99. * Do some decoding of the ORCONN states depending on whether a PT or
  100. * a proxy is in use.
  101. **/
  102. void
  103. bto_cevent_apconn(const bt_orconn_t *bto)
  104. {
  105. if (!bto_first_orconn)
  106. return;
  107. switch (bto->state) {
  108. case OR_CONN_STATE_CONNECTING:
  109. /* Exactly what kind of thing we're connecting to isn't
  110. * information we directly get from the states in connection_or.c,
  111. * so decode it here. */
  112. if (using_pt(bto))
  113. control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN_PT, 0);
  114. else if (using_proxy(bto))
  115. control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN_PROXY, 0);
  116. else
  117. control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN, 0);
  118. break;
  119. case OR_CONN_STATE_PROXY_HANDSHAKING:
  120. /* Similarly, starting a proxy handshake means the TCP connect()
  121. * succeeded to the proxy. Let's be specific about what kind of
  122. * proxy. */
  123. if (using_pt(bto))
  124. control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN_DONE_PT, 0);
  125. else if (using_proxy(bto))
  126. control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN_DONE_PROXY, 0);
  127. break;
  128. case OR_CONN_STATE_TLS_HANDSHAKING:
  129. control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN_DONE, 0);
  130. break;
  131. case OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING:
  132. case OR_CONN_STATE_OR_HANDSHAKING_V2:
  133. case OR_CONN_STATE_OR_HANDSHAKING_V3:
  134. control_event_bootstrap(BOOTSTRAP_STATUS_AP_HANDSHAKE, 0);
  135. break;
  136. case OR_CONN_STATE_OPEN:
  137. control_event_bootstrap(BOOTSTRAP_STATUS_AP_HANDSHAKE_DONE, 0);
  138. default:
  139. break;
  140. }
  141. }
  142. /** Forget that we completed our first OR connection */
  143. void
  144. bto_cevent_reset(void)
  145. {
  146. bto_first_orconn = false;
  147. }