Browse Source

dirserver should include itself in the directory

if connecting to a dirserver fails, remove it from the router array


svn:r113
Roger Dingledine 22 years ago
parent
commit
f033442be2
4 changed files with 68 additions and 19 deletions
  1. 4 2
      src/or/directory.c
  2. 38 17
      src/or/main.c
  3. 1 0
      src/or/or.h
  4. 25 0
      src/or/routers.c

+ 4 - 2
src/or/directory.c

@@ -1,4 +1,4 @@
-/* Copyright 2001,2002 Roger Dingledine, Matej Pfaêfar. */
+/* Copyright 2001,2002 Roger Dingledine, Matej Pfajfar. */
 /* See LICENSE for licensing information */
 /* $Id$ */
 
@@ -56,6 +56,7 @@ void directory_initiate_fetch(routerinfo_t *router) {
   if(connect(s,(struct sockaddr *)&router_addr,sizeof(router_addr)) < 0){
     if(errno != EINPROGRESS){
       /* yuck. kill it. */
+      router_forget_router(conn->addr, conn->port); /* don't try him again */
       connection_free(conn);
       return;
     } else {
@@ -210,6 +211,7 @@ int connection_dir_finished_flushing(connection_t *conn) {
         if(errno != EINPROGRESS){
           /* yuck. kill it. */
           log(LOG_DEBUG,"connection_dir_finished_flushing(): in-progress connect failed. Removing.");
+          router_forget_router(conn->addr, conn->port); /* don't try him again */
           return -1;
         } else {
           return 0; /* no change, see if next time is better */
@@ -217,7 +219,7 @@ int connection_dir_finished_flushing(connection_t *conn) {
       }
       /* the connect has finished. */
 
-      log(LOG_DEBUG,"connection_dir_finished_flushing(): DIR connection to router %s:%u established.",
+      log(LOG_DEBUG,"connection_dir_finished_flushing(): Dir connection to router %s:%u established.",
           conn->address,conn->port);
 
       return directory_send_command(conn);

+ 38 - 17
src/or/main.c

@@ -21,6 +21,8 @@ static int please_dumpstats=0; /* whether we should dump stats during the loop *
 /* private key */
 static crypto_pk_env_t *prkey;
 
+routerinfo_t *my_routerinfo=NULL;
+
 /********* END VARIABLES ************/
 
 /****************************************************************************
@@ -214,6 +216,10 @@ void check_conn_read(int i) {
       retval = connection_dir_handle_listener_read(conn);
     } else {
       retval = connection_read_to_buf(conn);
+      if (retval < 0 && conn->type == CONN_TYPE_DIR) {
+         /* as a special case: forget about this router */
+         router_forget_router(conn->addr,conn->port);
+      }
       if (retval >= 0) { /* all still well */
         retval = connection_process_inbuf(conn);
 //      log(LOG_DEBUG,"check_conn_read(): connection_process_inbuf returned %d.",retval);
@@ -501,14 +507,42 @@ void dumpstats (void) { /* dump stats to stdout */
   please_dumpstats = 0;
 }
 
-void dump_directory_to_string(char *s, int maxlen) {
-  int i;
-  connection_t *conn;
+int dump_router_to_string(char *s, int maxlen, routerinfo_t *router) {
   char *pkey;
   int pkeylen;
   int written;
+
+  if(crypto_pk_write_public_key_to_string(router->pkey,&pkey,&pkeylen)<0) {
+    log(LOG_ERR,"dump_directory_to_string(): write pkey to string failed!");
+    return 0;
+  }
+  written = snprintf(s, maxlen, "%s %d %d %d %d %d\n%s\n",
+    router->address,
+    router->or_port,
+    router->op_port,
+    router->ap_port,
+    router->dir_port,
+    router->bandwidth,
+    pkey);
+
+  free(pkey);
+
+  return written;
+}
+
+void dump_directory_to_string(char *s, int maxlen) {
+  int i;
+  connection_t *conn;
   routerinfo_t *router;
+  int written;
 
+  /* first write my own info */
+  /* XXX should check for errors here too */
+  written = dump_router_to_string(s, maxlen, my_routerinfo);
+  maxlen -= written;
+  s += written;
+
+  /* now write info for other routers */
   for(i=0;i<nfds;i++) {
     conn = connection_array[i];
 
@@ -519,20 +553,8 @@ void dump_directory_to_string(char *s, int maxlen) {
       log(LOG_ERR,"dump_directory_to_string(): couldn't find router %d:%d!",conn->addr,conn->port);
       return;
     }
-    if(crypto_pk_write_public_key_to_string(router->pkey,&pkey,&pkeylen)<0) {
-      log(LOG_ERR,"dump_directory_to_string(): write pkey to string failed!");
-      return;
-    }
-    written = snprintf(s, maxlen, "%s %d %d %d %d %d\n%s\n",
-      router->address,
-      router->or_port,
-      router->op_port,
-      router->ap_port,
-      router->dir_port,
-      router->bandwidth,
-      pkey);
 
-    free(pkey);
+    written = dump_router_to_string(s, maxlen, router);
 
     if(written < 0 || written > maxlen) { 
       /* apparently different glibcs do different things on error.. so check both */
@@ -543,7 +565,6 @@ void dump_directory_to_string(char *s, int maxlen) {
   
     maxlen -= written;
     s += written;
-
   }
 
 }

+ 1 - 0
src/or/or.h

@@ -653,6 +653,7 @@ routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port);
 unsigned int *router_new_route(int *routelen);
 unsigned char *router_create_onion(unsigned int *route, int routelen, int *len, crypt_path_t **cpath);
 routerinfo_t *router_get_first_in_route(unsigned int *route, int routelen);
+void router_forget_router(uint32_t addr, uint16_t port);
 int router_get_list_from_file(char *routerfile, uint16_t or_listenport);
 int router_get_list_from_string(char *s, uint16_t or_listenport);
 

+ 25 - 0
src/or/routers.c

@@ -21,6 +21,7 @@ static int rarray_len = 0;
 
 extern int global_role; /* from main.c */
 extern or_options_t options; /* command-line and config-file options */
+extern routerinfo_t *my_routerinfo; /* from main.c */
 
 /****************************************************************************/
 
@@ -175,6 +176,27 @@ void rarray_free(routerinfo_t **list) {
   free(list);
 }
 
+void router_forget_router(uint32_t addr, uint16_t port) {
+  int i;
+  routerinfo_t *router;
+
+  router = router_get_by_addr_port(addr,port);
+  if(!router) /* we don't seem to know about him in the first place */
+    return;
+
+  /* now walk down router_array until we get to router */
+  for(i=0;i<rarray_len;i++)
+    if(router_array[i] == router)
+      break;
+
+  assert(i != rarray_len); /* if so then router_get_by_addr_port should have returned null */
+
+  free(router);
+//  log(LOG_DEBUG,"router_forget_router(): Forgot about router %d:%d",addr,port);
+  for(; i<rarray_len-1;i++)
+    router_array[i] = router_array[i+1];
+}
+
 /* create a NULL-terminated array of pointers pointing to elements of a router list */
 /* this is done in two passes through the list - inefficient but irrelevant as this is
  * only done once when op/or start up */
@@ -289,6 +311,9 @@ int router_get_list_from_string(char *s, uint16_t or_listenport) {
     if(!router_is_me(router->addr, router->or_port, or_listenport)) {
       router->next = routerlist;
       routerlist = router;
+    } else {
+      if(!my_routerinfo) /* save it, so we can use it for directories */
+        my_routerinfo = router;
     }
     s = eat_whitespace(s);
   }