]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
prop340: Use relay messages accross the code
authorDavid Goulet <dgoulet@torproject.org>
Thu, 5 Oct 2023 16:29:54 +0000 (12:29 -0400)
committerNick Mathewson <nickm@torproject.org>
Mon, 5 May 2025 17:07:04 +0000 (13:07 -0400)
Author: David Goulet <dgoulet@torproject.org>

(This won't yet compile; for now I am _only_ taking the parts as
dgoulet wrote them, minus a codec-only piece.)

Modified by nickm:

Encode and decode relay messages using our new functions.

In David's original branch, this was done using codec objects,
but since we aren't doing prop340, this is simpler.

26 files changed:
src/core/or/circuitpadding.c
src/core/or/circuitpadding.h
src/core/or/conflux.c
src/core/or/conflux.h
src/core/or/conflux_cell.c
src/core/or/conflux_cell.h
src/core/or/conflux_pool.c
src/core/or/conflux_pool.h
src/core/or/congestion_control_flow.c
src/core/or/congestion_control_flow.h
src/core/or/connection_edge.c
src/core/or/connection_edge.h
src/core/or/relay.c
src/core/or/relay.h
src/core/or/relay_msg.h
src/feature/client/circpathbias.c
src/feature/client/circpathbias.h
src/feature/relay/circuitbuild_relay.c
src/feature/relay/circuitbuild_relay.h
src/test/test_cell_formats.c
src/test/test_circuitbuild.c
src/test/test_circuitpadding.c
src/test/test_conflux_cell.c
src/test/test_conflux_pool.c
src/test/test_relaycell.c
src/test/test_sendme.c

index 590a2d60c945b324209d62893a5852d212ecebd7..018d14b28f6c035c0c0f7384f9ab149c889585c3 100644 (file)
@@ -1846,22 +1846,21 @@ circpad_cell_event_nonpadding_sent(circuit_t *on_circ)
  *  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;
   }
 
@@ -1888,7 +1887,7 @@ circpad_check_received_cell(cell_t *cell, circuit_t *circ,
   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;
   }
@@ -2969,7 +2968,7 @@ circpad_padding_negotiated(circuit_t *circ,
  * 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? */
@@ -2983,8 +2982,7 @@ circpad_handle_padding_negotiate(circuit_t *circ, cell_t *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;
@@ -3057,7 +3055,7 @@ circpad_handle_padding_negotiate(circuit_t *circ, cell_t *cell)
  * 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;
@@ -3076,8 +3074,7 @@ circpad_handle_padding_negotiated(circuit_t *circ, cell_t *cell,
     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);
index 306d178684590d77ba27201aee264e97caf0e826..419701a68619a85a08968ccebae6080693ac928a 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "trunnel/circpad_negotiation.h"
 #include "lib/evloop/timers.h"
+#include "core/or/relay_msg_st.h"
 
 struct circuit_t;
 struct origin_circuit_t;
@@ -736,9 +737,9 @@ const circpad_machine_spec_t *circpad_string_to_machine(const char *str);
 
 /* 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,
@@ -753,9 +754,8 @@ bool circpad_padding_negotiated(struct circuit_t *circ,
 
 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 *));
index 9025dcffaf09cc5a5ed8ead58af270cb2a7bdde2..b657eb00ef378293f009371e8186c38378e737a6 100644 (file)
@@ -6,6 +6,7 @@
  * \brief Conflux multipath core algorithms
  */
 
+#include "core/or/relay_msg.h"
 #define TOR_CONFLUX_PRIVATE
 
 #include "core/or/or.h"
@@ -169,7 +170,7 @@ uint64_t
 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;
 }
@@ -680,8 +681,8 @@ conflux_queue_cmp(const void *a, const void *b)
 {
   // 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);
@@ -732,12 +733,11 @@ circuit_ccontrol(const circuit_t *circ)
  */
 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;
@@ -781,7 +781,7 @@ conflux_process_switch_command(circuit_t *in_circ,
     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
@@ -816,7 +816,7 @@ conflux_process_switch_command(circuit_t *in_circ,
   /* 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;
@@ -830,8 +830,8 @@ conflux_process_switch_command(circuit_t *in_circ,
  * 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.
@@ -867,14 +867,19 @@ conflux_process_cell(conflux_t *cfx, circuit_t *in_circ,
     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 */
@@ -888,10 +893,10 @@ conflux_process_cell(conflux_t *cfx, circuit_t *in_circ,
  * 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;
 
@@ -901,11 +906,21 @@ conflux_dequeue_cell(conflux_t *cfx)
    * 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);
+  }
+}
index e01b3233178431df734f50f99285299283d44c1e..1594039e2642a32a1f61257e1874019b54a8faf9 100644 (file)
@@ -11,6 +11,7 @@
 
 #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;
@@ -24,8 +25,7 @@ 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
@@ -37,10 +37,10 @@ typedef struct {
    */
   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);
@@ -54,15 +54,16 @@ circuit_t *conflux_decide_circ_for_send(conflux_t *cfx,
 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
index a59fa735f139c0c85ef49ca6dbfbda97e35e625a..24b85e300579e820b74878603e9f4af08ea759d6 100644 (file)
@@ -226,16 +226,14 @@ conflux_cell_parse_link_v1(const trn_cell_conflux_link_t *trn_link)
 }
 
 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;
@@ -258,10 +256,10 @@ 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_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 *
@@ -284,15 +282,15 @@ conflux_cell_new_link(const uint8_t *nonce, uint64_t last_seqno_sent,
  * 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.
index 60fff42241cc476fee1abd34f108e5454506f972..74c9596e750427342248bee04b0ef5ad940a06df 100644 (file)
@@ -10,6 +10,7 @@
 #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;
@@ -25,12 +26,9 @@ conflux_cell_link_t *conflux_cell_new_link(const uint8_t *nonce,
                                            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);
index 82043d607f6ecdda91ca8295a1c85a0f8eb307c8..9bfaf22b575c6bfa075a93bcea3eda233da1d87b 100644 (file)
@@ -196,7 +196,7 @@ conflux_free_(conflux_t *cfx)
   } 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));
