[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r16584: {tor} Add hidden service request history to dynamically determine (tor/branches/hidserv-perf/src/or)
Author: chrisw
Date: 2008-08-18 12:01:08 -0400 (Mon, 18 Aug 2008)
New Revision: 16584
Modified:
tor/branches/hidserv-perf/src/or/circuituse.c
tor/branches/hidserv-perf/src/or/or.h
tor/branches/hidserv-perf/src/or/rendservice.c
Log:
Add hidden service request history to dynamically determine necessary number of internal circuits.
Modified: tor/branches/hidserv-perf/src/or/circuituse.c
===================================================================
--- tor/branches/hidserv-perf/src/or/circuituse.c 2008-08-18 14:58:32 UTC (rev 16583)
+++ tor/branches/hidserv-perf/src/or/circuituse.c 2008-08-18 16:01:08 UTC (rev 16584)
@@ -431,6 +431,10 @@
}
/* Third, see if we need any more hidden service (server) circuits. */
+
+ /* Use dynamic number of internal circuits here */
+// if (num_rend_services() && num_uptime_internal <
+// get_number_of_internal_circuits_needed()) {
if (num_rend_services() && num_uptime_internal < 3) {
flags = (CIRCLAUNCH_NEED_CAPACITY | CIRCLAUNCH_NEED_UPTIME |
CIRCLAUNCH_IS_INTERNAL);
@@ -702,17 +706,22 @@
introcirc_already_open == 0) {
log_info(LD_GENERAL, "TWOINTRO First intro circ candidate %s "
- "opened for service %s", circ->cpath->extend_info->nickname, TO_CIRCUIT(circ)->
+ "opened for service %s",
+ circ->cpath->extend_info->nickname, TO_CIRCUIT(circ)->
introcirc_for_edge_connection->rend_query);
TO_CIRCUIT(circ)->introcirc_for_edge_connection->
introcirc_already_open = 1;
rend_client_introcirc_has_opened(circ);
} else{
- log_info(LD_GENERAL, "TWOINTRO Second intro circ candidate %s for "
- "service %s opened", circ->cpath->extend_info->nickname, TO_CIRCUIT(circ)->
- introcirc_for_edge_connection->rend_query);
-
+ log_info(LD_GENERAL, "TWOINTRO Second intro circ candidate %s for "
+ "service %s opened",
+ circ->cpath->extend_info->nickname, TO_CIRCUIT(circ)->
+ introcirc_for_edge_connection->rend_query);
+
+ /* Because this is the loser circuit, we relable it for later
+ * usage. */
+ circ->_base.purpose = CIRCUIT_PURPOSE_C_GENERAL;
}
break;
case CIRCUIT_PURPOSE_C_GENERAL:
@@ -1065,10 +1074,6 @@
if (desired_circuit_purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) {
/* need to pick an intro point */
extend_info = rend_client_get_random_intro(conn->rend_query);
-// while (!strcmp(extend_info2->identity_digest,
-// extend_info->identity_digest)) {
- extend_info2 = rend_client_get_random_intro(conn->rend_query);
-// }
/* TWOINTRO Select second intro point and fetch info, if neccessary */
if (!extend_info) {
@@ -1080,7 +1085,14 @@
conn->_base.state = AP_CONN_STATE_RENDDESC_WAIT;
return 0;
}
- log_info(LD_REND,"Chose '%s' and '%s' as intro points for '%s'.",
+
+ /* TWOINTRO Select second intro point from descriptor */
+ do {
+ extend_info2 = rend_client_get_random_intro(conn->rend_query);
+ } while (extend_info2 && !strcmp(extend_info2->identity_digest,
+ extend_info->identity_digest));
+
+ log_info(LD_REND,"Chose '%s' and '%s' as intro point candidates for '%s'.",
extend_info->nickname, extend_info2->nickname,
safe_str(conn->rend_query));
}
Modified: tor/branches/hidserv-perf/src/or/or.h
===================================================================
--- tor/branches/hidserv-perf/src/or/or.h 2008-08-18 14:58:32 UTC (rev 16583)
+++ tor/branches/hidserv-perf/src/or/or.h 2008-08-18 16:01:08 UTC (rev 16584)
@@ -3842,6 +3842,21 @@
/********************************* rendservice.c ***************************/
+/** Represents a single request in the request history */
+typedef struct request_history_item {
+ long request_time; /**< Time of this request. */
+ struct request_history_item *prev; /**< Previous item in list. */
+ struct request_history_item *next; /**< Next item in list. */
+} request_history_item_t;
+
+/** Represents a linked list of recent service requests */
+typedef struct request_history_t {
+ long last_update; /** Time of the last history update */
+ int internal_circuits_needed; /** Number of internal circuits needed */
+ request_history_item_t *first_item; /**< First item in list. */
+ request_history_item_t *last_item; /**< Last item in list. */
+} request_history_t;
+
int num_rend_services(void);
int rend_config_services(or_options_t *options, int validate_only);
int rend_service_load_keys(void);
@@ -3861,6 +3876,9 @@
origin_circuit_t *circ);
void rend_service_dump_stats(int severity);
void rend_service_free_all(void);
+void add_service_request(request_history_t *request_history);
+int count_service_requests(request_history_t *request_history);
+int get_number_of_internal_circuits_needed(request_history_t *request_history);
/********************************* rendmid.c *******************************/
int rend_mid_establish_intro(or_circuit_t *circ, const char *request,
Modified: tor/branches/hidserv-perf/src/or/rendservice.c
===================================================================
--- tor/branches/hidserv-perf/src/or/rendservice.c 2008-08-18 14:58:32 UTC (rev 16583)
+++ tor/branches/hidserv-perf/src/or/rendservice.c 2008-08-18 16:01:08 UTC (rev 16584)
@@ -39,6 +39,16 @@
/** How many seconds should we spend trying to connect to a requested
* rendezvous point before giving up? */
#define MAX_REND_TIMEOUT 30
+/** How old are service requests allowed to be until they are droped out
+ * of the request history? */
+#define SERVICE_REQUEST_HISTORY_LENGTH (60*15)
+/** How many seconds can we keep an old internal circuit value until we
+ * have to recalculate it? */
+#define REQUEST_HISTORY_UPDATE_INTERVAL (60*5)
+/** How many internal circuits do we want to have at least? */
+#define MIN_INTERNAL_CIRCUITS 3
+/** How many internal circuits do we want to have at most? */
+#define MAX_INTERNAL_CIRCUITS 12
/** Represents a single hidden service running at this OP. */
typedef struct rend_service_t {
@@ -66,6 +76,8 @@
* up-to-date. */
time_t next_upload_time; /**< Scheduled next hidden service descriptor
* upload time. */
+ request_history_t request_history; /**< History of service requests */
+
} rend_service_t;
/** A list of rend_service_t's for services run on this OP.
@@ -858,6 +870,9 @@
"Established circuit %d as introduction point for service %s",
circuit->_base.n_circ_id, serviceid);
+ /* Add this request to the service's request history */
+ add_service_request(&service->request_history);
+
/* If the introduction point will not be used in an unversioned
* descriptor, use the intro key instead of the service key in
* ESTABLISH_INTRO. */
@@ -1462,3 +1477,103 @@
return -1;
}
+/** Add a new service request to the request history
+ */
+void
+add_service_request(request_history_t *request_history)
+{
+ /* Create a new list item for this request */
+ request_history_item_t new_request;
+ new_request.request_time = time(0);
+
+ if (!request_history->first_item && !request_history->last_item) {
+ /* The list is not empty, so add the item to the beginning of the list */
+ new_request.prev = NULL;
+ new_request.next = request_history->first_item;
+ request_history->first_item->prev = &new_request;
+ request_history->first_item = &new_request;
+ } else {
+ /* The list is empty, so this is the first request */
+ request_history->first_item = &new_request;
+ request_history->last_item = &new_request;
+ new_request.next = NULL;
+ new_request.prev = NULL;
+ }
+}
+
+/** Count the number of service requests not older than
+ * SERVICE_REQUEST_HISTORY_LENGTH seconds and delete all the ones that
+ * are older.
+ */
+int
+count_service_requests(request_history_t *request_history)
+{
+ request_history_item_t *temp;
+ request_history_item_t *to_be_deleted;
+ int number_of_requests;
+
+ long time_limit;
+
+ temp = request_history->first_item;
+ number_of_requests = 0;
+
+ /* time_limit is set to SERVICE_REQUEST_HISTORY_LENGTH seconds in the past */
+ time_limit = time(0)-(SERVICE_REQUEST_HISTORY_LENGTH*1000);
+
+ while(temp && temp->request_time > time_limit) {
+ number_of_requests++;
+ temp = temp->next;
+ }
+
+ /* temp is now pointing to the most recent request, that is older
+ * than SERVICE_REQUEST_HISTORY_LENGTH seconds.
+ * We can delete all items from here */
+ request_history->last_item = temp;
+
+ while(temp) {
+ to_be_deleted = temp;
+ temp = temp->next;
+
+ tor_free(to_be_deleted);
+ }
+
+ request_history->last_item->next = NULL;
+
+
+ request_history->last_update = time(0);
+ return number_of_requests;
+}
+
+/** Return the number of internal circuits based upon the service's request
+ * history.
+ */
+int
+get_number_of_internal_circuits_needed(request_history_t *request_history)
+{
+ int requests_per_minute;
+ int internal_circuits_needed;
+
+ if (time(0) > (request_history->last_update +
+ REQUEST_HISTORY_UPDATE_INTERVAL)) {
+ /** The last update is more than REQUEST_HISTORY_UPDATE_INTERVAL seconds
+ * ago, so we have to recalculate it */
+
+ /** With 3 internal circuits we should be able to handle 15 requests per
+ * minute easily. */
+ requests_per_minute = count_service_requests(request_history)/
+ SERVICE_REQUEST_HISTORY_LENGTH;
+
+ /** For every 10 additional requests per minute we add another internal
+ * circuit. */
+ internal_circuits_needed = 3 + (requests_per_minute-15) *
+ (requests_per_minute * 10);
+
+ if (internal_circuits_needed < MIN_INTERNAL_CIRCUITS) {
+ return MIN_INTERNAL_CIRCUITS;
+ } else if (internal_circuits_needed > MAX_INTERNAL_CIRCUITS) {
+ return MAX_INTERNAL_CIRCUITS;
+ }
+ request_history->internal_circuits_needed = internal_circuits_needed;
+ }
+ return request_history->internal_circuits_needed;
+}