49 #include "core/or/dos.h"
63 #include "core/or/or_circuit_st.h"
92 case CELL_PADDING:
return "padding";
93 case CELL_CREATE:
return "create";
94 case CELL_CREATED:
return "created";
95 case CELL_RELAY:
return "relay";
96 case CELL_DESTROY:
return "destroy";
97 case CELL_CREATE_FAST:
return "create_fast";
98 case CELL_CREATED_FAST:
return "created_fast";
99 case CELL_VERSIONS:
return "versions";
100 case CELL_NETINFO:
return "netinfo";
101 case CELL_RELAY_EARLY:
return "relay_early";
102 case CELL_CREATE2:
return "create2";
103 case CELL_CREATED2:
return "created2";
104 case CELL_VPADDING:
return "vpadding";
105 case CELL_CERTS:
return "certs";
106 case CELL_AUTH_CHALLENGE:
return "auth_challenge";
107 case CELL_AUTHENTICATE:
return "authenticate";
108 case CELL_AUTHORIZE:
return "authorize";
109 default:
return "unrecognized";
113 #ifdef KEEP_TIMING_STATS
130 time_passed =
tv_udiff(&start, &end) ;
132 if (time_passed > 10000) {
133 log_debug(
LD_OR,
"That call just took %ld ms.",time_passed/1000);
135 if (time_passed < 0) {
136 log_info(
LD_GENERAL,
"That call took us back in time!");
139 *time += time_passed;
151 #ifdef KEEP_TIMING_STATS
154 static int num_create=0, num_created=0, num_relay=0, num_destroy=0;
156 static int create_time=0, created_time=0, relay_time=0, destroy_time=0;
159 time_t now = time(NULL);
164 "At end of second: %d creates (%d ms), %d createds (%d ms), "
165 "%d relays (%d ms), %d destroys (%d ms)",
166 num_create, create_time/1000,
167 num_created, created_time/1000,
168 num_relay, relay_time/1000,
169 num_destroy, destroy_time/1000);
172 num_create = num_created = num_relay = num_destroy = 0;
173 create_time = created_time = relay_time = destroy_time = 0;
180 #ifdef KEEP_TIMING_STATS
181 #define PROCESS_CELL(tp, cl, cn) STMT_BEGIN { \
183 command_time_process_cell(cl, cn, & tp ## time , \
184 command_process_ ## tp ## _cell); \
187 #define PROCESS_CELL(tp, cl, cn) command_process_ ## tp ## _cell(cl, cn)
192 case CELL_CREATE_FAST:
195 PROCESS_CELL(create, cell, chan);
198 case CELL_CREATED_FAST:
201 PROCESS_CELL(created, cell, chan);
204 case CELL_RELAY_EARLY:
206 PROCESS_CELL(relay, cell, chan);
210 PROCESS_CELL(destroy, cell, chan);
214 "Cell of unknown or unexpected type (%d) received. "
238 "Got a CREATE cell for circ_id %u on channel %"PRIu64
246 dos_cc_new_create_cell(chan);
253 "Received a create cell (type %d) from %s with zero circID; "
254 " ignoring.", (
int)cell->
command,
262 "Received CREATE cell (circID %u) for known circ. "
263 "Dropping (age %d).",
269 "Details: router %s, platform %s.",
278 "Received create cell but we're shutting down. Sending back "
281 END_CIRC_REASON_HIBERNATING);
286 if (dos_cc_get_defense_type(chan) == DOS_CC_DEFENSE_REFUSE_CELL) {
288 END_CIRC_REASON_RESOURCELIMIT);
295 "Received create cell (type %d) from %s, but we're connected "
296 "to it as a client. "
297 "Sending back a destroy.",
300 END_CIRC_REASON_TORPROTOCOL);
306 if (chan->wide_circ_ids)
307 id_is_high = cell->
circ_id & (1u<<31);
309 id_is_high = cell->
circ_id & (1u<<15);
315 "Received create cell with unexpected circ_id %u. Closing.",
318 END_CIRC_REASON_TORPROTOCOL);
329 "Bogus/unrecognized create cell; closing.");
330 circuit_mark_for_close(
TO_CIRCUIT(circ), END_CIRC_REASON_TORPROTOCOL);
351 log_debug(
LD_GENERAL,
"Failed to hand off onionskin. Closing.");
352 circuit_mark_for_close(
TO_CIRCUIT(circ), END_CIRC_REASON_RESOURCELIMIT);
355 log_debug(
LD_OR,
"success: handed off onionskin.");
359 uint8_t keys[CPATH_KEY_MATERIAL_LEN];
364 memset(&created_cell, 0,
sizeof(created_cell));
370 keys, CPATH_KEY_MATERIAL_LEN,
374 log_warn(
LD_OR,
"Failed to generate key material. Closing.");
375 circuit_mark_for_close(
TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
378 created_cell.
cell_type = CELL_CREATED_FAST;
382 (
const char *)keys,
sizeof(keys),
383 rend_circ_nonce)<0) {
384 log_warn(
LD_OR,
"Failed to reply to CREATE_FAST cell. Closing.");
385 circuit_mark_for_close(
TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
388 memwipe(keys, 0,
sizeof(keys));
410 "(circID %u) unknown circ (probably got a destroy earlier). "
411 "Dropping.", (
unsigned)cell->
circ_id);
417 "got created cell from Tor client? Closing.");
418 circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
423 log_fn(LOG_PROTOCOL_WARN,
LD_OR,
"Unparseable created cell.");
424 circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
431 log_debug(
LD_OR,
"at OP. Finishing handshake.");
434 circuit_mark_for_close(circ, -err_reason);
437 log_debug(
LD_OR,
"Moving to next skin.");
439 log_info(
LD_OR,
"circuit_send_next_onion_skin failed.");
441 circuit_mark_for_close(circ, -err_reason);
449 "Converting created cell to extended relay cell, sending.");
450 memset(payload, 0,
sizeof(payload));
452 extended_cell.
cell_type = RELAY_COMMAND_EXTENDED2;
454 extended_cell.
cell_type = RELAY_COMMAND_EXTENDED;
456 log_fn(LOG_PROTOCOL_WARN,
LD_OR,
"Can't format extended cell.");
457 circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
461 relay_send_command_from_edge(0, circ,
command,
462 (
const char*)payload, len, NULL);
475 int reason, direction;
476 uint32_t orig_delivered_bw = 0;
477 uint32_t orig_overhead_bw = 0;
483 "unknown circuit %u on connection from %s. Dropping.",
491 circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
530 if (cell->
command == CELL_RELAY_EARLY) {
536 "Received an inbound RELAY_EARLY cell on circuit %u."
537 " Closing circuit. Please report this event,"
538 " along with the following message.",
544 }
else if (circ->
n_chan) {
545 log_warn(
LD_OR,
" upstream=%s",
548 circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
554 "Received too many RELAY_EARLY cells on circ %u from %s."
558 circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
567 "(%s) failed. Closing.",
573 circuit_mark_for_close(circ, -reason);
600 CONST_TO_OR_CIRCUIT(circ)->circuit_carries_hs_traffic_stats) {
605 if (CONST_TO_OR_CIRCUIT(circ)->used_legacy_circuit_handshake) {
607 }
else if (CONST_TO_OR_CIRCUIT(circ)->rend_splice) {
642 log_info(
LD_OR,
"unknown circuit %u on connection from %s. Dropping.",
647 log_debug(
LD_OR,
"Received for circID %u.",(
unsigned)cell->
circ_id);
649 reason = (uint8_t)cell->
payload[0];
664 log_debug(
LD_OR,
"Delivering 'truncated' back.");
665 payload[0] = (char)reason;
666 relay_send_command_from_edge(0, circ, RELAY_COMMAND_TRUNCATED,
667 payload,
sizeof(payload), NULL);
Fixed-size cell structure.
int channel_is_outgoing(channel_t *chan)
void channel_timestamp_client(channel_t *chan)
void channel_set_cell_handlers(channel_t *chan, channel_cell_handler_fn_ptr cell_handler)
void channel_listener_set_listener_fn(channel_listener_t *chan_l, channel_listener_fn_ptr listener)
int channel_send_destroy(circid_t circ_id, channel_t *chan, int reason)
int channel_is_client(const channel_t *chan)
const char * channel_describe_peer(channel_t *chan)
time_t channel_when_created(channel_t *chan)
Header file for channel.c.
@ CHANNEL_LISTENER_STATE_LISTENING
void circuit_log_path(int severity, unsigned int domain, origin_circuit_t *circ)
int circuit_send_next_onion_skin(origin_circuit_t *circ)
int circuit_finish_handshake(origin_circuit_t *circ, const created_cell_t *reply)
Header file for circuitbuild.c.
int onionskin_answer(struct or_circuit_t *circ, const created_cell_t *created_cell, const char *keys, size_t keys_len, const uint8_t *rend_circ_nonce)
Header for feature/relay/circuitbuild_relay.c.
void circuit_set_p_circid_chan(or_circuit_t *or_circ, circid_t id, channel_t *chan)
int circuit_id_in_use_on_channel(circid_t circ_id, channel_t *chan)
void circuit_set_n_circid_chan(circuit_t *circ, circid_t id, channel_t *chan)
circuit_t * circuit_get_by_circid_channel(circid_t circ_id, channel_t *chan)
void circuit_set_state(circuit_t *circ, uint8_t state)
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
or_circuit_t * TO_OR_CIRCUIT(circuit_t *x)
or_circuit_t * or_circuit_new(circid_t p_circ_id, channel_t *p_chan)
Header file for circuitlist.c.
#define CIRCUIT_STATE_ONIONSKIN_PENDING
#define CIRCUIT_IS_ORIGIN(c)
#define CIRCUIT_PURPOSE_OR
void command_process_cell(channel_t *chan, cell_t *cell)
const char * cell_command_to_string(uint8_t command)
static void command_process_create_cell(cell_t *cell, channel_t *chan)
uint64_t stats_n_created_cells_processed
static void command_handle_incoming_channel(channel_listener_t *listener, channel_t *chan)
static void command_process_destroy_cell(cell_t *cell, channel_t *chan)
static void command_process_created_cell(cell_t *cell, channel_t *chan)
uint64_t stats_n_destroy_cells_processed
uint64_t stats_n_relay_cells_processed
void command_setup_listener(channel_listener_t *listener)
static void command_process_relay_cell(cell_t *cell, channel_t *chan)
void command_setup_channel(channel_t *chan)
uint64_t stats_n_create_cells_processed
Header file for command.c.
const or_options_t * get_options(void)
tor_cmdline_mode_t command
Header file for config.c.
Header file for connection.c.
Header file for connection_or.c.
int control_event_circ_bandwidth_used_for_circ(origin_circuit_t *ocirc)
Header file for control_events.c.
int assign_onionskin_to_cpuworker(or_circuit_t *circ, create_cell_t *onionskin)
Header file for cpuworker.c.
void memwipe(void *mem, uint8_t byte, size_t sz)
Common functions for cryptographic routines.
const char * node_describe(const node_t *node)
Header file for describe.c.
char * esc_for_log(const char *s)
int we_are_hibernating(void)
Header file for hibernate.c.
#define log_fn(severity, domain, args,...)
static time_t current_second
const char * node_get_platform(const node_t *node)
const node_t * node_get_by_id(const char *identity_digest)
Header file for nodelist.c.
int created_cell_parse(created_cell_t *cell_out, const cell_t *cell_in)
int create_cell_parse(create_cell_t *cell_out, const cell_t *cell_in)
int extended_cell_format(uint8_t *command_out, uint16_t *len_out, uint8_t *payload_out, const extended_cell_t *cell_in)
int onion_skin_server_handshake(int type, const uint8_t *onion_skin, size_t onionskin_len, const server_onion_keys_t *keys, uint8_t *reply_out, uint8_t *keys_out, size_t keys_out_len, uint8_t *rend_nonce_out)
Header file for onion_crypto.c.
Master header file for Tor-specific functionality.
#define CELL_PAYLOAD_SIZE
#define RELAY_PAYLOAD_SIZE
#define END_CIRC_REASON_FLAG_REMOTE
Origin circuit structure.
int circuit_receive_relay_cell(cell_t *cell, circuit_t *circ, cell_direction_t cell_direction)
void rep_hist_seen_new_rp_cell(bool is_v2)
void rep_hist_note_circuit_handshake_requested(uint16_t type)
Header file for rephist.c.
Header file for routerlist.c.
int public_server_mode(const or_options_t *options)
int server_mode(const or_options_t *options)
Header file for routermode.c.
uint8_t payload[CELL_PAYLOAD_SIZE]
channel_listener_state_t state
circ_id_type_bitfield_t circ_id_type
char identity_digest[DIGEST_LEN]
uint64_t global_identifier
unsigned int received_destroy
uint8_t onionskin[CELL_PAYLOAD_SIZE - 4]
uint8_t reply[CELL_PAYLOAD_SIZE - 2]
created_cell_t created_cell
unsigned int remaining_relay_early_cells
bool used_legacy_circuit_handshake
struct or_circuit_t * rend_splice
int HiddenServiceStatistics
uint32_t n_delivered_read_circ_bw
uint32_t n_overhead_read_circ_bw
void tor_gettimeofday(struct timeval *timeval)
long tv_udiff(const struct timeval *start, const struct timeval *end)
Variable-length cell structure.