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 }