tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

btrack_orconn_cevent.c (4617B)


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