Merge branch 'maint-0.2.4' into release-0.2.4
This commit is contained in:
commit
4ef52cc167
|
@ -0,0 +1,7 @@
|
|||
- Minor bugfixes:
|
||||
|
||||
- Treat ENETUNREACH, EACCES, and EPERM at an exit node as a
|
||||
NOROUTE error, not an INTERNAL error, since they can apparently
|
||||
happen when trying to connect to the wrong sort of
|
||||
netblocks. Fixes a part of bug 10777; bugfix on 0.1.0.1-rc.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
o Major bugfixes:
|
||||
- Do not treat END_STREAM_REASON_INTERNAL as indicating a definite
|
||||
circuit failure, since it could also indicate an ENETUNREACH
|
||||
error. Fixes part of bug 10777; bugfix on 0.2.4.8-alpha.
|
|
@ -0,0 +1,5 @@
|
|||
o Minor bugfixes (compilation):
|
||||
- Build without warnings under clang 3.4. (We have some macros that
|
||||
define static functions only some of which will get used later in
|
||||
the module. Starting with clang 3.4, these give a warning unless the
|
||||
unused attribute is set on them.)
|
|
@ -0,0 +1,6 @@
|
|||
- Minor bugfixes:
|
||||
- Fix build warnings about missing "a2x" comment when building the
|
||||
manpages from scratch on OpenBSD; OpenBSD calls it "a2x.py".
|
||||
Fixes bug 10929; bugfix on tor-0.2.2.9-alpha. Patch from
|
||||
Dana Koch.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
o Minor features:
|
||||
- Avoid using circuit paths if no node in the path supports the ntor
|
||||
circuit extension handshake. Implements ticket 9777.
|
|
@ -0,0 +1,3 @@
|
|||
o Minor features:
|
||||
- Update to the February 7 2014 Maxmind GeoLite2 Country database.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
o Minor features:
|
||||
- Fix our version of the February 7 2014 Maxmind GeoLite2 Country database.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
o Minor features:
|
||||
- Update geoip6 to the February 7 2014 Maxmind GeoLite2 Country
|
||||
database.
|
|
@ -167,7 +167,7 @@ AC_CHECK_PROG([SED],[sed],[sed],[/bin/false])
|
|||
|
||||
dnl check for asciidoc and a2x
|
||||
AC_PATH_PROG([ASCIIDOC], [asciidoc], none)
|
||||
AC_PATH_PROG([A2X], [a2x], none)
|
||||
AC_PATH_PROGS([A2X], [a2x a2x.py], none)
|
||||
|
||||
AM_CONDITIONAL(USE_ASCIIDOC, test x$asciidoc = xtrue)
|
||||
|
||||
|
|
|
@ -162,6 +162,7 @@ extern INLINE double U64_TO_DBL(uint64_t x) {
|
|||
*
|
||||
* #define ATTR_NONNULL(x) __attribute__((nonnull x)) */
|
||||
#define ATTR_NONNULL(x)
|
||||
#define ATTR_UNUSED __attribute__ ((unused))
|
||||
|
||||
/** Macro: Evaluates to <b>exp</b> and hints the compiler that the value
|
||||
* of <b>exp</b> will probably be true.
|
||||
|
@ -185,6 +186,7 @@ extern INLINE double U64_TO_DBL(uint64_t x) {
|
|||
#define ATTR_MALLOC
|
||||
#define ATTR_NORETURN
|
||||
#define ATTR_NONNULL(x)
|
||||
#define ATTR_UNUSED
|
||||
#define PREDICT_LIKELY(exp) (exp)
|
||||
#define PREDICT_UNLIKELY(exp) (exp)
|
||||
#endif
|
||||
|
|
|
@ -471,64 +471,74 @@ void* strmap_remove_lc(strmap_t *map, const char *key);
|
|||
#define DECLARE_TYPED_DIGESTMAP_FNS(prefix, maptype, valtype) \
|
||||
typedef struct maptype maptype; \
|
||||
typedef struct prefix##iter_t prefix##iter_t; \
|
||||
static INLINE maptype* prefix##new(void) \
|
||||
ATTR_UNUSED static INLINE maptype* \
|
||||
prefix##new(void) \
|
||||
{ \
|
||||
return (maptype*)digestmap_new(); \
|
||||
} \
|
||||
static INLINE digestmap_t* prefix##to_digestmap(maptype *map) \
|
||||
ATTR_UNUSED static INLINE digestmap_t* \
|
||||
prefix##to_digestmap(maptype *map) \
|
||||
{ \
|
||||
return (digestmap_t*)map; \
|
||||
} \
|
||||
static INLINE valtype* prefix##get(maptype *map, const char *key) \
|
||||
ATTR_UNUSED static INLINE valtype* \
|
||||
prefix##get(maptype *map, const char *key) \
|
||||
{ \
|
||||
return (valtype*)digestmap_get((digestmap_t*)map, key); \
|
||||
} \
|
||||
static INLINE valtype* prefix##set(maptype *map, const char *key, \
|
||||
valtype *val) \
|
||||
ATTR_UNUSED static INLINE valtype* \
|
||||
prefix##set(maptype *map, const char *key, valtype *val) \
|
||||
{ \
|
||||
return (valtype*)digestmap_set((digestmap_t*)map, key, val); \
|
||||
} \
|
||||
static INLINE valtype* prefix##remove(maptype *map, const char *key) \
|
||||
ATTR_UNUSED static INLINE valtype* \
|
||||
prefix##remove(maptype *map, const char *key) \
|
||||
{ \
|
||||
return (valtype*)digestmap_remove((digestmap_t*)map, key); \
|
||||
} \
|
||||
static INLINE void prefix##free(maptype *map, void (*free_val)(void*)) \
|
||||
ATTR_UNUSED static INLINE void \
|
||||
prefix##free(maptype *map, void (*free_val)(void*)) \
|
||||
{ \
|
||||
digestmap_free((digestmap_t*)map, free_val); \
|
||||
} \
|
||||
static INLINE int prefix##isempty(maptype *map) \
|
||||
ATTR_UNUSED static INLINE int \
|
||||
prefix##isempty(maptype *map) \
|
||||
{ \
|
||||
return digestmap_isempty((digestmap_t*)map); \
|
||||
} \
|
||||
static INLINE int prefix##size(maptype *map) \
|
||||
ATTR_UNUSED static INLINE int \
|
||||
prefix##size(maptype *map) \
|
||||
{ \
|
||||
return digestmap_size((digestmap_t*)map); \
|
||||
} \
|
||||
static INLINE prefix##iter_t *prefix##iter_init(maptype *map) \
|
||||
ATTR_UNUSED static INLINE \
|
||||
prefix##iter_t *prefix##iter_init(maptype *map) \
|
||||
{ \
|
||||
return (prefix##iter_t*) digestmap_iter_init((digestmap_t*)map); \
|
||||
} \
|
||||
static INLINE prefix##iter_t *prefix##iter_next(maptype *map, \
|
||||
prefix##iter_t *iter) \
|
||||
ATTR_UNUSED static INLINE \
|
||||
prefix##iter_t *prefix##iter_next(maptype *map, prefix##iter_t *iter) \
|
||||
{ \
|
||||
return (prefix##iter_t*) digestmap_iter_next( \
|
||||
(digestmap_t*)map, (digestmap_iter_t*)iter); \
|
||||
} \
|
||||
static INLINE prefix##iter_t *prefix##iter_next_rmv(maptype *map, \
|
||||
prefix##iter_t *iter) \
|
||||
ATTR_UNUSED static INLINE prefix##iter_t* \
|
||||
prefix##iter_next_rmv(maptype *map, prefix##iter_t *iter) \
|
||||
{ \
|
||||
return (prefix##iter_t*) digestmap_iter_next_rmv( \
|
||||
(digestmap_t*)map, (digestmap_iter_t*)iter); \
|
||||
} \
|
||||
static INLINE void prefix##iter_get(prefix##iter_t *iter, \
|
||||
const char **keyp, \
|
||||
valtype **valp) \
|
||||
ATTR_UNUSED static INLINE void \
|
||||
prefix##iter_get(prefix##iter_t *iter, \
|
||||
const char **keyp, \
|
||||
valtype **valp) \
|
||||
{ \
|
||||
void *v; \
|
||||
digestmap_iter_get((digestmap_iter_t*) iter, keyp, &v); \
|
||||
*valp = v; \
|
||||
} \
|
||||
static INLINE int prefix##iter_done(prefix##iter_t *iter) \
|
||||
ATTR_UNUSED static INLINE int \
|
||||
prefix##iter_done(prefix##iter_t *iter) \
|
||||
{ \
|
||||
return digestmap_iter_done((digestmap_iter_t*)iter); \
|
||||
}
|
||||
|
|
19698
src/config/geoip
19698
src/config/geoip
File diff suppressed because it is too large
Load Diff
7834
src/config/geoip6
7834
src/config/geoip6
File diff suppressed because it is too large
Load Diff
16
src/ext/ht.h
16
src/ext/ht.h
|
@ -168,7 +168,7 @@ ht_string_hash(const char *s)
|
|||
} \
|
||||
/* Insert the element 'elm' into the table 'head'. Do not call this \
|
||||
* function if the table might already contain a matching element. */ \
|
||||
static INLINE void \
|
||||
ATTR_UNUSED static INLINE void \
|
||||
name##_HT_INSERT(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type **p; \
|
||||
|
@ -183,7 +183,7 @@ ht_string_hash(const char *s)
|
|||
/* Insert the element 'elm' into the table 'head'. If there already \
|
||||
* a matching element in the table, replace that element and return \
|
||||
* it. */ \
|
||||
static INLINE struct type * \
|
||||
ATTR_UNUSED static INLINE struct type * \
|
||||
name##_HT_REPLACE(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type **p, *r; \
|
||||
|
@ -204,7 +204,7 @@ ht_string_hash(const char *s)
|
|||
} \
|
||||
/* Remove any element matching 'elm' from the table 'head'. If such \
|
||||
* an element is found, return it; otherwise return NULL. */ \
|
||||
static INLINE struct type * \
|
||||
ATTR_UNUSED static INLINE struct type * \
|
||||
name##_HT_REMOVE(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type **p, *r; \
|
||||
|
@ -222,11 +222,11 @@ ht_string_hash(const char *s)
|
|||
* using 'data' as its second argument. If the function returns \
|
||||
* nonzero, remove the most recently examined element before invoking \
|
||||
* the function again. */ \
|
||||
static INLINE void \
|
||||
ATTR_UNUSED static INLINE void \
|
||||
name##_HT_FOREACH_FN(struct name *head, \
|
||||
int (*fn)(struct type *, void *), \
|
||||
void *data) \
|
||||
{ \
|
||||
{ \
|
||||
unsigned idx; \
|
||||
struct type **p, **nextp, *next; \
|
||||
if (!head->hth_table) \
|
||||
|
@ -248,7 +248,7 @@ ht_string_hash(const char *s)
|
|||
/* Return a pointer to the first element in the table 'head', under \
|
||||
* an arbitrary order. This order is stable under remove operations, \
|
||||
* but not under others. If the table is empty, return NULL. */ \
|
||||
static INLINE struct type ** \
|
||||
ATTR_UNUSED static INLINE struct type ** \
|
||||
name##_HT_START(struct name *head) \
|
||||
{ \
|
||||
unsigned b = 0; \
|
||||
|
@ -264,7 +264,7 @@ ht_string_hash(const char *s)
|
|||
* NULL. If 'elm' is to be removed from the table, you must call \
|
||||
* this function for the next value before you remove it. \
|
||||
*/ \
|
||||
static INLINE struct type ** \
|
||||
ATTR_UNUSED static INLINE struct type ** \
|
||||
name##_HT_NEXT(struct name *head, struct type **elm) \
|
||||
{ \
|
||||
if ((*elm)->field.hte_next) { \
|
||||
|
@ -280,7 +280,7 @@ ht_string_hash(const char *s)
|
|||
return NULL; \
|
||||
} \
|
||||
} \
|
||||
static INLINE struct type ** \
|
||||
ATTR_UNUSED static INLINE struct type ** \
|
||||
name##_HT_NEXT_RMV(struct name *head, struct type **elm) \
|
||||
{ \
|
||||
unsigned h = HT_ELT_HASH_(*elm, field, hashfn); \
|
||||
|
|
|
@ -72,6 +72,9 @@ static void pathbias_count_use_failed(origin_circuit_t *circ);
|
|||
static void pathbias_measure_use_rate(entry_guard_t *guard);
|
||||
static void pathbias_measure_close_rate(entry_guard_t *guard);
|
||||
static void pathbias_scale_use_rates(entry_guard_t *guard);
|
||||
#ifdef CURVE25519_ENABLED
|
||||
static int circuits_can_use_ntor(void);
|
||||
#endif
|
||||
|
||||
/** This function tries to get a channel to the specified endpoint,
|
||||
* and then calls command_setup_channel() to give it the right
|
||||
|
@ -284,21 +287,74 @@ circuit_rep_hist_note_result(origin_circuit_t *circ)
|
|||
} while (hop!=circ->cpath);
|
||||
}
|
||||
|
||||
#ifdef CURVE25519_ENABLED
|
||||
/** Return 1 iff at least one node in circ's cpath supports ntor. */
|
||||
static int
|
||||
circuit_cpath_supports_ntor(const origin_circuit_t *circ)
|
||||
{
|
||||
crypt_path_t *head = circ->cpath, *cpath = circ->cpath;
|
||||
|
||||
cpath = head;
|
||||
do {
|
||||
if (cpath->extend_info &&
|
||||
!tor_mem_is_zero(
|
||||
(const char*)cpath->extend_info->curve25519_onion_key.public_key,
|
||||
CURVE25519_PUBKEY_LEN))
|
||||
return 1;
|
||||
|
||||
cpath = cpath->next;
|
||||
} while (cpath != head);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define circuit_cpath_supports_ntor(circ) 0
|
||||
#endif
|
||||
|
||||
/** Pick all the entries in our cpath. Stop and return 0 when we're
|
||||
* happy, or return -1 if an error occurs. */
|
||||
static int
|
||||
onion_populate_cpath(origin_circuit_t *circ)
|
||||
{
|
||||
int r;
|
||||
again:
|
||||
r = onion_extend_cpath(circ);
|
||||
if (r < 0) {
|
||||
log_info(LD_CIRC,"Generating cpath hop failed.");
|
||||
return -1;
|
||||
int n_tries = 0;
|
||||
#ifdef CURVE25519_ENABLED
|
||||
const int using_ntor = circuits_can_use_ntor();
|
||||
#else
|
||||
const int using_ntor = 0;
|
||||
#endif
|
||||
|
||||
#define MAX_POPULATE_ATTEMPTS 32
|
||||
|
||||
while (1) {
|
||||
int r = onion_extend_cpath(circ);
|
||||
if (r < 0) {
|
||||
log_info(LD_CIRC,"Generating cpath hop failed.");
|
||||
return -1;
|
||||
}
|
||||
if (r == 1) {
|
||||
/* This circuit doesn't need/shouldn't be forced to have an ntor hop */
|
||||
if (circ->build_state->desired_path_len <= 1 || ! using_ntor)
|
||||
return 0;
|
||||
|
||||
/* This circuit has an ntor hop. great! */
|
||||
if (circuit_cpath_supports_ntor(circ))
|
||||
return 0;
|
||||
|
||||
/* No node in the circuit supports ntor. Have we already tried too many
|
||||
* times? */
|
||||
if (++n_tries >= MAX_POPULATE_ATTEMPTS)
|
||||
break;
|
||||
|
||||
/* Clear the path and retry */
|
||||
circuit_clear_cpath(circ);
|
||||
}
|
||||
}
|
||||
if (r == 0)
|
||||
goto again;
|
||||
return 0; /* if r == 1 */
|
||||
log_warn(LD_CIRC, "I tried for %d times, but I couldn't build a %d-hop "
|
||||
"circuit with at least one node that supports ntor.",
|
||||
MAX_POPULATE_ATTEMPTS,
|
||||
circ->build_state->desired_path_len);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Create and return a new origin circuit. Initialize its purpose and
|
||||
|
@ -3475,6 +3531,9 @@ onion_next_hop_in_cpath(crypt_path_t *cpath)
|
|||
|
||||
/** Choose a suitable next hop in the cpath <b>head_ptr</b>,
|
||||
* based on <b>state</b>. Append the hop info to head_ptr.
|
||||
*
|
||||
* Return 1 if the path is complete, 0 if we successfully added a hop,
|
||||
* and -1 on error.
|
||||
*/
|
||||
static int
|
||||
onion_extend_cpath(origin_circuit_t *circ)
|
||||
|
|
|
@ -709,7 +709,7 @@ circuit_free_cpath(crypt_path_t *cpath)
|
|||
if (!cpath)
|
||||
return;
|
||||
|
||||
/* it's a doubly linked list, so we have to notice when we've
|
||||
/* it's a circular list, so we have to notice when we've
|
||||
* gone through it once. */
|
||||
while (cpath->next && cpath->next != head) {
|
||||
victim = cpath;
|
||||
|
@ -720,6 +720,14 @@ circuit_free_cpath(crypt_path_t *cpath)
|
|||
circuit_free_cpath_node(cpath);
|
||||
}
|
||||
|
||||
/** Remove all the items in the cpath on <b>circ</b>.*/
|
||||
void
|
||||
circuit_clear_cpath(origin_circuit_t *circ)
|
||||
{
|
||||
circuit_free_cpath(circ->cpath);
|
||||
circ->cpath = NULL;
|
||||
}
|
||||
|
||||
/** Release all storage held by circuits. */
|
||||
void
|
||||
circuit_free_all(void)
|
||||
|
|
|
@ -50,6 +50,7 @@ void circuit_mark_all_dirty_circs_as_unusable(void);
|
|||
void circuit_mark_for_close_(circuit_t *circ, int reason,
|
||||
int line, const char *file);
|
||||
int circuit_get_cpath_len(origin_circuit_t *circ);
|
||||
void circuit_clear_cpath(origin_circuit_t *circ);
|
||||
crypt_path_t *circuit_get_cpath_hop(origin_circuit_t *circ, int hopnum);
|
||||
void circuit_get_all_pending_on_channel(smartlist_t *out,
|
||||
channel_t *chan);
|
||||
|
|
|
@ -174,11 +174,12 @@ errno_to_stream_end_reason(int e)
|
|||
S_CASE(ENOTSOCK):
|
||||
S_CASE(EPROTONOSUPPORT):
|
||||
S_CASE(EAFNOSUPPORT):
|
||||
E_CASE(EACCES):
|
||||
S_CASE(ENOTCONN):
|
||||
S_CASE(ENETUNREACH):
|
||||
return END_STREAM_REASON_INTERNAL;
|
||||
S_CASE(ENETUNREACH):
|
||||
S_CASE(EHOSTUNREACH):
|
||||
E_CASE(EACCES):
|
||||
case EPERM:
|
||||
return END_STREAM_REASON_NOROUTE;
|
||||
S_CASE(ECONNREFUSED):
|
||||
return END_STREAM_REASON_CONNECTREFUSED;
|
||||
|
|
|
@ -731,13 +731,15 @@ connection_ap_process_end_not_open(
|
|||
|
||||
if (rh->length > 0) {
|
||||
if (reason == END_STREAM_REASON_TORPROTOCOL ||
|
||||
reason == END_STREAM_REASON_INTERNAL ||
|
||||
reason == END_STREAM_REASON_DESTROY) {
|
||||
/* All three of these reasons could mean a failed tag
|
||||
/* Both of these reasons could mean a failed tag
|
||||
* hit the exit and it complained. Do not probe.
|
||||
* Fail the circuit. */
|
||||
circ->path_state = PATH_STATE_USE_FAILED;
|
||||
return -END_CIRC_REASON_TORPROTOCOL;
|
||||
} else if (reason == END_STREAM_REASON_INTERNAL) {
|
||||
/* We can't infer success or failure, since older Tors report
|
||||
* ENETUNREACH as END_STREAM_REASON_INTERNAL. */
|
||||
} else {
|
||||
/* Path bias: If we get a valid reason code from the exit,
|
||||
* it wasn't due to tagging.
|
||||
|
|
Loading…
Reference in New Issue