mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 23:53:32 +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"
|
#include "or.h"
|
||||||
|
|
||||||
/* Channel handler function pointer typedefs */
|
/* 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_cell_handler_fn_ptr)(channel_t *, cell_t *);
|
||||||
typedef void (*channel_var_cell_handler_fn_ptr)(channel_t *, var_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? */
|
/* Should we expect to see this channel in the channel lists? */
|
||||||
unsigned char registered:1;
|
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?
|
/** Why did we close?
|
||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
@ -67,171 +61,210 @@ struct channel_s {
|
|||||||
/* Optional method to dump transport-specific statistics on the channel */
|
/* Optional method to dump transport-specific statistics on the channel */
|
||||||
void (*dumpstats)(channel_t *, int);
|
void (*dumpstats)(channel_t *, int);
|
||||||
|
|
||||||
union {
|
/* Registered handlers for incoming cells */
|
||||||
struct {
|
channel_cell_handler_fn_ptr cell_handler;
|
||||||
/* Registered listen handler to call on incoming connection */
|
channel_var_cell_handler_fn_ptr var_cell_handler;
|
||||||
channel_listener_fn_ptr listener;
|
|
||||||
|
|
||||||
/* List of pending incoming connections */
|
/* Methods implemented by the lower layer */
|
||||||
smartlist_t *incoming_list;
|
|
||||||
|
|
||||||
/* 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;
|
* Hash of the public RSA key for the other side's identity key, or
|
||||||
} listener;
|
* zeroes if the other side hasn't shown us a valid identity key.
|
||||||
struct {
|
*/
|
||||||
/* Registered handlers for incoming cells */
|
char identity_digest[DIGEST_LEN];
|
||||||
channel_cell_handler_fn_ptr cell_handler;
|
/* Nickname of the OR on the other side, or NULL if none. */
|
||||||
channel_var_cell_handler_fn_ptr var_cell_handler;
|
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;
|
||||||
|
|
||||||
/*
|
/* List of incoming cells to handle */
|
||||||
* Ask the underlying transport what the remote endpoint address is, in
|
smartlist_t *incoming_queue;
|
||||||
* 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 queued outgoing cells */
|
||||||
* Hash of the public RSA key for the other side's identity key, or
|
smartlist_t *outgoing_queue;
|
||||||
* 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;
|
|
||||||
|
|
||||||
/*
|
/* Circuit stuff for use by relay.c */
|
||||||
* Linked list of channels with the same identity digest, for the
|
|
||||||
* digest->channel map
|
|
||||||
*/
|
|
||||||
channel_t *next_with_same_id, *prev_with_same_id;
|
|
||||||
|
|
||||||
/* 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 */
|
/* Circuit ID generation stuff for use by circuitbuild.c */
|
||||||
smartlist_t *outgoing_queue;
|
|
||||||
|
|
||||||
/* 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;
|
||||||
|
|
||||||
/*
|
/* How many circuits use this connection as p_chan or n_chan? */
|
||||||
* Double-linked ring of circuits with queued cells waiting for room to
|
int n_circuits;
|
||||||
* 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;
|
|
||||||
|
|
||||||
/* 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;
|
||||||
|
|
||||||
/*
|
/** True iff we have decided that the other end of this connection
|
||||||
* When we send CREATE cells along this connection, which half of the
|
* is a client. Channels with this flag set should never be used
|
||||||
* space should we use?
|
* to satisfy an EXTEND request. */
|
||||||
*/
|
unsigned int is_client:1;
|
||||||
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;
|
|
||||||
|
|
||||||
/* How many circuits use this connection as p_chan or n_chan? */
|
/** Set if the channel was initiated remotely (came from a listener) */
|
||||||
int n_circuits;
|
unsigned int is_incoming:1;
|
||||||
|
|
||||||
/*
|
/** Set by lower layer if this is local; i.e., everything it communicates
|
||||||
* True iff this channel shouldn't get any new circs attached to it,
|
* with for this channel returns true for is_local_addr(). This is used
|
||||||
* because the connection is too old, or because there's a better one.
|
* to decide whether to declare reachability when we receive something on
|
||||||
* More generally, this flag is used to note an unhealthy connection;
|
* this channel in circuitbuild.c
|
||||||
* for example, if a bad connection fails we shouldn't assume that the
|
*/
|
||||||
* router itself has a problem.
|
unsigned int is_local:1;
|
||||||
*/
|
|
||||||
unsigned int is_bad_for_new_circs:1;
|
|
||||||
|
|
||||||
/** True iff we have decided that the other end of this connection
|
/** Channel timestamps for cell channels */
|
||||||
* is a client. Channels with this flag set should never be used
|
time_t timestamp_client; /* Client used this, according to relay.c */
|
||||||
* to satisfy an EXTEND request. */
|
time_t timestamp_drained; /* Output queue empty */
|
||||||
unsigned int is_client:1;
|
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) */
|
/* Timestamp for relay.c */
|
||||||
unsigned int is_incoming:1;
|
time_t timestamp_last_added_nonpadding;
|
||||||
|
|
||||||
/** Set by lower layer if this is local; i.e., everything it communicates
|
/** Unique ID for measuring direct network status requests;vtunneled ones
|
||||||
* with for this channel returns true for is_local_addr(). This is used
|
* come over a circuit_t, which has a dirreq_id field as well, but is a
|
||||||
* to decide whether to declare reachability when we receive something on
|
* distinct namespace. */
|
||||||
* this channel in circuitbuild.c
|
uint64_t dirreq_id;
|
||||||
*/
|
|
||||||
unsigned int is_local:1;
|
|
||||||
|
|
||||||
/** Channel timestamps for cell channels */
|
/** Channel counters for cell channels */
|
||||||
time_t timestamp_client; /* Client used this, according to relay.c */
|
uint64_t n_cells_recved;
|
||||||
time_t timestamp_drained; /* Output queue empty */
|
uint64_t n_cells_xmitted;
|
||||||
time_t timestamp_recv; /* Cell received from lower layer */
|
};
|
||||||
time_t timestamp_xmit; /* Cell sent to lower layer */
|
|
||||||
|
|
||||||
/* Timestamp for relay.c */
|
struct channel_listener_s {
|
||||||
time_t timestamp_last_added_nonpadding;
|
/* Current channel listener state */
|
||||||
|
channel_listener_state_t state;
|
||||||
|
|
||||||
/** Unique ID for measuring direct network status requests;vtunneled ones
|
/* Globally unique ID number for a channel over the lifetime of a Tor
|
||||||
* come over a circuit_t, which has a dirreq_id field as well, but is a
|
* process.
|
||||||
* distinct namespace. */
|
*/
|
||||||
uint64_t dirreq_id;
|
uint64_t global_identifier;
|
||||||
|
|
||||||
/** Channel counters for cell channels */
|
/* Should we expect to see this channel in the channel lists? */
|
||||||
uint64_t n_cells_recved;
|
unsigned char registered:1;
|
||||||
uint64_t n_cells_xmitted;
|
|
||||||
} cell_chan;
|
/** Why did we close?
|
||||||
} u;
|
*/
|
||||||
|
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 */
|
/* Channel state manipulations */
|
||||||
|
|
||||||
int channel_state_is_valid(channel_state_t state);
|
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_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_state_to_string(channel_state_t state);
|
||||||
|
const char *
|
||||||
|
channel_listener_state_to_string(channel_listener_state_t state);
|
||||||
|
|
||||||
/* Abstract channel operations */
|
/* 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_packed_cell(channel_t *chan, packed_cell_t *cell);
|
||||||
void channel_write_var_cell(channel_t *chan, var_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 */
|
/* Channel callback registrations */
|
||||||
|
|
||||||
/* Listener callback */
|
/* Listener callback */
|
||||||
channel_listener_fn_ptr channel_get_listener_fn(channel_t *chan);
|
channel_listener_fn_ptr
|
||||||
void channel_set_listener_fn(channel_t *chan,
|
channel_listener_get_listener_fn(channel_listener_t *chan);
|
||||||
channel_listener_fn_ptr listener);
|
|
||||||
|
void channel_listener_set_listener_fn(channel_listener_t *chan,
|
||||||
|
channel_listener_fn_ptr listener);
|
||||||
|
|
||||||
/* Incoming cell callbacks */
|
/* Incoming cell callbacks */
|
||||||
channel_cell_handler_fn_ptr channel_get_cell_handler(channel_t *chan);
|
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
|
channel_var_cell_handler_fn_ptr
|
||||||
var_cell_handler);
|
var_cell_handler);
|
||||||
|
|
||||||
/* Clean up closed channels periodically; called from run_scheduled_events()
|
/* Clean up closed channels and channel listeners periodically; these are
|
||||||
* in main.c
|
* called from run_scheduled_events() in main.c.
|
||||||
*/
|
*/
|
||||||
void channel_run_cleanup(void);
|
void channel_run_cleanup(void);
|
||||||
|
void channel_listener_run_cleanup(void);
|
||||||
|
|
||||||
/* Close all channels and deallocate everything */
|
/* Close all channels and deallocate everything */
|
||||||
void channel_free_all(void);
|
void channel_free_all(void);
|
||||||
|
|
||||||
/* Dump some statistics in the log */
|
/* Dump some statistics in the log */
|
||||||
void channel_dumpstats(int severity);
|
void channel_dumpstats(int severity);
|
||||||
|
void channel_listener_dumpstats(int severity);
|
||||||
|
|
||||||
#ifdef _TOR_CHANNEL_INTERNAL
|
#ifdef _TOR_CHANNEL_INTERNAL
|
||||||
|
|
||||||
@ -277,20 +316,29 @@ void channel_dumpstats(int severity);
|
|||||||
* constructors.
|
* constructors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void channel_init_for_cells(channel_t *chan);
|
void channel_init(channel_t *chan);
|
||||||
void channel_init_listener(channel_t *chan);
|
void channel_init_listener(channel_listener_t *chan);
|
||||||
|
|
||||||
/* Channel registration/unregistration */
|
/* Channel registration/unregistration */
|
||||||
void channel_register(channel_t *chan);
|
void channel_register(channel_t *chan);
|
||||||
void channel_unregister(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 */
|
/* Close from below */
|
||||||
void channel_close_from_lower_layer(channel_t *chan);
|
void channel_close_from_lower_layer(channel_t *chan);
|
||||||
void channel_close_for_error(channel_t *chan);
|
void channel_close_for_error(channel_t *chan);
|
||||||
void channel_closed(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 */
|
/* Free a channel */
|
||||||
void channel_free(channel_t *chan);
|
void channel_free(channel_t *chan);
|
||||||
|
void channel_listener_free(channel_listener_t *chan_l);
|
||||||
|
|
||||||
/* State/metadata setters */
|
/* State/metadata setters */
|
||||||
|
|
||||||
@ -306,17 +354,24 @@ void channel_set_remote_end(channel_t *chan,
|
|||||||
const char *identity_digest,
|
const char *identity_digest,
|
||||||
const char *nickname);
|
const char *nickname);
|
||||||
|
|
||||||
|
void channel_listener_change_state(channel_listener_t *chan_l,
|
||||||
|
channel_listener_state_t to_state);
|
||||||
|
|
||||||
/* Timestamp updates */
|
/* Timestamp updates */
|
||||||
void channel_timestamp_created(channel_t *chan);
|
void channel_timestamp_created(channel_t *chan);
|
||||||
void channel_timestamp_accepted(channel_t *chan);
|
|
||||||
void channel_timestamp_active(channel_t *chan);
|
void channel_timestamp_active(channel_t *chan);
|
||||||
void channel_timestamp_drained(channel_t *chan);
|
void channel_timestamp_drained(channel_t *chan);
|
||||||
void channel_timestamp_recv(channel_t *chan);
|
void channel_timestamp_recv(channel_t *chan);
|
||||||
void channel_timestamp_xmit(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 */
|
/* Incoming channel handling */
|
||||||
void channel_process_incoming(channel_t *listener);
|
void channel_listener_process_incoming(channel_listener_t *listener);
|
||||||
void channel_queue_incoming(channel_t *listener, channel_t *incoming);
|
void channel_listener_queue_incoming(channel_listener_t *listener,
|
||||||
|
channel_t *incoming);
|
||||||
|
|
||||||
/* Incoming cell handling */
|
/* Incoming cell handling */
|
||||||
void channel_process_cells(channel_t *chan);
|
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_set_circid_type(channel_t *chan, crypto_pk_t *identity_rcvd);
|
||||||
void channel_timestamp_client(channel_t *chan);
|
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 */
|
/* Timestamp queries */
|
||||||
time_t channel_when_created(channel_t *chan);
|
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_active(channel_t *chan);
|
||||||
time_t channel_when_last_client(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_drained(channel_t *chan);
|
||||||
time_t channel_when_last_recv(channel_t *chan);
|
time_t channel_when_last_recv(channel_t *chan);
|
||||||
time_t channel_when_last_xmit(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 */
|
/* Counter queries */
|
||||||
uint64_t channel_count_accepted(channel_t *chan);
|
|
||||||
uint64_t channel_count_recved(channel_t *chan);
|
uint64_t channel_count_recved(channel_t *chan);
|
||||||
uint64_t channel_count_xmitted(channel_t *chan);
|
uint64_t channel_count_xmitted(channel_t *chan);
|
||||||
|
|
||||||
|
uint64_t channel_listener_count_accepted(channel_listener_t *chan_l);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ uint64_t stats_n_authenticate_cells_processed = 0;
|
|||||||
uint64_t stats_n_authorize_cells_processed = 0;
|
uint64_t stats_n_authorize_cells_processed = 0;
|
||||||
|
|
||||||
/** Active listener, if any */
|
/** Active listener, if any */
|
||||||
channel_tls_t *channel_tls_listener = NULL;
|
channel_listener_t *channel_tls_listener = NULL;
|
||||||
|
|
||||||
/* channel_tls_t method declarations */
|
/* 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,
|
static int channel_tls_write_var_cell_method(channel_t *chan,
|
||||||
var_cell_t *var_cell);
|
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
|
/** Handle incoming cells for the handshake stuff here rather than
|
||||||
* passing them on up. */
|
* 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_tls_t *tlschan = tor_malloc_zero(sizeof(*tlschan));
|
||||||
channel_t *chan = TLS_CHAN_TO_BASE(tlschan);
|
channel_t *chan = TLS_CHAN_TO_BASE(tlschan);
|
||||||
channel_init_for_cells(chan);
|
channel_init(chan);
|
||||||
chan->state = CHANNEL_STATE_OPENING;
|
chan->state = CHANNEL_STATE_OPENING;
|
||||||
chan->close = channel_tls_close_method;
|
chan->close = channel_tls_close_method;
|
||||||
chan->describe_transport = channel_tls_describe_transport_method;
|
chan->describe_transport = channel_tls_describe_transport_method;
|
||||||
chan->u.cell_chan.get_remote_addr = channel_tls_get_remote_addr_method;
|
chan->get_remote_addr = channel_tls_get_remote_addr_method;
|
||||||
chan->u.cell_chan.get_remote_descr = channel_tls_get_remote_descr_method;
|
chan->get_remote_descr = channel_tls_get_remote_descr_method;
|
||||||
chan->u.cell_chan.has_queued_writes = channel_tls_has_queued_writes_method;
|
chan->has_queued_writes = channel_tls_has_queued_writes_method;
|
||||||
chan->u.cell_chan.is_canonical = channel_tls_is_canonical_method;
|
chan->is_canonical = channel_tls_is_canonical_method;
|
||||||
chan->u.cell_chan.matches_extend_info =
|
chan->matches_extend_info = channel_tls_matches_extend_info_method;
|
||||||
channel_tls_matches_extend_info_method;
|
chan->matches_target = channel_tls_matches_target_method;
|
||||||
chan->u.cell_chan.matches_target = channel_tls_matches_target_method;
|
chan->write_cell = channel_tls_write_cell_method;
|
||||||
chan->u.cell_chan.write_cell = channel_tls_write_cell_method;
|
chan->write_packed_cell = channel_tls_write_packed_cell_method;
|
||||||
chan->u.cell_chan.write_packed_cell = channel_tls_write_packed_cell_method;
|
chan->write_var_cell = channel_tls_write_var_cell_method;
|
||||||
chan->u.cell_chan.write_var_cell = channel_tls_write_var_cell_method;
|
|
||||||
|
|
||||||
log_debug(LD_CHANNEL,
|
log_debug(LD_CHANNEL,
|
||||||
"In channel_tls_connect() for channel %p "
|
"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);
|
if (is_local_addr(addr)) channel_mark_local(chan);
|
||||||
channel_mark_outgoing(chan);
|
channel_mark_outgoing(chan);
|
||||||
|
|
||||||
chan->u.cell_chan.active_circuit_pqueue = smartlist_new();
|
chan->active_circuit_pqueue = smartlist_new();
|
||||||
chan->u.cell_chan.active_circuit_pqueue_last_recalibrated =
|
chan->active_circuit_pqueue_last_recalibrated = cell_ewma_get_tick();
|
||||||
cell_ewma_get_tick();
|
|
||||||
|
|
||||||
/* Set up or_connection stuff */
|
/* Set up or_connection stuff */
|
||||||
tlschan->conn = connection_or_connect(addr, port, id_digest, tlschan);
|
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;
|
goto done;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
smartlist_free(chan->u.cell_chan.active_circuit_pqueue);
|
smartlist_free(chan->active_circuit_pqueue);
|
||||||
tor_free(tlschan);
|
tor_free(tlschan);
|
||||||
chan = NULL;
|
chan = NULL;
|
||||||
|
|
||||||
@ -154,14 +158,14 @@ channel_tls_connect(const tor_addr_t *addr, uint16_t port,
|
|||||||
/**
|
/**
|
||||||
* Return the current channel_tls_t listener
|
* 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
|
* NULL if none has been established
|
||||||
*/
|
*/
|
||||||
|
|
||||||
channel_t *
|
channel_listener_t *
|
||||||
channel_tls_get_listener(void)
|
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.
|
* and return that.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
channel_t *
|
channel_listener_t *
|
||||||
channel_tls_start_listener(void)
|
channel_tls_start_listener(void)
|
||||||
{
|
{
|
||||||
channel_tls_t *listener;
|
channel_listener_t *listener;
|
||||||
channel_t *lchan;
|
|
||||||
|
|
||||||
if (!channel_tls_listener) {
|
if (!channel_tls_listener) {
|
||||||
listener = tor_malloc_zero(sizeof(*listener));
|
listener = tor_malloc_zero(sizeof(*listener));
|
||||||
lchan = TLS_CHAN_TO_BASE(listener);
|
channel_init_listener(listener);
|
||||||
channel_init_listener(lchan);
|
listener->state = CHANNEL_LISTENER_STATE_LISTENING;
|
||||||
lchan->state = CHANNEL_STATE_LISTENING;
|
listener->close = channel_tls_listener_close_method;
|
||||||
lchan->close = channel_tls_close_method;
|
listener->describe_transport =
|
||||||
lchan->describe_transport = channel_tls_describe_transport_method;
|
channel_tls_listener_describe_transport_method;
|
||||||
|
|
||||||
channel_tls_listener = listener;
|
channel_tls_listener = listener;
|
||||||
|
|
||||||
log_debug(LD_CHANNEL,
|
log_debug(LD_CHANNEL,
|
||||||
"Starting TLS listener channel %p with global id " U64_FORMAT,
|
"Starting TLS channel listener %p with global id " U64_FORMAT,
|
||||||
lchan, U64_PRINTF_ARG(lchan->global_identifier));
|
listener, U64_PRINTF_ARG(listener->global_identifier));
|
||||||
|
|
||||||
channel_register(lchan);
|
channel_listener_register(listener);
|
||||||
} else lchan = TLS_CHAN_TO_BASE(channel_tls_listener);
|
} else listener = channel_tls_listener;
|
||||||
|
|
||||||
return lchan;
|
return listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -207,16 +210,13 @@ channel_tls_start_listener(void)
|
|||||||
void
|
void
|
||||||
channel_tls_free_all(void)
|
channel_tls_free_all(void)
|
||||||
{
|
{
|
||||||
channel_t *base = NULL;
|
|
||||||
|
|
||||||
log_debug(LD_CHANNEL,
|
log_debug(LD_CHANNEL,
|
||||||
"Shutting down TLS channels...");
|
"Shutting down TLS channels...");
|
||||||
|
|
||||||
if (channel_tls_listener) {
|
if (channel_tls_listener) {
|
||||||
base = TLS_CHAN_TO_BASE(channel_tls_listener);
|
channel_listener_unregister(channel_tls_listener);
|
||||||
channel_unregister(base);
|
channel_listener_mark_for_close(channel_tls_listener);
|
||||||
channel_mark_for_close(base);
|
channel_listener_free(channel_tls_listener);
|
||||||
channel_free(base);
|
|
||||||
channel_tls_listener = NULL;
|
channel_tls_listener = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,19 +237,18 @@ channel_tls_handle_incoming(or_connection_t *orconn)
|
|||||||
tor_assert(orconn);
|
tor_assert(orconn);
|
||||||
tor_assert(!(orconn->chan));
|
tor_assert(!(orconn->chan));
|
||||||
|
|
||||||
channel_init_for_cells(chan);
|
channel_init(chan);
|
||||||
chan->state = CHANNEL_STATE_OPENING;
|
chan->state = CHANNEL_STATE_OPENING;
|
||||||
chan->close = channel_tls_close_method;
|
chan->close = channel_tls_close_method;
|
||||||
chan->describe_transport = channel_tls_describe_transport_method;
|
chan->describe_transport = channel_tls_describe_transport_method;
|
||||||
chan->u.cell_chan.get_remote_descr = channel_tls_get_remote_descr_method;
|
chan->get_remote_descr = channel_tls_get_remote_descr_method;
|
||||||
chan->u.cell_chan.has_queued_writes = channel_tls_has_queued_writes_method;
|
chan->has_queued_writes = channel_tls_has_queued_writes_method;
|
||||||
chan->u.cell_chan.is_canonical = channel_tls_is_canonical_method;
|
chan->is_canonical = channel_tls_is_canonical_method;
|
||||||
chan->u.cell_chan.matches_extend_info =
|
chan->matches_extend_info = channel_tls_matches_extend_info_method;
|
||||||
channel_tls_matches_extend_info_method;
|
chan->matches_target = channel_tls_matches_target_method;
|
||||||
chan->u.cell_chan.matches_target = channel_tls_matches_target_method;
|
chan->write_cell = channel_tls_write_cell_method;
|
||||||
chan->u.cell_chan.write_cell = channel_tls_write_cell_method;
|
chan->write_packed_cell = channel_tls_write_packed_cell_method;
|
||||||
chan->u.cell_chan.write_packed_cell = channel_tls_write_packed_cell_method;
|
chan->write_var_cell = channel_tls_write_var_cell_method;
|
||||||
chan->u.cell_chan.write_var_cell = channel_tls_write_var_cell_method;
|
|
||||||
|
|
||||||
/* Link the channel and orconn to each other */
|
/* Link the channel and orconn to each other */
|
||||||
tlschan->conn = orconn;
|
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);
|
if (is_local_addr(&(TO_CONN(orconn)->addr))) channel_mark_local(chan);
|
||||||
channel_mark_incoming(chan);
|
channel_mark_incoming(chan);
|
||||||
|
|
||||||
chan->u.cell_chan.active_circuit_pqueue = smartlist_new();
|
chan->active_circuit_pqueue = smartlist_new();
|
||||||
chan->u.cell_chan.active_circuit_pqueue_last_recalibrated =
|
chan->active_circuit_pqueue_last_recalibrated = cell_ewma_get_tick();
|
||||||
cell_ewma_get_tick();
|
|
||||||
|
|
||||||
/* If we got one, we should register it */
|
/* If we got one, we should register it */
|
||||||
if (chan) channel_register(chan);
|
if (chan) channel_register(chan);
|
||||||
@ -285,43 +283,13 @@ channel_tls_close_method(channel_t *chan)
|
|||||||
|
|
||||||
tor_assert(tlschan);
|
tor_assert(tlschan);
|
||||||
|
|
||||||
if (chan->is_listener) {
|
if (tlschan->conn) connection_or_close_normally(tlschan->conn, 1);
|
||||||
/*
|
else {
|
||||||
* Listeners we just go ahead and change state through to CLOSED, but
|
/* Weird - we'll have to change the state ourselves, I guess */
|
||||||
* make sure to check if they're channel_tls_listener to NULL it out.
|
log_info(LD_CHANNEL,
|
||||||
*/
|
"Tried to close channel_tls_t %p with NULL conn",
|
||||||
if (chan == TLS_CHAN_TO_BASE(channel_tls_listener))
|
tlschan);
|
||||||
channel_tls_listener = NULL;
|
channel_change_state(chan, CHANNEL_STATE_ERROR);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,23 +310,19 @@ channel_tls_describe_transport_method(channel_t *chan)
|
|||||||
|
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
|
|
||||||
if (chan->is_listener) {
|
tlschan = BASE_CHAN_TO_TLS(chan);
|
||||||
rv = "TLS channel (listening)";
|
|
||||||
|
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 {
|
} else {
|
||||||
tlschan = BASE_CHAN_TO_TLS(chan);
|
rv = "TLS channel (no connection)";
|
||||||
|
|
||||||
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)";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
@ -603,6 +567,65 @@ channel_tls_write_var_cell_method(channel_t *chan, var_cell_t *var_cell)
|
|||||||
return 1;
|
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 *
|
* 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tor_assert(!(TLS_CHAN_TO_BASE(chan)->is_listener));
|
|
||||||
|
|
||||||
handshaking = (TO_CONN(conn)->state != OR_CONN_STATE_OPEN);
|
handshaking = (TO_CONN(conn)->state != OR_CONN_STATE_OPEN);
|
||||||
|
|
||||||
if (conn->_base.marked_for_close)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tor_assert(!(TLS_CHAN_TO_BASE(chan)->is_listener));
|
|
||||||
|
|
||||||
handshaking = (TO_CONN(conn)->state != OR_CONN_STATE_OPEN);
|
handshaking = (TO_CONN(conn)->state != OR_CONN_STATE_OPEN);
|
||||||
|
|
||||||
if (TO_CONN(conn)->marked_for_close)
|
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(cell);
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
tor_assert(!(TLS_CHAN_TO_BASE(chan)->is_listener));
|
|
||||||
tor_assert(chan->conn);
|
tor_assert(chan->conn);
|
||||||
|
|
||||||
started_here = connection_or_nonopen_was_started_here(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(cell);
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
tor_assert(!(TLS_CHAN_TO_BASE(chan)->is_listener));
|
|
||||||
tor_assert(chan->conn);
|
tor_assert(chan->conn);
|
||||||
|
|
||||||
started_here = connection_or_nonopen_was_started_here(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(cell);
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
tor_assert(!(TLS_CHAN_TO_BASE(chan)->is_listener));
|
|
||||||
tor_assert(chan->conn);
|
tor_assert(chan->conn);
|
||||||
|
|
||||||
if (chan->conn->link_proto < 2) {
|
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),
|
safe_str_client(chan->conn->_base.address),
|
||||||
chan->conn->_base.port,
|
chan->conn->_base.port,
|
||||||
(int)(chan->conn->link_proto),
|
(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),
|
DIGEST_LEN),
|
||||||
tor_addr_is_null(&my_apparent_addr) ?
|
tor_addr_is_null(&my_apparent_addr) ?
|
||||||
"<none>" : fmt_and_decorate_addr(&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(cell);
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
tor_assert(!(TLS_CHAN_TO_BASE(chan)->is_listener));
|
|
||||||
tor_assert(chan->conn);
|
tor_assert(chan->conn);
|
||||||
|
|
||||||
#define ERR(s) \
|
#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
|
* _trying_ to connect to an authority, not necessarily if we _did_ connect
|
||||||
* to one. */
|
* to one. */
|
||||||
if (router_digest_is_trusted_dir(
|
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;
|
severity = LOG_WARN;
|
||||||
else
|
else
|
||||||
severity = LOG_PROTOCOL_WARN;
|
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(cell);
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
tor_assert(!(TLS_CHAN_TO_BASE(chan)->is_listener));
|
|
||||||
tor_assert(chan->conn);
|
tor_assert(chan->conn);
|
||||||
|
|
||||||
#define ERR(s) \
|
#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(cell);
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
tor_assert(!(TLS_CHAN_TO_BASE(chan)->is_listener));
|
|
||||||
tor_assert(chan->conn);
|
tor_assert(chan->conn);
|
||||||
|
|
||||||
#define ERR(s) \
|
#define ERR(s) \
|
||||||
|
@ -28,8 +28,8 @@ struct channel_tls_s {
|
|||||||
|
|
||||||
channel_t * channel_tls_connect(const tor_addr_t *addr, uint16_t port,
|
channel_t * channel_tls_connect(const tor_addr_t *addr, uint16_t port,
|
||||||
const char *id_digest);
|
const char *id_digest);
|
||||||
channel_t * channel_tls_get_listener(void);
|
channel_listener_t * channel_tls_get_listener(void);
|
||||||
channel_t * channel_tls_start_listener(void);
|
channel_listener_t * channel_tls_start_listener(void);
|
||||||
channel_t * channel_tls_handle_incoming(or_connection_t *orconn);
|
channel_t * channel_tls_handle_incoming(or_connection_t *orconn);
|
||||||
|
|
||||||
/* Things for connection_or.c to call back into */
|
/* 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;
|
circid_t high_bit;
|
||||||
|
|
||||||
tor_assert(chan);
|
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,
|
log_warn(LD_BUG,
|
||||||
"Trying to pick a circuit ID for a connection from "
|
"Trying to pick a circuit ID for a connection from "
|
||||||
"a client with no identity.");
|
"a client with no identity.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
high_bit =
|
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 {
|
do {
|
||||||
/* Sequentially iterate over test_circ_id=1...1<<15-1 until we find a
|
/* 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. */
|
* 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) {
|
if (test_circ_id == 0 || test_circ_id >= 1<<15) {
|
||||||
test_circ_id = 1;
|
test_circ_id = 1;
|
||||||
chan->u.cell_chan.next_circ_id = 2;
|
chan->next_circ_id = 2;
|
||||||
}
|
}
|
||||||
if (++attempts > 1<<15) {
|
if (++attempts > 1<<15) {
|
||||||
/* Make sure we don't loop forever if all circ_id's are used. This
|
/* 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;
|
int err_reason = 0;
|
||||||
|
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
tor_assert(!(chan->is_listener));
|
|
||||||
|
|
||||||
log_debug(LD_CIRC,"chan to %s/%s, status=%d",
|
log_debug(LD_CIRC,"chan to %s/%s, status=%d",
|
||||||
chan->u.cell_chan.nickname ?
|
chan->nickname ? chan->nickname : "NULL",
|
||||||
chan->u.cell_chan.nickname : "NULL",
|
|
||||||
channel_get_canonical_remote_descr(chan), status);
|
channel_get_canonical_remote_descr(chan), status);
|
||||||
|
|
||||||
pending_circs = smartlist_new();
|
pending_circs = smartlist_new();
|
||||||
@ -2064,7 +2061,7 @@ circuit_n_chan_done(channel_t *chan, int status)
|
|||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
/* We expected a key. See if it's the right one. */
|
/* 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))
|
circ->n_hop->identity_digest, DIGEST_LEN))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2247,8 +2244,7 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
|
|||||||
else
|
else
|
||||||
control_event_bootstrap(BOOTSTRAP_STATUS_CIRCUIT_CREATE, 0);
|
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->identity_digest);
|
||||||
node = node_get_by_id(circ->_base.n_chan->u.cell_chan.identity_digest);
|
|
||||||
fast = should_use_create_fast_for_circuit(circ);
|
fast = should_use_create_fast_for_circuit(circ);
|
||||||
if (!fast) {
|
if (!fast) {
|
||||||
/* We are an OR and we know the right onion key: we should
|
/* 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
|
/* 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
|
* extend cell came from. There isn't any reason for that, and it can
|
||||||
* assist circular-path attacks. */
|
* assist circular-path attacks. */
|
||||||
tor_assert(!(TO_OR_CIRCUIT(circ)->p_chan->is_listener));
|
|
||||||
if (tor_memeq(id_digest,
|
if (tor_memeq(id_digest,
|
||||||
TO_OR_CIRCUIT(circ)->p_chan->
|
TO_OR_CIRCUIT(circ)->p_chan->identity_digest,
|
||||||
u.cell_chan.identity_digest,
|
|
||||||
DIGEST_LEN)) {
|
DIGEST_LEN)) {
|
||||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||||
"Client asked me to extend back to the previous hop.");
|
"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) {
|
if (!circ->has_opened) {
|
||||||
entry_guard_t *guard;
|
entry_guard_t *guard;
|
||||||
|
|
||||||
tor_assert(!(circ->_base.n_chan->is_listener));
|
guard =
|
||||||
guard = entry_guard_get_by_id_digest(
|
entry_guard_get_by_id_digest(circ->_base.n_chan->identity_digest);
|
||||||
circ->_base.n_chan->u.cell_chan.identity_digest);
|
|
||||||
if (guard) {
|
if (guard) {
|
||||||
if (circ->path_state == PATH_STATE_NEW_CIRC) {
|
if (circ->path_state == PATH_STATE_NEW_CIRC) {
|
||||||
circ->path_state = PATH_STATE_DID_FIRST_HOP;
|
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 */
|
/* Don't count cannibalized/reused circs for path bias */
|
||||||
if (!circ->has_opened) {
|
if (!circ->has_opened) {
|
||||||
tor_assert(!(circ->_base.n_chan->is_listener));
|
|
||||||
guard =
|
guard =
|
||||||
entry_guard_get_by_id_digest(circ->_base.n_chan->
|
entry_guard_get_by_id_digest(circ->_base.n_chan->identity_digest);
|
||||||
u.cell_chan.identity_digest);
|
|
||||||
|
|
||||||
if (guard) {
|
if (guard) {
|
||||||
if (circ->path_state == PATH_STATE_DID_FIRST_HOP) {
|
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;
|
circid_t old_id, *circid_ptr;
|
||||||
int was_active, make_active;
|
int was_active, make_active;
|
||||||
|
|
||||||
if (chan) tor_assert(!(chan->is_listener));
|
|
||||||
|
|
||||||
if (direction == CELL_DIRECTION_OUT) {
|
if (direction == CELL_DIRECTION_OUT) {
|
||||||
chan_ptr = &circ->n_chan;
|
chan_ptr = &circ->n_chan;
|
||||||
circid_ptr = &circ->n_circ_id;
|
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 */
|
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.circ_id = old_id;
|
||||||
search.chan = old_chan;
|
search.chan = old_chan;
|
||||||
found = HT_REMOVE(chan_circid_map, &chan_circid_map, &search);
|
found = HT_REMOVE(chan_circid_map, &chan_circid_map, &search);
|
||||||
if (found) {
|
if (found) {
|
||||||
tor_free(found);
|
tor_free(found);
|
||||||
--old_chan->u.cell_chan.n_circuits;
|
--old_chan->n_circuits;
|
||||||
}
|
}
|
||||||
if (was_active && old_chan != chan)
|
if (was_active && old_chan != chan)
|
||||||
make_circuit_inactive_on_chan(circ, old_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)
|
if (make_active && old_chan != chan)
|
||||||
make_circuit_active_on_chan(circ,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
|
/** 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(out);
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
tor_assert(!(chan->is_listener));
|
|
||||||
|
|
||||||
if (!circuits_pending_chans)
|
if (!circuits_pending_chans)
|
||||||
return;
|
return;
|
||||||
@ -259,8 +255,8 @@ circuit_get_all_pending_on_channel(smartlist_t *out, channel_t *chan)
|
|||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
/* We expected a key. See if it's the right one. */
|
/* 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))
|
circ->n_hop->identity_digest, DIGEST_LEN))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
smartlist_add(out, circ);
|
smartlist_add(out, circ);
|
||||||
@ -276,14 +272,12 @@ circuit_count_pending_on_channel(channel_t *chan)
|
|||||||
smartlist_t *sl = smartlist_new();
|
smartlist_t *sl = smartlist_new();
|
||||||
|
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
tor_assert(!(chan->is_listener));
|
|
||||||
|
|
||||||
circuit_get_all_pending_on_channel(sl, chan);
|
circuit_get_all_pending_on_channel(sl, chan);
|
||||||
cnt = smartlist_len(sl);
|
cnt = smartlist_len(sl);
|
||||||
smartlist_free(sl);
|
smartlist_free(sl);
|
||||||
log_debug(LD_CIRC,"or_conn to %s at %s, %d pending circs",
|
log_debug(LD_CIRC,"or_conn to %s at %s, %d pending circs",
|
||||||
chan->u.cell_chan.nickname ?
|
chan->nickname ? chan->nickname : "NULL",
|
||||||
chan->u.cell_chan.nickname : "NULL",
|
|
||||||
channel_get_canonical_remote_descr(chan),
|
channel_get_canonical_remote_descr(chan),
|
||||||
cnt);
|
cnt);
|
||||||
return cnt;
|
return cnt;
|
||||||
@ -839,7 +833,6 @@ circuit_dump_by_chan(channel_t *chan, int severity)
|
|||||||
circuit_t *circ;
|
circuit_t *circ;
|
||||||
|
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
tor_assert(!(chan->is_listener));
|
|
||||||
|
|
||||||
for (circ = global_circuitlist; circ; circ = circ->next) {
|
for (circ = global_circuitlist; circ; circ = circ->next) {
|
||||||
circid_t n_circ_id = circ->n_circ_id, p_circ_id = 0;
|
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 &&
|
if (!circ->n_chan && circ->n_hop &&
|
||||||
channel_matches_extend_info(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)) {
|
circ->n_hop->identity_digest, DIGEST_LEN)) {
|
||||||
circuit_dump_chan_details(severity, circ, chan,
|
circuit_dump_chan_details(severity, circ, chan,
|
||||||
(circ->state == CIRCUIT_STATE_OPEN &&
|
(circ->state == CIRCUIT_STATE_OPEN &&
|
||||||
|
@ -1185,9 +1185,8 @@ circuit_build_failed(origin_circuit_t *circ)
|
|||||||
int already_marked = 0;
|
int already_marked = 0;
|
||||||
if (circ->_base.n_chan) {
|
if (circ->_base.n_chan) {
|
||||||
n_chan = 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
|
/* We only want to blame this router when a fresh healthy
|
||||||
* connection fails. So don't mark this router as newly failed,
|
* connection fails. So don't mark this router as newly failed,
|
||||||
* since maybe this was just an old circuit attempt that's
|
* 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 "
|
"Our circuit failed to get a response from the first hop "
|
||||||
"(%s). I'm going to try to rotate to a better connection.",
|
"(%s). I'm going to try to rotate to a better connection.",
|
||||||
channel_get_canonical_remote_descr(n_chan));
|
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 {
|
} else {
|
||||||
log_info(LD_OR,
|
log_info(LD_OR,
|
||||||
"Our circuit died before the first hop with no connection");
|
"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;
|
uint64_t stats_n_destroy_cells_processed = 0;
|
||||||
|
|
||||||
/* Handle an incoming channel */
|
/* 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);
|
channel_t *chan);
|
||||||
|
|
||||||
/* These are the main functions for processing cells */
|
/* 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(cell);
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
tor_assert(!(chan->is_listener));
|
|
||||||
|
|
||||||
log_debug(LD_OR,
|
log_debug(LD_OR,
|
||||||
"Got a CREATE cell for circ_id %d on channel " U64_FORMAT
|
"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. */
|
* circ. */
|
||||||
id_is_high = cell->circ_id & (1<<15);
|
id_is_high = cell->circ_id & (1<<15);
|
||||||
if ((id_is_high &&
|
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 &&
|
(!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,
|
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||||
"Received create cell with unexpected circ_id %d. Closing.",
|
"Received create cell with unexpected circ_id %d. Closing.",
|
||||||
cell->circ_id);
|
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)) {
|
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,
|
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||||
"Received CREATE cell (circID %d) for known circ. "
|
"Received CREATE cell (circID %d) for known circ. "
|
||||||
"Dropping (age %d).",
|
"Dropping (age %d).",
|
||||||
@ -473,7 +472,7 @@ command_process_destroy_cell(cell_t *cell, channel_t *chan)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
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(listener);
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
@ -500,11 +499,11 @@ command_setup_channel(channel_t *chan)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
command_setup_listener(channel_t *listener)
|
command_setup_listener(channel_listener_t *listener)
|
||||||
{
|
{
|
||||||
tor_assert(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_cell(channel_t *chan, cell_t *cell);
|
||||||
void command_process_var_cell(channel_t *chan, var_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_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_padding_cells_processed;
|
||||||
extern uint64_t stats_n_create_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;
|
return 0;
|
||||||
}
|
}
|
||||||
if (or_circ && or_circ->p_chan) {
|
if (or_circ && or_circ->p_chan) {
|
||||||
tor_assert(!(or_circ->p_chan->is_listener));
|
|
||||||
if (!options->AllowSingleHopExits &&
|
if (!options->AllowSingleHopExits &&
|
||||||
(or_circ->is_first_hop ||
|
(or_circ->is_first_hop ||
|
||||||
(!connection_or_digest_is_known_relay(
|
(!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)))) {
|
should_refuse_unknown_exits(options)))) {
|
||||||
/* Don't let clients use us as a single-hop proxy, unless the user
|
/* Don't let clients use us as a single-hop proxy, unless the user
|
||||||
* has explicitly allowed that in the config. It attracts attackers
|
* 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);
|
tor_assert(conn);
|
||||||
|
|
||||||
if (conn->chan) {
|
if (conn->chan) {
|
||||||
tor_assert(!(TLS_CHAN_TO_BASE(conn->chan)->is_listener));
|
return TLS_CHAN_TO_BASE(conn->chan)->n_circuits;
|
||||||
return TLS_CHAN_TO_BASE(conn->chan)->u.cell_chan.n_circuits;
|
|
||||||
} else return 0;
|
} else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1001,8 +1000,6 @@ connection_or_notify_error(or_connection_t *conn,
|
|||||||
/* Tell the controlling channel if we have one */
|
/* Tell the controlling channel if we have one */
|
||||||
if (conn->chan) {
|
if (conn->chan) {
|
||||||
chan = TLS_CHAN_TO_BASE(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 */
|
/* Don't transition if we're already in closing, closed or error */
|
||||||
if (!(chan->state == CHANNEL_STATE_CLOSING ||
|
if (!(chan->state == CHANNEL_STATE_CLOSING ||
|
||||||
chan->state == CHANNEL_STATE_CLOSED ||
|
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));
|
else connection_mark_for_close(TO_CONN(orconn));
|
||||||
if (orconn->chan) {
|
if (orconn->chan) {
|
||||||
chan = TLS_CHAN_TO_BASE(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 */
|
/* Don't transition if we're already in closing, closed or error */
|
||||||
if (!(chan->state == CHANNEL_STATE_CLOSING ||
|
if (!(chan->state == CHANNEL_STATE_CLOSING ||
|
||||||
chan->state == CHANNEL_STATE_CLOSED ||
|
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));
|
else connection_mark_for_close(TO_CONN(orconn));
|
||||||
if (orconn->chan) {
|
if (orconn->chan) {
|
||||||
chan = TLS_CHAN_TO_BASE(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 */
|
/* Don't transition if we're already in closing, closed or error */
|
||||||
if (!(chan->state == CHANNEL_STATE_CLOSING ||
|
if (!(chan->state == CHANNEL_STATE_CLOSING ||
|
||||||
chan->state == CHANNEL_STATE_CLOSED ||
|
chan->state == CHANNEL_STATE_CLOSED ||
|
||||||
@ -1195,7 +1188,8 @@ connection_or_close_for_error(or_connection_t *orconn, int flush)
|
|||||||
int
|
int
|
||||||
connection_tls_start_handshake(or_connection_t *conn, int receiving)
|
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
|
/* Incoming connections will need a new channel passed to the
|
||||||
* channel_tls_listener */
|
* channel_tls_listener */
|
||||||
@ -1208,7 +1202,7 @@ connection_tls_start_handshake(or_connection_t *conn, int receiving)
|
|||||||
command_setup_listener(chan_listener);
|
command_setup_listener(chan_listener);
|
||||||
}
|
}
|
||||||
chan = channel_tls_handle_incoming(conn);
|
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);
|
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 */
|
/** 8c. Do channel cleanup just like for connections */
|
||||||
channel_run_cleanup();
|
channel_run_cleanup();
|
||||||
|
channel_listener_run_cleanup();
|
||||||
|
|
||||||
/** 9. and if we're a server, check whether our DNS is telling stories to
|
/** 9. and if we're a server, check whether our DNS is telling stories to
|
||||||
* us. */
|
* us. */
|
||||||
@ -2172,6 +2173,7 @@ dumpstats(int severity)
|
|||||||
} SMARTLIST_FOREACH_END(conn);
|
} SMARTLIST_FOREACH_END(conn);
|
||||||
|
|
||||||
channel_dumpstats(severity);
|
channel_dumpstats(severity);
|
||||||
|
channel_listener_dumpstats(severity);
|
||||||
|
|
||||||
log(severity, LD_NET,
|
log(severity, LD_NET,
|
||||||
"Cells processed: "U64_FORMAT" padding\n"
|
"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;
|
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 */
|
/* channel states for channel_t */
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -892,20 +896,9 @@ typedef enum {
|
|||||||
* Permitted transitions from:
|
* Permitted transitions from:
|
||||||
* - CHANNEL_STATE_CLOSING
|
* - CHANNEL_STATE_CLOSING
|
||||||
* Permitted transitions to:
|
* Permitted transitions to:
|
||||||
* - CHANNEL_STATE_LISTENING
|
|
||||||
* - CHANNEL_STATE_OPENING
|
* - CHANNEL_STATE_OPENING
|
||||||
*/
|
*/
|
||||||
CHANNEL_STATE_CLOSED = 0,
|
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
|
* Opening state - channel is trying to connect
|
||||||
*
|
*
|
||||||
@ -957,7 +950,6 @@ typedef enum {
|
|||||||
*
|
*
|
||||||
* Permitted transitions from:
|
* Permitted transitions from:
|
||||||
* - CHANNEL_STATE_CLOSING
|
* - CHANNEL_STATE_CLOSING
|
||||||
* - CHANNEL_STATE_LISTENING
|
|
||||||
* - CHANNEL_STATE_MAINT
|
* - CHANNEL_STATE_MAINT
|
||||||
* - CHANNEL_STATE_OPENING
|
* - CHANNEL_STATE_OPENING
|
||||||
* - CHANNEL_STATE_OPEN
|
* - CHANNEL_STATE_OPEN
|
||||||
@ -971,6 +963,55 @@ typedef enum {
|
|||||||
CHANNEL_STATE_LAST
|
CHANNEL_STATE_LAST
|
||||||
} channel_state_t;
|
} 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 */
|
/* TLS channel stuff */
|
||||||
|
|
||||||
typedef struct channel_tls_s channel_tls_t;
|
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. */
|
* and linked. */
|
||||||
static uint64_t next_id = 0;
|
static uint64_t next_id = 0;
|
||||||
circ->dirreq_id = ++next_id;
|
circ->dirreq_id = ++next_id;
|
||||||
tor_assert(!(TO_OR_CIRCUIT(circ)->p_chan->is_listener));
|
TO_OR_CIRCUIT(circ)->p_chan->dirreq_id = circ->dirreq_id;
|
||||||
TO_OR_CIRCUIT(circ)->p_chan->u.cell_chan.dirreq_id = circ->dirreq_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return connection_exit_begin_conn(cell, circ);
|
return connection_exit_begin_conn(cell, circ);
|
||||||
@ -2179,23 +2178,22 @@ scale_active_circuits(channel_t *chan, unsigned cur_tick)
|
|||||||
double factor;
|
double factor;
|
||||||
|
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
tor_assert(!(chan->is_listener));
|
|
||||||
|
|
||||||
factor =
|
factor =
|
||||||
get_scale_factor(
|
get_scale_factor(
|
||||||
chan->u.cell_chan.active_circuit_pqueue_last_recalibrated,
|
chan->active_circuit_pqueue_last_recalibrated,
|
||||||
cur_tick);
|
cur_tick);
|
||||||
/** Ordinarily it isn't okay to change the value of an element in a heap,
|
/** 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. */
|
* but it's okay here, since we are preserving the order. */
|
||||||
SMARTLIST_FOREACH_BEGIN(
|
SMARTLIST_FOREACH_BEGIN(
|
||||||
chan->u.cell_chan.active_circuit_pqueue,
|
chan->active_circuit_pqueue,
|
||||||
cell_ewma_t *, e) {
|
cell_ewma_t *, e) {
|
||||||
tor_assert(e->last_adjusted_tick ==
|
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->cell_count *= factor;
|
||||||
e->last_adjusted_tick = cur_tick;
|
e->last_adjusted_tick = cur_tick;
|
||||||
} SMARTLIST_FOREACH_END(e);
|
} 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
|
/** 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)
|
add_cell_ewma_to_chan(channel_t *chan, cell_ewma_t *ewma)
|
||||||
{
|
{
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
tor_assert(!(chan->is_listener));
|
|
||||||
tor_assert(ewma);
|
tor_assert(ewma);
|
||||||
tor_assert(ewma->heap_index == -1);
|
tor_assert(ewma->heap_index == -1);
|
||||||
|
|
||||||
scale_single_cell_ewma(
|
scale_single_cell_ewma(
|
||||||
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,
|
compare_cell_ewma_counts,
|
||||||
STRUCT_OFFSET(cell_ewma_t, heap_index),
|
STRUCT_OFFSET(cell_ewma_t, heap_index),
|
||||||
ewma);
|
ewma);
|
||||||
@ -2223,11 +2220,10 @@ static void
|
|||||||
remove_cell_ewma_from_chan(channel_t *chan, cell_ewma_t *ewma)
|
remove_cell_ewma_from_chan(channel_t *chan, cell_ewma_t *ewma)
|
||||||
{
|
{
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
tor_assert(!(chan->is_listener));
|
|
||||||
tor_assert(ewma);
|
tor_assert(ewma);
|
||||||
tor_assert(ewma->heap_index != -1);
|
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,
|
compare_cell_ewma_counts,
|
||||||
STRUCT_OFFSET(cell_ewma_t, heap_index),
|
STRUCT_OFFSET(cell_ewma_t, heap_index),
|
||||||
ewma);
|
ewma);
|
||||||
@ -2239,9 +2235,8 @@ static cell_ewma_t *
|
|||||||
pop_first_cell_ewma_from_chan(channel_t *chan)
|
pop_first_cell_ewma_from_chan(channel_t *chan)
|
||||||
{
|
{
|
||||||
tor_assert(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,
|
compare_cell_ewma_counts,
|
||||||
STRUCT_OFFSET(cell_ewma_t, heap_index));
|
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;
|
circuit_t **nextp = NULL, **prevp = NULL;
|
||||||
|
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
tor_assert(!(chan->is_listener));
|
|
||||||
tor_assert(circ);
|
tor_assert(circ);
|
||||||
|
|
||||||
nextp = next_circ_on_chan_p(circ, chan);
|
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);
|
assert_active_circuits_ok_paranoid(chan);
|
||||||
|
|
||||||
if (!(chan->u.cell_chan.active_circuits)) {
|
if (!(chan->active_circuits)) {
|
||||||
chan->u.cell_chan.active_circuits = circ;
|
chan->active_circuits = circ;
|
||||||
*prevp = *nextp = circ;
|
*prevp = *nextp = circ;
|
||||||
} else {
|
} 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);
|
circuit_t *old_tail = *prev_circ_on_chan_p(head, chan);
|
||||||
*next_circ_on_chan_p(old_tail, chan) = circ;
|
*next_circ_on_chan_p(old_tail, chan) = circ;
|
||||||
*nextp = head;
|
*nextp = head;
|
||||||
@ -2299,7 +2293,6 @@ make_circuit_inactive_on_chan(circuit_t *circ, channel_t *chan)
|
|||||||
circuit_t *next = NULL, *prev = NULL;
|
circuit_t *next = NULL, *prev = NULL;
|
||||||
|
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
tor_assert(!(chan->is_listener));
|
|
||||||
tor_assert(circ);
|
tor_assert(circ);
|
||||||
|
|
||||||
nextp = next_circ_on_chan_p(circ, chan);
|
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);
|
tor_assert(*next_circ_on_chan_p(prev, chan) == circ);
|
||||||
|
|
||||||
if (next == circ) {
|
if (next == circ) {
|
||||||
chan->u.cell_chan.active_circuits = NULL;
|
chan->active_circuits = NULL;
|
||||||
} else {
|
} else {
|
||||||
*prev_circ_on_chan_p(next, chan) = prev;
|
*prev_circ_on_chan_p(next, chan) = prev;
|
||||||
*next_circ_on_chan_p(prev, chan) = next;
|
*next_circ_on_chan_p(prev, chan) = next;
|
||||||
if (chan->u.cell_chan.active_circuits == circ)
|
if (chan->active_circuits == circ)
|
||||||
chan->u.cell_chan.active_circuits = next;
|
chan->active_circuits = next;
|
||||||
}
|
}
|
||||||
*prevp = *nextp = NULL;
|
*prevp = *nextp = NULL;
|
||||||
|
|
||||||
@ -2347,9 +2340,8 @@ channel_unlink_all_active_circs(channel_t *chan)
|
|||||||
circuit_t *head = NULL, *cur = NULL;
|
circuit_t *head = NULL, *cur = NULL;
|
||||||
|
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
tor_assert(!(chan->is_listener));
|
|
||||||
|
|
||||||
cur = head = chan->u.cell_chan.active_circuits;
|
cur = head = chan->active_circuits;
|
||||||
if (! head)
|
if (! head)
|
||||||
return;
|
return;
|
||||||
do {
|
do {
|
||||||
@ -2358,12 +2350,12 @@ channel_unlink_all_active_circs(channel_t *chan)
|
|||||||
*next_circ_on_chan_p(cur, chan) = NULL;
|
*next_circ_on_chan_p(cur, chan) = NULL;
|
||||||
cur = next;
|
cur = next;
|
||||||
} while (cur != head);
|
} 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,
|
cell_ewma_t *, e,
|
||||||
e->heap_index = -1);
|
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)
|
/** 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;
|
double ewma_increment = -1;
|
||||||
|
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
tor_assert(!(chan->is_listener));
|
|
||||||
|
|
||||||
circ = chan->u.cell_chan.active_circuits;
|
circ = chan->active_circuits;
|
||||||
if (!circ) return 0;
|
if (!circ) return 0;
|
||||||
assert_active_circuits_ok_paranoid(chan);
|
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);
|
tor_gettimeofday_cached(&now_hires);
|
||||||
tick = cell_ewma_tick_from_timeval(&now_hires, &fractional_tick);
|
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);
|
scale_active_circuits(chan, tick);
|
||||||
}
|
}
|
||||||
|
|
||||||
ewma_increment = pow(ewma_scale_factor, -fractional_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);
|
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
|
/* If we just flushed our queue and this circuit is used for a
|
||||||
* tunneled directory request, possibly advance its state. */
|
* tunneled directory request, possibly advance its state. */
|
||||||
if (queue->n == 0 && chan->u.cell_chan.dirreq_id)
|
if (queue->n == 0 && chan->dirreq_id)
|
||||||
geoip_change_dirreq_state(chan->u.cell_chan.dirreq_id,
|
geoip_change_dirreq_state(chan->dirreq_id,
|
||||||
DIRREQ_TUNNELED,
|
DIRREQ_TUNNELED,
|
||||||
DIRREQ_CIRC_QUEUE_FLUSHED);
|
DIRREQ_CIRC_QUEUE_FLUSHED);
|
||||||
|
|
||||||
@ -2534,7 +2525,7 @@ channel_flush_from_first_active_circuit(channel_t *chan, int max)
|
|||||||
tor_assert(tmp == cell_ewma);
|
tor_assert(tmp == cell_ewma);
|
||||||
add_cell_ewma_to_chan(chan, 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
|
/* If this happens, the current circuit just got made inactive by
|
||||||
* a call in connection_write_to_buf(). That's nothing to worry about:
|
* a call in connection_write_to_buf(). That's nothing to worry about:
|
||||||
* circuit_make_inactive_on_conn() already advanced chan->active_circuits
|
* 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));
|
tor_assert(*next_circ_on_chan_p(circ, chan));
|
||||||
assert_active_circuits_ok_paranoid(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
|
/* Is the cell queue low enough to unblock all the streams that are waiting
|
||||||
* to write to this circuit? */
|
* to write to this circuit? */
|
||||||
@ -2701,9 +2692,8 @@ assert_active_circuits_ok(channel_t *chan)
|
|||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
tor_assert(!(chan->is_listener));
|
|
||||||
|
|
||||||
cur = head = chan->u.cell_chan.active_circuits;
|
cur = head = chan->active_circuits;
|
||||||
|
|
||||||
if (! head)
|
if (! head)
|
||||||
return;
|
return;
|
||||||
@ -2723,13 +2713,13 @@ assert_active_circuits_ok(channel_t *chan)
|
|||||||
tor_assert(ewma->is_for_p_chan);
|
tor_assert(ewma->is_for_p_chan);
|
||||||
}
|
}
|
||||||
tor_assert(ewma->heap_index != -1);
|
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));
|
ewma->heap_index));
|
||||||
n++;
|
n++;
|
||||||
cur = next;
|
cur = next;
|
||||||
} while (cur != head);
|
} 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
|
/** Return 1 if we shouldn't restart reading on this circuit, even if
|
||||||
|
Loading…
Reference in New Issue
Block a user