summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2003-12-16 20:45:10 +0000
committerRoger Dingledine <arma@torproject.org>2003-12-16 20:45:10 +0000
commit4e50f79b11c03b07856bce1c725fd9750677be21 (patch)
treeac12623779f8d7446c54a5f8e0771f96458b0476
parentfd37a6fedf9f98dc3fed767db885f6f8796a9f4c (diff)
downloadtor-4e50f79b11c03b07856bce1c725fd9750677be21.tar.gz
tor-4e50f79b11c03b07856bce1c725fd9750677be21.zip
resolve an edge case in get_unique_circ_id_by_conn
svn:r944
-rw-r--r--src/or/circuit.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/src/or/circuit.c b/src/or/circuit.c
index 7a7cc13b63..2709445b8d 100644
--- a/src/or/circuit.c
+++ b/src/or/circuit.c
@@ -26,7 +26,6 @@ char *circuit_state_to_string[] = {
/********* END VARIABLES ************/
void circuit_add(circuit_t *circ) {
-
if(!global_circuitlist) { /* first one */
global_circuitlist = circ;
circ->next = NULL;
@@ -34,7 +33,6 @@ void circuit_add(circuit_t *circ) {
circ->next = global_circuitlist;
global_circuitlist = circ;
}
-
}
void circuit_remove(circuit_t *circ) {
@@ -126,20 +124,26 @@ static void circuit_free_cpath_node(crypt_path_t *victim) {
/* return 0 if can't get a unique circ_id. */
static circ_id_t get_unique_circ_id_by_conn(connection_t *conn, int circ_id_type) {
circ_id_t test_circ_id;
+ int attempts=0;
uint16_t high_bit;
- assert(conn && conn->type == CONN_TYPE_OR);
+ assert(conn && conn->type == CONN_TYPE_OR);
high_bit = (circ_id_type == CIRC_ID_TYPE_HIGHER) ? 1<<15 : 0;
do {
- /* Sequentially iterate over test_circ_id=1...1<<15-1 until we find an
+ /* Sequentially iterate over test_circ_id=1...1<<15-1 until we find a
* circID such that (high_bit|test_circ_id) is not already used. */
- /* XXX Will loop forever if all circ_id's in our range are used.
- * This matters because it's an external DoS vulnerability. */
test_circ_id = conn->next_circ_id++;
if (test_circ_id == 0 || test_circ_id >= 1<<15) {
test_circ_id = 1;
conn->next_circ_id = 2;
}
+ if(++attempts > 1<<15) {
+ /* Make sure we don't loop forever if all circ_id's are used. This
+ * matters because it's an external DoS vulnerability.
+ */
+ log_fn(LOG_WARN,"No unused circ IDs. Failing.");
+ return 0;
+ }
test_circ_id |= high_bit;
} while(circuit_get_by_circ_id_conn(test_circ_id, conn));
return test_circ_id;