|
@@ -4,6 +4,11 @@
|
|
|
/**
|
|
|
* \file btrack_orconn_cevent.c
|
|
|
* \brief Emit bootstrap status events for OR connections
|
|
|
+ *
|
|
|
+ * We do some decoding of the raw OR_CONN_STATE_* values. For
|
|
|
+ * example, OR_CONN_STATE_CONNECTING means the first TCP connect()
|
|
|
+ * completing, regardless of whether it's directly to a relay instead
|
|
|
+ * of a proxy or a PT.
|
|
|
**/
|
|
|
|
|
|
#include <stdbool.h>
|
|
@@ -25,33 +30,68 @@
|
|
|
**/
|
|
|
static bool bto_first_orconn = false;
|
|
|
|
|
|
+/** Is the ORCONN using a pluggable transport? */
|
|
|
+static bool
|
|
|
+using_pt(const bt_orconn_t *bto)
|
|
|
+{
|
|
|
+ return bto->proxy_type == PROXY_PLUGGABLE;
|
|
|
+}
|
|
|
+
|
|
|
+/** Is the ORCONN using a non-PT proxy? */
|
|
|
+static bool
|
|
|
+using_proxy(const bt_orconn_t *bto)
|
|
|
+{
|
|
|
+ switch (bto->proxy_type) {
|
|
|
+ case PROXY_CONNECT:
|
|
|
+ case PROXY_SOCKS4:
|
|
|
+ case PROXY_SOCKS5:
|
|
|
+ return true;
|
|
|
+ default:
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* Emit control events when we have updated our idea of the best state
|
|
|
* that any OR connection has reached.
|
|
|
+ *
|
|
|
+ * Do some decoding of the ORCONN states depending on whether a PT or
|
|
|
+ * a proxy is in use.
|
|
|
**/
|
|
|
void
|
|
|
bto_cevent_anyconn(const bt_orconn_t *bto)
|
|
|
{
|
|
|
switch (bto->state) {
|
|
|
case OR_CONN_STATE_CONNECTING:
|
|
|
+ /* Exactly what kind of thing we're connecting to isn't
|
|
|
+ * information we directly get from the states in connection_or.c,
|
|
|
+ * so decode it here. */
|
|
|
+ if (using_pt(bto))
|
|
|
+ control_event_bootstrap(BOOTSTRAP_STATUS_CONN_PT, 0);
|
|
|
+ else if (using_proxy(bto))
|
|
|
+ control_event_bootstrap(BOOTSTRAP_STATUS_CONN_PROXY, 0);
|
|
|
+ else
|
|
|
+ control_event_bootstrap(BOOTSTRAP_STATUS_CONN, 0);
|
|
|
+ break;
|
|
|
case OR_CONN_STATE_PROXY_HANDSHAKING:
|
|
|
- /* XXX This isn't quite right, because this isn't necessarily a
|
|
|
- directory server we're talking to, but we'll improve the
|
|
|
- bootstrap tags and messages later */
|
|
|
- control_event_bootstrap(BOOTSTRAP_STATUS_CONN_DIR, 0);
|
|
|
+ /* Similarly, starting a proxy handshake means the TCP connect()
|
|
|
+ * succeeded to the proxy. Let's be specific about what kind of
|
|
|
+ * proxy. */
|
|
|
+ if (using_pt(bto))
|
|
|
+ control_event_bootstrap(BOOTSTRAP_STATUS_CONN_DONE_PT, 0);
|
|
|
+ else if (using_proxy(bto))
|
|
|
+ control_event_bootstrap(BOOTSTRAP_STATUS_CONN_DONE_PROXY, 0);
|
|
|
break;
|
|
|
case OR_CONN_STATE_TLS_HANDSHAKING:
|
|
|
- /* Here we should report a connection completed (TCP or proxied),
|
|
|
- if we had the states */
|
|
|
+ control_event_bootstrap(BOOTSTRAP_STATUS_CONN_DONE, 0);
|
|
|
break;
|
|
|
case OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING:
|
|
|
case OR_CONN_STATE_OR_HANDSHAKING_V2:
|
|
|
case OR_CONN_STATE_OR_HANDSHAKING_V3:
|
|
|
- /* XXX Again, this isn't quite right, because it's not necessarily
|
|
|
- a directory server we're talking to. */
|
|
|
- control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE_DIR, 0);
|
|
|
+ control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE, 0);
|
|
|
break;
|
|
|
case OR_CONN_STATE_OPEN:
|
|
|
+ control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE_DONE, 0);
|
|
|
/* Unblock directory progress display */
|
|
|
control_event_boot_first_orconn();
|
|
|
/* Unblock apconn progress display */
|
|
@@ -65,6 +105,9 @@ bto_cevent_anyconn(const bt_orconn_t *bto)
|
|
|
/**
|
|
|
* Emit control events when we have updated our idea of the best state
|
|
|
* that any application circuit OR connection has reached.
|
|
|
+ *
|
|
|
+ * Do some decoding of the ORCONN states depending on whether a PT or
|
|
|
+ * a proxy is in use.
|
|
|
**/
|
|
|
void
|
|
|
bto_cevent_apconn(const bt_orconn_t *bto)
|
|
@@ -74,21 +117,35 @@ bto_cevent_apconn(const bt_orconn_t *bto)
|
|
|
|
|
|
switch (bto->state) {
|
|
|
case OR_CONN_STATE_CONNECTING:
|
|
|
+ /* Exactly what kind of thing we're connecting to isn't
|
|
|
+ * information we directly get from the states in connection_or.c,
|
|
|
+ * so decode it here. */
|
|
|
+ if (using_pt(bto))
|
|
|
+ control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN_PT, 0);
|
|
|
+ else if (using_proxy(bto))
|
|
|
+ control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN_PROXY, 0);
|
|
|
+ else
|
|
|
+ control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN, 0);
|
|
|
+ break;
|
|
|
case OR_CONN_STATE_PROXY_HANDSHAKING:
|
|
|
- control_event_bootstrap(BOOTSTRAP_STATUS_CONN_OR, 0);
|
|
|
+ /* Similarly, starting a proxy handshake means the TCP connect()
|
|
|
+ * succeeded to the proxy. Let's be specific about what kind of
|
|
|
+ * proxy. */
|
|
|
+ if (using_pt(bto))
|
|
|
+ control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN_DONE_PT, 0);
|
|
|
+ else if (using_proxy(bto))
|
|
|
+ control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN_DONE_PROXY, 0);
|
|
|
break;
|
|
|
case OR_CONN_STATE_TLS_HANDSHAKING:
|
|
|
- /* Here we should report a connection completed (TCP or proxied) */
|
|
|
+ control_event_bootstrap(BOOTSTRAP_STATUS_AP_CONN_DONE, 0);
|
|
|
break;
|
|
|
case OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING:
|
|
|
case OR_CONN_STATE_OR_HANDSHAKING_V2:
|
|
|
case OR_CONN_STATE_OR_HANDSHAKING_V3:
|
|
|
- control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE_OR, 0);
|
|
|
+ control_event_bootstrap(BOOTSTRAP_STATUS_AP_HANDSHAKE, 0);
|
|
|
break;
|
|
|
case OR_CONN_STATE_OPEN:
|
|
|
- /* XXX Not quite right, because it implictly reports the next
|
|
|
- state, but we'll improve it later. */
|
|
|
- control_event_bootstrap(BOOTSTRAP_STATUS_CIRCUIT_CREATE, 0);
|
|
|
+ control_event_bootstrap(BOOTSTRAP_STATUS_AP_HANDSHAKE_DONE, 0);
|
|
|
default:
|
|
|
break;
|
|
|
}
|