Browse Source

sendme: Add helper functions for DATA cell packaging

When we are about to send a DATA cell, we have to decrement the package window
for both the circuit and stream level.

This commit adds helper functions to handle the package window decrement.

Part of #26288

Signed-off-by: David Goulet <dgoulet@torproject.org>
David Goulet 5 years ago
parent
commit
8e38791baf
3 changed files with 50 additions and 7 deletions
  1. 9 7
      src/core/or/relay.c
  2. 37 0
      src/core/or/sendme.c
  3. 4 0
      src/core/or/sendme.h

+ 9 - 7
src/core/or/relay.c

@@ -2062,15 +2062,17 @@ connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial,
     return 0;
   }
 
-  if (!cpath_layer) { /* non-rendezvous exit */
-    tor_assert(circ->package_window > 0);
-    circ->package_window--;
-  } else { /* we're an AP, or an exit on a rendezvous circ */
-    tor_assert(cpath_layer->package_window > 0);
-    cpath_layer->package_window--;
+  /* Handle the circuit-level SENDME package window. */
+  if (sendme_circuit_data_packaged(circ, cpath_layer) < 0) {
+    /* Package window has gone under 0. Protocol issue. */
+    log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+           "Circuit package window is below 0. Closing circuit.");
+    conn->end_reason = END_STREAM_REASON_TORPROTOCOL;
+    return -1;
   }
 
-  if (--conn->package_window <= 0) { /* is it 0 after decrement? */
+  /* Handle the stream-level SENDME package window. */
+  if (sendme_stream_data_packaged(conn) < 0) {
     connection_stop_reading(TO_CONN(conn));
     log_debug(domain,"conn->package_window reached 0.");
     circuit_consider_stop_edge_reading(circ, cpath_layer);

+ 37 - 0
src/core/or/sendme.c

@@ -213,3 +213,40 @@ sendme_stream_data_received(edge_connection_t *conn)
   tor_assert(conn);
   return --conn->deliver_window;
 }
+
+/* Called when a relay DATA cell is packaged on the given circuit. If
+ * layer_hint is NULL, this means we are the Exit end point else we are the
+ * Client. Update the package window and return its new value. */
+int
+sendme_circuit_data_packaged(circuit_t *circ, crypt_path_t *layer_hint)
+{
+  int package_window, domain;
+
+  tor_assert(circ);
+
+  if (CIRCUIT_IS_ORIGIN(circ)) {
+    /* Client side. */
+    tor_assert(layer_hint);
+    --layer_hint->package_window;
+    package_window = layer_hint->package_window;
+    domain = LD_APP;
+  } else {
+    /* Exit side. */
+    tor_assert(!layer_hint);
+    --circ->package_window;
+    package_window = circ->package_window;
+    domain = LD_EXIT;
+  }
+
+  log_debug(domain, "Circuit package_window now %d.", package_window);
+  return package_window;
+}
+
+/* Called when a relay DATA cell is packaged for the given edge connection
+ * conn. Update the package window and return its new value. */
+int
+sendme_stream_data_packaged(edge_connection_t *conn)
+{
+  tor_assert(conn);
+  return --conn->package_window;
+}

+ 4 - 0
src/core/or/sendme.h

@@ -28,4 +28,8 @@ int sendme_process_stream_level(edge_connection_t *conn, circuit_t *circ,
 int sendme_stream_data_received(edge_connection_t *conn);
 int sendme_circuit_data_received(circuit_t *circ, crypt_path_t *layer_hint);
 
+/* Update package window functions. */
+int sendme_circuit_data_packaged(circuit_t *circ, crypt_path_t *layer_hint);
+int sendme_stream_data_packaged(edge_connection_t *conn);
+
 #endif /* !defined(TOR_SENDME_H) */