|
@@ -298,92 +298,93 @@ void check_conn_marked(int i) {
|
|
|
|
|
|
int prepare_for_poll(int *timeout) {
|
|
int prepare_for_poll(int *timeout) {
|
|
int i;
|
|
int i;
|
|
-// int need_to_wake_soon = 0;
|
|
|
|
- connection_t *conn = NULL;
|
|
|
|
|
|
+// connection_t *conn = NULL;
|
|
connection_t *tmpconn;
|
|
connection_t *tmpconn;
|
|
- struct timeval now, soonest;
|
|
|
|
|
|
+ struct timeval now; //soonest;
|
|
static long current_second = 0; /* from previous calls to gettimeofday */
|
|
static long current_second = 0; /* from previous calls to gettimeofday */
|
|
static long time_to_rebuild_directory = 0;
|
|
static long time_to_rebuild_directory = 0;
|
|
static long time_to_fetch_directory = 0;
|
|
static long time_to_fetch_directory = 0;
|
|
- int ms_until_conn;
|
|
|
|
|
|
+// int ms_until_conn;
|
|
cell_t cell;
|
|
cell_t cell;
|
|
|
|
|
|
if(gettimeofday(&now,NULL) < 0)
|
|
if(gettimeofday(&now,NULL) < 0)
|
|
return -1;
|
|
return -1;
|
|
|
|
|
|
- if(options.Role & ROLE_DIR_SERVER) {
|
|
|
|
- if(time_to_rebuild_directory < now.tv_sec) {
|
|
|
|
- /* it's time to rebuild our directory */
|
|
|
|
- if(time_to_rebuild_directory == 0) {
|
|
|
|
- /* we just started up. if we build a directory now it will be meaningless. */
|
|
|
|
- log(LOG_DEBUG,"prepare_for_poll(): Delaying initial dir build for 10 seconds.");
|
|
|
|
- time_to_rebuild_directory = now.tv_sec + 10; /* try in 10 seconds */
|
|
|
|
- } else {
|
|
|
|
- directory_rebuild();
|
|
|
|
- time_to_rebuild_directory = now.tv_sec + options.DirRebuildPeriod;
|
|
|
|
|
|
+ if(now.tv_sec > current_second) { /* the second has rolled over. check more stuff. */
|
|
|
|
+
|
|
|
|
+ if(options.Role & ROLE_DIR_SERVER) {
|
|
|
|
+ if(time_to_rebuild_directory < now.tv_sec) {
|
|
|
|
+ /* it's time to rebuild our directory */
|
|
|
|
+ if(time_to_rebuild_directory == 0) {
|
|
|
|
+ /* we just started up. if we build a directory now it will be meaningless. */
|
|
|
|
+ log(LOG_DEBUG,"prepare_for_poll(): Delaying initial dir build for 10 seconds.");
|
|
|
|
+ time_to_rebuild_directory = now.tv_sec + 10; /* try in 10 seconds */
|
|
|
|
+ } else {
|
|
|
|
+ directory_rebuild();
|
|
|
|
+ time_to_rebuild_directory = now.tv_sec + options.DirRebuildPeriod;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ if(time_to_fetch_directory < now.tv_sec) {
|
|
|
|
+ /* it's time to fetch a new directory */
|
|
|
|
+ /* NOTE directory servers do not currently fetch directories.
|
|
|
|
+ * Hope this doesn't bite us later.
|
|
|
|
+ */
|
|
|
|
+ directory_initiate_fetch(router_pick_directory_server());
|
|
|
|
+ time_to_fetch_directory = now.tv_sec + options.DirFetchPeriod;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- *timeout = 1000*(time_to_rebuild_directory - now.tv_sec) + (1000 - (now.tv_usec / 1000));
|
|
|
|
-// log(LOG_DEBUG,"prepare_for_poll(): DirBuild timeout is %d",*timeout);
|
|
|
|
- }
|
|
|
|
|
|
|
|
- if(!(options.Role & ROLE_DIR_SERVER)) {
|
|
|
|
- if(time_to_fetch_directory < now.tv_sec) {
|
|
|
|
- /* it's time to fetch a new directory */
|
|
|
|
- /* NOTE directory servers do not currently fetch directories.
|
|
|
|
- * Hope this doesn't bite us later.
|
|
|
|
- */
|
|
|
|
- directory_initiate_fetch(router_pick_directory_server());
|
|
|
|
- time_to_fetch_directory = now.tv_sec + options.DirFetchPeriod;
|
|
|
|
- }
|
|
|
|
- *timeout = 1000*(time_to_fetch_directory - now.tv_sec) + (1000 - (now.tv_usec / 1000));
|
|
|
|
- }
|
|
|
|
|
|
+ /* do housekeeping for each connection */
|
|
|
|
+ for(i=0;i<nfds;i++) {
|
|
|
|
+ tmpconn = connection_array[i];
|
|
|
|
+ connection_increment_receiver_bucket(tmpconn);
|
|
|
|
+ connection_array[i]->onions_handled_this_second = 0;
|
|
|
|
|
|
- /* check connections to see whether we should send a keepalive, expire, or wait */
|
|
|
|
- for(i=0;i<nfds;i++) {
|
|
|
|
- tmpconn = connection_array[i];
|
|
|
|
- if(!connection_speaks_cells(tmpconn))
|
|
|
|
- continue; /* this conn type doesn't send cells */
|
|
|
|
- if(now.tv_sec >= tmpconn->timestamp_lastwritten + options.KeepalivePeriod) {
|
|
|
|
- if((!(options.Role & ROLE_OR_CONNECT_ALL) && !circuit_get_by_conn(tmpconn)) ||
|
|
|
|
- (!connection_state_is_open(tmpconn))) {
|
|
|
|
- /* we're an onion proxy, with no circuits; or our handshake has expired. kill it. */
|
|
|
|
- log(LOG_DEBUG,"prepare_for_poll(): Expiring connection to %d (%s:%d).",
|
|
|
|
- i,tmpconn->address, tmpconn->port);
|
|
|
|
- tmpconn->marked_for_close = 1;
|
|
|
|
- } else {
|
|
|
|
- /* either a full router, or we've got a circuit. send a padding cell. */
|
|
|
|
-// log(LOG_DEBUG,"prepare_for_poll(): Sending keepalive to (%s:%d)",
|
|
|
|
-// tmpconn->address, tmpconn->port);
|
|
|
|
- memset(&cell,0,sizeof(cell_t));
|
|
|
|
- cell.command = CELL_PADDING;
|
|
|
|
- if(connection_write_cell_to_buf(&cell, tmpconn) < 0)
|
|
|
|
|
|
+ /* check connections to see whether we should send a keepalive, expire, or wait */
|
|
|
|
+ if(!connection_speaks_cells(tmpconn))
|
|
|
|
+ continue; /* this conn type doesn't send cells */
|
|
|
|
+ if(now.tv_sec >= tmpconn->timestamp_lastwritten + options.KeepalivePeriod) {
|
|
|
|
+ if((!(options.Role & ROLE_OR_CONNECT_ALL) && !circuit_get_by_conn(tmpconn)) ||
|
|
|
|
+ (!connection_state_is_open(tmpconn))) {
|
|
|
|
+ /* we're an onion proxy, with no circuits; or our handshake has expired. kill it. */
|
|
|
|
+ log(LOG_DEBUG,"prepare_for_poll(): Expiring connection to %d (%s:%d).",
|
|
|
|
+ i,tmpconn->address, tmpconn->port);
|
|
tmpconn->marked_for_close = 1;
|
|
tmpconn->marked_for_close = 1;
|
|
|
|
+ } else {
|
|
|
|
+ /* either a full router, or we've got a circuit. send a padding cell. */
|
|
|
|
+// log(LOG_DEBUG,"prepare_for_poll(): Sending keepalive to (%s:%d)",
|
|
|
|
+// tmpconn->address, tmpconn->port);
|
|
|
|
+// memset(&cell,0,sizeof(cell_t));
|
|
|
|
+ cell.command = CELL_PADDING;
|
|
|
|
+ if(connection_write_cell_to_buf(&cell, tmpconn) < 0)
|
|
|
|
+ tmpconn->marked_for_close = 1;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- if(!tmpconn->marked_for_close &&
|
|
|
|
- *timeout > 1000*(tmpconn->timestamp_lastwritten + options.KeepalivePeriod - now.tv_sec)) {
|
|
|
|
- *timeout = 1000*(tmpconn->timestamp_lastwritten + options.KeepalivePeriod - now.tv_sec);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- assert(*timeout >= 0);
|
|
|
|
- /* blow away any connections that need to die. can't do this later
|
|
|
|
- * because we might open up a circuit and not realize it we're about to cull it.
|
|
|
|
- */
|
|
|
|
- for(i=0;i<nfds;i++)
|
|
|
|
- check_conn_marked(i);
|
|
|
|
|
|
+ /* blow away any connections that need to die. can't do this later
|
|
|
|
+ * because we might open up a circuit and not realize it we're about to cull it.
|
|
|
|
+ */
|
|
|
|
+ for(i=0;i<nfds;i++)
|
|
|
|
+ check_conn_marked(i);
|
|
|
|
|
|
- if(now.tv_sec > current_second) { /* the second has already rolled over! */
|
|
|
|
- for(i=0;i<nfds;i++) {
|
|
|
|
- connection_increment_receiver_bucket(connection_array[i]);
|
|
|
|
- connection_array[i]->onions_handled_this_second = 0;
|
|
|
|
- }
|
|
|
|
current_second = now.tv_sec; /* remember which second it is, for next time */
|
|
current_second = now.tv_sec; /* remember which second it is, for next time */
|
|
}
|
|
}
|
|
|
|
|
|
- /* this timeout is definitely sooner than any of the above ones */
|
|
|
|
- *timeout = 1000 - (now.tv_usec / 1000); /* how many milliseconds til the next second? */
|
|
|
|
|
|
+ if(onion_pending_check()) {
|
|
|
|
+ /* there's an onion pending. check for new things to do, but don't wait any time */
|
|
|
|
+ *timeout = 0;
|
|
|
|
+ } else {
|
|
|
|
+ *timeout = 1000 - (now.tv_usec / 1000); /* how many milliseconds til the next second? */
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
|
|
|
|
+/* Link padding stuff left here for fun. Not used now. */
|
|
|
|
+#if 0
|
|
if(options.LinkPadding) {
|
|
if(options.LinkPadding) {
|
|
/* now check which conn wants to speak soonest */
|
|
/* now check which conn wants to speak soonest */
|
|
for(i=0;i<nfds;i++) {
|
|
for(i=0;i<nfds;i++) {
|
|
@@ -393,14 +394,9 @@ int prepare_for_poll(int *timeout) {
|
|
if(!connection_state_is_open(tmpconn))
|
|
if(!connection_state_is_open(tmpconn))
|
|
continue; /* only conns in state 'open' have a valid send_timeval */
|
|
continue; /* only conns in state 'open' have a valid send_timeval */
|
|
while(tv_cmp(&tmpconn->send_timeval,&now) <= 0) { /* send_timeval has already passed, let it send a cell */
|
|
while(tv_cmp(&tmpconn->send_timeval,&now) <= 0) { /* send_timeval has already passed, let it send a cell */
|
|
-// log(LOG_DEBUG,"prepare_for_poll(): doing backlogged connection_send_cell on socket %d (%d ms old)",tmpconn->s,
|
|
|
|
-// (now.tv_sec - tmpconn->send_timeval.tv_sec)*1000 +
|
|
|
|
-// (now.tv_usec - tmpconn->send_timeval.tv_usec)/1000
|
|
|
|
-// );
|
|
|
|
connection_send_cell(tmpconn);
|
|
connection_send_cell(tmpconn);
|
|
}
|
|
}
|
|
if(!conn || tv_cmp(&tmpconn->send_timeval, &soonest) < 0) { /* this is the best choice so far */
|
|
if(!conn || tv_cmp(&tmpconn->send_timeval, &soonest) < 0) { /* this is the best choice so far */
|
|
-// log(LOG_DEBUG,"prepare_for_poll(): chose socket %d as best connection so far",tmpconn->s);
|
|
|
|
conn = tmpconn;
|
|
conn = tmpconn;
|
|
soonest.tv_sec = conn->send_timeval.tv_sec;
|
|
soonest.tv_sec = conn->send_timeval.tv_sec;
|
|
soonest.tv_usec = conn->send_timeval.tv_usec;
|
|
soonest.tv_usec = conn->send_timeval.tv_usec;
|
|
@@ -417,14 +413,7 @@ int prepare_for_poll(int *timeout) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
- if(onion_pending_check()) {
|
|
|
|
- /* there's an onion pending. check for new things to do, but don't wait any time */
|
|
|
|
- *timeout = 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
|
|
+#endif
|
|
|
|
|
|
int do_main_loop(void) {
|
|
int do_main_loop(void) {
|
|
int i;
|
|
int i;
|
|
@@ -483,10 +472,6 @@ int do_main_loop(void) {
|
|
* conn that needs to send a cell)
|
|
* conn that needs to send a cell)
|
|
*/
|
|
*/
|
|
|
|
|
|
- /* if the timeout is less than 10, set it to 10 */
|
|
|
|
- if(timeout > 0 && timeout < 10)
|
|
|
|
- timeout = 10;
|
|
|
|
-
|
|
|
|
/* poll until we have an event, or it's time to do something */
|
|
/* poll until we have an event, or it's time to do something */
|
|
poll_result = poll(poll_array, nfds, timeout);
|
|
poll_result = poll(poll_array, nfds, timeout);
|
|
|
|
|