[or-cvs] Change retry_listeners: when force is false, close and re-o...

Nick Mathewson nickm at seul.org
Mon Jul 11 17:20:25 UTC 2005


Update of /home/or/cvsroot/tor/src/or
In directory moria:/tmp/cvs-serv3432/src/or

Modified Files:
	connection.c 
Log Message:
Change retry_listeners: when force is false, close and re-open a minimal set of listeners (i.e., those that do not match the configuration).  This fixes a possible bug on some windowses.  Maybe.

Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/connection.c,v
retrieving revision 1.380
retrieving revision 1.381
diff -u -d -r1.380 -r1.381
--- connection.c	17 Jun 2005 18:49:55 -0000	1.380
+++ connection.c	11 Jul 2005 17:20:22 -0000	1.381
@@ -508,6 +508,8 @@
 
   conn = connection_new(type);
   conn->s = s;
+  conn->address = tor_strdup(bindaddress);
+  conn->port = usePort;
 
   if (connection_add(conn) < 0) { /* no space, forget it */
     log_fn(LOG_WARN,"connection_add failed. Giving up.");
@@ -759,29 +761,6 @@
   return 1;
 }
 
-/** If there exist any listeners of type <b>type</b> in the connection
- * array, mark them for close.
- */
-static void
-listener_close_if_present(int type)
-{
-  connection_t *conn;
-  connection_t **carray;
-  int i,n;
-  tor_assert(type == CONN_TYPE_OR_LISTENER ||
-             type == CONN_TYPE_AP_LISTENER ||
-             type == CONN_TYPE_DIR_LISTENER ||
-             type == CONN_TYPE_CONTROL_LISTENER);
-  get_connection_array(&carray,&n);
-  for (i=0;i<n;i++) {
-    conn = carray[i];
-    if (conn->type == type && !conn->marked_for_close) {
-      connection_close_immediate(conn);
-      connection_mark_for_close(conn);
-    }
-  }
-}
-
 /**
  * Launch any configured listener connections of type <b>type</b>.  (A
  * listener is configured if <b>port_option</b> is non-zero.  If any
@@ -791,61 +770,90 @@
  *
  * If <b>force</b> is true, close and re-open all listener connections.
  * Otherwise, only relaunch the listeners of this type if the number of
- * existing connections is not as configured (e.g., because one died).
+ * existing connections is not as configured (e.g., because one died),
+ * or if the existing connections do not match those configured.
  */
 static int
 retry_listeners(int type, struct config_line_t *cfg,
                 int port_option, const char *default_addr, int force)
 {
-  if (!force) {
-    int want, have, n_conn, i;
-    struct config_line_t *c;
-    connection_t *conn;
-    connection_t **carray;
-    /* How many should there be? */
-    if (cfg && port_option) {
-      want = 0;
-      for (c = cfg; c; c = c->next)
-        ++want;
-    } else if (port_option) {
-      want = 1;
-    } else {
-      want = 0;
-    }
+  struct smartlist_t *launch = smartlist_create();
+  int free_launch_elts = 1;
+  struct config_line_t *c;
+  int n_conn, i;
+  connection_t *conn;
+  connection_t **carray;
+  struct config_line_t *line;
 
-    /* How many are there actually? */
-    have = 0;
-    get_connection_array(&carray,&n_conn);
-    for (i=0;i<n_conn;i++) {
-      conn = carray[i];
-      if (conn->type == type && !conn->marked_for_close)
-        ++have;
+  if (cfg && port_option) {
+    for (c = cfg; c; c = c->next) {
+      smartlist_add(launch, c);
     }
-
-    /* If we have the right number of listeners, do nothing. */
-    if (have == want)
-      return 0;
-
-    /* Otherwise, warn the user and relaunch. */
-    log_fn(LOG_NOTICE,"We have %d %s(s) open, but we want %d; relaunching.",
-           have, conn_type_to_string(type), want);
+    free_launch_elts = 0;
+  } else if (port_option) {
+    line = tor_malloc_zero(sizeof(struct config_line_t));
+    line->key = tor_strdup("");
+    line->value = tor_strdup(default_addr);
+    smartlist_add(launch, line);
   }
 
-  listener_close_if_present(type);
-  if (port_option) {
-    if (!cfg) {
-           if (connection_create_listener(default_addr, (uint16_t) port_option,
-                                     type)<0)
-        return -1;
+  get_connection_array(&carray,&n_conn);
+  for (i=0; i < n_conn; ++i) {
+    conn = carray[i];
+    if (conn->type != type || conn->marked_for_close)
+      continue;
+    if (force) {
+      /* It's a listener, and we're relaunching all listeners of this
+       * type. Close this one. */
+      log_fn(LOG_NOTICE, "Closing listener on %s:%d", conn->address, conn->port);
+      connection_close_immediate(conn);
+      connection_mark_for_close(conn);
+      continue;
+    }
+    /* Okay, so this is a listener.  Is it configured? */
+    line = NULL;
+    SMARTLIST_FOREACH(launch, struct config_line_t *, wanted,
+      {
+        char *addr;
+        uint16_t port;
+        if (! parse_addr_port(wanted->value, &addr, NULL, &port)) {
+          if (! port)
+            port = port_option;
+          if (port == conn->port && !strcasecmp(addr, conn->address)) {
+            line = wanted;
+            break;
+          }
+        }
+      });
+    if (! line) {
+      /* This one isn't configured. Close it. */
+      log_fn(LOG_NOTICE, "Closing listener on %s:%d", conn->address, conn->port);
+      connection_close_immediate(conn);
+      connection_mark_for_close(conn);
     } else {
-      for ( ; cfg; cfg = cfg->next) {
-        if (connection_create_listener(cfg->value, (uint16_t) port_option,
-                                       type)<0)
-          return -1;
-      }
+      /* It's configured; we don't need to launch it. */
+      log_fn(LOG_INFO, "Already have listener on %s:%d",conn->address,conn->port);
+      smartlist_remove(launch, line);
     }
   }
-  return 0;
+
+  /* Now open all the listeners that are configured but not opened. */
+  i = 0;
+  SMARTLIST_FOREACH(launch, struct config_line_t *, cfg,
+    {
+      log_fn(LOG_NOTICE, "Opening listener on %s:%d", cfg->value, port_option);
+      if (connection_create_listener(cfg->value, (uint16_t) port_option,
+                                     type)<0)
+        i = -1;
+  });
+
+  if (free_launch_elts) {
+    SMARTLIST_FOREACH(launch, struct config_line_t *, cfg,
+                      config_free_lines(cfg));
+  }
+  smartlist_free(launch);
+
+  return i;
 }
 
 /** (Re)launch listeners for each port you should have open.  If



More information about the tor-commits mailing list