[tor-commits] [tor/master] Bug 25903: Perform accounting for new CIRC_BW fields.

nickm at torproject.org nickm at torproject.org
Mon May 14 18:28:06 UTC 2018


commit e07e95edd35f1608ecba94b281818d27f63812e3
Author: Mike Perry <mikeperry-git at torproject.org>
Date:   Mon Apr 23 20:06:34 2018 +0000

    Bug 25903: Perform accounting for new CIRC_BW fields.
    
    Two new values in each direction. DELIVERED counts valid end-to-end circuit
    data that is accepted by our end and OVERHEAD counts the slack unused data in
    each of the relay command cells for those accepted cells.
    
    Control port changes are in the next commit.
---
 src/or/circuituse.c      | 38 ++++++++++++++++++++++++++++++++++++++
 src/or/circuituse.h      |  2 ++
 src/or/connection_edge.c |  9 ++++++++-
 src/or/or.h              | 24 ++++++++++++++++++++++--
 src/or/relay.c           | 40 +++++++++++++++++++++++++++++++++++++++-
 src/or/rendcommon.c      |  6 ++++++
 6 files changed, 115 insertions(+), 4 deletions(-)

diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 47e29c28d..a584e3eca 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -3083,3 +3083,41 @@ mark_circuit_unusable_for_new_conns(origin_circuit_t *circ)
   circ->unusable_for_new_conns = 1;
 }
 
+/**
+ * Add relay_body_len and RELAY_PAYLOAD_SIZE-relay_body_len to
+ * the valid delivered written fields and the overhead field,
+ * respectively.
+ */
+void
+circuit_sent_valid_data(origin_circuit_t *circ, uint16_t relay_body_len)
+{
+  if (!circ) return;
+
+  tor_assert_nonfatal(relay_body_len <= RELAY_PAYLOAD_SIZE);
+
+  circ->n_delivered_written_circ_bw =
+      tor_add_u32_nowrap(circ->n_delivered_written_circ_bw, relay_body_len);
+  circ->n_overhead_written_circ_bw =
+      tor_add_u32_nowrap(circ->n_overhead_written_circ_bw,
+                         RELAY_PAYLOAD_SIZE-relay_body_len);
+}
+
+/**
+ * Add relay_body_len and RELAY_PAYLOAD_SIZE-relay_body_len to
+ * the valid delivered read field and the overhead field,
+ * respectively.
+ */
+void
+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);
+
+  circ->n_delivered_read_circ_bw =
+      tor_add_u32_nowrap(circ->n_delivered_read_circ_bw, relay_body_len);
+  circ->n_overhead_read_circ_bw =
+      tor_add_u32_nowrap(circ->n_overhead_read_circ_bw,
+                         RELAY_PAYLOAD_SIZE-relay_body_len);
+}
+
diff --git a/src/or/circuituse.h b/src/or/circuituse.h
index 71c818b97..6458bd690 100644
--- a/src/or/circuituse.h
+++ b/src/or/circuituse.h
@@ -65,6 +65,8 @@ void mark_circuit_unusable_for_new_conns(origin_circuit_t *circ);
 
 int circuit_purpose_is_hidden_service(uint8_t);
 int circuit_should_use_vanguards(uint8_t);
+void circuit_sent_valid_data(origin_circuit_t *circ, uint16_t relay_body_len);
+void circuit_read_valid_data(origin_circuit_t *circ, uint16_t relay_body_len);
 
 #ifdef TOR_UNIT_TESTS
 /* Used only by circuituse.c and test_circuituse.c */
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 955f942c5..02f1680ee 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -3526,10 +3526,17 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
   n_stream->deliver_window = STREAMWINDOW_START;
 
   if (circ->purpose == CIRCUIT_PURPOSE_S_REND_JOINED) {
+    int ret;
     tor_free(address);
     /* We handle this circuit and stream in this function for all supported
      * hidden service version. */
-    return handle_hs_exit_conn(circ, n_stream);
+    ret = handle_hs_exit_conn(circ, n_stream);
+
+    if (ret == 0) {
+      /* This was a valid cell. Count it as delivered + overhead. */
+      circuit_read_valid_data(origin_circ, rh.length);
+    }
+    return ret;
   }
   tor_strlower(address);
   n_stream->base_.address = address;