@@ -1763,14 +1763,13 @@ conflux_circuit_has_opened(origin_circuit_t *orig_circ)
 
 /** 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);
@@ -1810,7 +1809,7 @@ conflux_process_link(circuit_t *circ, const cell_t *cell,
   }
 
   /* 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.");
@@ -1875,8 +1874,7 @@ conflux_process_link(circuit_t *circ, const cell_t *cell,
 /** 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;
 
@@ -1936,7 +1934,7 @@ conflux_process_linked(circuit_t *circ, crypt_path_t *layer_hint,
   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;
   }
@@ -2008,7 +2006,7 @@ conflux_process_linked(circuit_t *circ, crypt_path_t *layer_hint,
   }
 
   /* 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;
 
index eba726b03a1c14a818eb9f020813c2d4aea5bae5..7c97f495029694c183eb269654703e3c5a805b7c 100644 (file)
@@ -10,6 +10,7 @@
 #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);
@@ -31,10 +32,9 @@ void conflux_circuit_has_closed(circuit_t *circ);
 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;
index fa9455a8a15ade7bd970dabd4994c5db4a59b32f..4e1c545870a57bcf70e531b1a6fb0d753e726fe3 100644 (file)
@@ -232,10 +232,8 @@ circuit_send_stream_xon(edge_connection_t *stream)
  */
 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)) {
@@ -327,7 +325,7 @@ circuit_process_stream_xoff(edge_connection_t *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;
@@ -351,8 +349,7 @@ circuit_process_stream_xon(edge_connection_t *conn,
     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;
index 05e25c44d0e3ae0f116b3b7d95f34cf5cc56c092..74545ef882dd16bfacc9ce71391f45706f78961f 100644 (file)
 #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);
index b36d0d901388b2ee555ab81721fd47951b41478e..14a45a7b539fb6b80e6761dcf4685cee78c9fbf8 100644 (file)
@@ -3816,33 +3816,27 @@ connection_ap_handshake_socks_reply(entry_connection_t *conn, char *reply,
  * 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.");
@@ -3865,7 +3859,7 @@ begin_cell_parse(const cell_t *cell, begin_cell_t *bcell,
     *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;
@@ -3978,10 +3972,9 @@ handle_hs_exit_conn(circuit_t *circ, edge_connection_t *conn)
  * 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;
@@ -4002,25 +3995,22 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
     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;
   }
 
@@ -4044,7 +4034,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
                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,
@@ -4053,11 +4043,12 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
         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
@@ -4075,8 +4066,8 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
                * 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;
   }
@@ -4087,7 +4078,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
     /* 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;
     }
@@ -4104,7 +4095,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
 
   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;
@@ -4119,7 +4110,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
 
     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;
   }
@@ -4130,7 +4121,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
 
   /* 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;
@@ -4138,7 +4129,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
 
   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 &&
@@ -4159,8 +4150,8 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
     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:
@@ -4176,7 +4167,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
       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;
@@ -4196,16 +4187,12 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
  * 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);
@@ -4218,10 +4205,8 @@ connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ)
    * 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;
index 1bb0e6d368d52f99f444776b2c913593a90b2e38..6045bffc80a65010d9c6e2394706d483aa995684 100644 (file)
@@ -12,6 +12,8 @@
 #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"
 
@@ -129,8 +131,8 @@ void connection_ap_handshake_socks_resolved_addr(entry_connection_t *conn,
                                                  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,
@@ -268,8 +270,8 @@ typedef struct begin_cell_t {
   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);
index b78f8f4e000f9ced3d22b7be772c87467d0892ac..8aa74fafbb5b03b0daeb4e9ccbe524cfc78d6802 100644 (file)
@@ -45,7 +45,7 @@
  * 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"
@@ -85,6 +85,8 @@
 #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);
 
@@ -120,11 +124,10 @@ static void adjust_exit_policy_from_exitpolicy_failure(origin_circuit_t *circ,
                                                   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);
@@ -257,37 +260,50 @@ circuit_receive_relay_cell(cell_t *cell, circuit_t *circ,
 
   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,
@@ -297,9 +313,11 @@ circuit_receive_relay_cell(cell_t *cell, circuit_t *circ,
           log_warn(LD_OR,
                    "connection_edge_process_relay_cell (at origin) failed.");
         }
+        relay_msg_free(msg);
         return reason;
       }
     }
+    relay_msg_free(msg);
     return 0;
   }
 
@@ -444,15 +462,12 @@ circuit_package_relay_cell, (cell_t *cell, circuit_t *circ,
  * 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
@@ -461,19 +476,19 @@ relay_lookup_conn(circuit_t *circ, cell_t *cell,
   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;
@@ -481,9 +496,9 @@ relay_lookup_conn(circuit_t *circ, cell_t *cell,
     }
     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;
       }
     }
@@ -562,10 +577,6 @@ relay_command_to_string(uint8_t command)
   }
 }
 
-/** 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
@@ -607,9 +618,28 @@ relay_send_command_from_edge_,(streamid_t stream_id, circuit_t *orig_circ,
   /* 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);
@@ -621,18 +651,6 @@ relay_send_command_from_edge_,(streamid_t stream_id, circuit_t *orig_circ,
     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");
 
@@ -822,16 +840,16 @@ edge_reason_is_retriable(int reason)
  */
 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
@@ -854,9 +872,9 @@ connection_ap_process_end_not_open(
   }
 
   /* 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;
   }
 
@@ -875,19 +893,17 @@ connection_ap_process_end_not_open(
       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,",
@@ -1009,7 +1025,7 @@ connection_ap_process_end_not_open(
 
   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)
@@ -1082,17 +1098,17 @@ remap_event_helper(entry_connection_t *conn, const tor_addr_t *new_addr)
  * 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));
 
@@ -1100,13 +1116,13 @@ connected_cell_parse(const relay_header_t *rh, const cell_t *cell,
   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;
@@ -1134,8 +1150,8 @@ address_ttl_free_(address_ttl_t *addr)
  * 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;
@@ -1145,21 +1161,20 @@ resolved_cell_parse(const cell_t *cell, const relay_header_t *rh,
   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)
@@ -1306,8 +1321,7 @@ connection_ap_handshake_socks_got_resolved_cell(entry_connection_t *conn,
  * 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;
@@ -1321,7 +1335,7 @@ connection_edge_process_resolved_cell(edge_connection_t *conn,
   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);
@@ -1354,7 +1368,7 @@ connection_edge_process_resolved_cell(edge_connection_t *conn,
   /* 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,
@@ -1381,27 +1395,26 @@ connection_edge_process_resolved_cell(edge_connection_t *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);
@@ -1416,9 +1429,9 @@ connection_edge_process_relay_cell_not_open(
     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);
@@ -1496,7 +1509,7 @@ connection_edge_process_relay_cell_not_open(
     }
 
     /* 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) {
@@ -1507,13 +1520,13 @@ connection_edge_process_relay_cell_not_open(
     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);
@@ -1529,19 +1542,18 @@ connection_edge_process_relay_cell_not_open(
  * 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;
     }
@@ -1557,22 +1569,22 @@ process_sendme_cell(const relay_header_t *rh, const cell_t *cell,
     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;
@@ -1606,35 +1618,35 @@ process_sendme_cell(const relay_header_t *rh, const cell_t *cell,
  *  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 &&
@@ -1655,7 +1667,7 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
                "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
@@ -1665,11 +1677,11 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
         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;
@@ -1677,16 +1689,16 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
         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;
       }
 
@@ -1700,20 +1712,19 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
         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
@@ -1739,16 +1750,16 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
           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;
@@ -1758,35 +1769,34 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
           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;
           }
         }
@@ -1818,7 +1828,7 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
 
         /* 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;
@@ -1826,18 +1836,18 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
     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;
@@ -1851,11 +1861,11 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
         } 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:
@@ -1867,9 +1877,8 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
       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;
@@ -1887,7 +1896,7 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
       }
       /* 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:
@@ -1905,7 +1914,7 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
         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,
@@ -1930,11 +1939,9 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
       /* 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) {
@@ -1946,11 +1953,11 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
       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;
         }
       }
@@ -1958,10 +1965,10 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
       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,
@@ -1977,7 +1984,7 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
                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,
@@ -1989,11 +1996,11 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
         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;
         }
       }
@@ -2011,14 +2018,13 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
     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 */
 }
 
@@ -2032,39 +2038,31 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
  * 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:
         ;
@@ -2074,7 +2072,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
   /* 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. */
@@ -2098,37 +2096,39 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
    * 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);
       }
     }
   }
