Tor  0.4.7.0-alpha-dev
btrack_orconn_cevent.c
Go to the documentation of this file.
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"
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) {
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;
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;
87  control_event_bootstrap(BOOTSTRAP_STATUS_CONN_DONE, 0);
88  break;
92  control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE, 0);
93  break;
94  case OR_CONN_STATE_OPEN:
95  control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE_DONE, 0);
96  /* Unblock directory progress display */
98  /* Unblock apconn progress display */
99  bto_first_orconn = true;
100  break;
101  default:
102  break;
103  }
104 }
105 
106 /**
107  * Emit control events when we have updated our idea of the best state
108  * that any application circuit OR connection has reached.
109  *
110  * Do some decoding of the ORCONN states depending on whether a PT or
111  * a proxy is in use.
112  **/
113 void
114 bto_cevent_apconn(const bt_orconn_t *bto)
115 {
116  if (!bto_first_orconn)
117  return;
118 
119  switch (bto->state) {
121  /* Exactly what kind of thing we're connecting to isn't
122  * information we directly get from the states in connection_or.c,
123  * so decode it here. */
124  if (using_pt(bto))
125  control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN_PT, 0);
126  else if (using_proxy(bto))
127  control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN_PROXY, 0);
128  else
129  control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN, 0);
130  break;
132  /* Similarly, starting a proxy handshake means the TCP connect()
133  * succeeded to the proxy. Let's be specific about what kind of
134  * proxy. */
135  if (using_pt(bto))
136  control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN_DONE_PT, 0);
137  else if (using_proxy(bto))
138  control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN_DONE_PROXY, 0);
139  break;
141  control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN_DONE, 0);
142  break;
146  control_event_bootstrap(BOOTSTRAP_STATUS_AP_HANDSHAKE, 0);
147  break;
148  case OR_CONN_STATE_OPEN:
149  control_event_bootstrap(BOOTSTRAP_STATUS_AP_HANDSHAKE_DONE, 0);
150  break;
151  default:
152  break;
153  }
154 }
155 
156 /** Forget that we completed our first OR connection */
157 void
159 {
160  bto_first_orconn = false;
161 }
Header file for btrack_orconn.c.
void bto_cevent_reset(void)
void bto_cevent_anyconn(const bt_orconn_t *bto)
static bool using_pt(const bt_orconn_t *bto)
void bto_cevent_apconn(const bt_orconn_t *bto)
static bool using_proxy(const bt_orconn_t *bto)
static bool bto_first_orconn
Header file for btrack_orconn_cevent.c.
void control_event_bootstrap(bootstrap_status_t status, int progress)
void control_event_boot_first_orconn(void)
Header file for control_events.c.
Master header file for Tor-specific functionality.
Header file for orconn_event.c.
#define OR_CONN_STATE_CONNECTING
Definition: orconn_event.h:31
#define OR_CONN_STATE_OR_HANDSHAKING_V2
Definition: orconn_event.h:47
#define OR_CONN_STATE_PROXY_HANDSHAKING
Definition: orconn_event.h:33
#define OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING
Definition: orconn_event.h:39
#define OR_CONN_STATE_TLS_HANDSHAKING
Definition: orconn_event.h:36
#define OR_CONN_STATE_OR_HANDSHAKING_V3
Definition: orconn_event.h:51
#define OR_CONN_STATE_OPEN
Definition: orconn_event.h:53