Merge branch 'maint-0.2.5' into release-0.2.5

This commit is contained in:
Roger Dingledine 2014-07-24 16:31:09 -04:00
commit c0411e1c89
27 changed files with 3819 additions and 3971 deletions

View File

@ -0,0 +1,6 @@
o Minor bugfixes:
- Fix compilation when building with bufferevents enabled. (This
configuration is still not expected to work, however.)
Fixes bugs 12438, 12474, 11578; bugfixes on 0.2.5.1-alpha and
0.2.5.3-alpha. Patches from Anthony G. Basile and Sathyanarayanan
Gunasekaran.

5
changes/bug12602 Normal file
View File

@ -0,0 +1,5 @@
o Minor bugfixes (portability):
- Compile correctly with builds and forks of OpenSSL (such as
LibreSSL) that disable compression. Fixes bug 12602; bugfix on
0.2.1.1-alpha. Patch from "dhill".

11
changes/bug8387 Normal file
View File

@ -0,0 +1,11 @@
o Major bugfixes (client):
- Perform circuit cleanup operations even when circuit
construction operations are disabled (because the network is
disabled, or because there isn't enough directory information).
Previously, when we were not building predictive circuits, we
were not closing expired circuits either.
Fixes bug 8387; bugfix on 0.1.1.11-alpha. This bug became visible
in 0.2.4.10-alpha when we became more strict about when we have
"enough directory information to build circuits".

View File

@ -0,0 +1,12 @@
o Major bugfixes:
- Fix a bug in the bounds-checking in the 32-bit curve25519-donna
implementation that caused incorrect results on 32-bit
implementations when certain malformed inputs were used along with
a small class of private ntor keys. This bug does not currently
appear to allow an attacker to learn private keys or impersonate a
Tor server, but it could provide a means to distinguish 32-bit Tor
implementations from 64-bit Tor implementations. Fixes bug 12694;
bugfix on 0.2.4.8-alpha. Bug found by Robert Ransom; fix from
Adam Langley.

View File

@ -0,0 +1,2 @@
o Minor features (diagnostic):
- Slightly enhance the diagnostic message for bug 12184.

3
changes/geoip-july2014 Normal file
View File

@ -0,0 +1,3 @@
o Minor features:
- Update geoip to the July 10 2014 Maxmind GeoLite2 Country database.

2
changes/geoip6-july2014 Normal file
View File

@ -0,0 +1,2 @@
o Minor features:
- Update geoip6 to the July 10 2014 Maxmind GeoLite2 Country database.

6
changes/ticket12688 Normal file
View File

@ -0,0 +1,6 @@
Major features:
- Make the number of entry guards configurable via a new
NumEntryGuards consensus parameter, and the number of directory
guards configurable via a new NumDirectoryGuards consensus
parameter. Implements ticket 12688.

9
changes/ticket12690 Normal file
View File

@ -0,0 +1,9 @@
o Minor features:
- Authorities now assign the Guard flag to the fastest 25% of the
network (it used to be the fastest 50%). Also raise the consensus
weight that guarantees the Guard flag from 250 to 2000. For the
current network, this results in about 1100 guards, down from 2500.
This step paves the way for moving the number of entry guards
down to 1 (proposal 236) while still providing reasonable expected
performance for most users. Implements ticket 12690.

View File

@ -454,7 +454,7 @@ AC_CHECK_MEMBERS([struct event.min_heap_idx], , ,
[#include <event.h>
])
AC_CHECK_HEADERS(event2/event.h event2/dns.h)
AC_CHECK_HEADERS(event2/event.h event2/dns.h event2/bufferevent_ssl.h)
LIBS="$save_LIBS"
LDFLAGS="$save_LDFLAGS"

View File

@ -1092,12 +1092,16 @@ The following options are useful only for clients (that is, if
[[NumEntryGuards]] **NumEntryGuards** __NUM__::
If UseEntryGuards is set to 1, we will try to pick a total of NUM routers
as long-term entries for our circuits. (Default: 3)
as long-term entries for our circuits. If NUM is 0, we try to learn
the number from the NumEntryGuards consensus parameter, and default
to 3 if the consensus parameter isn't set. (Default: 0)
[[NumDirectoryGuards]] **NumDirectoryGuards** __NUM__::
If UseEntryGuardsAsDirectoryGuards is enabled, we try to make sure we
have at least NUM routers to use as directory guards. If this option
is set to 0, use the value from NumEntryGuards. (Default: 0)
is set to 0, use the value from the NumDirectoryGuards consensus
parameter, falling back to the value from NumEntryGuards if the
consensus parameter is 0 or isn't set. (Default: 0)
[[GuardLifetime]] **GuardLifetime** __N__ **days**|**weeks**|**months**::
If nonzero, and UseEntryGuards is set, minimum time to keep a guard before

View File

@ -1318,10 +1318,12 @@ tor_tls_context_new(crypto_pk_t *identity, unsigned int key_lifetime,
SSL_CTX_set_options(result->ctx,
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
}
#ifndef OPENSSL_NO_COMP
/* Don't actually allow compression; it uses ram and time, but the data
* we transmit is all encrypted anyway. */
if (result->ctx->comp_methods)
result->ctx->comp_methods = NULL;
#endif
#ifdef SSL_MODE_RELEASE_BUFFERS
SSL_CTX_set_mode(result->ctx, SSL_MODE_RELEASE_BUFFERS);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -43,8 +43,7 @@
*
* This is, almost, a clean room reimplementation from the curve25519 paper. It
* uses many of the tricks described therein. Only the crecip function is taken
* from the sample implementation.
*/
* from the sample implementation. */
#include "orconfig.h"
@ -61,25 +60,23 @@ typedef int64_t limb;
* significant first. The value of the field element is:
* x[0] + 2^26·x[1] + x^51·x[2] + 2^102·x[3] + ...
*
* i.e. the limbs are 26, 25, 26, 25, ... bits wide.
*/
* i.e. the limbs are 26, 25, 26, 25, ... bits wide. */
/* Sum two numbers: output += in */
static void fsum(limb *output, const limb *in) {
unsigned i;
for (i = 0; i < 10; i += 2) {
output[0+i] = (output[0+i] + in[0+i]);
output[1+i] = (output[1+i] + in[1+i]);
output[0+i] = output[0+i] + in[0+i];
output[1+i] = output[1+i] + in[1+i];
}
}
/* Find the difference of two numbers: output = in - output
* (note the order of the arguments!)
*/
* (note the order of the arguments!). */
static void fdifference(limb *output, const limb *in) {
unsigned i;
for (i = 0; i < 10; ++i) {
output[i] = (in[i] - output[i]);
output[i] = in[i] - output[i];
}
}
@ -95,7 +92,8 @@ static void fscalar_product(limb *output, const limb *in, const limb scalar) {
*
* output must be distinct to both inputs. The inputs are reduced coefficient
* form, the output is not.
*/
*
* output[x] <= 14 * the largest product of the input limbs. */
static void fproduct(limb *output, const limb *in2, const limb *in) {
output[0] = ((limb) ((s32) in2[0])) * ((s32) in[0]);
output[1] = ((limb) ((s32) in2[0])) * ((s32) in[1]) +
@ -199,9 +197,15 @@ static void fproduct(limb *output, const limb *in2, const limb *in) {
output[18] = 2 * ((limb) ((s32) in2[9])) * ((s32) in[9]);
}
/* Reduce a long form to a short form by taking the input mod 2^255 - 19. */
/* Reduce a long form to a short form by taking the input mod 2^255 - 19.
*
* On entry: |output[i]| < 14*2^54
* On exit: |output[0..8]| < 280*2^54 */
static void freduce_degree(limb *output) {
/* Each of these shifts and adds ends up multiplying the value by 19. */
/* Each of these shifts and adds ends up multiplying the value by 19.
*
* For output[0..8], the absolute entry value is < 14*2^54 and we add, at
* most, 19*14*2^54 thus, on exit, |output[0..8]| < 280*2^54. */
output[8] += output[18] << 4;
output[8] += output[18] << 1;
output[8] += output[18];
@ -235,11 +239,13 @@ static void freduce_degree(limb *output) {
#error "This code only works on a two's complement system"
#endif
/* return v / 2^26, using only shifts and adds. */
/* return v / 2^26, using only shifts and adds.
*
* On entry: v can take any value. */
static inline limb
div_by_2_26(const limb v)
{
/* High word of v; no shift needed*/
/* High word of v; no shift needed. */
const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
/* Set to all 1s if v was negative; else set to 0s. */
const int32_t sign = ((int32_t) highword) >> 31;
@ -249,7 +255,9 @@ div_by_2_26(const limb v)
return (v + roundoff) >> 26;
}
/* return v / (2^25), using only shifts and adds. */
/* return v / (2^25), using only shifts and adds.
*
* On entry: v can take any value. */
static inline limb
div_by_2_25(const limb v)
{
@ -263,17 +271,21 @@ div_by_2_25(const limb v)
return (v + roundoff) >> 25;
}
#if 0
/* return v / (2^25), using only shifts and adds.
*
* On entry: v can take any value. */
static inline s32
div_s32_by_2_25(const s32 v)
{
const s32 roundoff = ((uint32_t)(v >> 31)) >> 7;
return (v + roundoff) >> 25;
}
#endif
/* Reduce all coefficients of the short form input so that |x| < 2^26.
*
* On entry: |output[i]| < 2^62
*/
* On entry: |output[i]| < 280*2^54 */
static void freduce_coefficients(limb *output) {
unsigned i;
@ -281,56 +293,65 @@ static void freduce_coefficients(limb *output) {
for (i = 0; i < 10; i += 2) {
limb over = div_by_2_26(output[i]);
/* The entry condition (that |output[i]| < 280*2^54) means that over is, at
* most, 280*2^28 in the first iteration of this loop. This is added to the
* next limb and we can approximate the resulting bound of that limb by
* 281*2^54. */
output[i] -= over << 26;
output[i+1] += over;
/* For the first iteration, |output[i+1]| < 281*2^54, thus |over| <
* 281*2^29. When this is added to the next limb, the resulting bound can
* be approximated as 281*2^54.
*
* For subsequent iterations of the loop, 281*2^54 remains a conservative
* bound and no overflow occurs. */
over = div_by_2_25(output[i+1]);
output[i+1] -= over << 25;
output[i+2] += over;
}
/* Now |output[10]| < 2 ^ 38 and all other coefficients are reduced. */
/* Now |output[10]| < 281*2^29 and all other coefficients are reduced. */
output[0] += output[10] << 4;
output[0] += output[10] << 1;
output[0] += output[10];
output[10] = 0;
/* Now output[1..9] are reduced, and |output[0]| < 2^26 + 19 * 2^38
* So |over| will be no more than 77825 */
/* Now output[1..9] are reduced, and |output[0]| < 2^26 + 19*281*2^29
* So |over| will be no more than 2^16. */
{
limb over = div_by_2_26(output[0]);
output[0] -= over << 26;
output[1] += over;
}
/* Now output[0,2..9] are reduced, and |output[1]| < 2^25 + 77825
* So |over| will be no more than 1. */
{
/* output[1] fits in 32 bits, so we can use div_s32_by_2_25 here. */
s32 over32 = div_s32_by_2_25((s32) output[1]);
output[1] -= over32 << 25;
output[2] += over32;
}
/* Finally, output[0,1,3..9] are reduced, and output[2] is "nearly reduced":
* we have |output[2]| <= 2^26. This is good enough for all of our math,
* but it will require an extra freduce_coefficients before fcontract. */
/* Now output[0,2..9] are reduced, and |output[1]| < 2^25 + 2^16 < 2^26. The
* bound on |output[1]| is sufficient to meet our needs. */
}
/* A helpful wrapper around fproduct: output = in * in2.
*
* output must be distinct to both inputs. The output is reduced degree and
* reduced coefficient.
*/
* On entry: |in[i]| < 2^27 and |in2[i]| < 2^27.
*
* output must be distinct to both inputs. The output is reduced degree
* (indeed, one need only provide storage for 10 limbs) and |output[i]| < 2^26. */
static void
fmul(limb *output, const limb *in, const limb *in2) {
limb t[19];
fproduct(t, in, in2);
/* |t[i]| < 14*2^54 */
freduce_degree(t);
freduce_coefficients(t);
/* |t[i]| < 2^26 */
memcpy(output, t, sizeof(limb) * 10);
}
/* Square a number: output = in**2
*
* output must be distinct from the input. The inputs are reduced coefficient
* form, the output is not.
*
* output[x] <= 14 * the largest product of the input limbs. */
static void fsquare_inner(limb *output, const limb *in) {
output[0] = ((limb) ((s32) in[0])) * ((s32) in[0]);
output[1] = 2 * ((limb) ((s32) in[0])) * ((s32) in[1]);
@ -389,12 +410,23 @@ static void fsquare_inner(limb *output, const limb *in) {
output[18] = 2 * ((limb) ((s32) in[9])) * ((s32) in[9]);
}
/* fsquare sets output = in^2.
*
* On entry: The |in| argument is in reduced coefficients form and |in[i]| <
* 2^27.
*
* On exit: The |output| argument is in reduced coefficients form (indeed, one
* need only provide storage for 10 limbs) and |out[i]| < 2^26. */
static void
fsquare(limb *output, const limb *in) {
limb t[19];
fsquare_inner(t, in);
/* |t[i]| < 14*2^54 because the largest product of two limbs will be <
* 2^(27+27) and fsquare_inner adds together, at most, 14 of those
* products. */
freduce_degree(t);
freduce_coefficients(t);
/* |t[i]| < 2^26 */
memcpy(output, t, sizeof(limb) * 10);
}
@ -423,60 +455,143 @@ fexpand(limb *output, const u8 *input) {
#error "This code only works when >> does sign-extension on negative numbers"
#endif
/* s32_eq returns 0xffffffff iff a == b and zero otherwise. */
static s32 s32_eq(s32 a, s32 b) {
a = ~(a ^ b);
a &= a << 16;
a &= a << 8;
a &= a << 4;
a &= a << 2;
a &= a << 1;
return a >> 31;
}
/* s32_gte returns 0xffffffff if a >= b and zero otherwise, where a and b are
* both non-negative. */
static s32 s32_gte(s32 a, s32 b) {
a -= b;
/* a >= 0 iff a >= b. */
return ~(a >> 31);
}
/* Take a fully reduced polynomial form number and contract it into a
* little-endian, 32-byte array
*/
* little-endian, 32-byte array.
*
* On entry: |input_limbs[i]| < 2^26 */
static void
fcontract(u8 *output, limb *input) {
fcontract(u8 *output, limb *input_limbs) {
int i;
int j;
s32 input[10];
s32 mask;
/* |input_limbs[i]| < 2^26, so it's valid to convert to an s32. */
for (i = 0; i < 10; i++) {
input[i] = (s32) input_limbs[i];
}
for (j = 0; j < 2; ++j) {
for (i = 0; i < 9; ++i) {
if ((i & 1) == 1) {
/* This calculation is a time-invariant way to make input[i] positive
by borrowing from the next-larger limb.
*/
const s32 mask = (s32)(input[i]) >> 31;
const s32 carry = -(((s32)(input[i]) & mask) >> 25);
input[i] = (s32)(input[i]) + (carry << 25);
input[i+1] = (s32)(input[i+1]) - carry;
/* This calculation is a time-invariant way to make input[i]
* non-negative by borrowing from the next-larger limb. */
const s32 mask = input[i] >> 31;
const s32 carry = -((input[i] & mask) >> 25);
input[i] = input[i] + (carry << 25);
input[i+1] = input[i+1] - carry;
} else {
const s32 mask = (s32)(input[i]) >> 31;
const s32 carry = -(((s32)(input[i]) & mask) >> 26);
input[i] = (s32)(input[i]) + (carry << 26);
input[i+1] = (s32)(input[i+1]) - carry;
const s32 mask = input[i] >> 31;
const s32 carry = -((input[i] & mask) >> 26);
input[i] = input[i] + (carry << 26);
input[i+1] = input[i+1] - carry;
}
}
/* There's no greater limb for input[9] to borrow from, but we can multiply
* by 19 and borrow from input[0], which is valid mod 2^255-19. */
{
const s32 mask = (s32)(input[9]) >> 31;
const s32 carry = -(((s32)(input[9]) & mask) >> 25);
input[9] = (s32)(input[9]) + (carry << 25);
input[0] = (s32)(input[0]) - (carry * 19);
const s32 mask = input[9] >> 31;
const s32 carry = -((input[9] & mask) >> 25);
input[9] = input[9] + (carry << 25);
input[0] = input[0] - (carry * 19);
}
/* After the first iteration, input[1..9] are non-negative and fit within
* 25 or 26 bits, depending on position. However, input[0] may be
* negative. */
}
/* The first borrow-propagation pass above ended with every limb
except (possibly) input[0] non-negative.
Since each input limb except input[0] is decreased by at most 1
by a borrow-propagation pass, the second borrow-propagation pass
could only have wrapped around to decrease input[0] again if the
first pass left input[0] negative *and* input[1] through input[9]
were all zero. In that case, input[1] is now 2^25 - 1, and this
last borrow-propagation step will leave input[1] non-negative.
*/
If input[0] was negative after the first pass, then it was because of a
carry from input[9]. On entry, input[9] < 2^26 so the carry was, at most,
one, since (2**26-1) >> 25 = 1. Thus input[0] >= -19.
In the second pass, each limb is decreased by at most one. Thus the second
borrow-propagation pass could only have wrapped around to decrease
input[0] again if the first pass left input[0] negative *and* input[1]
through input[9] were all zero. In that case, input[1] is now 2^25 - 1,
and this last borrow-propagation step will leave input[1] non-negative. */
{
const s32 mask = (s32)(input[0]) >> 31;
const s32 carry = -(((s32)(input[0]) & mask) >> 26);
input[0] = (s32)(input[0]) + (carry << 26);
input[1] = (s32)(input[1]) - carry;
const s32 mask = input[0] >> 31;
const s32 carry = -((input[0] & mask) >> 26);
input[0] = input[0] + (carry << 26);
input[1] = input[1] - carry;
}
/* Both passes through the above loop, plus the last 0-to-1 step, are
necessary: if input[9] is -1 and input[0] through input[8] are 0,
negative values will remain in the array until the end.
*/
/* All input[i] are now non-negative. However, there might be values between
* 2^25 and 2^26 in a limb which is, nominally, 25 bits wide. */
for (j = 0; j < 2; j++) {
for (i = 0; i < 9; i++) {
if ((i & 1) == 1) {
const s32 carry = input[i] >> 25;
input[i] &= 0x1ffffff;
input[i+1] += carry;
} else {
const s32 carry = input[i] >> 26;
input[i] &= 0x3ffffff;
input[i+1] += carry;
}
}
{
const s32 carry = input[9] >> 25;
input[9] &= 0x1ffffff;
input[0] += 19*carry;
}
}
/* If the first carry-chain pass, just above, ended up with a carry from
* input[9], and that caused input[0] to be out-of-bounds, then input[0] was
* < 2^26 + 2*19, because the carry was, at most, two.
*
* If the second pass carried from input[9] again then input[0] is < 2*19 and
* the input[9] -> input[0] carry didn't push input[0] out of bounds. */
/* It still remains the case that input might be between 2^255-19 and 2^255.
* In this case, input[1..9] must take their maximum value and input[0] must
* be >= (2^255-19) & 0x3ffffff, which is 0x3ffffed. */
mask = s32_gte(input[0], 0x3ffffed);
for (i = 1; i < 10; i++) {
if ((i & 1) == 1) {
mask &= s32_eq(input[i], 0x1ffffff);
} else {
mask &= s32_eq(input[i], 0x3ffffff);
}
}
/* mask is either 0xffffffff (if input >= 2^255-19) and zero otherwise. Thus
* this conditionally subtracts 2^255-19. */
input[0] -= mask & 0x3ffffed;
for (i = 1; i < 10; i++) {
if ((i & 1) == 1) {
input[i] -= mask & 0x1ffffff;
} else {
input[i] -= mask & 0x3ffffff;
}
}
input[1] <<= 2;
input[2] <<= 3;
@ -514,7 +629,9 @@ fcontract(u8 *output, limb *input) {
* x z: short form, destroyed
* xprime zprime: short form, destroyed
* qmqp: short form, preserved
*/
*
* On entry and exit, the absolute value of the limbs of all inputs and outputs
* are < 2^26. */
static void fmonty(limb *x2, limb *z2, /* output 2Q */
limb *x3, limb *z3, /* output Q + Q' */
limb *x, limb *z, /* input Q */
@ -525,43 +642,69 @@ static void fmonty(limb *x2, limb *z2, /* output 2Q */
memcpy(origx, x, 10 * sizeof(limb));
fsum(x, z);
fdifference(z, origx); // does x - z
/* |x[i]| < 2^27 */
fdifference(z, origx); /* does x - z */
/* |z[i]| < 2^27 */
memcpy(origxprime, xprime, sizeof(limb) * 10);
fsum(xprime, zprime);
/* |xprime[i]| < 2^27 */
fdifference(zprime, origxprime);
/* |zprime[i]| < 2^27 */
fproduct(xxprime, xprime, z);
/* |xxprime[i]| < 14*2^54: the largest product of two limbs will be <
* 2^(27+27) and fproduct adds together, at most, 14 of those products.
* (Approximating that to 2^58 doesn't work out.) */
fproduct(zzprime, x, zprime);
/* |zzprime[i]| < 14*2^54 */
freduce_degree(xxprime);
freduce_coefficients(xxprime);
/* |xxprime[i]| < 2^26 */
freduce_degree(zzprime);
freduce_coefficients(zzprime);
/* |zzprime[i]| < 2^26 */
memcpy(origxprime, xxprime, sizeof(limb) * 10);
fsum(xxprime, zzprime);
/* |xxprime[i]| < 2^27 */
fdifference(zzprime, origxprime);
/* |zzprime[i]| < 2^27 */
fsquare(xxxprime, xxprime);
/* |xxxprime[i]| < 2^26 */
fsquare(zzzprime, zzprime);
/* |zzzprime[i]| < 2^26 */
fproduct(zzprime, zzzprime, qmqp);
/* |zzprime[i]| < 14*2^52 */
freduce_degree(zzprime);
freduce_coefficients(zzprime);
/* |zzprime[i]| < 2^26 */
memcpy(x3, xxxprime, sizeof(limb) * 10);
memcpy(z3, zzprime, sizeof(limb) * 10);
fsquare(xx, x);
/* |xx[i]| < 2^26 */
fsquare(zz, z);
/* |zz[i]| < 2^26 */
fproduct(x2, xx, zz);
/* |x2[i]| < 14*2^52 */
freduce_degree(x2);
freduce_coefficients(x2);
/* |x2[i]| < 2^26 */
fdifference(zz, xx); // does zz = xx - zz
/* |zz[i]| < 2^27 */
memset(zzz + 10, 0, sizeof(limb) * 9);
fscalar_product(zzz, zz, 121665);
/* |zzz[i]| < 2^(27+17) */
/* No need to call freduce_degree here:
fscalar_product doesn't increase the degree of its input. */
freduce_coefficients(zzz);
/* |zzz[i]| < 2^26 */
fsum(zzz, xx);
/* |zzz[i]| < 2^27 */
fproduct(z2, zz, zzz);
/* |z2[i]| < 14*2^(26+27) */
freduce_degree(z2);
freduce_coefficients(z2);
/* |z2|i| < 2^26 */
}
/* Conditionally swap two reduced-form limb arrays if 'iswap' is 1, but leave
@ -572,8 +715,7 @@ static void fmonty(limb *x2, limb *z2, /* output 2Q */
* wrong results. Also, the two limb arrays must be in reduced-coefficient,
* reduced-degree form: the values in a[10..19] or b[10..19] aren't swapped,
* and all all values in a[0..9],b[0..9] must have magnitude less than
* INT32_MAX.
*/
* INT32_MAX. */
static void
swap_conditional(limb a[19], limb b[19], limb iswap) {
unsigned i;
@ -590,8 +732,7 @@ swap_conditional(limb a[19], limb b[19], limb iswap) {
*
* resultx/resultz: the x coordinate of the resulting curve point (short form)
* n: a little endian, 32-byte number
* q: a point of the curve (short form)
*/
* q: a point of the curve (short form) */
static void
cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) {
limb a[19] = {0}, b[19] = {1}, c[19] = {1}, d[19] = {0};
@ -709,7 +850,7 @@ crecip(limb *out, const limb *z) {
/* 2^255 - 21 */ fmul(out,t1,z11);
}
int curve25519_donna(u8 *, const u8 *, const u8 *);
int curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint);
int
curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) {
@ -726,7 +867,6 @@ curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) {
cmult(x, z, e, bp);
crecip(zmone, z);
fmul(z, x, zmone);
freduce_coefficients(z);
fcontract(mypublic, z);
return 0;
}

View File

@ -19,6 +19,7 @@
#include "circuitbuild.h"
#include "circuitlist.h"
#include "circuitstats.h"
#include "config.h"
#include "connection_or.h" /* For var_cell_free() */
#include "circuitmux.h"
#include "entrynodes.h"
@ -3277,9 +3278,9 @@ channel_dump_statistics(channel_t *chan, int severity)
" is %s, and gives a canonical description of \"%s\" and an "
"actual description of \"%s\"",
U64_PRINTF_ARG(chan->global_identifier),
remote_addr_str,
channel_get_canonical_remote_descr(chan),
actual);
safe_str(remote_addr_str),
safe_str(channel_get_canonical_remote_descr(chan)),
safe_str(actual));
tor_free(remote_addr_str);
tor_free(actual);
} else {

View File

@ -183,6 +183,8 @@ get_unique_circ_id_by_chan(channel_t *chan)
if (0)
circuitmux_assert_okay(chan->cmux);
channel_dump_statistics(chan, LOG_WARN);
return 0;
}

View File

@ -783,6 +783,10 @@ circuit_expire_building(void)
}
}
/** For debugging #8387: track when we last called
* circuit_expire_old_circuits_clientside. */
static time_t last_expired_clientside_circuits = 0;
/**
* As a diagnostic for bug 8387, log information about how many one-hop
* circuits we have around that have been there for at least <b>age</b>
@ -894,6 +898,10 @@ circuit_log_ancient_one_hop_circuits(int age)
}
} SMARTLIST_FOREACH_END(ocirc);
log_notice(LD_HEARTBEAT, "It has been %ld seconds since I last called "
"circuit_expire_old_circuits_clientside().",
(long)(now - last_expired_clientside_circuits));
done:
smartlist_free(log_these);
}
@ -1089,7 +1097,6 @@ circuit_predict_and_launch_new(void)
void
circuit_build_needed_circs(time_t now)
{
static time_t time_to_new_circuit = 0;
const or_options_t *options = get_options();
/* launch a new circ for any pending streams that need one */
@ -1098,14 +1105,34 @@ circuit_build_needed_circs(time_t now)
/* make sure any hidden services have enough intro points */
rend_services_introduce();
if (time_to_new_circuit < now) {
circuit_expire_old_circs_as_needed(now);
if (!options->DisablePredictedCircuits)
circuit_predict_and_launch_new();
}
/**
* Called once a second either directly or from
* circuit_build_needed_circs(). As appropriate (once per NewCircuitPeriod)
* resets failure counts and expires old circuits.
*/
void
circuit_expire_old_circs_as_needed(time_t now)
{
static time_t time_to_expire_and_reset = 0;
if (time_to_expire_and_reset < now) {
circuit_reset_failure_count(1);
time_to_new_circuit = now + options->NewCircuitPeriod;
time_to_expire_and_reset = now + get_options()->NewCircuitPeriod;
if (proxy_mode(get_options()))
addressmap_clean(now);
circuit_expire_old_circuits_clientside();
#if 0 /* disable for now, until predict-and-launch-new can cull leftovers */
/* If we ever re-enable, this has to move into
* circuit_build_needed_circs */
circ = circuit_get_youngest_clean_open(CIRCUIT_PURPOSE_C_GENERAL);
if (get_options()->RunTesting &&
circ &&
@ -1115,8 +1142,6 @@ circuit_build_needed_circs(time_t now)
}
#endif
}
if (!options->DisablePredictedCircuits)
circuit_predict_and_launch_new();
}
/** If the stream <b>conn</b> is a member of any of the linked
@ -1203,6 +1228,7 @@ circuit_expire_old_circuits_clientside(void)
tor_gettimeofday(&now);
cutoff = now;
last_expired_clientside_circuits = now.tv_sec;
if (! circuit_build_times_disabled() &&
circuit_build_times_needs_circuits(get_circuit_build_times())) {

View File

@ -22,6 +22,7 @@ int circuit_conforms_to_options(const origin_circuit_t *circ,
const or_options_t *options);
#endif
void circuit_build_needed_circs(time_t now);
void circuit_expire_old_circs_as_needed(time_t now);
void circuit_detach_stream(circuit_t *circ, edge_connection_t *conn);
void circuit_expire_old_circuits_serverside(time_t now);

View File

@ -147,7 +147,7 @@ static config_var_t option_vars_[] = {
V(AuthDirInvalid, LINELIST, NULL),
V(AuthDirInvalidCCs, CSV, ""),
V(AuthDirFastGuarantee, MEMUNIT, "100 KB"),
V(AuthDirGuardBWGuarantee, MEMUNIT, "250 KB"),
V(AuthDirGuardBWGuarantee, MEMUNIT, "2 MB"),
V(AuthDirReject, LINELIST, NULL),
V(AuthDirRejectCCs, CSV, ""),
V(AuthDirRejectUnlisted, BOOL, "0"),
@ -325,7 +325,7 @@ static config_var_t option_vars_[] = {
VAR("NodeFamily", LINELIST, NodeFamilies, NULL),
V(NumCPUs, UINT, "0"),
V(NumDirectoryGuards, UINT, "0"),
V(NumEntryGuards, UINT, "3"),
V(NumEntryGuards, UINT, "0"),
V(ORListenAddress, LINELIST, NULL),
VPORT(ORPort, LINELIST, NULL),
V(OutboundBindAddress, LINELIST, NULL),
@ -3251,9 +3251,6 @@ options_validate(or_options_t *old_options, or_options_t *options,
"have it group-readable.");
}
if (options->UseEntryGuards && ! options->NumEntryGuards)
REJECT("Cannot enable UseEntryGuards with NumEntryGuards set to 0");
if (options->MyFamily && options->BridgeRelay) {
log_warn(LD_CONFIG, "Listing a family for a bridge relay is not "
"supported: it can reveal bridge fingerprints to censors. "

View File

@ -2650,14 +2650,6 @@ record_num_bytes_transferred(connection_t *conn,
}
#endif
#ifndef USE_BUFFEREVENTS
/** Last time at which the global or relay buckets were emptied in msec
* since midnight. */
static uint32_t global_relayed_read_emptied = 0,
global_relayed_write_emptied = 0,
global_read_emptied = 0,
global_write_emptied = 0;
/** Helper: convert given <b>tvnow</b> time value to milliseconds since
* midnight. */
static uint32_t
@ -2667,6 +2659,28 @@ msec_since_midnight(const struct timeval *tvnow)
((uint32_t)tvnow->tv_usec / (uint32_t)1000L));
}
/** Helper: return the time in milliseconds since <b>last_empty_time</b>
* when a bucket ran empty that previously had <b>tokens_before</b> tokens
* now has <b>tokens_after</b> tokens after refilling at timestamp
* <b>tvnow</b>, capped at <b>milliseconds_elapsed</b> milliseconds since
* last refilling that bucket. Return 0 if the bucket has not been empty
* since the last refill or has not been refilled. */
uint32_t
bucket_millis_empty(int tokens_before, uint32_t last_empty_time,
int tokens_after, int milliseconds_elapsed,
const struct timeval *tvnow)
{
uint32_t result = 0, refilled;
if (tokens_before <= 0 && tokens_after > tokens_before) {
refilled = msec_since_midnight(tvnow);
result = (uint32_t)((refilled + 86400L * 1000L - last_empty_time) %
(86400L * 1000L));
if (result > (uint32_t)milliseconds_elapsed)
result = (uint32_t)milliseconds_elapsed;
}
return result;
}
/** Check if a bucket which had <b>tokens_before</b> tokens and which got
* <b>tokens_removed</b> tokens removed at timestamp <b>tvnow</b> has run
* out of tokens, and if so, note the milliseconds since midnight in
@ -2680,6 +2694,14 @@ connection_buckets_note_empty_ts(uint32_t *timestamp_var,
*timestamp_var = msec_since_midnight(tvnow);
}
#ifndef USE_BUFFEREVENTS
/** Last time at which the global or relay buckets were emptied in msec
* since midnight. */
static uint32_t global_relayed_read_emptied = 0,
global_relayed_write_emptied = 0,
global_read_emptied = 0,
global_write_emptied = 0;
/** We just read <b>num_read</b> and wrote <b>num_written</b> bytes
* onto <b>conn</b>. Decrement buckets appropriately. */
static void
@ -2838,28 +2860,6 @@ connection_bucket_refill_helper(int *bucket, int rate, int burst,
}
}
/** Helper: return the time in milliseconds since <b>last_empty_time</b>
* when a bucket ran empty that previously had <b>tokens_before</b> tokens
* now has <b>tokens_after</b> tokens after refilling at timestamp
* <b>tvnow</b>, capped at <b>milliseconds_elapsed</b> milliseconds since
* last refilling that bucket. Return 0 if the bucket has not been empty
* since the last refill or has not been refilled. */
uint32_t
bucket_millis_empty(int tokens_before, uint32_t last_empty_time,
int tokens_after, int milliseconds_elapsed,
const struct timeval *tvnow)
{
uint32_t result = 0, refilled;
if (tokens_before <= 0 && tokens_after > tokens_before) {
refilled = msec_since_midnight(tvnow);
result = (uint32_t)((refilled + 86400L * 1000L - last_empty_time) %
(86400L * 1000L));
if (result > (uint32_t)milliseconds_elapsed)
result = (uint32_t)milliseconds_elapsed;
}
return result;
}
/** Time has passed; increment buckets appropriately. */
void
connection_bucket_refill(int milliseconds_elapsed, time_t now)

0
src/or/control.c Executable file → Normal file
View File

View File

@ -1588,7 +1588,7 @@ dirserv_compute_performance_thresholds(routerlist_t *rl,
/* (Now bandwidths is sorted.) */
if (fast_bandwidth_kb < ROUTER_REQUIRED_MIN_BANDWIDTH/(2 * 1000))
fast_bandwidth_kb = bandwidths_kb[n_active/4];
guard_bandwidth_including_exits_kb = bandwidths_kb[(n_active-1)/2];
guard_bandwidth_including_exits_kb = bandwidths_kb[n_active*3/4];
guard_tk = find_nth_long(tks, n_active, n_active/8);
}
@ -1646,7 +1646,8 @@ dirserv_compute_performance_thresholds(routerlist_t *rl,
if (n_active_nonexit) {
guard_bandwidth_excluding_exits_kb =
median_uint32(bandwidths_excluding_exits_kb, n_active_nonexit);
find_nth_uint32(bandwidths_excluding_exits_kb,
n_active_nonexit, n_active_nonexit*3/4);
}
log_info(LD_DIRSERV,

View File

@ -440,9 +440,20 @@ add_an_entry_guard(const node_t *chosen, int reset_status, int prepend,
static int
decide_num_guards(const or_options_t *options, int for_directory)
{
if (for_directory && options->NumDirectoryGuards != 0)
return options->NumDirectoryGuards;
return options->NumEntryGuards;
if (for_directory) {
int answer;
if (options->NumDirectoryGuards != 0)
return options->NumDirectoryGuards;
answer = networkstatus_get_param(NULL, "NumDirectoryGuards", 0, 0, 10);
if (answer) /* non-zero means use the consensus value */
return answer;
}
if (options->NumEntryGuards)
return options->NumEntryGuards;
/* Use the value from the consensus, or 3 if no guidance. */
return networkstatus_get_param(NULL, "NumEntryGuards", 3, 1, 10);
}
/** If the use of entry guards is configured, choose more entry guards
@ -841,6 +852,7 @@ entry_guards_set_from_config(const or_options_t *options)
{
smartlist_t *entry_nodes, *worse_entry_nodes, *entry_fps;
smartlist_t *old_entry_guards_on_list, *old_entry_guards_not_on_list;
const int numentryguards = decide_num_guards(options, 0);
tor_assert(entry_guards);
should_add_entry_nodes = 0;
@ -909,7 +921,7 @@ entry_guards_set_from_config(const or_options_t *options)
/* Next, the rest of EntryNodes */
SMARTLIST_FOREACH_BEGIN(entry_nodes, const node_t *, node) {
add_an_entry_guard(node, 0, 0, 1, 0);
if (smartlist_len(entry_guards) > options->NumEntryGuards * 10)
if (smartlist_len(entry_guards) > numentryguards * 10)
break;
} SMARTLIST_FOREACH_END(node);
log_notice(LD_GENERAL, "%d entries in guards", smartlist_len(entry_guards));

View File

@ -1512,8 +1512,11 @@ run_scheduled_events(time_t now)
* and we make a new circ if there are no clean circuits.
*/
have_dir_info = router_have_minimum_dir_info();
if (have_dir_info && !net_is_disabled())
if (have_dir_info && !net_is_disabled()) {
circuit_build_needed_circs(now);
} else {
circuit_expire_old_circs_as_needed(now);
}
/* every 10 seconds, but not at the same second as other such events */
if (now % 10 == 5)

0
src/or/router.c Executable file → Normal file
View File

View File

@ -97,16 +97,25 @@ dummy_edge_conn_new(circuit_t *circ,
int type, size_t in_bytes, size_t out_bytes)
{
edge_connection_t *conn;
generic_buffer_t *inbuf, *outbuf;
if (type == CONN_TYPE_EXIT)
conn = edge_connection_new(type, AF_INET);
else
conn = ENTRY_TO_EDGE_CONN(entry_connection_new(type, AF_INET));
#ifdef USE_BUFFEREVENTS
inbuf = bufferevent_get_input(TO_CONN(conn)->bufev);
outbuf = bufferevent_get_output(TO_CONN(conn)->bufev);
#else
inbuf = TO_CONN(conn)->inbuf;
outbuf = TO_CONN(conn)->outbuf;
#endif
/* We add these bytes directly to the buffers, to avoid all the
* edge connection read/write machinery. */
add_bytes_to_buf(TO_CONN(conn)->inbuf, in_bytes);
add_bytes_to_buf(TO_CONN(conn)->outbuf, out_bytes);
add_bytes_to_buf(inbuf, in_bytes);
add_bytes_to_buf(outbuf, out_bytes);
conn->on_circuit = circ;
if (type == CONN_TYPE_EXIT) {