Parcourir la source

Merge commit 'origin/maint-0.2.1'

Nick Mathewson il y a 16 ans
Parent
commit
479d21254a
3 fichiers modifiés avec 63 ajouts et 10 suppressions
  1. 7 0
      ChangeLog
  2. 42 10
      src/common/compat.c
  3. 14 0
      src/or/config.c

+ 7 - 0
ChangeLog

@@ -23,6 +23,13 @@ Changes in version 0.2.1.15??? - ????-??-??
       Bugfix on 0.2.0.9-alpha.
     - Provide a more useful log message if bug 977 (related to buffer
       freelists) ever reappears, and do not crash right away.
+    - Protect the count of open sockets with a mutex, so we can't
+      corrupt it when two threads are closing or opening sockets at once.
+      Fix for bug 939.  Bugfix on 0.2.0.1-alpha.
+    - Don't allow a bridge to publish its router descriptor to a non-bridge
+      directory authority.  Fixes part of bug 932.
+    - When we change to or from being a bridge, reset our counts of
+      client usage by country.  Fixes bug 932.
 
 
 Changes in version 0.2.1.14-rc - 2009-04-12

+ 42 - 10
src/common/compat.c

@@ -676,6 +676,23 @@ static int max_socket = -1;
  * eventdns and libevent.) */
 static int n_sockets_open = 0;
 
+/** Mutex to protect open_sockets, max_socket, and n_sockets_open. */
+static tor_mutex_t *socket_accounting_mutex = NULL;
+
+static INLINE void
+socket_accounting_lock(void)
+{
+  if (PREDICT_UNLIKELY(!socket_accounting_mutex))
+    socket_accounting_mutex = tor_mutex_new();
+  tor_mutex_acquire(socket_accounting_mutex);
+}
+
+static INLINE void
+socket_accounting_unlock(void)
+{
+  tor_mutex_release(socket_accounting_mutex);
+}
+
 /** As close(), but guaranteed to work for sockets across platforms (including
  * Windows, where close()ing a socket doesn't work.  Returns 0 on success, -1
  * on failure. */
@@ -683,15 +700,7 @@ int
 tor_close_socket(int s)
 {
   int r = 0;
-#ifdef DEBUG_SOCKET_COUNTING
-  if (s > max_socket || ! bitarray_is_set(open_sockets, s)) {
-    log_warn(LD_BUG, "Closing a socket (%d) that wasn't returned by tor_open_"
-             "socket(), or that was already closed or something.", s);
-  } else {
-    tor_assert(open_sockets && s <= max_socket);
-    bitarray_clear(open_sockets, s);
-  }
-#endif
+
   /* On Windows, you have to call close() on fds returned by open(),
    * and closesocket() on fds returned by socket().  On Unix, everything
    * gets close()'d.  We abstract this difference by always using
@@ -703,6 +712,17 @@ tor_close_socket(int s)
 #else
   r = close(s);
 #endif
+
+  socket_accounting_lock();
+#ifdef DEBUG_SOCKET_COUNTING
+  if (s > max_socket || ! bitarray_is_set(open_sockets, s)) {
+    log_warn(LD_BUG, "Closing a socket (%d) that wasn't returned by tor_open_"
+             "socket(), or that was already closed or something.", s);
+  } else {
+    tor_assert(open_sockets && s <= max_socket);
+    bitarray_clear(open_sockets, s);
+  }
+#endif
   if (r == 0) {
     --n_sockets_open;
   } else {
@@ -717,9 +737,11 @@ tor_close_socket(int s)
 #endif
     r = -1;
   }
+
   if (n_sockets_open < 0)
     log_warn(LD_BUG, "Our socket count is below zero: %d. Please submit a "
              "bug report.", n_sockets_open);
+  socket_accounting_unlock();
   return r;
 }
 
@@ -754,8 +776,10 @@ tor_open_socket(int domain, int type, int protocol)
 {
   int s = socket(domain, type, protocol);
   if (s >= 0) {
+    socket_accounting_lock();
     ++n_sockets_open;
     mark_socket_open(s);
+    socket_accounting_unlock();
   }
   return s;
 }
@@ -766,8 +790,10 @@ tor_accept_socket(int sockfd, struct sockaddr *addr, socklen_t *len)
 {
   int s = accept(sockfd, addr, len);
   if (s >= 0) {
+    socket_accounting_lock();
     ++n_sockets_open;
     mark_socket_open(s);
+    socket_accounting_unlock();
   }
   return s;
 }
@@ -776,7 +802,11 @@ tor_accept_socket(int sockfd, struct sockaddr *addr, socklen_t *len)
 int
 get_n_open_sockets(void)
 {
-  return n_sockets_open;
+  int n;
+  socket_accounting_lock();
+  n = n_sockets_open;
+  socket_accounting_unlock();
+  return n;
 }
 
 /** Turn <b>socket</b> into a nonblocking socket.
@@ -817,6 +847,7 @@ tor_socketpair(int family, int type, int protocol, int fd[2])
   int r;
   r = socketpair(family, type, protocol, fd);
   if (r == 0) {
+    socket_accounting_lock();
     if (fd[0] >= 0) {
       ++n_sockets_open;
       mark_socket_open(fd[0]);
@@ -825,6 +856,7 @@ tor_socketpair(int family, int type, int protocol, int fd[2])
       ++n_sockets_open;
       mark_socket_open(fd[1]);
     }
+    socket_accounting_unlock();
   }
   return r < 0 ? -errno : r;
 #else

+ 14 - 0
src/or/config.c

@@ -1329,6 +1329,11 @@ options_act(or_options_t *old_options)
       circuit_expire_all_dirty_circs();
     }
 
+    if (! bool_eq(options->BridgeRelay, old_options->BridgeRelay)) {
+      log_info(LD_GENERAL, "Bridge status changed.  Forgetting GeoIP stats.");
+      geoip_remove_old_clients(time(NULL)+3600);
+    }
+
     if (options_transition_affects_workers(old_options, options)) {
       log_info(LD_GENERAL,
                "Worker-related options changed. Rotating workers.");
@@ -3233,6 +3238,15 @@ options_validate(or_options_t *old_options, or_options_t *options,
     return -1;
   }
 
+  if ((options->BridgeRelay
+        || options->_PublishServerDescriptor & BRIDGE_AUTHORITY)
+      && (options->_PublishServerDescriptor
+          & (V1_AUTHORITY|V2_AUTHORITY|V3_AUTHORITY))) {
+    REJECT("Bridges are not supposed to publish router descriptors to the "
+           "directory authorities. Please correct your "
+           "PublishServerDescriptor line.");
+  }
+
   if (options->MinUptimeHidServDirectoryV2 < 0) {
     log_warn(LD_CONFIG, "MinUptimeHidServDirectoryV2 option must be at "
                         "least 0 seconds. Changing to 0.");