Control port STREAM XON/XOFF status event notification
[tor.git] / src / feature / control / btrack_orconn_cevent.c
blob525f4f5d0d4128d4079d7c39dfdebdcba8e14878
1 /* Copyright (c) 2007-2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 /**
5 * \file btrack_orconn_cevent.c
6 * \brief Emit bootstrap status events for OR connections
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 **/
14 #include <stdbool.h>
16 #include "core/or/or.h"
18 #define BTRACK_ORCONN_PRIVATE
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"
25 /**
26 * Have we completed our first OR connection?
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;
33 /** Is the ORCONN using a pluggable transport? */
34 static bool
35 using_pt(const bt_orconn_t *bto)
37 return bto->proxy_type == PROXY_PLUGGABLE;
40 /** Is the ORCONN using a non-PT proxy? */
41 static bool
42 using_proxy(const bt_orconn_t *bto)
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;
55 /**
56 * Emit control events when we have updated our idea of the best state
57 * that any OR connection has reached.
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)
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_TLS_CLIENT_RENEGOTIATING:
90 case OR_CONN_STATE_OR_HANDSHAKING_V2:
91 case OR_CONN_STATE_OR_HANDSHAKING_V3:
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 */
97 control_event_boot_first_orconn();
98 /* Unblock apconn progress display */
99 bto_first_orconn = true;
100 break;
101 default:
102 break;
107 * Emit control events when we have updated our idea of the best state
108 * that any application circuit OR connection has reached.
110 * Do some decoding of the ORCONN states depending on whether a PT or
111 * a proxy is in use.
113 void
114 bto_cevent_apconn(const bt_orconn_t *bto)
116 if (!bto_first_orconn)
117 return;
119 switch (bto->state) {
120 case OR_CONN_STATE_CONNECTING:
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;
131 case OR_CONN_STATE_PROXY_HANDSHAKING:
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;
140 case OR_CONN_STATE_TLS_HANDSHAKING:
141 control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN_DONE, 0);
142 break;
143 case OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING:
144 case OR_CONN_STATE_OR_HANDSHAKING_V2:
145 case OR_CONN_STATE_OR_HANDSHAKING_V3:
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;
156 /** Forget that we completed our first OR connection */
157 void
158 bto_cevent_reset(void)
160 bto_first_orconn = false;