diff --git a/src/or/or.h b/src/or/or.h
index e27f25197..fc72badb4 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -3250,16 +3250,36 @@ typedef struct origin_circuit_t {
    * associated with this circuit. */
   edge_connection_t *p_streams;
 
-  /** Bytes read from any attached stream since last call to
+  /** Bytes read on this circuit since last call to
    * control_event_circ_bandwidth_used().  Only used if we're configured
    * to emit CIRC_BW events. */
   uint32_t n_read_circ_bw;
 
-  /** Bytes written to any attached stream since last call to
+  /** Bytes written to on this circuit since last call to
    * control_event_circ_bandwidth_used().  Only used if we're configured
    * to emit CIRC_BW events. */
   uint32_t n_written_circ_bw;
 
+  /** Total known-valid relay cell bytes since last call to
+   * control_event_circ_bandwidth_used().  Only used if we're configured
+   * to emit CIRC_BW events. */
+  uint32_t n_delivered_read_circ_bw;
+
+  /** Total written relay cell bytes since last call to
+   * control_event_circ_bandwidth_used().  Only used if we're configured
+   * to emit CIRC_BW events. */
+  uint32_t n_delivered_written_circ_bw;
+
+  /** Total overhead data in all known-valid relay data cells since last
+   * call to control_event_circ_bandwidth_used().  Only used if we're
+   * configured to emit CIRC_BW events. */
+  uint32_t n_overhead_read_circ_bw;
+
+  /** Total written overhead data in all relay data cells since last call to
+   * control_event_circ_bandwidth_used().  Only used if we're configured
+   * to emit CIRC_BW events. */
+  uint32_t n_overhead_written_circ_bw;
+
   /** Build state for this circuit. It includes the intended path
    * length, the chosen exit router, rendezvous information, etc.
    */
diff --git a/src/or/relay.c b/src/or/relay.c
index 8c248e6d9..05f71efea 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -611,6 +611,10 @@ relay_send_command_from_edge_,(streamid_t stream_id, circuit_t *circ,
       tor_free(commands);
       smartlist_free(commands_list);
     }
+
+    /* Let's assume we're well-behaved: Anything that we decide to send is
+     * valid, delivered data. */
+    circuit_sent_valid_data(origin_circ, rh.length);
   }
 
   if (circuit_package_relay_cell(&cell, circ, cell_direction, cpath_layer,
@@ -740,6 +744,9 @@ connection_ap_process_end_not_open(
     }
   }
 
+  /* This end cell is now valid. */
+  circuit_read_valid_data(circ, rh->length);
+
   if (rh->length == 0) {
     reason = END_STREAM_REASON_MISC;
   }
@@ -1230,6 +1237,12 @@ 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);
+  }
+
   connection_ap_handshake_socks_got_resolved_cell(entry_conn,
                                                   errcode,
                                                   resolved_addresses);
@@ -1326,6 +1339,9 @@ connection_edge_process_relay_cell_not_open(
                                 entry_conn->chosen_exit_name, ttl);
 
       remap_event_helper(entry_conn, &addr);
+
+      /* This is valid data at this point. Count it */
+      circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh->length);
     }
     circuit_log_path(LOG_INFO,LD_APP,TO_ORIGIN_CIRCUIT(circ));
     /* don't send a socks reply to transparent conns */
@@ -1496,7 +1512,6 @@ connection_edge_process_relay_cell(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);
     case RELAY_COMMAND_DATA:
       ++stats_n_data_cells_received;
@@ -1532,6 +1547,10 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
                "(relay data) conn deliver_window below 0. Killing.");
         return -END_CIRC_REASON_TORPROTOCOL;
       }
+      /* Total all valid application bytes delivered */
+      if (CIRCUIT_IS_ORIGIN(circ)) {
+        circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+      }
 
       stats_n_data_bytes_received += rh.length;
       connection_buf_add((char*)(cell->payload + RELAY_HEADER_SIZE),
@@ -1584,6 +1603,11 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
         /* only mark it if not already marked. it's possible to
          * get the 'end' right around when the client hangs up on us. */
         connection_mark_and_flush(TO_CONN(conn));
+
+        /* Total all valid application bytes delivered */
+        if (CIRCUIT_IS_ORIGIN(circ)) {
+          circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+        }
       }
       return 0;
     case RELAY_COMMAND_EXTEND:
@@ -1649,6 +1673,10 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
         log_info(domain,"circuit_send_next_onion_skin() failed.");
         return reason;
       }
+      /* Total all valid bytes delivered. */
+      if (CIRCUIT_IS_ORIGIN(circ)) {
+        circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+      }
       return 0;
     case RELAY_COMMAND_TRUNCATE:
       if (layer_hint) {
@@ -1714,6 +1742,16 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
           log_debug(LD_APP,"circ-level sendme at origin, packagewindow %d.",
                     layer_hint->package_window);
           circuit_resume_edge_reading(circ, layer_hint);
+
+          /* We count circuit-level sendme's as valid delivered data because
+           * they are rate limited. Note that we cannot count stream
+           * sendme's because the other end could send as many as they like.
+           */
+          if (CIRCUIT_IS_ORIGIN(circ)) {
+            circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ),
+                                    rh.length);
+          }
+
         } else {
           if (circ->package_window + CIRCWINDOW_INCREMENT >
                 CIRCWINDOW_START_MAX) {
diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c
index 230da4be5..2a77b2ece 100644
--- a/src/or/rendcommon.c
+++ b/src/or/rendcommon.c
@@ -12,6 +12,7 @@
 
 #include "or.h"
 #include "circuitbuild.h"
+#include "circuituse.h"
 #include "config.h"
 #include "control.h"
 #include "hs_common.h"
@@ -807,6 +808,11 @@ rend_process_relay_cell(circuit_t *circ, const crypt_path_t *layer_hint,
       tor_fragile_assert();
   }
 
+  if (r == 0 && origin_circ) {
+    /* This was a valid cell. Count it as delivered + overhead. */
+    circuit_read_valid_data(origin_circ, length);
+  }
+
   if (r == -2)
     log_info(LD_PROTOCOL, "Dropping cell (type %d) for wrong circuit type.",
              command);





More information about the tor-commits mailing list