[tor-commits] [tor/master] prop289: Support sending SENDME version 1

asn at torproject.org asn at torproject.org
Thu May 2 15:16:20 UTC 2019


commit 023a70da841182fbbbe11389929c8fbbc7490365
Author: David Goulet <dgoulet at torproject.org>
Date:   Wed Jan 9 12:22:35 2019 -0500

    prop289: Support sending SENDME version 1
    
    This code will obey the consensus parameter "sendme_emit_min_version" to know
    which SENDME version it should send. For now, the default is 0 and the
    parameter is not yet used in the consensus.
    
    This commit adds the support to send version 1 SENDMEs but aren't sent on the
    wire at this commit.
    
    Closes #26840
    
    Signed-off-by: David Goulet <dgoulet at torproject.org>
---
 src/core/or/relay.c  |   2 +-
 src/core/or/sendme.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++---
 src/core/or/sendme.h |   3 +-
 3 files changed, 103 insertions(+), 8 deletions(-)

diff --git a/src/core/or/relay.c b/src/core/or/relay.c
index 6ff053d8a..6f69ed999 100644
--- a/src/core/or/relay.c
+++ b/src/core/or/relay.c
@@ -1560,7 +1560,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
       }
 
       /* Consider sending a circuit-level SENDME cell. */
-      sendme_circuit_consider_sending(circ, layer_hint);
+      sendme_circuit_consider_sending(circ, layer_hint, NULL);
 
       if (rh.stream_id == 0) {
         log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Relay data cell with zero "
diff --git a/src/core/or/sendme.c b/src/core/or/sendme.c
index bba760ae9..f22e7027d 100644
--- a/src/core/or/sendme.c
+++ b/src/core/or/sendme.c
@@ -16,6 +16,7 @@
 #include "core/or/relay.h"
 #include "core/or/sendme.h"
 #include "feature/nodelist/networkstatus.h"
+#include "trunnel/sendme.h"
 
 /* The cell version constants for when emitting a cell. */
 #define SENDME_EMIT_MIN_VERSION_DEFAULT 0
@@ -38,6 +39,7 @@ get_emit_min_version(void)
                                  SENDME_EMIT_MIN_VERSION_MAX);
 }
 
+#if 0
 /* Return the minimum version given by the consensus (if any) that should be
  * accepted when receiving a SENDME cell. */
 static int
@@ -48,6 +50,98 @@ get_accept_min_version(void)
                                  SENDME_ACCEPT_MIN_VERSION_MIN,
                                  SENDME_ACCEPT_MIN_VERSION_MAX);
 }