@@ -2140,17 +2140,17 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
  * 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. */
@@ -2158,22 +2158,21 @@ connection_edge_process_ordered_relay_cell(cell_t *cell, circuit_t *circ,
     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? */
@@ -2203,13 +2202,6 @@ circuit_reset_sendme_randomness(circuit_t *circ)
     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.
@@ -2217,7 +2209,8 @@ circuit_reset_sendme_randomness(circuit_t *circ)
 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;
@@ -2227,12 +2220,18 @@ connection_edge_get_inbuf_bytes_to_package(size_t n_available,
     (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. */
@@ -2249,7 +2248,7 @@ connection_edge_get_inbuf_bytes_to_package(size_t n_available,
   /* 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;
@@ -2341,7 +2340,8 @@ connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial,
   }
 
   length = connection_edge_get_inbuf_bytes_to_package(bytes_to_process,
-                                                      package_partial, circ);
+                                                      package_partial, circ,
+                                                      cpath_layer);
   if (!length)
     return 0;
 
index 492fee9c37f06c2edaf920bfea1d8bf6cfa7b9ec..a63a465bf28785a2878814dd4489a569b247e3ad 100644 (file)
@@ -12,6 +12,8 @@
 #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;
@@ -110,12 +112,12 @@ uint8_t packed_cell_get_command(const packed_cell_t *cell, int wide_circ_ids);
 
 #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;
@@ -125,21 +127,22 @@ typedef struct address_ttl_t {
 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) */
 
index b52123ab68fa1479c8e26bb31c3944e008fe7deb..cec56d6b28fff96433fb8f71e8548dbc0be2607b 100644 (file)
@@ -35,6 +35,9 @@ relay_msg_t *relay_msg_decode_cell(
 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 */
index 144a53c9723a1fd272b4f178536b36092cdea9fa..c7b42ecfaee38bbb9b6417dd1fb45813a85b1dfb 100644 (file)
 #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"
@@ -903,41 +904,37 @@ pathbias_send_usable_probe(circuit_t *circ)
  * 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.",
@@ -954,7 +951,7 @@ pathbias_check_probe_response(circuit_t *circ, const cell_t *cell)
   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;
 }
 
@@ -963,58 +960,54 @@ pathbias_check_probe_response(circuit_t *circ, const cell_t *cell)
  * 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;
   }
index e92756ae78761c5edf14dc43cd030b923feb215c..59750c752194b2cea02fe14074784ef9b9247798 100644 (file)
@@ -12,6 +12,8 @@
 #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);
@@ -19,8 +21,8 @@ void pathbias_count_timeout(origin_circuit_t *circ);
 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);
index 5ece5b4adc6570ec674c2e6defcff6da2c1cd5ae..4a2b3814be11c0666e1b1a82cd51f77e0177c3cd 100644 (file)
@@ -421,15 +421,14 @@ circuit_open_connection_for_extend(const struct extend_cell_t *ec,
  * 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;
   }
 
@@ -440,17 +439,13 @@ circuit_extend(struct cell_t *cell, struct circuit_t *circ)
   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;
index 307825bb5c1fa20e6fcba06ab6f08286c36a8f8c..0148aa5581f1f20510c1812a52d255dd7d1425a8 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "lib/cc/torint.h"
 #include "lib/log/log.h"
+#include "core/or/relay_msg_st.h"
 
 #include "app/config/config.h"
 
@@ -34,7 +35,7 @@ circuitbuild_warn_client_extend(void)
 
 #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,
@@ -44,9 +45,9 @@ int onionskin_answer(struct or_circuit_t *circ,
 #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;
index d3ad68f89add95e26cbe01e4dea5f5bbd6dbcdc7..178aec2ab2d409913ba0cf68cb463287da99781e 100644 (file)
@@ -54,35 +54,28 @@ test_cfmt_relay_header(void *arg)
 }
 
 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);
@@ -91,8 +84,8 @@ test_cfmt_begin_cells(void *arg)
 
   /* 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);
@@ -101,8 +94,8 @@ test_cfmt_begin_cells(void *arg)
 
   /* 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);
@@ -113,21 +106,21 @@ test_cfmt_begin_cells(void *arg)
   /* 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);
@@ -137,9 +130,9 @@ test_cfmt_begin_cells(void *arg)
 
   /* 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);
@@ -151,88 +144,85 @@ test_cfmt_begin_cells(void *arg)
   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);
@@ -241,144 +231,129 @@ test_cfmt_begin_cells(void *arg)
 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");
@@ -825,15 +800,15 @@ static void
 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_,      \
@@ -842,9 +817,10 @@ test_cfmt_resolved_cells(void *arg)
   } 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)
 
@@ -857,7 +833,7 @@ test_cfmt_resolved_cells(void *arg)
 
   /* 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);
@@ -865,8 +841,8 @@ test_cfmt_resolved_cells(void *arg)
 
   /* 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);
@@ -881,8 +857,8 @@ test_cfmt_resolved_cells(void *arg)
            "\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);
@@ -896,8 +872,8 @@ test_cfmt_resolved_cells(void *arg)
   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);
@@ -917,8 +893,8 @@ test_cfmt_resolved_cells(void *arg)
   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);
@@ -932,8 +908,8 @@ test_cfmt_resolved_cells(void *arg)
   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);
@@ -942,8 +918,8 @@ test_cfmt_resolved_cells(void *arg)
   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);
@@ -953,8 +929,8 @@ test_cfmt_resolved_cells(void *arg)
   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);
@@ -981,7 +957,7 @@ test_cfmt_resolved_cells(void *arg)
            "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);
@@ -1013,7 +989,7 @@ test_cfmt_resolved_cells(void *arg)
            "\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);
@@ -1053,8 +1029,8 @@ test_cfmt_resolved_cells(void *arg)
            "\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);
@@ -1068,68 +1044,71 @@ test_cfmt_resolved_cells(void *arg)
 
   /* 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);
 
@@ -1137,19 +1116,19 @@ test_cfmt_resolved_cells(void *arg)
            "\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);
 
index 0a5c3530bd5aec44963278fd56cc8ec9ad0e77b5..9bebcc2873f48732029ae0f20c2d545000971b10 100644 (file)
@@ -21,6 +21,7 @@
 #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"
@@ -1278,7 +1279,7 @@ static void
 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);
@@ -1293,10 +1294,13 @@ test_circuit_extend(void *arg)
 
   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))");
@@ -1308,7 +1312,7 @@ test_circuit_extend(void *arg)
   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();
 
@@ -1324,13 +1328,13 @@ test_circuit_extend(void *arg)
 
   /* 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();
 
@@ -1343,7 +1347,7 @@ test_circuit_extend(void *arg)
   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");
@@ -1354,7 +1358,7 @@ test_circuit_extend(void *arg)
   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");
@@ -1368,7 +1372,7 @@ test_circuit_extend(void *arg)
 
 #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,
@@ -1389,7 +1393,7 @@ test_circuit_extend(void *arg)
   /* 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);
 
@@ -1409,7 +1413,7 @@ test_circuit_extend(void *arg)
   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);
@@ -1433,7 +1437,7 @@ test_circuit_extend(void *arg)
   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);
@@ -1456,7 +1460,7 @@ test_circuit_extend(void *arg)
   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);
@@ -1502,7 +1506,7 @@ test_circuit_extend(void *arg)
   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);
index 95401465c1e0d408bb83afd69468002cace45830..a16a169cdf4becf6ecbc20d504f971fd4af72b86 100644 (file)
@@ -24,6 +24,7 @@
 #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"
@@ -172,11 +173,16 @@ circuit_package_relay_cell_mock(cell_t *cell, circuit_t *circ,
                            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,
@@ -190,7 +196,7 @@ circuit_package_relay_cell_mock(cell_t *cell, circuit_t *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) {
@@ -199,11 +205,11 @@ circuit_package_relay_cell_mock(cell_t *cell, circuit_t *circ,
     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.
@@ -211,7 +217,7 @@ circuit_package_relay_cell_mock(cell_t *cell, circuit_t *circ,
 
       // 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);
     }
 
@@ -219,6 +225,7 @@ circuit_package_relay_cell_mock(cell_t *cell, circuit_t *circ,
   }
 
  done:
+  relay_msg_free(msg);
   timers_advance_and_run(1);
   return 0;
 }
@@ -1251,7 +1258,7 @@ test_circuitpadding_wronghop(void *arg)
    */
   (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;
@@ -1331,17 +1338,20 @@ test_circuitpadding_wronghop(void *arg)
             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);
 
@@ -1350,7 +1360,7 @@ test_circuitpadding_wronghop(void *arg)
   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);
