Merge commit 'origin/maint-0.2.1'

This commit is contained in:
Nick Mathewson 2009-05-31 19:17:22 -04:00
commit 77ffd6b2a7
9 changed files with 138 additions and 15 deletions

View File

@ -29,10 +29,20 @@ Changes in version 0.2.1.16-?? - 2009-??-??
o Minor bugfixes (on 0.2.0.x):
- Log correct error messages for DNS-related network errors on
Windows.
- Don't warn users about low port and hibernation mix when they
provide a *ListenAddress directive to fix that. Bugfix on
0.2.1.15-rc.
- Fix a race condition that could cause crashes or memory
corruption when running as a server with a controller listening
for log messages.
o Minor bugfixes (on 0.2.1.x):
- When switching back and forth between bridge mode, do not start
gathering GeoIP data until two hours have passed.
- Do not complain that the user has requested an excluded node as
an exit when the node is not really an exit. This could happen
because the circuit was for testing, or an introduction point.
Fix for bug 984.
Changes in version 0.2.1.15-rc - 2009-05-25

View File

@ -2076,6 +2076,7 @@ tor_threads_init(void)
pthread_mutexattr_init(&attr_reentrant);
pthread_mutexattr_settype(&attr_reentrant, PTHREAD_MUTEX_RECURSIVE);
threads_initialized = 1;
set_main_thread();
}
}
#elif defined(USE_WIN32_THREADS)
@ -2168,9 +2169,27 @@ tor_threads_init(void)
#if 0
cond_event_tls_index = TlsAlloc();
#endif
set_main_thread();
}
#endif
/** Identity of the "main" thread */
static unsigned long main_thread_id = -1;
/** Start considering the current thread to be the 'main thread'. This has
* no effect on anything besides in_main_thread(). */
void
set_main_thread(void)
{
main_thread_id = tor_get_thread_id();
}
/** Return true iff called from the main thread. */
int
in_main_thread(void)
{
return main_thread_id == tor_get_thread_id();
}
/**
* On Windows, WSAEWOULDBLOCK is not always correct: when you see it,
* you need to ask the socket for its actual errno. Also, you need to

View File

@ -522,6 +522,9 @@ void tor_threads_init(void);
#define tor_threads_init() STMT_NIL
#endif
void set_main_thread(void);
int in_main_thread(void);
#ifdef TOR_IS_MULTITHREADED
#if 0
typedef struct tor_cond_t tor_cond_t;

View File

@ -2480,6 +2480,8 @@ start_daemon(void)
if (fork() != 0) {
exit(0);
}
set_main_thread(); /* We are now the main thread. */
return;
}
}

View File

