aboutsummaryrefslogtreecommitdiff
path: root/src/core/or/relay.c
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2019-01-08 15:03:04 -0500
committerDavid Goulet <dgoulet@torproject.org>2019-04-29 12:17:57 -0400
commit9c42cc1eb22da8125ec9596920dfb9113912eac0 (patch)
tree548f60c420955dc8cab545074905f7b294388a1a /src/core/or/relay.c
parented8593b9e0838f694eeb6315db38f6fadbc5ab71 (diff)
downloadtor-9c42cc1eb22da8125ec9596920dfb9113912eac0.tar.gz
tor-9c42cc1eb22da8125ec9596920dfb9113912eac0.zip
sendme: Refactor SENDME cell processing
This is a bit of a complicated commit. It moves code but also refactors part of it. No behavior change, the idea is to split things up so we can better handle and understand how SENDME cells are processed where ultimately it will be easier to handle authenticated SENDMEs (prop289) using the intermediate functions added in this commit. The entry point for the cell arriving at the edge (Client or Exit), is connection_edge_process_relay_cell() for which we look if it is a circuit or stream level SENDME. This commit refactors that part where two new functions are introduced to process each of the SENDME types. The sendme_process_circuit_level() has basically two code paths. If we are a Client (the circuit is origin) or we are an Exit. Depending on which, the package window is updated accordingly. Then finally, we resume the reading on every edge streams on the circuit. The sendme_process_stream_level() applies on the edge connection which will update the package window if needed and then will try to empty the inbuf if need be because we can now deliver more cells. Again, no behavior change but in order to split that code properly into their own functions and outside the relay.c file, code modification was needed. Part of #26840. Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat (limited to 'src/core/or/relay.c')
-rw-r--r--src/core/or/relay.c88
1 files changed, 27 insertions, 61 deletions
diff --git a/src/core/or/relay.c b/src/core/or/relay.c
index 7cfacf761a..132da21466 100644
--- a/src/core/or/relay.c
+++ b/src/core/or/relay.c
@@ -1807,87 +1807,52 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
(unsigned)circ->n_circ_id, rh.stream_id);
return 0;
case RELAY_COMMAND_SENDME:
- if (!rh.stream_id) {
- if (layer_hint) {
- if (layer_hint->package_window + CIRCWINDOW_INCREMENT >
- CIRCWINDOW_START_MAX) {
- static struct ratelim_t exit_warn_ratelim = RATELIM_INIT(600);
- log_fn_ratelim(&exit_warn_ratelim, LOG_WARN, LD_PROTOCOL,
- "Unexpected sendme cell from exit relay. "
- "Closing circ.");
- return -END_CIRC_REASON_TORPROTOCOL;
- }
- layer_hint->package_window += CIRCWINDOW_INCREMENT;
- 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.
- */
- if (CIRCUIT_IS_ORIGIN(circ)) {
- circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ),
- rh.length);
- }
+ {
+ int ret;
- } else {
- if (circ->package_window + CIRCWINDOW_INCREMENT >
- CIRCWINDOW_START_MAX) {
- static struct ratelim_t client_warn_ratelim = RATELIM_INIT(600);
- log_fn_ratelim(&client_warn_ratelim,LOG_PROTOCOL_WARN, LD_PROTOCOL,
- "Unexpected sendme cell from client. "
- "Closing circ (window %d).",
- circ->package_window);
- return -END_CIRC_REASON_TORPROTOCOL;
- }
- circ->package_window += CIRCWINDOW_INCREMENT;
- log_debug(LD_APP,
- "circ-level sendme at non-origin, packagewindow %d.",
- circ->package_window);
- circuit_resume_edge_reading(circ, layer_hint);
+ if (!rh.stream_id) {
+ /* Circuit level SENDME cell. */
+ ret = sendme_process_circuit_level(layer_hint, circ, rh.length);
+ if (ret < 0) {
+ return ret;
}
+ /* Resume reading on any streams now that we've processed a valid
+ * SENDME cell that updated our package window. */
+ circuit_resume_edge_reading(circ, layer_hint);
+ /* We are done, the rest of the code is for the stream level. */
return 0;
}
+
+ /* No connection, might be half edge state. We are done if so. */
if (!conn) {
if (CIRCUIT_IS_ORIGIN(circ)) {
origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
if (connection_half_edge_is_valid_sendme(ocirc->half_streams,
rh.stream_id)) {
circuit_read_valid_data(ocirc, rh.length);
- log_info(domain,
- "sendme cell on circ %u valid on half-closed "
- "stream id %d", ocirc->global_identifier, rh.stream_id);
+ log_info(domain, "Sendme cell on circ %u valid on half-closed "
+ "stream id %d",
+ ocirc->global_identifier, rh.stream_id);
}
}
- log_info(domain,"sendme cell dropped, unknown stream (streamid %d).",
+ log_info(domain, "SENDME cell dropped, unknown stream (streamid %d).",
rh.stream_id);
return 0;
}
- /* Don't allow the other endpoint to request more than our maximum
- * (i.e. initial) stream SENDME window worth of data. Well-behaved
- * stock clients will not request more than this max (as per the check
- * in the while loop of sendme_connection_edge_consider_sending()).
- */
- if (conn->package_window + STREAMWINDOW_INCREMENT >
- STREAMWINDOW_START_MAX) {
- static struct ratelim_t stream_warn_ratelim = RATELIM_INIT(600);
- log_fn_ratelim(&stream_warn_ratelim, LOG_PROTOCOL_WARN, LD_PROTOCOL,
- "Unexpected stream sendme cell. Closing circ (window %d).",
- conn->package_window);
- return -END_CIRC_REASON_TORPROTOCOL;
+ /* Stream level SENDME cell. */
+ ret = sendme_process_stream_level(conn, circ, rh.length);
+ if (ret < 0) {
+ /* Means we need to close the circuit with reason ret. */
+ return ret;
}
- /* At this point, the stream sendme is valid */
- if (CIRCUIT_IS_ORIGIN(circ)) {
- circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ),
- rh.length);
- }
+ /* We've now processed properly a SENDME cell, all windows have been
+ * properly updated, we'll read on the edge connection to see if we can
+ * get data out towards the end point (Exit or client) since we are now
+ * allowed to deliver more cells. */
- conn->package_window += STREAMWINDOW_INCREMENT;
- log_debug(domain,"stream-level sendme, packagewindow now %d.",
- conn->package_window);
if (circuit_queue_streams_are_blocked(circ)) {
/* Still waiting for queue to flush; don't touch conn */
return 0;
@@ -1900,6 +1865,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
return 0;
}
return 0;
+ }
case RELAY_COMMAND_RESOLVE:
if (layer_hint) {
log_fn(LOG_PROTOCOL_WARN, LD_APP,