@@ -1371,12 +1381,12 @@ test_circuitpadding_wronghop(void *arg)
   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);
 
@@ -1434,6 +1444,7 @@ test_circuitpadding_wronghop(void *arg)
   UNMOCK(circuitmux_attach_circuit);
   nodes_free();
   testing_disable_reproducible_rng();
+  relay_msg_clear(&msg);
 }
 
 void
@@ -3100,17 +3111,18 @@ static 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");
 
index bb440d0d0a9b42b235cd408c5472392b335f5527..7e02f5476426fbda44083259f5f4c7e43e75051d 100644 (file)
 #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;
 
@@ -34,10 +36,12 @@ test_link(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];
@@ -49,6 +53,7 @@ test_link(void *arg)
   tor_free(decoded_link);
 
  done:
+  relay_msg_clear(&msg);
   tor_free(decoded_link);
 }
 
@@ -57,4 +62,3 @@ struct testcase_t conflux_cell_tests[] = {
 
   END_OF_TESTCASES
 };
-
index 6fe3c8b65b01f1ec2eddacdba734b5857455fecf..1294a8256b57d9330a482be51444200533fb7915 100644 (file)
@@ -29,6 +29,7 @@
 #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"
@@ -223,6 +224,7 @@ static void
 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);
@@ -232,16 +234,20 @@ process_mock_cell_delivery(void)
 
   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));
