diff options
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/config.c | 1 | ||||
-rw-r--r-- | src/or/or.h | 5 | ||||
-rw-r--r-- | src/or/rendmid.c | 39 |
3 files changed, 41 insertions, 4 deletions
diff --git a/src/or/config.c b/src/or/config.c index 443ebcac8..b4b9ee9de 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -349,6 +349,7 @@ static config_var_t option_vars_[] = { V(PerConnBWRate, MEMUNIT, "0"), V(PidFile, STRING, NULL), V(IntroPointAcceptMutipleConnections, BOOL, "0"), + V(IntroPointLoadBalancingAlgorithm, STRING, "random"), V(TestingTorNetwork, BOOL, "0"), V(TestingMinExitFlagThreshold, MEMUNIT, "0"), V(TestingMinFastFlagThreshold, MEMUNIT, "0"), diff --git a/src/or/or.h b/src/or/or.h index 14097da6e..cfbaba469 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3206,6 +3206,9 @@ typedef struct or_circuit_t { * to zero, it is initialized to the default value. */ uint32_t max_middle_cells; + + /** True iff this circuit was the last one used for an introduction. */ + unsigned int intro_last_used : 1; } or_circuit_t; /** Convert a circuit subtype to a circuit_t. */ @@ -4022,6 +4025,8 @@ typedef struct { int IntroPointAcceptMutipleConnections; + char* IntroPointLoadBalancingAlgorithm; + /** Minimum value for the Exit flag threshold on testing networks. */ uint64_t TestingMinExitFlagThreshold; diff --git a/src/or/rendmid.c b/src/or/rendmid.c index e7a7849db..81a2f16ec 100644 --- a/src/or/rendmid.c +++ b/src/or/rendmid.c @@ -174,6 +174,7 @@ rend_mid_introduce(or_circuit_t *circ, const uint8_t *request, (char*)request, REND_SERVICE_ID_LEN); /* The first 20 bytes are all we look at: they have a hash of Bob's PK. */ + smartlist_t *intro_circuits = circuits_get_intro_point((char*)request); log_info(LD_REND, @@ -189,14 +190,44 @@ rend_mid_introduce(or_circuit_t *circ, const uint8_t *request, } // Need to select which circuit to use - int circ_selection = crypto_rand_int(smartlist_len(intro_circuits)); + int circ_selection = -1; - log_info(LD_REND, - "selected circuit %i for service %s", - circ_selection, safe_str(serviceid)); + if (strcasecmp(get_options()->IntroPointLoadBalancingAlgorithm, "random")) { + circ_selection = crypto_rand_int(smartlist_len(intro_circuits)); + + log_info(LD_REND, + "selected circuit %i randomly for service %s", + circ_selection, safe_str(serviceid)); + } else if (strcasecmp(get_options()->IntroPointLoadBalancingAlgorithm, + "roundrobin")) { + + SMARTLIST_FOREACH_BEGIN(intro_circuits, or_circuit_t *, circuit) + { + circ_selection++; + if (circuit->intro_last_used) { + circuit->intro_last_used = 0; + break; + } + } + SMARTLIST_FOREACH_END(circuit); + + circ_selection++; + + if (circ_selection == smartlist_len(intro_circuits)) + circ_selection = 0; + + log_info(LD_REND, + "selected circuit %i using round robin for service %s", + circ_selection, safe_str(serviceid)); + } else if (strcasecmp(get_options()->IntroPointLoadBalancingAlgorithm, + "weightedroundrobin")) { + + } intro_circ = smartlist_get(intro_circuits, circ_selection); + intro_circ->intro_last_used = 1; + log_info(LD_REND, "Sending introduction request for service %s " "from circ %u to circ %u", |