* not need any other consideration, otherwise return 1.
*/
int
-circpad_check_received_cell(cell_t *cell, circuit_t *circ,
- crypt_path_t *layer_hint,
- const relay_header_t *rh)
+circpad_check_received_cell(const relay_msg_t *msg, circuit_t *circ,
+ crypt_path_t *layer_hint)
{
/* First handle the padding commands, since we want to ignore any other
* commands if this circuit is padding-specific. */
- switch (rh->command) {
+ switch (msg->command) {
case RELAY_COMMAND_DROP:
/* Already examined in circpad_deliver_recognized_relay_cell_events */
return 0;
case RELAY_COMMAND_PADDING_NEGOTIATE:
- circpad_handle_padding_negotiate(circ, cell);
+ circpad_handle_padding_negotiate(circ, msg);
return 0;
case RELAY_COMMAND_PADDING_NEGOTIATED:
- if (circpad_handle_padding_negotiated(circ, cell, layer_hint) == 0)
- circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh->length);
+ if (circpad_handle_padding_negotiated(circ, msg, layer_hint) == 0)
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
return 0;
}
if (circ->purpose == CIRCUIT_PURPOSE_C_CIRCUIT_PADDING) {
log_fn(LOG_PROTOCOL_WARN, LD_CIRC,
"Ignored cell (%d) that arrived in padding circuit "
- " %u.", rh->command, CIRCUIT_IS_ORIGIN(circ) ?
+ " %u.", msg->command, CIRCUIT_IS_ORIGIN(circ) ?
TO_ORIGIN_CIRCUIT(circ)->global_identifier : 0);
return 0;
}
* Returns -1 on error, 0 on success.
*/
signed_error_t
-circpad_handle_padding_negotiate(circuit_t *circ, cell_t *cell)
+circpad_handle_padding_negotiate(circuit_t *circ, const relay_msg_t *msg)
{
int retval = 0;
/* Should we send back a STOP cell? */
return -1;
}
- if (circpad_negotiate_parse(&negotiate, cell->payload+RELAY_HEADER_SIZE,
- CELL_PAYLOAD_SIZE-RELAY_HEADER_SIZE) < 0) {
+ if (circpad_negotiate_parse(&negotiate, msg->body, msg->length) < 0) {
log_fn(LOG_PROTOCOL_WARN, LD_CIRC,
"Received malformed PADDING_NEGOTIATE cell; dropping.");
return -1;
* Returns -1 on error, 0 on success.
*/
signed_error_t
-circpad_handle_padding_negotiated(circuit_t *circ, cell_t *cell,
+circpad_handle_padding_negotiated(circuit_t *circ, const relay_msg_t *msg,
crypt_path_t *layer_hint)
{
circpad_negotiated_t *negotiated;
return -1;
}
- if (circpad_negotiated_parse(&negotiated, cell->payload+RELAY_HEADER_SIZE,
- CELL_PAYLOAD_SIZE-RELAY_HEADER_SIZE) < 0) {
+ if (circpad_negotiated_parse(&negotiated, msg->body, msg->length) < 0) {
log_fn(LOG_PROTOCOL_WARN, LD_CIRC,
"Received malformed PADDING_NEGOTIATED cell on circuit %u; "
"dropping.", TO_ORIGIN_CIRCUIT(circ)->global_identifier);
#include "trunnel/circpad_negotiation.h"
#include "lib/evloop/timers.h"
+#include "core/or/relay_msg_st.h"
struct circuit_t;
struct origin_circuit_t;
/* Padding negotiation between client and middle */
signed_error_t circpad_handle_padding_negotiate(struct circuit_t *circ,
- struct cell_t *cell);
+ const relay_msg_t *msg);
signed_error_t circpad_handle_padding_negotiated(struct circuit_t *circ,
- struct cell_t *cell,
+ const relay_msg_t *msg,
crypt_path_t *layer_hint);
signed_error_t circpad_negotiate_padding(struct origin_circuit_t *circ,
circpad_machine_num_t machine,
circpad_purpose_mask_t circpad_circ_purpose_to_mask(uint8_t circ_purpose);
-int circpad_check_received_cell(cell_t *cell, circuit_t *circ,
- crypt_path_t *layer_hint,
- const relay_header_t *rh);
+int circpad_check_received_cell(const relay_msg_t *msg, circuit_t *circ,
+ crypt_path_t *layer_hint);
MOCK_DECL(circpad_decision_t,
circpad_machine_schedule_padding,(circpad_machine_runtime_t *));
* \brief Conflux multipath core algorithms
*/
+#include "core/or/relay_msg.h"
#define TOR_CONFLUX_PRIVATE
#include "core/or/or.h"
conflux_get_circ_bytes_allocation(const circuit_t *circ)
{
if (circ->conflux) {
- return smartlist_len(circ->conflux->ooo_q) * sizeof(conflux_cell_t);
+ return smartlist_len(circ->conflux->ooo_q) * sizeof(conflux_msg_t);
}
return 0;
}
{
// Compare a and b as conflux_cell_t using the seq field, and return a
// comparison result such that the lowest seq is at the head of the pqueue.
- const conflux_cell_t *cell_a = a;
- const conflux_cell_t *cell_b = b;
+ const conflux_msg_t *cell_a = a;
+ const conflux_msg_t *cell_b = b;
tor_assert(cell_a);
tor_assert(cell_b);
*/
int
conflux_process_switch_command(circuit_t *in_circ,
- crypt_path_t *layer_hint, cell_t *cell,
- relay_header_t *rh)
+ crypt_path_t *layer_hint,
+ const relay_msg_t *msg)
{
tor_assert(in_circ);
- tor_assert(cell);
- tor_assert(rh);
+ tor_assert(msg);
conflux_t *cfx = in_circ->conflux;
uint32_t relative_seq;
return -1;
}
- relative_seq = conflux_cell_parse_switch(cell, rh->length);
+ relative_seq = conflux_cell_parse_switch(msg);
/*
* We have to make sure that the switch command is truely
/* Mark this data as validated for controlport and vanguards
* dropped cell handling */
if (CIRCUIT_IS_ORIGIN(in_circ)) {
- circuit_read_valid_data(TO_ORIGIN_CIRCUIT(in_circ), rh->length);
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(in_circ), msg->length);
}
return 0;
* to streams, false otherwise.
*/
bool
-conflux_process_cell(conflux_t *cfx, circuit_t *in_circ,
- crypt_path_t *layer_hint, cell_t *cell)
+conflux_process_relay_msg(conflux_t *cfx, circuit_t *in_circ,
+ crypt_path_t *layer_hint, const relay_msg_t *msg)
{
// TODO-329-TUNING: Temporarily validate legs here. We can remove
// this after tuning is complete.
circuit_mark_for_close(in_circ, END_CIRC_REASON_INTERNAL);
return false;
} else {
- conflux_cell_t *c_cell = tor_malloc_zero(sizeof(conflux_cell_t));
- c_cell->seq = leg->last_seq_recv;
-
- memcpy(&c_cell->cell, cell, sizeof(cell_t));
+ conflux_msg_t *c_msg = tor_malloc_zero(sizeof(conflux_msg_t));
+ c_msg->seq = leg->last_seq_recv;
+ /* Notice the copy here. Reason is that we don't have ownership of the
+ * message. If we wanted to pull that off, we would need to change the
+ * whole calling stack and unit tests on either not touching it after this
+ * function indicates that it has taken it or never allocate it from the
+ * stack. This is simpler and less error prone but might show up in our
+ * profile (maybe?). The Maze is serious. It needs to be respected. */
+ c_msg->msg = relay_msg_copy(msg);
smartlist_pqueue_add(cfx->ooo_q, conflux_queue_cmp,
- offsetof(conflux_cell_t, heap_idx), c_cell);
- total_ooo_q_bytes += sizeof(cell_t);
+ offsetof(conflux_msg_t, heap_idx), c_msg);
+ total_ooo_q_bytes += sizeof(msg->length);
/* This cell should not be processed yet, and the queue is not ready
* to process because the next absolute seqnum has not yet arrived */
* Returns the cell as a conflux_cell_t, or NULL if the queue is empty
* or has a hole.
*/
-conflux_cell_t *
-conflux_dequeue_cell(conflux_t *cfx)
+conflux_msg_t *
+conflux_dequeue_relay_msg(conflux_t *cfx)
{
- conflux_cell_t *top = NULL;
+ conflux_msg_t *top = NULL;
if (smartlist_len(cfx->ooo_q) == 0)
return NULL;
* pop and return it. */
if (top->seq == cfx->last_seq_delivered+1) {
smartlist_pqueue_pop(cfx->ooo_q, conflux_queue_cmp,
- offsetof(conflux_cell_t, heap_idx));
- total_ooo_q_bytes -= sizeof(cell_t);
+ offsetof(conflux_msg_t, heap_idx));
+ total_ooo_q_bytes -= sizeof(top->msg->length);
cfx->last_seq_delivered++;
return top;
} else {
return NULL;
}
}
+
+/** Free a given conflux msg object. */
+void
+conflux_relay_msg_free(conflux_msg_t *msg)
+{
+ if (msg) {
+ relay_msg_free(msg->msg);
+ tor_free(msg);
+ }
+}
#include "core/or/circuit_st.h"
#include "core/or/conflux_st.h"
+#include "core/or/relay_msg_st.h"
typedef struct conflux_t conflux_t;
typedef struct conflux_leg_t conflux_leg_t;
/** Helper: Return the number of legs a conflux object has. */
#define CONFLUX_NUM_LEGS(cfx) (smartlist_len(cfx->legs))
-/** A cell for the out-of-order queue.
- * XXX: Consider trying to use packed_cell_t instead here? */
+/** A relay message for the out-of-order queue. */
typedef struct {
/**
* Absolute sequence number of this cell, computed from the
*/
int heap_idx;
- /** The cell here is always guaranteed to have removed its
+ /** The relay message here is always guaranteed to have removed its
* extra conflux sequence number, for ease of processing */
- cell_t cell;
-} conflux_cell_t;
+ relay_msg_t *msg;
+} conflux_msg_t;
size_t conflux_handle_oom(size_t bytes_to_remove);
uint64_t conflux_get_total_bytes_allocation(void);
circuit_t *conflux_decide_next_circ(conflux_t *cfx);
int conflux_process_switch_command(circuit_t *in_circ,
- crypt_path_t *layer_hint, cell_t *cell,
- relay_header_t *rh);
+ crypt_path_t *layer_hint,
+ const relay_msg_t *msg);
bool conflux_should_multiplex(int relay_command);
-bool conflux_process_cell(conflux_t *cfx, circuit_t *in_circ,
- crypt_path_t *layer_hint,
- cell_t *cell);
-conflux_cell_t *conflux_dequeue_cell(conflux_t *cfx);
+bool conflux_process_relay_msg(conflux_t *cfx, circuit_t *in_circ,
+ crypt_path_t *layer_hint,
+ const relay_msg_t *msg);
+conflux_msg_t *conflux_dequeue_relay_msg(conflux_t *cfx);
void conflux_note_cell_sent(conflux_t *cfx, circuit_t *circ,
uint8_t relay_command);
+void conflux_relay_msg_free(conflux_msg_t *msg);
/* Private section starts. */
#ifdef TOR_CONFLUX_PRIVATE
}
conflux_cell_link_t *
-conflux_cell_parse_link(const cell_t *cell, const uint16_t cell_len)
+conflux_cell_parse_link(const relay_msg_t *msg)
{
conflux_cell_link_t *link = NULL;
trn_cell_conflux_link_t *trn_cell = NULL;
- tor_assert(cell);
+ tor_assert(msg);
- if (trn_cell_conflux_link_parse(&trn_cell,
- cell->payload + RELAY_HEADER_SIZE,
- cell_len) < 0) {
+ if (trn_cell_conflux_link_parse(&trn_cell, msg->body, msg->length) < 0) {
log_fn(LOG_PROTOCOL_WARN, LD_CIRC,
"Unable to parse CONFLUX_LINK cell.");
goto end;
}
conflux_cell_link_t *
-conflux_cell_parse_linked(const cell_t *cell, const uint16_t cell_len)
+conflux_cell_parse_linked(const relay_msg_t *msg)
{
/* At the moment, same exact payload so avoid code duplication. */
- return conflux_cell_parse_link(cell, cell_len);
+ return conflux_cell_parse_link(msg);
}
conflux_cell_link_t *
* Extracts the sequence number from a switch cell.
*/
uint32_t
-conflux_cell_parse_switch(const cell_t *cell, uint16_t rh_len)
+conflux_cell_parse_switch(const relay_msg_t *msg)
{
uint32_t seq = 0;
trn_cell_conflux_switch_t *switch_cell = NULL;
- tor_assert(cell);
+
+ tor_assert(msg);
if (trn_cell_conflux_switch_parse(&switch_cell,
- cell->payload + RELAY_HEADER_SIZE,
- rh_len) < 0) {
+ msg->body, msg->length) < 0) {
log_warn(LD_BUG, "Failed to parse switch cell");
// Zero counts as a failure to the validation, since legs should
// not switch after 0 cells.
#define TOR_CONFLUX_CELL_H
#include "core/or/or.h"
+#include "core/or/relay_msg_st.h"
typedef struct conflux_cell_link_t {
uint8_t version;
uint64_t last_recv,
uint8_t ux);
-conflux_cell_link_t *conflux_cell_parse_link(const cell_t *cell,
- const uint16_t cell_len);
-conflux_cell_link_t *conflux_cell_parse_linked(const cell_t *cell,
- const uint16_t cell_le);
-uint32_t conflux_cell_parse_switch(const cell_t *cell,
- const uint16_t rh_len);
+conflux_cell_link_t *conflux_cell_parse_link(const relay_msg_t *msg);
+conflux_cell_link_t *conflux_cell_parse_linked(const relay_msg_t *msg);
+uint32_t conflux_cell_parse_switch(const relay_msg_t *msg);
bool conflux_cell_send_link(const conflux_cell_link_t *link,
origin_circuit_t *circ);
} SMARTLIST_FOREACH_END(leg);
smartlist_free(cfx->legs);
- SMARTLIST_FOREACH(cfx->ooo_q, conflux_cell_t *, cell, tor_free(cell));
+ SMARTLIST_FOREACH(cfx->ooo_q, conflux_msg_t *, cell, tor_free(cell));
smartlist_free(cfx->ooo_q);
memwipe(cfx->nonce, 0, sizeof(cfx->nonce));
/** Process a CONFLUX_LINK cell which arrived on the given circuit. */
void
-conflux_process_link(circuit_t *circ, const cell_t *cell,
- const uint16_t cell_len)
+conflux_process_link(circuit_t *circ, const relay_msg_t *msg)
{
unlinked_circuits_t *unlinked = NULL;
conflux_cell_link_t *link = NULL;
tor_assert(circ);
- tor_assert(cell);
+ tor_assert(msg);
if (!conflux_is_enabled(circ)) {
circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
}
/* On errors, logging is emitted in this parsing function. */
- link = conflux_cell_parse_link(cell, cell_len);
+ link = conflux_cell_parse_link(msg);
if (!link) {
log_fn(LOG_PROTOCOL_WARN, LD_CIRC, "Unable to parse "
"CONFLUX_LINK cell. Closing circuit.");
/** Process a CONFLUX_LINKED cell which arrived on the given circuit. */
void
conflux_process_linked(circuit_t *circ, crypt_path_t *layer_hint,
- const cell_t *cell,
- const uint16_t cell_len)
+ const relay_msg_t *msg)
{
conflux_cell_link_t *link = NULL;
tor_assert_nonfatal(circ->purpose == CIRCUIT_PURPOSE_CONFLUX_UNLINKED);
/* On errors, logging is emitted in this parsing function. */
- link = conflux_cell_parse_link(cell, cell_len);
+ link = conflux_cell_parse_link(msg);
if (!link) {
goto close;
}
}
/* This cell is now considered valid for clients. */
- circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), cell_len);
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
goto end;
#define TOR_CONFLUX_POOL_H
#include "core/or/or.h"
+#include "core/or/relay_msg_st.h"
void conflux_pool_init(void);
void conflux_notify_shutdown(void);
void conflux_circuit_has_opened(origin_circuit_t *orig_circ);
void conflux_circuit_about_to_free(circuit_t *circ);
-void conflux_process_link(circuit_t *circ, const cell_t *cell,
- const uint16_t cell_len);
+void conflux_process_link(circuit_t *circ, const relay_msg_t *msg);
void conflux_process_linked(circuit_t *circ, crypt_path_t *layer_hint,
- const cell_t *cell, const uint16_t cell_len);
+ const relay_msg_t *msg);
void conflux_process_linked_ack(circuit_t *circ);
typedef struct conflux_t conflux_t;
*/
bool
circuit_process_stream_xoff(edge_connection_t *conn,
- const crypt_path_t *layer_hint,
- const cell_t *cell)
+ const crypt_path_t *layer_hint)
{
- (void)cell;
bool retval = true;
if (BUG(!conn)) {
bool
circuit_process_stream_xon(edge_connection_t *conn,
const crypt_path_t *layer_hint,
- const cell_t *cell)
+ const relay_msg_t *msg)
{
xon_cell_t *xon;
bool retval = true;
return false;
}
- if (xon_cell_parse(&xon, cell->payload+RELAY_HEADER_SIZE,
- CELL_PAYLOAD_SIZE-RELAY_HEADER_SIZE) < 0) {
+ if (xon_cell_parse(&xon, msg->body, msg->length) < 0) {
log_fn(LOG_PROTOCOL_WARN, LD_EDGE,
"Received malformed XON cell.");
return false;
#include "core/or/circuit_st.h"
#include "core/or/edge_connection_st.h"
+struct relay_msg_t;
+
void flow_control_new_consensus_params(const struct networkstatus_t *);
bool circuit_process_stream_xoff(edge_connection_t *conn,
- const crypt_path_t *layer_hint,
- const cell_t *cell);
+ const crypt_path_t *layer_hint);
bool circuit_process_stream_xon(edge_connection_t *conn,
const crypt_path_t *layer_hint,
- const cell_t *cell);
+ const struct relay_msg_t *msg);
int flow_control_decide_xoff(edge_connection_t *stream);
void flow_control_decide_xon(edge_connection_t *stream, size_t n_written);
* we don't.
**/
STATIC int
-begin_cell_parse(const cell_t *cell, begin_cell_t *bcell,
+begin_cell_parse(const relay_msg_t *msg, begin_cell_t *bcell,
uint8_t *end_reason_out)
{
- relay_header_t rh;
const uint8_t *body, *nul;
memset(bcell, 0, sizeof(*bcell));
*end_reason_out = END_STREAM_REASON_MISC;
- relay_header_unpack(&rh, cell->payload);
- if (rh.length > RELAY_PAYLOAD_SIZE) {
- return -2; /*XXXX why not TORPROTOCOL? */
- }
-
- bcell->stream_id = rh.stream_id;
+ bcell->stream_id = msg->stream_id;
- if (rh.command == RELAY_COMMAND_BEGIN_DIR) {
+ if (msg->command == RELAY_COMMAND_BEGIN_DIR) {
bcell->is_begindir = 1;
return 0;
- } else if (rh.command != RELAY_COMMAND_BEGIN) {
- log_warn(LD_BUG, "Got an unexpected command %d", (int)rh.command);
+ } else if (msg->command != RELAY_COMMAND_BEGIN) {
+ log_warn(LD_BUG, "Got an unexpected command %u", msg->command);
*end_reason_out = END_STREAM_REASON_INTERNAL;
return -1;
}
- body = cell->payload + RELAY_HEADER_SIZE;
- nul = memchr(body, 0, rh.length);
+ body = msg->body;
+ nul = memchr(body, 0, msg->length);
if (! nul) {
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Relay begin cell has no \\0. Closing.");
*end_reason_out = END_STREAM_REASON_TORPROTOCOL;
return -1;
}
- if (body + rh.length >= nul + 4)
+ if (body + msg->length >= nul + 4)
bcell->flags = ntohl(get_uint32(nul+1));
return 0;
* Else return 0.
*/
int
-connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
+connection_exit_begin_conn(const relay_msg_t *msg, circuit_t *circ)
{
edge_connection_t *n_stream;
- relay_header_t rh;
char *address = NULL;
uint16_t port = 0;
or_circuit_t *or_circ = NULL;
layer_hint = origin_circ->cpath->prev;
}
- relay_header_unpack(&rh, cell->payload);
- if (rh.length > RELAY_PAYLOAD_SIZE)
- return -END_CIRC_REASON_TORPROTOCOL;
-
if (!server_mode(options) &&
circ->purpose != CIRCUIT_PURPOSE_S_REND_JOINED) {
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Relay begin cell at non-server. Closing.");
- relay_send_end_cell_from_edge(rh.stream_id, circ,
+ relay_send_end_cell_from_edge(msg->stream_id, circ,
END_STREAM_REASON_EXITPOLICY, NULL);
return 0;
}
- rv = begin_cell_parse(cell, &bcell, &end_reason);
+ rv = begin_cell_parse(msg, &bcell, &end_reason);
if (rv < -1) {
return -END_CIRC_REASON_TORPROTOCOL;
} else if (rv == -1) {
tor_free(bcell.address);
- relay_send_end_cell_from_edge(rh.stream_id, circ, end_reason, layer_hint);
+ relay_send_end_cell_from_edge(msg->stream_id, circ, end_reason,
+ layer_hint);
return 0;
}
safe_str(channel_describe_peer(or_circ->p_chan)),
client_chan ? "on first hop of circuit" :
"from unknown relay");
- relay_send_end_cell_from_edge(rh.stream_id, circ,
+ relay_send_end_cell_from_edge(msg->stream_id, circ,
client_chan ?
END_STREAM_REASON_TORPROTOCOL :
END_STREAM_REASON_MISC,
return 0;
}
}
- } else if (rh.command == RELAY_COMMAND_BEGIN_DIR) {
+ } else if (msg->command == RELAY_COMMAND_BEGIN_DIR) {
if (!directory_permits_begindir_requests(options) ||
circ->purpose != CIRCUIT_PURPOSE_OR) {
- relay_send_end_cell_from_edge(rh.stream_id, circ,
- END_STREAM_REASON_NOTDIRECTORY, layer_hint);
+ relay_send_end_cell_from_edge(msg->stream_id, circ,
+ END_STREAM_REASON_NOTDIRECTORY,
+ layer_hint);
return 0;
}
/* Make sure to get the 'real' address of the previous hop: the
* isn't "really" a connection here. But we
* need to set it to something nonzero. */
} else {
- log_warn(LD_BUG, "Got an unexpected command %d", (int)rh.command);
- relay_send_end_cell_from_edge(rh.stream_id, circ,
+ log_warn(LD_BUG, "Got an unexpected command %u", msg->command);
+ relay_send_end_cell_from_edge(msg->stream_id, circ,
END_STREAM_REASON_INTERNAL, layer_hint);
return 0;
}
/* If you don't want IPv4, I can't help. */
if (bcell.flags & BEGIN_FLAG_IPV4_NOT_OK) {
tor_free(address);
- relay_send_end_cell_from_edge(rh.stream_id, circ,
+ relay_send_end_cell_from_edge(msg->stream_id, circ,
END_STREAM_REASON_EXITPOLICY, layer_hint);
return 0;
}
n_stream->base_.purpose = EXIT_PURPOSE_CONNECT;
n_stream->begincell_flags = bcell.flags;
- n_stream->stream_id = rh.stream_id;
+ n_stream->stream_id = msg->stream_id;
n_stream->base_.port = port;
/* leave n_stream->s at -1, because it's not yet valid */
n_stream->package_window = STREAMWINDOW_START;
if (ret == 0) {
/* This was a valid cell. Count it as delivered + overhead. */
- circuit_read_valid_data(origin_circ, rh.length);
+ circuit_read_valid_data(origin_circ, msg->length);
}
return ret;
}
/* If we're hibernating or shutting down, we refuse to open new streams. */
if (we_are_hibernating()) {
- relay_send_end_cell_from_edge(rh.stream_id, circ,
+ relay_send_end_cell_from_edge(msg->stream_id, circ,
END_STREAM_REASON_HIBERNATING, NULL);
connection_free_(TO_CONN(n_stream));
return 0;
n_stream->on_circuit = circ;
- if (rh.command == RELAY_COMMAND_BEGIN_DIR) {
+ if (msg->command == RELAY_COMMAND_BEGIN_DIR) {
tor_addr_t tmp_addr;
tor_assert(or_circ);
if (or_circ->p_chan &&
case DOS_STREAM_DEFENSE_REFUSE_STREAM:
// we don't use END_STREAM_REASON_RESOURCELIMIT because it would make a
// client mark us as non-functional until they get a new consensus.
- relay_send_end_cell_from_edge(rh.stream_id, circ, END_STREAM_REASON_MISC,
- layer_hint);
+ relay_send_end_cell_from_edge(msg->stream_id, circ,
+ END_STREAM_REASON_MISC, layer_hint);
connection_free_(TO_CONN(n_stream));
return 0;
case DOS_STREAM_DEFENSE_CLOSE_CIRCUIT:
connection_exit_connect(n_stream);
return 0;
case -1: /* resolve failed */
- relay_send_end_cell_from_edge(rh.stream_id, circ,
+ relay_send_end_cell_from_edge(msg->stream_id, circ,
END_STREAM_REASON_RESOLVEFAILED, NULL);
/* n_stream got freed. don't touch it. */
break;
* Else return 0.
*/
int
-connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ)
+connection_exit_begin_resolve(const relay_msg_t *msg, or_circuit_t *circ)
{
edge_connection_t *dummy_conn;
- relay_header_t rh;
dos_stream_defense_type_t dos_defense_type;
assert_circuit_ok(TO_CIRCUIT(circ));
- relay_header_unpack(&rh, cell->payload);
- if (rh.length > RELAY_PAYLOAD_SIZE)
- return 0;
/* Note the RESOLVE stream as seen. */
rep_hist_note_exit_stream(RELAY_COMMAND_RESOLVE);
* the housekeeping in dns.c would get way more complicated.)
*/
dummy_conn = edge_connection_new(CONN_TYPE_EXIT, AF_INET);
- dummy_conn->stream_id = rh.stream_id;
- dummy_conn->base_.address = tor_strndup(
- (char*)cell->payload+RELAY_HEADER_SIZE,
- rh.length);
+ dummy_conn->stream_id = msg->stream_id;
+ dummy_conn->base_.address = tor_strndup((char *) msg->body, msg->length);
dummy_conn->base_.port = 0;
dummy_conn->base_.state = EXIT_CONN_STATE_RESOLVEFAILED;
dummy_conn->base_.purpose = EXIT_PURPOSE_RESOLVE;
#ifndef TOR_CONNECTION_EDGE_H
#define TOR_CONNECTION_EDGE_H
+#include "core/or/relay_msg_st.h"
+
#include "lib/testsupport/testsupport.h"
#include "lib/encoding/confline.h"
int ttl,
time_t expires);
-int connection_exit_begin_conn(cell_t *cell, circuit_t *circ);
-int connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ);
+int connection_exit_begin_conn(const relay_msg_t *msg, circuit_t *circ);
+int connection_exit_begin_resolve(const relay_msg_t *msg, or_circuit_t *circ);
void connection_exit_connect(edge_connection_t *conn);
int connection_edge_is_rendezvous_stream(const edge_connection_t *conn);
int connection_ap_can_use_exit(const entry_connection_t *conn,
unsigned is_begindir : 1;
} begin_cell_t;
-STATIC int begin_cell_parse(const cell_t *cell, begin_cell_t *bcell,
- uint8_t *end_reason_out);
+STATIC int begin_cell_parse(const relay_msg_t *msg, begin_cell_t *bcell,
+ uint8_t *end_reason_out);
STATIC int connected_cell_format_payload(uint8_t *payload_out,
const tor_addr_t *addr,
uint32_t ttl);
* types of relay cells, launching requests or transmitting data as needed.
**/
-#include "core/or/relay_cell.h"
+#include "lib/log/log.h"
#define RELAY_PRIVATE
#include "core/or/or.h"
#include "feature/client/addressmap.h"
#include "core/or/scheduler.h"
#include "feature/hs/hs_metrics.h"
#include "feature/stats/rephist.h"
+#include "core/or/relay_cell.h"
+#include "core/or/relay_msg.h"
#include "core/or/cell_st.h"
#include "core/or/cell_queue_st.h"
#include "core/or/conflux.h"
#include "core/or/conflux_util.h"
#include "core/or/conflux_pool.h"
+#include "core/or/relay_msg_st.h"
-static edge_connection_t *relay_lookup_conn(circuit_t *circ, cell_t *cell,
+static edge_connection_t *relay_lookup_conn(circuit_t *circ,
+ const relay_msg_t *msg,
cell_direction_t cell_direction,
crypt_path_t *layer_hint);
entry_connection_t *conn,
node_t *node,
const tor_addr_t *addr);
-static int connection_edge_process_ordered_relay_cell(cell_t *cell,
+static int connection_edge_process_ordered_relay_cell(const relay_msg_t *msg,
circuit_t *circ,
edge_connection_t *conn,
- crypt_path_t *layer_hint,
- relay_header_t *rh);
+ crypt_path_t *layer_hint);
static void set_block_state_for_streams(circuit_t *circ,
edge_connection_t *stream_list,
int block, streamid_t stream_id);
if (recognized) {
edge_connection_t *conn = NULL;
+ relay_cell_fmt_t format = relay_msg_get_format(circ, layer_hint);
/* Recognized cell, the cell digest has been updated, we'll record it for
* the SENDME if need be. */
sendme_record_received_cell_digest(circ, layer_hint);
+ cell->relay_cell_proto = format; // ????? TODO #41051.
+ // TODO #41051: This also doesn't need to copy!
+ relay_msg_t *msg = relay_msg_decode_cell(format, cell);
+
+ if (msg == NULL) {
+ log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+ "Received undecodable relay cell");
+ return -END_CIRC_REASON_TORPROTOCOL;
+ }
+
if (circ->purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING) {
- if (pathbias_check_probe_response(circ, cell) == -1) {
- pathbias_count_valid_cells(circ, cell);
+ if (pathbias_check_probe_response(circ, msg) == -1) {
+ pathbias_count_valid_cells(circ, msg);
}
/* We need to drop this cell no matter what to avoid code that expects
* a certain purpose (such as the hidserv code). */
+ relay_msg_free(msg);
return 0;
}
- conn = relay_lookup_conn(circ, cell, cell_direction, layer_hint);
+ conn = relay_lookup_conn(circ, msg, cell_direction, layer_hint);
if (cell_direction == CELL_DIRECTION_OUT) {
++stats_n_relay_cells_delivered;
log_debug(LD_OR,"Sending away from origin.");
- reason = connection_edge_process_relay_cell(cell, circ, conn, NULL);
+ reason = connection_edge_process_relay_cell(msg, circ, conn, NULL);
if (reason < 0) {
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"connection_edge_process_relay_cell (away from origin) "
"failed.");
+ relay_msg_free(msg);
return reason;
}
}
if (cell_direction == CELL_DIRECTION_IN) {
++stats_n_relay_cells_delivered;
log_debug(LD_OR,"Sending to origin.");
- reason = connection_edge_process_relay_cell(cell, circ, conn,
+ reason = connection_edge_process_relay_cell(msg, circ, conn,
layer_hint);
if (reason < 0) {
/* If a client is trying to connect to unknown hidden service port,
log_warn(LD_OR,
"connection_edge_process_relay_cell (at origin) failed.");
}
+ relay_msg_free(msg);
return reason;
}
}
+ relay_msg_free(msg);
return 0;
}
* attached to circ, return that conn, else return NULL.
*/
static edge_connection_t *
-relay_lookup_conn(circuit_t *circ, cell_t *cell,
+relay_lookup_conn(circuit_t *circ, const relay_msg_t *msg,
cell_direction_t cell_direction, crypt_path_t *layer_hint)
{
edge_connection_t *tmpconn;
- relay_header_t rh;
- relay_header_unpack(&rh, cell->payload);
-
- if (!rh.stream_id)
+ if (!msg->stream_id)
return NULL;
/* IN or OUT cells could have come from either direction, now
if (CIRCUIT_IS_ORIGIN(circ)) {
for (tmpconn = TO_ORIGIN_CIRCUIT(circ)->p_streams; tmpconn;
tmpconn=tmpconn->next_stream) {
- if (rh.stream_id == tmpconn->stream_id &&
+ if (msg->stream_id == tmpconn->stream_id &&
!tmpconn->base_.marked_for_close &&
edge_uses_cpath(tmpconn, layer_hint)) {
- log_debug(LD_APP,"found conn for stream %d.", rh.stream_id);
+ log_debug(LD_APP,"found conn for stream %d.", msg->stream_id);
return tmpconn;
}
}
} else {
for (tmpconn = TO_OR_CIRCUIT(circ)->n_streams; tmpconn;
tmpconn=tmpconn->next_stream) {
- if (rh.stream_id == tmpconn->stream_id &&
+ if (msg->stream_id == tmpconn->stream_id &&
!tmpconn->base_.marked_for_close) {
- log_debug(LD_EXIT,"found conn for stream %d.", rh.stream_id);
+ log_debug(LD_EXIT,"found conn for stream %d.", msg->stream_id);
if (cell_direction == CELL_DIRECTION_OUT ||
connection_edge_is_rendezvous_stream(tmpconn))
return tmpconn;
}
for (tmpconn = TO_OR_CIRCUIT(circ)->resolving_streams; tmpconn;
tmpconn=tmpconn->next_stream) {
- if (rh.stream_id == tmpconn->stream_id &&
+ if (msg->stream_id == tmpconn->stream_id &&
!tmpconn->base_.marked_for_close) {
- log_debug(LD_EXIT,"found conn for stream %d.", rh.stream_id);
+ log_debug(LD_EXIT,"found conn for stream %d.", msg->stream_id);
return tmpconn;
}
}
}
}
-/** When padding a cell with randomness, leave this many zeros after the
- * payload. */
-#define CELL_PADDING_GAP 4
-
/** Make a relay cell out of <b>relay_command</b> and <b>payload</b>, and send
* it onto the open circuit <b>circ</b>. <b>stream_id</b> is the ID on
* <b>circ</b> for the stream that's sending the relay cell, or 0 if it's a
/* XXXX NM Split this function into a separate versions per circuit type? */
tor_assert(circ);
- tor_assert(payload_len <= RELAY_PAYLOAD_SIZE);
- memset(&cell, 0, sizeof(cell_t));
+ {
+ relay_cell_fmt_t cell_format = relay_msg_get_format(circ, cpath_layer);
+ relay_msg_t msg;
+ tor_assert(payload_len <=
+ relay_cell_max_payload_size(cell_format, relay_command));
+
+ msg.relay_cell_proto = cell_format;
+ msg.command = relay_command;
+ msg.stream_id = stream_id;
+ msg.length = payload_len;
+ // This cast is mildly naughty, but ultimately harmless:
+ // There is no need to copy the payload here, so long as we don't
+ // free it.
+ msg.body = (uint8_t *) payload;
+
+ if (relay_msg_encode_cell(cell_format, &msg, &cell) < 0) {
+ // This already gave a BUG warning, so no need to log.
+ return -1;
+ }
+ }
+
cell.command = CELL_RELAY;
if (CIRCUIT_IS_ORIGIN(circ)) {
tor_assert(cpath_layer);
cell_direction = CELL_DIRECTION_IN;
}
- memset(&rh, 0, sizeof(rh));
- rh.command = relay_command;
- rh.stream_id = stream_id;
- rh.length = payload_len;
- relay_header_pack(cell.payload, &rh);
-
- if (payload_len)
- memcpy(cell.payload+RELAY_HEADER_SIZE, payload, payload_len);
-
- /* Add random padding to the cell if we can. */
- relay_cell_pad_payload(&cell, payload_len);
-
log_debug(LD_OR,"delivering %d cell %s.", relay_command,
cell_direction == CELL_DIRECTION_OUT ? "forward" : "backward");
*/
static int
connection_ap_process_end_not_open(
- relay_header_t *rh, cell_t *cell, origin_circuit_t *circ,
+ const relay_msg_t *msg, origin_circuit_t *circ,
entry_connection_t *conn, crypt_path_t *layer_hint)
{
node_t *exitrouter;
- int reason = *(cell->payload+RELAY_HEADER_SIZE);
+ int reason = get_uint8(msg->body);
int control_reason;
edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(conn);
(void) layer_hint; /* unused */
- if (rh->length > 0) {
+ if (msg->length > 0) {
if (reason == END_STREAM_REASON_TORPROTOCOL ||
reason == END_STREAM_REASON_DESTROY) {
/* Both of these reasons could mean a failed tag
}
/* This end cell is now valid. */
- circuit_read_valid_data(circ, rh->length);
+ circuit_read_valid_data(circ, msg->length);
- if (rh->length == 0) {
+ if (msg->length == 0) {
reason = END_STREAM_REASON_MISC;
}
case END_STREAM_REASON_EXITPOLICY: {
tor_addr_t addr;
tor_addr_make_unspec(&addr);
- if (rh->length >= 5) {
+ if (msg->length >= 5) {
int ttl = -1;
tor_addr_make_unspec(&addr);
- if (rh->length == 5 || rh->length == 9) {
- tor_addr_from_ipv4n(&addr,
- get_uint32(cell->payload+RELAY_HEADER_SIZE+1));
- if (rh->length == 9)
- ttl = (int)ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE+5));
- } else if (rh->length == 17 || rh->length == 21) {
- tor_addr_from_ipv6_bytes(&addr,
- (cell->payload+RELAY_HEADER_SIZE+1));
- if (rh->length == 21)
- ttl = (int)ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE+17));
+ if (msg->length == 5 || msg->length == 9) {
+ tor_addr_from_ipv4n(&addr, get_uint32(msg->body + 1));
+ if (msg->length == 9)
+ ttl = (int)ntohl(get_uint32(msg->body + 5));
+ } else if (msg->length == 17 || msg->length == 21) {
+ tor_addr_from_ipv6_bytes(&addr, msg->body + 1);
+ if (msg->length == 21)
+ ttl = (int)ntohl(get_uint32(msg->body + 17));
}
if (tor_addr_is_null(&addr)) {
log_info(LD_APP,"Address '%s' resolved to 0.0.0.0. Closing,",
log_info(LD_APP,
"Edge got end (%s) before we're connected. Marking for close.",
- stream_end_reason_to_string(rh->length > 0 ? reason : -1));
+ stream_end_reason_to_string(msg->length > 0 ? reason : -1));
circuit_log_path(LOG_INFO,LD_APP,circ);
/* need to test because of detach_retriable */
if (!ENTRY_TO_CONN(conn)->marked_for_close)
* connection), and that the ttl can be absent (in which case <b>ttl_out</b>
* is set to -1). */
STATIC int
-connected_cell_parse(const relay_header_t *rh, const cell_t *cell,
- tor_addr_t *addr_out, int *ttl_out)
+connected_cell_parse(const relay_msg_t *msg, tor_addr_t *addr_out,
+ int *ttl_out)
{
uint32_t bytes;
- const uint8_t *payload = cell->payload + RELAY_HEADER_SIZE;
+ const uint8_t *payload = msg->body;
tor_addr_make_unspec(addr_out);
*ttl_out = -1;
- if (rh->length == 0)
+ if (msg->length == 0)
return 0;
- if (rh->length < 4)
+ if (msg->length < 4)
return -1;
bytes = ntohl(get_uint32(payload));
if (bytes != 0) {
/* v4 address */
tor_addr_from_ipv4h(addr_out, bytes);
- if (rh->length >= 8) {
+ if (msg->length >= 8) {
bytes = ntohl(get_uint32(payload + 4));
if (bytes <= INT32_MAX)
*ttl_out = bytes;
}
} else {
- if (rh->length < 25) /* 4 bytes of 0s, 1 addr, 16 ipv4, 4 ttl. */
+ if (msg->length < 25) /* 4 bytes of 0s, 1 addr, 16 ipv4, 4 ttl. */
return -1;
if (get_uint8(payload + 4) != 6)
return -1;
* one of 0, RESOLVED_TYPE_ERROR, or RESOLVED_TYPE_ERROR_TRANSIENT, and
* return 0. */
STATIC int
-resolved_cell_parse(const cell_t *cell, const relay_header_t *rh,
- smartlist_t *addresses_out, int *errcode_out)
+resolved_cell_parse(const relay_msg_t *msg, smartlist_t *addresses_out,
+ int *errcode_out)
{
const uint8_t *cp;
uint8_t answer_type;
int errcode = 0;
smartlist_t *addrs;
- tor_assert(cell);
- tor_assert(rh);
+ tor_assert(msg);
tor_assert(addresses_out);
tor_assert(errcode_out);
*errcode_out = 0;
- if (rh->length > RELAY_PAYLOAD_SIZE)
+ if (msg->length > RELAY_PAYLOAD_SIZE)
return -1;
addrs = smartlist_new();
- cp = cell->payload + RELAY_HEADER_SIZE;
+ cp = msg->body;
- remaining = rh->length;
+ remaining = msg->length;
while (remaining) {
const uint8_t *cp_orig = cp;
if (remaining < 2)
* stream. */
STATIC int
connection_edge_process_resolved_cell(edge_connection_t *conn,
- const cell_t *cell,
- const relay_header_t *rh)
+ const relay_msg_t *msg)
{
entry_connection_t *entry_conn = EDGE_TO_ENTRY_CONN(conn);
smartlist_t *resolved_addresses = NULL;
tor_assert(SOCKS_COMMAND_IS_RESOLVE(entry_conn->socks_request->command));
resolved_addresses = smartlist_new();
- if (resolved_cell_parse(cell, rh, resolved_addresses, &errcode)) {
+ if (resolved_cell_parse(msg, resolved_addresses, &errcode)) {
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Dropping malformed 'resolved' cell");
connection_mark_unattached_ap(entry_conn, END_STREAM_REASON_TORPROTOCOL);
/* This is valid data at this point. Count it */
if (conn->on_circuit && CIRCUIT_IS_ORIGIN(conn->on_circuit)) {
circuit_read_valid_data(TO_ORIGIN_CIRCUIT(conn->on_circuit),
- rh->length);
+ msg->length);
}
connection_ap_handshake_socks_got_resolved_cell(entry_conn,
*/
static int
connection_edge_process_relay_cell_not_open(
- relay_header_t *rh, cell_t *cell, circuit_t *circ,
+ const relay_msg_t *msg, circuit_t *circ,
edge_connection_t *conn, crypt_path_t *layer_hint)
{
- if (rh->command == RELAY_COMMAND_END) {
+ if (msg->command == RELAY_COMMAND_END) {
if (CIRCUIT_IS_ORIGIN(circ) && conn->base_.type == CONN_TYPE_AP) {
- return connection_ap_process_end_not_open(rh, cell,
+ return connection_ap_process_end_not_open(msg,
TO_ORIGIN_CIRCUIT(circ),
EDGE_TO_ENTRY_CONN(conn),
layer_hint);
} else {
/* we just got an 'end', don't need to send one */
conn->edge_has_sent_end = 1;
- conn->end_reason = *(cell->payload+RELAY_HEADER_SIZE) |
- END_STREAM_REASON_FLAG_REMOTE;
+ conn->end_reason = get_uint8(msg->body) | END_STREAM_REASON_FLAG_REMOTE;
connection_mark_for_close(TO_CONN(conn));
return 0;
}
}
if (conn->base_.type == CONN_TYPE_AP &&
- rh->command == RELAY_COMMAND_CONNECTED) {
+ msg->command == RELAY_COMMAND_CONNECTED) {
tor_addr_t addr;
int ttl;
entry_connection_t *entry_conn = EDGE_TO_ENTRY_CONN(conn);
log_info(LD_APP,"'connected' received for circid %u streamid %d "
"after %d seconds.",
(unsigned)circ->n_circ_id,
- rh->stream_id,
+ msg->stream_id,
(int)(time(NULL) - conn->base_.timestamp_last_read_allowed));
- if (connected_cell_parse(rh, cell, &addr, &ttl) < 0) {
+ if (connected_cell_parse(msg, &addr, &ttl) < 0) {
log_fn(LOG_PROTOCOL_WARN, LD_APP,
"Got a badly formatted connected cell. Closing.");
connection_edge_end(conn, END_STREAM_REASON_TORPROTOCOL);
}
/* This is valid data at this point. Count it */
- circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh->length);
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
/* handle anything that might have queued */
if (connection_edge_package_raw_inbuf(conn, 1, NULL) < 0) {
return 0;
}
if (conn->base_.type == CONN_TYPE_AP &&
- rh->command == RELAY_COMMAND_RESOLVED) {
- return connection_edge_process_resolved_cell(conn, cell, rh);
+ msg->command == RELAY_COMMAND_RESOLVED) {
+ return connection_edge_process_resolved_cell(conn, msg);
}
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Got an unexpected relay command %d, in state %d (%s). Dropping.",
- rh->command, conn->base_.state,
+ msg->command, conn->base_.state,
conn_state_to_string(conn->base_.type, conn->base_.state));
return 0; /* for forward compatibility, don't kill the circuit */
// connection_edge_end(conn, END_STREAM_REASON_TORPROTOCOL);
* Return 0 if everything went well or a negative value representing a circuit
* end reason on error for which the caller is responsible for closing it. */
static int
-process_sendme_cell(const relay_header_t *rh, const cell_t *cell,
- circuit_t *circ, edge_connection_t *conn,
- crypt_path_t *layer_hint, int domain)
+process_sendme_cell(const relay_msg_t *msg, circuit_t *circ,
+ edge_connection_t *conn, crypt_path_t *layer_hint,
+ int domain)
{
int ret;
- tor_assert(rh);
+ tor_assert(msg);
- if (!rh->stream_id) {
+ if (!msg->stream_id) {
/* Circuit level SENDME cell. */
- ret = sendme_process_circuit_level(layer_hint, circ,
- cell->payload + RELAY_HEADER_SIZE,
- rh->length);
+ ret = sendme_process_circuit_level(layer_hint, circ, msg->body,
+ msg->length);
if (ret < 0) {
return ret;
}
if (CIRCUIT_IS_ORIGIN(circ)) {
origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
if (connection_half_edge_is_valid_sendme(ocirc->half_streams,
- rh->stream_id)) {
- circuit_read_valid_data(ocirc, rh->length);
+ msg->stream_id)) {
+ circuit_read_valid_data(ocirc, msg->length);
log_info(domain, "Sendme cell on circ %u valid on half-closed "
"stream id %d",
- ocirc->global_identifier, rh->stream_id);
+ ocirc->global_identifier, msg->stream_id);
}
}
log_info(domain, "SENDME cell dropped, unknown stream (streamid %d).",
- rh->stream_id);
+ msg->stream_id);
return 0;
}
/* Stream level SENDME cell. */
// TODO: Turn this off for cc_alg=1,2,3; use XON/XOFF instead
- ret = sendme_process_stream_level(conn, circ, rh->length);
+ ret = sendme_process_stream_level(conn, circ, msg->length);
if (ret < 0) {
/* Means we need to close the circuit with reason ret. */
return ret;
* parent function.
*/
STATIC int
-handle_relay_cell_command(cell_t *cell, circuit_t *circ,
- edge_connection_t *conn, crypt_path_t *layer_hint,
- relay_header_t *rh, int optimistic_data)
+handle_relay_msg(const relay_msg_t *msg, circuit_t *circ,
+ edge_connection_t *conn, crypt_path_t *layer_hint,
+ int optimistic_data)
{
unsigned domain = layer_hint?LD_APP:LD_EXIT;
int reason;
- tor_assert(rh);
+ tor_assert(msg);
/* First pass the cell to the circuit padding subsystem, in case it's a
* padding cell or circuit that should be handled there. */
- if (circpad_check_received_cell(cell, circ, layer_hint, rh) == 0) {
+ if (circpad_check_received_cell(msg, circ, layer_hint) == 0) {
log_debug(domain, "Cell handled as circuit padding");
return 0;
}
/* Now handle all the other commands */
- switch (rh->command) {
+ switch (msg->command) {
case RELAY_COMMAND_CONFLUX_LINK:
- conflux_process_link(circ, cell, rh->length);
+ conflux_process_link(circ, msg);
return 0;
case RELAY_COMMAND_CONFLUX_LINKED:
- conflux_process_linked(circ, layer_hint, cell, rh->length);
+ conflux_process_linked(circ, layer_hint, msg);
return 0;
case RELAY_COMMAND_CONFLUX_LINKED_ACK:
conflux_process_linked_ack(circ);
return 0;
case RELAY_COMMAND_CONFLUX_SWITCH:
- return conflux_process_switch_command(circ, layer_hint, cell, rh);
+ return conflux_process_switch_command(circ, layer_hint, msg);
case RELAY_COMMAND_BEGIN:
case RELAY_COMMAND_BEGIN_DIR:
if (layer_hint &&
"Begin cell for known stream. Dropping.");
return 0;
}
- if (rh->command == RELAY_COMMAND_BEGIN_DIR &&
+ if (msg->command == RELAY_COMMAND_BEGIN_DIR &&
circ->purpose != CIRCUIT_PURPOSE_S_REND_JOINED) {
/* Assign this circuit and its app-ward OR connection a unique ID,
* so that we can measure download times. The local edge and dir
circ->dirreq_id = ++next_id;
TO_OR_CIRCUIT(circ)->p_chan->dirreq_id = circ->dirreq_id;
}
- return connection_exit_begin_conn(cell, circ);
+ return connection_exit_begin_conn(msg, circ);
case RELAY_COMMAND_DATA:
++stats_n_data_cells_received;
- if (rh->stream_id == 0) {
+ if (msg->stream_id == 0) {
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Relay data cell with zero "
"stream_id. Dropping.");
return 0;
if (CIRCUIT_IS_ORIGIN(circ)) {
origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
if (connection_half_edge_is_valid_data(ocirc->half_streams,
- rh->stream_id)) {
- circuit_read_valid_data(ocirc, rh->length);
+ msg->stream_id)) {
+ circuit_read_valid_data(ocirc, msg->length);
log_info(domain,
"data cell on circ %u valid on half-closed "
- "stream id %d", ocirc->global_identifier, rh->stream_id);
+ "stream id %d", ocirc->global_identifier, msg->stream_id);
}
}
log_info(domain,"data cell dropped, unknown stream (streamid %d).",
- rh->stream_id);
+ msg->stream_id);
return 0;
}
return -END_CIRC_REASON_TORPROTOCOL;
}
/* Total all valid application bytes delivered */
- if (CIRCUIT_IS_ORIGIN(circ) && rh->length > 0) {
- circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh->length);
+ if (CIRCUIT_IS_ORIGIN(circ) && msg->length > 0) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
}
/* For onion service connection, update the metrics. */
if (conn->hs_ident) {
hs_metrics_app_write_bytes(&conn->hs_ident->identity_pk,
conn->hs_ident->orig_virtual_port,
- rh->length);
+ msg->length);
}
- stats_n_data_bytes_received += rh->length;
- connection_buf_add((char*)(cell->payload + RELAY_HEADER_SIZE),
- rh->length, TO_CONN(conn));
+ stats_n_data_bytes_received += msg->length;
+ connection_buf_add((char*) msg->body, msg->length, TO_CONN(conn));
#ifdef MEASUREMENTS_21206
/* Count number of RELAY_DATA cells received on a linked directory
origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
if (relay_crypt_from_last_hop(ocirc, layer_hint) &&
connection_half_edge_is_valid_data(ocirc->half_streams,
- rh->stream_id)) {
- circuit_read_valid_data(ocirc, rh->length);
+ msg->stream_id)) {
+ circuit_read_valid_data(ocirc, msg->length);
}
}
return 0;
}
- if (circuit_process_stream_xoff(conn, layer_hint, cell)) {
+ if (circuit_process_stream_xoff(conn, layer_hint)) {
if (CIRCUIT_IS_ORIGIN(circ)) {
- circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh->length);
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
}
}
return 0;
origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
if (relay_crypt_from_last_hop(ocirc, layer_hint) &&
connection_half_edge_is_valid_data(ocirc->half_streams,
- rh->stream_id)) {
- circuit_read_valid_data(ocirc, rh->length);
+ msg->stream_id)) {
+ circuit_read_valid_data(ocirc, msg->length);
}
}
return 0;
}
- if (circuit_process_stream_xon(conn, layer_hint, cell)) {
+ if (circuit_process_stream_xon(conn, layer_hint, msg)) {
if (CIRCUIT_IS_ORIGIN(circ)) {
- circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh->length);
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
}
}
return 0;
case RELAY_COMMAND_END:
- reason = rh->length > 0 ?
- get_uint8(cell->payload+RELAY_HEADER_SIZE) : END_STREAM_REASON_MISC;
+ reason = msg->length > 0 ? get_uint8(msg->body) : END_STREAM_REASON_MISC;
if (!conn) {
if (CIRCUIT_IS_ORIGIN(circ)) {
origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
if (relay_crypt_from_last_hop(ocirc, layer_hint) &&
connection_half_edge_is_valid_end(ocirc->half_streams,
- rh->stream_id)) {
+ msg->stream_id)) {
- circuit_read_valid_data(ocirc, rh->length);
+ circuit_read_valid_data(ocirc, msg->length);
log_info(domain,
"end cell (%s) on circ %u valid on half-closed "
"stream id %d",
stream_end_reason_to_string(reason),
- ocirc->global_identifier, rh->stream_id);
+ ocirc->global_identifier, msg->stream_id);
return 0;
}
}
/* Total all valid application bytes delivered */
if (CIRCUIT_IS_ORIGIN(circ)) {
- circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh->length);
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
}
}
return 0;
case RELAY_COMMAND_EXTEND2: {
static uint64_t total_n_extend=0, total_nonearly=0;
total_n_extend++;
- if (rh->stream_id) {
+ if (msg->stream_id) {
log_fn(LOG_PROTOCOL_WARN, domain,
"'extend' cell received for non-zero stream. Dropping.");
return 0;
}
- if (cell->command != CELL_RELAY_EARLY &&
+ if (!msg->is_relay_early &&
!networkstatus_get_param(NULL,"AllowNonearlyExtend",0,0,1)) {
#define EARLY_WARNING_INTERVAL 3600
static ratelim_t early_warning_limit =
RATELIM_INIT(EARLY_WARNING_INTERVAL);
char *m;
- if (cell->command == CELL_RELAY) {
+ if (!msg->is_relay_early) {
++total_nonearly;
if ((m = rate_limit_log(&early_warning_limit, approx_time()))) {
double percentage = ((double)total_nonearly)/total_n_extend;
} else {
log_fn(LOG_WARN, domain,
"EXTEND cell received, in a cell with type %d! Dropping.",
- cell->command);
+ msg->command);
}
return 0;
}
- return circuit_extend(cell, circ);
+ return circuit_extend(msg, circ);
}
case RELAY_COMMAND_EXTENDED:
case RELAY_COMMAND_EXTENDED2:
log_debug(domain,"Got an extended cell! Yay.");
{
extended_cell_t extended_cell;
- if (extended_cell_parse(&extended_cell, rh->command,
- (const uint8_t*)cell->payload+RELAY_HEADER_SIZE,
- rh->length)<0) {
+ if (extended_cell_parse(&extended_cell, msg->command,
+ msg->body, msg->length) < 0) {
log_warn(LD_PROTOCOL,
"Can't parse EXTENDED cell; killing circuit.");
return -END_CIRC_REASON_TORPROTOCOL;
}
/* Total all valid bytes delivered. */
if (CIRCUIT_IS_ORIGIN(circ)) {
- circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh->length);
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
}
return 0;
case RELAY_COMMAND_TRUNCATE:
circuit_set_state(circ, CIRCUIT_STATE_OPEN);
}
if (circ->n_chan) {
- uint8_t trunc_reason = get_uint8(cell->payload + RELAY_HEADER_SIZE);
+ uint8_t trunc_reason = get_uint8(msg->body);
circuit_synchronize_written_or_bandwidth(circ, CIRCUIT_N_CHAN);
circuit_clear_cell_queue(circ, circ->n_chan);
channel_send_destroy(circ->n_circ_id, circ->n_chan,
/* Count the truncated as valid, for completeness. The
* circuit is being torn down anyway, though. */
if (CIRCUIT_IS_ORIGIN(circ)) {
- circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ),
- rh->length);
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
}
- circuit_truncated(TO_ORIGIN_CIRCUIT(circ),
- get_uint8(cell->payload + RELAY_HEADER_SIZE));
+ circuit_truncated(TO_ORIGIN_CIRCUIT(circ), get_uint8(msg->body));
return 0;
case RELAY_COMMAND_CONNECTED:
if (conn) {
if (CIRCUIT_IS_ORIGIN(circ)) {
origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
if (connection_half_edge_is_valid_connected(ocirc->half_streams,
- rh->stream_id)) {
- circuit_read_valid_data(ocirc, rh->length);
+ msg->stream_id)) {
+ circuit_read_valid_data(ocirc, msg->length);
log_info(domain,
"connected cell on circ %u valid on half-closed "
- "stream id %d", ocirc->global_identifier, rh->stream_id);
+ "stream id %d", ocirc->global_identifier, msg->stream_id);
return 0;
}
}
log_info(domain,
"'connected' received on circid %u for streamid %d, "
"no conn attached anymore. Ignoring.",
- (unsigned)circ->n_circ_id, rh->stream_id);
+ (unsigned)circ->n_circ_id, msg->stream_id);
return 0;
case RELAY_COMMAND_SENDME:
- return process_sendme_cell(rh, cell, circ, conn, layer_hint, domain);
+ return process_sendme_cell(msg, circ, conn, layer_hint, domain);
case RELAY_COMMAND_RESOLVE:
if (layer_hint) {
log_fn(LOG_PROTOCOL_WARN, LD_APP,
circ->purpose);
return 0;
}
- return connection_exit_begin_resolve(cell, TO_OR_CIRCUIT(circ));
+ return connection_exit_begin_resolve(msg, TO_OR_CIRCUIT(circ));
case RELAY_COMMAND_RESOLVED:
if (conn) {
log_fn(LOG_PROTOCOL_WARN, domain,
origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
if (relay_crypt_from_last_hop(ocirc, layer_hint) &&
connection_half_edge_is_valid_resolved(ocirc->half_streams,
- rh->stream_id)) {
- circuit_read_valid_data(ocirc, rh->length);
+ msg->stream_id)) {
+ circuit_read_valid_data(ocirc, msg->length);
log_info(domain,
"resolved cell on circ %u valid on half-closed "
- "stream id %d", ocirc->global_identifier, rh->stream_id);
+ "stream id %d", ocirc->global_identifier, msg->stream_id);
return 0;
}
}
case RELAY_COMMAND_INTRO_ESTABLISHED:
case RELAY_COMMAND_RENDEZVOUS_ESTABLISHED:
rend_process_relay_cell(circ, layer_hint,
- rh->command, rh->length,
- cell->payload+RELAY_HEADER_SIZE);
+ msg->command, msg->length, msg->body);
return 0;
}
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Received unknown relay command %d. Perhaps the other side is using "
"a newer version of Tor? Dropping.",
- rh->command);
+ msg->command);
return 0; /* for forward compatibility, don't kill the circuit */
}
* Return -reason if you want to warn and tear down the circuit, else 0.
*/
STATIC int
-connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
+connection_edge_process_relay_cell(const relay_msg_t *msg, circuit_t *circ,
edge_connection_t *conn,
crypt_path_t *layer_hint)
{
static int num_seen=0;
- relay_header_t rh;
unsigned domain = layer_hint?LD_APP:LD_EXIT;
- tor_assert(cell);
+ tor_assert(msg);
tor_assert(circ);
- relay_header_unpack(&rh, cell->payload);
// log_fn(LOG_DEBUG,"command %d stream %d", rh.command, rh.stream_id);
num_seen++;
log_debug(domain, "Now seen %d relay cells here (command %d, stream %d).",
- num_seen, rh.command, rh.stream_id);
-
- if (rh.length > RELAY_PAYLOAD_SIZE) {
- log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
- "Relay cell length field too long. Closing circuit.");
- return - END_CIRC_REASON_TORPROTOCOL;
- }
+ num_seen, msg->command, msg->stream_id);
- if (rh.stream_id == 0) {
- switch (rh.command) {
+ if (msg->stream_id == 0) {
+ switch (msg->command) {
case RELAY_COMMAND_BEGIN:
case RELAY_COMMAND_CONNECTED:
case RELAY_COMMAND_END:
case RELAY_COMMAND_RESOLVE:
case RELAY_COMMAND_RESOLVED:
case RELAY_COMMAND_BEGIN_DIR:
- log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Relay command %d with zero "
- "stream_id. Dropping.", (int)rh.command);
+ log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Relay command %u with zero "
+ "stream_id. Dropping.", msg->command);
return 0;
default:
;
/* Regardless of conflux or not, we always decide to send a SENDME
* for RELAY_DATA immediately
*/
- if (rh.command == RELAY_COMMAND_DATA) {
+ if (msg->command == RELAY_COMMAND_DATA) {
/* Update our circuit-level deliver window that we received a DATA cell.
* If the deliver window goes below 0, we end the circuit and stream due
* to a protocol failure. */
* queues, and if doing so results in ordered cells to deliver, we
* dequeue and process those in-order until there are no more.
*/
- if (!circ->conflux || !conflux_should_multiplex(rh.command)) {
- return connection_edge_process_ordered_relay_cell(cell, circ, conn,
- layer_hint, &rh);
+ if (!circ->conflux || !conflux_should_multiplex(msg->command)) {
+ return connection_edge_process_ordered_relay_cell(msg, circ, conn,
+ layer_hint);
} else {
// If conflux says this cell is in-order, then begin processing
// cells from queue until there are none. Otherwise, we do nothing
// until further cells arrive.
- if (conflux_process_cell(circ->conflux, circ, layer_hint, cell)) {
- conflux_cell_t *c_cell = NULL;
+ if (conflux_process_relay_msg(circ->conflux, circ, layer_hint,
+ (relay_msg_t *) msg)) {
+ conflux_msg_t *c_msg = NULL;
int ret = 0;
/* First, process this cell */
- if ((ret = connection_edge_process_ordered_relay_cell(cell, circ, conn,
- layer_hint, &rh)) < 0) {
+ if ((ret = connection_edge_process_ordered_relay_cell(msg, circ,
+ conn,
+ layer_hint) < 0)) {
return ret;
}
/* Now, check queue for more */
- while ((c_cell = conflux_dequeue_cell(circ->conflux))) {
- relay_header_unpack(&rh, c_cell->cell.payload);
- conn = relay_lookup_conn(circ, &c_cell->cell, CELL_DIRECTION_OUT,
+ while ((c_msg = conflux_dequeue_relay_msg(circ->conflux))) {
+ conn = relay_lookup_conn(circ, c_msg->msg, CELL_DIRECTION_OUT,
layer_hint);
- if ((ret = connection_edge_process_ordered_relay_cell(&c_cell->cell,
- circ, conn, layer_hint,
- &rh)) < 0) {
+ if ((ret =
+ connection_edge_process_ordered_relay_cell(c_msg->msg, circ,
+ conn,
+ layer_hint)) < 0) {
/* Negative return value is a fatal error. Return early and tear down
* circuit */
- tor_free(c_cell);
+ conflux_relay_msg_free(c_msg);
return ret;
}
- tor_free(c_cell);
+ conflux_relay_msg_free(c_msg);
}
}
}
* Helper function to process a relay cell that is in the proper order
* for processing right now. */
static int
-connection_edge_process_ordered_relay_cell(cell_t *cell, circuit_t *circ,
+connection_edge_process_ordered_relay_cell(const relay_msg_t *msg,
+ circuit_t *circ,
edge_connection_t *conn,
- crypt_path_t *layer_hint,
- relay_header_t *rh)
+ crypt_path_t *layer_hint)
{
int optimistic_data = 0; /* Set to 1 if we receive data on a stream
* that's in the EXIT_CONN_STATE_RESOLVING
* or EXIT_CONN_STATE_CONNECTING states. */
/* Tell circpad that we've received a recognized cell */
- circpad_deliver_recognized_relay_cell_events(circ, rh->command, layer_hint);
+ circpad_deliver_recognized_relay_cell_events(circ, msg->command, layer_hint);
/* either conn is NULL, in which case we've got a control cell, or else
* conn points to the recognized stream. */
if (conn->base_.type == CONN_TYPE_EXIT &&
(conn->base_.state == EXIT_CONN_STATE_CONNECTING ||
conn->base_.state == EXIT_CONN_STATE_RESOLVING) &&
- rh->command == RELAY_COMMAND_DATA) {
+ msg->command == RELAY_COMMAND_DATA) {
/* Allow DATA cells to be delivered to an exit node in state
* EXIT_CONN_STATE_CONNECTING or EXIT_CONN_STATE_RESOLVING.
* This speeds up HTTP, for example. */
optimistic_data = 1;
- } else if (rh->stream_id == 0 && rh->command == RELAY_COMMAND_DATA) {
+ } else if (msg->stream_id == 0 && msg->command == RELAY_COMMAND_DATA) {
log_warn(LD_BUG, "Somehow I had a connection that matched a "
"data cell with stream ID 0.");
} else {
return connection_edge_process_relay_cell_not_open(
- rh, cell, circ, conn, layer_hint);
+ msg, circ, conn, layer_hint);
}
}
- return handle_relay_cell_command(cell, circ, conn, layer_hint,
- rh, optimistic_data);
+ return handle_relay_msg(msg, circ, conn, layer_hint, optimistic_data);
}
/** How many relay_data cells have we built, ever? */
crypto_fast_rng_get_uint(get_thread_fast_rng(), CIRCWINDOW_INCREMENT / 2);
}
-/**
- * Any relay data payload containing fewer than this many real bytes is
- * considered to have enough randomness to.
- **/
-#define RELAY_PAYLOAD_LENGTH_FOR_RANDOM_SENDMES \
- (RELAY_PAYLOAD_SIZE - CELL_PADDING_GAP - 16)
-
/**
* Helper. Return the number of bytes that should be put into a cell from a
* given edge connection on which <b>n_available</b> bytes are available.
STATIC size_t
connection_edge_get_inbuf_bytes_to_package(size_t n_available,
int package_partial,
- circuit_t *on_circuit)
+ circuit_t *on_circuit,
+ crypt_path_t *cpath)
{
if (!n_available)
return 0;
(on_circuit->send_randomness_after_n_cells == 0) &&
(! on_circuit->have_sent_sufficiently_random_cell);
- /* At most how much would we like to send in this cell? */
- size_t target_length;
+ relay_cell_fmt_t cell_format = relay_msg_get_format(on_circuit, cpath);
+ size_t target_length =
+ relay_cell_max_payload_size(cell_format, RELAY_COMMAND_DATA);
+
+#define RELAY_CELL_PADDING_GAP 4
+
+ /* Any relay data payload containing fewer than this many real bytes is
+ * considered to have enough randomness to. */
+ size_t target_length_with_random = target_length -
+ RELAY_CELL_PADDING_GAP - 16;
if (force_random_bytes) {
- target_length = RELAY_PAYLOAD_LENGTH_FOR_RANDOM_SENDMES;
- } else {
- target_length = RELAY_PAYLOAD_SIZE;
+ target_length = target_length_with_random;
}
/* Decide how many bytes we will actually put into this cell. */
/* If we reach this point, we will be definitely sending the cell. */
tor_assert_nonfatal(package_length > 0);
- if (package_length <= RELAY_PAYLOAD_LENGTH_FOR_RANDOM_SENDMES) {
+ if (package_length <= target_length_with_random) {
/* This cell will have enough randomness in the padding to make a future
* sendme cell unpredictable. */
on_circuit->have_sent_sufficiently_random_cell = 1;
}
length = connection_edge_get_inbuf_bytes_to_package(bytes_to_process,
- package_partial, circ);
+ package_partial, circ,
+ cpath_layer);
if (!length)
return 0;
#ifndef TOR_RELAY_H
#define TOR_RELAY_H
+#include "core/or/relay_msg_st.h"
+
extern uint64_t stats_n_relay_cells_relayed;
extern uint64_t stats_n_relay_cells_delivered;
extern uint64_t stats_n_circ_max_cell_reached;
#ifdef RELAY_PRIVATE
STATIC int
-handle_relay_cell_command(cell_t *cell, circuit_t *circ,
- edge_connection_t *conn, crypt_path_t *layer_hint,
- relay_header_t *rh, int optimistic_data);
+handle_relay_msg(const relay_msg_t *msg, circuit_t *circ,
+ edge_connection_t *conn, crypt_path_t *layer_hint,
+ int optimistic_data);
-STATIC int connected_cell_parse(const relay_header_t *rh, const cell_t *cell,
- tor_addr_t *addr_out, int *ttl_out);
+STATIC int connected_cell_parse(const relay_msg_t *msg, tor_addr_t *addr_out,
+ int *ttl_out);
/** An address-and-ttl tuple as yielded by resolved_cell_parse */
typedef struct address_ttl_t {
tor_addr_t addr;
STATIC void address_ttl_free_(address_ttl_t *addr);
#define address_ttl_free(addr) \
FREE_AND_NULL(address_ttl_t, address_ttl_free_, (addr))
-STATIC int resolved_cell_parse(const cell_t *cell, const relay_header_t *rh,
+STATIC int resolved_cell_parse(const relay_msg_t *msg,
smartlist_t *addresses_out, int *errcode_out);
STATIC int connection_edge_process_resolved_cell(edge_connection_t *conn,
- const cell_t *cell,
- const relay_header_t *rh);
+ const relay_msg_t *msg);
STATIC packed_cell_t *packed_cell_new(void);
STATIC packed_cell_t *cell_queue_pop(cell_queue_t *queue);
STATIC destroy_cell_t *destroy_cell_queue_pop(destroy_cell_queue_t *queue);
STATIC int cell_queues_check_size(void);
-STATIC int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
- edge_connection_t *conn,
- crypt_path_t *layer_hint);
+STATIC int connection_edge_process_relay_cell(const relay_msg_t *msg,
+ circuit_t *circ,
+ edge_connection_t *conn,
+ crypt_path_t *layer_hint);
STATIC size_t connection_edge_get_inbuf_bytes_to_package(size_t n_available,
int package_partial,
- circuit_t *on_circuit);
+ circuit_t *on_circuit,
+ crypt_path_t *cpath);
#endif /* defined(RELAY_PRIVATE) */
relay_cell_fmt_t relay_msg_get_format(const circuit_t *circ,
const crypt_path_t *cpath);
+/* Helpers. */
+void relay_msg_free_messages(smartlist_t *messages);
+
#ifdef RELAY_MSG_PRIVATE
#endif /* RELAY_MSG_PRIVATE */
#include "feature/client/entrynodes.h"
#include "feature/nodelist/networkstatus.h"
#include "core/or/relay.h"
+#include "core/or/relay_cell.h"
+#include "core/or/relay_msg.h"
#include "lib/math/fp.h"
#include "lib/math/laplace.h"
-#include "core/or/cell_st.h"
#include "core/or/cpath_build_state_st.h"
#include "core/or/crypt_path_st.h"
#include "core/or/extend_info_st.h"
* If the response is valid, return 0. Otherwise return < 0.
*/
int
-pathbias_check_probe_response(circuit_t *circ, const cell_t *cell)
+pathbias_check_probe_response(circuit_t *circ, const relay_msg_t *msg)
{
/* Based on connection_edge_process_relay_cell() */
- relay_header_t rh;
int reason;
uint32_t ipv4_host;
origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
- tor_assert(cell);
+ tor_assert(msg);
tor_assert(ocirc);
tor_assert(circ->purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING);
- relay_header_unpack(&rh, cell->payload);
+ reason = msg->length > 0 ? get_uint8(msg->body) : END_STREAM_REASON_MISC;
- reason = rh.length > 0 ?
- get_uint8(cell->payload+RELAY_HEADER_SIZE) : END_STREAM_REASON_MISC;
-
- if (rh.command == RELAY_COMMAND_END &&
+ if (msg->command == RELAY_COMMAND_END &&
reason == END_STREAM_REASON_EXITPOLICY &&
- ocirc->pathbias_probe_id == rh.stream_id) {
+ ocirc->pathbias_probe_id == msg->stream_id) {
/* Check length+extract host: It is in network order after the reason code.
* See connection_edge_end(). */
- if (rh.length < 9) { /* reason+ipv4+dns_ttl */
+ if (msg->length < 9) { /* reason+ipv4+dns_ttl */
log_notice(LD_PROTOCOL,
- "Short path bias probe response length field (%d).", rh.length);
+ "Short path bias probe response length field (%d).", msg->length);
return - END_CIRC_REASON_TORPROTOCOL;
}
- ipv4_host = ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE+1));
+ ipv4_host = ntohl(get_uint32(msg->body + 1));
/* Check nonce */
if (ipv4_host == ocirc->pathbias_probe_nonce) {
pathbias_mark_use_success(ocirc);
- circuit_read_valid_data(ocirc, rh.length);
+ circuit_read_valid_data(ocirc, msg->length);
circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
log_info(LD_CIRC,
"Got valid path bias probe back for circ %d, stream %d.",
log_info(LD_CIRC,
"Got another cell back back on pathbias probe circuit %d: "
"Command: %d, Reason: %d, Stream-id: %d",
- ocirc->global_identifier, rh.command, reason, rh.stream_id);
+ ocirc->global_identifier, msg->command, reason, msg->stream_id);
return -1;
}
* and if so, count it as valid.
*/
void
-pathbias_count_valid_cells(circuit_t *circ, const cell_t *cell)
+pathbias_count_valid_cells(circuit_t *circ, const relay_msg_t *msg)
{
origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
- relay_header_t rh;
-
- relay_header_unpack(&rh, cell->payload);
/* Check to see if this is a cell from a previous connection,
* or is a request to close the circuit. */
- switch (rh.command) {
+ switch (msg->command) {
case RELAY_COMMAND_TRUNCATED:
/* Truncated cells can arrive on path bias circs. When they do,
* just process them. This closes the circ, but it was junk anyway.
* No reason to wait for the probe. */
- circuit_read_valid_data(ocirc, rh.length);
- circuit_truncated(TO_ORIGIN_CIRCUIT(circ),
- get_uint8(cell->payload + RELAY_HEADER_SIZE));
+ circuit_read_valid_data(ocirc, msg->length);
+ circuit_truncated(TO_ORIGIN_CIRCUIT(circ), get_uint8(msg->body));
break;
case RELAY_COMMAND_END:
if (connection_half_edge_is_valid_end(ocirc->half_streams,
- rh.stream_id)) {
- circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+ msg->stream_id)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
}
break;
case RELAY_COMMAND_DATA:
if (connection_half_edge_is_valid_data(ocirc->half_streams,
- rh.stream_id)) {
- circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+ msg->stream_id)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
}
break;
case RELAY_COMMAND_SENDME:
if (connection_half_edge_is_valid_sendme(ocirc->half_streams,
- rh.stream_id)) {
- circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+ msg->stream_id)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
}
break;
case RELAY_COMMAND_CONNECTED:
if (connection_half_edge_is_valid_connected(ocirc->half_streams,
- rh.stream_id)) {
- circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+ msg->stream_id)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
}
break;
case RELAY_COMMAND_RESOLVED:
if (connection_half_edge_is_valid_resolved(ocirc->half_streams,
- rh.stream_id)) {
- circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+ msg->stream_id)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length);
}
break;
}
#ifndef TOR_CIRCPATHBIAS_H
#define TOR_CIRCPATHBIAS_H
+#include "core/or/relay_msg_st.h"
+
double pathbias_get_extreme_rate(const or_options_t *options);
double pathbias_get_extreme_use_rate(const or_options_t *options);
int pathbias_get_dropguards(const or_options_t *options);
void pathbias_count_build_success(origin_circuit_t *circ);
int pathbias_count_build_attempt(origin_circuit_t *circ);
int pathbias_check_close(origin_circuit_t *circ, int reason);
-int pathbias_check_probe_response(circuit_t *circ, const cell_t *cell);
-void pathbias_count_valid_cells(circuit_t *circ, const cell_t *cell);
+int pathbias_check_probe_response(circuit_t *circ, const relay_msg_t *msg);
+void pathbias_count_valid_cells(circuit_t *circ, const relay_msg_t *msg);
void pathbias_count_use_attempt(origin_circuit_t *circ);
void pathbias_mark_use_success(origin_circuit_t *circ);
void pathbias_mark_use_rollback(origin_circuit_t *circ);
* Return -1 if we want to warn and tear down the circuit, else return 0.
*/
int
-circuit_extend(struct cell_t *cell, struct circuit_t *circ)
+circuit_extend(const relay_msg_t *rmsg, struct circuit_t *circ)
{
channel_t *n_chan;
- relay_header_t rh;
extend_cell_t ec;
const char *msg = NULL;
int should_launch = 0;
- IF_BUG_ONCE(!cell) {
+ IF_BUG_ONCE(!rmsg) {
return -1;
}
if (circuit_extend_state_valid_helper(circ) < 0)
return -1;
- relay_header_unpack(&rh, cell->payload);
-
/* We no longer accept EXTEND messages; only EXTEND2. */
- if (rh.command == RELAY_COMMAND_EXTEND) {
+ if (rmsg->command == RELAY_COMMAND_EXTEND) {
/* TODO: Should we log this? */
return -1;
}
- if (extend_cell_parse(&ec, rh.command,
- cell->payload+RELAY_HEADER_SIZE,
- rh.length) < 0) {
+ if (extend_cell_parse(&ec, rmsg->command, rmsg->body, rmsg->length) < 0) {
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Can't parse extend cell. Closing circuit.");
return -1;
#include "lib/cc/torint.h"
#include "lib/log/log.h"
+#include "core/or/relay_msg_st.h"
#include "app/config/config.h"
#ifdef HAVE_MODULE_RELAY
-int circuit_extend(struct cell_t *cell, struct circuit_t *circ);
+int circuit_extend(const relay_msg_t *msg, struct circuit_t *circ);
int onionskin_answer(struct or_circuit_t *circ,
const struct created_cell_t *created_cell,
#else /* !defined(HAVE_MODULE_RELAY) */
static inline int
-circuit_extend(struct cell_t *cell, struct circuit_t *circ)
+circuit_extend(const relay_msg_t *msg, struct circuit_t *circ)
{
- (void)cell;
+ (void)msg;
(void)circ;
circuitbuild_warn_client_extend();
return -1;
}
static void
-make_relay_cell(cell_t *out, uint8_t command,
- const void *body, size_t bodylen)
+make_relay_msg(relay_msg_t *out, uint8_t command,
+ const void *body, size_t bodylen)
{
- relay_header_t rh;
-
- memset(&rh, 0, sizeof(rh));
- rh.stream_id = 5;
- rh.command = command;
- rh.length = bodylen;
-
- out->command = CELL_RELAY;
- out->circ_id = 10;
- relay_header_pack(out->payload, &rh);
-
- memcpy(out->payload + RELAY_HEADER_SIZE, body, bodylen);
+ memset(out, 0, sizeof(*out));
+ out->command = command;
+ out->body = (uint8_t *)body;
+ out->length = bodylen;
+ out->stream_id = 5;
}
static void
test_cfmt_begin_cells(void *arg)
{
- cell_t cell;
+ relay_msg_t msg;
begin_cell_t bcell;
uint8_t end_reason;
(void)arg;
/* Try begindir. */
memset(&bcell, 0x7f, sizeof(bcell));
- make_relay_cell(&cell, RELAY_COMMAND_BEGIN_DIR, "", 0);
- tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
+ make_relay_msg(&msg, RELAY_COMMAND_BEGIN_DIR, "", 0);
+ tt_int_op(0, OP_EQ, begin_cell_parse(&msg, &bcell, &end_reason));
tt_ptr_op(NULL, OP_EQ, bcell.address);
tt_int_op(0, OP_EQ, bcell.flags);
tt_int_op(0, OP_EQ, bcell.port);
/* A Begindir with extra stuff. */
memset(&bcell, 0x7f, sizeof(bcell));
- make_relay_cell(&cell, RELAY_COMMAND_BEGIN_DIR, "12345", 5);
- tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
+ make_relay_msg(&msg, RELAY_COMMAND_BEGIN_DIR, "12345", 5);
+ tt_int_op(0, OP_EQ, begin_cell_parse(&msg, &bcell, &end_reason));
tt_ptr_op(NULL, OP_EQ, bcell.address);
tt_int_op(0, OP_EQ, bcell.flags);
tt_int_op(0, OP_EQ, bcell.port);
/* A short but valid begin cell */
memset(&bcell, 0x7f, sizeof(bcell));
- make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:9", 6);
- tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
+ make_relay_msg(&msg, RELAY_COMMAND_BEGIN, "a.b:9", 6);
+ tt_int_op(0, OP_EQ, begin_cell_parse(&msg, &bcell, &end_reason));
tt_str_op("a.b", OP_EQ, bcell.address);
tt_int_op(0, OP_EQ, bcell.flags);
tt_int_op(9, OP_EQ, bcell.port);
/* A significantly loner begin cell */
memset(&bcell, 0x7f, sizeof(bcell));
{
- const char c[] = "here-is-a-nice-long.hostname.com:65535";
- make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, strlen(c)+1);
- }
- tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
+ const char c[] = "here-is-a-nice-long.hostname.com:65535";
+ make_relay_msg(&msg, RELAY_COMMAND_BEGIN, c, strlen(c)+1);
+ tt_int_op(0, OP_EQ, begin_cell_parse(&msg, &bcell, &end_reason));
tt_str_op("here-is-a-nice-long.hostname.com", OP_EQ, bcell.address);
tt_int_op(0, OP_EQ, bcell.flags);
tt_int_op(65535, OP_EQ, bcell.port);
tt_int_op(5, OP_EQ, bcell.stream_id);
tt_int_op(0, OP_EQ, bcell.is_begindir);
tor_free(bcell.address);
+ }
/* An IPv4 begin cell. */
memset(&bcell, 0x7f, sizeof(bcell));
- make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "18.9.22.169:80", 15);
- tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
+ make_relay_msg(&msg, RELAY_COMMAND_BEGIN, "18.9.22.169:80", 15);
+ tt_int_op(0, OP_EQ, begin_cell_parse(&msg, &bcell, &end_reason));
tt_str_op("18.9.22.169", OP_EQ, bcell.address);
tt_int_op(0, OP_EQ, bcell.flags);
tt_int_op(80, OP_EQ, bcell.port);
/* An IPv6 begin cell. Let's make sure we handle colons*/
memset(&bcell, 0x7f, sizeof(bcell));
- make_relay_cell(&cell, RELAY_COMMAND_BEGIN,
+ make_relay_msg(&msg, RELAY_COMMAND_BEGIN,
"[2620::6b0:b:1a1a:0:26e5:480e]:80", 34);
- tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
+ tt_int_op(0, OP_EQ, begin_cell_parse(&msg, &bcell, &end_reason));
tt_str_op("[2620::6b0:b:1a1a:0:26e5:480e]", OP_EQ, bcell.address);
tt_int_op(0, OP_EQ, bcell.flags);
tt_int_op(80, OP_EQ, bcell.port);
memset(&bcell, 0x7f, sizeof(bcell));
{
const char c[] = "another.example.com:80\x00\x01\x02";
- make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
+ make_relay_msg(&msg, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
+ tt_int_op(0, OP_EQ, begin_cell_parse(&msg, &bcell, &end_reason));
+ tt_str_op("another.example.com", OP_EQ, bcell.address);
+ tt_int_op(0, OP_EQ, bcell.flags);
+ tt_int_op(80, OP_EQ, bcell.port);
+ tt_int_op(5, OP_EQ, bcell.stream_id);
+ tt_int_op(0, OP_EQ, bcell.is_begindir);
+ tor_free(bcell.address);
}
- tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
- tt_str_op("another.example.com", OP_EQ, bcell.address);
- tt_int_op(0, OP_EQ, bcell.flags);
- tt_int_op(80, OP_EQ, bcell.port);
- tt_int_op(5, OP_EQ, bcell.stream_id);
- tt_int_op(0, OP_EQ, bcell.is_begindir);
- tor_free(bcell.address);
/* a begin cell with flags. */
memset(&bcell, 0x7f, sizeof(bcell));
{
const char c[] = "another.example.com:443\x00\x01\x02\x03\x04";
- make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
+ make_relay_msg(&msg, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
+ tt_int_op(0, OP_EQ, begin_cell_parse(&msg, &bcell, &end_reason));
+ tt_str_op("another.example.com", OP_EQ, bcell.address);
+ tt_int_op(0x1020304, OP_EQ, bcell.flags);
+ tt_int_op(443, OP_EQ, bcell.port);
+ tt_int_op(5, OP_EQ, bcell.stream_id);
+ tt_int_op(0, OP_EQ, bcell.is_begindir);
+ tor_free(bcell.address);
}
- tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
- tt_str_op("another.example.com", OP_EQ, bcell.address);
- tt_int_op(0x1020304, OP_EQ, bcell.flags);
- tt_int_op(443, OP_EQ, bcell.port);
- tt_int_op(5, OP_EQ, bcell.stream_id);
- tt_int_op(0, OP_EQ, bcell.is_begindir);
- tor_free(bcell.address);
/* a begin cell with flags and even more cruft after that. */
memset(&bcell, 0x7f, sizeof(bcell));
{
const char c[] = "a-further.example.com:22\x00\xee\xaa\x00\xffHi mom";
- make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
+ make_relay_msg(&msg, RELAY_COMMAND_BEGIN, c, sizeof(c)-1);
+ tt_int_op(0, OP_EQ, begin_cell_parse(&msg, &bcell, &end_reason));
+ tt_str_op("a-further.example.com", OP_EQ, bcell.address);
+ tt_int_op(0xeeaa00ff, OP_EQ, bcell.flags);
+ tt_int_op(22, OP_EQ, bcell.port);
+ tt_int_op(5, OP_EQ, bcell.stream_id);
+ tt_int_op(0, OP_EQ, bcell.is_begindir);
+ tor_free(bcell.address);
}
- tt_int_op(0, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
- tt_str_op("a-further.example.com", OP_EQ, bcell.address);
- tt_int_op(0xeeaa00ff, OP_EQ, bcell.flags);
- tt_int_op(22, OP_EQ, bcell.port);
- tt_int_op(5, OP_EQ, bcell.stream_id);
- tt_int_op(0, OP_EQ, bcell.is_begindir);
- tor_free(bcell.address);
+#if 0
+ // Note: This is now checked at when we decode the relay message.
/* bad begin cell: impossible length. */
memset(&bcell, 0x7f, sizeof(bcell));
- make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:80", 7);
- cell.payload[9] = 0x01; /* Set length to 510 */
- cell.payload[10] = 0xfe;
- {
- relay_header_t rh;
- relay_header_unpack(&rh, cell.payload);
- tt_int_op(rh.length, OP_EQ, 510);
- }
- tt_int_op(-2, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
+ make_relay_msg(&msg, RELAY_COMMAND_BEGIN, "a.b:80", 7);
+ msg.length = 510;
+ tt_int_op(-2, OP_EQ, begin_cell_parse(&msg, &bcell, &end_reason));
+#endif
/* Bad begin cell: no body. */
memset(&bcell, 0x7f, sizeof(bcell));
- make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "", 0);
- tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
+ make_relay_msg(&msg, RELAY_COMMAND_BEGIN, "", 0);
+ tt_int_op(-1, OP_EQ, begin_cell_parse(&msg, &bcell, &end_reason));
/* bad begin cell: no body. */
memset(&bcell, 0x7f, sizeof(bcell));
- make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "", 0);
- tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
+ make_relay_msg(&msg, RELAY_COMMAND_BEGIN, "", 0);
+ tt_int_op(-1, OP_EQ, begin_cell_parse(&msg, &bcell, &end_reason));
/* bad begin cell: no colon */
memset(&bcell, 0x7f, sizeof(bcell));
- make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b", 4);
- tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
+ make_relay_msg(&msg, RELAY_COMMAND_BEGIN, "a.b", 4);
+ tt_int_op(-1, OP_EQ, begin_cell_parse(&msg, &bcell, &end_reason));
/* bad begin cell: no ports */
memset(&bcell, 0x7f, sizeof(bcell));
- make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:", 5);
- tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
+ make_relay_msg(&msg, RELAY_COMMAND_BEGIN, "a.b:", 5);
+ tt_int_op(-1, OP_EQ, begin_cell_parse(&msg, &bcell, &end_reason));
/* bad begin cell: bad port */
memset(&bcell, 0x7f, sizeof(bcell));
- make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:xyz", 8);
- tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
+ make_relay_msg(&msg, RELAY_COMMAND_BEGIN, "a.b:xyz", 8);
+ tt_int_op(-1, OP_EQ, begin_cell_parse(&msg, &bcell, &end_reason));
memset(&bcell, 0x7f, sizeof(bcell));
- make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:100000", 11);
- tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
+ make_relay_msg(&msg, RELAY_COMMAND_BEGIN, "a.b:100000", 11);
+ tt_int_op(-1, OP_EQ, begin_cell_parse(&msg, &bcell, &end_reason));
/* bad begin cell: no nul */
memset(&bcell, 0x7f, sizeof(bcell));
- make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:80", 6);
- tt_int_op(-1, OP_EQ, begin_cell_parse(&cell, &bcell, &end_reason));
+ make_relay_msg(&msg, RELAY_COMMAND_BEGIN, "a.b:80", 6);
+ tt_int_op(-1, OP_EQ, begin_cell_parse(&msg, &bcell, &end_reason));
done:
tor_free(bcell.address);
static void
test_cfmt_connected_cells(void *arg)
{
- relay_header_t rh;
- cell_t cell;
tor_addr_t addr;
int ttl, r;
char *mem_op_hex_tmp = NULL;
+ relay_msg_t msg;
+ uint8_t buf[512];
(void)arg;
/* Let's try an oldschool one with nothing in it. */
- make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "", 0);
- relay_header_unpack(&rh, cell.payload);
- r = connected_cell_parse(&rh, &cell, &addr, &ttl);
+ make_relay_msg(&msg, RELAY_COMMAND_CONNECTED, "", 0);
+ r = connected_cell_parse(&msg, &addr, &ttl);
tt_int_op(r, OP_EQ, 0);
tt_int_op(tor_addr_family(&addr), OP_EQ, AF_UNSPEC);
tt_int_op(ttl, OP_EQ, -1);
/* A slightly less oldschool one: only an IPv4 address */
- make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x20\x30\x40\x50", 4);
- relay_header_unpack(&rh, cell.payload);
- r = connected_cell_parse(&rh, &cell, &addr, &ttl);
+ make_relay_msg(&msg, RELAY_COMMAND_CONNECTED, "\x20\x30\x40\x50", 4);
+ r = connected_cell_parse(&msg, &addr, &ttl);
tt_int_op(r, OP_EQ, 0);
tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
tt_str_op(fmt_addr(&addr), OP_EQ, "32.48.64.80");
tt_int_op(ttl, OP_EQ, -1);
/* Bogus but understandable: truncated TTL */
- make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x11\x12\x13\x14\x15", 5);
- relay_header_unpack(&rh, cell.payload);
- r = connected_cell_parse(&rh, &cell, &addr, &ttl);
+ make_relay_msg(&msg, RELAY_COMMAND_CONNECTED, "\x11\x12\x13\x14\x15", 5);
+ r = connected_cell_parse(&msg, &addr, &ttl);
tt_int_op(r, OP_EQ, 0);
tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
tt_str_op(fmt_addr(&addr), OP_EQ, "17.18.19.20");
tt_int_op(ttl, OP_EQ, -1);
/* Regular IPv4 one: address and TTL */
- make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
+ make_relay_msg(&msg, RELAY_COMMAND_CONNECTED,
"\x02\x03\x04\x05\x00\x00\x0e\x10", 8);
- relay_header_unpack(&rh, cell.payload);
- r = connected_cell_parse(&rh, &cell, &addr, &ttl);
+ r = connected_cell_parse(&msg, &addr, &ttl);
tt_int_op(r, OP_EQ, 0);
tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
tt_str_op(fmt_addr(&addr), OP_EQ, "2.3.4.5");
tt_int_op(ttl, OP_EQ, 3600);
/* IPv4 with too-big TTL */
- make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
+ make_relay_msg(&msg, RELAY_COMMAND_CONNECTED,
"\x02\x03\x04\x05\xf0\x00\x00\x00", 8);
- relay_header_unpack(&rh, cell.payload);
- r = connected_cell_parse(&rh, &cell, &addr, &ttl);
+ r = connected_cell_parse(&msg, &addr, &ttl);
tt_int_op(r, OP_EQ, 0);
tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
tt_str_op(fmt_addr(&addr), OP_EQ, "2.3.4.5");
tt_int_op(ttl, OP_EQ, -1);
/* IPv6 (ttl is mandatory) */
- make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
+ make_relay_msg(&msg, RELAY_COMMAND_CONNECTED,
"\x00\x00\x00\x00\x06"
"\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
"\x00\x00\x00\x00\x00\x00\x00\x68"
"\x00\x00\x02\x58", 25);
- relay_header_unpack(&rh, cell.payload);
- r = connected_cell_parse(&rh, &cell, &addr, &ttl);
+ r = connected_cell_parse(&msg, &addr, &ttl);
tt_int_op(r, OP_EQ, 0);
tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET6);
tt_str_op(fmt_addr(&addr), OP_EQ, "2607:f8b0:400c:c02::68");
tt_int_op(ttl, OP_EQ, 600);
/* IPv6 (ttl too big) */
- make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
+ make_relay_msg(&msg, RELAY_COMMAND_CONNECTED,
"\x00\x00\x00\x00\x06"
"\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
"\x00\x00\x00\x00\x00\x00\x00\x68"
"\x90\x00\x02\x58", 25);
- relay_header_unpack(&rh, cell.payload);
- r = connected_cell_parse(&rh, &cell, &addr, &ttl);
+ r = connected_cell_parse(&msg, &addr, &ttl);
tt_int_op(r, OP_EQ, 0);
tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET6);
tt_str_op(fmt_addr(&addr), OP_EQ, "2607:f8b0:400c:c02::68");
tt_int_op(ttl, OP_EQ, -1);
/* Bogus size: 3. */
- make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
+ make_relay_msg(&msg, RELAY_COMMAND_CONNECTED,
"\x00\x01\x02", 3);
- relay_header_unpack(&rh, cell.payload);
- r = connected_cell_parse(&rh, &cell, &addr, &ttl);
+ r = connected_cell_parse(&msg, &addr, &ttl);
tt_int_op(r, OP_EQ, -1);
/* Bogus family: 7. */
- make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
+ make_relay_msg(&msg, RELAY_COMMAND_CONNECTED,
"\x00\x00\x00\x00\x07"
"\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
"\x00\x00\x00\x00\x00\x00\x00\x68"
"\x90\x00\x02\x58", 25);
- relay_header_unpack(&rh, cell.payload);
- r = connected_cell_parse(&rh, &cell, &addr, &ttl);
+ r = connected_cell_parse(&msg, &addr, &ttl);
tt_int_op(r, OP_EQ, -1);
/* Truncated IPv6. */
- make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
+ make_relay_msg(&msg, RELAY_COMMAND_CONNECTED,
"\x00\x00\x00\x00\x06"
"\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
"\x00\x00\x00\x00\x00\x00\x00\x68"
"\x00\x00\x02", 24);
- relay_header_unpack(&rh, cell.payload);
- r = connected_cell_parse(&rh, &cell, &addr, &ttl);
+ r = connected_cell_parse(&msg, &addr, &ttl);
tt_int_op(r, OP_EQ, -1);
/* Now make sure we can generate connected cells correctly. */
/* Try an IPv4 address */
- memset(&rh, 0, sizeof(rh));
- memset(&cell, 0, sizeof(cell));
tor_addr_parse(&addr, "30.40.50.60");
- rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE,
- &addr, 1024);
- tt_int_op(rh.length, OP_EQ, 8);
- test_memeq_hex(cell.payload+RELAY_HEADER_SIZE, "1e28323c" "00000400");
+ msg.body = buf;
+ msg.length = connected_cell_format_payload(buf, &addr, 1024);
+ tt_int_op(msg.length, OP_EQ, 8);
+ test_memeq_hex(msg.body, "1e28323c" "00000400");
/* Try parsing it. */
tor_addr_make_unspec(&addr);
- r = connected_cell_parse(&rh, &cell, &addr, &ttl);
+ r = connected_cell_parse(&msg, &addr, &ttl);
tt_int_op(r, OP_EQ, 0);
tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET);
tt_str_op(fmt_addr(&addr), OP_EQ, "30.40.50.60");
tt_int_op(ttl, OP_EQ, 1024);
/* Try an IPv6 address */
- memset(&rh, 0, sizeof(rh));
- memset(&cell, 0, sizeof(cell));
tor_addr_parse(&addr, "2620::6b0:b:1a1a:0:26e5:480e");
- rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE,
- &addr, 3600);
- tt_int_op(rh.length, OP_EQ, 25);
- test_memeq_hex(cell.payload + RELAY_HEADER_SIZE,
+ msg.length = connected_cell_format_payload(buf, &addr, 3600);
+ tt_int_op(msg.length, OP_EQ, 25);
+ test_memeq_hex(msg.body,
"00000000" "06"
"2620000006b0000b1a1a000026e5480e" "00000e10");
/* Try parsing it. */
tor_addr_make_unspec(&addr);
- r = connected_cell_parse(&rh, &cell, &addr, &ttl);
+ r = connected_cell_parse(&msg, &addr, &ttl);
tt_int_op(r, OP_EQ, 0);
tt_int_op(tor_addr_family(&addr), OP_EQ, AF_INET6);
tt_str_op(fmt_addr(&addr), OP_EQ, "2620:0:6b0:b:1a1a:0:26e5:480e");
test_cfmt_resolved_cells(void *arg)
{
smartlist_t *addrs = smartlist_new();
- relay_header_t rh;
- cell_t cell;
int r, errcode;
address_ttl_t *a;
+ relay_msg_t msg;
+ uint8_t buf[500];
(void)arg;
#define CLEAR_CELL() do { \
- memset(&cell, 0, sizeof(cell)); \
- memset(&rh, 0, sizeof(rh)); \
+ memset(&msg, 0, sizeof(msg)); \
+ memset(&buf, 0, sizeof(buf)); \
} while (0)
#define CLEAR_ADDRS() do { \
SMARTLIST_FOREACH(addrs, address_ttl_t *, aa_, \
} while (0)
#define SET_CELL(s) do { \
CLEAR_CELL(); \
- memcpy(cell.payload + RELAY_HEADER_SIZE, (s), sizeof((s))-1); \
- rh.length = sizeof((s))-1; \
- rh.command = RELAY_COMMAND_RESOLVED; \
+ memcpy(buf, (s), sizeof((s))-1); \
+ msg.length = sizeof((s))-1; \
+ msg.body = buf; \
+ msg.command = RELAY_COMMAND_RESOLVED; \
errcode = -1; \
} while (0)
/* Let's try an empty cell */
SET_CELL("");
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(errcode, OP_EQ, 0);
tt_int_op(r, OP_EQ, 0);
tt_int_op(smartlist_len(addrs), OP_EQ, 0);
/* Cell with one ipv4 addr */
SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00");
- tt_int_op(rh.length, OP_EQ, 10);
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ tt_int_op(msg.length, OP_EQ, 10);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(errcode, OP_EQ, 0);
tt_int_op(r, OP_EQ, 0);
tt_int_op(smartlist_len(addrs), OP_EQ, 1);
"\x20\x02\x90\x90\x00\x00\x00\x00"
"\x00\x00\x00\x00\xf0\xf0\xab\xcd"
"\x02\00\x00\x01");
- tt_int_op(rh.length, OP_EQ, 22);
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ tt_int_op(msg.length, OP_EQ, 22);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(errcode, OP_EQ, 0);
tt_int_op(r, OP_EQ, 0);
tt_int_op(smartlist_len(addrs), OP_EQ, 1);
SET_CELL("\x00\x11"
"motherbrain.zebes"
"\x00\00\x00\x00");
- tt_int_op(rh.length, OP_EQ, 23);
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ tt_int_op(msg.length, OP_EQ, 23);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(errcode, OP_EQ, 0);
tt_int_op(r, OP_EQ, 0);
tt_int_op(smartlist_len(addrs), OP_EQ, 1);
SET_CELL("\x00\xff"
LONG_NAME
"\x00\01\x00\x00");
- tt_int_op(rh.length, OP_EQ, 261);
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ tt_int_op(msg.length, OP_EQ, 261);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(errcode, OP_EQ, 0);
tt_int_op(r, OP_EQ, 0);
tt_int_op(smartlist_len(addrs), OP_EQ, 1);
SET_CELL("\xf0\x2b"
"I'm sorry, Dave. I'm afraid I can't do that"
"\x00\x11\x22\x33");
- tt_int_op(rh.length, OP_EQ, 49);
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ tt_int_op(msg.length, OP_EQ, 49);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(errcode, OP_EQ, RESOLVED_TYPE_ERROR_TRANSIENT);
tt_int_op(r, OP_EQ, 0);
tt_int_op(smartlist_len(addrs), OP_EQ, 0);
SET_CELL("\xf1\x40"
"This hostname is too important for me to allow you to resolve it"
"\x00\x00\x00\x00");
- tt_int_op(rh.length, OP_EQ, 70);
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ tt_int_op(msg.length, OP_EQ, 70);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(errcode, OP_EQ, RESOLVED_TYPE_ERROR);
tt_int_op(r, OP_EQ, 0);
tt_int_op(smartlist_len(addrs), OP_EQ, 0);
SET_CELL("\xee\x16"
"fault in the AE35 unit"
"\x09\x09\x01\x01");
- tt_int_op(rh.length, OP_EQ, 28);
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ tt_int_op(msg.length, OP_EQ, 28);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(errcode, OP_EQ, 0);
tt_int_op(r, OP_EQ, 0);
tt_int_op(smartlist_len(addrs), OP_EQ, 0);
"motherbrain.zebes"
"\x00\00\x00\x00"
);
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(errcode, OP_EQ, 0); /* no error reported; we got answers */
tt_int_op(r, OP_EQ, 0);
tt_int_op(smartlist_len(addrs), OP_EQ, 3);
"\x20\x02\x90\x01\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\xfa\xca\xde"
"\x00\00\x00\x03");
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(errcode, OP_EQ, 0);
tt_int_op(r, OP_EQ, 0);
tt_int_op(smartlist_len(addrs), OP_EQ, 5);
"\x00\xe7"
LONG_NAME2
"\x00\01\x00\x00");
- tt_int_op(rh.length, OP_EQ, RELAY_PAYLOAD_SIZE);
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ tt_int_op(msg.length, OP_EQ, RELAY_PAYLOAD_SIZE);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(errcode, OP_EQ, 0);
tt_int_op(r, OP_EQ, 0);
tt_int_op(smartlist_len(addrs), OP_EQ, 2);
/* Invalid length on an IPv4 */
SET_CELL("\x04\x03zzz1234");
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(errcode, OP_EQ, 0);
tt_int_op(r, OP_EQ, -1);
tt_int_op(smartlist_len(addrs), OP_EQ, 0);
SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00"
"\x04\x05zzzzz1234");
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(errcode, OP_EQ, 0);
tt_int_op(r, OP_EQ, -1);
tt_int_op(smartlist_len(addrs), OP_EQ, 0);
/* Invalid length on an IPv6 */
SET_CELL("\x06\x03zzz1234");
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(errcode, OP_EQ, 0);
tt_int_op(r, OP_EQ, -1);
tt_int_op(smartlist_len(addrs), OP_EQ, 0);
SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00"
"\x06\x17wwwwwwwwwwwwwwwww1234");
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(errcode, OP_EQ, 0);
tt_int_op(r, OP_EQ, -1);
tt_int_op(smartlist_len(addrs), OP_EQ, 0);
SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00"
"\x06\x10xxxx");
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(errcode, OP_EQ, 0);
tt_int_op(r, OP_EQ, -1);
tt_int_op(smartlist_len(addrs), OP_EQ, 0);
/* Empty hostname */
SET_CELL("\x00\x00xxxx");
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(errcode, OP_EQ, 0);
tt_int_op(r, OP_EQ, -1);
tt_int_op(smartlist_len(addrs), OP_EQ, 0);
+#if 0
+ //No longer possible with relay message encoding.
/* rh.length out of range */
CLEAR_CELL();
rh.length = 499;
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(errcode, OP_EQ, 0);
tt_int_op(r, OP_EQ, -1);
tt_int_op(smartlist_len(addrs), OP_EQ, 0);
+#endif
/* Item length extends beyond rh.length */
CLEAR_CELL();
SET_CELL("\x00\xff"
LONG_NAME
"\x00\01\x00\x00");
- rh.length -= 1;
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ msg.length -= 1;
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(r, OP_EQ, -1);
tt_int_op(smartlist_len(addrs), OP_EQ, 0);
- rh.length -= 5;
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ msg.length -= 5;
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(r, OP_EQ, -1);
tt_int_op(smartlist_len(addrs), OP_EQ, 0);
SET_CELL("\x04\x04" "\x7f\x00\x02\x0a" "\x00\00\x01\x00");
- rh.length -= 1;
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ msg.length -= 1;
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(r, OP_EQ, -1);
tt_int_op(smartlist_len(addrs), OP_EQ, 0);
"\x20\x02\x90\x01\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\xfa\xca\xde"
"\x00\00\x00\x03");
- rh.length -= 1;
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ msg.length -= 1;
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(r, OP_EQ, -1);
tt_int_op(smartlist_len(addrs), OP_EQ, 0);
/* Truncated item after first character */
SET_CELL("\x04");
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(r, OP_EQ, -1);
tt_int_op(smartlist_len(addrs), OP_EQ, 0);
SET_CELL("\xee");
- r = resolved_cell_parse(&cell, &rh, addrs, &errcode);
+ r = resolved_cell_parse(&msg, addrs, &errcode);
tt_int_op(r, OP_EQ, -1);
tt_int_op(smartlist_len(addrs), OP_EQ, 0);
#include "core/or/circuitlist.h"
#include "core/or/circuituse.h"
#include "core/or/onion.h"
+#include "core/or/relay_msg.h"
#include "core/or/cell_st.h"
#include "core/or/cpath_build_state_st.h"
test_circuit_extend(void *arg)
{
(void)arg;
- cell_t *cell = tor_malloc_zero(sizeof(cell_t));
+ relay_msg_t *msg = tor_malloc_zero(sizeof(relay_msg_t));
channel_t *p_chan = tor_malloc_zero(sizeof(channel_t));
or_circuit_t *or_circ = tor_malloc_zero(sizeof(or_circuit_t));
circuit_t *circ = TO_CIRCUIT(or_circ);
setup_full_capture_of_logs(LOG_INFO);
+ msg->command = RELAY_COMMAND_EXTEND2;
+ msg->body = tor_memdup("xyz", 3);
+
#ifndef ALL_BUGS_ARE_FATAL
/* Circuit must be non-NULL */
tor_capture_bugs_(1);
- tt_int_op(circuit_extend(cell, NULL), OP_EQ, -1);
+ tt_int_op(circuit_extend(msg, NULL), OP_EQ, -1);
tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
"!(ASSERT_PREDICT_UNLIKELY_(!circ))");
tt_int_op(circuit_extend(NULL, circ), OP_EQ, -1);
tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
- "!(ASSERT_PREDICT_UNLIKELY_(!cell))");
+ "!(ASSERT_PREDICT_UNLIKELY_(!rmsg))");
tor_end_capture_bugs_();
mock_clean_saved_logs();
/* Clients can't extend */
server = 0;
- tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
+ tt_int_op(circuit_extend(msg, circ), OP_EQ, -1);
expect_log_msg("Got an extend cell, but running as a client. Closing.\n");
mock_clean_saved_logs();
/* But servers can. Unpack the cell, but fail parsing. */
server = 1;
- tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
+ tt_int_op(circuit_extend(msg, circ), OP_EQ, -1);
expect_log_msg("Can't parse extend cell. Closing circuit.\n");
mock_clean_saved_logs();
mock_extend_cell_parse_result = 0;
mock_extend_cell_parse_calls = 0;
- tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
+ tt_int_op(circuit_extend(msg, circ), OP_EQ, -1);
tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
expect_log_msg(
"Client asked me to extend without specifying an id_digest.\n");
memset(&mock_extend_cell_parse_cell_out.node_id, 0xAA,
sizeof(mock_extend_cell_parse_cell_out.node_id));
- tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
+ tt_int_op(circuit_extend(msg, circ), OP_EQ, -1);
tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
expect_log_msg("Client asked me to extend to a zero destination port "
"or unspecified address '[scrubbed]'.\n");
#ifndef ALL_BUGS_ARE_FATAL
tor_capture_bugs_(1);
- tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
+ tt_int_op(circuit_extend(msg, circ), OP_EQ, -1);
tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
/* Test circuit not established, but don't launch another one */
mock_channel_get_for_extend_launch_out = 0;
mock_channel_get_for_extend_nchan = NULL;
- tt_int_op(circuit_extend(cell, circ), OP_EQ, 0);
+ tt_int_op(circuit_extend(msg, circ), OP_EQ, 0);
tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
tt_int_op(mock_channel_get_for_extend_calls, OP_EQ, 1);
mock_channel_get_for_extend_launch_out = 1;
mock_channel_get_for_extend_nchan = NULL;
mock_channel_connect_nchan = fake_n_chan;
- tt_int_op(circuit_extend(cell, circ), OP_EQ, 0);
+ tt_int_op(circuit_extend(msg, circ), OP_EQ, 0);
tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
tt_int_op(mock_channel_get_for_extend_calls, OP_EQ, 1);
tt_int_op(mock_channel_connect_calls, OP_EQ, 1);
mock_channel_get_for_extend_nchan = fake_n_chan;
mock_channel_connect_nchan = NULL;
mock_circuit_deliver_create_cell_result = 0;
- tt_int_op(circuit_extend(cell, circ), OP_EQ, 0);
+ tt_int_op(circuit_extend(msg, circ), OP_EQ, 0);
tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
tt_int_op(mock_channel_get_for_extend_calls, OP_EQ, 1);
tt_int_op(mock_channel_connect_calls, OP_EQ, 0);
mock_channel_get_for_extend_nchan = fake_n_chan;
mock_channel_connect_nchan = NULL;
mock_circuit_deliver_create_cell_result = -1;
- tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
+ tt_int_op(circuit_extend(msg, circ), OP_EQ, -1);
tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
tt_int_op(mock_channel_get_for_extend_calls, OP_EQ, 1);
tt_int_op(mock_channel_connect_calls, OP_EQ, 0);
mock_circuit_deliver_create_cell_calls = 0;
mock_circuit_deliver_create_cell_result = 0;
- tor_free(cell);
+ relay_msg_free(msg);
/* circ and or_circ are the same object */
tor_free(circ->n_hop);
tor_free(circ->n_chan_create_cell);
#include "core/or/circuitpadding.h"
#include "core/or/circuitpadding_machines.h"
#include "core/or/extendinfo.h"
+#include "core/or/relay_msg.h"
#include "core/mainloop/netstatus.h"
#include "core/crypto/relay_crypto.h"
#include "core/or/protover.h"
const char *filename, int lineno)
{
(void)cell; (void)on_stream; (void)filename; (void)lineno;
+ relay_msg_t *msg = NULL;
+
+ msg = relay_msg_decode_cell(RELAY_CELL_FORMAT_V0, cell);
+ if (! msg)
+ goto done;
if (circ == client_side) {
if (cell->payload[0] == RELAY_COMMAND_PADDING_NEGOTIATE) {
// Deliver to relay
- circpad_handle_padding_negotiate(relay_side, cell);
+ circpad_handle_padding_negotiate(relay_side, msg);
} else {
int is_target_hop = circpad_padding_is_from_expected_hop(circ,
// Receive padding cell at middle
circpad_deliver_recognized_relay_cell_events(relay_side,
- cell->payload[0], NULL);
+ msg->command, NULL);
}
n_client_cells++;
} else if (circ == relay_side) {
if (cell->payload[0] == RELAY_COMMAND_PADDING_NEGOTIATED) {
// XXX: blah need right layer_hint..
if (deliver_negotiated)
- circpad_handle_padding_negotiated(client_side, cell,
+ circpad_handle_padding_negotiated(client_side, msg,
TO_ORIGIN_CIRCUIT(client_side)
->cpath->next);
} else if (cell->payload[0] == RELAY_COMMAND_PADDING_NEGOTIATE) {
- circpad_handle_padding_negotiate(client_side, cell);
+ circpad_handle_padding_negotiate(client_side, msg);
} else {
// No need to pretend a padding cell was sent: This event is
// now emitted internally when the circuitpadding code sends them.
// Receive padding cell at client
circpad_deliver_recognized_relay_cell_events(client_side,
- cell->payload[0],
+ msg->command,
TO_ORIGIN_CIRCUIT(client_side)->cpath->next);
}
}
done:
+ relay_msg_free(msg);
timers_advance_and_run(1);
return 0;
}
*/
(void)arg;
uint32_t read_bw = 0, overhead_bw = 0;
- cell_t cell;
+ relay_msg_t msg;
signed_error_t ret;
origin_circuit_t *orig_client;
int64_t actual_mocked_monotime_start;
orig_client->n_overhead_read_circ_bw);
/* 2. Test padding negotiated not handled from hops 1,3 */
- ret = circpad_handle_padding_negotiated(client_side, &cell,
+ memset(&msg, 0, sizeof(msg));
+ ret = circpad_handle_padding_negotiated(client_side, &msg,
TO_ORIGIN_CIRCUIT(client_side)->cpath);
tt_int_op(ret, OP_EQ, -1);
- ret = circpad_handle_padding_negotiated(client_side, &cell,
+ ret = circpad_handle_padding_negotiated(client_side, &msg,
TO_ORIGIN_CIRCUIT(client_side)->cpath->next->next);
tt_int_op(ret, OP_EQ, -1);
/* 3. Garbled negotiated cell */
- memset(&cell, 255, sizeof(cell));
- ret = circpad_handle_padding_negotiated(client_side, &cell,
+ memset(&msg, 0, sizeof(msg));
+ msg.body = tor_malloc_zero(99);
+ memset(msg.body, 0xff, 99);
+ ret = circpad_handle_padding_negotiated(client_side, &msg,
TO_ORIGIN_CIRCUIT(client_side)->cpath->next);
tt_int_op(ret, OP_EQ, -1);
overhead_bw = orig_client->n_overhead_read_circ_bw;
relay_send_command_from_edge(0, relay_side,
RELAY_COMMAND_PADDING_NEGOTIATE,
- (void*)cell.payload,
+ "xyz",
(size_t)3, NULL);
tt_int_op(read_bw, OP_EQ,
orig_client->n_delivered_read_circ_bw);
tt_int_op(n_client_cells, OP_EQ, 2);
/* 6. Sending negotiated command to relay does nothing */
- ret = circpad_handle_padding_negotiated(relay_side, &cell, NULL);
+ ret = circpad_handle_padding_negotiated(relay_side, &msg, NULL);
tt_int_op(ret, OP_EQ, -1);
/* 7. Test garbled negotiated cell (bad command 255) */
- memset(&cell, 0, sizeof(cell));
- ret = circpad_handle_padding_negotiate(relay_side, &cell);
+ relay_msg_clear(&msg);
+ ret = circpad_handle_padding_negotiate(relay_side, &msg);
tt_int_op(ret, OP_EQ, -1);
tt_int_op(n_client_cells, OP_EQ, 2);
UNMOCK(circuitmux_attach_circuit);
nodes_free();
testing_disable_reproducible_rng();
+ relay_msg_clear(&msg);
}
void
test_circuitpadding_ignore_non_padding_cells(void *arg)
{
int retval;
- relay_header_t rh;
(void) arg;
client_side = (circuit_t *)origin_circuit_new();
client_side->purpose = CIRCUIT_PURPOSE_C_CIRCUIT_PADDING;
- rh.command = RELAY_COMMAND_BEGIN;
+ relay_msg_t msg;
+ memset(&msg, 0, sizeof(msg));
+ msg.command = RELAY_COMMAND_BEGIN;
setup_full_capture_of_logs(LOG_INFO);
- retval = handle_relay_cell_command(NULL, client_side, NULL, NULL, &rh, 0);
+ retval = handle_relay_msg(&msg, client_side, NULL, NULL, 0);
tt_int_op(retval, OP_EQ, 0);
expect_log_msg_containing("Ignored cell");
#include "core/or/conflux_cell.h"
#include "core/or/conflux_st.h"
#include "trunnel/conflux.h"
+#include "core/or/relay_msg.h"
+#include "core/or/relay_msg_st.h"
#include "lib/crypt_ops/crypto_rand.h"
static void
test_link(void *arg)
{
- cell_t cell;
conflux_cell_link_t link;
conflux_cell_link_t *decoded_link = NULL;
+ relay_msg_t msg;
(void) arg;
crypto_rand((char *) link.nonce, sizeof(link.nonce));
- ssize_t cell_len = build_link_cell(&link, cell.payload+RELAY_HEADER_SIZE);
+ msg.body = tor_malloc(500);
+ ssize_t cell_len = build_link_cell(&link, msg.body);
tt_int_op(cell_len, OP_GT, 0);
+ msg.length = cell_len;
- decoded_link = conflux_cell_parse_link(&cell, cell_len);
+ decoded_link = conflux_cell_parse_link(&msg);
tt_assert(decoded_link);
uint8_t buf[RELAY_PAYLOAD_SIZE];
tor_free(decoded_link);
done:
+ relay_msg_clear(&msg);
tor_free(decoded_link);
}
END_OF_TESTCASES
};
-
#include "core/or/congestion_control_st.h"
#include "core/or/congestion_control_common.h"
#include "core/or/extendinfo.h"
+#include "core/or/relay_msg.h"
#include "core/mainloop/netstatus.h"
#include "core/crypto/relay_crypto.h"
#include "core/or/protover.h"
process_mock_cell_delivery(void)
{
relay_header_t rh;
+ relay_msg_t *msg = NULL;
cell_delivery_t *delivery = smartlist_pop_last(mock_cell_delivery);
tor_assert(delivery);
timers_advance_and_run(1);
- switch (cell->payload[0]) {
+ msg = relay_msg_decode_cell(RELAY_CELL_FORMAT_V0, cell);
+
+ tor_assert(msg);
+
+ switch (msg->command) {
case RELAY_COMMAND_CONFLUX_LINK:
tor_assert(!CIRCUIT_IS_ORIGIN(dest_circ));
- conflux_process_link(dest_circ, cell, rh.length);
+ conflux_process_link(dest_circ, msg);
break;
case RELAY_COMMAND_CONFLUX_LINKED:
tor_assert(CIRCUIT_IS_ORIGIN(dest_circ));
conflux_process_linked(dest_circ,
TO_ORIGIN_CIRCUIT(dest_circ)->cpath->prev,
- cell, rh.length);
+ msg);
break;
case RELAY_COMMAND_CONFLUX_LINKED_ACK:
tor_assert(!CIRCUIT_IS_ORIGIN(dest_circ));
// the case where the switch is initiated by the exit, we will need to
// get the cpath layer hint for the client.
tor_assert(!CIRCUIT_IS_ORIGIN(dest_circ));
- conflux_process_switch_command(dest_circ, NULL, cell, &rh);
+ conflux_process_switch_command(dest_circ, NULL, msg);
break;
}
tor_free(delivery);
tor_free(cell);
+ relay_msg_free(msg);
return;
}
#include "core/or/connection_edge.h"
#include "core/or/sendme.h"
#include "core/or/relay.h"
+#include "core/or/relay_msg.h"
#include "test/test.h"
#include "test/log_test_helpers.h"
}
#define PACK_CELL(id, cmd, body_s) do { \
- memset(&cell, 0, sizeof(cell)); \
- memset(&rh, 0, sizeof(rh)); \
- memcpy(cell.payload+RELAY_HEADER_SIZE, (body_s), sizeof((body_s))-1); \
- rh.length = sizeof((body_s))-1; \
- rh.command = (cmd); \
- rh.stream_id = (id); \
- relay_header_pack((uint8_t*)&cell.payload, &rh); \
+ len_tmp = sizeof(body_s)-1; \
+ relay_msg_free(msg); \
+ msg = tor_malloc_zero(sizeof(relay_msg_t)); \
+ msg->command = (cmd); \
+ msg->stream_id = (id); \
+ msg->body = tor_malloc(len_tmp); \
+ msg->length = len_tmp; \
+ memcpy(msg->body, (body_s), len_tmp); \
} while (0)
#define ASSERT_COUNTED_BW() do { \
- tt_int_op(circ->n_delivered_read_circ_bw, OP_EQ, delivered+rh.length); \
+ tt_int_op(circ->n_delivered_read_circ_bw, OP_EQ, delivered+msg->length); \
tt_int_op(circ->n_overhead_read_circ_bw, OP_EQ, \
- overhead+RELAY_PAYLOAD_SIZE-rh.length); \
+ overhead+RELAY_PAYLOAD_SIZE-msg->length); \
delivered = circ->n_delivered_read_circ_bw; \
overhead = circ->n_overhead_read_circ_bw; \
} while (0)
static int
subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
{
- cell_t cell;
- relay_header_t rh;
+ relay_msg_t *msg = NULL;
+ size_t len_tmp;
edge_connection_t *edgeconn;
entry_connection_t *entryconn2=NULL;
entry_connection_t *entryconn3=NULL;
/* Data cell not in the half-opened list */
PACK_CELL(4000, RELAY_COMMAND_DATA, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), msg);
else
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Sendme cell not in the half-opened list */
PACK_CELL(4000, RELAY_COMMAND_SENDME, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), msg);
else
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Connected cell not in the half-opened list */
PACK_CELL(4000, RELAY_COMMAND_CONNECTED, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), msg);
else
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Resolved cell not in the half-opened list */
PACK_CELL(4000, RELAY_COMMAND_RESOLVED, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), msg);
else
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_UNCOUNTED_BW();
edgeconn = ENTRY_TO_EDGE_CONN(entryconn2);
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), msg);
else
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_UNCOUNTED_BW();
ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), msg);
else
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_COUNTED_BW();
data_cells--;
ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), msg);
else
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_UNCOUNTED_BW();
ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), msg);
else
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_COUNTED_BW();
sendme_cells--;
ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), msg);
else
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_UNCOUNTED_BW();
ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), msg);
else
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_COUNTED_BW();
ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), msg);
else
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* sendme cell on open entryconn with full window */
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
int ret =
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
tt_int_op(ret, OP_EQ, -END_CIRC_REASON_TORPROTOCOL);
ASSERT_UNCOUNTED_BW();
connection_edge_reached_eof(edgeconn);
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), msg);
else
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_COUNTED_BW();
ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), msg);
else
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_UNCOUNTED_BW();
ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), msg);
else
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_COUNTED_BW();
ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
ret =
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
tt_int_op(ret, OP_NE, -END_CIRC_REASON_TORPROTOCOL);
ASSERT_UNCOUNTED_BW();
ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), msg);
else
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_UNCOUNTED_BW();
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_RESOLVED,
"\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), msg);
else
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_COUNTED_BW();
ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_RESOLVED,
"\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_UNCOUNTED_BW();
ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), msg);
else
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_UNCOUNTED_BW();
ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), msg);
else
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_UNCOUNTED_BW();
+ relay_msg_free(msg);
connection_free_minimal(ENTRY_TO_CONN(entryconn2));
connection_free_minimal(ENTRY_TO_CONN(entryconn3));
connection_free_minimal(ENTRY_TO_CONN(entryconn4));
return 1;
done:
+ relay_msg_free(msg);
connection_free_minimal(ENTRY_TO_CONN(entryconn2));
connection_free_minimal(ENTRY_TO_CONN(entryconn3));
connection_free_minimal(ENTRY_TO_CONN(entryconn4));
static void
test_circbw_relay(void *arg)
{
- cell_t cell;
- relay_header_t rh;
+ relay_msg_t *msg = NULL;
+ size_t len_tmp;
tor_addr_t addr;
edge_connection_t *edgeconn;
entry_connection_t *entryconn1=NULL;
/* Stream id 0: Not counted */
PACK_CELL(0, RELAY_COMMAND_END, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Stream id 1: Counted */
PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_COUNTED_BW();
/* Properly formatted connect cell: counted */
PACK_CELL(1, RELAY_COMMAND_CONNECTED, "Data1234");
+ tor_free(msg->body);
+ msg->body = tor_malloc(500);
tor_addr_parse(&addr, "30.40.50.60");
- rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE,
- &addr, 1024);
- relay_header_pack((uint8_t*)&cell.payload, &rh); \
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ msg->length = connected_cell_format_payload(msg->body,
+ &addr, 1024);
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_COUNTED_BW();
edgeconn->on_circuit = TO_CIRCUIT(circ);
PACK_CELL(1, RELAY_COMMAND_RESOLVED,
"\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_COUNTED_BW();
/* Connected cell after open: not counted */
PACK_CELL(1, RELAY_COMMAND_CONNECTED, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Resolved cell after open: not counted */
PACK_CELL(1, RELAY_COMMAND_RESOLVED, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Drop cell: not counted */
PACK_CELL(1, RELAY_COMMAND_DROP, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Data cell on stream 0: not counted */
PACK_CELL(0, RELAY_COMMAND_DATA, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Data cell on open connection: counted */
ENTRY_TO_CONN(entryconn1)->marked_for_close = 0;
PACK_CELL(1, RELAY_COMMAND_DATA, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_COUNTED_BW();
/* Empty Data cell on open connection: not counted */
ENTRY_TO_CONN(entryconn1)->marked_for_close = 0;
PACK_CELL(1, RELAY_COMMAND_DATA, "");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Sendme on valid stream: counted */
edgeconn->package_window -= STREAMWINDOW_INCREMENT;
PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_COUNTED_BW();
/* Sendme on valid stream with full window: not counted */
PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
edgeconn->package_window = STREAMWINDOW_START;
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Sendme on unknown stream: not counted */
PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Sendme on circuit with full window: not counted */
PACK_CELL(0, RELAY_COMMAND_SENDME, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_UNCOUNTED_BW();
circ->cpath->package_window = 901;
sendme_record_cell_digest_on_circ(TO_CIRCUIT(circ), circ->cpath);
circ->cpath->package_window = 900;
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_COUNTED_BW();
/* Invalid extended cell: not counted */
PACK_CELL(1, RELAY_COMMAND_EXTENDED2, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Invalid extended cell: not counted */
PACK_CELL(1, RELAY_COMMAND_EXTENDED, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Invalid HS cell: not counted */
PACK_CELL(1, RELAY_COMMAND_ESTABLISH_INTRO, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* "Valid" HS cell in expected state: counted */
TO_CIRCUIT(circ)->purpose = CIRCUIT_PURPOSE_C_ESTABLISH_REND;
PACK_CELL(1, RELAY_COMMAND_RENDEZVOUS_ESTABLISHED, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_COUNTED_BW();
/* End cell on non-closed connection: counted */
PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_COUNTED_BW();
/* End cell on connection that already got one: not counted */
PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ connection_edge_process_relay_cell(msg, TO_CIRCUIT(circ), NULL,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Path bias: truncated */
tt_int_op(circ->base_.marked_for_close, OP_EQ, 0);
PACK_CELL(0, RELAY_COMMAND_TRUNCATED, "Data1234");
- pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), msg);
tt_int_op(circ->base_.marked_for_close, OP_EQ, 1);
done:
+ relay_msg_free(msg);
UNMOCK(connection_start_reading);
UNMOCK(connection_mark_unattached_ap_);
UNMOCK(connection_mark_for_close_internal_);
{
entry_connection_t *entryconn;
edge_connection_t *edgeconn;
- cell_t cell;
- relay_header_t rh;
+ relay_msg_t *msg = NULL;
int r;
or_options_t *options = get_options_mutable();
+ size_t len_tmp;
#define SET_CELL(s) do { \
- memset(&cell, 0, sizeof(cell)); \
- memset(&rh, 0, sizeof(rh)); \
- memcpy(cell.payload + RELAY_HEADER_SIZE, (s), sizeof((s))-1); \
- rh.length = sizeof((s))-1; \
- rh.command = RELAY_COMMAND_RESOLVED; \
+ relay_msg_free(msg); \
+ msg = tor_malloc_zero(sizeof(relay_msg_t)); \
+ len_tmp = sizeof(s) - 1; \
+ msg->body = tor_malloc_zero(len_tmp); \
+ msg->length = len_tmp; \
+ memcpy(msg->body, s, len_tmp); \
} while (0)
#define MOCK_RESET() do { \
srm_ncalls = mum_ncalls = 0; \
tt_ptr_op(mum_conn, OP_EQ, entryconn); \
tt_int_op(mum_endreason, OP_EQ, (reason)); \
} while (0)
-#define ASSERT_RESOLVED_CALLED(atype, answer, ttl, expires) do { \
- tt_int_op(srm_ncalls, OP_EQ, 1); \
- tt_ptr_op(srm_conn, OP_EQ, entryconn); \
- tt_int_op(srm_atype, OP_EQ, (atype)); \
- if ((answer) != NULL) { \
- tt_int_op(srm_alen, OP_EQ, sizeof(answer)-1); \
- tt_int_op(srm_alen, OP_LT, 512); \
- tt_int_op(srm_answer_is_set, OP_EQ, 1); \
- tt_mem_op(srm_answer, OP_EQ, answer, sizeof(answer)-1); \
- } else { \
- tt_int_op(srm_answer_is_set, OP_EQ, 0); \
- } \
- tt_int_op(srm_ttl, OP_EQ, ttl); \
- tt_i64_op(srm_expires, OP_EQ, expires); \
+#define ASSERT_RESOLVED_CALLED(atype, answer, ttl, expires) do { \
+ tt_int_op(srm_ncalls, OP_EQ, 1); \
+ tt_ptr_op(srm_conn, OP_EQ, entryconn); \
+ tt_int_op(srm_atype, OP_EQ, (atype)); \
+ if ((answer) != NULL) { \
+ tt_int_op(srm_alen, OP_EQ, sizeof(answer)-1); \
+ tt_int_op(srm_alen, OP_LT, 512); \
+ tt_int_op(srm_answer_is_set, OP_EQ, 1); \
+ tt_mem_op(srm_answer, OP_EQ, answer, sizeof(answer)-1); \
+ } else { \
+ tt_int_op(srm_answer_is_set, OP_EQ, 0); \
+ } \
+ tt_int_op(srm_ttl, OP_EQ, ttl); \
+ tt_i64_op(srm_expires, OP_EQ, expires); \
} while (0)
(void)arg;
/* Try with connection in non-RESOLVE_WAIT state: cell gets ignored */
MOCK_RESET();
- r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
+ r = connection_edge_process_resolved_cell(edgeconn, msg);
tt_int_op(r, OP_EQ, 0);
tt_int_op(srm_ncalls, OP_EQ, 0);
tt_int_op(mum_ncalls, OP_EQ, 0);
/* We prefer ipv4, so we should get the first ipv4 answer */
MOCK_RESET();
- r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
+ r = connection_edge_process_resolved_cell(edgeconn, msg);
tt_int_op(r, OP_EQ, 0);
ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
/* But we may be discarding private answers. */
MOCK_RESET();
options->ClientDNSRejectInternalAddresses = 1;
- r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
+ r = connection_edge_process_resolved_cell(edgeconn, msg);
tt_int_op(r, OP_EQ, 0);
ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
/* now prefer ipv6, and get the first ipv6 answer */
entryconn->entry_cfg.prefer_ipv6 = 1;
MOCK_RESET();
- r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
+ r = connection_edge_process_resolved_cell(edgeconn, msg);
tt_int_op(r, OP_EQ, 0);
ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
/* With a cell that only has IPv4, we report IPv4 even if we prefer IPv6 */
MOCK_RESET();
SET_CELL("\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
- r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
+ r = connection_edge_process_resolved_cell(edgeconn, msg);
tt_int_op(r, OP_EQ, 0);
ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
* ipv4 */
MOCK_RESET();
entryconn->entry_cfg.ipv4_traffic = 0;
- r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
+ r = connection_edge_process_resolved_cell(edgeconn, msg);
tt_int_op(r, OP_EQ, 0);
ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
MOCK_RESET();
entryconn->entry_cfg.ipv4_traffic = 1;
entryconn->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR;
- r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
+ r = connection_edge_process_resolved_cell(edgeconn, msg);
tt_int_op(r, OP_EQ, 0);
ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
/* A hostname cell is fine though. */
MOCK_RESET();
SET_CELL("\x00\x0fwww.example.com\x00\x01\x00\x00");
- r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
+ r = connection_edge_process_resolved_cell(edgeconn, msg);
tt_int_op(r, OP_EQ, 0);
ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
MOCK_RESET();
entryconn->socks_request->command = SOCKS_COMMAND_RESOLVE;
SET_CELL("\x04\x04\x01\x02\x03\x04"); /* no ttl */
- r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
+ r = connection_edge_process_resolved_cell(edgeconn, msg);
tt_int_op(r, OP_EQ, 0);
ASSERT_MARK_CALLED(END_STREAM_REASON_TORPROTOCOL);
tt_int_op(srm_ncalls, OP_EQ, 0);
"\x04\x04\x7f\x00\x01\x02\x00\x00\x01\x00"
/* IPv4: 192.168.1.1, ttl 256 */
"\x04\x04\xc0\xa8\x01\x01\x00\x00\x01\x00");
- r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
+ r = connection_edge_process_resolved_cell(edgeconn, msg);
tt_int_op(r, OP_EQ, 0);
ASSERT_MARK_CALLED(END_STREAM_REASON_TORPROTOCOL);
ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_ERROR_TRANSIENT, NULL, 0, TIME_MAX);
/* Legit error code */
MOCK_RESET();
SET_CELL("\xf0\x15" "quiet and meaningless" "\x00\x00\x0f\xff");
- r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
+ r = connection_edge_process_resolved_cell(edgeconn, msg);
tt_int_op(r, OP_EQ, 0);
ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_ERROR_TRANSIENT, NULL, -1, -1);
done:
+ relay_msg_free(msg);
UNMOCK(connection_mark_unattached_ap_);
UNMOCK(connection_ap_handshake_socks_resolved);
}
test_package_payload_len(void *arg)
{
(void)arg;
- /* this is not a real circuit: it only has the fields needed for this
- * test. */
- circuit_t *c = tor_malloc_zero(sizeof(circuit_t));
+ or_circuit_t *or_circ = or_circuit_new(0, NULL);
+ crypt_path_t *cpath = NULL;
+ circuit_t *c = TO_CIRCUIT(or_circ);
+
+ or_circ->relay_cell_format = RELAY_CELL_FORMAT_V0;
/* check initial conditions. */
circuit_reset_sendme_randomness(c);
/* We have a bunch of cells before we need to send randomness, so the first
* few can be packaged full. */
int initial = c->send_randomness_after_n_cells;
- size_t n = connection_edge_get_inbuf_bytes_to_package(10000, 0, c);
+ size_t n = connection_edge_get_inbuf_bytes_to_package(10000, 0, c, cpath);
tt_uint_op(RELAY_PAYLOAD_SIZE, OP_EQ, n);
- n = connection_edge_get_inbuf_bytes_to_package(95000, 1, c);
+ n = connection_edge_get_inbuf_bytes_to_package(95000, 1, c, cpath);
tt_uint_op(RELAY_PAYLOAD_SIZE, OP_EQ, n);
tt_int_op(c->send_randomness_after_n_cells, OP_EQ, initial - 2);
/* If package_partial isn't set, we won't package a partially full cell at
* all. */
- n = connection_edge_get_inbuf_bytes_to_package(RELAY_PAYLOAD_SIZE-1, 0, c);
+ n = connection_edge_get_inbuf_bytes_to_package(RELAY_PAYLOAD_SIZE-1, 0,
+ c, cpath);
tt_int_op(n, OP_EQ, 0);
/* no change in our state, since nothing was sent. */
tt_assert(! c->have_sent_sufficiently_random_cell);
/* If package_partial is set and the partial cell is not going to have
* _enough_ randomness, we package it, but we don't consider ourselves to
* have sent a sufficiently random cell. */
- n = connection_edge_get_inbuf_bytes_to_package(RELAY_PAYLOAD_SIZE-1, 1, c);
+ n = connection_edge_get_inbuf_bytes_to_package(RELAY_PAYLOAD_SIZE-1, 1,
+ c, cpath);
tt_int_op(n, OP_EQ, RELAY_PAYLOAD_SIZE-1);
tt_assert(! c->have_sent_sufficiently_random_cell);
tt_int_op(c->send_randomness_after_n_cells, OP_EQ, initial - 3);
/* Make sure we set have_set_sufficiently_random_cell as appropriate. */
- n = connection_edge_get_inbuf_bytes_to_package(RELAY_PAYLOAD_SIZE-64, 1, c);
+ n = connection_edge_get_inbuf_bytes_to_package(RELAY_PAYLOAD_SIZE-64, 1,
+ c, cpath);
tt_int_op(n, OP_EQ, RELAY_PAYLOAD_SIZE-64);
tt_assert(c->have_sent_sufficiently_random_cell);
tt_int_op(c->send_randomness_after_n_cells, OP_EQ, initial - 4);
* sent a sufficiently random cell, we will not force this one to have a gap.
*/
c->send_randomness_after_n_cells = 0;
- n = connection_edge_get_inbuf_bytes_to_package(10000, 1, c);
+ n = connection_edge_get_inbuf_bytes_to_package(10000, 1, c, cpath);
tt_int_op(n, OP_EQ, RELAY_PAYLOAD_SIZE);
/* Now these will be reset. */
tt_assert(! c->have_sent_sufficiently_random_cell);
/* What would happen if we hadn't sent a sufficiently random cell? */
c->send_randomness_after_n_cells = 0;
- n = connection_edge_get_inbuf_bytes_to_package(10000, 1, c);
+ n = connection_edge_get_inbuf_bytes_to_package(10000, 1, c, cpath);
const size_t reduced_payload_size = RELAY_PAYLOAD_SIZE - 4 - 16;
tt_int_op(n, OP_EQ, reduced_payload_size);
/* Now these will be reset. */
* package_partial==0 should mean we accept that many bytes.
*/
c->send_randomness_after_n_cells = 0;
- n = connection_edge_get_inbuf_bytes_to_package(reduced_payload_size, 0, c);
+ n = connection_edge_get_inbuf_bytes_to_package(reduced_payload_size, 0,
+ c, cpath);
tt_int_op(n, OP_EQ, reduced_payload_size);
done:
- tor_free(c);
+ circuit_free(c);
}
/* Check that circuit_sendme_is_next works with a window of 1000,