aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changes/ticket405683
-rw-r--r--src/core/or/congestion_control_common.c42
-rw-r--r--src/core/or/congestion_control_common.h1
-rw-r--r--src/core/or/congestion_control_flow.c29
-rw-r--r--src/core/or/congestion_control_nola.c16
-rw-r--r--src/core/or/congestion_control_vegas.c9
-rw-r--r--src/core/or/congestion_control_westwood.c9
-rw-r--r--src/core/or/sendme.c8
-rw-r--r--src/feature/control/control_events.c16
-rw-r--r--src/feature/control/control_events.h6
10 files changed, 131 insertions, 8 deletions
diff --git a/changes/ticket40568 b/changes/ticket40568
new file mode 100644
index 0000000000..a90669673a
--- /dev/null
+++ b/changes/ticket40568
@@ -0,0 +1,3 @@
+ o Minor features (control port):
+ - Provide congestion control fields on CIRC_BW and STREAM control
+ port events, for use by sbws. Closes ticket 40568.
diff --git a/src/core/or/congestion_control_common.c b/src/core/or/congestion_control_common.c
index 93d3a9f2c5..36099cc1c6 100644
--- a/src/core/or/congestion_control_common.c
+++ b/src/core/or/congestion_control_common.c
@@ -1442,3 +1442,45 @@ congestion_control_parse_ext_response(const uint8_t *msg,
return (int)ret;
}
+
+/**
+ * Returns a formatted string of fields containing congestion
+ * control information, for the CIRC_BW control port event.
+ *
+ * An origin circuit can have a ccontrol object directly on it,
+ * if it is an onion service, or onion client. Exit-bound clients
+ * will have the ccontrol on the cpath associated with their exit
+ * (the last one in the cpath list).
+ *
+ * WARNING: This function does not support leaky-pipe topology. It
+ * is to be used for control port information only.
+ */
+char *
+congestion_control_get_control_port_fields(const origin_circuit_t *circ)
+{
+ const congestion_control_t *ccontrol = NULL;
+ char *ret = NULL;
+ int len;
+
+ if (TO_CIRCUIT(circ)->ccontrol) {
+ ccontrol = TO_CIRCUIT(circ)->ccontrol;
+ } else if (circ->cpath && circ->cpath->prev->ccontrol) {
+ /* Get ccontrol for last hop (exit) if it exists */
+ ccontrol = circ->cpath->prev->ccontrol;
+ }
+
+ if (!ccontrol)
+ return NULL;
+
+ len = tor_asprintf(&ret,
+ " SS=%d CWND=%"PRIu64" RTT=%"PRIu64" MIN_RTT=%"PRIu64,
+ ccontrol->in_slow_start, ccontrol->cwnd,
+ ccontrol->ewma_rtt_usec/1000,
+ ccontrol->min_rtt_usec/1000);
+ if (len < 0) {
+ log_warn(LD_BUG, "Unable to format event for controller.");
+ return NULL;
+ }
+
+ return ret;
+}
diff --git a/src/core/or/congestion_control_common.h b/src/core/or/congestion_control_common.h
index 1a57d71331..71e984f914 100644
--- a/src/core/or/congestion_control_common.h
+++ b/src/core/or/congestion_control_common.h
@@ -80,6 +80,7 @@ int congestion_control_parse_ext_response(const uint8_t *msg,
const size_t msg_len,
circuit_params_t *params_out);
bool congestion_control_validate_sendme_increment(uint8_t sendme_inc);
+char *congestion_control_get_control_port_fields(const origin_circuit_t *);
/* Ugh, C.. these are private. Use the getter instead, when
* external to the congestion control code. */
diff --git a/src/core/or/congestion_control_flow.c b/src/core/or/congestion_control_flow.c
index 3a3a9522fd..035337b55e 100644
--- a/src/core/or/congestion_control_flow.c
+++ b/src/core/or/congestion_control_flow.c
@@ -22,6 +22,7 @@
#include "core/or/trace_probes_cc.h"
#include "feature/nodelist/networkstatus.h"
#include "trunnel/flow_control_cells.h"
+#include "feature/control/control_events.h"
#include "core/or/connection_st.h"
#include "core/or/cell_st.h"
@@ -147,6 +148,13 @@ circuit_send_stream_xoff(edge_connection_t *stream)
if (connection_edge_send_command(stream, RELAY_COMMAND_XOFF,
(char*)payload, (size_t)xoff_size) == 0) {
stream->xoff_sent = true;
+
+ /* If this is an entry conn, notify control port */
+ if (TO_CONN(stream)->type == CONN_TYPE_AP) {
+ control_event_stream_status(TO_ENTRY_CONN(TO_CONN(stream)),
+ STREAM_EVENT_XOFF_SENT,
+ 0);
+ }
}
}
@@ -213,6 +221,13 @@ circuit_send_stream_xon(edge_connection_t *stream)
(size_t)xon_size) == 0) {
/* Revert the xoff sent status, so we can send another one if need be */
stream->xoff_sent = false;
+
+ /* If it's an entry conn, notify control port */
+ if (TO_CONN(stream)->type == CONN_TYPE_AP) {
+ control_event_stream_status(TO_ENTRY_CONN(TO_CONN(stream)),
+ STREAM_EVENT_XON_SENT,
+ 0);
+ }
}
}
@@ -299,6 +314,13 @@ circuit_process_stream_xoff(edge_connection_t *conn,
connection_stop_reading(TO_CONN(conn));
conn->xoff_received = true;
+ /* If this is an entry conn, notify control port */
+ if (TO_CONN(conn)->type == CONN_TYPE_AP) {
+ control_event_stream_status(TO_ENTRY_CONN(TO_CONN(conn)),
+ STREAM_EVENT_XOFF_RECV,
+ 0);
+ }
+
return retval;
}
@@ -403,6 +425,13 @@ circuit_process_stream_xon(edge_connection_t *conn,
connection_start_reading(TO_CONN(conn));
}
+ /* If this is an entry conn, notify control port */
+ if (TO_CONN(conn)->type == CONN_TYPE_AP) {
+ control_event_stream_status(TO_ENTRY_CONN(TO_CONN(conn)),
+ STREAM_EVENT_XON_RECV,
+ 0);
+ }
+
xon_cell_free(xon);
return retval;
diff --git a/src/core/or/congestion_control_nola.c b/src/core/or/congestion_control_nola.c
index 52d41157a2..0c64793d91 100644
--- a/src/core/or/congestion_control_nola.c
+++ b/src/core/or/congestion_control_nola.c
@@ -22,6 +22,7 @@
#include "core/or/origin_circuit_st.h"
#include "core/or/channel.h"
#include "feature/nodelist/networkstatus.h"
+#include "feature/control/control_events.h"
#define NOLA_BDP_OVERSHOOT 100
@@ -70,8 +71,19 @@ congestion_control_nola_process_sendme(congestion_control_t *cc,
/* If we get a congestion event, the only thing NOLA
* does is note this as if we exited slow-start
* (which for NOLA just means we finished our ICW). */
- if (cc->next_cc_event == 0)
- cc->in_slow_start = 0;
+ if (cc->next_cc_event == 0) {
+ if (cc->in_slow_start) {
+ cc->in_slow_start = 0;
+
+ /* We need to report that slow start has exited ASAP,
+ * for sbws bandwidth measurement. */
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ /* We must discard const here because the event modifies fields :/ */
+ control_event_circ_bandwidth_used_for_circ(
+ TO_ORIGIN_CIRCUIT((circuit_t*)circ));
+ }
+ }
+ }
/* If we did not successfully update BDP, we must return. Otherwise,
* NOLA can drift downwards */
diff --git a/src/core/or/congestion_control_vegas.c b/src/core/or/congestion_control_vegas.c
index 5c62787375..5451d7849c 100644
--- a/src/core/or/congestion_control_vegas.c
+++ b/src/core/or/congestion_control_vegas.c
@@ -22,6 +22,7 @@
#include "core/or/origin_circuit_st.h"
#include "core/or/channel.h"
#include "feature/nodelist/networkstatus.h"
+#include "feature/control/control_events.h"
#define OUTBUF_CELLS (2*TLS_RECORD_MAX_CELLS)
@@ -236,6 +237,14 @@ congestion_control_vegas_process_sendme(congestion_control_t *cc,
cc->cwnd = vegas_bdp_mix(cc) + cc->vegas_params.gamma;
cc->in_slow_start = 0;
log_info(LD_CIRC, "CC: TOR_VEGAS exiting slow start");
+
+ /* We need to report that slow start has exited ASAP,
+ * for sbws bandwidth measurement. */
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ /* We must discard const here because the event modifies fields :/ */
+ control_event_circ_bandwidth_used_for_circ(
+ TO_ORIGIN_CIRCUIT((circuit_t*)circ));
+ }
}
} else {
if (queue_use > cc->vegas_params.delta) {
diff --git a/src/core/or/congestion_control_westwood.c b/src/core/or/congestion_control_westwood.c
index 357cdeb3b9..2e4575554a 100644
--- a/src/core/or/congestion_control_westwood.c
+++ b/src/core/or/congestion_control_westwood.c
@@ -22,6 +22,7 @@
#include "core/or/origin_circuit_st.h"
#include "core/or/channel.h"
#include "feature/nodelist/networkstatus.h"
+#include "feature/control/control_events.h"
#define USEC_ONE_MS (1000)
@@ -179,6 +180,14 @@ congestion_control_westwood_process_sendme(congestion_control_t *cc,
log_info(LD_CIRC, "CC: TOR_WESTWOOD congestion. New max RTT: %"PRIu64,
cc->max_rtt_usec/1000);
+
+ /* We need to report that slow start has exited ASAP,
+ * for sbws bandwidth measurement. */
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ /* We must discard const here because the event modifies fields :/ */
+ control_event_circ_bandwidth_used_for_circ(
+ TO_ORIGIN_CIRCUIT((circuit_t*)circ));
+ }
}
/* cwnd can never fall below 1 increment */
diff --git a/src/core/or/sendme.c b/src/core/or/sendme.c
index 494910049e..90f4dfcf05 100644
--- a/src/core/or/sendme.c
+++ b/src/core/or/sendme.c
@@ -474,12 +474,14 @@ sendme_process_circuit_level(crypt_path_t *layer_hint,
return -END_CIRC_REASON_TORPROTOCOL;
}
+ /* origin circuits need to count valid sendmes as valid protocol data */
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), cell_payload_len);
+ }
+
// Get CC
if (layer_hint) {
cc = layer_hint->ccontrol;
-
- /* origin circuits need to count valid sendmes as valid protocol data */
- circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), cell_payload_len);
} else {
cc = circ->ccontrol;
}
diff --git a/src/feature/control/control_events.c b/src/feature/control/control_events.c
index e2aca6c03e..4c8cf9a425 100644
--- a/src/feature/control/control_events.c
+++ b/src/feature/control/control_events.c
@@ -21,6 +21,7 @@
#include "core/or/command.h"
#include "core/or/connection_edge.h"
#include "core/or/connection_or.h"
+#include "core/or/congestion_control_common.h"
#include "core/or/reasons.h"
#include "feature/control/control.h"
#include "feature/control/control_events.h"
@@ -819,6 +820,10 @@ control_event_stream_status(entry_connection_t *conn, stream_status_event_t tp,
case STREAM_EVENT_FAILED_RETRIABLE: status = "DETACHED"; break;
case STREAM_EVENT_REMAP: status = "REMAP"; break;
case STREAM_EVENT_CONTROLLER_WAIT: status = "CONTROLLER_WAIT"; break;
+ case STREAM_EVENT_XOFF_SENT: status = "XOFF_SENT"; break;
+ case STREAM_EVENT_XOFF_RECV: status = "XOFF_RECV"; break;
+ case STREAM_EVENT_XON_SENT: status = "XON_SENT"; break;
+ case STREAM_EVENT_XON_RECV: status = "XON_RECV"; break;
default:
log_warn(LD_BUG, "Unrecognized status code %d", (int)tp);
return 0;
@@ -1075,10 +1080,12 @@ control_event_circ_bandwidth_used_for_circ(origin_circuit_t *ocirc)
tor_gettimeofday(&now);
format_iso_time_nospace_usec(tbuf, &now);
+
+ char *ccontrol_buf = congestion_control_get_control_port_fields(ocirc);
send_control_event(EVENT_CIRC_BANDWIDTH_USED,
"650 CIRC_BW ID=%d READ=%lu WRITTEN=%lu TIME=%s "
"DELIVERED_READ=%lu OVERHEAD_READ=%lu "
- "DELIVERED_WRITTEN=%lu OVERHEAD_WRITTEN=%lu\r\n",
+ "DELIVERED_WRITTEN=%lu OVERHEAD_WRITTEN=%lu%s\r\n",
ocirc->global_identifier,
(unsigned long)ocirc->n_read_circ_bw,
(unsigned long)ocirc->n_written_circ_bw,
@@ -1086,11 +1093,16 @@ control_event_circ_bandwidth_used_for_circ(origin_circuit_t *ocirc)
(unsigned long)ocirc->n_delivered_read_circ_bw,
(unsigned long)ocirc->n_overhead_read_circ_bw,
(unsigned long)ocirc->n_delivered_written_circ_bw,
- (unsigned long)ocirc->n_overhead_written_circ_bw);
+ (unsigned long)ocirc->n_overhead_written_circ_bw,
+ ccontrol_buf ? ccontrol_buf : "");
+
ocirc->n_written_circ_bw = ocirc->n_read_circ_bw = 0;
ocirc->n_overhead_written_circ_bw = ocirc->n_overhead_read_circ_bw = 0;
ocirc->n_delivered_written_circ_bw = ocirc->n_delivered_read_circ_bw = 0;
+ if (ccontrol_buf)
+ tor_free(ccontrol_buf);
+
return 0;
}
diff --git a/src/feature/control/control_events.h b/src/feature/control/control_events.h
index 68269cabba..901d2701cf 100644
--- a/src/feature/control/control_events.h
+++ b/src/feature/control/control_events.h
@@ -37,7 +37,11 @@ typedef enum stream_status_event_t {
STREAM_EVENT_NEW_RESOLVE = 6,
STREAM_EVENT_FAILED_RETRIABLE = 7,
STREAM_EVENT_REMAP = 8,
- STREAM_EVENT_CONTROLLER_WAIT = 9
+ STREAM_EVENT_CONTROLLER_WAIT = 9,
+ STREAM_EVENT_XOFF_SENT = 10,
+ STREAM_EVENT_XOFF_RECV = 11,
+ STREAM_EVENT_XON_SENT = 12,
+ STREAM_EVENT_XON_RECV = 13
} stream_status_event_t;
/** Used to indicate the type of a buildtime event */