summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2018-06-21 09:20:03 -0400
committerNick Mathewson <nickm@torproject.org>2018-06-21 09:20:03 -0400
commit2ad062ee601bc30594b81a33404662fbd59ef8b1 (patch)
tree95b8a086f37938c09cebacc9ffa1ae06bb230682
parentd46969e8208394640d9fe84edbc428329d4ec642 (diff)
parent46b06cd6999439608f4a8a34bb68f6fe6a6311e9 (diff)
downloadtor-2ad062ee601bc30594b81a33404662fbd59ef8b1.tar.gz
tor-2ad062ee601bc30594b81a33404662fbd59ef8b1.zip
Merge branch 'mikeperry_bug26214-rebased_squashed'
-rw-r--r--changes/bug262143
-rw-r--r--src/or/or.h1
-rw-r--r--src/or/relay.c24
-rw-r--r--src/test/test_relaycell.c17
4 files changed, 42 insertions, 3 deletions
diff --git a/changes/bug26214 b/changes/bug26214
new file mode 100644
index 0000000000..4277b9c6ec
--- /dev/null
+++ b/changes/bug26214
@@ -0,0 +1,3 @@
+ o Minor bugfixes (correctness, flow control):
+ - Upon receiving a stream-level SENDME cell, verify that our window has
+ not grown too large. Fixes bug 26214; bugfix on svn r54 (pre-0.0.1)
diff --git a/src/or/or.h b/src/or/or.h
index 33a674d146..55364beee9 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -921,6 +921,7 @@ typedef enum {
/** Initial value on both sides of a stream transmission window when the
* stream is initialized. Measured in cells. */
#define STREAMWINDOW_START 500
+#define STREAMWINDOW_START_MAX 500
/** Amount to increment a stream window when we get a stream SENDME. */
#define STREAMWINDOW_INCREMENT 50
diff --git a/src/or/relay.c b/src/or/relay.c
index 143580a310..af03cd4748 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -1765,8 +1765,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
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.
+ * they are rate limited.
*/
if (CIRCUIT_IS_ORIGIN(circ)) {
circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ),
@@ -1796,6 +1795,27 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
rh.stream_id);
return 0;
}
+
+ /* Don't allow the other endpoint to request more than our maximim
+ * (ie 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 connection_edge_consider_sending_sendme()).
+ */
+ 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;
+ }
+
+ /* At this point, the stream sendme is valid */
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ),
+ rh.length);
+ }
+
conn->package_window += STREAMWINDOW_INCREMENT;
log_debug(domain,"stream-level sendme, packagewindow now %d.",
conn->package_window);
diff --git a/src/test/test_relaycell.c b/src/test/test_relaycell.c
index 770692440d..64b0664292 100644
--- a/src/test/test_relaycell.c
+++ b/src/test/test_relaycell.c
@@ -246,11 +246,26 @@ test_circbw_relay(void *arg)
circ->cpath);
ASSERT_UNCOUNTED_BW();
- /* Sendme on stream: not counted */
+ /* Sendme on valid stream: counted */
ENTRY_TO_CONN(entryconn)->outbuf_flushlen = 0;
PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ /* Sendme on valid stream with full window: not counted */
+ ENTRY_TO_CONN(entryconn)->outbuf_flushlen = 0;
+ PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
+ edgeconn->package_window = 500;
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Sendme on unknown stream: not counted */
+ ENTRY_TO_CONN(entryconn)->outbuf_flushlen = 0;
+ PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Sendme on circuit with full window: not counted */