]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Rename and hand-audit all users of RELAY_PAYLOAD_SIZE.
authorNick Mathewson <nickm@torproject.org>
Fri, 18 Apr 2025 00:21:06 +0000 (20:21 -0400)
committerNick Mathewson <nickm@torproject.org>
Mon, 5 May 2025 17:07:37 +0000 (13:07 -0400)
Since the maximum number of bytes you can put in a relay message
is no longer constant, it doesn't make sense to have a "size" for this.
Instead, we can only have a "max" or "min" size.

19 files changed:
src/app/main/main.c
src/core/mainloop/connection.c
src/core/or/circuitbuild.c
src/core/or/circuituse.c
src/core/or/command.c
src/core/or/conflux_cell.c
src/core/or/congestion_control_flow.c
src/core/or/connection_edge.c
src/core/or/onion.c
src/core/or/onion.h
src/core/or/or.h
src/core/or/relay.c
src/core/or/sendme.c
src/core/or/status.c
src/feature/client/circpathbias.c
src/feature/hs/hs_cell.c
src/feature/hs/hs_circuit.c
src/feature/relay/dns.c
src/test/test_cell_formats.c

index 962e6e9d672aecd10b23abf43d32aa4dadc7a71c..b4957ce0d9fa172665db0c2bc4b34b508352d53e 100644 (file)
@@ -377,6 +377,7 @@ dumpstats(int severity)
   channel_dumpstats(severity);
   channel_listener_dumpstats(severity);
 
+  // TODO CGO: Use of RELAY_PAYLOAD_SIZE_MAX may make this a bit wrong.
   tor_log(severity, LD_NET,
       "Cells processed: %"PRIu64" padding\n"
       "                 %"PRIu64" create\n"
@@ -395,11 +396,11 @@ dumpstats(int severity)
   if (stats_n_data_cells_packaged)
     tor_log(severity,LD_NET,"Average packaged cell fullness: %2.3f%%",
         100*(((double)stats_n_data_bytes_packaged) /
-             ((double)stats_n_data_cells_packaged*RELAY_PAYLOAD_SIZE)) );
+             ((double)stats_n_data_cells_packaged*RELAY_PAYLOAD_SIZE_MAX)) );
   if (stats_n_data_cells_received)
     tor_log(severity,LD_NET,"Average delivered cell fullness: %2.3f%%",
         100*(((double)stats_n_data_bytes_received) /
-             ((double)stats_n_data_cells_received*RELAY_PAYLOAD_SIZE)) );
+             ((double)stats_n_data_cells_received*RELAY_PAYLOAD_SIZE_MAX)) );
 
   cpuworker_log_onionskin_overhead(severity, ONION_HANDSHAKE_TYPE_TAP, "TAP");
   cpuworker_log_onionskin_overhead(severity, ONION_HANDSHAKE_TYPE_NTOR,"ntor");