@ -1436,17 +1436,67 @@ choose_good_exit_server(uint8_t purpose, routerlist_t *dir,
/** Log a warning if the user specified an exit for the circuit that
* has been excluded from use by ExcludeNodes or ExcludeExitNodes. */
static void
warn_if_router_excluded(const extend_info_t *exit)
warn_if_last_router_excluded(uint8_t purpose, const extend_info_t *exit)
{
or_options_t *options = get_options();
routerinfo_t *ri = router_get_by_digest(exit->identity_digest);
routerset_t *rs = options->ExcludeNodes;
const char *description;
int severity;
int domain = LD_CIRC;
if (!ri || !options->_ExcludeExitNodesUnion)
return;
switch (purpose)
{
default:
case CIRCUIT_PURPOSE_OR:
case CIRCUIT_PURPOSE_INTRO_POINT:
case CIRCUIT_PURPOSE_REND_POINT_WAITING:
case CIRCUIT_PURPOSE_REND_ESTABLISHED:
log_warn(LD_BUG, "Called on non-origin circuit (purpose %d)",
(int)purpose);
return;
case CIRCUIT_PURPOSE_C_GENERAL:
description = "Requested exit node";
rs = options->_ExcludeExitNodesUnion;
severity = LOG_WARN;
break;
case CIRCUIT_PURPOSE_C_INTRODUCING:
case CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT:
case CIRCUIT_PURPOSE_C_INTRODUCE_ACKED:
description = "Introduction point for hidden service";
severity = LOG_INFO;
break;
case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
case CIRCUIT_PURPOSE_C_REND_READY:
case CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED:
case CIRCUIT_PURPOSE_C_REND_JOINED:
description = "Chosen rendezvous point";
severity = LOG_WARN;
domain = LD_BUG;
break;
case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO:
description = "Chosen introduction point";
severity = LOG_INFO;
break;
case CIRCUIT_PURPOSE_S_CONNECT_REND:
case CIRCUIT_PURPOSE_S_REND_JOINED:
description = "Client-selected rendezvous point";
severity = LOG_INFO;
break;
case CIRCUIT_PURPOSE_TESTING:
description = "Target for testing circuit";
severity = LOG_INFO;
break;
case CIRCUIT_PURPOSE_CONTROLLER:
rs = options->_ExcludeExitNodesUnion;
description = "Controller-selected circuit target";
severity = LOG_WARN;
break;
}
if (routerset_contains_router(options->_ExcludeExitNodesUnion, ri))
log_warn(LD_CIRC,"Requested exit node '%s' is in ExcludeNodes, "
"or ExcludeExitNodes, using anyway.",exit->nickname);
if (routerset_contains_extendinfo(rs, exit))
log_fn(severity, domain, "%s '%s' is in ExcludeNodes%s. Using anyway.",
description,exit->nickname,
rs==options->ExcludeNodes?"":" or ExcludeExitNodes.");
return;
}
@ -1471,7 +1521,7 @@ onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit)
}
if (exit) { /* the circuit-builder pre-requested one */
warn_if_router_excluded(exit);
warn_if_last_router_excluded(circ->_base.purpose, exit);
log_info(LD_CIRC,"Using requested exit node '%s'", exit->nickname);
exit = extend_info_dup(exit);
} else { /* we have to decide one */

View File

@ -699,6 +699,9 @@ static int or_state_validate(or_state_t *old_options, or_state_t *options,
static int or_state_load(void);
static int options_init_logs(or_options_t *options, int validate_only);
static int is_listening_on_low_port(uint16_t port_option,
const config_line_t *listen_options);
static uint64_t config_parse_memunit(const char *s, int *ok);
static int config_parse_interval(const char *s, int *ok);
static void init_libevent(void);
@ -2631,6 +2634,35 @@ options_init(or_options_t *options)
config_init(&options_format, options);
}
/* Check if the port number given in <b>port_option</b> in combination with
* the specified port in <b>listen_options</b> will result in Tor actually
* opening a low port (meaning a port lower than 1024). Return 1 if
* it is, or 0 if it isn't or the concept of a low port isn't applicable for
* the platform we're on. */
static int
is_listening_on_low_port(uint16_t port_option,
const config_line_t *listen_options)
{
#ifdef MS_WINDOWS
return 0; /* No port is too low for windows. */
#else
const config_line_t *l;
uint16_t p;
if (port_option == 0)
return 0; /* We're not listening */
if (listen_options == NULL)
return (port_option < 1024);
for (l = listen_options; l; l = l->next) {
parse_addr_port(LOG_WARN, l->value, NULL, NULL, &p);
if (p<1024) {
return 1;
}
}
return 0;
#endif
}
/** Set all vars in the configuration object <b>options</b> to their default
* values. */
static void
@ -3032,17 +3064,18 @@ options_validate(or_options_t *old_options, or_options_t *options,
REJECT("TransPort and TransListenAddress are disabled in this build.");
#endif
#ifndef MS_WINDOWS
if (options->AccountingMax &&
(options->DirPort < 1024 || options->ORPort < 1024))
log(LOG_WARN, LD_CONFIG,
if (options->AccountingMax &&
(is_listening_on_low_port(options->ORPort, options->ORListenAddress) ||
is_listening_on_low_port(options->DirPort, options->DirListenAddress)))
{
log(LOG_WARN, LD_CONFIG,
"You have set AccountingMax to use hibernation. You have also "
"chosen a low DirPort or OrPort. This combination can make Tor stop "
"working when it tries to re-attach the port after a period of "
"hibernation. Please choose a different port or turn off "
"hibernation unless you know this combination will work on your "
"platform.");
#endif
}
if (options->ExcludeExitNodes || options->ExcludeNodes) {
options->_ExcludeExitNodesUnion = routerset_new();

View File

@ -3230,6 +3230,11 @@ control_event_logmsg(int severity, uint32_t domain, const char *msg)
{
int event;
/* Don't even think of trying to add stuff to a buffer from a cpuworker
* thread. */
if (! in_main_thread())
return;
if (disable_log_messages)
return;

View File

@ -4499,7 +4499,8 @@ int routerset_needs_geoip(const routerset_t *set);
int routerset_contains_router(const routerset_t *set, routerinfo_t *ri);
int routerset_contains_routerstatus(const routerset_t *set,
routerstatus_t *rs);
int routerset_contains_extendinfo(const routerset_t *set, extend_info_t *ei);
int routerset_contains_extendinfo(const routerset_t *set,
const extend_info_t *ei);
void routerset_get_all_routers(smartlist_t *out, const routerset_t *routerset,
int running_only);
void routersets_get_disjunction(smartlist_t *target, const smartlist_t *source,

View File

@ -5119,7 +5119,7 @@ routerset_contains(const routerset_t *set, const tor_addr_t *addr,
/** Return true iff we can tell that <b>ei</b> is a member of <b>set</b>. */
int
routerset_contains_extendinfo(const routerset_t *set, extend_info_t *ei)
routerset_contains_extendinfo(const routerset_t *set, const extend_info_t *ei)
{
return routerset_contains(set,
&ei->addr,