|
|
@@ -23,6 +23,13 @@ safe_connection_refresh_events(safe_connection_t *safe_conn);
|
|
|
static void
|
|
|
safe_or_connection_refresh_bucket_rw_states(safe_or_connection_t *safe_or_conn);
|
|
|
|
|
|
+static void
|
|
|
+safe_or_conn_link_protocol_version_cb(event_label_t label, event_data_t data,
|
|
|
+ void *context);
|
|
|
+
|
|
|
+static void
|
|
|
+safe_or_conn_open_cb(event_label_t label, event_data_t data, void *context);
|
|
|
+
|
|
|
static tor_error_t
|
|
|
safe_or_connection_update_state(safe_or_connection_t *safe_or_conn,
|
|
|
or_conn_state_t new_state);
|
|
|
@@ -131,6 +138,7 @@ socket_rw_state_set(socket_rw_state_t *rw_state,
|
|
|
|
|
|
void
|
|
|
safe_connection_init(safe_connection_t *safe_conn, uint32_t type_magic,
|
|
|
+ event_source_t *conn_event_source,
|
|
|
bool (*is_read_wanted)(safe_connection_t *),
|
|
|
bool (*is_write_wanted)(safe_connection_t *),
|
|
|
void (*read_cb)(safe_connection_t *),
|
|
|
@@ -140,6 +148,8 @@ safe_connection_init(safe_connection_t *safe_conn, uint32_t type_magic,
|
|
|
void (*outbuf_modified_cb)(safe_connection_t *),
|
|
|
bool requires_buffers, bool linked)
|
|
|
{
|
|
|
+ (void)conn_event_source;
|
|
|
+
|
|
|
tor_assert(safe_conn != NULL);
|
|
|
tor_assert(is_read_wanted != NULL);
|
|
|
tor_assert(is_write_wanted != NULL);
|
|
|
@@ -153,6 +163,7 @@ safe_connection_init(safe_connection_t *safe_conn, uint32_t type_magic,
|
|
|
safe_conn->linked = linked;
|
|
|
|
|
|
safe_conn->event_source = event_source_new();
|
|
|
+ safe_conn->event_listener = event_listener_new(safe_conn);
|
|
|
|
|
|
socket_rw_state_init(&safe_conn->read_allowed, true);
|
|
|
socket_rw_state_init(&safe_conn->write_allowed, true);
|
|
|
@@ -293,6 +304,7 @@ safe_connection_unregister_events(safe_connection_t *safe_conn)
|
|
|
if (safe_conn->write_event != NULL) {
|
|
|
tor_event_free(safe_conn->write_event);
|
|
|
}
|
|
|
+ event_listener_detach(safe_conn->event_listener);
|
|
|
|
|
|
tor_mutex_release(&safe_conn->lock);
|
|
|
}
|
|
|
@@ -324,6 +336,8 @@ safe_connection_register_events(safe_connection_t *safe_conn,
|
|
|
return E_ERROR;
|
|
|
}
|
|
|
|
|
|
+ event_listener_attach(safe_conn->event_listener, event_base);
|
|
|
+
|
|
|
safe_connection_refresh_events(safe_conn);
|
|
|
|
|
|
tor_mutex_release(&safe_conn->lock);
|
|
|
@@ -448,13 +462,15 @@ safe_connection_outbuf_modified(safe_connection_t *safe_conn)
|
|
|
|
|
|
safe_or_connection_t *
|
|
|
safe_or_connection_new(bool requires_buffers, bool is_outgoing,
|
|
|
- const char *remote_address_str)
|
|
|
+ const char *remote_address_str,
|
|
|
+ event_source_t *conn_event_source)
|
|
|
{
|
|
|
safe_or_connection_t *safe_or_conn = \
|
|
|
tor_malloc_zero(sizeof(safe_or_connection_t));
|
|
|
|
|
|
safe_connection_init(TO_SAFE_CONN(safe_or_conn),
|
|
|
SAFE_OR_CONN_MAGIC,
|
|
|
+ conn_event_source,
|
|
|
safe_or_connection_is_read_wanted,
|
|
|
safe_or_connection_is_write_wanted,
|
|
|
safe_or_connection_read_cb,
|
|
|
@@ -475,9 +491,25 @@ safe_or_connection_new(bool requires_buffers, bool is_outgoing,
|
|
|
log_warn(LD_OR, "No remote address string was provided");
|
|
|
}
|
|
|
|
|
|
+ event_listener_set_callback(TO_SAFE_CONN(safe_or_conn)->event_listener,
|
|
|
+ or_conn_link_protocol_version_ev,
|
|
|
+ NULL, safe_or_conn_link_protocol_version_cb);
|
|
|
+ event_listener_set_callback(TO_SAFE_CONN(safe_or_conn)->event_listener,
|
|
|
+ or_conn_open_ev,
|
|
|
+ NULL, safe_or_conn_open_cb);
|
|
|
+
|
|
|
+ if (conn_event_source) {
|
|
|
+ event_source_subscribe(conn_event_source,
|
|
|
+ TO_SAFE_CONN(safe_or_conn)->event_listener,
|
|
|
+ or_conn_link_protocol_version_ev);
|
|
|
+ event_source_subscribe(conn_event_source,
|
|
|
+ TO_SAFE_CONN(safe_or_conn)->event_listener,
|
|
|
+ or_conn_open_ev);
|
|
|
+ }
|
|
|
+
|
|
|
safe_or_conn->link_protocol = 0; // unknown protocol
|
|
|
safe_or_conn->wide_circ_ids = false;
|
|
|
- safe_or_conn->allowed_to_process_cells = true;
|
|
|
+ safe_or_conn->waiting_for_link_protocol = false;
|
|
|
|
|
|
// these states should be set by 'safe_or_connection_update_state()'
|
|
|
socket_rw_state_init(&safe_or_conn->tor_read_wanted, false);
|
|
|
@@ -550,19 +582,42 @@ safe_or_connection_refresh_bucket_rw_states(safe_or_connection_t *safe_or_conn)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void
|
|
|
-safe_or_connection_set_link_protocol(safe_or_connection_t *safe_or_conn,
|
|
|
- uint16_t link_protocol)
|
|
|
+static void
|
|
|
+safe_or_conn_link_protocol_version_cb(event_label_t label, event_data_t data,
|
|
|
+ void *context)
|
|
|
{
|
|
|
+ safe_or_connection_t *safe_or_conn = context;
|
|
|
+ tor_assert(label == or_conn_link_protocol_version_ev);
|
|
|
tor_assert(safe_or_conn != NULL);
|
|
|
- tor_assert(link_protocol >= 3);
|
|
|
- tor_assert(safe_or_conn->allowed_to_process_cells == false);
|
|
|
tor_mutex_acquire(&TO_SAFE_CONN(safe_or_conn)->lock);
|
|
|
+ tor_assert(safe_or_conn->state == SAFE_OR_CONN_STATE_LINK_HANDSHAKING);
|
|
|
+ tor_assert(safe_or_conn->waiting_for_link_protocol);
|
|
|
+
|
|
|
+ uint16_t link_protocol = data.u16;
|
|
|
+ tor_assert(link_protocol >= 3);
|
|
|
|
|
|
safe_or_conn->link_protocol = link_protocol;
|
|
|
safe_or_conn->wide_circ_ids = (link_protocol >= 3);
|
|
|
- safe_or_conn->allowed_to_process_cells = true;
|
|
|
+ safe_or_conn->waiting_for_link_protocol = false;
|
|
|
event_active(TO_SAFE_CONN(safe_or_conn)->read_event, 0, 0);
|
|
|
+ // we need to process incoming cells on the buffer, even if there's
|
|
|
+ // no data waiting on the incoming socket
|
|
|
+
|
|
|
+ tor_mutex_release(&TO_SAFE_CONN(safe_or_conn)->lock);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+safe_or_conn_open_cb(event_label_t label, event_data_t data, void *context)
|
|
|
+{
|
|
|
+ (void)data;
|
|
|
+
|
|
|
+ safe_or_connection_t *safe_or_conn = context;
|
|
|
+ tor_assert(label == or_conn_open_ev);
|
|
|
+ tor_assert(safe_or_conn != NULL);
|
|
|
+ tor_mutex_acquire(&TO_SAFE_CONN(safe_or_conn)->lock);
|
|
|
+ tor_assert(safe_or_conn->state == SAFE_OR_CONN_STATE_LINK_HANDSHAKING);
|
|
|
+
|
|
|
+ safe_or_connection_update_state(safe_or_conn, SAFE_OR_CONN_STATE_OPEN);
|
|
|
|
|
|
tor_mutex_release(&TO_SAFE_CONN(safe_or_conn)->lock);
|
|
|
}
|
|
|
@@ -633,7 +688,7 @@ safe_or_connection_refill_buckets(safe_or_connection_t *safe_or_conn,
|
|
|
|
|
|
// TODO: this might be better implemented as a message so that we don't need
|
|
|
// to wait for the lock (but would require us to add a listener to the
|
|
|
-// safe conn
|
|
|
+// safe conn)
|
|
|
void
|
|
|
safe_or_connection_adjust_buckets(safe_or_connection_t *safe_or_conn,
|
|
|
uint32_t rate, uint32_t burst,
|
|
|
@@ -1335,7 +1390,9 @@ safe_or_connection_read_cb(safe_connection_t *safe_conn)
|
|
|
// TODO: we may not actually want to read here now that the states are
|
|
|
// updated, should we re-check?
|
|
|
|
|
|
- bool use_conn_buckets = (safe_or_conn->state == SAFE_OR_CONN_STATE_OPEN);
|
|
|
+ //bool use_conn_buckets = (safe_or_conn->state == SAFE_OR_CONN_STATE_OPEN);
|
|
|
+ bool use_conn_buckets = false;
|
|
|
+ // TODO: still need to implement a timer event to refresh the token buckets
|
|
|
|
|
|
tor_error_t rv = safe_or_connection_read_encrypted(safe_or_conn,
|
|
|
use_conn_buckets);
|
|
|
@@ -1344,7 +1401,7 @@ safe_or_connection_read_cb(safe_connection_t *safe_conn)
|
|
|
SAFE_OR_CONN_STATE_CLOSED) == E_SUCCESS);
|
|
|
}
|
|
|
|
|
|
- if (safe_or_conn->allowed_to_process_cells) {
|
|
|
+ if (!safe_or_conn->waiting_for_link_protocol) {
|
|
|
process_cells_from_inbuf(safe_or_conn);
|
|
|
}
|
|
|
|
|
|
@@ -1516,7 +1573,7 @@ process_cells_from_inbuf(safe_or_connection_t *safe_or_conn)
|
|
|
// this is the first VERSIONS cell we've received;
|
|
|
// in order to process future cells, we need to be told our
|
|
|
// protocol version
|
|
|
- safe_or_conn->allowed_to_process_cells = false;
|
|
|
+ safe_or_conn->waiting_for_link_protocol = true;
|
|
|
return;
|
|
|
}
|
|
|
} else {
|