@@ -253,12 +259,13 @@ process_mock_cell_delivery(void)
     // 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;
 }
 
index 6edc1030f900c2b6583e979ad13d0fa065c02baf..ed5732b1f32156c708cfb6f962f4212382308af2 100644 (file)
@@ -19,6 +19,7 @@
 #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"
 
@@ -173,18 +174,19 @@ fake_entry_conn(origin_circuit_t *oncirc, streamid_t id)
 }
 
 #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)
@@ -196,8 +198,8 @@ fake_entry_conn(origin_circuit_t *oncirc, streamid_t id)
 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;
@@ -225,36 +227,36 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
   /* 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();
 
@@ -262,9 +264,9 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
   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();
 
@@ -273,9 +275,9 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
     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--;
@@ -283,9 +285,9 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
   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();
 
@@ -294,9 +296,9 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
     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--;
@@ -304,9 +306,9 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
   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();
 
@@ -314,18 +316,18 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
   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();
 
@@ -335,7 +337,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
   /* 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();
@@ -346,18 +348,18 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
   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();
 
@@ -365,16 +367,16 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
   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();
@@ -382,9 +384,9 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
   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();
 
@@ -400,16 +402,16 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
   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();
 
@@ -417,9 +419,9 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
   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();
 
@@ -427,17 +429,19 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
   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));
@@ -666,8 +670,8 @@ test_halfstream_wrap(void *arg)
 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;
@@ -692,23 +696,24 @@ test_circbw_relay(void *arg)
 
   /* 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();
 
@@ -718,7 +723,7 @@ test_circbw_relay(void *arg)
   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();
 
@@ -727,65 +732,65 @@ test_circbw_relay(void *arg)
 
   /* 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();
 
@@ -796,44 +801,44 @@ test_circbw_relay(void *arg)
   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();
 
@@ -848,10 +853,11 @@ test_circbw_relay(void *arg)
   /* 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_);
@@ -872,17 +878,18 @@ test_relaycell_resolved(void *arg)
 {
   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;                \
@@ -892,20 +899,20 @@ test_relaycell_resolved(void *arg)
     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;
@@ -930,7 +937,7 @@ test_relaycell_resolved(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);
@@ -944,7 +951,7 @@ test_relaycell_resolved(void *arg)
 
   /* 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);
@@ -953,7 +960,7 @@ test_relaycell_resolved(void *arg)
   /* 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);
@@ -962,7 +969,7 @@ test_relaycell_resolved(void *arg)
   /* 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);
@@ -974,7 +981,7 @@ test_relaycell_resolved(void *arg)
   /* 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);
@@ -984,7 +991,7 @@ test_relaycell_resolved(void *arg)
    * 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);
@@ -994,7 +1001,7 @@ test_relaycell_resolved(void *arg)
   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);
@@ -1003,7 +1010,7 @@ test_relaycell_resolved(void *arg)
   /* 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);
@@ -1013,7 +1020,7 @@ test_relaycell_resolved(void *arg)
   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);
@@ -1024,7 +1031,7 @@ test_relaycell_resolved(void *arg)
            "\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);
@@ -1032,13 +1039,14 @@ test_relaycell_resolved(void *arg)
   /* 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);
 }
index 6dd18425019afe240238dd07d3a50ab893313f2b..7ece88c2ccbf44a4ec4267fe72843fc5d71c1a89 100644 (file)
@@ -235,9 +235,11 @@ static void
 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);
@@ -248,15 +250,16 @@ test_package_payload_len(void *arg)
   /* 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);
@@ -265,13 +268,15 @@ test_package_payload_len(void *arg)
   /* 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);
@@ -280,7 +285,7 @@ test_package_payload_len(void *arg)
    * 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);
@@ -289,7 +294,7 @@ test_package_payload_len(void *arg)
 
   /* 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. */
@@ -301,11 +306,12 @@ test_package_payload_len(void *arg)
    * 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,