[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] Split dns_cancel_pending_resolve into dns_cancel_pending_re...
- To: or-cvs@freehaven.net
- Subject: [or-cvs] Split dns_cancel_pending_resolve into dns_cancel_pending_re...
- From: nickm@seul.org (Nick Mathewson)
- Date: Sat, 28 Feb 2004 17:23:46 -0500 (EST)
- Delivered-to: archiver@seul.org
- Delivered-to: or-cvs-outgoing@seul.org
- Delivered-to: or-cvs@seul.org
- Delivery-date: Sat, 28 Feb 2004 17:23:57 -0500
- Reply-to: or-dev@freehaven.net
- Sender: owner-or-cvs@freehaven.net
Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/tmp/cvs-serv32174/src/or
Modified Files:
connection.c dns.c or.h
Log Message:
Split dns_cancel_pending_resolve into dns_cancel_pending_resolve (kill a
resolve in response to a DNS worker dying) and connection_dns_remove (remove
a pending connection from the resolve structure.)
Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection.c,v
retrieving revision 1.164
retrieving revision 1.165
diff -u -d -r1.164 -r1.165
--- connection.c 28 Feb 2004 19:14:11 -0000 1.164
+++ connection.c 28 Feb 2004 22:23:44 -0000 1.165
@@ -182,14 +182,14 @@
case CONN_TYPE_EXIT:
case CONN_TYPE_AP:
if (conn->state == EXIT_CONN_STATE_RESOLVING)
- dns_cancel_pending_resolve(conn->address, conn);
+ connection_dns_remove(conn);
if (!conn->has_sent_end && reason &&
connection_edge_end(conn, reason, conn->cpath_layer) < 0)
return -1;
break;
case CONN_TYPE_DNSWORKER:
if (conn->state == DNSWORKER_STATE_BUSY) {
- dns_cancel_pending_resolve(conn->address, NULL);
+ dns_cancel_pending_resolve(conn->address);
}
break;
default:
Index: dns.c
===================================================================
RCS file: /home/or/cvsroot/src/or/dns.c,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -d -r1.58 -r1.59
--- dns.c 28 Feb 2004 22:13:58 -0000 1.58
+++ dns.c 28 Feb 2004 22:23:44 -0000 1.59
@@ -171,7 +171,7 @@
if(!dnsconn) {
log_fn(LOG_WARN,"no idle dns workers. Failing.");
- dns_cancel_pending_resolve(exitconn->address, NULL);
+ dns_cancel_pending_resolve(exitconn->address);
return -1;
}
@@ -192,12 +192,53 @@
}
+void connection_dns_remove(connection_t *conn)
+{
+ struct pending_connection_t *pend, *victim;
+ struct cached_resolve search;
+ struct cached_resolve *resolve;
+
+ strncpy(search.address, conn->address, MAX_ADDRESSLEN);
+ search.address[MAX_ADDRESSLEN-1] = 0;
+
+ resolve = SPLAY_FIND(cache_tree, &cache_root, &search);
+ if(!resolve) {
+ log_fn(LOG_WARN,"Address '%s' is not pending. Dropping.", conn->address);
+ return;
+ }
+
+ assert(resolve->pending_connections);
+ assert_connection_ok(conn,0);
+
+ pend = resolve->pending_connections;
+
+ if(pend->conn == conn) {
+ resolve->pending_connections = pend->next;
+ free(pend);
+ log_fn(LOG_DEBUG, "Connection (fd %d) no longer waiting for resolve of '%s'",
+ conn->s, conn->address);
+ return;
+ } else {
+ for( ; pend->next; pend = pend->next) {
+ if(pend->next->conn == conn) {
+ victim = pend->next;
+ pend->next = victim->next;
+ free(victim);
+ log_fn(LOG_DEBUG, "Connection (fd %d) no longer waiting for resolve of '%s'",
+ conn->s, conn->address);
+ return; /* more are pending */
+ }
+ }
+ assert(0); /* not reachable unless onlyconn not in pending list */
+ }
+}
+
/* If onlyconn is NULL, cancel all pending connections. If onlyconn is
* defined, then remove onlyconn from the pending list. Does not cancel the
* resolve itself, or remove the 'struct cached_resolve' from the cache.
*/
-void dns_cancel_pending_resolve(char *address, connection_t *onlyconn) {
- struct pending_connection_t *pend, *victim;
+void dns_cancel_pending_resolve(char *address) {
+ struct pending_connection_t *pend;
struct cached_resolve search;
struct cached_resolve *resolve, *tmp;
@@ -212,40 +253,38 @@
assert(resolve->pending_connections);
- if(onlyconn) {
- assert_connection_ok(onlyconn,0);
+ /* mark all pending connections to fail */
+ log_fn(LOG_DEBUG, "Failing all connections waiting on DNS resolve of '%s'",
+ address);
+ while(resolve->pending_connections) {
pend = resolve->pending_connections;
- if(pend->conn == onlyconn) {
- resolve->pending_connections = pend->next;
- free(pend);
- if(resolve->pending_connections) {/* more pending, don't cancel it */
- log_fn(LOG_DEBUG, "Connection (fd %d) no longer waiting for resolve of '%s'",
- onlyconn->s, address);
- }
- } else {
- for( ; pend->next; pend = pend->next) {
- if(pend->next->conn == onlyconn) {
- victim = pend->next;
- pend->next = victim->next;
- free(victim);
- log_fn(LOG_DEBUG, "Connection (fd %d) no longer waiting for resolve of '%s'",
- onlyconn->s, address);
- return; /* more are pending */
- }
- }
- assert(0); /* not reachable unless onlyconn not in pending list */
- }
+ /* This calls dns_cancel_pending_resolve, which removes pend
+ * from the list, so we don't have to do it. Beware of
+ * modify-while-iterating bugs hereabouts! */
+ connection_mark_for_close(pend->conn, END_STREAM_REASON_MISC);
+ assert(resolve->pending_connections != pend);
+ }
+
+ /* remove resolve from the linked list */
+ if(resolve == oldest_cached_resolve) {
+ oldest_cached_resolve = resolve->next;
+ if(oldest_cached_resolve == NULL)
+ newest_cached_resolve = NULL;
} else {
- /* mark all pending connections to fail */
- log_fn(LOG_DEBUG, "Failing all connections waiting on DNS resolve of '%s'",
- address);
- while(resolve->pending_connections) {
- pend = resolve->pending_connections;
- connection_mark_for_close(pend->conn, END_STREAM_REASON_MISC);
- resolve->pending_connections = pend->next;
- free(pend);
- }
+ /* FFFF make it a doubly linked list if this becomes too slow */
+ for(tmp=oldest_cached_resolve; tmp && tmp->next != resolve; tmp=tmp->next) ;
+ assert(tmp); /* it's got to be in the list, or we screwed up somewhere else */
+ tmp->next = resolve->next; /* unlink it */
+
+ if(newest_cached_resolve == resolve)
+ newest_cached_resolve = tmp;
}
+
+ /* remove resolve from the tree */
+ SPLAY_REMOVE(cache_tree, &cache_root, resolve);
+
+ free(resolve);
+
}
static void dns_found_answer(char *address, uint32_t addr) {
@@ -315,7 +354,7 @@
if(conn->inbuf_reached_eof) {
log_fn(LOG_WARN,"Read eof. Worker dying.");
if(conn->state == DNSWORKER_STATE_BUSY) {
- dns_cancel_pending_resolve(conn->address, NULL);
+ dns_cancel_pending_resolve(conn->address);
num_dnsworkers_busy--;
}
num_dnsworkers--;
Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.235
retrieving revision 1.236
diff -u -d -r1.235 -r1.236
--- or.h 28 Feb 2004 19:14:11 -0000 1.235
+++ or.h 28 Feb 2004 22:23:44 -0000 1.236
@@ -754,7 +754,8 @@
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);
+void connection_dns_remove(connection_t *conn);
+void dns_cancel_pending_resolve(char *question);
int dns_resolve(connection_t *exitconn);
/********************************* main.c ***************************/