index 559c640f426e3ec878302da148dfa862a2de8b97..d8fd4839f939b0bca692c9e093a0ee6a59d03fb9 100644 (file)
@@ -3481,7 +3481,7 @@ connection_bucket_get_share(int base, int priority,
 static ssize_t
 connection_bucket_read_limit(connection_t *conn, time_t now)
 {
-  int base = RELAY_PAYLOAD_SIZE;
+  int base = RELAY_PAYLOAD_SIZE_MAX;
   int priority = conn->type != CONN_TYPE_DIR;
   ssize_t conn_bucket = -1;
   size_t global_bucket_val = token_bucket_rw_get_read(&global_bucket);
@@ -3535,7 +3535,7 @@ connection_bucket_read_limit(connection_t *conn, time_t now)
 ssize_t
 connection_bucket_write_limit(connection_t *conn, time_t now)
 {
-  int base = RELAY_PAYLOAD_SIZE;
+  int base = RELAY_PAYLOAD_SIZE_MAX;
   int priority = conn->type != CONN_TYPE_DIR;
   size_t conn_bucket = buf_datalen(conn->outbuf);
   size_t global_bucket_val = token_bucket_rw_get_write(&global_bucket);
index 5047724a7208141ed673fdafdd6967f9a3d447f2..da8b51c374533c4ca6bdabafa0a8a1c76112b62f 100644 (file)
@@ -1185,12 +1185,18 @@ circuit_send_intermediate_onion_skin(origin_circuit_t *circ,
   {
     uint8_t command = 0;
     uint16_t payload_len=0;
-    uint8_t payload[RELAY_PAYLOAD_SIZE];
+    uint8_t payload[RELAY_PAYLOAD_SIZE_MAX];
     if (extend_cell_format(&command, &payload_len, payload, &ec)<0) {
       log_warn(LD_CIRC,"Couldn't format extend cell");
       return -END_CIRC_REASON_INTERNAL;
     }
 
+    if (payload_len > circuit_max_relay_payload(
+                             TO_CIRCUIT(circ), hop->prev, command)) {
+      log_warn(LD_BUG, "Generated a too-long extend cell");
+      return -END_CIRC_REASON_INTERNAL;
+    }
+
     /* send it to hop->prev, because that relay will transfer
      * it to a create cell and then send to hop */
     if (relay_send_command_from_edge(0, TO_CIRCUIT(circ),
index e114a52541f6f56aff345113c3af998fa022fb6c..1967593cfa2b42c35d340f292d536487b05ddf24 100644 (file)
@@ -3181,15 +3181,16 @@ circuit_sent_valid_data(origin_circuit_t *circ, uint16_t relay_body_len)
 {
   if (!circ) return;
 
-  tor_assertf_nonfatal(relay_body_len <= RELAY_PAYLOAD_SIZE,
+  tor_assertf_nonfatal(relay_body_len <= RELAY_PAYLOAD_SIZE_MAX,
                        "Wrong relay_body_len: %d (should be at most %d)",
-                       relay_body_len, RELAY_PAYLOAD_SIZE);
+                       relay_body_len, RELAY_PAYLOAD_SIZE_MAX);
 
   circ->n_delivered_written_circ_bw =
       tor_add_u32_nowrap(circ->n_delivered_written_circ_bw, relay_body_len);
+  // TODO CGO: I think this may now be somewhat incorrect.
   circ->n_overhead_written_circ_bw =
       tor_add_u32_nowrap(circ->n_overhead_written_circ_bw,
-                         RELAY_PAYLOAD_SIZE-relay_body_len);
+                         RELAY_PAYLOAD_SIZE_MAX-relay_body_len);
 }
 
 /**
@@ -3202,11 +3203,12 @@ circuit_read_valid_data(origin_circuit_t *circ, uint16_t relay_body_len)
 {
   if (!circ) return;
 
-  tor_assert_nonfatal(relay_body_len <= RELAY_PAYLOAD_SIZE);
+  tor_assert_nonfatal(relay_body_len <= RELAY_PAYLOAD_SIZE_MAX);
 
   circ->n_delivered_read_circ_bw =
       tor_add_u32_nowrap(circ->n_delivered_read_circ_bw, relay_body_len);
+  // TODO CGO: I think this may now be somewhat incorrect.
   circ->n_overhead_read_circ_bw =
       tor_add_u32_nowrap(circ->n_overhead_read_circ_bw,
-                         RELAY_PAYLOAD_SIZE-relay_body_len);
+                         RELAY_PAYLOAD_SIZE_MAX-relay_body_len);
 }
index c35400d7a1985e5e8b28d8eb9d2f88c13b583cf8..414f5217a8a3de4bb1e713e6a038b08f9bdf0563 100644 (file)
@@ -456,7 +456,7 @@ command_process_created_cell(cell_t *cell, channel_t *chan)
   } else { /* pack it into an extended relay cell, and send it. */
     uint8_t command=0;
     uint16_t len=0;
-    uint8_t payload[RELAY_PAYLOAD_SIZE];
+    uint8_t payload[RELAY_PAYLOAD_SIZE_MAX];
     log_debug(LD_OR,
               "Converting created cell to extended relay cell, sending.");
     memset(payload, 0, sizeof(payload));
@@ -469,6 +469,11 @@ command_process_created_cell(cell_t *cell, channel_t *chan)
       circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
       return;
     }
+    if (len > circuit_max_relay_payload(circ, NULL, command)) {
+      log_fn(LOG_PROTOCOL_WARN, LD_OR, "Created cell too big to package.");
+      circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
+      return;
+    }
 
     relay_send_command_from_edge(0, circ, command,
                                  (const char*)payload, len, NULL);
index 24b85e300579e820b74878603e9f4af08ea759d6..ae4a6c4a6fdf103c8f7f86f8c5443a5e258eca7b 100644 (file)
@@ -63,7 +63,8 @@ build_link_cell(const conflux_cell_link_t *link, uint8_t *cell_out)
       trn_cell_conflux_link_getlen_payload(cell), payload);
 
   /* Encode cell. */
-  cell_len = trn_cell_conflux_link_encode(cell_out, RELAY_PAYLOAD_SIZE, cell);
+  cell_len = trn_cell_conflux_link_encode(cell_out,
+                                          RELAY_PAYLOAD_SIZE_MAX, cell);
 
   trn_cell_conflux_link_payload_v1_free(payload);
   trn_cell_conflux_link_free(cell);
@@ -87,7 +88,8 @@ build_linked_ack_cell(uint8_t *cell_out)
   tor_assert(cell_out);
 
   cell = trn_cell_conflux_linked_ack_new();
-  cell_len = trn_cell_conflux_linked_ack_encode(cell_out, RELAY_PAYLOAD_SIZE,
+  cell_len = trn_cell_conflux_linked_ack_encode(cell_out,
+                                                RELAY_PAYLOAD_SIZE_MAX,
                                                 cell);
 
   trn_cell_conflux_linked_ack_free(cell);
@@ -97,7 +99,7 @@ build_linked_ack_cell(uint8_t *cell_out)
 bool
 conflux_cell_send_link(const conflux_cell_link_t *link, origin_circuit_t *circ)
 {
-  uint8_t payload[RELAY_PAYLOAD_SIZE] = {0};
+  uint8_t payload[RELAY_PAYLOAD_SIZE_MAX] = {0};
   ssize_t cell_len;
 
   tor_assert(link);
@@ -131,7 +133,7 @@ conflux_cell_send_link(const conflux_cell_link_t *link, origin_circuit_t *circ)
 bool
 conflux_cell_send_linked(const conflux_cell_link_t *link, or_circuit_t *circ)
 {
-  uint8_t payload[RELAY_PAYLOAD_SIZE] = {0};
+  uint8_t payload[RELAY_PAYLOAD_SIZE_MAX] = {0};
   ssize_t cell_len;
 
   tor_assert(link);
@@ -164,7 +166,7 @@ conflux_cell_send_linked(const conflux_cell_link_t *link, or_circuit_t *circ)
 bool
 conflux_cell_send_linked_ack(origin_circuit_t *circ)
 {
-  uint8_t payload[RELAY_PAYLOAD_SIZE] = {0};
+  uint8_t payload[RELAY_PAYLOAD_SIZE_MAX] = {0};
   ssize_t cell_len;
 
   tor_assert(circ);
@@ -319,7 +321,7 @@ conflux_send_switch_command(circuit_t *send_circ, uint64_t relative_seq)
 
   trn_cell_conflux_switch_set_seqnum(switch_cell, (uint32_t)relative_seq);
 
-  if (trn_cell_conflux_switch_encode(cell.payload, RELAY_PAYLOAD_SIZE,
+  if (trn_cell_conflux_switch_encode(cell.payload, RELAY_PAYLOAD_SIZE_MAX,
                                      switch_cell) < 0) {
     log_warn(LD_BUG, "Failed to encode conflux switch cell");
     ret = false;
@@ -327,21 +329,22 @@ conflux_send_switch_command(circuit_t *send_circ, uint64_t relative_seq)
   }
 
   /* Send the switch command to the new hop */
+  // TODO CGO XXXXX Fix bug #41056.
   if (CIRCUIT_IS_ORIGIN(send_circ)) {
     relay_send_command_from_edge(0, send_circ,
                                RELAY_COMMAND_CONFLUX_SWITCH,
                                (const char*)cell.payload,
-                               RELAY_PAYLOAD_SIZE,
+                               RELAY_PAYLOAD_SIZE_MAX,
                                TO_ORIGIN_CIRCUIT(send_circ)->cpath->prev);
   } else {
     relay_send_command_from_edge(0, send_circ,
                                RELAY_COMMAND_CONFLUX_SWITCH,
                                (const char*)cell.payload,
-                               RELAY_PAYLOAD_SIZE, NULL);
+                                 RELAY_PAYLOAD_SIZE_MAX,
+                                 NULL);
   }
 
 end:
   trn_cell_conflux_switch_free(switch_cell);
   return ret;
 }
-
index 4e1c545870a57bcf70e531b1a6fb0d753e726fe3..9f3461a2d8a4a011d19953e533afbb4b8df1a8bf 100644 (file)
@@ -71,13 +71,15 @@ double cc_stats_flow_xon_outbuf_ma = 0;
 void
 flow_control_new_consensus_params(const networkstatus_t *ns)
 {
+  // TODO CGO: These numbers might be wrong for the v1 cell format!
+
 #define CC_XOFF_CLIENT_DFLT 500
 #define CC_XOFF_CLIENT_MIN 1
 #define CC_XOFF_CLIENT_MAX 10000
   xoff_client = networkstatus_get_param(ns, "cc_xoff_client",
       CC_XOFF_CLIENT_DFLT,
       CC_XOFF_CLIENT_MIN,
-      CC_XOFF_CLIENT_MAX)*RELAY_PAYLOAD_SIZE;
+      CC_XOFF_CLIENT_MAX)*RELAY_PAYLOAD_SIZE_MAX;
 
 #define CC_XOFF_EXIT_DFLT 500
 #define CC_XOFF_EXIT_MIN 1
@@ -85,7 +87,7 @@ flow_control_new_consensus_params(const networkstatus_t *ns)
   xoff_exit = networkstatus_get_param(ns, "cc_xoff_exit",
       CC_XOFF_EXIT_DFLT,
       CC_XOFF_EXIT_MIN,
-      CC_XOFF_EXIT_MAX)*RELAY_PAYLOAD_SIZE;
+      CC_XOFF_EXIT_MAX)*RELAY_PAYLOAD_SIZE_MAX;
 
 #define CC_XON_CHANGE_PCT_DFLT 25
 #define CC_XON_CHANGE_PCT_MIN 1
@@ -101,7 +103,7 @@ flow_control_new_consensus_params(const networkstatus_t *ns)
   xon_rate_bytes = networkstatus_get_param(ns, "cc_xon_rate",
       CC_XON_RATE_BYTES_DFLT,
       CC_XON_RATE_BYTES_MIN,
-      CC_XON_RATE_BYTES_MAX)*RELAY_PAYLOAD_SIZE;
+      CC_XON_RATE_BYTES_MAX)*RELAY_PAYLOAD_SIZE_MAX;
 
 #define CC_XON_EWMA_CNT_DFLT (2)
 #define CC_XON_EWMA_CNT_MIN (2)
@@ -477,7 +479,8 @@ flow_control_decide_xoff(edge_connection_t *stream)
    * do this because writes only happen when the socket unblocks, so
    * may not otherwise notice accumulation of data in the outbuf for
    * advisory XONs. */
-   if (total_buffered > MAX_EXPECTED_CELL_BURST*RELAY_PAYLOAD_SIZE) {
+  // TODO CGO: This might be wrong for the v1 cell format!
+   if (total_buffered > MAX_EXPECTED_CELL_BURST*RELAY_PAYLOAD_SIZE_MAX) {
      flow_control_decide_xon(stream, 0);
    }
 
@@ -710,4 +713,3 @@ conn_uses_flow_control(connection_t *conn)
 
   return ret;
 }
-
index 14a45a7b539fb6b80e6761dcf4685cee78c9fbf8..640ba157c16b6c971aba663b3660962f23164598 100644 (file)
@@ -513,7 +513,7 @@ clip_dns_fuzzy_ttl(uint32_t ttl)
 int
 connection_edge_end(edge_connection_t *conn, uint8_t reason)
 {
-  char payload[RELAY_PAYLOAD_SIZE];
+  char payload[RELAY_PAYLOAD_SIZE_MAX];
   size_t payload_len=1;
   circuit_t *circ;
   uint8_t control_reason = reason;
@@ -3238,8 +3238,8 @@ connection_ap_get_begincell_flags(entry_connection_t *ap_conn)
 MOCK_IMPL(int,
 connection_ap_handshake_send_begin,(entry_connection_t *ap_conn))
 {
-  char payload[CELL_PAYLOAD_SIZE];
-  int payload_len;
+  char payload[RELAY_PAYLOAD_SIZE_MAX];
+  size_t payload_len;
   int begin_type;
   const or_options_t *options = get_options();
   origin_circuit_t *circ;
@@ -3264,17 +3264,20 @@ connection_ap_handshake_send_begin,(entry_connection_t *ap_conn))
     return -1;
   }
 
+  size_t payload_max = circuit_max_relay_payload(
+                edge_conn->on_circuit, edge_conn->cpath_layer,
+                RELAY_COMMAND_BEGIN);
   /* Set up begin cell flags. */
   edge_conn->begincell_flags = connection_ap_get_begincell_flags(ap_conn);
 
-  tor_snprintf(payload,RELAY_PAYLOAD_SIZE, "%s:%d",
+  tor_snprintf(payload,payload_max, "%s:%d",
                (circ->base_.purpose == CIRCUIT_PURPOSE_C_GENERAL ||
                 circ->base_.purpose == CIRCUIT_PURPOSE_CONFLUX_LINKED ||
                 circ->base_.purpose == CIRCUIT_PURPOSE_CONTROLLER) ?
                  ap_conn->socks_request->address : "",
                ap_conn->socks_request->port);
-  payload_len = (int)strlen(payload)+1;
-  if (payload_len <= RELAY_PAYLOAD_SIZE - 4 && edge_conn->begincell_flags) {
+  payload_len = strlen(payload)+1;
+  if (payload_len <= payload_max - 4 && edge_conn->begincell_flags) {
     set_uint32(payload + payload_len, htonl(edge_conn->begincell_flags));
     payload_len += 4;
   }
index 07c26a80e82928ab9ce67082b2e5a6332b3f5aa0..1474cb81265e3f42371c46ca1d4c1fd56cf77f76 100644 (file)
@@ -128,7 +128,7 @@ parse_create2_payload(create_cell_t *cell_out, const uint8_t *p, size_t p_len)
   handshake_type = ntohs(get_uint16(p));
   handshake_len = ntohs(get_uint16(p+2));
 
-  if (handshake_len > CELL_PAYLOAD_SIZE - 4 || handshake_len > p_len - 4)
+  if (handshake_len > MAX_CREATE_LEN || handshake_len > p_len - 4)
     return -1;
   if (handshake_type == ONION_HANDSHAKE_TYPE_FAST)
     return -1;
@@ -183,7 +183,7 @@ check_created_cell(const created_cell_t *cell)
       return -1;
     break;
   case CELL_CREATED2:
-    if (cell->handshake_len > RELAY_PAYLOAD_SIZE-2)
+    if (cell->handshake_len > MAX_CREATED_LEN)
       return -1;
     break;
   }
@@ -211,7 +211,7 @@ created_cell_parse(created_cell_t *cell_out, const cell_t *cell_in)
       const uint8_t *p = cell_in->payload;
       cell_out->cell_type = CELL_CREATED2;
       cell_out->handshake_len = ntohs(get_uint16(p));
-      if (cell_out->handshake_len > CELL_PAYLOAD_SIZE - 2)
+      if (cell_out->handshake_len > MAX_CREATED_LEN)
         return -1;
       memcpy(cell_out->reply, p+2, cell_out->handshake_len);
       break;
@@ -353,7 +353,7 @@ extend_cell_parse,(extend_cell_t *cell_out,
   tor_assert(cell_out);
   tor_assert(payload);
 
-  if (payload_length > RELAY_PAYLOAD_SIZE)
+  if (payload_length > RELAY_PAYLOAD_SIZE_MAX)
     return -1;
 
   switch (command) {
@@ -412,7 +412,7 @@ extended_cell_parse(extended_cell_t *cell_out,
   tor_assert(payload);
 
   memset(cell_out, 0, sizeof(*cell_out));
-  if (payload_len > RELAY_PAYLOAD_SIZE)
+  if (payload_len > RELAY_PAYLOAD_SIZE_MAX)
     return -1;
 
   switch (command) {
@@ -423,7 +423,7 @@ extended_cell_parse(extended_cell_t *cell_out,
       cell_out->cell_type = RELAY_COMMAND_EXTENDED2;
       cell_out->created_cell.cell_type = CELL_CREATED2;
       cell_out->created_cell.handshake_len = ntohs(get_uint16(payload));
-      if (cell_out->created_cell.handshake_len > RELAY_PAYLOAD_SIZE - 2 ||
+      if (cell_out->created_cell.handshake_len > RELAY_PAYLOAD_SIZE_MAX - 2 ||
           cell_out->created_cell.handshake_len > payload_len - 2)
         return -1;
       memcpy(cell_out->created_cell.reply, payload+2,
@@ -544,7 +544,9 @@ should_include_ed25519_id_extend_cells(const networkstatus_t *ns,
 /** Format the EXTEND{,2} cell in <b>cell_in</b>, storing its relay payload in
  * <b>payload_out</b>, the number of bytes used in *<b>len_out</b>, and the
  * relay command in *<b>command_out</b>. The <b>payload_out</b> must have
- * RELAY_PAYLOAD_SIZE bytes available.  Return 0 on success, -1 on failure. */
+ * RELAY_PAYLOAD_SIZE_MAX bytes available.
+ *
+ * Return 0 on success, -1 on failure. */
 int
 extend_cell_format(uint8_t *command_out, uint16_t *len_out,
                    uint8_t *payload_out, const extend_cell_t *cell_in)
@@ -555,7 +557,7 @@ extend_cell_format(uint8_t *command_out, uint16_t *len_out,
 
   p = payload_out;
 
-  memset(p, 0, RELAY_PAYLOAD_SIZE);
+  memset(p, 0, RELAY_PAYLOAD_SIZE_MAX);
 
   switch (cell_in->cell_type) {
   case RELAY_COMMAND_EXTEND:
@@ -618,7 +620,7 @@ extend_cell_format(uint8_t *command_out, uint16_t *len_out,
              cell_in->create_cell.handshake_len);
 
       ssize_t len_encoded = extend2_cell_body_encode(
-                             payload_out, RELAY_PAYLOAD_SIZE,
+                             payload_out, RELAY_PAYLOAD_SIZE_MAX,
                              cell);
       extend2_cell_body_free(cell);
       if (len_encoded < 0 || len_encoded > UINT16_MAX)
@@ -636,7 +638,9 @@ extend_cell_format(uint8_t *command_out, uint16_t *len_out,
 /** Format the EXTENDED{,2} cell in <b>cell_in</b>, storing its relay payload
  * in <b>payload_out</b>, the number of bytes used in *<b>len_out</b>, and the
  * relay command in *<b>command_out</b>. The <b>payload_out</b> must have
- * RELAY_PAYLOAD_SIZE bytes available.  Return 0 on success, -1 on failure. */
+ * RELAY_PAYLOAD_SIZE_MAX bytes available.
+ *
+ * Return 0 on success, -1 on failure. */
 int
 extended_cell_format(uint8_t *command_out, uint16_t *len_out,
                      uint8_t *payload_out, const extended_cell_t *cell_in)
@@ -646,7 +650,7 @@ extended_cell_format(uint8_t *command_out, uint16_t *len_out,
     return -1;
 
   p = payload_out;
-  memset(p, 0, RELAY_PAYLOAD_SIZE);
+  memset(p, 0, RELAY_PAYLOAD_SIZE_MAX);
 
   switch (cell_in->cell_type) {
   case RELAY_COMMAND_EXTENDED:
@@ -656,7 +660,7 @@ extended_cell_format(uint8_t *command_out, uint16_t *len_out,
       *command_out = RELAY_COMMAND_EXTENDED2;
       *len_out = 2 + cell_in->created_cell.handshake_len;
       set_uint16(payload_out, htons(cell_in->created_cell.handshake_len));
-      if (2+cell_in->created_cell.handshake_len > RELAY_PAYLOAD_SIZE)
+      if (cell_in->created_cell.handshake_len > MAX_CREATED_LEN)
         return -1;
       memcpy(payload_out+2, cell_in->created_cell.reply,
              cell_in->created_cell.handshake_len);
index bba2e38411142b22be66ff7ba95edca346be74ce..173b60fa5ce7db515c2d15dd98fd278b849f5e33 100644 (file)
@@ -20,6 +20,9 @@ struct curve25519_public_key_t;
 #define MAX_ONIONSKIN_CHALLENGE_LEN 255
 #define MAX_ONIONSKIN_REPLY_LEN 255
 
+#define MAX_CREATE_LEN (CELL_PAYLOAD_SIZE - 4)
+#define MAX_CREATED_LEN (CELL_PAYLOAD_SIZE - 2)
+
 /** A parsed CREATE, CREATE_FAST, or CREATE2 cell. */
 typedef struct create_cell_t {
   /** The cell command. One of CREATE{,_FAST,2} */
@@ -29,7 +32,7 @@ typedef struct create_cell_t {
   /** The number of bytes used in <b>onionskin</b>. */
   uint16_t handshake_len;
   /** The client-side message for the circuit creation handshake. */
-  uint8_t onionskin[CELL_PAYLOAD_SIZE - 4];
+  uint8_t onionskin[MAX_CREATE_LEN];
 } create_cell_t;
 
 /** A parsed CREATED, CREATED_FAST, or CREATED2 cell. */
@@ -39,7 +42,7 @@ typedef struct created_cell_t {
   /** The number of bytes used in <b>reply</b>. */
   uint16_t handshake_len;
   /** The server-side message for the circuit creation handshake. */
-  uint8_t reply[CELL_PAYLOAD_SIZE - 2];
+  uint8_t reply[MAX_CREATED_LEN];
 } created_cell_t;
 
 /** A parsed RELAY_EXTEND or RELAY_EXTEND2 cell */
index 57d5d3e6949feba8daeb536a732d1479f83edaa3..44ec332838b8d08cb20fb6ae9caec38f5b5eff6f 100644 (file)
@@ -550,12 +550,6 @@ static inline int get_circ_id_size(int wide_circ_ids)
   return wide_circ_ids ? 4 : 2;
 }
 
-/* TODO #41051: It would be better if these went away. */
-/** Number of bytes in a relay cell's header (not including general cell
- * header). */
-/** Largest number of bytes that can fit in a relay cell payload. */
-#define RELAY_PAYLOAD_SIZE (CELL_PAYLOAD_SIZE-(1+2+2+4+2))
-
 /** Number of bytes used for a relay cell's header, in the v0 format. */
 #define RELAY_HEADER_SIZE_V0 (1+2+2+4+2)
 /** Number of bytes used for a relay cell's header, in the v1 format,
@@ -565,6 +559,22 @@ static inline int get_circ_id_size(int wide_circ_ids)
  * if a StreamID is used. */
 #define RELAY_HEADER_SIZE_V1_WITH_STREAM_ID (16+1+2+2)
 
+/** Largest number of bytes that can fit in any relay cell payload.
+ *
+ * Note that the actual maximum may be smaller if the V1 cell format
+ * is in use; see relay_cell_max_payload_size() for the real maximum.
+ */
+#define RELAY_PAYLOAD_SIZE_MAX (CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE_V0)
+
+/** Smallest capacity of any relay cell payload. */
+#define RELAY_PAYLOAD_SIZE_MIN \
+  (CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE_V1_WITH_STREAM_ID)
+
+#ifdef TOR_UNIT_TESTS
+// This name is for testing only.
+#define RELAY_PAYLOAD_SIZE RELAY_PAYLOAD_SIZE_MAX
+#endif
+
 /** Identifies a circuit on an or_connection */
 typedef uint32_t circid_t;
 /** Identifies a stream on a circuit */
index aa8c64f1e269051a580c233ce13cfd51094eb309..9aed85f31f6022a46c3bc49780a513a24319e2e2 100644 (file)
@@ -1178,7 +1178,7 @@ resolved_cell_parse(const relay_msg_t *msg, smartlist_t *addresses_out,
 
   *errcode_out = 0;
 
-  if (msg->length > RELAY_PAYLOAD_SIZE)
+  if (msg->length > RELAY_PAYLOAD_SIZE_MAX)
     return -1;
 
   addrs = smartlist_new();
index 03af99048447f09d6d1aaaadf2c46d822da68139..933170d9f0fd284746df58c65f21f0eb5979033e 100644 (file)
@@ -229,7 +229,7 @@ sendme_is_valid(const circuit_t *circ, const uint8_t *cell_payload,
 }
 
 /* Build and encode a version 1 SENDME cell into payload, which must be at
- * least of RELAY_PAYLOAD_SIZE bytes, using the digest for the cell data.
+ * least of RELAY_PAYLOAD_SIZE_MAX bytes, using the digest for the cell data.
  *
  * Return the size in bytes of the encoded cell in payload. A negative value
  * is returned on encoding failure. */
@@ -254,7 +254,7 @@ build_cell_payload_v1(const uint8_t *cell_digest, uint8_t *payload)
          sendme_cell_get_data_len(cell));
 
   /* Finally, encode the cell into the payload. */
-  len = sendme_cell_encode(payload, RELAY_PAYLOAD_SIZE, cell);
+  len = sendme_cell_encode(payload, RELAY_PAYLOAD_SIZE_MAX, cell);
 
   sendme_cell_free(cell);
   return len;
@@ -270,7 +270,7 @@ send_circuit_level_sendme(circuit_t *circ, crypt_path_t *layer_hint,
                           const uint8_t *cell_digest)
 {
   uint8_t emit_version;
-  uint8_t payload[RELAY_PAYLOAD_SIZE];
+  uint8_t payload[RELAY_PAYLOAD_SIZE_MAX];
   ssize_t payload_len;
 
   tor_assert(circ);
index 11912ffc25c24f4f68d601281face26d5dbfd281..fd50a76b88354bdac355438be2bcd6dfa3e08e4b 100644 (file)
@@ -221,10 +221,11 @@ log_heartbeat(time_t now)
   }
 
   double fullness_pct = 100;
+  // TODO CGO: This is slightly wrong?
   if (stats_n_data_cells_packaged && !hibernating) {
     fullness_pct =
       100*(((double)stats_n_data_bytes_packaged) /
-           ((double)stats_n_data_cells_packaged*RELAY_PAYLOAD_SIZE));
+           ((double)stats_n_data_cells_packaged*RELAY_PAYLOAD_SIZE_MAX));
   }
   const double overhead_pct = ( r - 1.0 ) * 100.0;
 
index e388c5512551595058c7f8c5a28000e25fb419d0..47aa0efe99b7a84186733d2f26a590dab150d2dc 100644 (file)
@@ -798,7 +798,7 @@ static int
 pathbias_send_usable_probe(circuit_t *circ)
 {
   /* Based on connection_ap_handshake_send_begin() */
-  char payload[CELL_PAYLOAD_SIZE];
+  char payload[RELAY_PAYLOAD_SIZE_MAX];
   int payload_len;
   origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
   crypt_path_t *cpath_layer = NULL;
@@ -853,7 +853,7 @@ pathbias_send_usable_probe(circuit_t *circ)
     return -1;
   }
 
-  tor_snprintf(payload,RELAY_PAYLOAD_SIZE, "%s:25", probe_nonce);
+  tor_snprintf(payload,RELAY_PAYLOAD_SIZE_MAX, "%s:25", probe_nonce);
   payload_len = (int)strlen(payload)+1;
 
   // XXX: need this? Can we assume ipv4 will always be supported?
index 0039825f3cb51abe5aed96587887b1d17357d6d1..584bc35c4dd6867329f65c08f7a1fe5246c52c7a 100644 (file)
@@ -41,7 +41,7 @@ compute_introduce_mac(const uint8_t *encoded_cell, size_t encoded_cell_len,
 {
   size_t offset = 0;
   size_t mac_msg_len;
-  uint8_t mac_msg[RELAY_PAYLOAD_SIZE] = {0};
+  uint8_t mac_msg[RELAY_PAYLOAD_SIZE_MAX] = {0};
 
   tor_assert(encoded_cell);
   tor_assert(encrypted);
@@ -299,8 +299,8 @@ introduce1_encrypt_and_encode(trn_cell_introduce1_t *cell,
   size_t offset = 0;
   ssize_t encrypted_len;
   ssize_t encoded_cell_len, encoded_enc_cell_len;
-  uint8_t encoded_cell[RELAY_PAYLOAD_SIZE] = {0};
-  uint8_t encoded_enc_cell[RELAY_PAYLOAD_SIZE] = {0};
+  uint8_t encoded_cell[RELAY_PAYLOAD_SIZE_MAX] = {0};
+  uint8_t encoded_enc_cell[RELAY_PAYLOAD_SIZE_MAX] = {0};
   uint8_t *encrypted = NULL;
   uint8_t mac[DIGEST256_LEN];
   crypto_cipher_t *cipher = NULL;
@@ -339,7 +339,7 @@ introduce1_encrypt_and_encode(trn_cell_introduce1_t *cell,
    * ENCRYPTED_DATA and MAC length. */
   encrypted_len = sizeof(data->client_kp->pubkey) + encoded_enc_cell_len +
                   sizeof(mac);
-  tor_assert(encrypted_len < RELAY_PAYLOAD_SIZE);
+  tor_assert(encrypted_len < RELAY_PAYLOAD_SIZE_MAX);
   encrypted = tor_malloc_zero(encrypted_len);
 
   /* Put the CLIENT_PK first. */
@@ -709,7 +709,7 @@ hs_cell_build_establish_intro(const char *circ_nonce,
     ssize_t tmp_cell_mac_offset =
       sig_len + sizeof(cell->sig_len) +
       trn_cell_establish_intro_getlen_handshake_mac(cell);
-    uint8_t tmp_cell_enc[RELAY_PAYLOAD_SIZE] = {0};
+    uint8_t tmp_cell_enc[RELAY_PAYLOAD_SIZE_MAX] = {0};
     uint8_t mac[TRUNNEL_SHA3_256_LEN], *handshake_ptr;
 
     /* We first encode the current fields we have in the cell so we can
@@ -738,7 +738,7 @@ hs_cell_build_establish_intro(const char *circ_nonce,
   {
     ssize_t tmp_cell_enc_len = 0;
     ssize_t tmp_cell_sig_offset = (sig_len + sizeof(cell->sig_len));
-    uint8_t tmp_cell_enc[RELAY_PAYLOAD_SIZE] = {0}, *sig_ptr;
+    uint8_t tmp_cell_enc[RELAY_PAYLOAD_SIZE_MAX] = {0}, *sig_ptr;
     ed25519_signature_t sig;
 
     /* We first encode the current fields we have in the cell so we can
@@ -764,7 +764,8 @@ hs_cell_build_establish_intro(const char *circ_nonce,
   }
 
   /* Encode the cell. Can't be bigger than a standard cell. */
-  cell_len = trn_cell_establish_intro_encode(cell_out, RELAY_PAYLOAD_SIZE,
+  cell_len = trn_cell_establish_intro_encode(cell_out,
+                                             RELAY_PAYLOAD_SIZE_MAX,
                                              cell);
 
  done:
@@ -1161,7 +1162,8 @@ hs_cell_build_rendezvous1(const uint8_t *rendezvous_cookie,
   memcpy(trn_cell_rendezvous1_getarray_handshake_info(cell),
          rendezvous_handshake_info, rendezvous_handshake_info_len);
   /* Encoding. */
-  cell_len = trn_cell_rendezvous1_encode(cell_out, RELAY_PAYLOAD_SIZE, cell);
+  cell_len = trn_cell_rendezvous1_encode(cell_out,
+                                         RELAY_PAYLOAD_SIZE_MAX, cell);
   tor_assert(cell_len > 0);
 
   trn_cell_rendezvous1_free(cell);
@@ -1200,7 +1202,8 @@ hs_cell_build_introduce1(const hs_cell_introduce1_data_t *data,
   introduce1_set_encrypted(cell, data);
 
   /* Final encoding. */
-  cell_len = trn_cell_introduce1_encode(cell_out, RELAY_PAYLOAD_SIZE, cell);
+  cell_len = trn_cell_introduce1_encode(cell_out,
+                                        RELAY_PAYLOAD_SIZE_MAX, cell);
 
   trn_cell_introduce1_free(cell);
   return cell_len;
index 306550f99cd3de6d72c8045ff92663077c95f4ca..e11fc8915ad4940e098806ba4086c8d93440e4f4 100644 (file)
@@ -271,7 +271,7 @@ send_establish_intro(const hs_service_t *service,
                      hs_service_intro_point_t *ip, origin_circuit_t *circ)
 {
   ssize_t cell_len;
-  uint8_t payload[RELAY_PAYLOAD_SIZE];
+  uint8_t payload[RELAY_PAYLOAD_SIZE_MAX];
 
   tor_assert(service);
   tor_assert(ip);
@@ -1156,7 +1156,7 @@ hs_circ_service_rp_has_opened(const hs_service_t *service,
                               origin_circuit_t *circ)
 {
   size_t payload_len;
-  uint8_t payload[RELAY_PAYLOAD_SIZE] = {0};
+  uint8_t payload[RELAY_PAYLOAD_SIZE_MAX] = {0};
 
   tor_assert(service);
   tor_assert(circ);
@@ -1445,7 +1445,7 @@ hs_circ_send_introduce1(origin_circuit_t *intro_circ,
 {
   int ret = -1;
   ssize_t payload_len;
-  uint8_t payload[RELAY_PAYLOAD_SIZE] = {0};
+  uint8_t payload[RELAY_PAYLOAD_SIZE_MAX] = {0};
   hs_cell_introduce1_data_t intro1_data;
 
   tor_assert(intro_circ);
@@ -1529,7 +1529,7 @@ int
 hs_circ_send_establish_rendezvous(origin_circuit_t *circ)
 {
   ssize_t cell_len = 0;
-  uint8_t cell[RELAY_PAYLOAD_SIZE] = {0};
+  uint8_t cell[RELAY_PAYLOAD_SIZE_MAX] = {0};
 
   tor_assert(circ);
   tor_assert(TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND);
index eb316781892af6ea5196f60e3d91455096030495..bd27b91c7916e10b29b0537b4628985ab8963a74 100644 (file)
@@ -508,7 +508,9 @@ MOCK_IMPL(STATIC void,
 send_resolved_cell,(edge_connection_t *conn, uint8_t answer_type,
                     const cached_resolve_t *resolved))
 {
-  char buf[RELAY_PAYLOAD_SIZE], *cp = buf;
+  // (We use the minimum here to ensure that we never
+  // generate a too-big message.)
+  char buf[RELAY_PAYLOAD_SIZE_MIN], *cp = buf;
   size_t buflen = 0;
   uint32_t ttl;
 
@@ -581,7 +583,7 @@ MOCK_IMPL(STATIC void,
 send_resolved_hostname_cell,(edge_connection_t *conn,
                              const char *hostname))
 {
-  char buf[RELAY_PAYLOAD_SIZE];
+  char buf[RELAY_PAYLOAD_SIZE_MAX];
   size_t buflen;
   uint32_t ttl;
 
@@ -590,7 +592,9 @@ send_resolved_hostname_cell,(edge_connection_t *conn,
 
   size_t namelen = strlen(hostname);
 
-  tor_assert(namelen < 256);
+  if (BUG(namelen >= 256)) {
+    return;
+  }
   ttl = conn->address_ttl;
 
   buf[0] = RESOLVED_TYPE_HOSTNAME;
index b46726aa4af9ca91f4b70d3d8bd4f446d0b5dbd4..0c02325facc49c18acfd3674195b10ab0ef56cd7 100644 (file)
@@ -495,11 +495,11 @@ test_cfmt_created_cells(void *arg)
   memset(b, 0, sizeof(b));
   crypto_rand((char*)b, 496);
   cell.command = CELL_CREATED2;
-  memcpy(cell.payload, "\x01\xF1", 2);
+  memcpy(cell.payload, "\x02\xFF", 2);
   tt_int_op(-1, OP_EQ, created_cell_parse(&cc, &cell));
 
   /* Unformattable CREATED2 cell: too long! */
-  cc.handshake_len = 497;
+  cc.handshake_len = 508;
   tt_int_op(-1, OP_EQ, created_cell_format(&cell2, &cc));
 
  done: