commit 7acc7c3dc6299438f7d5e6ebc6cb64f2ea3b5fa6 Author: Roger Dingledine arma@torproject.org Date: Tue Sep 3 20:40:16 2013 -0400
do a lopsided round-robin between the onion queues
that way tap won't starve entirely, but we'll still handle ntor requests quicker. --- src/or/onion.c | 43 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-)
diff --git a/src/or/onion.c b/src/or/onion.c index 0b04891..639481b 100644 --- a/src/or/onion.c +++ b/src/or/onion.c @@ -165,6 +165,42 @@ onion_pending_add(or_circuit_t *circ, create_cell_t *onionskin) return 0; }
+/** Return a fairness parameter, to prefer processing NTOR style + * handshakes but still slowly drain the TAP queue so we don't starve + * it entirely. */ +static int +num_ntors_per_tap(void) +{ +#define NUM_NTORS_PER_TAP 5 + return NUM_NTORS_PER_TAP; +} + +/** Choose which onion queue we'll pull from next. If one is empty choose + * the other; if they both have elements, load balance across them but + * favoring NTOR. */ +static uint16_t +decide_next_handshake_type(void) +{ + /* The number of times we've chosen ntor lately when both were available. */ + static int recently_chosen_ntors = 0; + + if (!ol_entries[ONION_HANDSHAKE_TYPE_NTOR]) + return ONION_HANDSHAKE_TYPE_TAP; /* no ntors? try tap */ + + if (!ol_entries[ONION_HANDSHAKE_TYPE_TAP]) + return ONION_HANDSHAKE_TYPE_NTOR; /* no taps? try ntor */ + + /* They both have something queued. Pick ntor if we haven't done that + * too much lately. */ + if (++recently_chosen_ntors <= num_ntors_per_tap()) { + return ONION_HANDSHAKE_TYPE_NTOR; + } + + /* Else, it's time to let tap have its turn. */ + recently_chosen_ntors = 0; + return ONION_HANDSHAKE_TYPE_TAP; +} + /** Remove the highest priority item from ol_list[] and return it, or * return NULL if the lists are empty. */ @@ -172,11 +208,8 @@ or_circuit_t * onion_next_task(create_cell_t **onionskin_out) { or_circuit_t *circ; - - /* skip ol_list[ONION_HANDSHAKE_TYPE_FAST] since we know it'll be empty */ - onion_queue_t *head = TOR_TAILQ_FIRST(&ol_list[ONION_HANDSHAKE_TYPE_NTOR]); - if (!head) - head = TOR_TAILQ_FIRST(&ol_list[ONION_HANDSHAKE_TYPE_TAP]); + uint16_t handshake_to_choose = decide_next_handshake_type(); + onion_queue_t *head = TOR_TAILQ_FIRST(&ol_list[handshake_to_choose]);
if (!head) return NULL; /* no onions pending, we're done */
tor-commits@lists.torproject.org