aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2009-05-13 16:55:42 -0400
committerNick Mathewson <nickm@torproject.org>2009-05-13 16:55:42 -0400
commit479d21254ac49f6493087ce1385bcfe8d84476d4 (patch)
tree1c333bdd791d0c677bf297e5e9e93475861ab937
parentce768fc06e093da114ddfebfc2400c47115c2c38 (diff)
parent45171cd9e9cb492bd64a1251dcd7758cab686f4b (diff)
downloadtor-479d21254ac49f6493087ce1385bcfe8d84476d4.tar
tor-479d21254ac49f6493087ce1385bcfe8d84476d4.tar.gz
Merge commit 'origin/maint-0.2.1'
-rw-r--r--ChangeLog7
-rw-r--r--src/common/compat.c52
-rw-r--r--src/or/config.c14
3 files changed, 63 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index eff171db2..492fb435e 100644
--- a/ChangeLog
+++ b/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
diff --git a/src/common/compat.c b/src/common/compat.c
index 82957722c..51794c762 100644
--- a/src/common/compat.c
+++ b/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
diff --git a/src/or/config.c b/src/or/config.c
index 1ac38039e..9b83e9d81 100644
--- a/src/or/config.c
+++ b/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.");