+#endif
+
+/* 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.
+ *
+ * Return the size in bytes of the encoded cell in payload. A negative value
+ * is returned on encoding failure. */
+static ssize_t
+build_cell_payload_v1(crypto_digest_t *cell_digest, uint8_t *payload)
+{
+  ssize_t len = -1;
+  sendme_cell_t *cell = NULL;
+  sendme_data_v1_t *data = NULL;
+
+  tor_assert(cell_digest);
+  tor_assert(payload);
+
+  cell = sendme_cell_new();
+  data = sendme_data_v1_new();
+
+  /* Building a payload for version 1. */
+  sendme_cell_set_version(cell, 0x01);
+
+  /* Copy the digest into the data payload. */
+  crypto_digest_get_digest(cell_digest,
+                           (char *) sendme_data_v1_getarray_digest(data),
+                           sendme_data_v1_getlen_digest(data));
+
+  /* Set the length of the data in the cell payload. It is the encoded length
+   * of the v1 data object. */
+  sendme_cell_setlen_data(cell, sendme_data_v1_encoded_len(data));
+  /* Encode into the cell's data field using its current length just set. */
+  if (sendme_data_v1_encode(sendme_cell_getarray_data(cell),
+                            sendme_cell_getlen_data(cell), data) < 0) {
+    goto end;
+  }
+  /* Set the DATA_LEN field to what we've just encoded. */
+  sendme_cell_set_data_len(cell, sendme_cell_getlen_data(cell));
+
+  /* Finally, encode the cell into the payload. */
+  len = sendme_cell_encode(payload, RELAY_PAYLOAD_SIZE, cell);
+
+ end:
+  sendme_cell_free(cell);
+  sendme_data_v1_free(data);
+  return len;
+}
+
+/* Send a circuit-level SENDME on the given circuit using the layer_hint if
+ * not NULL. The digest is only used for version 1.
+ *
+ * Return 0 on success else a negative value and the circuit will be closed
+ * because we failed to send the cell on it. */
+static int
+send_circuit_level_sendme(circuit_t *circ, crypt_path_t *layer_hint,
+                          crypto_digest_t *cell_digest)
+{
+  uint8_t emit_version;
+  uint8_t payload[RELAY_PAYLOAD_SIZE];
+  ssize_t payload_len;
+
+  tor_assert(circ);
+  tor_assert(cell_digest);
+
+  emit_version = get_emit_min_version();
+  switch (emit_version) {
+  case 0x01:
+    payload_len = build_cell_payload_v1(cell_digest, payload);
+    if (BUG(payload_len < 0)) {
+      /* Unable to encode the cell, abort. We can recover from this by closing
+       * the circuit but in theory it should never happen. */
+      return -1;
+    }
+    log_debug(LD_PROTOCOL, "Emitting SENDME version 1 cell.");
+    break;
+  case 0x00:
+    /* Fallthrough because default is to use v0. */
+  default:
+    /* Unknown version, fallback to version 0 meaning no payload. */
+    payload_len = 0;
+    break;
+  }
+
+  if (relay_send_command_from_edge(0, circ, RELAY_COMMAND_SENDME,
+                                   (char *) payload, payload_len,
+                                   layer_hint) < 0) {
+    log_warn(LD_CIRC,
+             "SENDME relay_send_command_from_edge failed. Circuit's closed.");
+    return -1; /* the circuit's closed, don't continue */
+  }
+  return 0;
+}
 
 /** Called when we've just received a relay data cell, when we've just
  * finished flushing all bytes to stream <b>conn</b>, or when we've flushed
@@ -100,8 +194,11 @@ sendme_connection_edge_consider_sending(edge_connection_t *conn)
  * more.
  */
 void
-sendme_circuit_consider_sending(circuit_t *circ, crypt_path_t *layer_hint)
+sendme_circuit_consider_sending(circuit_t *circ, crypt_path_t *layer_hint,
+                                crypto_digest_t *digest)
 {
+  tor_assert(digest);
+
   while ((layer_hint ? layer_hint->deliver_window : circ->deliver_window) <=
           CIRCWINDOW_START - CIRCWINDOW_INCREMENT) {
     log_debug(LD_CIRC,"Queuing circuit sendme.");
@@ -109,11 +206,8 @@ sendme_circuit_consider_sending(circuit_t *circ, crypt_path_t *layer_hint)
       layer_hint->deliver_window += CIRCWINDOW_INCREMENT;
     else
       circ->deliver_window += CIRCWINDOW_INCREMENT;
-    if (relay_send_command_from_edge(0, circ, RELAY_COMMAND_SENDME,
-                                     NULL, 0, layer_hint) < 0) {
-      log_warn(LD_CIRC,
-               "relay_send_command_from_edge failed. Circuit's closed.");
-      return; /* the circuit's closed, don't continue */
+    if (send_circuit_level_sendme(circ, layer_hint, digest) < 0) {
+      return; /* The circuit's closed, don't continue */
     }
   }
 }
diff --git a/src/core/or/sendme.h b/src/core/or/sendme.h
index f50ccfbfe..ba01ecfaf 100644
--- a/src/core/or/sendme.h
+++ b/src/core/or/sendme.h
@@ -16,7 +16,8 @@
 /* Sending SENDME cell. */
 void sendme_connection_edge_consider_sending(edge_connection_t *edge_conn);
 void sendme_circuit_consider_sending(circuit_t *circ,
-                                     crypt_path_t *layer_hint);
+                                     crypt_path_t *layer_hint,
+                                     crypto_digest_t *digest);
 
 /* Processing SENDME cell. */
 int sendme_process_circuit_level(crypt_path_t *layer_hint,





More information about the tor-commits mailing list