aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2013-06-14 01:44:46 -0400
committerNick Mathewson <nickm@torproject.org>2013-06-14 01:44:46 -0400
commitd780cd5fd428176ebf4a72610ec4066c18346c09 (patch)
tree760ae90a44e4b7e19916924232a90a4c08295d10
parent4835faebf533f93eb390649dfcb5c8cc0289e3d3 (diff)
parent9e8c104ab879f979d313d1f1cef4c1480f431ceb (diff)
downloadtor-d780cd5fd428176ebf4a72610ec4066c18346c09.tar.gz
tor-d780cd5fd428176ebf4a72610ec4066c18346c09.zip
Merge branch 'circuit_queue_cap-0.2.3-squashed' into maint-0.2.3
-rw-r--r--changes/bug90633
-rw-r--r--src/or/or.h9
-rw-r--r--src/or/relay.c23
3 files changed, 34 insertions, 1 deletions
diff --git a/changes/bug9063 b/changes/bug9063
new file mode 100644
index 0000000000..af3b1a87f4
--- /dev/null
+++ b/changes/bug9063
@@ -0,0 +1,3 @@
+ o Normal bugfixes:
+ - Close any circuit that has more cells queued than the spec permits.
+ Fixes bug #9063; bugfix on 0.2.3.25.
diff --git a/src/or/or.h b/src/or/or.h
index 6728b862b5..83bf8c8900 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -539,6 +539,8 @@ typedef enum {
#define CIRCUIT_PURPOSE_IS_ESTABLISHED_REND(p) \
((p) == CIRCUIT_PURPOSE_C_REND_JOINED || \
(p) == CIRCUIT_PURPOSE_S_REND_JOINED)
+/** True iff the circuit_t c is actually an or_circuit_t */
+#define CIRCUIT_IS_ORCIRC(c) (((circuit_t *)(c))->magic == OR_CIRCUIT_MAGIC)
/** How many circuits do we want simultaneously in-progress to handle
* a given stream? */
@@ -814,6 +816,13 @@ typedef enum {
/** Amount to increment a stream window when we get a stream SENDME. */
#define STREAMWINDOW_INCREMENT 50
+/** Maximum number of queued cells on a circuit for which we are the
+ * midpoint before we give up and kill it. This must be >= circwindow
+ * to avoid killing innocent circuits, and >= circwindow*2 to give
+ * leaky-pipe a chance for being useful someday.
+ */
+#define ORCIRC_MAX_MIDDLE_CELLS (21*(CIRCWINDOW_START_MAX)/10)
+
/* Cell commands. These values are defined in tor-spec.txt. */
#define CELL_PADDING 0
#define CELL_CREATE 1
diff --git a/src/or/relay.c b/src/or/relay.c
index a17c333310..087459c5c0 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -2532,8 +2532,10 @@ append_cell_to_circuit_queue(circuit_t *circ, or_connection_t *orconn,
cell_t *cell, cell_direction_t direction,
streamid_t fromstream)
{
+ or_circuit_t *orcirc = NULL;
cell_queue_t *queue;
int streams_blocked;
+
if (circ->marked_for_close)
return;
@@ -2541,11 +2543,30 @@ append_cell_to_circuit_queue(circuit_t *circ, or_connection_t *orconn,
queue = &circ->n_conn_cells;
streams_blocked = circ->streams_blocked_on_n_conn;
} else {
- or_circuit_t *orcirc = TO_OR_CIRCUIT(circ);
+ orcirc = TO_OR_CIRCUIT(circ);
queue = &orcirc->p_conn_cells;
streams_blocked = circ->streams_blocked_on_p_conn;
}
+ /* Are we a middle circuit about to exceed ORCIRC_MAX_MIDDLE_CELLS? */
+ if ((circ->n_conn != NULL) && CIRCUIT_IS_ORCIRC(circ)) {
+ orcirc = TO_OR_CIRCUIT(circ);
+ if (orcirc->p_conn) {
+ if (queue->n + 1 >= ORCIRC_MAX_MIDDLE_CELLS) {
+ /* Queueing this cell would put queue over the cap */
+ log_warn(LD_CIRC,
+ "Got a cell exceeding the cap of %u in the %s direction "
+ "on middle circ ID %u; killing the circuit.",
+ ORCIRC_MAX_MIDDLE_CELLS,
+ (direction == CELL_DIRECTION_OUT) ? "n" : "p",
+ (direction == CELL_DIRECTION_OUT) ?
+ circ->n_circ_id : orcirc->p_circ_id);
+ circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT);
+ return;
+ }
+ }
+ }
+
cell_queue_append_packed_copy(queue, cell);
/* If we have too many cells on the circuit, we should stop reading from