[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] if stream ends before resolve finishes, inform resolver
- To: or-cvs@freehaven.net
- Subject: [or-cvs] if stream ends before resolve finishes, inform resolver
- From: arma@seul.org (Roger Dingledine)
- Date: Thu, 26 Jun 2003 20:57:06 -0400 (EDT)
- Delivered-to: archiver@seul.org
- Delivered-to: or-cvs-outgoing@seul.org
- Delivered-to: or-cvs@seul.org
- Delivery-date: Thu, 26 Jun 2003 20:57:16 -0400
- Reply-to: or-dev@freehaven.net
- Sender: owner-or-cvs@freehaven.net
Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/home/arma/work/onion/cvs/src/or
Modified Files:
connection_edge.c dns.c or.h
Log Message:
if stream ends before resolve finishes, inform resolver
Index: connection_edge.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_edge.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- connection_edge.c 17 Jun 2003 22:18:26 -0000 1.12
+++ connection_edge.c 27 Jun 2003 00:57:04 -0000 1.13
@@ -118,6 +118,10 @@
if(conn->type == CONN_TYPE_EXIT && relay_command == RELAY_COMMAND_END) {
log_fn(LOG_INFO,"Exit got end before we're connected. Marking for close.");
conn->marked_for_close = 1;
+ if(conn->state == EXIT_CONN_STATE_RESOLVING) {
+ log_fn(LOG_INFO,"...and informing resolver we don't want the answer anymore.");
+ dns_cancel_pending_resolve(conn->address, conn);
+ }
} else {
log_fn(LOG_DEBUG,"Got an unexpected relay cell, not in 'open' state. Dropping.");
}
Index: dns.c
===================================================================
RCS file: /home/or/cvsroot/src/or/dns.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- dns.c 25 Jun 2003 07:19:30 -0000 1.15
+++ dns.c 27 Jun 2003 00:57:04 -0000 1.16
@@ -20,7 +20,6 @@
int num_workers_busy=0;
static int dns_assign_to_worker(connection_t *exitconn);
-static void dns_cancel_pending_resolve(char *question);
static void dns_found_answer(char *question, uint32_t answer);
static void dnsworker_main(int fd);
static int dns_spawn_worker(void);
@@ -154,7 +153,7 @@
if(!dnsconn) {
log(LOG_INFO,"dns_assign_to_worker(): no idle dns workers. Failing.");
- dns_cancel_pending_resolve(exitconn->address);
+ dns_cancel_pending_resolve(exitconn->address, NULL);
return -1;
}
@@ -168,7 +167,7 @@
connection_write_to_buf(dnsconn->address, len, dnsconn) < 0) {
log(LOG_NOTICE,"dns_assign_to_worker(): Write failed. Closing worker and failing resolve.");
dnsconn->marked_for_close = 1;
- dns_cancel_pending_resolve(exitconn->address);
+ dns_cancel_pending_resolve(exitconn->address, NULL);
return -1;
}
@@ -176,8 +175,12 @@
return 0;
}
-static void dns_cancel_pending_resolve(char *question) {
- struct pending_connection_t *pend;
+/* if onlyconn is NULL, cancel the whole thing. if onlyconn is defined,
+ * then remove onlyconn from the pending list, and if the pending list
+ * is now empty, cancel the whole thing.
+ */
+void dns_cancel_pending_resolve(char *question, connection_t *onlyconn) {
+ struct pending_connection_t *pend, *victim;
struct cached_resolve search;
struct cached_resolve *resolve, *tmp;
@@ -185,18 +188,39 @@
resolve = SPLAY_FIND(cache_tree, &cache_root, &search);
if(!resolve) {
- log_fn(LOG_ERR,"Answer to unasked question '%s'? Dropping.", question);
+ log_fn(LOG_INFO,"Answer to unasked question '%s'? Dropping.", question);
return;
}
assert(resolve->state == CACHE_STATE_PENDING);
+ assert(resolve->pending_connections);
- /* mark all pending connections to fail */
- while(resolve->pending_connections) {
+ if(onlyconn) {
pend = resolve->pending_connections;
- pend->conn->marked_for_close = 1;
- resolve->pending_connections = pend->next;
- free(pend);
+ if(pend->conn == onlyconn) {
+ resolve->pending_connections = pend->next;
+ free(pend);
+ if(resolve->pending_connections) /* more pending, don't cancel it */
+ return;
+ } else {
+ for( ; pend->next; pend = pend->next) {
+ if(pend->next->conn == onlyconn) {
+ victim = pend->next;
+ pend->next = victim->next;
+ free(victim);
+ return; /* more are pending */
+ }
+ }
+ assert(0); /* not reachable unless onlyconn not in pending list */
+ }
+ } else {
+ /* mark all pending connections to fail */
+ while(resolve->pending_connections) {
+ pend = resolve->pending_connections;
+ pend->conn->marked_for_close = 1;
+ resolve->pending_connections = pend->next;
+ free(pend);
+ }
}
/* remove resolve from the linked list */
@@ -229,19 +253,11 @@
resolve = SPLAY_FIND(cache_tree, &cache_root, &search);
if(!resolve) {
- log_fn(LOG_ERR,"Answer to unasked question '%s'? Dropping.", question);
+ log_fn(LOG_INFO,"Answer to unasked question '%s'? Dropping.", question);
return;
}
assert(resolve->state == CACHE_STATE_PENDING);
- /* XXX this is a bug which hasn't been found yet. Probably something
- * about slaves answering questions when they're not supposed to, and
- * reusing the old question.
- */
- if(resolve->state != CACHE_STATE_PENDING) {
- log(LOG_ERR,"dns_found_answer(): BUG: resolve '%s' in state %d (not pending). Dropping.",question, resolve->state);
- return;
- }
resolve->answer = ntohl(answer);
if(resolve->answer)
@@ -276,7 +292,7 @@
if(conn->inbuf_reached_eof) {
log(LOG_ERR,"connection_dnsworker_process_inbuf(): Read eof. Worker dying.");
if(conn->state == DNSWORKER_STATE_BUSY)
- dns_cancel_pending_resolve(conn->address);
+ dns_cancel_pending_resolve(conn->address, NULL);
return -1;
}
@@ -398,7 +414,7 @@
assert(dnsconn);
/* tell the exit connection that it's failed */
- dns_cancel_pending_resolve(dnsconn->address);
+ dns_cancel_pending_resolve(dnsconn->address, NULL);
dnsconn->marked_for_close = 1;
num_workers_busy--;
Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.95
retrieving revision 1.96
diff -u -d -r1.95 -r1.96
--- or.h 25 Jun 2003 07:19:30 -0000 1.95
+++ or.h 27 Jun 2003 00:57:04 -0000 1.96
@@ -395,6 +395,7 @@
int KeepalivePeriod;
int MaxOnionsPending;
int NewCircuitPeriod;
+ int TotalBandwidth;
int Role;
int loglevel;
} or_options_t;
@@ -638,6 +639,7 @@
void dns_init(void);
int connection_dns_finished_flushing(connection_t *conn);
int connection_dns_process_inbuf(connection_t *conn);
+void dns_cancel_pending_resolve(char *question, connection_t *onlyconn);
int dns_resolve(connection_t *exitconn);
/********************************* main.c ***************************/