mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 14:23:30 +01:00
Split channel_t into channel_t and channel_listener_t; get rid of that big union
This commit is contained in:
parent
6391f963fb
commit
3f4b95b1a3
2129
src/or/channel.c
2129
src/or/channel.c
File diff suppressed because it is too large
Load Diff
375
src/or/channel.h
375
src/or/channel.h
@ -12,7 +12,7 @@
|
||||
#include "or.h"
|
||||
|
||||
/* Channel handler function pointer typedefs */
|
||||
typedef void (*channel_listener_fn_ptr)(channel_t *, channel_t *);
|
||||
typedef void (*channel_listener_fn_ptr)(channel_listener_t *, channel_t *);
|
||||
typedef void (*channel_cell_handler_fn_ptr)(channel_t *, cell_t *);
|
||||
typedef void (*channel_var_cell_handler_fn_ptr)(channel_t *, var_cell_t *);
|
||||
|
||||
@ -37,12 +37,6 @@ struct channel_s {
|
||||
/* Should we expect to see this channel in the channel lists? */
|
||||
unsigned char registered:1;
|
||||
|
||||
/** Set this if this channel is created in CHANNEL_STATE_LISTEN, so
|
||||
* lower-layer close methods that see the channel in CHANNEL_STATE_CLOSING
|
||||
* know.
|
||||
*/
|
||||
unsigned int is_listener:1;
|
||||
|
||||
/** Why did we close?
|
||||
*/
|
||||
enum {
|
||||
@ -67,171 +61,210 @@ struct channel_s {
|
||||
/* Optional method to dump transport-specific statistics on the channel */
|
||||
void (*dumpstats)(channel_t *, int);
|
||||
|
||||
union {
|
||||
struct {
|
||||
/* Registered listen handler to call on incoming connection */
|
||||
channel_listener_fn_ptr listener;
|
||||
/* Registered handlers for incoming cells */
|
||||
channel_cell_handler_fn_ptr cell_handler;
|
||||
channel_var_cell_handler_fn_ptr var_cell_handler;
|
||||
|
||||
/* List of pending incoming connections */
|
||||
smartlist_t *incoming_list;
|
||||
/* Methods implemented by the lower layer */
|
||||
|
||||
/* Timestamps for listeners */
|
||||
time_t timestamp_accepted;
|
||||
/*
|
||||
* Ask the underlying transport what the remote endpoint address is, in
|
||||
* a tor_addr_t. This is optional and subclasses may leave this NULL.
|
||||
* If they implement it, they should write the address out to the
|
||||
* provided tor_addr_t *, and return 1 if successful or 0 if no address
|
||||
* available.
|
||||
*/
|
||||
int (*get_remote_addr)(channel_t *, tor_addr_t *);
|
||||
/*
|
||||
* Get a text description of the remote endpoint; canonicalized if the
|
||||
* arg is 0, or the one we originally connected to/received from if it's
|
||||
* 1.
|
||||
*/
|
||||
const char * (*get_remote_descr)(channel_t *, int);
|
||||
/* Check if the lower layer has queued writes */
|
||||
int (*has_queued_writes)(channel_t *);
|
||||
/*
|
||||
* If the second param is zero, ask the lower layer if this is
|
||||
* 'canonical', for a transport-specific definition of canonical; if
|
||||
* it is 1, ask if the answer to the preceding query is safe to rely
|
||||
* on.
|
||||
*/
|
||||
int (*is_canonical)(channel_t *, int);
|
||||
/* Check if this channel matches a specified extend_info_t */
|
||||
int (*matches_extend_info)(channel_t *, extend_info_t *);
|
||||
/* Check if this channel matches a target address when extending */
|
||||
int (*matches_target)(channel_t *, const tor_addr_t *);
|
||||
/* Write a cell to an open channel */
|
||||
int (*write_cell)(channel_t *, cell_t *);
|
||||
/* Write a packed cell to an open channel */
|
||||
int (*write_packed_cell)(channel_t *, packed_cell_t *);
|
||||
/* Write a variable-length cell to an open channel */
|
||||
int (*write_var_cell)(channel_t *, var_cell_t *);
|
||||
|
||||
/* Counters for listeners */
|
||||
uint64_t n_accepted;
|
||||
} listener;
|
||||
struct {
|
||||
/* Registered handlers for incoming cells */
|
||||
channel_cell_handler_fn_ptr cell_handler;
|
||||
channel_var_cell_handler_fn_ptr var_cell_handler;
|
||||
/*
|
||||
* Hash of the public RSA key for the other side's identity key, or
|
||||
* zeroes if the other side hasn't shown us a valid identity key.
|
||||
*/
|
||||
char identity_digest[DIGEST_LEN];
|
||||
/* Nickname of the OR on the other side, or NULL if none. */
|
||||
char *nickname;
|
||||
|
||||
/* Methods implemented by the lower layer */
|
||||
/*
|
||||
* Linked list of channels with the same identity digest, for the
|
||||
* digest->channel map
|
||||
*/
|
||||
channel_t *next_with_same_id, *prev_with_same_id;
|
||||
|
||||
/*
|
||||
* Ask the underlying transport what the remote endpoint address is, in
|
||||
* a tor_addr_t. This is optional and subclasses may leave this NULL.
|
||||
* If they implement it, they should write the address out to the
|
||||
* provided tor_addr_t *, and return 1 if successful or 0 if no address
|
||||
* available.
|
||||
*/
|
||||
int (*get_remote_addr)(channel_t *, tor_addr_t *);
|
||||
/*
|
||||
* Get a text description of the remote endpoint; canonicalized if the
|
||||
* arg is 0, or the one we originally connected to/received from if it's
|
||||
* 1.
|
||||
*/
|
||||
const char * (*get_remote_descr)(channel_t *, int);
|
||||
/* Check if the lower layer has queued writes */
|
||||
int (*has_queued_writes)(channel_t *);
|
||||
/*
|
||||
* If the second param is zero, ask the lower layer if this is
|
||||
* 'canonical', for a transport-specific definition of canonical; if
|
||||
* it is 1, ask if the answer to the preceding query is safe to rely
|
||||
* on.
|
||||
*/
|
||||
int (*is_canonical)(channel_t *, int);
|
||||
/* Check if this channel matches a specified extend_info_t */
|
||||
int (*matches_extend_info)(channel_t *, extend_info_t *);
|
||||
/* Check if this channel matches a target address when extending */
|
||||
int (*matches_target)(channel_t *, const tor_addr_t *);
|
||||
/* Write a cell to an open channel */
|
||||
int (*write_cell)(channel_t *, cell_t *);
|
||||
/* Write a packed cell to an open channel */
|
||||
int (*write_packed_cell)(channel_t *, packed_cell_t *);
|
||||
/* Write a variable-length cell to an open channel */
|
||||
int (*write_var_cell)(channel_t *, var_cell_t *);
|
||||
/* List of incoming cells to handle */
|
||||
smartlist_t *incoming_queue;
|
||||
|
||||
/*
|
||||
* Hash of the public RSA key for the other side's identity key, or
|
||||
* zeroes if the other side hasn't shown us a valid identity key.
|
||||
*/
|
||||
char identity_digest[DIGEST_LEN];
|
||||
/* Nickname of the OR on the other side, or NULL if none. */
|
||||
char *nickname;
|
||||
/* List of queued outgoing cells */
|
||||
smartlist_t *outgoing_queue;
|
||||
|
||||
/*
|
||||
* Linked list of channels with the same identity digest, for the
|
||||
* digest->channel map
|
||||
*/
|
||||
channel_t *next_with_same_id, *prev_with_same_id;
|
||||
/* Circuit stuff for use by relay.c */
|
||||
|
||||
/* List of incoming cells to handle */
|
||||
smartlist_t *incoming_queue;
|
||||
/*
|
||||
* Double-linked ring of circuits with queued cells waiting for room to
|
||||
* free up on this connection's outbuf. Every time we pull cells from
|
||||
* a circuit, we advance this pointer to the next circuit in the ring.
|
||||
*/
|
||||
struct circuit_t *active_circuits;
|
||||
/*
|
||||
* Priority queue of cell_ewma_t for circuits with queued cells waiting
|
||||
* for room to free up on this connection's outbuf. Kept in heap order
|
||||
* according to EWMA.
|
||||
*
|
||||
* This is redundant with active_circuits; if we ever decide only to use
|
||||
* the cell_ewma algorithm for choosing circuits, we can remove
|
||||
* active_circuits.
|
||||
*/
|
||||
smartlist_t *active_circuit_pqueue;
|
||||
/*
|
||||
* The tick on which the cell_ewma_ts in active_circuit_pqueue last had
|
||||
* their ewma values rescaled.
|
||||
*/
|
||||
unsigned active_circuit_pqueue_last_recalibrated;
|
||||
|
||||
/* List of queued outgoing cells */
|
||||
smartlist_t *outgoing_queue;
|
||||
/* Circuit ID generation stuff for use by circuitbuild.c */
|
||||
|
||||
/* Circuit stuff for use by relay.c */
|
||||
/*
|
||||
* When we send CREATE cells along this connection, which half of the
|
||||
* space should we use?
|
||||
*/
|
||||
circ_id_type_t circ_id_type:2;
|
||||
/*
|
||||
* Which circ_id do we try to use next on this connection? This is
|
||||
* always in the range 0..1<<15-1.
|
||||
*/
|
||||
circid_t next_circ_id;
|
||||
|
||||
/*
|
||||
* Double-linked ring of circuits with queued cells waiting for room to
|
||||
* free up on this connection's outbuf. Every time we pull cells from
|
||||
* a circuit, we advance this pointer to the next circuit in the ring.
|
||||
*/
|
||||
struct circuit_t *active_circuits;
|
||||
/*
|
||||
* Priority queue of cell_ewma_t for circuits with queued cells waiting
|
||||
* for room to free up on this connection's outbuf. Kept in heap order
|
||||
* according to EWMA.
|
||||
*
|
||||
* This is redundant with active_circuits; if we ever decide only to use
|
||||
* the cell_ewma algorithm for choosing circuits, we can remove
|
||||
* active_circuits.
|
||||
*/
|
||||
smartlist_t *active_circuit_pqueue;
|
||||
/*
|
||||
* The tick on which the cell_ewma_ts in active_circuit_pqueue last had
|
||||
* their ewma values rescaled.
|
||||
*/
|
||||
unsigned active_circuit_pqueue_last_recalibrated;
|
||||
/* How many circuits use this connection as p_chan or n_chan? */
|
||||
int n_circuits;
|
||||
|
||||
/* Circuit ID generation stuff for use by circuitbuild.c */
|
||||
/*
|
||||
* True iff this channel shouldn't get any new circs attached to it,
|
||||
* because the connection is too old, or because there's a better one.
|
||||
* More generally, this flag is used to note an unhealthy connection;
|
||||
* for example, if a bad connection fails we shouldn't assume that the
|
||||
* router itself has a problem.
|
||||
*/
|
||||
unsigned int is_bad_for_new_circs:1;
|
||||
|
||||
/*
|
||||
* When we send CREATE cells along this connection, which half of the
|
||||
* space should we use?
|
||||
*/
|
||||
circ_id_type_t circ_id_type:2;
|
||||
/*
|
||||
* Which circ_id do we try to use next on this connection? This is
|
||||
* always in the range 0..1<<15-1.
|
||||
*/
|
||||
circid_t next_circ_id;
|
||||
/** True iff we have decided that the other end of this connection
|
||||
* is a client. Channels with this flag set should never be used
|
||||
* to satisfy an EXTEND request. */
|
||||
unsigned int is_client:1;
|
||||
|
||||
/* How many circuits use this connection as p_chan or n_chan? */
|
||||
int n_circuits;
|
||||
/** Set if the channel was initiated remotely (came from a listener) */
|
||||
unsigned int is_incoming:1;
|
||||
|
||||
/*
|
||||
* True iff this channel shouldn't get any new circs attached to it,
|
||||
* because the connection is too old, or because there's a better one.
|
||||
* More generally, this flag is used to note an unhealthy connection;
|
||||
* for example, if a bad connection fails we shouldn't assume that the
|
||||
* router itself has a problem.
|
||||
*/
|
||||
unsigned int is_bad_for_new_circs:1;
|
||||
/** Set by lower layer if this is local; i.e., everything it communicates
|
||||
* with for this channel returns true for is_local_addr(). This is used
|
||||
* to decide whether to declare reachability when we receive something on
|
||||
* this channel in circuitbuild.c
|
||||
*/
|
||||
unsigned int is_local:1;
|
||||
|
||||
/** True iff we have decided that the other end of this connection
|
||||
* is a client. Channels with this flag set should never be used
|
||||
* to satisfy an EXTEND request. */
|
||||
unsigned int is_client:1;
|
||||
/** Channel timestamps for cell channels */
|
||||
time_t timestamp_client; /* Client used this, according to relay.c */
|
||||
time_t timestamp_drained; /* Output queue empty */
|
||||
time_t timestamp_recv; /* Cell received from lower layer */
|
||||
time_t timestamp_xmit; /* Cell sent to lower layer */
|
||||
|
||||
/** Set if the channel was initiated remotely (came from a listener) */
|
||||
unsigned int is_incoming:1;
|
||||
/* Timestamp for relay.c */
|
||||
time_t timestamp_last_added_nonpadding;
|
||||
|
||||
/** Set by lower layer if this is local; i.e., everything it communicates
|
||||
* with for this channel returns true for is_local_addr(). This is used
|
||||
* to decide whether to declare reachability when we receive something on
|
||||
* this channel in circuitbuild.c
|
||||
*/
|
||||
unsigned int is_local:1;
|
||||
/** Unique ID for measuring direct network status requests;vtunneled ones
|
||||
* come over a circuit_t, which has a dirreq_id field as well, but is a
|
||||
* distinct namespace. */
|
||||
uint64_t dirreq_id;
|
||||
|
||||
/** Channel timestamps for cell channels */
|
||||
time_t timestamp_client; /* Client used this, according to relay.c */
|
||||
time_t timestamp_drained; /* Output queue empty */
|
||||
time_t timestamp_recv; /* Cell received from lower layer */
|
||||
time_t timestamp_xmit; /* Cell sent to lower layer */
|
||||
/** Channel counters for cell channels */
|
||||
uint64_t n_cells_recved;
|
||||
uint64_t n_cells_xmitted;
|
||||
};
|
||||
|
||||
/* Timestamp for relay.c */
|
||||
time_t timestamp_last_added_nonpadding;
|
||||
struct channel_listener_s {
|
||||
/* Current channel listener state */
|
||||
channel_listener_state_t state;
|
||||
|
||||
/** Unique ID for measuring direct network status requests;vtunneled ones
|
||||
* come over a circuit_t, which has a dirreq_id field as well, but is a
|
||||
* distinct namespace. */
|
||||
uint64_t dirreq_id;
|
||||
/* Globally unique ID number for a channel over the lifetime of a Tor
|
||||
* process.
|
||||
*/
|
||||
uint64_t global_identifier;
|
||||
|
||||
/** Channel counters for cell channels */
|
||||
uint64_t n_cells_recved;
|
||||
uint64_t n_cells_xmitted;
|
||||
} cell_chan;
|
||||
} u;
|
||||
/* Should we expect to see this channel in the channel lists? */
|
||||
unsigned char registered:1;
|
||||
|
||||
/** Why did we close?
|
||||
*/
|
||||
enum {
|
||||
CHANNEL_LISTENER_NOT_CLOSING = 0,
|
||||
CHANNEL_LISTENER_CLOSE_REQUESTED,
|
||||
CHANNEL_LISTENER_CLOSE_FROM_BELOW,
|
||||
CHANNEL_LISTENER_CLOSE_FOR_ERROR
|
||||
} reason_for_closing;
|
||||
|
||||
/* Timestamps for both cell channels and listeners */
|
||||
time_t timestamp_created; /* Channel created */
|
||||
time_t timestamp_active; /* Any activity */
|
||||
|
||||
/* Methods implemented by the lower layer */
|
||||
|
||||
/* Free a channel */
|
||||
void (*free)(channel_listener_t *);
|
||||
/* Close an open channel */
|
||||
void (*close)(channel_listener_t *);
|
||||
/* Describe the transport subclass for this channel */
|
||||
const char * (*describe_transport)(channel_listener_t *);
|
||||
/* Optional method to dump transport-specific statistics on the channel */
|
||||
void (*dumpstats)(channel_listener_t *, int);
|
||||
|
||||
/* Registered listen handler to call on incoming connection */
|
||||
channel_listener_fn_ptr listener;
|
||||
|
||||
/* List of pending incoming connections */
|
||||
smartlist_t *incoming_list;
|
||||
|
||||
/* Timestamps for listeners */
|
||||
time_t timestamp_accepted;
|
||||
|
||||
/* Counters for listeners */
|
||||
uint64_t n_accepted;
|
||||
};
|
||||
|
||||
/* Channel state manipulations */
|
||||
|
||||
int channel_state_is_valid(channel_state_t state);
|
||||
int channel_listener_state_is_valid(channel_listener_state_t state);
|
||||
|
||||
int channel_state_can_transition(channel_state_t from, channel_state_t to);
|
||||
int channel_listener_state_can_transition(channel_listener_state_t from,
|
||||
channel_listener_state_t to);
|
||||
|
||||
const char * channel_state_to_string(channel_state_t state);
|
||||
const char *
|
||||
channel_listener_state_to_string(channel_listener_state_t state);
|
||||
|
||||
/* Abstract channel operations */
|
||||
|
||||
@ -240,12 +273,16 @@ void channel_write_cell(channel_t *chan, cell_t *cell);
|
||||
void channel_write_packed_cell(channel_t *chan, packed_cell_t *cell);
|
||||
void channel_write_var_cell(channel_t *chan, var_cell_t *cell);
|
||||
|
||||
void channel_listener_mark_for_close(channel_listener_t *chan_l);
|
||||
|
||||
/* Channel callback registrations */
|
||||
|
||||
/* Listener callback */
|
||||
channel_listener_fn_ptr channel_get_listener_fn(channel_t *chan);
|
||||
void channel_set_listener_fn(channel_t *chan,
|
||||
channel_listener_fn_ptr listener);
|
||||
channel_listener_fn_ptr
|
||||
channel_listener_get_listener_fn(channel_listener_t *chan);
|
||||
|
||||
void channel_listener_set_listener_fn(channel_listener_t *chan,
|
||||
channel_listener_fn_ptr listener);
|
||||
|
||||
/* Incoming cell callbacks */
|
||||
channel_cell_handler_fn_ptr channel_get_cell_handler(channel_t *chan);
|
||||
@ -258,16 +295,18 @@ void channel_set_cell_handlers(channel_t *chan,
|
||||
channel_var_cell_handler_fn_ptr
|
||||
var_cell_handler);
|
||||
|
||||
/* Clean up closed channels periodically; called from run_scheduled_events()
|
||||
* in main.c
|
||||
/* Clean up closed channels and channel listeners periodically; these are
|
||||
* called from run_scheduled_events() in main.c.
|
||||
*/
|
||||
void channel_run_cleanup(void);
|
||||
void channel_listener_run_cleanup(void);
|
||||
|
||||
/* Close all channels and deallocate everything */
|
||||
void channel_free_all(void);
|
||||
|
||||
/* Dump some statistics in the log */
|
||||
void channel_dumpstats(int severity);
|
||||
void channel_listener_dumpstats(int severity);
|
||||
|
||||
#ifdef _TOR_CHANNEL_INTERNAL
|
||||
|
||||
@ -277,20 +316,29 @@ void channel_dumpstats(int severity);
|
||||
* constructors.
|
||||
*/
|
||||
|
||||
void channel_init_for_cells(channel_t *chan);
|
||||
void channel_init_listener(channel_t *chan);
|
||||
void channel_init(channel_t *chan);
|
||||
void channel_init_listener(channel_listener_t *chan);
|
||||
|
||||
/* Channel registration/unregistration */
|
||||
void channel_register(channel_t *chan);
|
||||
void channel_unregister(channel_t *chan);
|
||||
|
||||
/* Channel listener registration/unregistration */
|
||||
void channel_listener_register(channel_listener_t *chan_l);
|
||||
void channel_listener_unregister(channel_listener_t *chan_l);
|
||||
|
||||
/* Close from below */
|
||||
void channel_close_from_lower_layer(channel_t *chan);
|
||||
void channel_close_for_error(channel_t *chan);
|
||||
void channel_closed(channel_t *chan);
|
||||
|
||||
void channel_listener_close_from_lower_layer(channel_listener_t *chan_l);
|
||||
void channel_listener_close_for_error(channel_listener_t *chan_l);
|
||||
void channel_listener_closed(channel_listener_t *chan_l);
|
||||
|
||||
/* Free a channel */
|
||||
void channel_free(channel_t *chan);
|
||||
void channel_listener_free(channel_listener_t *chan_l);
|
||||
|
||||
/* State/metadata setters */
|
||||
|
||||
@ -306,17 +354,24 @@ void channel_set_remote_end(channel_t *chan,
|
||||
const char *identity_digest,
|
||||
const char *nickname);
|
||||
|
||||
void channel_listener_change_state(channel_listener_t *chan_l,
|
||||
channel_listener_state_t to_state);
|
||||
|
||||
/* Timestamp updates */
|
||||
void channel_timestamp_created(channel_t *chan);
|
||||
void channel_timestamp_accepted(channel_t *chan);
|
||||
void channel_timestamp_active(channel_t *chan);
|
||||
void channel_timestamp_drained(channel_t *chan);
|
||||
void channel_timestamp_recv(channel_t *chan);
|
||||
void channel_timestamp_xmit(channel_t *chan);
|
||||
|
||||
void channel_listener_timestamp_created(channel_listener_t *chan_l);
|
||||
void channel_listener_timestamp_active(channel_listener_t *chan_l);
|
||||
void channel_listener_timestamp_accepted(channel_listener_t *chan_l);
|
||||
|
||||
/* Incoming channel handling */
|
||||
void channel_process_incoming(channel_t *listener);
|
||||
void channel_queue_incoming(channel_t *listener, channel_t *incoming);
|
||||
void channel_listener_process_incoming(channel_listener_t *listener);
|
||||
void channel_listener_queue_incoming(channel_listener_t *listener,
|
||||
channel_t *incoming);
|
||||
|
||||
/* Incoming cell handling */
|
||||
void channel_process_cells(channel_t *chan);
|
||||
@ -401,19 +456,29 @@ int channel_matches_target_addr_for_extend(channel_t *chan,
|
||||
void channel_set_circid_type(channel_t *chan, crypto_pk_t *identity_rcvd);
|
||||
void channel_timestamp_client(channel_t *chan);
|
||||
|
||||
const char * channel_listener_describe_transport(channel_listener_t *chan_l);
|
||||
void channel_listener_dump_statistics(channel_listener_t *chan_l,
|
||||
int severity);
|
||||
void channel_listener_dump_transport_statistics(channel_listener_t *chan_l,
|
||||
int severity);
|
||||
|
||||
/* Timestamp queries */
|
||||
time_t channel_when_created(channel_t *chan);
|
||||
time_t channel_when_last_accepted(channel_t *chan);
|
||||
time_t channel_when_last_active(channel_t *chan);
|
||||
time_t channel_when_last_client(channel_t *chan);
|
||||
time_t channel_when_last_drained(channel_t *chan);
|
||||
time_t channel_when_last_recv(channel_t *chan);
|
||||
time_t channel_when_last_xmit(channel_t *chan);
|
||||
|
||||
time_t channel_listener_when_created(channel_listener_t *chan_l);
|
||||
time_t channel_listener_when_last_active(channel_listener_t *chan_l);
|
||||
time_t channel_listener_when_last_accepted(channel_listener_t *chan_l);
|
||||
|
||||
/* Counter queries */
|
||||
uint64_t channel_count_accepted(channel_t *chan);
|
||||
uint64_t channel_count_recved(channel_t *chan);
|
||||
uint64_t channel_count_xmitted(channel_t *chan);
|
||||
|
||||
uint64_t channel_listener_count_accepted(channel_listener_t *chan_l);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -42,7 +42,7 @@ uint64_t stats_n_authenticate_cells_processed = 0;
|
||||
uint64_t stats_n_authorize_cells_processed = 0;
|
||||
|
||||
/** Active listener, if any */
|
||||
channel_tls_t *channel_tls_listener = NULL;
|
||||
channel_listener_t *channel_tls_listener = NULL;
|
||||
|
||||
/* channel_tls_t method declarations */
|
||||
|
||||
@ -66,6 +66,12 @@ static int channel_tls_write_packed_cell_method(channel_t *chan,
|
||||
static int channel_tls_write_var_cell_method(channel_t *chan,
|
||||
var_cell_t *var_cell);
|
||||
|
||||
/* channel_listener_tls_t method declarations */
|
||||
|
||||
static void channel_tls_listener_close_method(channel_listener_t *chan_l);
|
||||
static const char *
|
||||
channel_tls_listener_describe_transport_method(channel_listener_t *chan_l);
|
||||
|
||||
/** Handle incoming cells for the handshake stuff here rather than
|
||||
* passing them on up. */
|
||||
|
||||
@ -97,20 +103,19 @@ channel_tls_connect(const tor_addr_t *addr, uint16_t port,
|
||||
{
|
||||
channel_tls_t *tlschan = tor_malloc_zero(sizeof(*tlschan));
|
||||
channel_t *chan = TLS_CHAN_TO_BASE(tlschan);
|
||||
channel_init_for_cells(chan);
|
||||
channel_init(chan);
|
||||
chan->state = CHANNEL_STATE_OPENING;
|
||||
chan->close = channel_tls_close_method;
|
||||
chan->describe_transport = channel_tls_describe_transport_method;
|
||||
chan->u.cell_chan.get_remote_addr = channel_tls_get_remote_addr_method;
|
||||
chan->u.cell_chan.get_remote_descr = channel_tls_get_remote_descr_method;
|
||||
chan->u.cell_chan.has_queued_writes = channel_tls_has_queued_writes_method;
|
||||
chan->u.cell_chan.is_canonical = channel_tls_is_canonical_method;
|
||||
chan->u.cell_chan.matches_extend_info =
|
||||
channel_tls_matches_extend_info_method;
|
||||
chan->u.cell_chan.matches_target = channel_tls_matches_target_method;
|
||||
chan->u.cell_chan.write_cell = channel_tls_write_cell_method;
|
||||
chan->u.cell_chan.write_packed_cell = channel_tls_write_packed_cell_method;
|
||||
chan->u.cell_chan.write_var_cell = channel_tls_write_var_cell_method;
|
||||
chan->get_remote_addr = channel_tls_get_remote_addr_method;
|
||||
chan->get_remote_descr = channel_tls_get_remote_descr_method;
|
||||
chan->has_queued_writes = channel_tls_has_queued_writes_method;
|
||||
chan->is_canonical = channel_tls_is_canonical_method;
|
||||
chan->matches_extend_info = channel_tls_matches_extend_info_method;
|
||||
chan->matches_target = channel_tls_matches_target_method;
|
||||
chan->write_cell = channel_tls_write_cell_method;
|
||||
chan->write_packed_cell = channel_tls_write_packed_cell_method;
|
||||
chan->write_var_cell = channel_tls_write_var_cell_method;
|
||||
|
||||
log_debug(LD_CHANNEL,
|
||||
"In channel_tls_connect() for channel %p "
|
||||
@ -121,9 +126,8 @@ channel_tls_connect(const tor_addr_t *addr, uint16_t port,
|
||||
if (is_local_addr(addr)) channel_mark_local(chan);
|
||||
channel_mark_outgoing(chan);
|
||||
|
||||
chan->u.cell_chan.active_circuit_pqueue = smartlist_new();
|
||||
chan->u.cell_chan.active_circuit_pqueue_last_recalibrated =
|
||||
cell_ewma_get_tick();
|
||||
chan->active_circuit_pqueue = smartlist_new();
|
||||
chan->active_circuit_pqueue_last_recalibrated = cell_ewma_get_tick();
|
||||
|
||||
/* Set up or_connection stuff */
|
||||
tlschan->conn = connection_or_connect(addr, port, id_digest, tlschan);
|
||||
@ -140,7 +144,7 @@ channel_tls_connect(const tor_addr_t *addr, uint16_t port,
|
||||
goto done;
|
||||
|
||||
err:
|
||||
smartlist_free(chan->u.cell_chan.active_circuit_pqueue);
|
||||
smartlist_free(chan->active_circuit_pqueue);
|
||||
tor_free(tlschan);
|
||||
chan = NULL;
|
||||
|
||||
@ -154,14 +158,14 @@ channel_tls_connect(const tor_addr_t *addr, uint16_t port,
|
||||
/**
|
||||
* Return the current channel_tls_t listener
|
||||
*
|
||||
* Returns the current listening channel for incoming TLS connections, or
|
||||
* Returns the current channel listener for incoming TLS connections, or
|
||||
* NULL if none has been established
|
||||
*/
|
||||
|
||||
channel_t *
|
||||
channel_listener_t *
|
||||
channel_tls_get_listener(void)
|
||||
{
|
||||
return TLS_CHAN_TO_BASE(channel_tls_listener);
|
||||
return channel_tls_listener;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -171,30 +175,29 @@ channel_tls_get_listener(void)
|
||||
* and return that.
|
||||
*/
|
||||
|
||||
channel_t *
|
||||
channel_listener_t *
|
||||
channel_tls_start_listener(void)
|
||||
{
|
||||
channel_tls_t *listener;
|
||||
channel_t *lchan;
|
||||
channel_listener_t *listener;
|
||||
|
||||
if (!channel_tls_listener) {
|
||||
listener = tor_malloc_zero(sizeof(*listener));
|
||||
lchan = TLS_CHAN_TO_BASE(listener);
|
||||
channel_init_listener(lchan);
|
||||
lchan->state = CHANNEL_STATE_LISTENING;
|
||||
lchan->close = channel_tls_close_method;
|
||||
lchan->describe_transport = channel_tls_describe_transport_method;
|
||||
channel_init_listener(listener);
|
||||
listener->state = CHANNEL_LISTENER_STATE_LISTENING;
|
||||
listener->close = channel_tls_listener_close_method;
|
||||
listener->describe_transport =
|
||||
channel_tls_listener_describe_transport_method;
|
||||
|
||||
channel_tls_listener = listener;
|
||||
|
||||
log_debug(LD_CHANNEL,
|
||||
"Starting TLS listener channel %p with global id " U64_FORMAT,
|
||||
lchan, U64_PRINTF_ARG(lchan->global_identifier));
|
||||
"Starting TLS channel listener %p with global id " U64_FORMAT,
|
||||
listener, U64_PRINTF_ARG(listener->global_identifier));
|
||||
|
||||
channel_register(lchan);
|
||||
} else lchan = TLS_CHAN_TO_BASE(channel_tls_listener);
|
||||
channel_listener_register(listener);
|
||||
} else listener = channel_tls_listener;
|
||||
|
||||
return lchan;
|
||||
return listener;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -207,16 +210,13 @@ channel_tls_start_listener(void)
|
||||
void
|
||||
channel_tls_free_all(void)
|
||||
{
|
||||
channel_t *base = NULL;
|
||||
|
||||
log_debug(LD_CHANNEL,
|
||||
"Shutting down TLS channels...");
|
||||
|
||||
if (channel_tls_listener) {
|
||||
base = TLS_CHAN_TO_BASE(channel_tls_listener);
|
||||
channel_unregister(base);
|
||||
channel_mark_for_close(base);
|
||||
channel_free(base);
|
||||
channel_listener_unregister(channel_tls_listener);
|
||||
channel_listener_mark_for_close(channel_tls_listener);
|
||||
channel_listener_free(channel_tls_listener);
|
||||
channel_tls_listener = NULL;
|
||||
}
|
||||
|
||||
@ -237,19 +237,18 @@ channel_tls_handle_incoming(or_connection_t *orconn)
|
||||
tor_assert(orconn);
|
||||
tor_assert(!(orconn->chan));
|
||||
|
||||
channel_init_for_cells(chan);
|
||||
channel_init(chan);
|
||||
chan->state = CHANNEL_STATE_OPENING;
|
||||
chan->close = channel_tls_close_method;
|
||||
chan->describe_transport = channel_tls_describe_transport_method;
|
||||
chan->u.cell_chan.get_remote_descr = channel_tls_get_remote_descr_method;
|
||||
chan->u.cell_chan.has_queued_writes = channel_tls_has_queued_writes_method;
|
||||
chan->u.cell_chan.is_canonical = channel_tls_is_canonical_method;
|
||||
chan->u.cell_chan.matches_extend_info =
|
||||
channel_tls_matches_extend_info_method;
|
||||
chan->u.cell_chan.matches_target = channel_tls_matches_target_method;
|
||||
chan->u.cell_chan.write_cell = channel_tls_write_cell_method;
|
||||
chan->u.cell_chan.write_packed_cell = channel_tls_write_packed_cell_method;
|
||||
chan->u.cell_chan.write_var_cell = channel_tls_write_var_cell_method;
|
||||
chan->get_remote_descr = channel_tls_get_remote_descr_method;
|
||||
chan->has_queued_writes = channel_tls_has_queued_writes_method;
|
||||
chan->is_canonical = channel_tls_is_canonical_method;
|
||||
chan->matches_extend_info = channel_tls_matches_extend_info_method;
|
||||
chan->matches_target = channel_tls_matches_target_method;
|
||||
chan->write_cell = channel_tls_write_cell_method;
|
||||
chan->write_packed_cell = channel_tls_write_packed_cell_method;
|
||||
chan->write_var_cell = channel_tls_write_var_cell_method;
|
||||
|
||||
/* Link the channel and orconn to each other */
|
||||
tlschan->conn = orconn;
|
||||
@ -258,9 +257,8 @@ channel_tls_handle_incoming(or_connection_t *orconn)
|
||||
if (is_local_addr(&(TO_CONN(orconn)->addr))) channel_mark_local(chan);
|
||||
channel_mark_incoming(chan);
|
||||
|
||||
chan->u.cell_chan.active_circuit_pqueue = smartlist_new();
|
||||
chan->u.cell_chan.active_circuit_pqueue_last_recalibrated =
|
||||
cell_ewma_get_tick();
|
||||
chan->active_circuit_pqueue = smartlist_new();
|
||||
chan->active_circuit_pqueue_last_recalibrated = cell_ewma_get_tick();
|
||||
|
||||
/* If we got one, we should register it */
|
||||
if (chan) channel_register(chan);
|
||||
@ -285,43 +283,13 @@ channel_tls_close_method(channel_t *chan)
|
||||
|
||||
tor_assert(tlschan);
|
||||
|
||||
if (chan->is_listener) {
|
||||
/*
|
||||
* Listeners we just go ahead and change state through to CLOSED, but
|
||||
* make sure to check if they're channel_tls_listener to NULL it out.
|
||||
*/
|
||||
if (chan == TLS_CHAN_TO_BASE(channel_tls_listener))
|
||||
channel_tls_listener = NULL;
|
||||
|
||||
if (!(chan->state == CHANNEL_STATE_CLOSING ||
|
||||
chan->state == CHANNEL_STATE_CLOSED ||
|
||||
chan->state == CHANNEL_STATE_ERROR)) {
|
||||
channel_change_state(chan, CHANNEL_STATE_CLOSING);
|
||||
}
|
||||
|
||||
if (chan->u.listener.incoming_list) {
|
||||
SMARTLIST_FOREACH_BEGIN(chan->u.listener.incoming_list,
|
||||
channel_t *, ichan) {
|
||||
channel_mark_for_close(ichan);
|
||||
} SMARTLIST_FOREACH_END(ichan);
|
||||
|
||||
smartlist_free(chan->u.listener.incoming_list);
|
||||
chan->u.listener.incoming_list = NULL;
|
||||
}
|
||||
|
||||
if (!(chan->state == CHANNEL_STATE_CLOSED ||
|
||||
chan->state == CHANNEL_STATE_ERROR)) {
|
||||
channel_change_state(chan, CHANNEL_STATE_CLOSED);
|
||||
}
|
||||
} else {
|
||||
if (tlschan->conn) connection_or_close_normally(tlschan->conn, 1);
|
||||
else {
|
||||
/* Weird - we'll have to change the state ourselves, I guess */
|
||||
log_info(LD_CHANNEL,
|
||||
"Tried to close channel_tls_t %p with NULL conn",
|
||||
tlschan);
|
||||
channel_change_state(chan, CHANNEL_STATE_ERROR);
|
||||
}
|
||||
if (tlschan->conn) connection_or_close_normally(tlschan->conn, 1);
|
||||
else {
|
||||
/* Weird - we'll have to change the state ourselves, I guess */
|
||||
log_info(LD_CHANNEL,
|
||||
"Tried to close channel_tls_t %p with NULL conn",
|
||||
tlschan);
|
||||
channel_change_state(chan, CHANNEL_STATE_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@ -342,23 +310,19 @@ channel_tls_describe_transport_method(channel_t *chan)
|
||||
|
||||
tor_assert(chan);
|
||||
|
||||
if (chan->is_listener) {
|
||||
rv = "TLS channel (listening)";
|
||||
tlschan = BASE_CHAN_TO_TLS(chan);
|
||||
|
||||
if (tlschan->conn) {
|
||||
id = TO_CONN(tlschan->conn)->global_identifier;
|
||||
|
||||
if (buf) tor_free(buf);
|
||||
tor_asprintf(&buf,
|
||||
"TLS channel (connection " U64_FORMAT ")",
|
||||
U64_PRINTF_ARG(id));
|
||||
|
||||
rv = buf;
|
||||
} else {
|
||||
tlschan = BASE_CHAN_TO_TLS(chan);
|
||||
|
||||
if (tlschan->conn) {
|
||||
id = TO_CONN(tlschan->conn)->global_identifier;
|
||||
|
||||
if (buf) tor_free(buf);
|
||||
tor_asprintf(&buf,
|
||||
"TLS channel (connection " U64_FORMAT ")",
|
||||
U64_PRINTF_ARG(id));
|
||||
|
||||
rv = buf;
|
||||
} else {
|
||||
rv = "TLS channel (no connection)";
|
||||
}
|
||||
rv = "TLS channel (no connection)";
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -603,6 +567,65 @@ channel_tls_write_var_cell_method(channel_t *chan, var_cell_t *var_cell)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Method implementations for channel_listener_t *
|
||||
************************************************/
|
||||
|
||||
/**
|
||||
* Close a channel_listener_t
|
||||
*
|
||||
* This implements the close method for channel_listener_t
|
||||
*/
|
||||
|
||||
static void
|
||||
channel_tls_listener_close_method(channel_listener_t *chan_l)
|
||||
{
|
||||
tor_assert(chan_l);
|
||||
|
||||
/*
|
||||
* Listeners we just go ahead and change state through to CLOSED, but
|
||||
* make sure to check if they're channel_tls_listener to NULL it out.
|
||||
*/
|
||||
if (chan_l == channel_tls_listener)
|
||||
channel_tls_listener = NULL;
|
||||
|
||||
if (!(chan_l->state == CHANNEL_LISTENER_STATE_CLOSING ||
|
||||
chan_l->state == CHANNEL_LISTENER_STATE_CLOSED ||
|
||||
chan_l->state == CHANNEL_LISTENER_STATE_ERROR)) {
|
||||
channel_listener_change_state(chan_l, CHANNEL_LISTENER_STATE_CLOSING);
|
||||
}
|
||||
|
||||
if (chan_l->incoming_list) {
|
||||
SMARTLIST_FOREACH_BEGIN(chan_l->incoming_list,
|
||||
channel_t *, ichan) {
|
||||
channel_mark_for_close(ichan);
|
||||
} SMARTLIST_FOREACH_END(ichan);
|
||||
|
||||
smartlist_free(chan_l->incoming_list);
|
||||
chan_l->incoming_list = NULL;
|
||||
}
|
||||
|
||||
if (!(chan_l->state == CHANNEL_LISTENER_STATE_CLOSED ||
|
||||
chan_l->state == CHANNEL_LISTENER_STATE_ERROR)) {
|
||||
channel_listener_change_state(chan_l, CHANNEL_LISTENER_STATE_CLOSED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Describe the transport for a channel_listener_t
|
||||
*
|
||||
* This returns the string "TLS channel (listening)" to the upper
|
||||
* layer.
|
||||
*/
|
||||
|
||||
static const char *
|
||||
channel_tls_listener_describe_transport_method(channel_listener_t *chan_l)
|
||||
{
|
||||
tor_assert(chan_l);
|
||||
|
||||
return "TLS channel (listening)";
|
||||
}
|
||||
|
||||
/*******************************************************
|
||||
* Functions for handling events on an or_connection_t *
|
||||
******************************************************/
|
||||
@ -782,8 +805,6 @@ channel_tls_handle_cell(cell_t *cell, or_connection_t *conn)
|
||||
return;
|
||||
}
|
||||
|
||||
tor_assert(!(TLS_CHAN_TO_BASE(chan)->is_listener));
|
||||
|
||||
handshaking = (TO_CONN(conn)->state != OR_CONN_STATE_OPEN);
|
||||
|
||||
if (conn->_base.marked_for_close)
|
||||
@ -892,8 +913,6 @@ channel_tls_handle_var_cell(var_cell_t *var_cell, or_connection_t *conn)
|
||||
return;
|
||||
}
|
||||
|
||||
tor_assert(!(TLS_CHAN_TO_BASE(chan)->is_listener));
|
||||
|
||||
handshaking = (TO_CONN(conn)->state != OR_CONN_STATE_OPEN);
|
||||
|
||||
if (TO_CONN(conn)->marked_for_close)
|
||||
@ -1049,7 +1068,6 @@ enter_v3_handshake_with_cell(var_cell_t *cell, channel_tls_t *chan)
|
||||
|
||||
tor_assert(cell);
|
||||
tor_assert(chan);
|
||||
tor_assert(!(TLS_CHAN_TO_BASE(chan)->is_listener));
|
||||
tor_assert(chan->conn);
|
||||
|
||||
started_here = connection_or_nonopen_was_started_here(chan->conn);
|
||||
@ -1091,7 +1109,6 @@ channel_tls_process_versions_cell(var_cell_t *cell, channel_tls_t *chan)
|
||||
|
||||
tor_assert(cell);
|
||||
tor_assert(chan);
|
||||
tor_assert(!(TLS_CHAN_TO_BASE(chan)->is_listener));
|
||||
tor_assert(chan->conn);
|
||||
|
||||
started_here = connection_or_nonopen_was_started_here(chan->conn);
|
||||
@ -1247,7 +1264,6 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan)
|
||||
|
||||
tor_assert(cell);
|
||||
tor_assert(chan);
|
||||
tor_assert(!(TLS_CHAN_TO_BASE(chan)->is_listener));
|
||||
tor_assert(chan->conn);
|
||||
|
||||
if (chan->conn->link_proto < 2) {
|
||||
@ -1386,7 +1402,7 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan)
|
||||
safe_str_client(chan->conn->_base.address),
|
||||
chan->conn->_base.port,
|
||||
(int)(chan->conn->link_proto),
|
||||
hex_str(TLS_CHAN_TO_BASE(chan)->u.cell_chan.identity_digest,
|
||||
hex_str(TLS_CHAN_TO_BASE(chan)->identity_digest,
|
||||
DIGEST_LEN),
|
||||
tor_addr_is_null(&my_apparent_addr) ?
|
||||
"<none>" : fmt_and_decorate_addr(&my_apparent_addr));
|
||||
@ -1422,7 +1438,6 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan)
|
||||
|
||||
tor_assert(cell);
|
||||
tor_assert(chan);
|
||||
tor_assert(!(TLS_CHAN_TO_BASE(chan)->is_listener));
|
||||
tor_assert(chan->conn);
|
||||
|
||||
#define ERR(s) \
|
||||
@ -1515,7 +1530,7 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan)
|
||||
* _trying_ to connect to an authority, not necessarily if we _did_ connect
|
||||
* to one. */
|
||||
if (router_digest_is_trusted_dir(
|
||||
TLS_CHAN_TO_BASE(chan)->u.cell_chan.identity_digest))
|
||||
TLS_CHAN_TO_BASE(chan)->identity_digest))
|
||||
severity = LOG_WARN;
|
||||
else
|
||||
severity = LOG_PROTOCOL_WARN;
|
||||
@ -1616,7 +1631,6 @@ channel_tls_process_auth_challenge_cell(var_cell_t *cell, channel_tls_t *chan)
|
||||
|
||||
tor_assert(cell);
|
||||
tor_assert(chan);
|
||||
tor_assert(!(TLS_CHAN_TO_BASE(chan)->is_listener));
|
||||
tor_assert(chan->conn);
|
||||
|
||||
#define ERR(s) \
|
||||
@ -1714,7 +1728,6 @@ channel_tls_process_authenticate_cell(var_cell_t *cell, channel_tls_t *chan)
|
||||
|
||||
tor_assert(cell);
|
||||
tor_assert(chan);
|
||||
tor_assert(!(TLS_CHAN_TO_BASE(chan)->is_listener));
|
||||
tor_assert(chan->conn);
|
||||
|
||||
#define ERR(s) \
|
||||
|
@ -28,8 +28,8 @@ struct channel_tls_s {
|
||||
|
||||
channel_t * channel_tls_connect(const tor_addr_t *addr, uint16_t port,
|
||||
const char *id_digest);
|
||||
channel_t * channel_tls_get_listener(void);
|
||||
channel_t * channel_tls_start_listener(void);
|
||||
channel_listener_t * channel_tls_get_listener(void);
|
||||
channel_listener_t * channel_tls_start_listener(void);
|
||||
channel_t * channel_tls_handle_incoming(or_connection_t *orconn);
|
||||
|
||||
/* Things for connection_or.c to call back into */
|
||||
|
@ -1711,23 +1711,22 @@ get_unique_circ_id_by_chan(channel_t *chan)
|
||||
circid_t high_bit;
|
||||
|
||||
tor_assert(chan);
|
||||
tor_assert(!(chan->is_listener));
|
||||
|
||||
if (chan->u.cell_chan.circ_id_type == CIRC_ID_TYPE_NEITHER) {
|
||||
if (chan->circ_id_type == CIRC_ID_TYPE_NEITHER) {
|
||||
log_warn(LD_BUG,
|
||||
"Trying to pick a circuit ID for a connection from "
|
||||
"a client with no identity.");
|
||||
return 0;
|
||||
}
|
||||
high_bit =
|
||||
(chan->u.cell_chan.circ_id_type == CIRC_ID_TYPE_HIGHER) ? 1<<15 : 0;
|
||||
(chan->circ_id_type == CIRC_ID_TYPE_HIGHER) ? 1<<15 : 0;
|
||||
do {
|
||||
/* Sequentially iterate over test_circ_id=1...1<<15-1 until we find a
|
||||
* circID such that (high_bit|test_circ_id) is not already used. */
|
||||
test_circ_id = chan->u.cell_chan.next_circ_id++;
|
||||
test_circ_id = chan->next_circ_id++;
|
||||
if (test_circ_id == 0 || test_circ_id >= 1<<15) {
|
||||
test_circ_id = 1;
|
||||
chan->u.cell_chan.next_circ_id = 2;
|
||||
chan->next_circ_id = 2;
|
||||
}
|
||||
if (++attempts > 1<<15) {
|
||||
/* Make sure we don't loop forever if all circ_id's are used. This
|
||||
@ -2039,11 +2038,9 @@ circuit_n_chan_done(channel_t *chan, int status)
|
||||
int err_reason = 0;
|
||||
|
||||
tor_assert(chan);
|
||||
tor_assert(!(chan->is_listener));
|
||||
|
||||
log_debug(LD_CIRC,"chan to %s/%s, status=%d",
|
||||
chan->u.cell_chan.nickname ?
|
||||
chan->u.cell_chan.nickname : "NULL",
|
||||
chan->nickname ? chan->nickname : "NULL",
|
||||
channel_get_canonical_remote_descr(chan), status);
|
||||
|
||||
pending_circs = smartlist_new();
|
||||
@ -2064,7 +2061,7 @@ circuit_n_chan_done(channel_t *chan, int status)
|
||||
continue;
|
||||
} else {
|
||||
/* We expected a key. See if it's the right one. */
|
||||
if (tor_memneq(chan->u.cell_chan.identity_digest,
|
||||
if (tor_memneq(chan->identity_digest,
|
||||
circ->n_hop->identity_digest, DIGEST_LEN))
|
||||
continue;
|
||||
}
|
||||
@ -2247,8 +2244,7 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
|
||||
else
|
||||
control_event_bootstrap(BOOTSTRAP_STATUS_CIRCUIT_CREATE, 0);
|
||||
|
||||
tor_assert(!(circ->_base.n_chan->is_listener));
|
||||
node = node_get_by_id(circ->_base.n_chan->u.cell_chan.identity_digest);
|
||||
node = node_get_by_id(circ->_base.n_chan->identity_digest);
|
||||
fast = should_use_create_fast_for_circuit(circ);
|
||||
if (!fast) {
|
||||
/* We are an OR and we know the right onion key: we should
|
||||
@ -2487,10 +2483,8 @@ circuit_extend(cell_t *cell, circuit_t *circ)
|
||||
/* Next, check if we're being asked to connect to the hop that the
|
||||
* extend cell came from. There isn't any reason for that, and it can
|
||||
* assist circular-path attacks. */
|
||||
tor_assert(!(TO_OR_CIRCUIT(circ)->p_chan->is_listener));
|
||||
if (tor_memeq(id_digest,
|
||||
TO_OR_CIRCUIT(circ)->p_chan->
|
||||
u.cell_chan.identity_digest,
|
||||
TO_OR_CIRCUIT(circ)->p_chan->identity_digest,
|
||||
DIGEST_LEN)) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||
"Client asked me to extend back to the previous hop.");
|
||||
@ -2733,9 +2727,8 @@ pathbias_count_first_hop(origin_circuit_t *circ)
|
||||
if (!circ->has_opened) {
|
||||
entry_guard_t *guard;
|
||||
|
||||
tor_assert(!(circ->_base.n_chan->is_listener));
|
||||
guard = entry_guard_get_by_id_digest(
|
||||
circ->_base.n_chan->u.cell_chan.identity_digest);
|
||||
guard =
|
||||
entry_guard_get_by_id_digest(circ->_base.n_chan->identity_digest);
|
||||
if (guard) {
|
||||
if (circ->path_state == PATH_STATE_NEW_CIRC) {
|
||||
circ->path_state = PATH_STATE_DID_FIRST_HOP;
|
||||
@ -2840,10 +2833,8 @@ pathbias_count_success(origin_circuit_t *circ)
|
||||
|
||||
/* Don't count cannibalized/reused circs for path bias */
|
||||
if (!circ->has_opened) {
|
||||
tor_assert(!(circ->_base.n_chan->is_listener));
|
||||
guard =
|
||||
entry_guard_get_by_id_digest(circ->_base.n_chan->
|
||||
u.cell_chan.identity_digest);
|
||||
entry_guard_get_by_id_digest(circ->_base.n_chan->identity_digest);
|
||||
|
||||
if (guard) {
|
||||
if (circ->path_state == PATH_STATE_DID_FIRST_HOP) {
|
||||
|
@ -102,8 +102,6 @@ circuit_set_circid_chan_helper(circuit_t *circ, int direction,
|
||||
circid_t old_id, *circid_ptr;
|
||||
int was_active, make_active;
|
||||
|
||||
if (chan) tor_assert(!(chan->is_listener));
|
||||
|
||||
if (direction == CELL_DIRECTION_OUT) {
|
||||
chan_ptr = &circ->n_chan;
|
||||
circid_ptr = &circ->n_circ_id;
|
||||
@ -131,13 +129,12 @@ circuit_set_circid_chan_helper(circuit_t *circ, int direction,
|
||||
}
|
||||
|
||||
if (old_chan) { /* we may need to remove it from the conn-circid map */
|
||||
tor_assert(!(old_chan->is_listener));
|
||||
search.circ_id = old_id;
|
||||
search.chan = old_chan;
|
||||
found = HT_REMOVE(chan_circid_map, &chan_circid_map, &search);
|
||||
if (found) {
|
||||
tor_free(found);
|
||||
--old_chan->u.cell_chan.n_circuits;
|
||||
--old_chan->n_circuits;
|
||||
}
|
||||
if (was_active && old_chan != chan)
|
||||
make_circuit_inactive_on_chan(circ, old_chan);
|
||||
@ -167,7 +164,7 @@ circuit_set_circid_chan_helper(circuit_t *circ, int direction,
|
||||
if (make_active && old_chan != chan)
|
||||
make_circuit_active_on_chan(circ,chan);
|
||||
|
||||
++chan->u.cell_chan.n_circuits;
|
||||
++chan->n_circuits;
|
||||
}
|
||||
|
||||
/** Set the p_conn field of a circuit <b>circ</b>, along
|
||||
@ -242,7 +239,6 @@ circuit_get_all_pending_on_channel(smartlist_t *out, channel_t *chan)
|
||||
{
|
||||
tor_assert(out);
|
||||
tor_assert(chan);
|
||||
tor_assert(!(chan->is_listener));
|
||||
|
||||
if (!circuits_pending_chans)
|
||||
return;
|
||||
@ -259,8 +255,8 @@ circuit_get_all_pending_on_channel(smartlist_t *out, channel_t *chan)
|
||||
continue;
|
||||
} else {
|
||||
/* We expected a key. See if it's the right one. */
|
||||
if (tor_memneq(chan->u.cell_chan.identity_digest,
|
||||
circ->n_hop->identity_digest, DIGEST_LEN))
|
||||
if (tor_memneq(chan->identity_digest,
|
||||
circ->n_hop->identity_digest, DIGEST_LEN))
|
||||
continue;
|
||||
}
|
||||
smartlist_add(out, circ);
|
||||
@ -276,14 +272,12 @@ circuit_count_pending_on_channel(channel_t *chan)
|
||||
smartlist_t *sl = smartlist_new();
|
||||
|
||||
tor_assert(chan);
|
||||
tor_assert(!(chan->is_listener));
|
||||
|
||||
circuit_get_all_pending_on_channel(sl, chan);
|
||||
cnt = smartlist_len(sl);
|
||||
smartlist_free(sl);
|
||||
log_debug(LD_CIRC,"or_conn to %s at %s, %d pending circs",
|
||||
chan->u.cell_chan.nickname ?
|
||||
chan->u.cell_chan.nickname : "NULL",
|
||||
chan->nickname ? chan->nickname : "NULL",
|
||||
channel_get_canonical_remote_descr(chan),
|
||||
cnt);
|
||||
return cnt;
|
||||
@ -839,7 +833,6 @@ circuit_dump_by_chan(channel_t *chan, int severity)
|
||||
circuit_t *circ;
|
||||
|
||||
tor_assert(chan);
|
||||
tor_assert(!(chan->is_listener));
|
||||
|
||||
for (circ = global_circuitlist; circ; circ = circ->next) {
|
||||
circid_t n_circ_id = circ->n_circ_id, p_circ_id = 0;
|
||||
@ -865,7 +858,7 @@ circuit_dump_by_chan(channel_t *chan, int severity)
|
||||
|
||||
if (!circ->n_chan && circ->n_hop &&
|
||||
channel_matches_extend_info(chan, circ->n_hop) &&
|
||||
tor_memeq(chan->u.cell_chan.identity_digest,
|
||||
tor_memeq(chan->identity_digest,
|
||||
circ->n_hop->identity_digest, DIGEST_LEN)) {
|
||||
circuit_dump_chan_details(severity, circ, chan,
|
||||
(circ->state == CIRCUIT_STATE_OPEN &&
|
||||
|
@ -1185,9 +1185,8 @@ circuit_build_failed(origin_circuit_t *circ)
|
||||
int already_marked = 0;
|
||||
if (circ->_base.n_chan) {
|
||||
n_chan = circ->_base.n_chan;
|
||||
tor_assert(!(n_chan->is_listener));
|
||||
|
||||
if (n_chan->u.cell_chan.is_bad_for_new_circs) {
|
||||
if (n_chan->is_bad_for_new_circs) {
|
||||
/* We only want to blame this router when a fresh healthy
|
||||
* connection fails. So don't mark this router as newly failed,
|
||||
* since maybe this was just an old circuit attempt that's
|
||||
@ -1201,7 +1200,7 @@ circuit_build_failed(origin_circuit_t *circ)
|
||||
"Our circuit failed to get a response from the first hop "
|
||||
"(%s). I'm going to try to rotate to a better connection.",
|
||||
channel_get_canonical_remote_descr(n_chan));
|
||||
n_chan->u.cell_chan.is_bad_for_new_circs = 1;
|
||||
n_chan->is_bad_for_new_circs = 1;
|
||||
} else {
|
||||
log_info(LD_OR,
|
||||
"Our circuit died before the first hop with no connection");
|
||||
|
@ -44,7 +44,7 @@ uint64_t stats_n_relay_cells_processed = 0;
|
||||
uint64_t stats_n_destroy_cells_processed = 0;
|
||||
|
||||
/* Handle an incoming channel */
|
||||
static void command_handle_incoming_channel(channel_t *listener,
|
||||
static void command_handle_incoming_channel(channel_listener_t *listener,
|
||||
channel_t *chan);
|
||||
|
||||
/* These are the main functions for processing cells */
|
||||
@ -190,7 +190,6 @@ command_process_create_cell(cell_t *cell, channel_t *chan)
|
||||
|
||||
tor_assert(cell);
|
||||
tor_assert(chan);
|
||||
tor_assert(!(chan->is_listener));
|
||||
|
||||
log_debug(LD_OR,
|
||||
"Got a CREATE cell for circ_id %d on channel " U64_FORMAT
|
||||
@ -223,9 +222,9 @@ command_process_create_cell(cell_t *cell, channel_t *chan)
|
||||
* circ. */
|
||||
id_is_high = cell->circ_id & (1<<15);
|
||||
if ((id_is_high &&
|
||||
chan->u.cell_chan.circ_id_type == CIRC_ID_TYPE_HIGHER) ||
|
||||
chan->circ_id_type == CIRC_ID_TYPE_HIGHER) ||
|
||||
(!id_is_high &&
|
||||
chan->u.cell_chan.circ_id_type == CIRC_ID_TYPE_LOWER)) {
|
||||
chan->circ_id_type == CIRC_ID_TYPE_LOWER)) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||
"Received create cell with unexpected circ_id %d. Closing.",
|
||||
cell->circ_id);
|
||||
@ -235,7 +234,7 @@ command_process_create_cell(cell_t *cell, channel_t *chan)
|
||||
}
|
||||
|
||||
if (circuit_id_in_use_on_channel(cell->circ_id, chan)) {
|
||||
const node_t *node = node_get_by_id(chan->u.cell_chan.identity_digest);
|
||||
const node_t *node = node_get_by_id(chan->identity_digest);
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||
"Received CREATE cell (circID %d) for known circ. "
|
||||
"Dropping (age %d).",
|
||||
@ -473,7 +472,7 @@ command_process_destroy_cell(cell_t *cell, channel_t *chan)
|
||||
*/
|
||||
|
||||
static void
|
||||
command_handle_incoming_channel(channel_t *listener, channel_t *chan)
|
||||
command_handle_incoming_channel(channel_listener_t *listener, channel_t *chan)
|
||||
{
|
||||
tor_assert(listener);
|
||||
tor_assert(chan);
|
||||
@ -500,11 +499,11 @@ command_setup_channel(channel_t *chan)
|
||||
*/
|
||||
|
||||
void
|
||||
command_setup_listener(channel_t *listener)
|
||||
command_setup_listener(channel_listener_t *listener)
|
||||
{
|
||||
tor_assert(listener);
|
||||
tor_assert(listener->state == CHANNEL_STATE_LISTENING);
|
||||
tor_assert(listener->state == CHANNEL_LISTENER_STATE_LISTENING);
|
||||
|
||||
channel_set_listener_fn(listener, command_handle_incoming_channel);
|
||||
channel_listener_set_listener_fn(listener, command_handle_incoming_channel);
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
void command_process_cell(channel_t *chan, cell_t *cell);
|
||||
void command_process_var_cell(channel_t *chan, var_cell_t *cell);
|
||||
void command_setup_channel(channel_t *chan);
|
||||
void command_setup_listener(channel_t *chan);
|
||||
void command_setup_listener(channel_listener_t *chan_l);
|
||||
|
||||
extern uint64_t stats_n_padding_cells_processed;
|
||||
extern uint64_t stats_n_create_cells_processed;
|
||||
|
@ -3070,11 +3070,10 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
|
||||
return 0;
|
||||
}
|
||||
if (or_circ && or_circ->p_chan) {
|
||||
tor_assert(!(or_circ->p_chan->is_listener));
|
||||
if (!options->AllowSingleHopExits &&
|
||||
(or_circ->is_first_hop ||
|
||||
(!connection_or_digest_is_known_relay(
|
||||
or_circ->p_chan->u.cell_chan.identity_digest) &&
|
||||
or_circ->p_chan->identity_digest) &&
|
||||
should_refuse_unknown_exits(options)))) {
|
||||
/* Don't let clients use us as a single-hop proxy, unless the user
|
||||
* has explicitly allowed that in the config. It attracts attackers
|
||||
|
@ -336,8 +336,7 @@ connection_or_get_num_circuits(or_connection_t *conn)
|
||||
tor_assert(conn);
|
||||
|
||||
if (conn->chan) {
|
||||
tor_assert(!(TLS_CHAN_TO_BASE(conn->chan)->is_listener));
|
||||
return TLS_CHAN_TO_BASE(conn->chan)->u.cell_chan.n_circuits;
|
||||
return TLS_CHAN_TO_BASE(conn->chan)->n_circuits;
|
||||
} else return 0;
|
||||
}
|
||||
|
||||
@ -1001,8 +1000,6 @@ connection_or_notify_error(or_connection_t *conn,
|
||||
/* Tell the controlling channel if we have one */
|
||||
if (conn->chan) {
|
||||
chan = TLS_CHAN_TO_BASE(conn->chan);
|
||||
/* This shouldn't ever happen in the listening state */
|
||||
tor_assert(chan->state != CHANNEL_STATE_LISTENING);
|
||||
/* Don't transition if we're already in closing, closed or error */
|
||||
if (!(chan->state == CHANNEL_STATE_CLOSING ||
|
||||
chan->state == CHANNEL_STATE_CLOSED ||
|
||||
@ -1148,8 +1145,6 @@ connection_or_close_normally(or_connection_t *orconn, int flush)
|
||||
else connection_mark_for_close(TO_CONN(orconn));
|
||||
if (orconn->chan) {
|
||||
chan = TLS_CHAN_TO_BASE(orconn->chan);
|
||||
/* This shouldn't ever happen in the listening state */
|
||||
tor_assert(chan->state != CHANNEL_STATE_LISTENING);
|
||||
/* Don't transition if we're already in closing, closed or error */
|
||||
if (!(chan->state == CHANNEL_STATE_CLOSING ||
|
||||
chan->state == CHANNEL_STATE_CLOSED ||
|
||||
@ -1173,8 +1168,6 @@ connection_or_close_for_error(or_connection_t *orconn, int flush)
|
||||
else connection_mark_for_close(TO_CONN(orconn));
|
||||
if (orconn->chan) {
|
||||
chan = TLS_CHAN_TO_BASE(orconn->chan);
|
||||
/* This shouldn't ever happen in the listening state */
|
||||
tor_assert(chan->state != CHANNEL_STATE_LISTENING);
|
||||
/* Don't transition if we're already in closing, closed or error */
|
||||
if (!(chan->state == CHANNEL_STATE_CLOSING ||
|
||||
chan->state == CHANNEL_STATE_CLOSED ||
|
||||
@ -1195,7 +1188,8 @@ connection_or_close_for_error(or_connection_t *orconn, int flush)
|
||||
int
|
||||
connection_tls_start_handshake(or_connection_t *conn, int receiving)
|
||||
{
|
||||
channel_t *chan_listener, *chan;
|
||||
channel_listener_t *chan_listener;
|
||||
channel_t *chan;
|
||||
|
||||
/* Incoming connections will need a new channel passed to the
|
||||
* channel_tls_listener */
|
||||
@ -1208,7 +1202,7 @@ connection_tls_start_handshake(or_connection_t *conn, int receiving)
|
||||
command_setup_listener(chan_listener);
|
||||
}
|
||||
chan = channel_tls_handle_incoming(conn);
|
||||
channel_queue_incoming(chan_listener, chan);
|
||||
channel_listener_queue_incoming(chan_listener, chan);
|
||||
}
|
||||
|
||||
connection_or_change_state(conn, OR_CONN_STATE_TLS_HANDSHAKING);
|
||||
|
@ -1539,6 +1539,7 @@ run_scheduled_events(time_t now)
|
||||
|
||||
/** 8c. Do channel cleanup just like for connections */
|
||||
channel_run_cleanup();
|
||||
channel_listener_run_cleanup();
|
||||
|
||||
/** 9. and if we're a server, check whether our DNS is telling stories to
|
||||
* us. */
|
||||
@ -2172,6 +2173,7 @@ dumpstats(int severity)
|
||||
} SMARTLIST_FOREACH_END(conn);
|
||||
|
||||
channel_dumpstats(severity);
|
||||
channel_listener_dumpstats(severity);
|
||||
|
||||
log(severity, LD_NET,
|
||||
"Cells processed: "U64_FORMAT" padding\n"
|
||||
|
65
src/or/or.h
65
src/or/or.h
@ -883,6 +883,10 @@ typedef uint16_t streamid_t;
|
||||
|
||||
typedef struct channel_s channel_t;
|
||||
|
||||
/* channel_listener_t typedef; struct channel_listener_s is in channel.h */
|
||||
|
||||
typedef struct channel_listener_s channel_listener_t;
|
||||
|
||||
/* channel states for channel_t */
|
||||
|
||||
typedef enum {
|
||||
@ -892,20 +896,9 @@ typedef enum {
|
||||
* Permitted transitions from:
|
||||
* - CHANNEL_STATE_CLOSING
|
||||
* Permitted transitions to:
|
||||
* - CHANNEL_STATE_LISTENING
|
||||
* - CHANNEL_STATE_OPENING
|
||||
*/
|
||||
CHANNEL_STATE_CLOSED = 0,
|
||||
/*
|
||||
* Listening state - channel is listening for incoming connections
|
||||
*
|
||||
* Permitted transitions from:
|
||||
* - CHANNEL_STATE_CLOSED
|
||||
* Permitted transitions to:
|
||||
* - CHANNEL_STATE_CLOSING
|
||||
* - CHANNEL_STATE_ERROR
|
||||
*/
|
||||
CHANNEL_STATE_LISTENING,
|
||||
/*
|
||||
* Opening state - channel is trying to connect
|
||||
*
|
||||
@ -957,7 +950,6 @@ typedef enum {
|
||||
*
|
||||
* Permitted transitions from:
|
||||
* - CHANNEL_STATE_CLOSING
|
||||
* - CHANNEL_STATE_LISTENING
|
||||
* - CHANNEL_STATE_MAINT
|
||||
* - CHANNEL_STATE_OPENING
|
||||
* - CHANNEL_STATE_OPEN
|
||||
@ -971,6 +963,55 @@ typedef enum {
|
||||
CHANNEL_STATE_LAST
|
||||
} channel_state_t;
|
||||
|
||||
/* channel listener states for channel_listener_t */
|
||||
|
||||
typedef enum {
|
||||
/*
|
||||
* Closed state - channel listener is inactive
|
||||
*
|
||||
* Permitted transitions from:
|
||||
* - CHANNEL_LISTENER_STATE_CLOSING
|
||||
* Permitted transitions to:
|
||||
* - CHANNEL_LISTENER_STATE_LISTENING
|
||||
*/
|
||||
CHANNEL_LISTENER_STATE_CLOSED = 0,
|
||||
/*
|
||||
* Listening state - channel listener is listening for incoming
|
||||
* connections
|
||||
*
|
||||
* Permitted transitions from:
|
||||
* - CHANNEL_LISTENER_STATE_CLOSED
|
||||
* Permitted transitions to:
|
||||
* - CHANNEL_LISTENER_STATE_CLOSING
|
||||
* - CHANNEL_LISTENER_STATE_ERROR
|
||||
*/
|
||||
CHANNEL_LISTENER_STATE_LISTENING,
|
||||
/*
|
||||
* Closing state - channel listener is shutting down
|
||||
*
|
||||
* Permitted transitions from:
|
||||
* - CHANNEL_LISTENER_STATE_LISTENING
|
||||
* Permitted transitions to:
|
||||
* - CHANNEL_LISTENER_STATE_CLOSED,
|
||||
* - CHANNEL_LISTENER_STATE_ERROR
|
||||
*/
|
||||
CHANNEL_LISTENER_STATE_CLOSING,
|
||||
/*
|
||||
* Error state - channel listener has experienced a permanent error
|
||||
*
|
||||
* Permitted transitions from:
|
||||
* - CHANNEL_STATE_CLOSING
|
||||
* - CHANNEL_STATE_LISTENING
|
||||
* Permitted transitions to:
|
||||
* - None
|
||||
*/
|
||||
CHANNEL_LISTENER_STATE_ERROR,
|
||||
/*
|
||||
* Placeholder for maximum state value
|
||||
*/
|
||||
CHANNEL_LISTENER_STATE_LAST
|
||||
} channel_listener_state_t;
|
||||
|
||||
/* TLS channel stuff */
|
||||
|
||||
typedef struct channel_tls_s channel_tls_t;
|
||||
|
@ -1096,8 +1096,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
|
||||
* and linked. */
|
||||
static uint64_t next_id = 0;
|
||||
circ->dirreq_id = ++next_id;
|
||||
tor_assert(!(TO_OR_CIRCUIT(circ)->p_chan->is_listener));
|
||||
TO_OR_CIRCUIT(circ)->p_chan->u.cell_chan.dirreq_id = circ->dirreq_id;
|
||||
TO_OR_CIRCUIT(circ)->p_chan->dirreq_id = circ->dirreq_id;
|
||||
}
|
||||
|
||||
return connection_exit_begin_conn(cell, circ);
|
||||
@ -2179,23 +2178,22 @@ scale_active_circuits(channel_t *chan, unsigned cur_tick)
|
||||
double factor;
|
||||
|
||||
tor_assert(chan);
|
||||
tor_assert(!(chan->is_listener));
|
||||
|
||||
factor =
|
||||
get_scale_factor(
|
||||
chan->u.cell_chan.active_circuit_pqueue_last_recalibrated,
|
||||
chan->active_circuit_pqueue_last_recalibrated,
|
||||
cur_tick);
|
||||
/** Ordinarily it isn't okay to change the value of an element in a heap,
|
||||
* but it's okay here, since we are preserving the order. */
|
||||
SMARTLIST_FOREACH_BEGIN(
|
||||
chan->u.cell_chan.active_circuit_pqueue,
|
||||
chan->active_circuit_pqueue,
|
||||
cell_ewma_t *, e) {
|
||||
tor_assert(e->last_adjusted_tick ==
|
||||
chan->u.cell_chan.active_circuit_pqueue_last_recalibrated);
|
||||
chan->active_circuit_pqueue_last_recalibrated);
|
||||
e->cell_count *= factor;
|
||||
e->last_adjusted_tick = cur_tick;
|
||||
} SMARTLIST_FOREACH_END(e);
|
||||
chan->u.cell_chan.active_circuit_pqueue_last_recalibrated = cur_tick;
|
||||
chan->active_circuit_pqueue_last_recalibrated = cur_tick;
|
||||
}
|
||||
|
||||
/** Rescale <b>ewma</b> to the same scale as <b>chan</b>, and add it to
|
||||
@ -2204,15 +2202,14 @@ static void
|
||||
add_cell_ewma_to_chan(channel_t *chan, cell_ewma_t *ewma)
|
||||
{
|
||||
tor_assert(chan);
|
||||
tor_assert(!(chan->is_listener));
|
||||
tor_assert(ewma);
|
||||
tor_assert(ewma->heap_index == -1);
|
||||
|
||||
scale_single_cell_ewma(
|
||||
ewma,
|
||||
chan->u.cell_chan.active_circuit_pqueue_last_recalibrated);
|
||||
chan->active_circuit_pqueue_last_recalibrated);
|
||||
|
||||
smartlist_pqueue_add(chan->u.cell_chan.active_circuit_pqueue,
|
||||
smartlist_pqueue_add(chan->active_circuit_pqueue,
|
||||
compare_cell_ewma_counts,
|
||||
STRUCT_OFFSET(cell_ewma_t, heap_index),
|
||||
ewma);
|
||||
@ -2223,11 +2220,10 @@ static void
|
||||
remove_cell_ewma_from_chan(channel_t *chan, cell_ewma_t *ewma)
|
||||
{
|
||||
tor_assert(chan);
|
||||
tor_assert(!(chan->is_listener));
|
||||
tor_assert(ewma);
|
||||
tor_assert(ewma->heap_index != -1);
|
||||
|
||||
smartlist_pqueue_remove(chan->u.cell_chan.active_circuit_pqueue,
|
||||
smartlist_pqueue_remove(chan->active_circuit_pqueue,
|
||||
compare_cell_ewma_counts,
|
||||
STRUCT_OFFSET(cell_ewma_t, heap_index),
|
||||
ewma);
|
||||
@ -2239,9 +2235,8 @@ static cell_ewma_t *
|
||||
pop_first_cell_ewma_from_chan(channel_t *chan)
|
||||
{
|
||||
tor_assert(chan);
|
||||
tor_assert(!(chan->is_listener));
|
||||
|
||||
return smartlist_pqueue_pop(chan->u.cell_chan.active_circuit_pqueue,
|
||||
return smartlist_pqueue_pop(chan->active_circuit_pqueue,
|
||||
compare_cell_ewma_counts,
|
||||
STRUCT_OFFSET(cell_ewma_t, heap_index));
|
||||
}
|
||||
@ -2254,7 +2249,6 @@ make_circuit_active_on_chan(circuit_t *circ, channel_t *chan)
|
||||
circuit_t **nextp = NULL, **prevp = NULL;
|
||||
|
||||
tor_assert(chan);
|
||||
tor_assert(!(chan->is_listener));
|
||||
tor_assert(circ);
|
||||
|
||||
nextp = next_circ_on_chan_p(circ, chan);
|
||||
@ -2267,11 +2261,11 @@ make_circuit_active_on_chan(circuit_t *circ, channel_t *chan)
|
||||
|
||||
assert_active_circuits_ok_paranoid(chan);
|
||||
|
||||
if (!(chan->u.cell_chan.active_circuits)) {
|
||||
chan->u.cell_chan.active_circuits = circ;
|
||||
if (!(chan->active_circuits)) {
|
||||
chan->active_circuits = circ;
|
||||
*prevp = *nextp = circ;
|
||||
} else {
|
||||
circuit_t *head = chan->u.cell_chan.active_circuits;
|
||||
circuit_t *head = chan->active_circuits;
|
||||
circuit_t *old_tail = *prev_circ_on_chan_p(head, chan);
|
||||
*next_circ_on_chan_p(old_tail, chan) = circ;
|
||||
*nextp = head;
|
||||
@ -2299,7 +2293,6 @@ make_circuit_inactive_on_chan(circuit_t *circ, channel_t *chan)
|
||||
circuit_t *next = NULL, *prev = NULL;
|
||||
|
||||
tor_assert(chan);
|
||||
tor_assert(!(chan->is_listener));
|
||||
tor_assert(circ);
|
||||
|
||||
nextp = next_circ_on_chan_p(circ, chan);
|
||||
@ -2319,12 +2312,12 @@ make_circuit_inactive_on_chan(circuit_t *circ, channel_t *chan)
|
||||
tor_assert(*next_circ_on_chan_p(prev, chan) == circ);
|
||||
|
||||
if (next == circ) {
|
||||
chan->u.cell_chan.active_circuits = NULL;
|
||||
chan->active_circuits = NULL;
|
||||
} else {
|
||||
*prev_circ_on_chan_p(next, chan) = prev;
|
||||
*next_circ_on_chan_p(prev, chan) = next;
|
||||
if (chan->u.cell_chan.active_circuits == circ)
|
||||
chan->u.cell_chan.active_circuits = next;
|
||||
if (chan->active_circuits == circ)
|
||||
chan->active_circuits = next;
|
||||
}
|
||||
*prevp = *nextp = NULL;
|
||||
|
||||
@ -2347,9 +2340,8 @@ channel_unlink_all_active_circs(channel_t *chan)
|
||||
circuit_t *head = NULL, *cur = NULL;
|
||||
|
||||
tor_assert(chan);
|
||||
tor_assert(!(chan->is_listener));
|
||||
|
||||
cur = head = chan->u.cell_chan.active_circuits;
|
||||
cur = head = chan->active_circuits;
|
||||
if (! head)
|
||||
return;
|
||||
do {
|
||||
@ -2358,12 +2350,12 @@ channel_unlink_all_active_circs(channel_t *chan)
|
||||
*next_circ_on_chan_p(cur, chan) = NULL;
|
||||
cur = next;
|
||||
} while (cur != head);
|
||||
chan->u.cell_chan.active_circuits = NULL;
|
||||
chan->active_circuits = NULL;
|
||||
|
||||
SMARTLIST_FOREACH(chan->u.cell_chan.active_circuit_pqueue,
|
||||
SMARTLIST_FOREACH(chan->active_circuit_pqueue,
|
||||
cell_ewma_t *, e,
|
||||
e->heap_index = -1);
|
||||
smartlist_clear(chan->u.cell_chan.active_circuit_pqueue);
|
||||
smartlist_clear(chan->active_circuit_pqueue);
|
||||
}
|
||||
|
||||
/** Block (if <b>block</b> is true) or unblock (if <b>block</b> is false)
|
||||
@ -2440,9 +2432,8 @@ channel_flush_from_first_active_circuit(channel_t *chan, int max)
|
||||
double ewma_increment = -1;
|
||||
|
||||
tor_assert(chan);
|
||||
tor_assert(!(chan->is_listener));
|
||||
|
||||
circ = chan->u.cell_chan.active_circuits;
|
||||
circ = chan->active_circuits;
|
||||
if (!circ) return 0;
|
||||
assert_active_circuits_ok_paranoid(chan);
|
||||
|
||||
@ -2453,13 +2444,13 @@ channel_flush_from_first_active_circuit(channel_t *chan, int max)
|
||||
tor_gettimeofday_cached(&now_hires);
|
||||
tick = cell_ewma_tick_from_timeval(&now_hires, &fractional_tick);
|
||||
|
||||
if (tick != chan->u.cell_chan.active_circuit_pqueue_last_recalibrated) {
|
||||
if (tick != chan->active_circuit_pqueue_last_recalibrated) {
|
||||
scale_active_circuits(chan, tick);
|
||||
}
|
||||
|
||||
ewma_increment = pow(ewma_scale_factor, -fractional_tick);
|
||||
|
||||
cell_ewma = smartlist_get(chan->u.cell_chan.active_circuit_pqueue, 0);
|
||||
cell_ewma = smartlist_get(chan->active_circuit_pqueue, 0);
|
||||
circ = cell_ewma_to_circuit(cell_ewma);
|
||||
}
|
||||
|
||||
@ -2511,8 +2502,8 @@ channel_flush_from_first_active_circuit(channel_t *chan, int max)
|
||||
|
||||
/* If we just flushed our queue and this circuit is used for a
|
||||
* tunneled directory request, possibly advance its state. */
|
||||
if (queue->n == 0 && chan->u.cell_chan.dirreq_id)
|
||||
geoip_change_dirreq_state(chan->u.cell_chan.dirreq_id,
|
||||
if (queue->n == 0 && chan->dirreq_id)
|
||||
geoip_change_dirreq_state(chan->dirreq_id,
|
||||
DIRREQ_TUNNELED,
|
||||
DIRREQ_CIRC_QUEUE_FLUSHED);
|
||||
|
||||
@ -2534,7 +2525,7 @@ channel_flush_from_first_active_circuit(channel_t *chan, int max)
|
||||
tor_assert(tmp == cell_ewma);
|
||||
add_cell_ewma_to_chan(chan, cell_ewma);
|
||||
}
|
||||
if (!ewma_enabled && circ != chan->u.cell_chan.active_circuits) {
|
||||
if (!ewma_enabled && circ != chan->active_circuits) {
|
||||
/* If this happens, the current circuit just got made inactive by
|
||||
* a call in connection_write_to_buf(). That's nothing to worry about:
|
||||
* circuit_make_inactive_on_conn() already advanced chan->active_circuits
|
||||
@ -2546,7 +2537,7 @@ channel_flush_from_first_active_circuit(channel_t *chan, int max)
|
||||
}
|
||||
tor_assert(*next_circ_on_chan_p(circ, chan));
|
||||
assert_active_circuits_ok_paranoid(chan);
|
||||
chan->u.cell_chan.active_circuits = *next_circ_on_chan_p(circ, chan);
|
||||
chan->active_circuits = *next_circ_on_chan_p(circ, chan);
|
||||
|
||||
/* Is the cell queue low enough to unblock all the streams that are waiting
|
||||
* to write to this circuit? */
|
||||
@ -2701,9 +2692,8 @@ assert_active_circuits_ok(channel_t *chan)
|
||||
int n = 0;
|
||||
|
||||
tor_assert(chan);
|
||||
tor_assert(!(chan->is_listener));
|
||||
|
||||
cur = head = chan->u.cell_chan.active_circuits;
|
||||
cur = head = chan->active_circuits;
|
||||
|
||||
if (! head)
|
||||
return;
|
||||
@ -2723,13 +2713,13 @@ assert_active_circuits_ok(channel_t *chan)
|
||||
tor_assert(ewma->is_for_p_chan);
|
||||
}
|
||||
tor_assert(ewma->heap_index != -1);
|
||||
tor_assert(ewma == smartlist_get(chan->u.cell_chan.active_circuit_pqueue,
|
||||
tor_assert(ewma == smartlist_get(chan->active_circuit_pqueue,
|
||||
ewma->heap_index));
|
||||
n++;
|
||||
cur = next;
|
||||
} while (cur != head);
|
||||
|
||||
tor_assert(n == smartlist_len(chan->u.cell_chan.active_circuit_pqueue));
|
||||
tor_assert(n == smartlist_len(chan->active_circuit_pqueue));
|
||||
}
|
||||
|
||||
/** Return 1 if we shouldn't restart reading on this circuit, even if
|
||||
|
Loading…
Reference in New Issue
Block a user