mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 23:53:32 +01:00
Support time-based half-closed connection handling.
Since we no longer use stream SENDMEs for congestion control, we must now use time to decide when data should stop arriving on a half-closed stream.
This commit is contained in:
parent
bd0aabe20f
commit
5e17f8acab
@ -69,6 +69,8 @@
|
||||
#include "core/or/circuituse.h"
|
||||
#include "core/or/circuitpadding.h"
|
||||
#include "core/or/connection_edge.h"
|
||||
#include "core/or/congestion_control_flow.h"
|
||||
#include "core/or/circuitstats.h"
|
||||
#include "core/or/connection_or.h"
|
||||
#include "core/or/extendinfo.h"
|
||||
#include "core/or/policies.h"
|
||||
@ -614,20 +616,39 @@ connection_half_edge_add(const edge_connection_t *conn,
|
||||
|
||||
half_conn->stream_id = conn->stream_id;
|
||||
|
||||
// How many sendme's should I expect?
|
||||
half_conn->sendmes_pending =
|
||||
(STREAMWINDOW_START-conn->package_window)/STREAMWINDOW_INCREMENT;
|
||||
|
||||
// Is there a connected cell pending?
|
||||
half_conn->connected_pending = conn->base_.state ==
|
||||
AP_CONN_STATE_CONNECT_WAIT;
|
||||
|
||||
/* Data should only arrive if we're not waiting on a resolved cell.
|
||||
* It can arrive after waiting on connected, because of optimistic
|
||||
* data. */
|
||||
if (conn->base_.state != AP_CONN_STATE_RESOLVE_WAIT) {
|
||||
// How many more data cells can arrive on this id?
|
||||
half_conn->data_pending = conn->deliver_window;
|
||||
if (edge_uses_flow_control(conn)) {
|
||||
/* If the edge uses the new congestion control flow control, we must use
|
||||
* time-based limits on half-edge activity. */
|
||||
uint64_t timeout_usec = (uint64_t)(get_circuit_build_timeout_ms()*1000);
|
||||
half_conn->used_ccontrol = 1;
|
||||
|
||||
/* If this is an onion service circuit, double the CBT as an approximate
|
||||
* value for the other half of the circuit */
|
||||
if (conn->hs_ident) {
|
||||
timeout_usec *= 2;
|
||||
}
|
||||
|
||||
/* The stream should stop seeing any use after the larger of the circuit
|
||||
* RTT and the overall circuit build timeout */
|
||||
half_conn->end_ack_expected_usec = MAX(timeout_usec,
|
||||
edge_get_max_rtt(conn)) +
|
||||
monotime_absolute_usec();
|
||||
} else {
|
||||
// How many sendme's should I expect?
|
||||
half_conn->sendmes_pending =
|
||||
(STREAMWINDOW_START-conn->package_window)/STREAMWINDOW_INCREMENT;
|
||||
|
||||
/* Data should only arrive if we're not waiting on a resolved cell.
|
||||
* It can arrive after waiting on connected, because of optimistic
|
||||
* data. */
|
||||
if (conn->base_.state != AP_CONN_STATE_RESOLVE_WAIT) {
|
||||
// How many more data cells can arrive on this id?
|
||||
half_conn->data_pending = conn->deliver_window;
|
||||
}
|
||||
}
|
||||
|
||||
insert_at = smartlist_bsearch_idx(circ->half_streams, &half_conn->stream_id,
|
||||
@ -688,6 +709,12 @@ connection_half_edge_is_valid_data(const smartlist_t *half_conns,
|
||||
if (!half)
|
||||
return 0;
|
||||
|
||||
if (half->used_ccontrol) {
|
||||
if (monotime_absolute_usec() > half->end_ack_expected_usec)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (half->data_pending > 0) {
|
||||
half->data_pending--;
|
||||
return 1;
|
||||
@ -740,6 +767,10 @@ connection_half_edge_is_valid_sendme(const smartlist_t *half_conns,
|
||||
if (!half)
|
||||
return 0;
|
||||
|
||||
/* congestion control edges don't use sendmes */
|
||||
if (half->used_ccontrol)
|
||||
return 0;
|
||||
|
||||
if (half->sendmes_pending > 0) {
|
||||
half->sendmes_pending--;
|
||||
return 1;
|
||||
|
@ -31,6 +31,18 @@ typedef struct half_edge_t {
|
||||
* our deliver window */
|
||||
int data_pending;
|
||||
|
||||
/**
|
||||
* Monotime timestamp of when the other end should have successfuly
|
||||
* shut down the stream and stop sending data, based on the larger
|
||||
* of circuit RTT and CBT. Used if 'used_ccontrol' is true, to expire
|
||||
* the half_edge at this monotime timestamp. */
|
||||
uint64_t end_ack_expected_usec;
|
||||
|
||||
/**
|
||||
* Did this edge use congestion control? If so, use
|
||||
* timer instead of pending data approach */
|
||||
int used_ccontrol : 1;
|
||||
|
||||
/** Is there a connected cell pending? */
|
||||
int connected_pending : 1;
|
||||
} half_edge_t;
|
||||
|
Loading…
Reference in New Issue
Block a user