summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--ChangeLog23
-rw-r--r--Doxyfile.in1
-rw-r--r--Makefile.am1
-rw-r--r--acinclude.m41
-rw-r--r--configure.in7
-rwxr-xr-xcontrib/checkOptionDocs.pl1
-rwxr-xr-xcontrib/checkSpace.pl5
-rwxr-xr-xcontrib/cross.sh1
-rw-r--r--contrib/id_to_fp.c1
-rwxr-xr-xcontrib/nagios-check-tor-authority-cert2
-rw-r--r--contrib/osx/package.sh1
-rw-r--r--contrib/polipo/package.sh1
-rw-r--r--contrib/rc.subr1
-rw-r--r--contrib/tor-mingw.nsi.in2
-rwxr-xr-xcontrib/tor-resolve.py1
-rw-r--r--contrib/torify.118
-rwxr-xr-xcontrib/torify.in65
-rw-r--r--doc/HACKING8
-rw-r--r--doc/TODO.0211
-rw-r--r--doc/TODO.02253
-rw-r--r--doc/TODO.external14
-rw-r--r--doc/TODO.future1
-rw-r--r--doc/design-paper/latex8.bst2
-rw-r--r--doc/design-paper/usenix.sty2
-rw-r--r--doc/spec/address-spec.txt1
-rw-r--r--doc/spec/bridges-spec.txt1
-rw-r--r--doc/spec/control-spec-v0.txt1
-rw-r--r--doc/spec/control-spec.txt11
-rw-r--r--doc/spec/dir-spec-v1.txt1
-rw-r--r--doc/spec/dir-spec-v2.txt1
-rw-r--r--doc/spec/dir-spec.txt1
-rw-r--r--doc/spec/path-spec.txt1
-rw-r--r--doc/spec/proposals/000-index.txt19
-rw-r--r--doc/spec/proposals/001-process.txt10
-rw-r--r--doc/spec/proposals/098-todo.txt2
-rw-r--r--doc/spec/proposals/099-misc.txt2
-rw-r--r--doc/spec/proposals/100-tor-spec-udp.txt2
-rw-r--r--doc/spec/proposals/101-dir-voting.txt2
-rw-r--r--doc/spec/proposals/102-drop-opt.txt2
-rw-r--r--doc/spec/proposals/103-multilevel-keys.txt2
-rw-r--r--doc/spec/proposals/104-short-descriptors.txt2
-rw-r--r--doc/spec/proposals/105-handshake-revision.txt2
-rw-r--r--doc/spec/proposals/106-less-tls-constraint.txt2
-rw-r--r--doc/spec/proposals/107-uptime-sanity-checking.txt2
-rw-r--r--doc/spec/proposals/108-mtbf-based-stability.txt2
-rw-r--r--doc/spec/proposals/109-no-sharing-ips.txt2
-rw-r--r--doc/spec/proposals/110-avoid-infinite-circuits.txt2
-rw-r--r--doc/spec/proposals/111-local-traffic-priority.txt2
-rw-r--r--doc/spec/proposals/112-bring-back-pathlencoinweight.txt2
-rw-r--r--doc/spec/proposals/113-fast-authority-interface.txt2
-rw-r--r--doc/spec/proposals/114-distributed-storage.txt2
-rw-r--r--doc/spec/proposals/115-two-hop-paths.txt2
-rw-r--r--doc/spec/proposals/116-two-hop-paths-from-guard.txt2
-rw-r--r--doc/spec/proposals/117-ipv6-exits.txt2
-rw-r--r--doc/spec/proposals/118-multiple-orports.txt2
-rw-r--r--doc/spec/proposals/119-controlport-auth.txt2
-rw-r--r--doc/spec/proposals/120-shutdown-descriptors.txt2
-rw-r--r--doc/spec/proposals/121-hidden-service-authentication.txt2
-rw-r--r--doc/spec/proposals/122-unnamed-flag.txt2
-rw-r--r--doc/spec/proposals/123-autonaming.txt2
-rw-r--r--doc/spec/proposals/124-tls-certificates.txt2
-rw-r--r--doc/spec/proposals/125-bridges.txt2
-rw-r--r--doc/spec/proposals/126-geoip-reporting.txt2
-rw-r--r--doc/spec/proposals/127-dirport-mirrors-downloads.txt2
-rw-r--r--doc/spec/proposals/128-bridge-families.txt2
-rw-r--r--doc/spec/proposals/129-reject-plaintext-ports.txt2
-rw-r--r--doc/spec/proposals/130-v2-conn-protocol.txt2
-rw-r--r--doc/spec/proposals/131-verify-tor-usage.txt2
-rw-r--r--doc/spec/proposals/132-browser-check-tor-service.txt2
-rw-r--r--doc/spec/proposals/134-robust-voting.txt22
-rw-r--r--doc/spec/proposals/135-private-tor-networks.txt2
-rw-r--r--doc/spec/proposals/137-bootstrap-phases.txt2
-rw-r--r--doc/spec/proposals/138-remove-down-routers-from-consensus.txt2
-rw-r--r--doc/spec/proposals/140-consensus-diffs.txt11
-rw-r--r--doc/spec/proposals/141-jit-sd-downloads.txt8
-rw-r--r--doc/spec/proposals/142-combine-intro-and-rend-points.txt2
-rw-r--r--doc/spec/proposals/143-distributed-storage-improvements.txt2
-rw-r--r--doc/spec/proposals/145-newguard-flag.txt2
-rw-r--r--doc/spec/proposals/146-long-term-stability.txt2
-rw-r--r--doc/spec/proposals/147-prevoting-opinions.txt2
-rw-r--r--doc/spec/proposals/148-uniform-client-end-reason.txt2
-rw-r--r--doc/spec/proposals/149-using-netinfo-data.txt2
-rw-r--r--doc/spec/proposals/150-exclude-exit-nodes.txt1
-rw-r--r--doc/spec/proposals/151-path-selection-improvements.txt2
-rw-r--r--doc/spec/proposals/152-single-hop-circuits.txt2
-rw-r--r--doc/spec/proposals/153-automatic-software-update-protocol.txt2
-rw-r--r--doc/spec/proposals/154-automatic-updates.txt2
-rw-r--r--doc/spec/proposals/155-four-hidden-service-improvements.txt2
-rw-r--r--doc/spec/proposals/156-tracking-blocked-ports.txt2
-rw-r--r--doc/spec/proposals/157-specific-cert-download.txt2
-rw-r--r--doc/spec/proposals/158-microdescriptors.txt167
-rw-r--r--doc/spec/proposals/159-exit-scanning.txt2
-rw-r--r--doc/spec/proposals/160-bandwidth-offset.txt105
-rw-r--r--doc/spec/proposals/161-computing-bandwidth-adjustments.txt188
-rw-r--r--doc/spec/proposals/162-consensus-flavors.txt178
-rw-r--r--doc/spec/proposals/163-detecting-clients.txt115
-rw-r--r--doc/spec/proposals/164-reporting-server-status.txt91
-rw-r--r--doc/spec/proposals/165-simple-robust-voting.txt119
-rw-r--r--doc/spec/proposals/ideas/xxx-bwrate-algs.txt106
-rw-r--r--doc/spec/proposals/ideas/xxx-choosing-crypto-in-tor-protocol.txt138
-rw-r--r--doc/spec/proposals/ideas/xxx-encrypted-services.txt18
-rw-r--r--doc/spec/proposals/ideas/xxx-hide-platform.txt2
-rw-r--r--doc/spec/proposals/ideas/xxx-port-knocking.txt2
-rw-r--r--doc/spec/proposals/ideas/xxx-separate-streams-by-port.txt2
-rw-r--r--doc/spec/proposals/ideas/xxx-what-uses-sha1.txt139
-rwxr-xr-xdoc/spec/proposals/reindex.py2
-rw-r--r--doc/spec/rend-spec.txt111
-rw-r--r--doc/spec/socks-extensions.txt1
-rw-r--r--doc/spec/tor-spec.txt1
-rw-r--r--doc/spec/version-spec.txt1
-rw-r--r--src/common/Makefile.am16
-rw-r--r--src/common/ht.h4
-rw-r--r--src/common/memarea.c37
-rw-r--r--src/common/util.h2
-rw-r--r--src/common/util_codedigest.c11
-rw-r--r--src/config/torrc.complete.in2
-rw-r--r--src/or/Makefile.am20
-rw-r--r--src/or/circuitbuild.c30
-rw-r--r--src/or/circuituse.c5
-rw-r--r--src/or/config.c18
-rw-r--r--src/or/config_codedigest.c11
-rw-r--r--src/or/connection.c15
-rw-r--r--src/or/connection_edge.c10
-rw-r--r--src/or/control.c322
-rw-r--r--src/or/directory.c25
-rw-r--r--src/or/dirserv.c12
-rw-r--r--src/or/dns.c24
-rw-r--r--src/or/eventdns.c76
-rw-r--r--src/or/geoip.c65
-rw-r--r--src/or/main.c11
-rw-r--r--src/or/or.h39
-rw-r--r--src/or/relay.c4
-rw-r--r--src/or/rendclient.c4
-rw-r--r--src/or/rendcommon.c55
-rw-r--r--src/or/rendservice.c217
-rw-r--r--src/or/router.c7
-rw-r--r--src/or/test.c87
-rw-r--r--src/win32/orconfig.h2
-rw-r--r--tor.spec.in17
140 files changed, 1889 insertions, 1155 deletions
diff --git a/.gitignore b/.gitignore
index 46917c311f..6eacae932d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -108,6 +108,7 @@
# /src/common/
/src/common/Makefile
/src/common/Makefile.in
+/src/common/common_sha1.i
/src/common/libor.a
/src/common/libor-crypto.a
@@ -121,6 +122,7 @@
# /src/or/
/src/or/Makefile
/src/or/Makefile.in
+/src/or/or_sha1.i
/src/or/micro-revision.*
/src/or/tor
/src/or/test
diff --git a/ChangeLog b/ChangeLog
index ef12f4385d..c279c9b17b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+Changes in version 0.2.2.1-alpha - 2009-??-??
+ o Minor features
+ - New --digests command-line switch to output the digests of the
+ source files Tor was built with.
+ - The "torify" script now uses torsocks where available.
+ - The memarea code now uses a sentinel value at the end of each area
+ to make sure nothing writes beyond the end of an area. This might
+ help debug some conceivable causes of bug 930.
+ - Directories that are configured with the --enable-geoip-stats flag
+ now write their GeoIP stats to disk exactly every 24 hours.
+
+ o Deprecated and removed features:
+ - The controller no longer accepts the old obsolete "addr-mappings/"
+ GETINFO value.
+ - Hidden services no longer publish version 0 descriptors, and clients
+ do not request or use version 0 descriptors. However, the authorities
+ still accept and serve version 0 descriptors when contacted by older
+ hidden services/clients.
+ - The EXTENDED_EVENTS and VERBOSE_NAMES controller features are now
+ always on; using them is necessary for correct forward-compatible
+ controllers.
+
+
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
diff --git a/Doxyfile.in b/Doxyfile.in
index b4d21c334d..24355f5f04 100644
--- a/Doxyfile.in
+++ b/Doxyfile.in
@@ -1,4 +1,3 @@
-# $Id$
# Doxyfile 1.5.1
# This file describes the settings to be used by the documentation system
diff --git a/Makefile.am b/Makefile.am
index b6e559ef0c..d4ebbb1fda 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,3 @@
-# $Id$
# Copyright (c) 2001-2004, Roger Dingledine
# Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson
# Copyright (c) 2007-2008, The Tor Project, Inc.
diff --git a/acinclude.m4 b/acinclude.m4
index 47d421c260..766ca1e62e 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -1,4 +1,3 @@
-dnl $Id$
dnl Helper macros for Tor configure.in
dnl Copyright (c) 2001-2004, Roger Dingledine
dnl Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson
diff --git a/configure.in b/configure.in
index ceca53f078..8a4101f41d 100644
--- a/configure.in
+++ b/configure.in
@@ -1,11 +1,10 @@
-dnl $Id$
dnl Copyright (c) 2001-2004, Roger Dingledine
dnl Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson
dnl Copyright (c) 2007-2008, The Tor Project, Inc.
dnl See LICENSE for licensing information
AC_INIT
-AM_INIT_AUTOMAKE(tor, 0.2.1.15-rc-dev)
+AM_INIT_AUTOMAKE(tor, 0.2.2.0-alpha-dev)
AM_CONFIG_HEADER(orconfig.h)
AC_CANONICAL_HOST
@@ -107,6 +106,10 @@ AC_PROG_CC
AC_PROG_CPP
AC_PROG_MAKE_SET
AC_PROG_RANLIB
+AC_PROG_SED
+
+AC_PATH_PROG([SHA1SUM], [sha1sum], none)
+AC_PATH_PROG([OPENSSL], [openssl], none)
TORUSER=_tor
AC_ARG_WITH(tor-user,
diff --git a/contrib/checkOptionDocs.pl b/contrib/checkOptionDocs.pl
index ca3fba55e3..c2e8757362 100755
--- a/contrib/checkOptionDocs.pl
+++ b/contrib/checkOptionDocs.pl
@@ -1,5 +1,4 @@
#!/usr/bin/perl -w
-# $Id
use strict;
my %options = ();
diff --git a/contrib/checkSpace.pl b/contrib/checkSpace.pl
index 37f079c52b..db061a0828 100755
--- a/contrib/checkSpace.pl
+++ b/contrib/checkSpace.pl
@@ -42,9 +42,8 @@ for $fn (@ARGV) {
$lastnil = 0;
}
## Terminals are still 80 columns wide in my world. I refuse to
- ## accept double-line lines. Except, of course, svn Id tags
- ## can make us go long.
- if (/^.{80}/ && !/\$Id: /) {
+ ## accept double-line lines.
+ if (/^.{80}/) {
print " Wide:$fn:$.\n";
}
### Juju to skip over comments and strings, since the tests
diff --git a/contrib/cross.sh b/contrib/cross.sh
index e660be780d..af68755dbf 100755
--- a/contrib/cross.sh
+++ b/contrib/cross.sh
@@ -1,5 +1,4 @@
#!/bin/bash
-# $Id$
# Copyright 2006 Michael Mohr with modifications by Roger Dingledine
# See LICENSE for licensing information.
diff --git a/contrib/id_to_fp.c b/contrib/id_to_fp.c
index 73395e16c1..55b025dfaf 100644
--- a/contrib/id_to_fp.c
+++ b/contrib/id_to_fp.c
@@ -1,5 +1,4 @@
/* Copyright 2006 Nick Mathewson; see LICENSE for licensing information */
-/* $Id$ */
/* id_to_fp.c : Helper for directory authority ops. When somebody sends us
* a private key, this utility converts the private key into a fingerprint
diff --git a/contrib/nagios-check-tor-authority-cert b/contrib/nagios-check-tor-authority-cert
index 0e2c1d06c4..46dc7284b7 100755
--- a/contrib/nagios-check-tor-authority-cert
+++ b/contrib/nagios-check-tor-authority-cert
@@ -8,8 +8,6 @@
# Usage: nagios-check-tor-authority-cert <authority identity fingerprint>
# e.g.: nagios-check-tor-authority-cert A9AC67E64B200BBF2FA26DF194AC0469E2A948C6
-# $Id$
-
# Copyright (c) 2008 Peter Palfrader <peter@palfrader.org>
#
# Permission is hereby granted, free of charge, to any person obtaining
diff --git a/contrib/osx/package.sh b/contrib/osx/package.sh
index 040c7cd4c9..eeb0f95078 100644
--- a/contrib/osx/package.sh
+++ b/contrib/osx/package.sh
@@ -1,5 +1,4 @@
#!/bin/sh
-# $Id$
# Copyright 2004-2005 Nick Mathewson.
# Copyright 2005-2007 Andrew Lewman
# Copyright 2008 The Tor Project, Inc.
diff --git a/contrib/polipo/package.sh b/contrib/polipo/package.sh
index 83f74212be..4ec72c81d8 100644
--- a/contrib/polipo/package.sh
+++ b/contrib/polipo/package.sh
@@ -1,5 +1,4 @@
#!/bin/sh
-# $Id: package.sh 8992 2006-12-23 03:12:09Z phobos $
# Copyright 2004-2005 Nick Mathewson & Andrew Lewman.
# Copyright 2005-2008 Andrew Lewman
# This is licensed under the Modified BSD License.
diff --git a/contrib/rc.subr b/contrib/rc.subr
index 117ae71d47..d757e89528 100644
--- a/contrib/rc.subr
+++ b/contrib/rc.subr
@@ -1,5 +1,4 @@
#!/bin/sh
-# $Id$
# $FreeBSD: ports/security/tor-devel/files/tor.in,v 1.1 2006/02/17 22:21:25 mnag Exp $
#
# (rc.subr written by Peter Thoenen for Net/FreeBSD)
diff --git a/contrib/tor-mingw.nsi.in b/contrib/tor-mingw.nsi.in
index 5d67768f6f..b8c4bec5d1 100644
--- a/contrib/tor-mingw.nsi.in
+++ b/contrib/tor-mingw.nsi.in
@@ -9,7 +9,7 @@
!include "FileFunc.nsh"
!insertmacro GetParameters
-!define VERSION "0.2.1.15-rc-dev"
+!define VERSION "0.2.2.0-alpha-dev"
!define INSTALLER "tor-${VERSION}-win32.exe"
!define WEBSITE "https://www.torproject.org/"
!define LICENSE "LICENSE"
diff --git a/contrib/tor-resolve.py b/contrib/tor-resolve.py
index 919bc876cc..47ae1a0c38 100755
--- a/contrib/tor-resolve.py
+++ b/contrib/tor-resolve.py
@@ -1,5 +1,4 @@
#!/usr/bin/python
-#$Id$
import socket
import struct
diff --git a/contrib/torify.1 b/contrib/torify.1
index b08d468451..9ae4e40d9d 100644
--- a/contrib/torify.1
+++ b/contrib/torify.1
@@ -1,22 +1,27 @@
.TH torify 1 "" Jan-2009 ""
-.\" manual page by Peter Palfrader
+.\" manual page by Peter Palfrader and Jacob Appelbaum
.SH NAME
.LP
-torify \- wrapper for tsocks and tor
+torify \- wrapper for torsocks or tsocks and tor
.SH SYNOPSIS
\fBtorify\fP\ \fIapplication\fP\ [\fIapplication's\ arguments\fP]
.SH DESCRIPTION
-\fBtorify\fR is a simple wrapper that calls tsocks with a tor specific
+\fBtorify\fR is a simple wrapper that attempts to find the best underlying Tor
+wrapper available on a system. It calls torsocks or tsocks with a tor specific
configuration file.
+torsocks is an improved wrapper that explictly rejects UDP, safely resolves DNS
+lookups and properly socksifies your TCP connections.
+
tsocks itself is a wrapper between the tsocks library and the application
that you would like to run socksified.
-Please note that since tsocks uses LD_PRELOAD, torify cannot be applied
+Please note that since both method use LD_PRELOAD, torify cannot be applied
to suid binaries.
+.SH WARNING
You should also be aware that the way tsocks currently works only TCP
connections are socksified. Be aware that this will in most circumstances
not include hostname lookups which would still be routed through your
@@ -25,8 +30,13 @@ normal system resolver to your usual resolving nameservers. The
The Tor FAQ at https://wiki.torproject.org/noreply/TheOnionRouter/TorFAQ might
have further information on this subject.
+When used with torsocks, torify should not leak DNS requests or UDP data.
+
+Both will leak ICMP data.
+
.SH SEE ALSO
.BR tor (1),
.BR tor-resolve (1),
+.BR torsocks (1),
.BR tsocks (1),
.BR tsocks.conf (5).
diff --git a/contrib/torify.in b/contrib/torify.in
index 05645fd07c..6b1e440dc1 100755
--- a/contrib/torify.in
+++ b/contrib/torify.in
@@ -10,36 +10,67 @@
# Define and ensure we have tsocks
# XXX: what if we don't have which?
+TORSOCKS="`which torsocks`"
TSOCKS="`which tsocks`"
+PROG=""
if [ ! -x "$TSOCKS" ]
then
- echo "$0: Can't find tsocks in PATH. Perhaps you haven't installed it?" >&2
- exit 1
+ echo "$0: Can't find tsocks in PATH. Perhaps you haven't installed it?" >&2
+else
+ PROG=$TSOCKS
+fi
+if [ ! -x "$TORSOCKS" ]
+then
+ echo "$0: Can't find torsocks in PATH. Perhaps you haven't installed it?" >&2
+else
+ PROG=$TORSOCKS
+fi
+
+if [ ! -x "$PROG" ]
+then
+ echo "$0: Can't find the required tor helpers in our PATH. Perhaps you haven't installed them?" >&2
+ exit 1;
fi
# Check for any argument list
if [ "$#" = 0 ]
then
- echo "Usage: $0 <command> [<options>...]" >&2
- exit 1
+ echo "Usage: $0 [-hv] <command> [<options>...]" >&2
+ exit 1
fi
if [ "$#" = 1 ] && ( [ "$1" = "-h" ] || [ "$1" = "--help" ] )
then
- echo "Usage: $0 <command> [<options>...]"
- exit 0
+ echo "Usage: $0 [-hv] <command> [<options>...]"
+ exit 0
fi
-# Define our tsocks config file
-TSOCKS_CONF_FILE="@CONFDIR@/tor-tsocks.conf"
-export TSOCKS_CONF_FILE
+if [ "$1" = "-v" ] || [ "$1" = "--verbose" ]
+then
+ echo "We're armed with the following tsocks: $TSOCKS"
+ echo "We're armed with the following torsocks: $TORSOCKS"
+ echo "We're attempting to use $PROG for all tor action."
+ shift 1
+fi
-# Check that we've got a tsocks config file
-if [ -r "$TSOCKS_CONF_FILE" ]
+if [ "$PROG" == "$TSOCKS" ]
then
- exec tsocks "$@"
- echo "$0: Failed to exec tsocks $@" >&2
- exit 1
-else
- echo "$0: Missing tsocks configuration file \"$TSOCKS_CONF_FILE\"." >&2
- exit 1
+ # Define our tsocks config file
+ TSOCKS_CONF_FILE="/etc/tor/tor-tsocks.conf"
+ export TSOCKS_CONF_FILE
+
+ # Check that we've got a tsocks config file
+ if [ -r "$TSOCKS_CONF_FILE" ]
+ then
+ echo "WARNING: tsocks is known to leak DNS and UDP data." >&2
+ exec tsocks "$@"
+ echo "$0: Failed to exec tsocks $@" >&2
+ exit 1
+ else
+ echo "$0: Missing tsocks configuration file \"$TSOCKS_CONF_FILE\"." >&2
+ exit 1
+ fi
+fi
+if [ "$PROG" == "$TORSOCKS" ]
+then
+ exec torsocks "$@"
fi
diff --git a/doc/HACKING b/doc/HACKING
index 50b5d80d18..3d3f2c1dfc 100644
--- a/doc/HACKING
+++ b/doc/HACKING
@@ -11,12 +11,20 @@
0.1. Useful command-lines that are non-trivial to reproduce but can
help with tracking bugs or leaks.
+0.1.1. Dmalloc
+
dmalloc -l ~/dmalloc.log
(run the commands it tells you)
./configure --with-dmalloc
+0.2.2. Valgrind
+
valgrind --leak-check=yes --error-limit=no --show-reachable=yes src/or/tor
+(Note that if you get a zillion openssl warnings, you will also need to
+ pass --undef-value-errors=no to valgrind, or rebuild your openssl
+ with -DPURIFY.)
+
0.2. Running gcov for unit test coverage
make clean
diff --git a/doc/TODO.021 b/doc/TODO.021
index 881ba5ee4b..37c5b9845b 100644
--- a/doc/TODO.021
+++ b/doc/TODO.021
@@ -1,4 +1,3 @@
-$Id$
Legend:
SPEC!! - Not specified
SPEC - Spec not finalized
diff --git a/doc/TODO.022 b/doc/TODO.022
index 3eeae006cb..a0644f1af8 100644
--- a/doc/TODO.022
+++ b/doc/TODO.022
@@ -8,10 +8,12 @@ NOTE 2: It's easy to list stuff like this with no time estimates and
0.2.2, figure out how long the stuff we want will take, and
triage accordingly, or vice versa.
-- Design
+- Design only
- Begin design work for UDP transition; identify areas where we need to
make changes or instrument stuff early.
+ [multiple weeks, ongoing. Need to do a draft early.]
+
- Performance, mostly protocol-neutral.
- Work with Libevent 2.0's bufferevent interface
- Identify any performance stuff we need to push back into
@@ -30,14 +32,33 @@ NOTE 2: It's easy to list stuff like this with no time estimates and
- Figure out good ways to instrument Tor internals so we can tell
how well our bandwidth and flow-control stuff is actually working.
+ - What ports eat the bandwidth?
+ - How full do queues get?
+ - How much latency do queues get?
+
+ - Rate limit at clients:
+ - Give clients an upper bound on how much they're willing to use
+ the network if they're not relaying?
+ - ... or group client circuits by IP at the server and rate-limit
+ like that.
+
-- Features
+
+- Other features
- Proposals to implement:
- - 146: reflect long-term stability
+ - 146: reflect long-term stability in consensuses
- 147: Stop using v2 directories to generate v3 votes.
+ - Start pinging as soon as we learn about a relay, not on a
+ 22-minute cycle. Prioritize new and volatile relays for
+ testing.
- Proposals to improve and implement
- 158: microdescriptors
+N - Revise proposal
+ - 160: list bandwidth in consensus
+RNM? - Finish proposal
+ - and actually set it reasonably
+ - and actually use it.
- Proposals to improve and implement if not broken
- IPv6 support. (Parts of 117, but figure out how to handle DNS
@@ -46,6 +67,32 @@ NOTE 2: It's easy to list stuff like this with no time estimates and
- 149: learn info from netinfo cells.
- 134: handle authority fragmentation (Needs more analysis)
+ - Needs a proposal, or at least some design
+ - Detect client-status better
+N - Write proposal
+ - Have authorities report relay and voting status better: make it
+ easy to answer, "Why is my server not listed/not Guard/not
+ Running/etc"
+N - Write proposal
+ - Have consensuses come in multiple "flavours".
+N - Write proposal
+ - Weaken the requirements for being a Guard, based on K's
+ measurements.
+K - Finish measurements
+K? - Write proposal
+ - Adaptive timeouts for giving up on circuits and streams.
+M/N - Revise proposal 151
+ - Downweight guards more sensibly: be more forgiving about using
+ Guard nodes as non-first-hop.
+ - Write proposal.
+ - Lagged weight updates in consensuses: don't just move abruptly.
+M? - Write proposal
+ d Don't kill a circuit on the first failed extend.
+
+- Installers
+ - Switch to MSI on win32
+ - Use Thandy, perhaps?
+
- Deprecations
- Make .exit safe, or make it off-by-default.
diff --git a/doc/TODO.external b/doc/TODO.external
index c02d6aca54..12048fa344 100644
--- a/doc/TODO.external
+++ b/doc/TODO.external
@@ -1,4 +1,3 @@
-$Id$
Legend:
SPEC!! - Not specified
SPEC - Spec not finalized
@@ -85,16 +84,9 @@ SM - 4.1, balance traffic better
(rejigger the bandwidth numbers at the authorities based on
Steven's algorithm), or Mike's plan (relay scanning to identify
the unbalanced relays and fix them on the fly), or both.
- - Figure out how to actually modify bandwidths in the consensus. We
- may need to change the consensus voting algorithm to decide what
- bandwidth to advertise based on something other than median:
- if 7 authorities provide bandwidths, and 2 are doing scanning,
- then the 5 that aren't scanning will outvote any changes. Should
- all 7 scan? Should only some vote? Extra points if it doesn't
- change all the numbers every new consensus, so consensus diffing
- is still practical.
-? - 4.5, Older entry guards are overloaded
- - Pick a conservative timeout like a month, and implement.
+ - Implement Proposal 160
+ o 4.5, Older entry guards are overloaded
+ o Pick a conservative timeout like a month, and implement.
M - 5.2, better timeouts for giving up on circuits/streams
- clients gather data about circuit timeouts, and then abandon
circuits that take more than a std dev above that.
diff --git a/doc/TODO.future b/doc/TODO.future
index 64169ecfec..a6cc95150e 100644
--- a/doc/TODO.future
+++ b/doc/TODO.future
@@ -1,4 +1,3 @@
-$Id$
Legend:
SPEC!! - Not specified
SPEC - Spec not finalized
diff --git a/doc/design-paper/latex8.bst b/doc/design-paper/latex8.bst
index 2dd3249633..bae8e209ee 100644
--- a/doc/design-paper/latex8.bst
+++ b/doc/design-paper/latex8.bst
@@ -1,8 +1,6 @@
% ---------------------------------------------------------------
%
-% $Id$
-%
% by Paolo.Ienne@di.epfl.ch
%
diff --git a/doc/design-paper/usenix.sty b/doc/design-paper/usenix.sty
index 4442f11574..575c854e77 100644
--- a/doc/design-paper/usenix.sty
+++ b/doc/design-paper/usenix.sty
@@ -5,8 +5,6 @@
% \usepackage{usenix-2e}
% and put {\rm ....} around the author names.
%
-% $Id$
-%
% The following definitions are modifications of standard article.sty
% definitions, arranged to do a better job of matching the USENIX
% guidelines.
diff --git a/doc/spec/address-spec.txt b/doc/spec/address-spec.txt
index 2a84d857e6..95641b49b8 100644
--- a/doc/spec/address-spec.txt
+++ b/doc/spec/address-spec.txt
@@ -1,4 +1,3 @@
-$Id$
Special Hostnames in Tor
Nick Mathewson
diff --git a/doc/spec/bridges-spec.txt b/doc/spec/bridges-spec.txt
index 4a9b373c8e..647118815c 100644
--- a/doc/spec/bridges-spec.txt
+++ b/doc/spec/bridges-spec.txt
@@ -1,4 +1,3 @@
-$Id$
Tor bridges specification
diff --git a/doc/spec/control-spec-v0.txt b/doc/spec/control-spec-v0.txt
index faf75a64a4..3515d395a6 100644
--- a/doc/spec/control-spec-v0.txt
+++ b/doc/spec/control-spec-v0.txt
@@ -1,4 +1,3 @@
-$Id$
TC: A Tor control protocol (Version 0)
diff --git a/doc/spec/control-spec.txt b/doc/spec/control-spec.txt
index 576c5dcd53..0c739eca03 100644
--- a/doc/spec/control-spec.txt
+++ b/doc/spec/control-spec.txt
@@ -1,4 +1,3 @@
-$Id$
TC: A Tor control protocol (Version 1)
@@ -774,9 +773,8 @@ $Id$
Same as passing 'EXTENDED' to SETEVENTS; this is the preferred way to
request the extended event syntax.
- This will not be always-enabled until at least two stable releases
- after 0.1.2.3-alpha, the release where it was first used for
- anything.
+ This feaure was first used in 0.1.2.3-alpha. It is always-on in
+ Tor 0.2.2.1-alpha and later.
VERBOSE_NAMES
@@ -787,8 +785,9 @@ $Id$
LongName format includes a Fingerprint, an indication of Named status,
and a Nickname (if one is known).
- This will not be always-enabled until at least two stable releases
- after 0.1.2.2-alpha, the release where it was first available.
+ This will not be always-enabled until at least two stable
+ releases after 0.1.2.2-alpha, the release where it was first
+ available. It is always-on in Tor 0.2.2.1-alpha and later.
3.20. RESOLVE
diff --git a/doc/spec/dir-spec-v1.txt b/doc/spec/dir-spec-v1.txt
index 286df664e2..a92fc7999a 100644
--- a/doc/spec/dir-spec-v1.txt
+++ b/doc/spec/dir-spec-v1.txt
@@ -1,4 +1,3 @@
-$Id$
Tor Protocol Specification
diff --git a/doc/spec/dir-spec-v2.txt b/doc/spec/dir-spec-v2.txt
index 4873c4a728..d1be27f3db 100644
--- a/doc/spec/dir-spec-v2.txt
+++ b/doc/spec/dir-spec-v2.txt
@@ -1,4 +1,3 @@
-$Id$
Tor directory protocol, version 2
diff --git a/doc/spec/dir-spec.txt b/doc/spec/dir-spec.txt
index 9a2a62bc46..0a3b0c11bc 100644
--- a/doc/spec/dir-spec.txt
+++ b/doc/spec/dir-spec.txt
@@ -1,4 +1,3 @@
-$Id$
Tor directory protocol, version 3
diff --git a/doc/spec/path-spec.txt b/doc/spec/path-spec.txt
index dceb21dad7..b53e4bda66 100644
--- a/doc/spec/path-spec.txt
+++ b/doc/spec/path-spec.txt
@@ -1,4 +1,3 @@
-$Id$
Tor Path Specification
diff --git a/doc/spec/proposals/000-index.txt b/doc/spec/proposals/000-index.txt
index d75157650d..b26f382f6a 100644
--- a/doc/spec/proposals/000-index.txt
+++ b/doc/spec/proposals/000-index.txt
@@ -1,7 +1,5 @@
Filename: 000-index.txt
Title: Index of Tor Proposals
-Version: $Revision$
-Last-Modified: $Date$
Author: Nick Mathewson
Created: 26-Jan-2007
Status: Meta
@@ -56,7 +54,7 @@ Proposals by number:
131 Help users to verify they are using Tor [NEEDS-REVISION]
132 A Tor Web Service For Verifying Correct Browser Configuration [DRAFT]
133 Incorporate Unreachable ORs into the Tor Network [DRAFT]
-134 More robust consensus voting with diverse authority sets [ACCEPTED]
+134 More robust consensus voting with diverse authority sets [REJECTED]
135 Simplify Configuration of Private Tor Networks [CLOSED]
136 Mass authority migration with legacy keys [CLOSED]
137 Keep controllers informed as Tor bootstraps [CLOSED]
@@ -82,6 +80,12 @@ Proposals by number:
157 Make certificate downloads specific [ACCEPTED]
158 Clients download consensus + microdescriptors [OPEN]
159 Exit Scanning [OPEN]
+160 Authorities vote for bandwidth offsets in consensus [OPEN]
+161 Computing Bandwidth Adjustments [OPEN]
+162 Publish the consensus in multiple flavors [OPEN]
+163 Detecting whether a connection comes from a client [OPEN]
+164 Reporting the status of server votes [OPEN]
+165 Easy migration for voting authority sets [OPEN]
Proposals by status:
@@ -103,11 +107,16 @@ Proposals by status:
156 Tracking blocked ports on the client side [for 0.2.?]
158 Clients download consensus + microdescriptors
159 Exit Scanning
+ 160 Authorities vote for bandwidth offsets in consensus [for 0.2.2.x]
+ 161 Computing Bandwidth Adjustments [for 0.2.2.x]
+ 162 Publish the consensus in multiple flavors [for 0.2.2]
+ 163 Detecting whether a connection comes from a client [for 0.2.2]
+ 164 Reporting the status of server votes [for 0.2.2]
+ 165 Easy migration for voting authority sets
ACCEPTED:
110 Avoiding infinite length circuits [for 0.2.1.x] [in 0.2.1.3-alpha]
117 IPv6 exits [for 0.2.1.x]
118 Advertising multiple ORPorts at once [for 0.2.1.x]
- 134 More robust consensus voting with diverse authority sets [for 0.2.2.x]
140 Provide diffs between consensuses [for 0.2.2.x]
147 Eliminate the need for v2 directories in generating v3 directories [for 0.2.1.x]
157 Make certificate downloads specific [for 0.2.1.x]
@@ -159,3 +168,5 @@ Proposals by status:
120 Shutdown descriptors when Tor servers stop
128 Families of private bridges
142 Combine Introduction and Rendezvous Points
+ REJECTED:
+ 134 More robust consensus voting with diverse authority sets
diff --git a/doc/spec/proposals/001-process.txt b/doc/spec/proposals/001-process.txt
index 3a767b5fa4..636ba2c2fa 100644
--- a/doc/spec/proposals/001-process.txt
+++ b/doc/spec/proposals/001-process.txt
@@ -1,7 +1,5 @@
Filename: 001-process.txt
Title: The Tor Proposal Process
-Version: $Revision$
-Last-Modified: $Date$
Author: Nick Mathewson
Created: 30-Jan-2007
Status: Meta
@@ -47,7 +45,7 @@ How to change the specs now:
Like an RFC, every proposal gets a number. Unlike RFCs, proposals can
change over time and keep the same number, until they are finally
accepted or rejected. The history for each proposal
- will be stored in the Tor Subversion repository.
+ will be stored in the Tor repository.
Once a proposal is in the repository, we should discuss and improve it
until we've reached consensus that it's a good idea, and that it's
@@ -82,9 +80,7 @@ How new proposals get added:
What should go in a proposal:
Every proposal should have a header containing these fields:
- Filename, Title, Version, Last-Modified, Author, Created, Status.
- The Version and Last-Modified fields should use the SVN Revision and Date
- tags respectively.
+ Filename, Title, Author, Created, Status.
These fields are optional but recommended:
Target, Implemented-In.
@@ -97,7 +93,7 @@ What should go in a proposal:
what the proposal's about, what it does, and about what state it's in.
After the Overview, the proposal becomes more free-form. Depending on its
- the length and complexity, the proposal can break into sections as
+ length and complexity, the proposal can break into sections as
appropriate, or follow a short discursive format. Every proposal should
contain at least the following information before it is "ACCEPTED",
though the information does not need to be in sections with these names.
diff --git a/doc/spec/proposals/098-todo.txt b/doc/spec/proposals/098-todo.txt
index e891ea890c..a0bbbeb568 100644
--- a/doc/spec/proposals/098-todo.txt
+++ b/doc/spec/proposals/098-todo.txt
@@ -1,7 +1,5 @@
Filename: 098-todo.txt
Title: Proposals that should be written
-Version: $Revision$
-Last-Modified: $Date$
Author: Nick Mathewson, Roger Dingledine
Created: 26-Jan-2007
Status: Meta
diff --git a/doc/spec/proposals/099-misc.txt b/doc/spec/proposals/099-misc.txt
index ba13ea2a71..a3621dd25f 100644
--- a/doc/spec/proposals/099-misc.txt
+++ b/doc/spec/proposals/099-misc.txt
@@ -1,7 +1,5 @@
Filename: 099-misc.txt
Title: Miscellaneous proposals
-Version: $Revision$
-Last-Modified: $Date$
Author: Various
Created: 26-Jan-2007
Status: Meta
diff --git a/doc/spec/proposals/100-tor-spec-udp.txt b/doc/spec/proposals/100-tor-spec-udp.txt
index 8224682ec8..7f062222c5 100644
--- a/doc/spec/proposals/100-tor-spec-udp.txt
+++ b/doc/spec/proposals/100-tor-spec-udp.txt
@@ -1,7 +1,5 @@
Filename: 100-tor-spec-udp.txt
Title: Tor Unreliable Datagram Extension Proposal
-Version: $Revision$
-Last-Modified: $Date$
Author: Marc Liberatore
Created: 23 Feb 2006
Status: Dead
diff --git a/doc/spec/proposals/101-dir-voting.txt b/doc/spec/proposals/101-dir-voting.txt
index be900a641e..634d3f1948 100644
--- a/doc/spec/proposals/101-dir-voting.txt
+++ b/doc/spec/proposals/101-dir-voting.txt
@@ -1,7 +1,5 @@
Filename: 101-dir-voting.txt
Title: Voting on the Tor Directory System
-Version: $Revision$
-Last-Modified: $Date$
Author: Nick Mathewson
Created: Nov 2006
Status: Closed
diff --git a/doc/spec/proposals/102-drop-opt.txt b/doc/spec/proposals/102-drop-opt.txt
index 8f6a38ae6c..490376bb53 100644
--- a/doc/spec/proposals/102-drop-opt.txt
+++ b/doc/spec/proposals/102-drop-opt.txt
@@ -1,7 +1,5 @@
Filename: 102-drop-opt.txt
Title: Dropping "opt" from the directory format
-Version: $Revision$
-Last-Modified: $Date$
Author: Nick Mathewson
Created: Jan 2007
Status: Closed
diff --git a/doc/spec/proposals/103-multilevel-keys.txt b/doc/spec/proposals/103-multilevel-keys.txt
index ef51e18047..c8a7a6677b 100644
--- a/doc/spec/proposals/103-multilevel-keys.txt
+++ b/doc/spec/proposals/103-multilevel-keys.txt
@@ -1,7 +1,5 @@
Filename: 103-multilevel-keys.txt
Title: Splitting identity key from regularly used signing key.
-Version: $Revision$
-Last-Modified: $Date$
Author: Nick Mathewson
Created: Jan 2007
Status: Closed
diff --git a/doc/spec/proposals/104-short-descriptors.txt b/doc/spec/proposals/104-short-descriptors.txt
index a1c42c8ff7..90e0764fe6 100644
--- a/doc/spec/proposals/104-short-descriptors.txt
+++ b/doc/spec/proposals/104-short-descriptors.txt
@@ -1,7 +1,5 @@
Filename: 104-short-descriptors.txt
Title: Long and Short Router Descriptors
-Version: $Revision$
-Last-Modified: $Date$
Author: Nick Mathewson
Created: Jan 2007
Status: Closed
diff --git a/doc/spec/proposals/105-handshake-revision.txt b/doc/spec/proposals/105-handshake-revision.txt
index f6c209e71b..791a016c26 100644
--- a/doc/spec/proposals/105-handshake-revision.txt
+++ b/doc/spec/proposals/105-handshake-revision.txt
@@ -1,7 +1,5 @@
Filename: 105-handshake-revision.txt
Title: Version negotiation for the Tor protocol.
-Version: $Revision$
-Last-Modified: $Date$
Author: Nick Mathewson, Roger Dingledine
Created: Jan 2007
Status: Closed
diff --git a/doc/spec/proposals/106-less-tls-constraint.txt b/doc/spec/proposals/106-less-tls-constraint.txt
index 35d6bf1066..7e7621df69 100644
--- a/doc/spec/proposals/106-less-tls-constraint.txt
+++ b/doc/spec/proposals/106-less-tls-constraint.txt
@@ -1,7 +1,5 @@
Filename: 106-less-tls-constraint.txt
Title: Checking fewer things during TLS handshakes
-Version: $Revision$
-Last-Modified: $Date$
Author: Nick Mathewson
Created: 9-Feb-2007
Status: Closed
diff --git a/doc/spec/proposals/107-uptime-sanity-checking.txt b/doc/spec/proposals/107-uptime-sanity-checking.txt
index b11be89380..922129b21d 100644
--- a/doc/spec/proposals/107-uptime-sanity-checking.txt
+++ b/doc/spec/proposals/107-uptime-sanity-checking.txt
@@ -1,7 +1,5 @@
Filename: 107-uptime-sanity-checking.txt
Title: Uptime Sanity Checking
-Version: $Revision$
-Last-Modified: $Date$
Author: Kevin Bauer & Damon McCoy
Created: 8-March-2007
Status: Closed
diff --git a/doc/spec/proposals/108-mtbf-based-stability.txt b/doc/spec/proposals/108-mtbf-based-stability.txt
index 2c66481530..294103760b 100644
--- a/doc/spec/proposals/108-mtbf-based-stability.txt
+++ b/doc/spec/proposals/108-mtbf-based-stability.txt
@@ -1,7 +1,5 @@
Filename: 108-mtbf-based-stability.txt
Title: Base "Stable" Flag on Mean Time Between Failures
-Version: $Revision$
-Last-Modified: $Date$
Author: Nick Mathewson
Created: 10-Mar-2007
Status: Closed
diff --git a/doc/spec/proposals/109-no-sharing-ips.txt b/doc/spec/proposals/109-no-sharing-ips.txt
index 1a88b00c0f..5438cf049a 100644
--- a/doc/spec/proposals/109-no-sharing-ips.txt
+++ b/doc/spec/proposals/109-no-sharing-ips.txt
@@ -1,7 +1,5 @@
Filename: 109-no-sharing-ips.txt
Title: No more than one server per IP address.
-Version: $Revision$
-Last-Modified: $Date$
Author: Kevin Bauer & Damon McCoy
Created: 9-March-2007
Status: Closed
diff --git a/doc/spec/proposals/110-avoid-infinite-circuits.txt b/doc/spec/proposals/110-avoid-infinite-circuits.txt
index 1834cd34a7..fffc41c25a 100644
--- a/doc/spec/proposals/110-avoid-infinite-circuits.txt
+++ b/doc/spec/proposals/110-avoid-infinite-circuits.txt
@@ -1,7 +1,5 @@
Filename: 110-avoid-infinite-circuits.txt
Title: Avoiding infinite length circuits
-Version: $Revision$
-Last-Modified: $Date$
Author: Roger Dingledine
Created: 13-Mar-2007
Status: Accepted
diff --git a/doc/spec/proposals/111-local-traffic-priority.txt b/doc/spec/proposals/111-local-traffic-priority.txt
index f8a37efc94..9411463c21 100644
--- a/doc/spec/proposals/111-local-traffic-priority.txt
+++ b/doc/spec/proposals/111-local-traffic-priority.txt
@@ -1,7 +1,5 @@
Filename: 111-local-traffic-priority.txt
Title: Prioritizing local traffic over relayed traffic
-Version: $Revision$
-Last-Modified: $Date$
Author: Roger Dingledine
Created: 14-Mar-2007
Status: Closed
diff --git a/doc/spec/proposals/112-bring-back-pathlencoinweight.txt b/doc/spec/proposals/112-bring-back-pathlencoinweight.txt
index e7cc6b4e36..3f6c3376f0 100644
--- a/doc/spec/proposals/112-bring-back-pathlencoinweight.txt
+++ b/doc/spec/proposals/112-bring-back-pathlencoinweight.txt
@@ -1,7 +1,5 @@
Filename: 112-bring-back-pathlencoinweight.txt
Title: Bring Back Pathlen Coin Weight
-Version: $Revision$
-Last-Modified: $Date$
Author: Mike Perry
Created:
Status: Superseded
diff --git a/doc/spec/proposals/113-fast-authority-interface.txt b/doc/spec/proposals/113-fast-authority-interface.txt
index 20cf33e429..8912b53220 100644
--- a/doc/spec/proposals/113-fast-authority-interface.txt
+++ b/doc/spec/proposals/113-fast-authority-interface.txt
@@ -1,7 +1,5 @@
Filename: 113-fast-authority-interface.txt
Title: Simplifying directory authority administration
-Version: $Revision$
-Last-Modified: $Date$
Author: Nick Mathewson
Created:
Status: Superseded
diff --git a/doc/spec/proposals/114-distributed-storage.txt b/doc/spec/proposals/114-distributed-storage.txt
index e9271fb82d..91a787d301 100644
--- a/doc/spec/proposals/114-distributed-storage.txt
+++ b/doc/spec/proposals/114-distributed-storage.txt
@@ -1,7 +1,5 @@
Filename: 114-distributed-storage.txt
Title: Distributed Storage for Tor Hidden Service Descriptors
-Version: $Revision$
-Last-Modified: $Date$
Author: Karsten Loesing
Created: 13-May-2007
Status: Closed
diff --git a/doc/spec/proposals/115-two-hop-paths.txt b/doc/spec/proposals/115-two-hop-paths.txt
index ee10d949c4..9854c9ad55 100644
--- a/doc/spec/proposals/115-two-hop-paths.txt
+++ b/doc/spec/proposals/115-two-hop-paths.txt
@@ -1,7 +1,5 @@
Filename: 115-two-hop-paths.txt
Title: Two Hop Paths
-Version: $Revision$
-Last-Modified: $Date$
Author: Mike Perry
Created:
Status: Dead
diff --git a/doc/spec/proposals/116-two-hop-paths-from-guard.txt b/doc/spec/proposals/116-two-hop-paths-from-guard.txt
index 454b344abf..f45625350b 100644
--- a/doc/spec/proposals/116-two-hop-paths-from-guard.txt
+++ b/doc/spec/proposals/116-two-hop-paths-from-guard.txt
@@ -1,7 +1,5 @@
Filename: 116-two-hop-paths-from-guard.txt
Title: Two hop paths from entry guards
-Version: $Revision$
-Last-Modified: $Date$
Author: Michael Lieberman
Created: 26-Jun-2007
Status: Dead
diff --git a/doc/spec/proposals/117-ipv6-exits.txt b/doc/spec/proposals/117-ipv6-exits.txt
index c8402821ed..00cd7cef10 100644
--- a/doc/spec/proposals/117-ipv6-exits.txt
+++ b/doc/spec/proposals/117-ipv6-exits.txt
@@ -1,7 +1,5 @@
Filename: 117-ipv6-exits.txt
Title: IPv6 exits
-Version: $Revision$
-Last-Modified: $Date$
Author: coderman
Created: 10-Jul-2007
Status: Accepted
diff --git a/doc/spec/proposals/118-multiple-orports.txt b/doc/spec/proposals/118-multiple-orports.txt
index 1bef2504d9..2381ec7ca3 100644
--- a/doc/spec/proposals/118-multiple-orports.txt
+++ b/doc/spec/proposals/118-multiple-orports.txt
@@ -1,7 +1,5 @@
Filename: 118-multiple-orports.txt
Title: Advertising multiple ORPorts at once
-Version: $Revision$
-Last-Modified: $Date$
Author: Nick Mathewson
Created: 09-Jul-2007
Status: Accepted
diff --git a/doc/spec/proposals/119-controlport-auth.txt b/doc/spec/proposals/119-controlport-auth.txt
index dc57a27368..9ed1cc1cbe 100644
--- a/doc/spec/proposals/119-controlport-auth.txt
+++ b/doc/spec/proposals/119-controlport-auth.txt
@@ -1,7 +1,5 @@
Filename: 119-controlport-auth.txt
Title: New PROTOCOLINFO command for controllers
-Version: $Revision$
-Last-Modified: $Date$
Author: Roger Dingledine
Created: 14-Aug-2007
Status: Closed
diff --git a/doc/spec/proposals/120-shutdown-descriptors.txt b/doc/spec/proposals/120-shutdown-descriptors.txt
index dc1265b03b..5cfe2b5bc6 100644
--- a/doc/spec/proposals/120-shutdown-descriptors.txt
+++ b/doc/spec/proposals/120-shutdown-descriptors.txt
@@ -1,7 +1,5 @@
Filename: 120-shutdown-descriptors.txt
Title: Shutdown descriptors when Tor servers stop
-Version: $Revision$
-Last-Modified: $Date$
Author: Roger Dingledine
Created: 15-Aug-2007
Status: Dead
diff --git a/doc/spec/proposals/121-hidden-service-authentication.txt b/doc/spec/proposals/121-hidden-service-authentication.txt
index 828bf3c92d..0d92b53a8c 100644
--- a/doc/spec/proposals/121-hidden-service-authentication.txt
+++ b/doc/spec/proposals/121-hidden-service-authentication.txt
@@ -1,7 +1,5 @@
Filename: 121-hidden-service-authentication.txt
Title: Hidden Service Authentication
-Version: $Revision$
-Last-Modified: $Date$
Author: Tobias Kamm, Thomas Lauterbach, Karsten Loesing, Ferdinand Rieger,
Christoph Weingarten
Created: 10-Sep-2007
diff --git a/doc/spec/proposals/122-unnamed-flag.txt b/doc/spec/proposals/122-unnamed-flag.txt
index 6502b9c560..2ce7bb22b9 100644
--- a/doc/spec/proposals/122-unnamed-flag.txt
+++ b/doc/spec/proposals/122-unnamed-flag.txt
@@ -1,7 +1,5 @@
Filename: 122-unnamed-flag.txt
Title: Network status entries need a new Unnamed flag
-Version: $Revision$
-Last-Modified: $Date$
Author: Roger Dingledine
Created: 04-Oct-2007
Status: Closed
diff --git a/doc/spec/proposals/123-autonaming.txt b/doc/spec/proposals/123-autonaming.txt
index 6cd25329f8..74c486985d 100644
--- a/doc/spec/proposals/123-autonaming.txt
+++ b/doc/spec/proposals/123-autonaming.txt
@@ -1,7 +1,5 @@
Filename: 123-autonaming.txt
Title: Naming authorities automatically create bindings
-Version: $Revision$
-Last-Modified: $Date$
Author: Peter Palfrader
Created: 2007-10-11
Status: Closed
diff --git a/doc/spec/proposals/124-tls-certificates.txt b/doc/spec/proposals/124-tls-certificates.txt
index 0a47772732..9472d14af8 100644
--- a/doc/spec/proposals/124-tls-certificates.txt
+++ b/doc/spec/proposals/124-tls-certificates.txt
@@ -1,7 +1,5 @@
Filename: 124-tls-certificates.txt
Title: Blocking resistant TLS certificate usage
-Version: $Revision$
-Last-Modified: $Date$
Author: Steven J. Murdoch
Created: 2007-10-25
Status: Superseded
diff --git a/doc/spec/proposals/125-bridges.txt b/doc/spec/proposals/125-bridges.txt
index 8bb3169780..9d95729d42 100644
--- a/doc/spec/proposals/125-bridges.txt
+++ b/doc/spec/proposals/125-bridges.txt
@@ -1,7 +1,5 @@
Filename: 125-bridges.txt
Title: Behavior for bridge users, bridge relays, and bridge authorities
-Version: $Revision$
-Last-Modified: $Date$
Author: Roger Dingledine
Created: 11-Nov-2007
Status: Closed
diff --git a/doc/spec/proposals/126-geoip-reporting.txt b/doc/spec/proposals/126-geoip-reporting.txt
index d48a08ba38..9f3b21c670 100644
--- a/doc/spec/proposals/126-geoip-reporting.txt
+++ b/doc/spec/proposals/126-geoip-reporting.txt
@@ -1,7 +1,5 @@
Filename: 126-geoip-reporting.txt
Title: Getting GeoIP data and publishing usage summaries
-Version: $Revision$
-Last-Modified: $Date$
Author: Roger Dingledine
Created: 2007-11-24
Status: Closed
diff --git a/doc/spec/proposals/127-dirport-mirrors-downloads.txt b/doc/spec/proposals/127-dirport-mirrors-downloads.txt
index 1b55a02d61..72d6c0cb9f 100644
--- a/doc/spec/proposals/127-dirport-mirrors-downloads.txt
+++ b/doc/spec/proposals/127-dirport-mirrors-downloads.txt
@@ -1,7 +1,5 @@
Filename: 127-dirport-mirrors-downloads.txt
Title: Relaying dirport requests to Tor download site / website
-Version: $Revision$
-Last-Modified: $Date$
Author: Roger Dingledine
Created: 2007-12-02
Status: Draft
diff --git a/doc/spec/proposals/128-bridge-families.txt b/doc/spec/proposals/128-bridge-families.txt
index e8a0050c3c..e5bdcf95cb 100644
--- a/doc/spec/proposals/128-bridge-families.txt
+++ b/doc/spec/proposals/128-bridge-families.txt
@@ -1,7 +1,5 @@
Filename: 128-bridge-families.txt
Title: Families of private bridges
-Version: $Revision$
-Last-Modified: $Date$
Author: Roger Dingledine
Created: 2007-12-xx
Status: Dead
diff --git a/doc/spec/proposals/129-reject-plaintext-ports.txt b/doc/spec/proposals/129-reject-plaintext-ports.txt
index d4767d03d8..8080ff5b75 100644
--- a/doc/spec/proposals/129-reject-plaintext-ports.txt
+++ b/doc/spec/proposals/129-reject-plaintext-ports.txt
@@ -1,7 +1,5 @@
Filename: 129-reject-plaintext-ports.txt
Title: Block Insecure Protocols by Default
-Version: $Revision$
-Last-Modified: $Date$
Author: Kevin Bauer & Damon McCoy
Created: 2008-01-15
Status: Closed
diff --git a/doc/spec/proposals/130-v2-conn-protocol.txt b/doc/spec/proposals/130-v2-conn-protocol.txt
index 16f5bf2844..60e742a622 100644
--- a/doc/spec/proposals/130-v2-conn-protocol.txt
+++ b/doc/spec/proposals/130-v2-conn-protocol.txt
@@ -1,7 +1,5 @@
Filename: 130-v2-conn-protocol.txt
Title: Version 2 Tor connection protocol
-Version: $Revision$
-Last-Modified: $Date$
Author: Nick Mathewson
Created: 2007-10-25
Status: Closed
diff --git a/doc/spec/proposals/131-verify-tor-usage.txt b/doc/spec/proposals/131-verify-tor-usage.txt
index 2687139189..d3c6efe75a 100644
--- a/doc/spec/proposals/131-verify-tor-usage.txt
+++ b/doc/spec/proposals/131-verify-tor-usage.txt
@@ -1,7 +1,5 @@
Filename: 131-verify-tor-usage.txt
Title: Help users to verify they are using Tor
-Version: $Revision$
-Last-Modified: $Date$
Author: Steven J. Murdoch
Created: 2008-01-25
Status: Needs-Revision
diff --git a/doc/spec/proposals/132-browser-check-tor-service.txt b/doc/spec/proposals/132-browser-check-tor-service.txt
index d07a10dcde..6132e5d060 100644
--- a/doc/spec/proposals/132-browser-check-tor-service.txt
+++ b/doc/spec/proposals/132-browser-check-tor-service.txt
@@ -1,7 +1,5 @@
Filename: 132-browser-check-tor-service.txt
Title: A Tor Web Service For Verifying Correct Browser Configuration
-Version: $Revision$
-Last-Modified: $Date$
Author: Robert Hogan
Created: 2008-03-08
Status: Draft
diff --git a/doc/spec/proposals/134-robust-voting.txt b/doc/spec/proposals/134-robust-voting.txt
index 5d5e77fa3b..c5dfb3b47f 100644
--- a/doc/spec/proposals/134-robust-voting.txt
+++ b/doc/spec/proposals/134-robust-voting.txt
@@ -2,8 +2,10 @@ Filename: 134-robust-voting.txt
Title: More robust consensus voting with diverse authority sets
Author: Peter Palfrader
Created: 2008-04-01
-Status: Accepted
-Target: 0.2.2.x
+Status: Rejected
+
+History:
+ 2009 May 27: Added note on rejecting this proposal -- Nick
Overview:
@@ -103,3 +105,19 @@ Possible Attacks/Open Issues/Some thinking required:
Q: Can this ever force us to build a consensus with authorities we do not
recognize?
A: No, we can never build a fully connected set with them in step 3.
+
+------------------------------
+
+I'm rejecting this proposal as insecure.
+
+Suppose that we have a clique of size N, and M hostile members in the
+clique. If these hostile members stop declaring trust for up to M-1
+good members of the clique, the clique with the hostile members will
+in it will be larger than the one without them.
+
+The M hostile members will constitute a majority of this new clique
+when M > (N-(M-1)) / 2, or when M > (N + 1) / 3. This breaks our
+requirement that an adversary must compromise a majority of authorities
+in order to control the consensus.
+
+-- Nick
diff --git a/doc/spec/proposals/135-private-tor-networks.txt b/doc/spec/proposals/135-private-tor-networks.txt
index 131bbb9068..19ef68b7b1 100644
--- a/doc/spec/proposals/135-private-tor-networks.txt
+++ b/doc/spec/proposals/135-private-tor-networks.txt
@@ -1,7 +1,5 @@
Filename: 135-private-tor-networks.txt
Title: Simplify Configuration of Private Tor Networks
-Version: $Revision$
-Last-Modified: $Date$
Author: Karsten Loesing
Created: 29-Apr-2008
Status: Closed
diff --git a/doc/spec/proposals/137-bootstrap-phases.txt b/doc/spec/proposals/137-bootstrap-phases.txt
index 18d3dfae12..ebe044c707 100644
--- a/doc/spec/proposals/137-bootstrap-phases.txt
+++ b/doc/spec/proposals/137-bootstrap-phases.txt
@@ -1,7 +1,5 @@
Filename: 137-bootstrap-phases.txt
Title: Keep controllers informed as Tor bootstraps
-Version: $Revision$
-Last-Modified: $Date$
Author: Roger Dingledine
Created: 07-Jun-2008
Status: Closed
diff --git a/doc/spec/proposals/138-remove-down-routers-from-consensus.txt b/doc/spec/proposals/138-remove-down-routers-from-consensus.txt
index a07764d536..776911b5c9 100644
--- a/doc/spec/proposals/138-remove-down-routers-from-consensus.txt
+++ b/doc/spec/proposals/138-remove-down-routers-from-consensus.txt
@@ -1,7 +1,5 @@
Filename: 138-remove-down-routers-from-consensus.txt
Title: Remove routers that are not Running from consensus documents
-Version: $Revision$
-Last-Modified: $Date$
Author: Peter Palfrader
Created: 11-Jun-2008
Status: Closed
diff --git a/doc/spec/proposals/140-consensus-diffs.txt b/doc/spec/proposals/140-consensus-diffs.txt
index da63bfe23c..8bc4070bfe 100644
--- a/doc/spec/proposals/140-consensus-diffs.txt
+++ b/doc/spec/proposals/140-consensus-diffs.txt
@@ -1,12 +1,15 @@
Filename: 140-consensus-diffs.txt
Title: Provide diffs between consensuses
-Version: $Revision$
-Last-Modified: $Date$
Author: Peter Palfrader
Created: 13-Jun-2008
Status: Accepted
Target: 0.2.2.x
+0. History
+
+ 22-May-2009: Restricted the ed format even more strictly for ease of
+ implementation. -nickm
+
1. Overview.
Tor clients and servers need a list of which relays are on the
@@ -135,6 +138,10 @@ Target: 0.2.2.x
Note that line numbers always apply to the file after all previous
commands have already been applied.
+ The commands MUST apply to the file from back to front, such that
+ lines are only ever referred to by their position in the original
+ file.
+
The "current line" is either the first line of the file, if this is
the first command, the last line of a block we added in an append or
change command, or the line immediate following a set of lines we just
diff --git a/doc/spec/proposals/141-jit-sd-downloads.txt b/doc/spec/proposals/141-jit-sd-downloads.txt
index b0c2b2cbcd..2ac7a086b7 100644
--- a/doc/spec/proposals/141-jit-sd-downloads.txt
+++ b/doc/spec/proposals/141-jit-sd-downloads.txt
@@ -1,7 +1,5 @@
Filename: 141-jit-sd-downloads.txt
Title: Download server descriptors on demand
-Version: $Revision$
-Last-Modified: $Date$
Author: Peter Palfrader
Created: 15-Jun-2008
Status: Draft
@@ -63,8 +61,8 @@ Status: Draft
which tries to convey a server's capacity to clients.
Currently we weigh servers differently for different purposes. There
- is a weigh for when we use a server as a guard node (our entry to the
- Tor network), there is one weigh we assign servers for exit duties,
+ is a weight for when we use a server as a guard node (our entry to the
+ Tor network), there is one weight we assign servers for exit duties,
and a third for when we need intermediate (middle) nodes.
2.2 Exit information
@@ -80,7 +78,7 @@ Status: Draft
2.3 Capability information
- Server descriptors contain information about the specific version or
+ Server descriptors contain information about the specific version of
the Tor protocol they understand [proposal 105].
Furthermore the server descriptor also contains the exact version of
diff --git a/doc/spec/proposals/142-combine-intro-and-rend-points.txt b/doc/spec/proposals/142-combine-intro-and-rend-points.txt
index 3456b285a9..3abd5c863d 100644
--- a/doc/spec/proposals/142-combine-intro-and-rend-points.txt
+++ b/doc/spec/proposals/142-combine-intro-and-rend-points.txt
@@ -1,7 +1,5 @@
Filename: 142-combine-intro-and-rend-points.txt
Title: Combine Introduction and Rendezvous Points
-Version: $Revision$
-Last-Modified: $Date$
Author: Karsten Loesing, Christian Wilms
Created: 27-Jun-2008
Status: Dead
diff --git a/doc/spec/proposals/143-distributed-storage-improvements.txt b/doc/spec/proposals/143-distributed-storage-improvements.txt
index 8789d84663..0f7468f1dc 100644
--- a/doc/spec/proposals/143-distributed-storage-improvements.txt
+++ b/doc/spec/proposals/143-distributed-storage-improvements.txt
@@ -1,7 +1,5 @@
Filename: 143-distributed-storage-improvements.txt
Title: Improvements of Distributed Storage for Tor Hidden Service Descriptors
-Version: $Revision$
-Last-Modified: $Date$
Author: Karsten Loesing
Created: 28-Jun-2008
Status: Open
diff --git a/doc/spec/proposals/145-newguard-flag.txt b/doc/spec/proposals/145-newguard-flag.txt
index 31d707d725..9e61e30be9 100644
--- a/doc/spec/proposals/145-newguard-flag.txt
+++ b/doc/spec/proposals/145-newguard-flag.txt
@@ -1,7 +1,5 @@
Filename: 145-newguard-flag.txt
Title: Separate "suitable as a guard" from "suitable as a new guard"
-Version: $Revision$
-Last-Modified: $Date$
Author: Nick Mathewson
Created: 1-Jul-2008
Status: Open
diff --git a/doc/spec/proposals/146-long-term-stability.txt b/doc/spec/proposals/146-long-term-stability.txt
index 7cfd58f564..9af0017441 100644
--- a/doc/spec/proposals/146-long-term-stability.txt
+++ b/doc/spec/proposals/146-long-term-stability.txt
@@ -1,7 +1,5 @@
Filename: 146-long-term-stability.txt
Title: Add new flag to reflect long-term stability
-Version: $Revision$
-Last-Modified: $Date$
Author: Nick Mathewson
Created: 19-Jun-2008
Status: Open
diff --git a/doc/spec/proposals/147-prevoting-opinions.txt b/doc/spec/proposals/147-prevoting-opinions.txt
index 2b8cf30e46..3d9659c984 100644
--- a/doc/spec/proposals/147-prevoting-opinions.txt
+++ b/doc/spec/proposals/147-prevoting-opinions.txt
@@ -1,7 +1,5 @@
Filename: 147-prevoting-opinions.txt
Title: Eliminate the need for v2 directories in generating v3 directories
-Version: $Revision$
-Last-Modified: $Date$
Author: Nick Mathewson
Created: 2-Jul-2008
Status: Accepted
diff --git a/doc/spec/proposals/148-uniform-client-end-reason.txt b/doc/spec/proposals/148-uniform-client-end-reason.txt
index cec81253ea..1db3b3e596 100644
--- a/doc/spec/proposals/148-uniform-client-end-reason.txt
+++ b/doc/spec/proposals/148-uniform-client-end-reason.txt
@@ -1,7 +1,5 @@
Filename: 148-uniform-client-end-reason.txt
Title: Stream end reasons from the client side should be uniform
-Version: $Revision$
-Last-Modified: $Date$
Author: Roger Dingledine
Created: 2-Jul-2008
Status: Closed
diff --git a/doc/spec/proposals/149-using-netinfo-data.txt b/doc/spec/proposals/149-using-netinfo-data.txt
index 4919514b4c..cbfc759f22 100644
--- a/doc/spec/proposals/149-using-netinfo-data.txt
+++ b/doc/spec/proposals/149-using-netinfo-data.txt
@@ -1,7 +1,5 @@
Filename: 149-using-netinfo-data.txt
Title: Using data from NETINFO cells
-Version: $Revision$
-Last-Modified: $Date$
Author: Nick Mathewson
Created: 2-Jul-2008
Status: Open
diff --git a/doc/spec/proposals/150-exclude-exit-nodes.txt b/doc/spec/proposals/150-exclude-exit-nodes.txt
index b73a9cc4d1..b497ae62c1 100644
--- a/doc/spec/proposals/150-exclude-exit-nodes.txt
+++ b/doc/spec/proposals/150-exclude-exit-nodes.txt
@@ -1,6 +1,5 @@
Filename: 150-exclude-exit-nodes.txt
Title: Exclude Exit Nodes from a circuit
-Version: $Revision$
Author: Mfr
Created: 2008-06-15
Status: Closed
diff --git a/doc/spec/proposals/151-path-selection-improvements.txt b/doc/spec/proposals/151-path-selection-improvements.txt
index e3c8f35451..3d5f07d3ab 100644
--- a/doc/spec/proposals/151-path-selection-improvements.txt
+++ b/doc/spec/proposals/151-path-selection-improvements.txt
@@ -1,7 +1,5 @@
Filename: 151-path-selection-improvements.txt
Title: Improving Tor Path Selection
-Version:
-Last-Modified:
Author: Fallon Chen, Mike Perry
Created: 5-Jul-2008
Status: Draft
diff --git a/doc/spec/proposals/152-single-hop-circuits.txt b/doc/spec/proposals/152-single-hop-circuits.txt
index e49a4250e0..d0b28b1c72 100644
--- a/doc/spec/proposals/152-single-hop-circuits.txt
+++ b/doc/spec/proposals/152-single-hop-circuits.txt
@@ -1,7 +1,5 @@
Filename: 152-single-hop-circuits.txt
Title: Optionally allow exit from single-hop circuits
-Version:
-Last-Modified:
Author: Geoff Goodell
Created: 13-Jul-2008
Status: Closed
diff --git a/doc/spec/proposals/153-automatic-software-update-protocol.txt b/doc/spec/proposals/153-automatic-software-update-protocol.txt
index 7bc809d440..c2979bb695 100644
--- a/doc/spec/proposals/153-automatic-software-update-protocol.txt
+++ b/doc/spec/proposals/153-automatic-software-update-protocol.txt
@@ -1,7 +1,5 @@
Filename: 153-automatic-software-update-protocol.txt
Title: Automatic software update protocol
-Version: $Revision$
-Last-Modified: $Date$
Author: Jacob Appelbaum
Created: 14-July-2008
Status: Superseded
diff --git a/doc/spec/proposals/154-automatic-updates.txt b/doc/spec/proposals/154-automatic-updates.txt
index 00a820de08..4c2c6d3899 100644
--- a/doc/spec/proposals/154-automatic-updates.txt
+++ b/doc/spec/proposals/154-automatic-updates.txt
@@ -1,7 +1,5 @@
Filename: 154-automatic-updates.txt
Title: Automatic Software Update Protocol
-Version: $Revision$
-Last-Modified: $Date$
Author: Matt Edman
Created: 30-July-2008
Status: Superseded
diff --git a/doc/spec/proposals/155-four-hidden-service-improvements.txt b/doc/spec/proposals/155-four-hidden-service-improvements.txt
index f528f8baf2..e342bf1c39 100644
--- a/doc/spec/proposals/155-four-hidden-service-improvements.txt
+++ b/doc/spec/proposals/155-four-hidden-service-improvements.txt
@@ -1,7 +1,5 @@
Filename: 155-four-hidden-service-improvements.txt
Title: Four Improvements of Hidden Service Performance
-Version: $Revision$
-Last-Modified: $Date$
Author: Karsten Loesing, Christian Wilms
Created: 25-Sep-2008
Status: Finished
diff --git a/doc/spec/proposals/156-tracking-blocked-ports.txt b/doc/spec/proposals/156-tracking-blocked-ports.txt
index 1e7b0d963f..419de7e74c 100644
--- a/doc/spec/proposals/156-tracking-blocked-ports.txt
+++ b/doc/spec/proposals/156-tracking-blocked-ports.txt
@@ -1,7 +1,5 @@
Filename: 156-tracking-blocked-ports.txt
Title: Tracking blocked ports on the client side
-Version: $Revision$
-Last-Modified: $Date$
Author: Robert Hogan
Created: 14-Oct-2008
Status: Open
diff --git a/doc/spec/proposals/157-specific-cert-download.txt b/doc/spec/proposals/157-specific-cert-download.txt
index e54a987277..204b20973a 100644
--- a/doc/spec/proposals/157-specific-cert-download.txt
+++ b/doc/spec/proposals/157-specific-cert-download.txt
@@ -1,7 +1,5 @@
Filename: 157-specific-cert-download.txt
Title: Make certificate downloads specific
-Version: $Revision$
-Last-Modified: $Date$
Author: Nick Mathewson
Created: 2-Dec-2008
Status: Accepted
diff --git a/doc/spec/proposals/158-microdescriptors.txt b/doc/spec/proposals/158-microdescriptors.txt
index f478a3c834..59c14c3bcc 100644
--- a/doc/spec/proposals/158-microdescriptors.txt
+++ b/doc/spec/proposals/158-microdescriptors.txt
@@ -1,11 +1,18 @@
Filename: 158-microdescriptors.txt
Title: Clients download consensus + microdescriptors
-Version: $Revision$
-Last-Modified: $Date$
Author: Roger Dingledine
Created: 17-Jan-2009
Status: Open
+0. History
+
+ 15 May 2009: Substantially revised based on discussions on or-dev
+ from late January. Removed the notion of voting on how to choose
+ microdescriptors; made it just a function of the consesus method.
+ (This lets us avoid the possibility of "desynchronization.")
+ Added suggestion to use a new consensus flavor. Specified use of
+ SHA256 for new hashes. -nickm
+
1. Overview
This proposal replaces section 3.2 of proposal 141, which was
@@ -24,6 +31,10 @@ Status: Open
them, we'll need to resume considering some design like the one in
proposal 141.
+ Note also that any descriptor element which clients need to use to
+ decide which servers to fetch info about, or which servers to fetch
+ info from, needs to stay in the consensus.
+
2. Motivation
See
@@ -36,89 +47,69 @@ Status: Open
3. Design
There are three pieces to the proposal. First, authorities will list in
- their votes (and thus in the consensus) what relay descriptor elements
- are included in the microdescriptor, and also list the expected hash
+ their votes (and thus in the consensus) the expected hash
of microdescriptor for each relay. Second, directory mirrors will serve
microdescriptors. Third, clients will ask for them and cache them.
3.1. Consensus changes
- V3 votes should include a new line:
- microdescriptor-elements bar baz foo
- listing each descriptor element (sorted alphabetically) that authority
- included when it calculated its expected microdescriptor hashes.
+ If the authorities choose a consensus method of a given version or
+ later, a microdescriptor format is implicit in that version.
+ A microdescriptor should in every case be a pure function of the
+ router descriptor and the conensus method.
- We also need to include the hash of each expected microdescriptor in
+ In votes, need to include the hash of each expected microdescriptor in
the routerstatus section. I suggest a new "m" line for each stanza,
- with the base64 of the hash of the elements that the authority voted
- for above.
+ with the base64 of the SHA256 hash of the router's microdescriptor.
+
+ For every consensus method that an authority supports, it includes a
+ separate "m" line in each router section of its vote, containing:
+ "m" SP methods SP digest NL
+ where methods is a comma-separated list of the consensus methods
+ that the authority believes will produce "digest".
+
+ (As with base64 encoding of SHA1 hashes in consensuses, let's
+ omit the trailing =s)
The consensus microdescriptor-elements and "m" lines are then computed
as described in Section 3.1.2 below.
- I believe that means we need a new consensus-method "6" that knows
- how to compute the microdescriptor-elements and add "m" lines.
+ (This means we need a new consensus-method that knows
+ how to compute the microdescriptor-elements and add "m" lines.)
3.1.1. Descriptor elements to include for now
- To start, the element list that authorities suggest should be
- family onion-key
+ In the first version, the microdescriptor should contain the
+ onion-key element and the family element from the router descriptor.
- (Note that the or-dev posts above only mention onion-key, but if
- we don't also include family then clients will never learn it. It
- seemed like it should be relatively static, so putting it in the
- microdescriptor is smarter than trying to fit it into the consensus.)
+3.1.2. Computing consensus for microdescriptor-elements and "m" lines
- We could imagine a config option "family,onion-key" so authorities
- could change their voted preferences without needing to upgrade.
+ When we generating a consensus, we use whichever m line
+ unambiguously corresponds to the descriptor digest that will be
+ included in the consensus. (If there are multiple m lines for that
+ descriptor digest, we use whichever is most common. If they are
+ equally common, we break ties in the favor of the lexically
+ earliest. Either way, we should log a warning: That's likely a
+ bug.)
-3.1.2. Computing consensus for microdescriptor-elements and "m" lines
+ The "m" lines in a consensus contain only the digest, not a list of
+ consensus methods.
- One approach is for the consensus microdescriptor-elements line to
- include every element listed by a majority of authorities, sorted. The
- problem here is that it will no longer be deterministic what the correct
- hash for the "m" line should be. We could imagine telling the authority
- to go look in its descriptor and produce the right hash itself, but
- we don't want consensus calculation to be based on external data like
- that. (Plus, the authority may not have the descriptor that everybody
- else voted to use.)
-
- The better approach is to take the exact set that has the most votes
- (breaking ties by the set that has the most elements, and breaking
- ties after that by whichever is alphabetically first). That will
- increase the odds that we actually get a microdescriptor hash that
- is both a) for the descriptor we're putting in the consensus, and b)
- over the elements that we're declaring it should be for.
-
- Then the "m" line for a given relay is the one that gets the most votes
- from authorities that both a) voted for the microdescriptor-elements
- line we're using, and b) voted for the descriptor we're using.
-
- (If there's a tie, use the smaller hash. But really, if there are
- multiple such votes and they differ about a microdescriptor, we caught
- one of them lying or being buggy. We should log it to track down why.)
-
- If there are no such votes, then we leave out the "m" line for that
- relay. That means clients should avoid it for this time period. (As
- an extension it could instead mean that clients should fetch the
- descriptor and figure out its microdescriptor themselves. But let's
- not get ahead of ourselves.)
-
- It would be nice to have a more foolproof way to agree on what
- microdescriptor hash each authority should vote for, so we can avoid
- missing "m" lines. Just switching to a new consensus-method each time
- we change the set of microdescriptor-elements won't help though, since
- each authority will still have to decide what hash to vote for before
- knowing what consensus-method will be used.
-
- Here's one way we could do it. Each vote / consensus includes
- the microdescriptor-elements that were used to compute the hashes,
- and also a preferred-microdescriptor-elements set. If an authority
- has a consensus from the previous period, then it should use the
- consensus preferred-microdescriptor-elements when computing its votes
- for microdescriptor-elements and the appropriate hashes in the upcoming
- period. (If it has no previous consensus, then it just writes its
- own preferences in both lines.)
+3.1.3. A new flavor of consensus
+
+ Rather than inserting "m" lines in the current consensus format,
+ they should be included in a new consensus flavor (see proposal
+ 162).
+
+ This flavor can safely omit descriptor digests.
+
+ We still need to descide whether to move ports into microdescriptors
+ or not. In either case, they can be removed from the current "ns"
+ flavor of consensus, since no current clients use them, and they
+ take up about 5% of the compressed consensus.
+
+ This new consensus flavor should be signed with the sha256 signature
+ format as documented in proposal 162.
3.2. Directory mirrors serve microdescriptors
@@ -127,8 +118,10 @@ Status: Open
continue to serve normal relay descriptors too, a) to serve old clients
and b) to be able to construct microdescriptors on the fly.)
- The microdescriptors with hashes <D1>,<D2>,<D3> should be available at:
- http://<hostname>/tor/micro/d/<D1>+<D2>+<D3>.z
+ The microdescriptors with base64 hashes <D1>,<D2>,<D3> should be available at:
+ http://<hostname>/tor/micro/d/<D1>-<D2>-<D3>.z
+ (We use base64 for size and for consistency with the consensus
+ format. We use -s instead of +s to separate these items, since
All the microdescriptors from the current consensus should also be
available at:
@@ -136,24 +129,9 @@ Status: Open
so a client that's bootstrapping doesn't need to send a 70KB URL just
to name every microdescriptor it's looking for.
- The format of a microdescriptor is the header line
- "microdescriptor-header"
- followed by each element (keyword and body), alphabetically. There's
- no need to mention what hash it's for, since it's self-identifying:
- you can hash the elements to learn this.
-
- (Do we need a footer line to show that it's over, or is the next
- microdescriptor line or EOF enough of a hint? A footer line wouldn't
- hurt much. Also, no fair voting for the microdescriptor-element
- "microdescriptor-header".)
-
+ Microdescriptors have no header or footer.
The hash of the microdescriptor is simply the hash of the concatenated
- elements -- not counting the header line or hypothetical footer line.
- Unless you prefer that?
-
- Is there a reasonable way to version these things? We could say that
- the microdescriptor-header line can contain arguments which clients
- must ignore if they don't understand them. Any better ways?
+ elements.
Directory mirrors should check to make sure that the microdescriptors
they're about to serve match the right hashes (either the hashes from
@@ -170,10 +148,14 @@ Status: Open
When a client gets a new consensus, it looks to see if there are any
microdescriptors it needs to learn. If it needs to learn more than
some threshold of the microdescriptors (half?), it requests 'all',
- else it requests only the missing ones.
+ else it requests only the missing ones. Clients MAY try to
+ determine whether the upload bandwidth for listing the
+ microdescriptors they want is more or less than the download
+ bandwidth for the microdescriptors they do not want.
Clients maintain a cache of microdescriptors along with metadata like
- when it was last referenced by a consensus. They keep a microdescriptor
+ when it was last referenced by a consensus, and which identity key
+ it corresponds to. They keep a microdescriptor
until it hasn't been mentioned in any consensus for a week. Future
clients might cache them for longer or shorter times.
@@ -194,14 +176,11 @@ Status: Open
Phase one, the directory authorities should start voting on
microdescriptors and microdescriptor elements, and putting them in the
- consensus. This should happen during the 0.2.1.x series, and should
- be relatively easy to do.
+ consensus.
Phase two, directory mirrors should learn how to serve them, and learn
- how to read the consensus to find out what they should be serving. This
- phase could be done either in 0.2.1.x or early in 0.2.2.x, depending
- on how messy it turns out to be and how quickly we get around to it.
+ how to read the consensus to find out what they should be serving.
Phase three, clients should start fetching and caching them instead
- of normal descriptors. This should happen post 0.2.1.x.
+ of normal descriptors.
diff --git a/doc/spec/proposals/159-exit-scanning.txt b/doc/spec/proposals/159-exit-scanning.txt
index fbc69aa9e6..7090f2ed08 100644
--- a/doc/spec/proposals/159-exit-scanning.txt
+++ b/doc/spec/proposals/159-exit-scanning.txt
@@ -1,7 +1,5 @@
Filename: 159-exit-scanning.txt
Title: Exit Scanning
-Version: $Revision$
-Last-Modified: $Date$
Author: Mike Perry
Created: 13-Feb-2009
Status: Open
diff --git a/doc/spec/proposals/160-bandwidth-offset.txt b/doc/spec/proposals/160-bandwidth-offset.txt
new file mode 100644
index 0000000000..7ca74dfae3
--- /dev/null
+++ b/doc/spec/proposals/160-bandwidth-offset.txt
@@ -0,0 +1,105 @@
+Filename: 160-bandwidth-offset.txt
+Title: Authorities vote for bandwidth offsets in consensus
+Author: Roger Dingledine
+Created: 4-May-2009
+Status: Open
+Target: 0.2.2.x
+
+1. Motivation
+
+ As part of proposal 141, we moved the bandwidth value for each relay
+ into the consensus. Now clients can know how they should load balance
+ even before they've fetched the corresponding relay descriptors.
+
+ Putting the bandwidth in the consensus also lets the directory
+ authorities choose more accurate numbers to advertise, if we come up
+ with a better algorithm for deciding weightings.
+
+ Our original plan was to teach directory authorities how to measure
+ bandwidth themselves; then every authority would vote for the bandwidth
+ it prefers, and we'd take the median of votes as usual.
+
+ The problem comes when we have 7 authorities, and only a few of them
+ have smarter bandwidth allocation algorithms. So long as the majority
+ of them are voting for the number in the relay descriptor, the minority
+ that have better numbers will be ignored.
+
+2. Options
+
+ One fix would be to demand that every authority also run the
+ new bandwidth measurement algorithms: in that case, part of the
+ responsibility of being an authority operator is that you need to run
+ this code too. But in practice we can't really require all current
+ authority operators to do that; and if we want to expand the set of
+ authority operators even further, it will become even more impractical.
+ Also, bandwidth testing adds load to the network, so we don't really
+ want to require that the number of concurrent bandwidth tests match
+ the number of authorities we have.
+
+ The better fix is to allow certain authorities to specify that they are
+ voting on bandwidth measurements: more accurate bandwidth values that
+ have actually been evaluated. In this way, authorities can vote on
+ the median measured value if sufficient measured votes exist for a router,
+ and otherwise fall back to the median value taken from the published router
+ descriptors.
+
+3. Security implications
+
+ If only some authorities choose to vote on an offset, then a majority of
+ those voting authorities can arbitrarily change the bandwidth weighting
+ for the relay. At the extreme, if there's only one offset-voting
+ authority, then that authority can dictate which relays clients will
+ find attractive.
+
+ This problem isn't entirely new: we already have the worry wrt
+ the subset of authorities that vote for BadExit.
+
+ To make it not so bad, we should deploy at least three offset-voting
+ authorities.
+
+ Also, authorities that know how to vote for offsets should vote for
+ an offset of zero for new nodes, rather than choosing not to vote on
+ any offset in those cases.
+
+4. Design
+
+ First, we need a new consensus method to support this new calculation.
+
+ Now v3 votes can have an additional value on the "w" line:
+ "w Bandwidth=X Measured=" INT.
+
+ Once we're using the new consensus method, the new way to compute the
+ Bandwidth weight is by checking if there are at least 3 "Measured"
+ votes. If so, the median of these is taken. Otherwise, the median
+ of the "Bandwidth=" values are taken, as described in Proposal 141.
+
+ Then the actual consensus looks just the same as it did before,
+ so clients never have to know that this additional calculation is
+ happening.
+
+5. Implementation
+
+ The Measured values will be read from a file provided by the scanners
+ described in proposal 161. Files with a timestamp older than 3 days
+ will be ignored.
+
+ The file will be read in from dirserv_generate_networkstatus_vote_obj()
+ in a location specified by a new config option "V3MeasuredBandwidths".
+ A helper function will be called to populate new 'measured' and
+ 'has_measured' fields of the routerstatus_t 'routerstatuses' list with
+ values read from this file.
+
+ An additional for_vote flag will be passed to
+ routerstatus_format_entry() from format_networkstatus_vote(), which will
+ indicate that the "Measured=" string should be appended to the "w Bandwith="
+ line with the measured value in the struct.
+
+ routerstatus_parse_entry_from_string() will be modified to parse the
+ "Measured=" lines into routerstatus_t struct fields.
+
+ Finally, networkstatus_compute_consensus() will set rs_out.bandwidth
+ to the median of the measured values if there are more than 3, otherwise
+ it will use the bandwidth value median as normal.
+
+
+
diff --git a/doc/spec/proposals/161-computing-bandwidth-adjustments.txt b/doc/spec/proposals/161-computing-bandwidth-adjustments.txt
new file mode 100644
index 0000000000..b02dc64eb2
--- /dev/null
+++ b/doc/spec/proposals/161-computing-bandwidth-adjustments.txt
@@ -0,0 +1,188 @@
+Title: Computing Bandwidth Adjustments
+Filename: 161-computing-bandwidth-adjustments.txt
+Author: Mike Perry
+Created: 12-May-2009
+Target: 0.2.2.x
+Status: Open
+
+
+1. Motivation
+
+ There is high variance in the performance of the Tor network. Despite
+ our efforts to balance load evenly across the Tor nodes, some nodes are
+ significantly slower and more overloaded than others.
+
+ Proposal 160 describes how we can augment the directory authorities to
+ vote on measured bandwidths for routers. This proposal describes what
+ goes into the measuring process.
+
+
+2. Measurement Selection
+
+ The general idea is to determine a load factor representing the ratio
+ of the capacity of measured nodes to the rest of the network. This load
+ factor could be computed from three potentially relevant statistics:
+ circuit failure rates, circuit extend times, or stream capacity.
+
+ Circuit failure rates and circuit extend times appear to be
+ non-linearly proportional to node load. We've observed that the same
+ nodes when scanned at US nighttime hours (when load is presumably
+ lower) exhibit almost no circuit failure, and significantly faster
+ extend times than when scanned during the day.
+
+ Stream capacity, however, is much more uniform, even during US
+ nighttime hours. Moreover, it is a more intuitive representation of
+ node capacity, and also less dependent upon distance and latency
+ if amortized over large stream fetches.
+
+
+3. Average Stream Bandwidth Calculation
+
+ The average stream bandwidths are obtained by dividing the network into
+ slices of 50 nodes each, grouped according to advertised node bandwidth.
+
+ Two hop circuits are built using nodes from the same slice, and a large
+ file is downloaded via these circuits. For nodes in the first 15% of the
+ network, a 500K file will be used. For nodes in the next 15%, a 250K file
+ will be used. For nodes in next 15%, a 100K file will be used. The
+ remainder of the nodes will fetch a 75K file.[1]
+
+ This process is repeated 250 times, and average stream capacities are
+ assigned to each node from these results.
+
+ In the future, a node generator type can be created to ensure that
+ each node is chosen to participate in an equal number of circuits,
+ and the selection will continue until every live node is chosen
+ to participate in at least 7 circuits.
+
+
+4. Ratio Calculation Options
+
+ There are two options for deriving the ratios themselves. They can
+ be obtained by dividing each nodes' average stream capacity by
+ either the average for the slice, or the average for the network as a
+ whole.
+
+ Dividing by the network-wide average has the advantage that it will
+ account for issues related to unbalancing between higher vs lower
+ capacity, such as Steven Murdoch's queuing theory weighting result.
+ For this reason, we will opt for network-wide averages.
+
+
+5. Ratio Filtering
+
+ After the base ratios are calculated, a second pass is performed
+ to remove any streams with nodes of ratios less than X=0.5 from
+ the results of other nodes. In addition, all outlying streams
+ with capacity of one standard deviation below a node's average
+ are also removed.
+
+ The final ratio result will be calculated as the maximum of
+ these two resulting ratios if both are less than 1.0, the minimum
+ if both are greater than 1.0, and the mean if one is greater
+ and one is less than 1.0.
+
+
+6. Pseudocode for Ratio Calculation Algorithm
+
+ Here is the complete pseudocode for the ratio algorithm:
+
+ Slices = {S | S is 50 nodes of similar consensus capacity}
+ for S in Slices:
+ while exists node N in S with circ_chosen(N) < 7:
+ fetch_slice_file(build_2hop_circuit(N, (exit in S)))
+ for N in S:
+ BW_measured(N) = MEAN(b | b is bandwidth of a stream through N)
+ Bw_stddev(N) = STDDEV(b | b is bandwidth of a stream through N)
+ Bw_avg(S) = MEAN(b | b = BW_measured(N) for all N in S)
+ Normal_Routers(S) = {N | Bw_measured(N)/Bw_avg(S) > 0.5 }
+ for N in S:
+ Normal_Streams(N) =
+ {stream via N | all nodes in stream not in {Normal_Routers(S)-N}
+ and bandwidth > BW_measured(N)-Bw_stddev(N)}
+ BW_Norm_measured(N) = MEAN(b | b is a bandwidth of Normal_Streams(N))
+
+ Bw_net_avg(Slices) = MEAN(BW_measured(N) for all N in Slices)
+ Bw_Norm_net_avg(Slices) = MEAN(BW_Norm_measured(N) for all N in Slices)
+
+ for N in all Slices:
+ Bw_net_ratio(N) = Bw_measured(N)/Bw_net_avg(Slices)
+ Bw_Norm_net_ratio(N) = Bw_measured2(N)/Bw_Norm_net_avg(Slices)
+
+ if Bw_net_ratio(N) < 1.0 and Bw_Norm_net_ratio(N) < 1.0:
+ ResultRatio(N) = MAX(Bw_net_ratio(N), Bw_Norm_net_ratio(N))
+ else if Bw_net_ratio(N) > 1.0 and Bw_Norm_net_ratio(N) > 1.0:
+ ResultRatio(N) = MIN(Bw_net_ratio(N), Bw_Norm_net_ratio(N))
+ else:
+ ResultRatio(N) = MEAN(Bw_net_ratio(N), Bw_Norm_net_ratio(N))
+
+
+7. Security implications
+
+ The ratio filtering will deal with cases of sabotage by dropping
+ both very slow outliers in stream average calculations, as well
+ as dropping streams that used very slow nodes from the calculation
+ of other nodes.
+
+ This scheme will not address nodes that try to game the system by
+ providing better service to scanners. The scanners can be detected
+ at the entry by IP address, and at the exit by the destination fetch.
+
+ Measures can be taken to obfuscate and separate the scanners' source
+ IP address from the directory authority IP address. For instance,
+ scans can happen offsite and the results can be rsynced into the
+ authorities. The destination fetch can also be obscured by using SSL
+ and periodically changing the large document that is fetched.
+
+ Neither of these methods are foolproof, but such nodes can already
+ lie about their bandwidth to attract more traffic, so this solution
+ does not set us back any in that regard.
+
+
+8. Parallelization
+
+ Because each slice takes as long as 6 hours to complete, we will want
+ to parallelize as much as possible. This will be done by concurrently
+ running multiple scanners from each authority to deal with different
+ segments of the network. Each scanner piece will continually loop
+ over a portion of the network, outputting files of the form:
+
+ node_id=<idhex> SP strm_bw=<BW_measured(N)> SP
+ filt_bw=<BW_Norm_measured(N)> NL
+
+ The most recent file from each scanner will be periodically gathered
+ by another script that uses them to produce network-wide averages
+ and calculate ratios as per the algorithm in section 6. Because nodes
+ may shift in capacity, they may appear in more than one slice and/or
+ appear more than once in the file set. The line that yields a ratio
+ closest to 1.0 will be chosen in this case.
+
+
+9. Integration with Proposal 160
+
+ The final results will be produced for the voting mechanism
+ described in Proposal 160 by multiplying the derived ratio by
+ the average published consensus bandwidth during the course of the
+ scan, and taking the weighted average with the previous consensus
+ bandwidth:
+
+ Bw_new = (Bw_current * Alpha + Bw_scan_avg*Bw_ratio)/(Alpha + 1)
+
+ The Alpha parameter is a smoothing parameter intended to prevent
+ rapid oscillation between loaded and unloaded conditions.
+
+ This will produce a new bandwidth value that will be output into a
+ file consisting of lines of the form:
+
+ node_id=<idhex> SP bw=<Bw_new> NL
+
+ The first line of the file will contain a timestamp in UNIX time()
+ seconds. This will be used by the authority to decide if the
+ measured values are too old to use.
+
+ This file can be either copied or rsynced into a directory readable
+ by the directory authority.
+
+
+1. Exact values for each segment are still being determined via
+test scans.
diff --git a/doc/spec/proposals/162-consensus-flavors.txt b/doc/spec/proposals/162-consensus-flavors.txt
new file mode 100644
index 0000000000..80fee1e688
--- /dev/null
+++ b/doc/spec/proposals/162-consensus-flavors.txt
@@ -0,0 +1,178 @@
+Filename: 162-consensus-flavors.txt
+Title: Publish the consensus in multiple flavors
+Author: Nick Mathewson
+Created: 14-May-2009
+Target: 0.2.2
+Status: Open
+
+
+Overview:
+
+ This proposal describes a way to publish each consensus in
+ multiple simultaneous formats, or "flavors". This will reduce the
+ amount of time needed to deploy new consensus-like documents, and
+ reduce the size of consensus documents in the long term.
+
+Motivation:
+
+ In the future, we will almost surely want different fields and
+ data in the network-status document. Examples include:
+ - Publishing hashes of microdescriptors instead of hashes of
+ full descriptors (Proposal 158).
+ - Including different digests of descriptors, instead of the
+ perhaps-soon-to-be-totally-broken SHA1.
+
+ Note that in both cases, from the client's point of view, this
+ information _replaces_ older information. If we're using a
+ SHA256 hash, we don't need to see the SHA1. If clients only want
+ microdescriptors, they don't (necessarily) need to see hashes of
+ other things.
+
+ Our past approach to cases like this has been to shovel all of
+ the data into the consensus document. But this is rather poor
+ for bandwidth. Adding a single SHA256 hash to a consensus for
+ each router increases the compressed consensus size by 47%. In
+ comparison, replacing a single SHA1 hash with a SHA256 hash for
+ each listed router increases the consensus size by only 18%.
+
+Design in brief:
+
+ Let the voting process will remain as it is, until a consensus is
+ generated. With future versions of the voting algorithm, instead
+ of just a single consensus being generated, multiple consensus
+ "flavors" are produced.
+
+ Consensuses (all of them) include a list of which flavors are
+ being generated. Caches fetch and serve all flavors of consensus
+ that are listed, regardless of whether they can parse or validate
+ them, and serve them to clients. Thus, once this design is in
+ place, we won't need to deploy more cache changes in order to get
+ new flavors of consensus to be cached.
+
+ Clients download only the consensus flavor they want.
+
+A note on hashes:
+
+ Everything in this document is specified to use SHA256, and to be
+ upgradeable to use better hashes in the future.
+
+Spec modifications:
+
+ 1. URLs and changes to the current consensus format.
+
+ Every consensus flavor has a name consisting of a sequence of one
+ or more alphanumeric characters and dashes. For compatibility
+ current descriptor flavor is called "ns".
+
+ The supported consensus flavors are defined as part of the
+ authorities' consensus method.
+
+ For each supported flavors, every authority calculates another
+ consensus document of as-yet-unspecified format, and exchange
+ detached signatures for these documents as in the current consensus
+ design.
+
+ In addition to the consensus currently served at
+ /tor/status-vote/(current|next)/consensus.z , authorities serve
+ another consensus of each flavor "F" from the location
+ /tor/status-vote/(current|next)/F/consensus.z.
+
+ When caches serve these documents, they do so from the same
+ locations.
+
+ 2. Document format: generic consensus.
+
+ The format of a flavored consensus is as-yet-unspecified, except
+ that the first line is:
+ "network-status-version" SP version SP flavor NL
+
+ where version is 3 or higher, and the flavor is a string
+ consisting of alphanumeric characters and dashes, matching the
+ corresponding flavor listed in the unflavored consensus.
+
+ 3. Document format: detached signatures.
+
+ In addition to the current detached signature format, we allow
+ the first line to take the form,
+ "consensus-digest" SP flavor SP 1*(Algname "=" Digest) NL
+
+ The consensus-signatures URL should contain the signatures
+ for _all_ flavors of consensus.
+
+ 4. The consensus index:
+
+ Authorities additionally generate and serve a consensus-index
+ document. Its format is:
+
+ Header ValidAfter ValidUntil Documents Signatures
+
+ Header = "consensus-index" SP version NL
+ ValidAfter = as in a consensus
+ ValidUntil = as in a consensus
+ Documents = Document*
+ Document = "document" SP flavor SP SignedLength
+ 1*(SP AlgorithmName "=" Digest) NL
+ Signatures = Signature *
+ Signature = "directory-signature" SP algname SP identity
+ SP signing-key-digest NL signature
+
+ There must be one Document line for each generated consensus flavor
+ Each Document line describes the length of the signed portion of
+ a consensus (the signatures themselves are not included), along
+ with one or more digests of that signed portion. Digests are
+ given in hex. The algorithm "sha256" MUST be included; others
+ are allowed.
+
+ The algname part of a signature describes what algorithm was
+ used to hash the identity and signing keys, and to compute the
+ signature. The algorithm "sha256" MUST be recognized;
+ signatures with unrecognized algorithms MUST be ignored.
+ (See below).
+
+ The consensus index is made available at
+ /tor/status-vote/(current|next)/consensus-index.z.
+
+ Caches should fetch this document so they can check the
+ correctness of the different consensus documents they fetch.
+ They do not need to check anything about an unrecognized
+ consensus document beyond its digest.
+
+ 4.1. The "sha256" signature format.
+
+ The 'SHA256' signature format for directory objects is defined as
+ the RSA signature of the OAEP+-padded SHA256 digest of the SHA256
+ digest of the the item to be signed. When checking signatures,
+ the signature MUST be treated as valid if the signed material
+ begins with SHA256(SHA256(document)); this allows us to add other
+ data later.
+
+Considerations:
+
+ - We should not create a new flavor of consensus when adding a
+ field wouldn't be too onerous.
+
+ - We should not proliferate flavors lightly: clients will be
+ distinguishable based on which flavor they download.
+
+Migration:
+
+ - Stage one: authorities begin generating and serving
+ consensus-index files.
+
+ - Stage two: Caches begin downloading consenusus-index files,
+ validating them, and using them to decide what flavors of
+ consensus documents to cache. They download all listed
+ documents, and compare them to the digests given in the
+ consensus.
+
+ - Stage three: Once we want to make a significant change to the
+ consensus format, we deploy another flavor of consensus at the
+ authorities. This will immediately start getting cached by the
+ caches, and clients can start fetching the new flavor without
+ waiting a version or two for enough caches to begin supporting
+ it.
+
+Acknowledgements:
+
+ Aspects of this design and its applications to hash migration were
+ heavily influenced by IRC conversations with Marian.
diff --git a/doc/spec/proposals/163-detecting-clients.txt b/doc/spec/proposals/163-detecting-clients.txt
new file mode 100644
index 0000000000..d838b17063
--- /dev/null
+++ b/doc/spec/proposals/163-detecting-clients.txt
@@ -0,0 +1,115 @@
+Filename: 163-detecting-clients.txt
+Title: Detecting whether a connection comes from a client
+Author: Nick Mathewson
+Created: 22-May-2009
+Target: 0.2.2
+Status: Open
+
+
+Overview:
+
+ Some aspects of Tor's design require relays to distinguish
+ connections from clients from connections that come from relays.
+ The existing means for doing this is easy to spoof. We propose
+ a better approach.
+
+Motivation:
+
+ There are at least two reasons for which Tor servers want to tell
+ which connections come from clients and which come from other
+ servers:
+
+ 1) Some exits, proposal 152 notwithstanding, want to disallow
+ their use as single-hop proxies.
+ 2) Some performance-related proposals involve prioritizing
+ traffic from relays, or limiting traffic per client (but not
+ per relay).
+
+ Right now, we detect client vs server status based on how the
+ client opens circuits. (Check out the code that implements the
+ AllowSingleHopExits option if you want all the details.) This
+ method is depressingly easy to fake, though. This document
+ proposes better means.
+
+Goals:
+
+ To make grabbing relay privileges at least as difficult as just
+ running a relay.
+
+ In the analysis below, "using server privileges" means taking any
+ action that only servers are supposed to do, like delivering a
+ BEGIN cell to an exit node that doesn't allow single hop exits,
+ or claiming server-like amounts of bandwidth.
+
+Passive detection:
+
+ A connection is definitely a client connection if it takes one of
+ the TLS methods during setup that does not establish an identity
+ key.
+
+ A circuit is definitely a client circuit if it is initiated with
+ a CREATE_FAST cell, though the node could be a client or a server.
+
+ A node that's listed in a recent consensus is probably a server.
+
+ A node to which we have successfully extended circuits from
+ multiple origins is probably a server.
+
+Active detection:
+
+ If a node doesn't try to use server privileges at all, we never
+ need to care whether it's a server.
+
+ When a node or circuit tries to use server privileges, if it is
+ "definitely a client" as per above, we can refuse it immediately.
+
+ If it's "probably a server" as per above, we can accept it.
+
+ Otherwise, we have either a client, or a server that is neither
+ listed in any consensus or used by any other clients -- in other
+ words, a new or private server.
+
+ For these servers, we should attempt to build one or more test
+ circuits through them. If enough of the circuits succeed, the
+ node is a real relay. If not, it is probably a client.
+
+ While we are waiting for the test circuits to succeed, we should
+ allow a short grace period in which server privileges are
+ permitted. When a test is done, we should remember its outcome
+ for a while, so we don't need to do it again.
+
+Why it's hard to do good testing:
+
+ Doing a test circuit starting with an unlisted router requires
+ only that we have an open connection for it. Doing a test
+ circuit starting elsewhere _through_ an unlisted router--though
+ more reliable-- would require that we have a known address, port,
+ identity key, and onion key for the router. Only the address and
+ identity key are easily available via the current Tor protocol in
+ all cases.
+
+ We could fix this part by requiring that all servers support
+ BEGIN_DIR and support downloading at least a current descriptor
+ for themselves.
+
+Open questions:
+
+ What are the thresholds for the needed numbers of circuits
+ for us to decide that a node is a relay?
+
+ [Suggested answer: two circuits from two distinct hosts.]
+
+ How do we pick grace periods? How long do we remember the
+ outcome of a test?
+
+ [Suggested answer: 10 minute grace period; 48 hour memory of
+ test outcomes.]
+
+ If we can build circuits starting at a suspect node, but we don't
+ have enough information to try extending circuits elsewhere
+ through the node, should we conclude that the node is
+ "server-like" or not?
+
+ [Suggested answer: for now, just try making circuits through
+ the node. Extend this to extending circuits as needed.]
+
diff --git a/doc/spec/proposals/164-reporting-server-status.txt b/doc/spec/proposals/164-reporting-server-status.txt
new file mode 100644
index 0000000000..705f5f1a84
--- /dev/null
+++ b/doc/spec/proposals/164-reporting-server-status.txt
@@ -0,0 +1,91 @@
+Filename: 164-reporting-server-status.txt
+Title: Reporting the status of server votes
+Author: Nick Mathewson
+Created: 22-May-2009
+Target: 0.2.2
+Status: Open
+
+
+Overview:
+
+ When a given node isn't listed in the directory, it isn't always easy
+ to tell why. This proposal suggest a quick-and-dirty way for
+ authorities to export not only how they voted, but why, and a way to
+ collate the information.
+
+Motivation:
+
+ Right now, if you want to know the reason why your server was listed
+ a certain way in the Tor directory, the following steps are
+ recommended:
+
+ - Look through your log for reports of what the authority said
+ when you tried to upload.
+
+ - Look at the consensus; see if you're listed.
+
+ - Wait a while, see if things get better.
+
+ - Download the votes from all the authorities, and see how they
+ voted. Try to figure out why.
+
+ - If you think they'll listen to you, ask some authority
+ operators to look you up in their mtbf files and logs to see
+ why they voted as they did.
+
+ This is far too hard.
+
+Solution:
+
+ We should add a new vote-like information-only document that
+ authorities serve on request. Call it a "vote info". It is
+ generated at the same time as a vote, but used only for
+ determining why a server voted as it did. It is served from
+ /tor/status-vote-info/current/authority[.z]
+
+ It differs from a vote in that:
+
+ * Its vote-status field is 'vote-info'.
+
+ * It includes routers that the authority would not include
+ in its vote.
+
+ For these, it includes an "omitted" line with an English
+ message explaining why they were omitted.
+
+ * For each router, it includes a line describing its WFU and
+ MTBF. The format is:
+
+ "stability <mtbf> up-since='date'"
+ "uptime <wfu> down-since='date'"
+
+ * It describes the WFU and MTBF thresholds it requires to
+ vote for a given router in various roles in the header.
+ The format is:
+
+ "flag-requirement <flag-name> <field> <op> <value>"
+
+ e.g.
+
+ "flag-requirement Guard uptime > 80"
+
+ * It includes info on routers all of whose descriptors that
+ were uploaded but rejected over the past few hours. The
+ "r" lines for these are the same as for regular routers.
+ The other lines are omitted for these routers, and are
+ replaced with a single "rejected" line, explaining (in
+ English) why the router was rejected.
+
+
+ A status site (like Torweather or Torstatus or another
+ tool) can poll these files when they are generated, collate
+ the data, and make it available to server operators.
+
+Risks:
+
+ This document makes no provisions for caching these "vote
+ info" documents. If many people wind up fetching them
+ aggressively from the authorities, that would be bad.
+
+
+
diff --git a/doc/spec/proposals/165-simple-robust-voting.txt b/doc/spec/proposals/165-simple-robust-voting.txt
new file mode 100644
index 0000000000..d8993c9e95
--- /dev/null
+++ b/doc/spec/proposals/165-simple-robust-voting.txt
@@ -0,0 +1,119 @@
+Filename: 165-simple-robust-voting.txt
+Title: Easy migration for voting authority sets
+Author: Nick Mathewson
+Created: 2009-05-28
+Status: Open
+
+Overview:
+
+ This proposal describes any easy-to-implement, easy-to-verify way to
+ change the set of authorities without creating a "flag day" situation.
+
+Motivation:
+
+ From proposal 134 ("More robust consensus voting with diverse
+ authority sets") by Peter Palfrader:
+
+ Right now there are about five authoritative directory servers
+ in the Tor network, tho this number is expected to rise to about
+ 15 eventually.
+
+ Adding a new authority requires synchronized action from all
+ operators of directory authorities so that at any time during the
+ update at least half of all authorities are running and agree on
+ who is an authority. The latter requirement is there so that the
+ authorities can arrive at a common consensus: Each authority
+ builds the consensus based on the votes from all authorities it
+ recognizes, and so a different set of recognized authorities will
+ lead to a different consensus document.
+
+ In response to this problem, proposal 134 suggested that every
+ candidate authority list in its vote whom it believes to be an
+ authority. These A-says-B-is-an-authority relationships form a
+ directed graph. Each authority then iteratively finds the largest
+ clique in the graph and remove it, until they find one containing
+ them. They vote with this clique.
+
+ Proposal 134 had some problems:
+
+ - It had a security problem in that M hostile authorities in a
+ clique could effectively kick out M-1 honest authorities. This
+ could enable a minority of the original authorities to take over.
+
+ - It was too complex in its implications to analyze well: it took us
+ over a year to realize that it was insecure.
+
+ - It tried to solve a bigger problem: general fragmentation of
+ authority trust. Really, all we wanted to have was the ability to
+ add and remove authorities without forcing a flag day.
+
+Proposed protocol design:
+
+ A "Voting Set" is a set of authorities. Each authority has a list of
+ the voting sets it considers acceptable. These sets must always
+ contain the authority itself. Each authority lists all of these
+ voting sets in its votes.
+
+ Authorities exchange votes with every other authority in any of their
+ voting sets.
+
+ When it comes time to calculate a consensus, an authority votes with
+ whichever voting set it lists that is listed by the most members of
+ that set.
+
+ For example, suppose authority A recognizes two sets, "A B C D" and
+ "A E F G H". Suppose that the first set is recognized by all of A,
+ B, C, and D, whereas the second set is recognized only by A, E, and
+ F. Because the first set is recognize by more of the authorities in
+ it than the other one, A will vote with the first set.
+
+ Ties are broken in favor of some arbitrary function of the identity
+ keys of the authorities in the set.
+
+How to migrate authority sets:
+
+ In steady state, each authority should list only the current actual
+ voting set as accepted.
+
+ When we want to add an authority, we list two voting sets: one
+ containing all the old authorities, and one containing the old
+ authorities and the new authority too. Once all authorities are
+ listing the new set of authorities, they will start preferring that
+ set because of its size.
+
+ When we want to remove an authority, we list two voting sets: one
+ containing all the authorities, and one omitting the authority we
+ want to remove. Once enough authorities list the new set as
+ acceptable, we start having authorities stop listing the old set.
+ Once there are more listing the new set than the old set, the new set
+ will win.
+
+Data format changes:
+
+ Add a new 'voting-set' line to the vote document format. Allow it to
+ occur any number of times. Its format is:
+
+ voting-set SP 'fingerprint' SP 'fingerprint' ... NL
+
+ where each fingerprint is the hex fingerprint of an identity key of
+ an authority. Sort fingerprints in ascending order.
+
+ When the consensus method is at least 'X' (decide this when we
+ implement the proposal), add this line to the consensus format as
+ well, before the first dir-source line. [This information is not
+ redundant with the dir-source sections in the consensus: If an
+ authority is recognized didn't vote, that authority will appear in
+ the voting-set line but not in the dir-source sections.]
+
+ We don't need to list other information about authorities in our
+ vote.
+
+Migration issues:
+
+ We should keep track somewhere of which Tor client versions
+ recognized which authorities.
+
+Acknowledgments:
+
+ The design came out of an IRC conversation with Peter Palfrader. He
+ had the basic idea first.
diff --git a/doc/spec/proposals/ideas/xxx-bwrate-algs.txt b/doc/spec/proposals/ideas/xxx-bwrate-algs.txt
new file mode 100644
index 0000000000..757f5bc55e
--- /dev/null
+++ b/doc/spec/proposals/ideas/xxx-bwrate-algs.txt
@@ -0,0 +1,106 @@
+# The following two algorithms
+
+
+# Algorithm 1
+# TODO: Burst and Relay/Regular differentiation
+
+BwRate = Bandwidth Rate in Bytes Per Second
+GlobalWriteBucket = 0
+GlobalReadBucket = 0
+Epoch = Token Fill Rate in seconds: suggest 50ms=.050
+SecondCounter = 0
+MinWriteBytes = Minimum amount bytes per write
+
+Every Epoch Seconds:
+ UseMinWriteBytes = MinWriteBytes
+ WriteCnt = 0
+ ReadCnt = 0
+ BytesRead = 0
+
+ For Each Open OR Conn with pending write data:
+ WriteCnt++
+ For Each Open OR Conn:
+ ReadCnt++
+
+ BytesToRead = (BwRate*Epoch + GlobalReadBucket)/ReadCnt
+ BytesToWrite = (BwRate*Epoch + GlobalWriteBucket)/WriteCnt
+
+ if BwRate/WriteCnt < MinWriteBytes:
+ # If we aren't likely to accumulate enough bytes in a second to
+ # send a whole cell for our connections, send partials
+ Log(NOTICE, "Too many ORCons to write full blocks. Sending short packets.")
+ UseMinWriteBytes = 1
+ # Other option: We could switch to plan 2 here
+
+ # Service each writable ORConn. If there are any partial writes,
+ # return remaining bytes from this epoch to the global pool
+ For Each Open OR Conn with pending write data:
+ ORConn->write_bucket += BytesToWrite
+ if ORConn->write_bucket > UseMinWriteBytes:
+ w = write(ORConn, MIN(len(ORConn->write_data), ORConn->write_bucket))
+ # possible that w < ORConn->write_data here due to TCP pushback.
+ # We should restore the rest of the write_bucket to the global
+ # buffer
+ GlobalWriteBucket += (ORConn->write_bucket - w)
+ ORConn->write_bucket = 0
+
+ For Each Open OR Conn:
+ r = read_nonblock(ORConn, BytesToRead)
+ BytesRead += r
+
+ SecondCounter += Epoch
+ if SecondCounter < 1:
+ # Save unused bytes from this epoch to be used later in the second
+ GlobalReadBucket += (BwRate*Epoch - BytesRead)
+ else:
+ SecondCounter = 0
+ GlobalReadBucket = 0
+ GlobalWriteBucket = 0
+ For Each ORConn:
+ ORConn->write_bucket = 0
+
+
+
+# Alternate plan for Writing fairly. Reads would still be covered
+# by plan 1 as there is no additional network overhead for short reads,
+# so we don't need to try to avoid them.
+#
+# I think this is actually pretty similar to what we do now, but
+# with the addition that the bytes accumulate up to the second mark
+# and we try to keep track of our position in the write list here
+# (unless libevent is doing that for us already and I just don't see it)
+#
+# TODO: Burst and Relay/Regular differentiation
+
+# XXX: The inability to send single cells will cause us to block
+# on EXTEND cells for low-bandwidth node pairs..
+BwRate = Bandwidth Rate in Bytes Per Second
+WriteBytes = Bytes per write
+Epoch = MAX(MIN(WriteBytes/BwRate, .333s), .050s)
+
+SecondCounter = 0
+GlobalWriteBucket = 0
+
+# New connections are inserted at Head-1 (the 'tail' of this circular list)
+# This is not 100% fifo for all node data, but it is the best we can do
+# without insane amounts of additional queueing complexity.
+WriteConnList = List of Open OR Conns with pending write data > WriteBytes
+WriteConnHead = 0
+
+Every Epoch Seconds:
+ GlobalWriteBucket += BwRate*Epoch
+ WriteListEnd = WriteConnHead
+
+ do
+ ORCONN = WriteConnList[WriteConnHead]
+ w = write(ORConn, WriteBytes)
+ GlobalWriteBucket -= w
+ WriteConnHead += 1
+ while GlobalWriteBucket > 0 and WriteConnHead != WriteListEnd
+
+ SecondCounter += Epoch
+ if SecondCounter >= 1:
+ SecondCounter = 0
+ GlobalWriteBucket = 0
+
+
diff --git a/doc/spec/proposals/ideas/xxx-choosing-crypto-in-tor-protocol.txt b/doc/spec/proposals/ideas/xxx-choosing-crypto-in-tor-protocol.txt
new file mode 100644
index 0000000000..e8489570f7
--- /dev/null
+++ b/doc/spec/proposals/ideas/xxx-choosing-crypto-in-tor-protocol.txt
@@ -0,0 +1,138 @@
+Filename: xxx-choosing-crypto-in-tor-protocol.txt
+Title: Picking cryptographic standards in the Tor wire protocol
+Author: Marian
+Created: 2009-05-16
+Status: Draft
+
+Motivation:
+
+ SHA-1 is horribly outdated and not suited for security critical
+ purposes. SHA-2, RIPEMD-160, Whirlpool and Tigerare good options
+ for a short-term replacement, but in the long run, we will
+ probably want to upgrade to the winner or a semi-finalist of the
+ SHA-3 competition.
+
+ For a 2006 comparison of different hash algorithms, read:
+ http://www.sane.nl/sane2006/program/final-papers/R10.pdf
+
+ Other reading about SHA-1:
+ http://www.schneier.com/blog/archives/2005/02/sha1_broken.html
+ http://www.schneier.com/blog/archives/2005/08/new_cryptanalyt.html
+ http://www.schneier.com/paper-preimages.html
+
+ Additionally, AES has been theoretically broken for years. While
+ the attack is still not efficient enough that the public sector
+ has been able to prove that it works, we should probably consider
+ the time between a theoretical attack and a practical attack as an
+ opportunity to figure out how to upgrade to a better algorithm,
+ such as Twofish.
+
+ See:
+ http://schneier.com/crypto-gram-0209.html#1
+
+Design:
+
+ I suggest that nodes should publish in directories which
+ cryptographic standards, such as hash algorithms and ciphers,
+ they support. Clients communicating with nodes will then
+ pick whichever of those cryptographic standards they prefer
+ the most. In the case that the node does not publish which
+ cryptographic standards it supports, the client should assume
+ that the server supports the older standards, such as SHA-1
+ and AES, until such time as we choose to desupport those
+ standards.
+
+ Node to node communications could work similarly. However, in
+ case they both support a set of algorithms but have different
+ preferences, the disagreement would have to be resolved
+ somehow. Two possibilities include:
+ * the node requesting communications presents which
+ cryptographic standards it supports in the request. The
+ other node picks.
+ * both nodes send each other lists of what they support and
+ what version of Tor they are using. The newer node picks,
+ based on the assumption that the newer node has the most up
+ to date information about which hash algorithm is the best.
+ Of course, the node could lie about its version, but then
+ again, it could also maliciously choose only to support older
+ algorithms.
+
+ Using this method, we could potentially add server side support
+ to hash algorithms and ciphers before we instruct clients to
+ begin preferring those hash algorithms and ciphers. In this way,
+ the clients could upgrade and the servers would already support
+ the newly preferred hash algorithms and ciphers, even if the
+ servers were still using older versions of Tor, so long as the
+ older versions of Tor were at least new enough to have server
+ side support.
+
+ This would make quickly upgrading to new hash algorithms and
+ ciphers easier. This could be very useful when new attacks
+ are published.
+
+ One concern is that client preferences could expose the client
+ to segmentation attacks. To mitigate this, we suggest hardcoding
+ preferences in the client, to prevent the client from choosing
+ to use a new hash algorithm or cipher that no one else is using
+ yet. While offering a preference might be useful in case a client
+ with an older version of Tor wants to start using the newer hash
+ algorithm or cipher that everyone else is using, if the client
+ cares enough, he or she can just upgrade Tor.
+
+ We may also have to worry about nodes which, through laziness or
+ maliciousness, refuse to start supporting new hash algorithms or
+ ciphers. This must be balanced with the need to maintain
+ backward compatibility so the client will have a large selection
+ of nodes to pick from. Adding new hash algorithms and ciphers
+ long before we suggest nodes start using them can help mitigate
+ this. However, eventually, once sufficient nodes support new
+ standards, client side support for older standards should be
+ disabled, particularly if there are practical rather than merely
+ theoretical attacks.
+
+ Server side support for older standards can be kept much longer
+ than client side support, since clients using older hashes and
+ ciphers are really only hurting theirselvse.
+
+ If server side support for a hash algorithm or cipher is added
+ but never preferred before we decide we don't really want it,
+ support can be removed without having to worry about backward
+ compatibility.
+
+Security implications:
+ Improving cryptography will improve Tor's security. However, if
+ clients pick different cryptographic standards, they could be
+ partitioned based on their cryptographic preferences. We also
+ need to worry about nodes refusing to support new standards.
+ These issues are detailed above.
+
+Specification:
+
+ Todo. Need better understanding of how Tor currently works or
+ help from someone who does.
+
+Compatibility:
+
+ This idea is intended to allow easier upgrading of cryptographic
+ hash algorithms and ciphers while maintaining backwards
+ compatibility. However, at some point, backwards compatibility
+ with very old hashes and ciphers should be dropped for security
+ reasons.
+
+Implementation:
+
+ Todo.
+
+Performance and scalability nodes:
+
+ Better hashes and cipher are someimes a little more CPU intensive
+ than weaker ones. For instance, on most computers AES is a little
+ faster than Twofish. However, in that example, I consider Twofish's
+ additional security worth the tradeoff.
+
+Acknowledgements:
+
+ Discussed this on IRC with a few people, mostly Nick Mathewson.
+ Nick was particularly helpful in explaining how Tor works,
+ explaining goals, and providing various links to Tor
+ specifications.
diff --git a/doc/spec/proposals/ideas/xxx-encrypted-services.txt b/doc/spec/proposals/ideas/xxx-encrypted-services.txt
new file mode 100644
index 0000000000..3414f3c4fb
--- /dev/null
+++ b/doc/spec/proposals/ideas/xxx-encrypted-services.txt
@@ -0,0 +1,18 @@
+
+the basic idea might be to generate a keypair, and sign little statements
+like "this key corresponds to this relay id", and publish them on karsten's
+hs dht.
+
+so if you want to talk to it, you look it up, then go to that exit.
+and by 'go to' i mean 'build a tor circuit like normal except you're sure
+where to exit'
+
+connecting to it is slower than usual, but once you're connected, it's no
+slower than normal tor.
+and you get what wikileaks wants from its hidden service, which is really
+just the UI piece.
+indymedia also wants this.
+
+might be interesting to let an encrypted service list more than one relay,
+too.
+
diff --git a/doc/spec/proposals/ideas/xxx-hide-platform.txt b/doc/spec/proposals/ideas/xxx-hide-platform.txt
index 3fed5cfbd4..ad19fb1fd4 100644
--- a/doc/spec/proposals/ideas/xxx-hide-platform.txt
+++ b/doc/spec/proposals/ideas/xxx-hide-platform.txt
@@ -1,7 +1,5 @@
Filename: xxx-hide-platform.txt
Title: Hide Tor Platform Information
-Version: $Revision$
-Last-Modified: $Date$
Author: Jacob Appelbaum
Created: 24-July-2008
Status: Draft
diff --git a/doc/spec/proposals/ideas/xxx-port-knocking.txt b/doc/spec/proposals/ideas/xxx-port-knocking.txt
index 9fbcdf3545..85c27ec52d 100644
--- a/doc/spec/proposals/ideas/xxx-port-knocking.txt
+++ b/doc/spec/proposals/ideas/xxx-port-knocking.txt
@@ -1,7 +1,5 @@
Filename: xxx-port-knocking.txt
Title: Port knocking for bridge scanning resistance
-Version: $Revision$
-Last-Modified: $Date$
Author: Jacob Appelbaum
Created: 19-April-2009
Status: Draft
diff --git a/doc/spec/proposals/ideas/xxx-separate-streams-by-port.txt b/doc/spec/proposals/ideas/xxx-separate-streams-by-port.txt
index cebde65a9b..f26c1e580f 100644
--- a/doc/spec/proposals/ideas/xxx-separate-streams-by-port.txt
+++ b/doc/spec/proposals/ideas/xxx-separate-streams-by-port.txt
@@ -1,7 +1,5 @@
Filename: xxx-separate-streams-by-port.txt
Title: Separate streams across circuits by destination port
-Version: $Revision$
-Last-Modified: $Date$
Author: Robert Hogan
Created: 21-Oct-2008
Status: Draft
diff --git a/doc/spec/proposals/ideas/xxx-what-uses-sha1.txt b/doc/spec/proposals/ideas/xxx-what-uses-sha1.txt
index 9b6e20c586..b3ca3eea5a 100644
--- a/doc/spec/proposals/ideas/xxx-what-uses-sha1.txt
+++ b/doc/spec/proposals/ideas/xxx-what-uses-sha1.txt
@@ -1,8 +1,6 @@
Filename: xxx-what-uses-sha1.txt
Title: Where does Tor use SHA-1 today?
-Version: $Revision$
-Last-Modified: $Date$
-Author: Nick Mathewson
+Authors: Nick Mathewson, Marian
Created: 30-Dec-2008
Status: Meta
@@ -15,9 +13,15 @@ Introduction:
too long.
According to smart crypto people, the SHA-2 functions (SHA-256, etc)
- share too much of SHA-1's structure to be very good. Some people
- like other hash functions; most of these have not seen enough
- analysis to be widely regarded as an extra-good idea.
+ share too much of SHA-1's structure to be very good. RIPEMD-160 is
+ also based on flawed past hashes. Some people think other hash
+ functions (e.g. Whirlpool and Tiger) are not as bad; most of these
+ have not seen enough analysis to be used yet.
+
+ Here is a 2006 paper about hash algorithms.
+ http://www.sane.nl/sane2006/program/final-papers/R10.pdf
+
+ (Todo: Ask smart crypto people.)
By 2012, the NIST SHA-3 competition will be done, and with luck we'll
have something good to switch too. But it's probably a bad idea to
@@ -54,50 +58,138 @@ Why now?
one look silly.
+Triage
+
+ How severe are these problems? Let's divide them into these
+ categories, where H(x) is the SHA-1 hash of x:
+ PREIMAGE -- find any x such that a H(x) has a chosen value
+ -- A SHA-1 usage that only depends on preimage
+ resistance
+ * Also SECOND PREIMAGE. Given x, find a y not equal to
+ x such that H(x) = H(y)
+ COLLISION<role> -- A SHA-1 usage that depends on collision
+ resistance, but the only party who could mount a
+ collision-based attack is already in a trusted role
+ (like a distribution signer or a directory authority).
+ COLLISION -- find any x and y such that H(x) = H(y) -- A
+ SHA-1 usage that depends on collision resistance
+ and doesn't need the attacker to have any special keys.
+
+ There is no need to put much effort into fixing PREIMAGE and SECOND
+ PREIMAGE usages in the near-term: while there have been some
+ theoretical results doing these attacks against SHA-1, they don't
+ seem to be close to practical yet. To fix COLLISION<code-signing>
+ usages is not too important either, since anyone who has the key to
+ sign the code can mount far worse attacks. It would be good to fix
+ COLLISION<authority> usages, since we try to resist bad authorities
+ to a limited extent. The COLLISION usages are the most important
+ to fix.
+
+ Kelsey and Schneier published a theoretical second preimage attack
+ against SHA-1 in 2005, so it would be a good idea to fix PREIMAGE
+ and SECOND PREIMAGE usages after fixing COLLISION usages or where fixes
+ require minimal effort.
+
+ http://www.schneier.com/paper-preimages.html
+
+ Additionally, we need to consider the impact of a successful attack
+ in each of these cases. SHA-1 collisions are still expensive even
+ if recent results are verified, and anybody with the resources to
+ compute one also has the resources to mount a decent Sybil attack.
+
+ Let's be pessimistic, and not assume that producing collisions of
+ a given format is actually any harder than producing collisions at
+ all.
+
What Tor uses hashes for today:
1. Infrastructure.
A. Our X.509 certificates are signed with SHA-1.
+ COLLSION
B. TLS uses SHA-1 (and MD5) internally to generate keys.
+ PREIMAGE?
+ * At least breaking SHA-1 and MD5 simultaneously is
+ much more difficult than breaking either
+ independently.
C. Some of the TLS ciphersuites we allow use SHA-1.
+ PREIMAGE?
D. When we sign our code with GPG, it might be using SHA-1.
+ COLLISION<code-signing>
+ * GPG 1.4 and up have writing support for SHA-2 hashes.
+ This blog has help for converting:
+ http://www.schwer.us/journal/2005/02/19/sha-1-broken-and-gnupg-gpg/
E. Our GPG keys might be authenticated with SHA-1.
+ COLLISION<code-signing-key-signing>
F. OpenSSL's random number generator uses SHA-1, I believe.
+ PREIMAGE
2. The Tor protocol
A. Everything we sign, we sign using SHA-1-based OAEP-MGF1.
+ PREIMAGE?
B. Our CREATE cell format uses SHA-1 for: OAEP padding.
+ PREIMAGE?
C. Our EXTEND cells use SHA-1 to hash the identity key of the
target server.
+ COLLISION
D. Our CREATED cells use SHA-1 to hash the derived key data.
+ ??
E. The data we use in CREATE_FAST cells to generate a key is the
length of a SHA-1.
+ NONE
F. The data we send back in a CREATED/CREATED_FAST cell is the length
of a SHA-1.
- G. We use SHA-1 to derive our circuit keys from the negotiated g^xy value.
+ NONE
+ G. We use SHA-1 to derive our circuit keys from the negotiated g^xy
+ value.
+ NONE
H. We use SHA-1 to derive the digest field of each RELAY cell, but that's
used more as a checksum than as a strong digest.
+ NONE
3. Directory services
+ [All are COLLISION or COLLISION<authority> ]
+
A. All signatures are generated on the SHA-1 of their corresponding
documents, using PKCS1 padding.
+ * In dir-spec.txt, section 1.3, it states,
+ "SIGNATURE" Object contains a signature (using the signing key)
+ of the PKCS1-padded digest of the entire document, taken from
+ the beginning of the Initial item, through the newline after
+ the Signature Item's keyword and its arguments."
+ So our attacker, Malcom, could generate a collision for the hash
+ that is signed. Thus, a second pre-image attack is possible.
+ Vulnerable to regular collision attack only if key is stolen.
+ If the key is stolen, Malcom could distribute two different
+ copies of the document which have the same hash. Maybe useful
+ for a partitioning attack?
B. Router descriptors identify their corresponding extra-info documents
by their SHA-1 digest.
+ * A third party might use a second pre-image attack to generate a
+ false extra-info document that has the same hash. The router
+ itself might use a regular collision attack to generate multiple
+ extra-info documents with the same hash, which might be useful
+ for a partitioning attack.
C. Fingerprints in router descriptors are taken using SHA-1.
- D. Fingerprints in authority certs are taken using SHA-1.
- E. Fingerprints in dir-source lines of votes and consensuses are taken
+ * The fingerprint must match the public key. Not sure what would
+ happen if two routers had different public keys but the same
+ fingerprint. There could perhaps be unpredictable behaviour.
+ D. In router descriptors, routers in the same "Family" may be listed
+ by server nicknames or hexdigests.
+ * Does not seem critical.
+ E. Fingerprints in authority certs are taken using SHA-1.
+ F. Fingerprints in dir-source lines of votes and consensuses are taken
using SHA-1.
- F. Networkstatuses refer to routers identity keys and descriptors by their
+ G. Networkstatuses refer to routers identity keys and descriptors by their
SHA-1 digests.
- G. Directory-signature lines identify which key is doing the signing by
+ H. Directory-signature lines identify which key is doing the signing by
the SHA-1 digests of the authority's signing key and its identity key.
- H. The following items are downloaded by the SHA-1 of their contents:
+ I. The following items are downloaded by the SHA-1 of their contents:
XXXX list them
- I. The following items are downloaded by the SHA-1 of an identity key:
+ J. The following items are downloaded by the SHA-1 of an identity key:
XXXX list them too.
4. The rendezvous protocol
@@ -107,6 +199,12 @@ What Tor uses hashes for today:
establishment requests.
B. Hidden servers use SHA-1 in multiple places when generating hidden
service descriptors.
+ * The permanent-id is the first 80 bits of the SHA-1 hash of the
+ public key
+ ** time-period performs caclulations using the permanent-id
+ * The secret-id-part is the SHA-1 has of the time period, the
+ descriptor-cookie, and replica.
+ * Hash of introduction point's identity key.
C. Hidden servers performing basic-type client authorization for their
services use SHA-1 when encrypting introduction points contained in
hidden service descriptors.
@@ -115,26 +213,35 @@ What Tor uses hashes for today:
identifier or not.
E. Hidden servers use SHA-1 to derive .onion addresses of their
services.
+ * What's worse, it only uses the first 80 bits of the SHA-1 hash.
+ However, the rend-spec.txt says we aren't worried about arbitrary
+ collisons?
F. Clients use SHA-1 to generate the current hidden service descriptor
identifiers for a given .onion address.
G. Hidden servers use SHA-1 to remember digests of the first parts of
Diffie-Hellman handshakes contained in introduction requests in order
- to detect replays.
+ to detect replays. See the RELAY_ESTABLISH_INTRO cell. We seem to be
+ taking a hash of a hash here.
H. Hidden servers use SHA-1 during the Diffie-Hellman key exchange with
a connecting client.
5. The bridge protocol
XXXX write me
+
+ A. Client may attempt to query for bridges where he knows a digest
+ (probably SHA-1) before a direct query.
6. The Tor user interface
A. We log information about servers based on SHA-1 hashes of their
identity keys.
+ COLLISION
B. The controller identifies servers based on SHA-1 hashes of their
identity keys.
+ COLLISION
C. Nearly all of our configuration options that list servers allow SHA-1
hashes of their identity keys.
+ COLLISION
E. The deprecated .exit notation uses SHA-1 hashes of identity keys
-
-
+ COLLISION
diff --git a/doc/spec/proposals/reindex.py b/doc/spec/proposals/reindex.py
index 2b4c02516b..980bc0659f 100755
--- a/doc/spec/proposals/reindex.py
+++ b/doc/spec/proposals/reindex.py
@@ -4,7 +4,7 @@ import re, os
class Error(Exception): pass
STATUSES = """DRAFT NEEDS-REVISION NEEDS-RESEARCH OPEN ACCEPTED META FINISHED
- CLOSED SUPERSEDED DEAD""".split()
+ CLOSED SUPERSEDED DEAD REJECTED""".split()
REQUIRED_FIELDS = [ "Filename", "Status", "Title" ]
CONDITIONAL_FIELDS = { "OPEN" : [ "Target" ],
"ACCEPTED" : [ "Target "],
diff --git a/doc/spec/rend-spec.txt b/doc/spec/rend-spec.txt
index e3fbe2253b..f030092679 100644
--- a/doc/spec/rend-spec.txt
+++ b/doc/spec/rend-spec.txt
@@ -1,4 +1,3 @@
-$Id$
Tor Rendezvous Specification
@@ -145,33 +144,10 @@ $Id$
1.2. Bob's OP generates service descriptors.
The first time the OP provides an advertised service, it generates
- a public/private keypair (stored locally). Periodically, the OP
- generates and publishes a descriptor of type "V0".
+ a public/private keypair (stored locally).
- The "V0" descriptor contains:
-
- KL Key length [2 octets]
- PK Bob's public key [KL octets]
- TS A timestamp [4 octets]
- NI Number of introduction points [2 octets]
- Ipt A list of NUL-terminated ORs [variable]
- SIG Signature of above fields [variable]
-
- KL is the length of PK, in octets.
- TS is the number of seconds elapsed since Jan 1, 1970.
-
- The members of Ipt may be either (a) nicknames, or (b) identity key
- digests, encoded in hex, and prefixed with a '$'. Clients must
- accept both forms. Services must only generate the second form.
- Once 0.0.9.x is obsoleted, we can drop the first form.
-
- [It's ok for Bob to advertise 0 introduction points. He might want
- to do that if he previously advertised some introduction points,
- and now he doesn't have any. -RD]
-
- Beginning with 0.2.0.10-alpha, Bob's OP encodes "V2" descriptors in
- addition to "V0" descriptors. The format of a "V2" descriptor is as
- follows:
+ Beginning with 0.2.0.10-alpha, Bob's OP encodes "V2" descriptors. The
+ format of a "V2" descriptor is as follows:
"rendezvous-service-descriptor" descriptor-id NL
@@ -340,6 +316,10 @@ $Id$
(This ends the fields in the encrypted portion of the descriptor.)
+ [It's ok for Bob to advertise 0 introduction points. He might want
+ to do that if he previously advertised some introduction points,
+ and now he doesn't have any. -RD]
+
"signature" NL signature-string
[At end, exactly once]
@@ -349,6 +329,21 @@ $Id$
1.2.1. Other descriptor formats we don't use.
+ Support for the V0 descriptor format was dropped in 0.2.2.0-alpha-dev:
+
+ KL Key length [2 octets]
+ PK Bob's public key [KL octets]
+ TS A timestamp [4 octets]
+ NI Number of introduction points [2 octets]
+ Ipt A list of NUL-terminated ORs [variable]
+ SIG Signature of above fields [variable]
+
+ KL is the length of PK, in octets.
+ TS is the number of seconds elapsed since Jan 1, 1970.
+
+ The members of Ipt may be either (a) nicknames, or (b) identity key
+ digests, encoded in hex, and prefixed with a '$'.
+
The V1 descriptor format was understood and accepted from
0.1.1.5-alpha-cvs to 0.2.0.6-alpha-dev, but no Tors generated it and
it was removed:
@@ -409,7 +404,7 @@ $Id$
RELAY_ESTABLISH_INTRO cell, containing:
KL Key length [2 octets]
- PK Bob's public key [KL octets]
+ PK Introduction public key [KL octets]
HS Hash of session info [20 octets]
SIG Signature of above information [variable]
@@ -431,16 +426,13 @@ $Id$
currently associated with PK. On success, the OR sends Bob a
RELAY_INTRO_ESTABLISHED cell with an empty payload.
- If a hidden service is configured to publish only v2 hidden service
- descriptors, Bob's OP does not include its own public key in the
- RELAY_ESTABLISH_INTRO cell, but the public key of a freshly generated
- key pair. The OP also includes these fresh public keys in the v2 hidden
- service descriptor together with the other introduction point
- information. The reason is that the introduction point does not need to
- and therefore should not know for which hidden service it works, so as
- to prevent it from tracking the hidden service's activity. If the hidden
- service is configured to publish both, v0 and v2 descriptors, two
- separate sets of introduction points are established.
+ Bob's OP does not include its own public key in the RELAY_ESTABLISH_INTRO
+ cell, but the public key of a freshly generated introduction key pair.
+ The OP also includes these fresh public keys in the v2 hidden service
+ descriptor together with the other introduction point information. The
+ reason is that the introduction point does not need to and therefore
+ should not know for which hidden service it works, so as to prevent it
+ from tracking the hidden service's activity.
1.4. Bob's OP advertises his service descriptor(s).
@@ -464,10 +456,8 @@ $Id$
after its timestamp. At least every 18 hours, Bob's OP uploads a
fresh descriptor.
- If Bob's OP is configured to publish v2 descriptors instead of or in
- addition to v0 descriptors, it does so to a changing subset of all v2
- hidden service directories instead of the authoritative directory
- servers. Therefore, Bob's OP opens a stream via Tor to each
+ Bob's OP publishes v2 descriptors to a changing subset of all v2 hidden
+ service directories. Therefore, Bob's OP opens a stream via Tor to each
responsible hidden service directory. (He may re-use old circuits
for this.) Over this stream, Bob's OP makes an HTTP 'POST' request to a
URL "/tor/rendezvous2/publish" relative to the hidden service
@@ -520,12 +510,21 @@ $Id$
1.6. Alice's OP retrieves a service descriptor.
- Alice opens a stream to a directory server via Tor, and makes an HTTP GET
- request for the document '/tor/rendezvous/<z>', where '<z>' is replaced
- with the encoding of Bob's public key as described above. (She may re-use
- old circuits for this.) The directory replies with a 404 HTTP response if
- it does not recognize <z>, and otherwise returns Bob's most recently
- uploaded service descriptor.
+ Similarly to the description in section 1.4, Alice's OP fetches a v2
+ descriptor from a randomly chosen hidden service directory out of the
+ changing subset of 6 nodes. If the request is unsuccessful, Alice retries
+ the other remaining responsible hidden service directories in a random
+ order. Alice relies on Bob to care about a potential clock skew between
+ the two by possibly storing two sets of descriptors (see end of section
+ 1.4).
+
+ Alice's OP opens a stream via Tor to the chosen v2 hidden service
+ directory. (She may re-use old circuits for this.) Over this stream,
+ Alice's OP makes an HTTP 'GET' request for the document
+ "/tor/rendezvous2/<z>", where z is replaced with the encoding of the
+ descriptor ID. The directory replies with a 404 HTTP response if it does
+ not recognize <z>, and otherwise returns Bob's most recently uploaded
+ service descriptor.
If Alice's OP receives a 404 response, it tries the other directory
servers, and only fails the lookup if none recognize the public key hash.
@@ -541,22 +540,6 @@ $Id$
[Caching may make her partitionable, but she fetched it anonymously,
and we can't very well *not* cache it. -RD]
- Alice's OP fetches v2 descriptors in parallel to v0 descriptors. Similarly
- to the description in section 1.4, the OP fetches a v2 descriptor from a
- randomly chosen hidden service directory out of the changing subset of
- 6 nodes. If the request is unsuccessful, Alice retries the other
- remaining responsible hidden service directories in a random order.
- Alice relies on Bob to care about a potential clock skew between the two
- by possibly storing two sets of descriptors (see end of section 1.4).
-
- Alice's OP opens a stream via Tor to the chosen v2 hidden service
- directory. (She may re-use old circuits for this.) Over this stream,
- Alice's OP makes an HTTP 'GET' request for the document
- "/tor/rendezvous2/<z>", where z is replaced with the encoding of the
- descriptor ID. The directory replies with a 404 HTTP response if it does
- not recognize <z>, and otherwise returns Bob's most recently uploaded
- service descriptor.
-
1.7. Alice's OP establishes a rendezvous point.
When Alice requests a connection to a given location-hidden service,
diff --git a/doc/spec/socks-extensions.txt b/doc/spec/socks-extensions.txt
index 8d58987f35..62d86acd9f 100644
--- a/doc/spec/socks-extensions.txt
+++ b/doc/spec/socks-extensions.txt
@@ -1,4 +1,3 @@
-$Id$
Tor's extensions to the SOCKS protocol
1. Overview
diff --git a/doc/spec/tor-spec.txt b/doc/spec/tor-spec.txt
index 77a91cad8e..9ae22a92d7 100644
--- a/doc/spec/tor-spec.txt
+++ b/doc/spec/tor-spec.txt
@@ -1,4 +1,3 @@
-$Id$
Tor Protocol Specification
diff --git a/doc/spec/version-spec.txt b/doc/spec/version-spec.txt
index 842271ae19..265717f409 100644
--- a/doc/spec/version-spec.txt
+++ b/doc/spec/version-spec.txt
@@ -1,4 +1,3 @@
-$Id$
HOW TOR VERSION NUMBERS WORK
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 105c413343..ad54e1aaaa 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -1,6 +1,8 @@
noinst_LIBRARIES = libor.a libor-crypto.a
+EXTRA_DIST = common_sha1.i
+
#CFLAGS = -Wall -Wpointer-arith -O2
if USE_OPENBSD_MALLOC
@@ -10,7 +12,19 @@ libor_extra_source=
endif
libor_a_SOURCES = address.c log.c util.c compat.c container.c mempool.c \
- memarea.c $(libor_extra_source)
+ memarea.c util_codedigest.c $(libor_extra_source)
libor_crypto_a_SOURCES = crypto.c aes.c tortls.c torgzip.c
noinst_HEADERS = address.h log.h crypto.h test.h util.h compat.h aes.h torint.h tortls.h strlcpy.c strlcat.c torgzip.h container.h ht.h mempool.h memarea.h ciphers.inc
+
+common_sha1.i: $(libor_SOURCES) $(libor_crypto_a_SOURCES) $(noinst_HEADERS)
+ if test "@SHA1SUM@" != none; then \
+ @SHA1SUM@ $(libor_SOURCES) $(libor_crypto_a_SOURCES) $(noinst_HEADERS) | @SED@ -n 's/^\(.*\)$$/"\1\\n"/p' > common_sha1.i; \
+ elif test "@OPENSSL@" != none; then \
+ @OPENSSL@ sha1 $(libor_SOURCES) $(libor_crypto_a_SOURCES) $(noinst_HEADERS) | @SED@ -n 's/SHA1(\(.*\))= \(.*\)/"\2 \1\\n"/p' > common_sha1.i; \
+ else \
+ rm common_sha1.i; \
+ touch common_sha1.i; \
+ fi
+
+util_codedigest.o: common_sha1.i
diff --git a/src/common/ht.h b/src/common/ht.h
index b31492ec3c..5187c90e6f 100644
--- a/src/common/ht.h
+++ b/src/common/ht.h
@@ -42,6 +42,10 @@
#define HT_SIZE(head) \
((head)->hth_n_entries)
+/* Return memory usage for a hashtable (not counting the entries themselves) */
+#define HT_MEM_USAGE(head) \
+ (sizeof(*head) + (head)->hth_table_length * sizeof(void*))
+
#define HT_FIND(name, head, elm) name##_HT_FIND((head), (elm))
#define HT_INSERT(name, head, elm) name##_HT_INSERT((head), (elm))
#define HT_REPLACE(name, head, elm) name##_HT_REPLACE((head), (elm))
diff --git a/src/common/memarea.c b/src/common/memarea.c
index 1c81e2fd78..e7f6720646 100644
--- a/src/common/memarea.c
+++ b/src/common/memarea.c
@@ -13,6 +13,10 @@
#include "compat.h"
#include "log.h"
+/** If true, we try to detect any attempts to write beyond the length of a
+ * memarea. */
+#define USE_SENTINELS
+
/** All returned pointers should be aligned to the nearest multiple of this
* value. */
#define MEMAREA_ALIGN SIZEOF_VOID_P
@@ -25,6 +29,24 @@
#error "void* is neither 4 nor 8 bytes long. I don't know how to align stuff."
#endif
+#ifdef USE_SENTINELS
+#define SENTINEL_VAL 0x90806622u
+#define SENTINEL_LEN sizeof(uint32_t)
+#define SET_SENTINEL(chunk) \
+ STMT_BEGIN \
+ set_uint32( &(chunk)->u.mem[chunk->mem_size], SENTINEL_VAL ); \
+ STMT_END
+#define CHECK_SENTINEL(chunk) \
+ STMT_BEGIN \
+ uint32_t sent_val = get_uint32(&(chunk)->u.mem[chunk->mem_size]); \
+ tor_assert(sent_val == SENTINEL_VAL); \
+ STMT_END
+#else
+#define SENTINEL_LEN 0
+#define SET_SENTINEL(chunk) STMT_NIL
+#define CHECK_SENTINEL(chunk) STMT_NIL
+#endif
+
/** Increment <b>ptr</b> until it is aligned to MEMAREA_ALIGN. */
static INLINE void *
realign_pointer(void *ptr)
@@ -78,15 +100,20 @@ alloc_chunk(size_t sz, int freelist_ok)
freelist = res->next_chunk;
res->next_chunk = NULL;
--freelist_len;
+ CHECK_SENTINEL(res);
return res;
} else {
size_t chunk_size = freelist_ok ? CHUNK_SIZE : sz;
- memarea_chunk_t *res = tor_malloc_roundup(&chunk_size);
+ memarea_chunk_t *res;
+ chunk_size += SENTINEL_LEN;
+ res = tor_malloc_roundup(&chunk_size);
res->next_chunk = NULL;
- res->mem_size = chunk_size - CHUNK_HEADER_SIZE;
+ res->mem_size = chunk_size - CHUNK_HEADER_SIZE - SENTINEL_LEN;
res->next_mem = res->u.mem;
- tor_assert(res->next_mem+res->mem_size == ((char*)res)+chunk_size);
+ tor_assert(res->next_mem+res->mem_size+SENTINEL_LEN ==
+ ((char*)res)+chunk_size);
tor_assert(realign_pointer(res->next_mem) == res->next_mem);
+ SET_SENTINEL(res);
return res;
}
}
@@ -96,6 +123,7 @@ alloc_chunk(size_t sz, int freelist_ok)
static void
chunk_free(memarea_chunk_t *chunk)
{
+ CHECK_SENTINEL(chunk);
if (freelist_len < MAX_FREELIST_LEN) {
++freelist_len;
chunk->next_chunk = freelist;
@@ -182,6 +210,7 @@ memarea_alloc(memarea_t *area, size_t sz)
memarea_chunk_t *chunk = area->first;
char *result;
tor_assert(chunk);
+ CHECK_SENTINEL(chunk);
if (sz == 0)
sz = 1;
if (chunk->next_mem+sz > chunk->u.mem+chunk->mem_size) {
@@ -258,6 +287,7 @@ memarea_get_stats(memarea_t *area, size_t *allocated_out, size_t *used_out)
size_t a = 0, u = 0;
memarea_chunk_t *chunk;
for (chunk = area->first; chunk; chunk = chunk->next_chunk) {
+ CHECK_SENTINEL(chunk);
a += CHUNK_HEADER_SIZE + chunk->mem_size;
tor_assert(chunk->next_mem >= chunk->u.mem);
u += CHUNK_HEADER_SIZE + (chunk->next_mem - chunk->u.mem);
@@ -274,6 +304,7 @@ memarea_assert_ok(memarea_t *area)
tor_assert(area->first);
for (chunk = area->first; chunk; chunk = chunk->next_chunk) {
+ CHECK_SENTINEL(chunk);
tor_assert(chunk->next_mem >= chunk->u.mem);
tor_assert(chunk->next_mem <=
(char*) realign_pointer(chunk->u.mem+chunk->mem_size));
diff --git a/src/common/util.h b/src/common/util.h
index dca2f86cd1..18033f39df 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -294,5 +294,7 @@ void start_daemon(void);
void finish_daemon(const char *desired_cwd);
void write_pidfile(char *filename);
+const char *libor_get_digests(void);
+
#endif
diff --git a/src/common/util_codedigest.c b/src/common/util_codedigest.c
new file mode 100644
index 0000000000..88fe508b92
--- /dev/null
+++ b/src/common/util_codedigest.c
@@ -0,0 +1,11 @@
+
+#include "util.h"
+
+const char *
+libor_get_digests(void)
+{
+ return ""
+#include "common_sha1.i"
+ ;
+}
+
diff --git a/src/config/torrc.complete.in b/src/config/torrc.complete.in
index 310458a5c0..2fbf494e56 100644
--- a/src/config/torrc.complete.in
+++ b/src/config/torrc.complete.in
@@ -1,5 +1,3 @@
-# $Id$
-# Last updated on $Date$
####################################################################
## This config file is divided into four sections. They are:
## 1. Global Options (clients and servers)
diff --git a/src/or/Makefile.am b/src/or/Makefile.am
index 28d7e736dc..11923fbd35 100644
--- a/src/or/Makefile.am
+++ b/src/or/Makefile.am
@@ -10,7 +10,7 @@ else
tor_platform_source=
endif
-EXTRA_DIST=ntmain.c
+EXTRA_DIST=ntmain.c or_sha1.i
tor_SOURCES = buffers.c circuitbuild.c circuitlist.c \
circuituse.c command.c config.c \
@@ -20,7 +20,7 @@ tor_SOURCES = buffers.c circuitbuild.c circuitlist.c \
networkstatus.c onion.c policies.c \
reasons.c relay.c rendcommon.c rendclient.c rendmid.c \
rendservice.c rephist.c router.c routerlist.c routerparse.c \
- eventdns.c \
+ eventdns.c config_codedigest.c \
tor_main.c
AM_CPPFLAGS = -DSHARE_DATADIR="\"$(datadir)\"" \
@@ -42,7 +42,7 @@ test_SOURCES = buffers.c circuitbuild.c circuitlist.c \
networkstatus.c onion.c policies.c \
reasons.c relay.c rendcommon.c rendclient.c rendmid.c \
rendservice.c rephist.c router.c routerlist.c routerparse.c \
- eventdns.c \
+ eventdns.c config_codedigest.c \
test_data.c test.c
test_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \
@@ -52,6 +52,8 @@ test_LDADD = ../common/libor.a ../common/libor-crypto.a \
noinst_HEADERS = or.h eventdns.h eventdns_tor.h micro-revision.i
+config_codedigest.o: or_sha1.i
+
tor_main.o: micro-revision.i
micro-revision.i: FORCE
@@ -103,5 +105,17 @@ micro-revision.i: FORCE
mv micro-revision.tmp micro-revision.i; \
fi; true
+or_sha1.i: $(tor_SOURCES) test_data.c test.c
+ if test "@SHA1SUM@" != none; then \
+ @SHA1SUM@ $(tor_SOURCES) test_data.c test.c | @SED@ -n 's/^\(.*\)$$/"\1\\n"/p' > or_sha1.i; \
+ elif test "@OPENSSL@" != none; then \
+ @OPENSSL@ sha1 $(tor_SOURCES) test_data.c test.c | @SED@ -n 's/SHA1(\(.*\))= \(.*\)/"\2 \1\\n"/p' > or_sha1.i; \
+ else \
+ rm or_sha1.i; \
+ touch or_sha1.i; \
+ fi
+
+
+
#Dummy target to ensure that micro-revision.i _always_ gets built.
FORCE:
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 777f16aad2..a70594ba38 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -2849,8 +2849,7 @@ int
getinfo_helper_entry_guards(control_connection_t *conn,
const char *question, char **answer)
{
- int use_long_names = conn->use_long_names;
-
+ (void) conn;
if (!strcmp(question,"entry-guards") ||
!strcmp(question,"helper-nodes")) {
smartlist_t *sl = smartlist_create();
@@ -2858,12 +2857,13 @@ getinfo_helper_entry_guards(control_connection_t *conn,
char nbuf[MAX_VERBOSE_NICKNAME_LEN+1];
if (!entry_guards)
entry_guards = smartlist_create();
- SMARTLIST_FOREACH(entry_guards, entry_guard_t *, e,
- {
+ SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, e) {
size_t len = MAX_VERBOSE_NICKNAME_LEN+ISO_TIME_LEN+32;
char *c = tor_malloc(len);
const char *status = NULL;
time_t when = 0;
+ routerinfo_t *ri;
+
if (!e->made_contact) {
status = "never-connected";
} else if (e->bad_since) {
@@ -2872,19 +2872,17 @@ getinfo_helper_entry_guards(control_connection_t *conn,
} else {
status = "up";
}
- if (use_long_names) {
- routerinfo_t *ri = router_get_by_digest(e->identity);
- if (ri) {
- router_get_verbose_nickname(nbuf, ri);
- } else {
- nbuf[0] = '$';
- base16_encode(nbuf+1, sizeof(nbuf)-1, e->identity, DIGEST_LEN);
- /* e->nickname field is not very reliable if we don't know about
- * this router any longer; don't include it. */
- }
+
+ ri = router_get_by_digest(e->identity);
+ if (ri) {
+ router_get_verbose_nickname(nbuf, ri);
} else {
- base16_encode(nbuf, sizeof(nbuf), e->identity, DIGEST_LEN);
+ nbuf[0] = '$';
+ base16_encode(nbuf+1, sizeof(nbuf)-1, e->identity, DIGEST_LEN);
+ /* e->nickname field is not very reliable if we don't know about
+ * this router any longer; don't include it. */
}
+
if (when) {
format_iso_time(tbuf, when);
tor_snprintf(c, len, "%s %s %s\n", nbuf, status, tbuf);
@@ -2892,7 +2890,7 @@ getinfo_helper_entry_guards(control_connection_t *conn,
tor_snprintf(c, len, "%s %s\n", nbuf, status);
}
smartlist_add(sl, c);
- });
+ } SMARTLIST_FOREACH_END(e);
*answer = smartlist_join_strings(sl, "", 0, NULL);
SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
smartlist_free(sl);
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 6a54c34397..a2110a4da4 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -1111,12 +1111,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
log_info(LD_REND,
"No intro points for '%s': re-fetching service descriptor.",
safe_str(conn->rend_data->onion_address));
- /* Fetch both, v0 and v2 rend descriptors in parallel. Use whichever
- * arrives first. Exception: When using client authorization, only
- * fetch v2 descriptors.*/
rend_client_refetch_v2_renddesc(conn->rend_data);
- if (conn->rend_data->auth_type == REND_NO_AUTH)
- rend_client_refetch_renddesc(conn->rend_data->onion_address);
conn->_base.state = AP_CONN_STATE_RENDDESC_WAIT;
return 0;
}
diff --git a/src/or/config.c b/src/or/config.c
index b192ca8ffa..0cf0db7578 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -187,10 +187,10 @@ static config_var_t _option_vars[] = {
V(DirPortFrontPage, FILENAME, NULL),
OBSOLETE("DirPostPeriod"),
#ifdef ENABLE_GEOIP_STATS
- V(DirRecordUsageByCountry, BOOL, "0"),
- V(DirRecordUsageGranularity, UINT, "4"),
- V(DirRecordUsageRetainIPs, INTERVAL, "14 days"),
- V(DirRecordUsageSaveInterval, INTERVAL, "6 hours"),
+ OBSOLETE("DirRecordUsageByCountry"),
+ OBSOLETE("DirRecordUsageGranularity"),
+ OBSOLETE("DirRecordUsageRetainIPs"),
+ OBSOLETE("DirRecordUsageSaveInterval"),
#endif
VAR("DirServer", LINELIST, DirServers, NULL),
V(DNSPort, UINT, "0"),
@@ -1280,14 +1280,14 @@ options_act(or_options_t *old_options)
return 0;
/* Finish backgrounding the process */
- if (running_tor && options->RunAsDaemon) {
+ if (options->RunAsDaemon) {
/* We may be calling this for the n'th time (on SIGHUP), but it's safe. */
finish_daemon(options->DataDirectory);
}
/* Write our PID to the PID file. If we do not have write permissions we
* will log a warning */
- if (running_tor && options->PidFile)
+ if (options->PidFile)
write_pidfile(options->PidFile);
/* Register addressmap directives */
@@ -3954,6 +3954,12 @@ options_init_from_torrc(int argc, char **argv)
printf("Tor version %s.\n",get_version());
exit(0);
}
+ if (argc > 1 && (!strcmp(argv[1],"--digests"))) {
+ printf("Tor version %s.\n",get_version());
+ printf("%s", libor_get_digests());
+ printf("%s", tor_get_digests());
+ exit(0);
+ }
/* Go through command-line variables */
if (!global_cmdline_options) {
diff --git a/src/or/config_codedigest.c b/src/or/config_codedigest.c
new file mode 100644
index 0000000000..be9eaa331d
--- /dev/null
+++ b/src/or/config_codedigest.c
@@ -0,0 +1,11 @@
+
+const char *tor_get_digests(void);
+
+const char *
+tor_get_digests(void)
+{
+ return ""
+#include "or_sha1.i"
+ ;
+}
+
diff --git a/src/or/connection.c b/src/or/connection.c
index 32ae259cf1..66a62c549a 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -544,13 +544,6 @@ connection_about_to_close_connection(connection_t *conn)
* failed: forget about this router, and maybe try again. */
connection_dir_request_failed(dir_conn);
}
- if (conn->purpose == DIR_PURPOSE_FETCH_RENDDESC && dir_conn->rend_data) {
- /* Give it a try. However, there is no re-fetching for v0 rend
- * descriptors; if the response is empty or the descriptor is
- * unusable, close pending connections (unless a v2 request is
- * still in progress). */
- rend_client_desc_trynow(dir_conn->rend_data->onion_address, 0);
- }
/* If we were trying to fetch a v2 rend desc and did not succeed,
* retry as needed. (If a fetch is successful, the connection state
* is changed to DIR_PURPOSE_HAS_FETCHED_RENDDESC to mark that
@@ -2577,13 +2570,11 @@ connection_get_by_type_state(int type, int state)
/** Return a connection of type <b>type</b> that has rendquery equal
* to <b>rendquery</b>, and that is not marked for close. If state
- * is non-zero, conn must be of that state too. If rendversion is
- * nonnegative, conn must be fetching that rendversion, too.
+ * is non-zero, conn must be of that state too.
*/
connection_t *
connection_get_by_type_state_rendquery(int type, int state,
- const char *rendquery,
- int rendversion)
+ const char *rendquery)
{
smartlist_t *conns = get_connection_array();
@@ -2598,8 +2589,6 @@ connection_get_by_type_state_rendquery(int type, int state,
(!state || state == conn->state)) {
if (type == CONN_TYPE_DIR &&
TO_DIR_CONN(conn)->rend_data &&
- (rendversion < 0 ||
- rendversion == TO_DIR_CONN(conn)->rend_data->rend_desc_version) &&
!rend_cmp_service_ids(rendquery,
TO_DIR_CONN(conn)->rend_data->onion_address))
return conn;
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 9b1f737917..6207ad3178 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -1676,12 +1676,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
conn->_base.state = AP_CONN_STATE_RENDDESC_WAIT;
log_info(LD_REND, "Unknown descriptor %s. Fetching.",
safe_str(conn->rend_data->onion_address));
- /* Fetch both, v0 and v2 rend descriptors in parallel. Use whichever
- * arrives first. Exception: When using client authorization, only
- * fetch v2 descriptors.*/
rend_client_refetch_v2_renddesc(conn->rend_data);
- if (conn->rend_data->auth_type == REND_NO_AUTH)
- rend_client_refetch_renddesc(conn->rend_data->onion_address);
} else { /* r > 0 */
/** How long after we receive a hidden service descriptor do we consider
* it valid? */
@@ -1698,12 +1693,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
conn->_base.state = AP_CONN_STATE_RENDDESC_WAIT;
log_info(LD_REND, "Stale descriptor %s. Re-fetching.",
safe_str(conn->rend_data->onion_address));
- /* Fetch both, v0 and v2 rend descriptors in parallel. Use whichever
- * arrives first. Exception: When using client authorization, only
- * fetch v2 descriptors.*/
rend_client_refetch_v2_renddesc(conn->rend_data);
- if (conn->rend_data->auth_type == REND_NO_AUTH)
- rend_client_refetch_renddesc(conn->rend_data->onion_address);
}
}
return 0;
diff --git a/src/or/control.c b/src/or/control.c
index 8ded31574c..2052b967c7 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -54,13 +54,9 @@
**/
typedef uint32_t event_mask_t;
-/** An event mask of all the events that controller with the LONG_NAMES option
- * set is interested in receiving. */
-static event_mask_t global_event_mask1long = 0;
-
-/** An event mask of all the events that controller with the SHORT_NAMES option
- * set is interested in receiving. */
-static event_mask_t global_event_mask1short = 0;
+/** An event mask of all the events that any controller is interested in
+ * receiving. */
+static event_mask_t global_event_mask = 0;
/** True iff we have disabled log messages from being sent to the controller */
static int disable_log_messages = 0;
@@ -68,13 +64,7 @@ static int disable_log_messages = 0;
/** Macro: true if any control connection is interested in events of type
* <b>e</b>. */
#define EVENT_IS_INTERESTING(e) \
- ((global_event_mask1long|global_event_mask1short) & (1<<(e)))
-/** Macro: true if any control connection with the LONG_NAMES option is
- * interested in events of type <b>e</b>. */
-#define EVENT_IS_INTERESTING1L(e) (global_event_mask1long & (1<<(e)))
-/** Macro: true if any control connection with the SHORT_NAMES option is
- * interested in events of type <b>e</b>. */
-#define EVENT_IS_INTERESTING1S(e) (global_event_mask1short & (1<<(e)))
+ (global_event_mask & (1<<(e)))
/** If we're using cookie-type authentication, how long should our cookies be?
*/
@@ -95,25 +85,13 @@ static char authentication_cookie[AUTHENTICATION_COOKIE_LEN];
* of this so we can respond to getinfo status/bootstrap-phase queries. */
static char last_sent_bootstrap_message[BOOTSTRAP_MSG_LEN];
-/** Flag for event_format_t. Indicates that we should use the old
- * name format of nickname|hexdigest
- */
-#define SHORT_NAMES 1
-/** Flag for event_format_t. Indicates that we should use the new
- * name format of $hexdigest[=~]nickname
+/** Flag for event_format_t. Indicates that we should use the one standard
+ format.
*/
-#define LONG_NAMES 2
-#define ALL_NAMES (SHORT_NAMES|LONG_NAMES)
-/** Flag for event_format_t. Indicates that we should use the new event
- * format where extra event fields are allowed using a NAME=VAL format. */
-#define EXTENDED_FORMAT 4
-/** Flag for event_format_t. Indicates that we are using the old event format
- * where extra fields aren't allowed. */
-#define NONEXTENDED_FORMAT 8
-#define ALL_FORMATS (EXTENDED_FORMAT|NONEXTENDED_FORMAT)
+#define ALL_FORMATS 1
/** Bit field of flags to select how to format a controller event. Recognized
- * flags are SHORT_NAMES, LONG_NAMES, EXTENDED_FORMAT, NONEXTENDED_FORMAT. */
+ * flag is ALL_FORMATS. */
typedef int event_format_t;
static void connection_printf_to_buf(control_connection_t *conn,
@@ -123,9 +101,6 @@ static void send_control_done(control_connection_t *conn);
static void send_control_event(uint16_t event, event_format_t which,
const char *format, ...)
CHECK_PRINTF(3,4);
-static void send_control_event_extended(uint16_t event, event_format_t which,
- const char *format, ...)
- CHECK_PRINTF(3,4);
static int handle_control_setconf(control_connection_t *conn, uint32_t len,
char *body);
static int handle_control_resetconf(control_connection_t *conn, uint32_t len,
@@ -174,7 +149,7 @@ static int handle_control_usefeature(control_connection_t *conn,
const char *body);
static int write_stream_target_to_buf(edge_connection_t *conn, char *buf,
size_t len);
-static void orconn_target_get_name(int long_names, char *buf, size_t len,
+static void orconn_target_get_name(char *buf, size_t len,
or_connection_t *conn);
static char *get_cookie_file(void);
@@ -214,25 +189,19 @@ control_update_global_event_mask(void)
{
smartlist_t *conns = get_connection_array();
event_mask_t old_mask, new_mask;
- old_mask = global_event_mask1short;
- old_mask |= global_event_mask1long;
+ old_mask = global_event_mask;
- global_event_mask1short = 0;
- global_event_mask1long = 0;
+ global_event_mask = 0;
SMARTLIST_FOREACH(conns, connection_t *, _conn,
{
if (_conn->type == CONN_TYPE_CONTROL &&
STATE_IS_OPEN(_conn->state)) {
control_connection_t *conn = TO_CONTROL_CONN(_conn);
- if (conn->use_long_names)
- global_event_mask1long |= conn->event_mask;
- else
- global_event_mask1short |= conn->event_mask;
+ global_event_mask |= conn->event_mask;
}
});
- new_mask = global_event_mask1short;
- new_mask |= global_event_mask1long;
+ new_mask = global_event_mask;
/* Handle the aftermath. Set up the log callback to tell us only what
* we want to hear...*/
@@ -542,28 +511,15 @@ send_control_event_string(uint16_t event, event_format_t which,
const char *msg)
{
smartlist_t *conns = get_connection_array();
+ (void)which;
tor_assert(event >= _EVENT_MIN && event <= _EVENT_MAX);
- SMARTLIST_FOREACH(conns, connection_t *, conn,
- {
+ SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
if (conn->type == CONN_TYPE_CONTROL &&
!conn->marked_for_close &&
conn->state == CONTROL_CONN_STATE_OPEN) {
control_connection_t *control_conn = TO_CONTROL_CONN(conn);
- if (control_conn->use_long_names) {
- if (!(which & LONG_NAMES))
- continue;
- } else {
- if (!(which & SHORT_NAMES))
- continue;
- }
- if (control_conn->use_extended_events) {
- if (!(which & EXTENDED_FORMAT))
- continue;
- } else {
- if (!(which & NONEXTENDED_FORMAT))
- continue;
- }
+
if (control_conn->event_mask & (1<<event)) {
int is_err = 0;
connection_write_to_buf(msg, strlen(msg), TO_CONN(control_conn));
@@ -579,7 +535,7 @@ send_control_event_string(uint16_t event, event_format_t which,
connection_handle_write(TO_CONN(control_conn), 1);
}
}
- });
+ } SMARTLIST_FOREACH_END(conn);
}
/** Helper for send_control1_event and send_control1_event_extended:
@@ -587,22 +543,17 @@ send_control_event_string(uint16_t event, event_format_t which,
* <b>event</b>. The event's body is created by the printf-style format in
* <b>format</b>, and other arguments as provided.
*
- * If <b>extended</b> is true, and the format contains a single '@' character,
- * it will be replaced with a space and all text after that character will be
- * sent only to controllers that have enabled extended events.
- *
* Currently the length of the message is limited to 1024 (including the
* ending \\r\\n\\0). */
static void
-send_control_event_impl(uint16_t event, event_format_t which, int extended,
- const char *format, va_list ap)
+send_control_event_impl(uint16_t event, event_format_t which,
+ const char *format, va_list ap)
{
/* This is just a little longer than the longest allowed log message */
#define SEND_CONTROL1_EVENT_BUFFERSIZE 10064
int r;
char buf[SEND_CONTROL1_EVENT_BUFFERSIZE];
size_t len;
- char *cp;
r = tor_vsnprintf(buf, sizeof(buf), format, ap);
if (r<0) {
@@ -618,15 +569,7 @@ send_control_event_impl(uint16_t event, event_format_t which, int extended,
buf[SEND_CONTROL1_EVENT_BUFFERSIZE-3] = '\r';
}
- if (extended && (cp = strchr(buf, '@'))) {
- which &= ~ALL_FORMATS;
- *cp = ' ';
- send_control_event_string(event, which|EXTENDED_FORMAT, buf);
- memcpy(cp, "\r\n\0", 3);
- send_control_event_string(event, which|NONEXTENDED_FORMAT, buf);
- } else {
- send_control_event_string(event, which|ALL_FORMATS, buf);
- }
+ send_control_event_string(event, which|ALL_FORMATS, buf);
}
/** Send an event to all v1 controllers that are listening for code
@@ -641,27 +584,7 @@ send_control_event(uint16_t event, event_format_t which,
{
va_list ap;
va_start(ap, format);
- send_control_event_impl(event, which, 0, format, ap);
- va_end(ap);
-}
-
-/** Send an event to all v1 controllers that are listening for code
- * <b>event</b>. The event's body is created by the printf-style format in
- * <b>format</b>, and other arguments as provided.
- *
- * If the format contains a single '@' character, it will be replaced with a
- * space and all text after that character will be sent only to controllers
- * that have enabled extended events.
- *
- * Currently the length of the message is limited to 1024 (including the
- * ending \\n\\r\\0. */
-static void
-send_control_event_extended(uint16_t event, event_format_t which,
- const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- send_control_event_impl(event, which, 1, format, ap);
+ send_control_event_impl(event, which, format, ap);
va_end(ap);
}
@@ -948,7 +871,6 @@ handle_control_setevents(control_connection_t *conn, uint32_t len,
{
uint16_t event_code;
uint32_t event_mask = 0;
- unsigned int extended = 0;
smartlist_t *events = smartlist_create();
(void) len;
@@ -958,7 +880,6 @@ handle_control_setevents(control_connection_t *conn, uint32_t len,
SMARTLIST_FOREACH_BEGIN(events, const char *, ev)
{
if (!strcasecmp(ev, "EXTENDED")) {
- extended = 1;
continue;
} else if (!strcasecmp(ev, "CIRC"))
event_code = EVENT_CIRCUIT_STATUS;
@@ -1016,8 +937,6 @@ handle_control_setevents(control_connection_t *conn, uint32_t len,
smartlist_free(events);
conn->event_mask = event_mask;
- if (extended)
- conn->use_extended_events = 1;
control_update_global_event_mask();
send_control_done(conn);
@@ -1463,6 +1382,7 @@ static int
getinfo_helper_dir(control_connection_t *control_conn,
const char *question, char **answer)
{
+ (void) control_conn;
if (!strcmpstart(question, "desc/id/")) {
routerinfo_t *ri = router_get_by_hexdigest(question+strlen("desc/id/"));
if (ri) {
@@ -1597,10 +1517,8 @@ getinfo_helper_dir(control_connection_t *control_conn,
}
} else if (!strcmp(question, "network-status")) { /* v1 */
routerlist_t *routerlist = router_get_routerlist();
- int verbose = control_conn->use_long_names;
if (!routerlist || !routerlist->routers ||
- list_server_status_v1(routerlist->routers, answer,
- verbose ? 2 : 1) < 0) {
+ list_server_status_v1(routerlist->routers, answer, 1) < 0) {
return -1;
}
} else if (!strcmpstart(question, "extra-info/digest/")) {
@@ -1636,6 +1554,7 @@ static int
getinfo_helper_events(control_connection_t *control_conn,
const char *question, char **answer)
{
+ (void) control_conn;
if (!strcmp(question, "circuit-status")) {
circuit_t *circ;
smartlist_t *status = smartlist_create();
@@ -1646,10 +1565,9 @@ getinfo_helper_events(control_connection_t *control_conn,
const char *purpose;
if (! CIRCUIT_IS_ORIGIN(circ) || circ->marked_for_close)
continue;
- if (control_conn->use_long_names)
- path = circuit_list_path_for_controller(TO_ORIGIN_CIRCUIT(circ));
- else
- path = circuit_list_path(TO_ORIGIN_CIRCUIT(circ),0);
+
+ path = circuit_list_path_for_controller(TO_ORIGIN_CIRCUIT(circ));
+
if (circ->state == CIRCUIT_STATE_OPEN)
state = "BUILT";
else if (strlen(path))
@@ -1727,8 +1645,7 @@ getinfo_helper_events(control_connection_t *control_conn,
} else if (!strcmp(question, "orconn-status")) {
smartlist_t *conns = get_connection_array();
smartlist_t *status = smartlist_create();
- SMARTLIST_FOREACH(conns, connection_t *, base_conn,
- {
+ SMARTLIST_FOREACH_BEGIN(conns, connection_t *, base_conn) {
const char *state;
char *s;
char name[128];
@@ -1743,29 +1660,19 @@ getinfo_helper_events(control_connection_t *control_conn,
state = "LAUNCHED";
else
state = "NEW";
- orconn_target_get_name(control_conn->use_long_names, name, sizeof(name),
- conn);
+ orconn_target_get_name(name, sizeof(name), conn);
slen = strlen(name)+strlen(state)+2;
s = tor_malloc(slen+1);
tor_snprintf(s, slen, "%s %s", name, state);
smartlist_add(status, s);
- });
+ } SMARTLIST_FOREACH_END(base_conn);
*answer = smartlist_join_strings(status, "\r\n", 0, NULL);
SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
smartlist_free(status);
- } else if (!strcmpstart(question, "addr-mappings/") ||
- !strcmpstart(question, "address-mappings/")) {
+ } else if (!strcmpstart(question, "address-mappings/")) {
time_t min_e, max_e;
smartlist_t *mappings;
- int want_expiry = !strcmpstart(question, "address-mappings/");
- if (!strcmpstart(question, "addr-mappings/")) {
- /* XXXX022 This has been deprecated since 0.2.0.3-alpha, and has
- generated a warning since 0.2.1.10-alpha; remove late in 0.2.2.x. */
- log_warn(LD_CONTROL, "Controller used obsolete addr-mappings/ GETINFO "
- "key; use address-mappings/ instead.");
- }
- question += strlen(want_expiry ? "address-mappings/"
- : "addr-mappings/");
+ question += strlen("address-mappings/");
if (!strcmp(question, "all")) {
min_e = 0; max_e = TIME_MAX;
} else if (!strcmp(question, "cache")) {
@@ -1778,7 +1685,7 @@ getinfo_helper_events(control_connection_t *control_conn,
return 0;
}
mappings = smartlist_create();
- addressmap_get_mappings(mappings, min_e, max_e, want_expiry);
+ addressmap_get_mappings(mappings, min_e, max_e, 1);
*answer = smartlist_join_strings(mappings, "\r\n", 0, NULL);
SMARTLIST_FOREACH(mappings, char *, cp, tor_free(cp));
smartlist_free(mappings);
@@ -1940,14 +1847,6 @@ static const getinfo_item_t getinfo_items[] = {
DOC("address-mappings/config",
"Current address mappings from configuration."),
DOC("address-mappings/control", "Current address mappings from controller."),
- PREFIX("addr-mappings/", events, NULL),
- DOC("addr-mappings/all", "Current address mappings without expiry times."),
- DOC("addr-mappings/cache",
- "Current cached DNS replies without expiry times."),
- DOC("addr-mappings/config",
- "Current address mappings from configuration without expiry times."),
- DOC("addr-mappings/control",
- "Current address mappings from controller without expiry times."),
PREFIX("status/", events, NULL),
DOC("status/circuit-established",
"Whether we think client functionality is working."),
@@ -2705,7 +2604,6 @@ handle_control_usefeature(control_connection_t *conn,
const char *body)
{
smartlist_t *args;
- int verbose_names = 0, extended_events = 0;
int bad = 0;
(void) len; /* body is nul-terminated; it's safe to ignore the length */
args = smartlist_create();
@@ -2713,9 +2611,9 @@ handle_control_usefeature(control_connection_t *conn,
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
SMARTLIST_FOREACH(args, const char *, arg, {
if (!strcasecmp(arg, "VERBOSE_NAMES"))
- verbose_names = 1;
+ ;
else if (!strcasecmp(arg, "EXTENDED_EVENTS"))
- extended_events = 1;
+ ;
else {
connection_printf_to_buf(conn, "552 Unrecognized feature \"%s\"\r\n",
arg);
@@ -2725,12 +2623,6 @@ handle_control_usefeature(control_connection_t *conn,
});
if (!bad) {
- if (verbose_names) {
- conn->use_long_names = 1;
- control_update_global_event_mask();
- }
- if (extended_events)
- conn->use_extended_events = 1;
send_control_done(conn);
}
@@ -3028,20 +2920,11 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp,
tor_free(reason);
}
- if (EVENT_IS_INTERESTING1S(EVENT_CIRCUIT_STATUS)) {
- char *path = circuit_list_path(circ,0);
- const char *sp = strlen(path) ? " " : "";
- send_control_event_extended(EVENT_CIRCUIT_STATUS, SHORT_NAMES,
- "650 CIRC %lu %s%s%s@%s\r\n",
- (unsigned long)circ->global_identifier,
- status, sp, path, extended_buf);
- tor_free(path);
- }
- if (EVENT_IS_INTERESTING1L(EVENT_CIRCUIT_STATUS)) {
+ {
char *vpath = circuit_list_path_for_controller(circ);
const char *sp = strlen(vpath) ? " " : "";
- send_control_event_extended(EVENT_CIRCUIT_STATUS, LONG_NAMES,
- "650 CIRC %lu %s%s%s@%s\r\n",
+ send_control_event(EVENT_CIRCUIT_STATUS, ALL_FORMATS,
+ "650 CIRC %lu %s%s%s %s\r\n",
(unsigned long)circ->global_identifier,
status, sp, vpath, extended_buf);
tor_free(vpath);
@@ -3177,8 +3060,8 @@ control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp,
circ = circuit_get_by_edge_conn(conn);
if (circ && CIRCUIT_IS_ORIGIN(circ))
origin_circ = TO_ORIGIN_CIRCUIT(circ);
- send_control_event_extended(EVENT_STREAM_STATUS, ALL_NAMES,
- "650 STREAM "U64_FORMAT" %s %lu %s@%s%s%s\r\n",
+ send_control_event(EVENT_STREAM_STATUS, ALL_FORMATS,
+ "650 STREAM "U64_FORMAT" %s %lu %s %s%s%s\r\n",
U64_PRINTF_ARG(conn->_base.global_identifier), status,
origin_circ?
(unsigned long)origin_circ->global_identifier : 0ul,
@@ -3191,30 +3074,21 @@ control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp,
/** Figure out the best name for the target router of an OR connection
* <b>conn</b>, and write it into the <b>len</b>-character buffer
- * <b>name</b>. Use verbose names if <b>long_names</b> is set. */
+ * <b>name</b>. */
static void
-orconn_target_get_name(int long_names,
- char *name, size_t len, or_connection_t *conn)
-{
- if (! long_names) {
- if (conn->nickname)
- strlcpy(name, conn->nickname, len);
- else
- tor_snprintf(name, len, "%s:%d",
- conn->_base.address, conn->_base.port);
+orconn_target_get_name(char *name, size_t len, or_connection_t *conn)
+{
+ routerinfo_t *ri = router_get_by_digest(conn->identity_digest);
+ if (ri) {
+ tor_assert(len > MAX_VERBOSE_NICKNAME_LEN);
+ router_get_verbose_nickname(name, ri);
+ } else if (! tor_digest_is_zero(conn->identity_digest)) {
+ name[0] = '$';
+ base16_encode(name+1, len-1, conn->identity_digest,
+ DIGEST_LEN);
} else {
- routerinfo_t *ri = router_get_by_digest(conn->identity_digest);
- if (ri) {
- tor_assert(len > MAX_VERBOSE_NICKNAME_LEN);
- router_get_verbose_nickname(name, ri);
- } else if (! tor_digest_is_zero(conn->identity_digest)) {
- name[0] = '$';
- base16_encode(name+1, len-1, conn->identity_digest,
- DIGEST_LEN);
- } else {
- tor_snprintf(name, len, "%s:%d",
- conn->_base.address, conn->_base.port);
- }
+ tor_snprintf(name, len, "%s:%d",
+ conn->_base.address, conn->_base.port);
}
}
@@ -3253,24 +3127,13 @@ control_event_or_conn_status(or_connection_t *conn, or_conn_status_event_t tp,
reason ? " " : "", ncircs);
}
- if (EVENT_IS_INTERESTING1S(EVENT_OR_CONN_STATUS)) {
- orconn_target_get_name(0, name, sizeof(name), conn);
- send_control_event_extended(EVENT_OR_CONN_STATUS, SHORT_NAMES,
- "650 ORCONN %s %s@%s%s%s\r\n",
- name, status,
- reason ? "REASON=" : "",
- orconn_end_reason_to_control_string(reason),
- ncircs_buf);
- }
- if (EVENT_IS_INTERESTING1L(EVENT_OR_CONN_STATUS)) {
- orconn_target_get_name(1, name, sizeof(name), conn);
- send_control_event_extended(EVENT_OR_CONN_STATUS, LONG_NAMES,
- "650 ORCONN %s %s@%s%s%s\r\n",
- name, status,
- reason ? "REASON=" : "",
- orconn_end_reason_to_control_string(reason),
- ncircs_buf);
- }
+ orconn_target_get_name(name, sizeof(name), conn);
+ send_control_event(EVENT_OR_CONN_STATUS, ALL_FORMATS,
+ "650 ORCONN %s %s %s%s%s\r\n",
+ name, status,
+ reason ? "REASON=" : "",
+ orconn_end_reason_to_control_string(reason),
+ ncircs_buf);
return 0;
}
@@ -3285,7 +3148,7 @@ control_event_stream_bandwidth(edge_connection_t *edge_conn)
if (!edge_conn->n_read && !edge_conn->n_written)
return 0;
- send_control_event(EVENT_STREAM_BANDWIDTH_USED, ALL_NAMES,
+ send_control_event(EVENT_STREAM_BANDWIDTH_USED, ALL_FORMATS,
"650 STREAM_BW "U64_FORMAT" %lu %lu\r\n",
U64_PRINTF_ARG(edge_conn->_base.global_identifier),
(unsigned long)edge_conn->n_read,
@@ -3314,7 +3177,7 @@ control_event_stream_bandwidth_used(void)
if (!edge_conn->n_read && !edge_conn->n_written)
continue;
- send_control_event(EVENT_STREAM_BANDWIDTH_USED, ALL_NAMES,
+ send_control_event(EVENT_STREAM_BANDWIDTH_USED, ALL_FORMATS,
"650 STREAM_BW "U64_FORMAT" %lu %lu\r\n",
U64_PRINTF_ARG(edge_conn->_base.global_identifier),
(unsigned long)edge_conn->n_read,
@@ -3334,7 +3197,7 @@ int
control_event_bandwidth_used(uint32_t n_read, uint32_t n_written)
{
if (EVENT_IS_INTERESTING(EVENT_BANDWIDTH_USED)) {
- send_control_event(EVENT_BANDWIDTH_USED, ALL_NAMES,
+ send_control_event(EVENT_BANDWIDTH_USED, ALL_FORMATS,
"650 BW %lu %lu\r\n",
(unsigned long)n_read,
(unsigned long)n_written);
@@ -3399,7 +3262,7 @@ control_event_logmsg(int severity, uint32_t domain, const char *msg)
default: s = "UnknownLogSeverity"; break;
}
++disable_log_messages;
- send_control_event(event, ALL_NAMES, "650 %s %s\r\n", s, b?b:msg);
+ send_control_event(event, ALL_FORMATS, "650 %s %s\r\n", s, b?b:msg);
--disable_log_messages;
tor_free(b);
}
@@ -3412,31 +3275,12 @@ control_event_logmsg(int severity, uint32_t domain, const char *msg)
int
control_event_descriptors_changed(smartlist_t *routers)
{
- size_t len;
char *msg;
- smartlist_t *identities = NULL;
- char buf[HEX_DIGEST_LEN+1];
if (!EVENT_IS_INTERESTING(EVENT_NEW_DESC))
return 0;
- if (EVENT_IS_INTERESTING1S(EVENT_NEW_DESC)) {
- identities = smartlist_create();
- SMARTLIST_FOREACH(routers, routerinfo_t *, r,
- {
- base16_encode(buf,sizeof(buf),r->cache_info.identity_digest,DIGEST_LEN);
- smartlist_add(identities, tor_strdup(buf));
- });
- }
- if (EVENT_IS_INTERESTING1S(EVENT_NEW_DESC)) {
- char *ids = smartlist_join_strings(identities, " ", 0, &len);
- size_t ids_len = strlen(ids)+32;
- msg = tor_malloc(ids_len);
- tor_snprintf(msg, ids_len, "650 NEWDESC %s\r\n", ids);
- send_control_event_string(EVENT_NEW_DESC, SHORT_NAMES|ALL_FORMATS, msg);
- tor_free(ids);
- tor_free(msg);
- }
- if (EVENT_IS_INTERESTING1L(EVENT_NEW_DESC)) {
+
+ {
smartlist_t *names = smartlist_create();
char *ids;
size_t names_len;
@@ -3449,16 +3293,12 @@ control_event_descriptors_changed(smartlist_t *routers)
names_len = strlen(ids)+32;
msg = tor_malloc(names_len);
tor_snprintf(msg, names_len, "650 NEWDESC %s\r\n", ids);
- send_control_event_string(EVENT_NEW_DESC, LONG_NAMES|ALL_FORMATS, msg);
+ send_control_event_string(EVENT_NEW_DESC, ALL_FORMATS, msg);
tor_free(ids);
tor_free(msg);
SMARTLIST_FOREACH(names, char *, cp, tor_free(cp));
smartlist_free(names);
}
- if (identities) {
- SMARTLIST_FOREACH(identities, char *, cp, tor_free(cp));
- smartlist_free(identities);
- }
return 0;
}
@@ -3475,17 +3315,17 @@ control_event_address_mapped(const char *from, const char *to, time_t expires,
return 0;
if (expires < 3 || expires == TIME_MAX)
- send_control_event_extended(EVENT_ADDRMAP, ALL_NAMES,
- "650 ADDRMAP %s %s NEVER@%s\r\n", from, to,
+ send_control_event(EVENT_ADDRMAP, ALL_FORMATS,
+ "650 ADDRMAP %s %s NEVER %s\r\n", from, to,
error?error:"");
else {
char buf[ISO_TIME_LEN+1];
char buf2[ISO_TIME_LEN+1];
format_local_iso_time(buf,expires);
format_iso_time(buf2,expires);
- send_control_event_extended(EVENT_ADDRMAP, ALL_NAMES,
+ send_control_event(EVENT_ADDRMAP, ALL_FORMATS,
"650 ADDRMAP %s %s \"%s\""
- "@%s%sEXPIRES=\"%s\"\r\n",
+ " %s%sEXPIRES=\"%s\"\r\n",
from, to, buf,
error?error:"", error?" ":"",
buf2);
@@ -3525,9 +3365,9 @@ control_event_or_authdir_new_descriptor(const char *action,
buf = tor_malloc(totallen);
strlcpy(buf, firstline, totallen);
strlcpy(buf+strlen(firstline), esc, totallen);
- send_control_event_string(EVENT_AUTHDIR_NEWDESCS, ALL_NAMES|ALL_FORMATS,
+ send_control_event_string(EVENT_AUTHDIR_NEWDESCS, ALL_FORMATS,
buf);
- send_control_event_string(EVENT_AUTHDIR_NEWDESCS, ALL_NAMES|ALL_FORMATS,
+ send_control_event_string(EVENT_AUTHDIR_NEWDESCS, ALL_FORMATS,
"650 OK\r\n");
tor_free(esc);
tor_free(buf);
@@ -3565,8 +3405,8 @@ control_event_networkstatus_changed_helper(smartlist_t *statuses,
SMARTLIST_FOREACH(strs, char *, cp, tor_free(cp));
smartlist_free(strs);
tor_free(s);
- send_control_event_string(event, ALL_NAMES|ALL_FORMATS, esc);
- send_control_event_string(event, ALL_NAMES|ALL_FORMATS,
+ send_control_event_string(event, ALL_FORMATS, esc);
+ send_control_event_string(event, ALL_FORMATS,
"650 OK\r\n");
tor_free(esc);
@@ -3615,7 +3455,7 @@ control_event_networkstatus_changed_single(routerstatus_t *rs)
int
control_event_my_descriptor_changed(void)
{
- send_control_event(EVENT_DESCCHANGED, ALL_NAMES, "650 DESCCHANGED\r\n");
+ send_control_event(EVENT_DESCCHANGED, ALL_FORMATS, "650 DESCCHANGED\r\n");
return 0;
}
@@ -3663,7 +3503,7 @@ control_event_status(int type, int severity, const char *format, va_list args)
return -1;
}
- send_control_event_impl(type, ALL_NAMES|ALL_FORMATS, 0, format_buf, args);
+ send_control_event_impl(type, ALL_FORMATS, format_buf, args);
return 0;
}
@@ -3727,7 +3567,7 @@ control_event_guard(const char *nickname, const char *digest,
if (!EVENT_IS_INTERESTING(EVENT_GUARD))
return 0;
- if (EVENT_IS_INTERESTING1L(EVENT_GUARD)) {
+ {
char buf[MAX_VERBOSE_NICKNAME_LEN+1];
routerinfo_t *ri = router_get_by_digest(digest);
if (ri) {
@@ -3735,13 +3575,9 @@ control_event_guard(const char *nickname, const char *digest,
} else {
tor_snprintf(buf, sizeof(buf), "$%s~%s", hbuf, nickname);
}
- send_control_event(EVENT_GUARD, LONG_NAMES,
+ send_control_event(EVENT_GUARD, ALL_FORMATS,
"650 GUARD ENTRY %s %s\r\n", buf, status);
}
- if (EVENT_IS_INTERESTING1S(EVENT_GUARD)) {
- send_control_event(EVENT_GUARD, SHORT_NAMES,
- "650 GUARD ENTRY $%s %s\r\n", hbuf, status);
- }
return 0;
}
diff --git a/src/or/directory.c b/src/or/directory.c
index d783772eac..d86495dca5 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -1050,31 +1050,10 @@ directory_send_command(dir_connection_t *conn,
httpcommand = "POST";
url = tor_strdup("/tor/post/consensus-signature");
break;
- case DIR_PURPOSE_FETCH_RENDDESC:
- tor_assert(resource);
- tor_assert(!payload);
-
- /* this must be true or we wouldn't be doing the lookup */
- tor_assert(strlen(resource) <= REND_SERVICE_ID_LEN_BASE32);
- /* This breaks the function abstraction. */
- conn->rend_data = tor_malloc_zero(sizeof(rend_data_t));
- strlcpy(conn->rend_data->onion_address, resource,
- sizeof(conn->rend_data->onion_address));
- conn->rend_data->rend_desc_version = 0;
-
- httpcommand = "GET";
- /* Request the most recent versioned descriptor. */
- // (XXXX We were going to switch this to fetch rendezvous1 descriptors,
- // but that never got testing, and it wasn't a good design.)
- len = strlen(resource)+32;
- url = tor_malloc(len);
- tor_snprintf(url, len, "/tor/rendezvous/%s", resource);
- break;
case DIR_PURPOSE_FETCH_RENDDESC_V2:
tor_assert(resource);
tor_assert(strlen(resource) <= REND_DESC_ID_V2_LEN_BASE32);
tor_assert(!payload);
- conn->rend_data->rend_desc_version = 2;
httpcommand = "GET";
len = strlen(resource) + 32;
url = tor_malloc(len);
@@ -1920,7 +1899,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
/* Success, or at least there's a v2 descriptor already
* present. Notify pending connections about this. */
conn->_base.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
- rend_client_desc_trynow(conn->rend_data->onion_address, -1);
+ rend_client_desc_trynow(conn->rend_data->onion_address);
}
break;
case 404:
@@ -1967,7 +1946,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
log_info(LD_REND, "Successfully fetched v2 rendezvous "
"descriptor.");
conn->_base.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
- rend_client_desc_trynow(conn->rend_data->onion_address, -1);
+ rend_client_desc_trynow(conn->rend_data->onion_address);
break;
}
break;
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index 88afe9fccc..76ac3978f8 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -964,7 +964,6 @@ dirserv_set_router_is_running(routerinfo_t *router, time_t now)
* *<b>router_status_out</b>. Return 0 on success, -1 on failure.
*
* If for_controller is true, include the routers with very old descriptors.
- * If for_controller is &gt;1, use the verbose nickname format.
*/
int
list_server_status_v1(smartlist_t *routers, char **router_status_out,
@@ -984,23 +983,22 @@ list_server_status_v1(smartlist_t *routers, char **router_status_out,
rs_entries = smartlist_create();
- SMARTLIST_FOREACH(routers, routerinfo_t *, ri,
- {
+ SMARTLIST_FOREACH_BEGIN(routers, routerinfo_t *, ri) {
if (authdir) {
/* Update router status in routerinfo_t. */
dirserv_set_router_is_running(ri, now);
}
- if (for_controller == 1 || ri->cache_info.published_on >= cutoff)
- smartlist_add(rs_entries, list_single_server_status(ri, ri->is_running));
- else if (for_controller > 2) {
+ if (for_controller) {
char name_buf[MAX_VERBOSE_NICKNAME_LEN+2];
char *cp = name_buf;
if (!ri->is_running)
*cp++ = '!';
router_get_verbose_nickname(cp, ri);
smartlist_add(rs_entries, tor_strdup(name_buf));
+ } else if (ri->cache_info.published_on >= cutoff) {
+ smartlist_add(rs_entries, list_single_server_status(ri, ri->is_running));
}
- });
+ } SMARTLIST_FOREACH_END(ri);
*router_status_out = smartlist_join_strings(rs_entries, " ", 0, NULL);
diff --git a/src/or/dns.c b/src/or/dns.c
index ad5b5de405..fb3620c165 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -1612,6 +1612,30 @@ assert_resolve_ok(cached_resolve_t *resolve)
}
}
+/** Return the number of DNS cache entries as an int */
+static int
+dns_cache_entry_count(void)
+{
+ return HT_SIZE(&cache_root);
+}
+
+/** Log memory information about our internal DNS cache at level 'severity'. */
+void
+dump_dns_mem_usage(int severity)
+{
+ /* This should never be larger than INT_MAX. */
+ int hash_count = dns_cache_entry_count();
+ size_t hash_mem = sizeof(struct cached_resolve_t) * hash_count;
+ hash_mem += HT_MEM_USAGE(&cache_root);
+
+ /* Print out the count and estimated size of our &cache_root. It undercounts
+ hostnames in cached reverse resolves.
+ */
+ log(severity, LD_MM, "Our DNS cache has %d entries.", hash_count);
+ log(severity, LD_MM, "Our DNS cache size is approximately %u bytes.",
+ (unsigned)hash_mem);
+}
+
#ifdef DEBUG_DNS_CACHE
/** Exit with an assertion if the DNS cache is corrupt. */
static void
diff --git a/src/or/eventdns.c b/src/or/eventdns.c
index 4464148141..34c16248dd 100644
--- a/src/or/eventdns.c
+++ b/src/or/eventdns.c
@@ -173,8 +173,6 @@ struct evdns_request {
/* these objects are kept in a circular list */
struct evdns_request *next, *prev;
- u16 timeout_event_deleted; /**< Debugging: where was timeout_event
- * deleted? 0 for "it's added." */
struct event timeout_event;
u16 trans_id; /* the transaction id */
@@ -214,8 +212,6 @@ struct nameserver {
struct event event;
/* these objects are kept in a circular list */
struct nameserver *next, *prev;
- u16 timeout_event_deleted; /**< Debugging: where was timeout_event
- * deleted? 0 for "it's added." */
struct event timeout_event; /* used to keep the timeout for */
/* when we next probe this server. */
/* Valid if state == 0 */
@@ -474,51 +470,10 @@ sockaddr_eq(const struct sockaddr *sa1, const struct sockaddr *sa2,
return 1;
}
-/* for debugging bug 929. XXXX022 */
-static int
-_add_timeout_event(u16 *lineno, struct event *ev, struct timeval *to)
-{
- *lineno = 0;
- return evtimer_add(ev, to);
-}
-#define add_timeout_event(s, to) \
- (_add_timeout_event(&(s)->timeout_event_deleted, &(s)->timeout_event, (to)))
-
-/* for debugging bug 929. XXXX022 */
-static int
-_del_timeout_event(u16 *lineno, struct event *ev, int line)
-{
- if (*lineno) {
- log(EVDNS_LOG_DEBUG,
- "Duplicate timeout event_del from line %d: first call "
- "was at %d.", line, (int)*lineno);
- return 0;
- } else {
- *lineno = (u16)line;
- return event_del(ev);
- }
-}
-#define del_timeout_event(s) \
- (_del_timeout_event(&(s)->timeout_event_deleted, &(s)->timeout_event, \
- __LINE__))
-/* For debugging bug 929/957. XXXX022 */
-static int
-_del_timeout_event_if_set(u16 *lineno, struct event *ev, int line)
-{
- if (*lineno == 0) {
- log(EVDNS_LOG_DEBUG,
- "Event that I thought was non-added as of line %d "
- "was actually added on line %d",
- line, (int)*lineno);
- *lineno = line;
- return event_del(ev);
- }
- return 0;
-}
-#define del_timeout_event_if_set(s) \
- _del_timeout_event_if_set(&(s)->timeout_event_deleted, \
- &(s)->timeout_event, \
- __LINE__)
+#define add_timeout_event(s, to) \
+ (event_add(&(s)->timeout_event, (to)))
+#define del_timeout_event(s) \
+ (event_del(&(s)->timeout_event))
/* This walks the list of inflight requests to find the */
/* one with a matching transaction id. Returns NULL on */
@@ -555,7 +510,7 @@ static void
nameserver_probe_failed(struct nameserver *const ns) {
const struct timeval * timeout;
del_timeout_event(ns);
- CLEAR(&ns->timeout_event);
+
if (ns->state == 1) {
/* This can happen if the nameserver acts in a way which makes us mark */
/* it as bad and then starts sending good replies. */
@@ -567,8 +522,6 @@ nameserver_probe_failed(struct nameserver *const ns) {
global_nameserver_timeouts_length - 1)];
ns->failed_times++;
- del_timeout_event_if_set(ns);
- evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
if (add_timeout_event(ns, (struct timeval *) timeout) < 0) {
log(EVDNS_LOG_WARN,
"Error from libevent when adding timer event for %s",
@@ -597,8 +550,6 @@ nameserver_failed(struct nameserver *const ns, const char *msg) {
ns->state = 0;
ns->failed_times = 1;
- del_timeout_event_if_set(ns);
- evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
if (add_timeout_event(ns, (struct timeval *) &global_nameserver_timeouts[0]) < 0) {
log(EVDNS_LOG_WARN,
"Error from libevent when adding timer event for %s",
@@ -634,7 +585,6 @@ nameserver_up(struct nameserver *const ns) {
log(EVDNS_LOG_WARN, "Nameserver %s is back up",
debug_ntop((struct sockaddr *)&ns->address));
del_timeout_event(ns);
- CLEAR(&ns->timeout_event);
ns->state = 1;
ns->failed_times = 0;
ns->timedout = 0;
@@ -666,7 +616,6 @@ request_finished(struct evdns_request *const req, struct evdns_request **head) {
log(EVDNS_LOG_DEBUG, "Removing timeout for request %lx",
(unsigned long) req);
del_timeout_event(req);
- CLEAR(&req->timeout_event);
search_request_finished(req);
global_requests_inflight--;
@@ -2046,7 +1995,6 @@ evdns_request_timeout_callback(int fd, short events, void *arg) {
* request_finished; that one already deletes the timeout event.
* XXXX021 port this change to libevent. */
del_timeout_event(req);
- CLEAR(&req->timeout_event);
evdns_request_transmit(req);
}
}
@@ -2109,8 +2057,7 @@ evdns_request_transmit(struct evdns_request *req) {
/* transmitted; we need to check for timeout. */
log(EVDNS_LOG_DEBUG,
"Setting timeout for request %lx", (unsigned long) req);
- del_timeout_event_if_set(req);
- evtimer_set(&req->timeout_event, evdns_request_timeout_callback, req);
+
if (add_timeout_event(req, &global_timeout) < 0) {
log(EVDNS_LOG_WARN,
"Error from libevent when adding timer for request %lx",
@@ -2225,7 +2172,6 @@ evdns_clear_nameservers_and_suspend(void)
(void) event_del(&server->event);
CLEAR(&server->event);
del_timeout_event(server);
- CLEAR(&server->timeout_event);
if (server->socket >= 0)
CLOSE_SOCKET(server->socket);
CLEAR(server);
@@ -2243,7 +2189,6 @@ evdns_clear_nameservers_and_suspend(void)
req->ns = NULL;
/* ???? What to do about searches? */
del_timeout_event(req);
- CLEAR(&req->timeout_event);
req->trans_id = 0;
req->transmit_me = 0;
@@ -2318,7 +2263,8 @@ _evdns_nameserver_add_impl(const struct sockaddr *address,
if (!ns) return -1;
memset(ns, 0, sizeof(struct nameserver));
- ns->timeout_event_deleted = __LINE__;
+
+ evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
ns->socket = socket(PF_INET, SOCK_DGRAM, 0);
if (ns->socket < 0) { err = 1; goto out1; }
@@ -2553,7 +2499,8 @@ request_new(int type, const char *name, int flags,
}
memset(req, 0, sizeof(struct evdns_request));
- req->timeout_event_deleted = __LINE__;
+
+ evtimer_set(&req->timeout_event, evdns_request_timeout_callback, req);
if (global_randomize_case) {
unsigned i;
@@ -3384,8 +3331,7 @@ evdns_shutdown(int fail_requests)
if (server->socket >= 0)
CLOSE_SOCKET(server->socket);
(void) event_del(&server->event);
- if (server->state == 0)
- del_timeout_event(server);
+ del_timeout_event(server);
CLEAR(server);
mm_free(server);
if (server_next == server_head)
diff --git a/src/or/geoip.c b/src/or/geoip.c
index aabbe26889..41c8f21cdb 100644
--- a/src/or/geoip.c
+++ b/src/or/geoip.c
@@ -12,6 +12,7 @@
#include "ht.h"
static void clear_geoip_db(void);
+static void dump_geoip_stats(void);
/** An entry from the GeoIP file: maps an IP range to a country. */
typedef struct geoip_entry_t {
@@ -21,9 +22,9 @@ typedef struct geoip_entry_t {
} geoip_entry_t;
/** For how many periods should we remember per-country request history? */
-#define REQUEST_HIST_LEN 3
+#define REQUEST_HIST_LEN 1
/** How long are the periods for which we should remember request history? */
-#define REQUEST_HIST_PERIOD (8*60*60)
+#define REQUEST_HIST_PERIOD (24*60*60)
/** A per-country record for GeoIP request history. */
typedef struct geoip_country_t {
@@ -42,7 +43,7 @@ static strmap_t *country_idxplus1_by_lc_code = NULL;
static smartlist_t *geoip_entries = NULL;
/** Return the index of the <b>country</b>'s entry in the GeoIP DB
- * if it is a valid 2-letter country code, otherwise return zero.
+ * if it is a valid 2-letter country code, otherwise return -1.
*/
country_t
geoip_get_country(const char *country)
@@ -261,8 +262,8 @@ geoip_is_loaded(void)
typedef struct clientmap_entry_t {
HT_ENTRY(clientmap_entry_t) node;
uint32_t ipaddr;
- time_t last_seen; /* The last 2 bits of this value hold the client
- * operation. */
+ unsigned int last_seen_in_minutes:30;
+ unsigned int action:2;
} clientmap_entry_t;
#define ACTION_MASK 3
@@ -289,7 +290,7 @@ clientmap_entry_hash(const clientmap_entry_t *a)
static INLINE int
clientmap_entries_eq(const clientmap_entry_t *a, const clientmap_entry_t *b)
{
- return a->ipaddr == b->ipaddr;
+ return a->ipaddr == b->ipaddr && a->action == b->action;
}
HT_PROTOTYPE(clientmap, clientmap_entry_t, node, clientmap_entry_hash,
@@ -298,7 +299,8 @@ HT_GENERATE(clientmap, clientmap_entry_t, node, clientmap_entry_hash,
clientmap_entries_eq, 0.6, malloc, realloc, free);
/** Note that we've seen a client connect from the IP <b>addr</b> (host order)
- * at time <b>now</b>. Ignored by all but bridges. */
+ * at time <b>now</b>. Ignored by all but bridges and directories if
+ * configured accordingly. */
void
geoip_note_client_seen(geoip_client_action_t action,
uint32_t addr, time_t now)
@@ -315,8 +317,7 @@ geoip_note_client_seen(geoip_client_action_t action,
#ifndef ENABLE_GEOIP_STATS
return;
#else
- if (options->BridgeRelay || options->BridgeAuthoritativeDir ||
- !options->DirRecordUsageByCountry)
+ if (options->BridgeRelay || options->BridgeAuthoritativeDir)
return;
#endif
}
@@ -329,6 +330,14 @@ geoip_note_client_seen(geoip_client_action_t action,
current_request_period_starts = now;
break;
}
+ /* Also discard all items in the client history that are too old.
+ * (This only works here because bridge and directory stats are
+ * independent. Otherwise, we'd only want to discard those items
+ * with action GEOIP_CLIENT_NETWORKSTATUS{_V2}.) */
+ geoip_remove_old_clients(current_request_period_starts);
+ /* Before rotating, write the current stats to disk. */
+ dump_geoip_stats();
+ /* Now rotate request period */
SMARTLIST_FOREACH(geoip_countries, geoip_country_t *, c, {
memmove(&c->n_v2_ns_requests[0], &c->n_v2_ns_requests[1],
sizeof(uint32_t)*(REQUEST_HIST_LEN-1));
@@ -340,20 +349,18 @@ geoip_note_client_seen(geoip_client_action_t action,
current_request_period_starts += REQUEST_HIST_PERIOD;
if (n_old_request_periods < REQUEST_HIST_LEN-1)
++n_old_request_periods;
- }
+ }
- /* We use the low 3 bits of the time to encode the action. Since we're
- * potentially remembering tons of clients, we don't want to make
- * clientmap_entry_t larger than it has to be. */
- now = (now & ~ACTION_MASK) | (((int)action) & ACTION_MASK);
lookup.ipaddr = addr;
+ lookup.action = (int)action;
ent = HT_FIND(clientmap, &client_history, &lookup);
if (ent) {
- ent->last_seen = now;
+ ent->last_seen_in_minutes = now / 60;
} else {
ent = tor_malloc_zero(sizeof(clientmap_entry_t));
ent->ipaddr = addr;
- ent->last_seen = now;
+ ent->last_seen_in_minutes = now / 60;
+ ent->action = (int)action;
HT_INSERT(clientmap, &client_history, ent);
}
@@ -380,8 +387,8 @@ geoip_note_client_seen(geoip_client_action_t action,
static int
_remove_old_client_helper(struct clientmap_entry_t *ent, void *_cutoff)
{
- time_t cutoff = *(time_t*)_cutoff;
- if (ent->last_seen < cutoff) {
+ time_t cutoff = *(time_t*)_cutoff / 60;
+ if (ent->last_seen_in_minutes < cutoff) {
tor_free(ent);
return 1;
} else {
@@ -465,9 +472,13 @@ char *
geoip_get_client_history(time_t now, geoip_client_action_t action)
{
char *result = NULL;
+ int min_observation_time = GEOIP_MIN_OBSERVATION_TIME;
+#ifdef ENABLE_GEOIP_STATS
+ min_observation_time = DIR_RECORD_USAGE_MIN_OBSERVATION_TIME;
+#endif
if (!geoip_is_loaded())
return NULL;
- if (client_history_starts < (now - GEOIP_MIN_OBSERVATION_TIME)) {
+ if (client_history_starts < (now - min_observation_time)) {
char buf[32];
smartlist_t *chunks = NULL;
smartlist_t *entries = NULL;
@@ -478,12 +489,11 @@ geoip_get_client_history(time_t now, geoip_client_action_t action)
unsigned total = 0;
unsigned granularity = IP_GRANULARITY;
#ifdef ENABLE_GEOIP_STATS
- if (get_options()->DirRecordUsageByCountry)
- granularity = get_options()->DirRecordUsageGranularity;
+ granularity = DIR_RECORD_USAGE_GRANULARITY;
#endif
HT_FOREACH(ent, clientmap, &client_history) {
int country;
- if (((*ent)->last_seen & ACTION_MASK) != (int)action)
+ if ((*ent)->action != (int)action)
continue;
country = geoip_get_country_by_ip((*ent)->ipaddr);
if (country < 0)
@@ -545,12 +555,13 @@ geoip_get_request_history(time_t now, geoip_client_action_t action)
smartlist_t *entries, *strings;
char *result;
unsigned granularity = IP_GRANULARITY;
+ int min_observation_time = GEOIP_MIN_OBSERVATION_TIME;
#ifdef ENABLE_GEOIP_STATS
- if (get_options()->DirRecordUsageByCountry)
- granularity = get_options()->DirRecordUsageGranularity;
+ granularity = DIR_RECORD_USAGE_GRANULARITY;
+ min_observation_time = DIR_RECORD_USAGE_MIN_OBSERVATION_TIME;
#endif
- if (client_history_starts >= (now - GEOIP_MIN_OBSERVATION_TIME))
+ if (client_history_starts >= (now - min_observation_time))
return NULL;
if (action != GEOIP_CLIENT_NETWORKSTATUS &&
action != GEOIP_CLIENT_NETWORKSTATUS_V2)
@@ -591,7 +602,7 @@ geoip_get_request_history(time_t now, geoip_client_action_t action)
}
/** Store all our geoip statistics into $DATADIR/geoip-stats. */
-void
+static void
dump_geoip_stats(void)
{
#ifdef ENABLE_GEOIP_STATS
@@ -608,7 +619,7 @@ dump_geoip_stats(void)
data_v3 = geoip_get_client_history(now, GEOIP_CLIENT_NETWORKSTATUS);
format_iso_time(since, geoip_get_history_start());
format_iso_time(written, now);
- out = start_writing_to_stdio_file(filename, OPEN_FLAGS_REPLACE,
+ out = start_writing_to_stdio_file(filename, OPEN_FLAGS_APPEND,
0600, &open_file);
if (!out)
goto done;
diff --git a/src/or/main.c b/src/or/main.c
index a26fd0eff8..b21c00c9c7 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -774,7 +774,7 @@ run_connection_housekeeping(int i, time_t now)
}
}
-/** Honor a NEWNYM request: make future requests unlinkability to past
+/** Honor a NEWNYM request: make future requests unlinkable to past
* requests. */
static void
signewnym_impl(time_t now)
@@ -807,7 +807,6 @@ run_scheduled_events(time_t now)
static time_t time_to_clean_caches = 0;
static time_t time_to_recheck_bandwidth = 0;
static time_t time_to_check_for_expired_networkstatus = 0;
- static time_t time_to_dump_geoip_stats = 0;
static time_t time_to_retry_dns_init = 0;
or_options_t *options = get_options();
int i;
@@ -935,13 +934,6 @@ run_scheduled_events(time_t now)
time_to_check_for_expired_networkstatus = now + CHECK_EXPIRED_NS_INTERVAL;
}
- if (time_to_dump_geoip_stats < now) {
-#define DUMP_GEOIP_STATS_INTERVAL (60*60);
- if (time_to_dump_geoip_stats)
- dump_geoip_stats();
- time_to_dump_geoip_stats = now + DUMP_GEOIP_STATS_INTERVAL;
- }
-
/* Remove old information from rephist and the rend cache. */
if (time_to_clean_caches < now) {
rep_history_clean(now - options->RephistTrackTime);
@@ -1588,6 +1580,7 @@ dumpmemusage(int severity)
U64_PRINTF_ARG(rephist_total_alloc), rephist_total_num);
dump_routerlist_mem_usage(severity);
dump_cell_pool_usage(severity);
+ dump_dns_mem_usage(severity);
buf_dump_freelist_sizes(severity);
tor_log_mallinfo(severity);
}
diff --git a/src/or/or.h b/src/or/or.h
index 6cc30c4f0b..0d906e0870 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -483,7 +483,7 @@ typedef enum {
#define CIRCUIT_PURPOSE_IS_ORIGIN(p) ((p)>_CIRCUIT_PURPOSE_OR_MAX)
/** True iff the circuit purpose <b>p</b> is for a circuit that originated
* here to serve as a client. (Hidden services don't count here.) */
-#define CIRCUIT_PURPOSE_IS_CLIENT(p) \
+#define CIRCUIT_PURPOSE_IS_CLIENT(p) \
((p)> _CIRCUIT_PURPOSE_OR_MAX && \
(p)<=_CIRCUIT_PURPOSE_C_MAX)
/** True iff the circuit_t <b>c</b> is actually an origin_circuit_t. */
@@ -730,12 +730,6 @@ typedef struct rend_data_t {
/** Rendezvous cookie used by both, client and service. */
char rend_cookie[REND_COOKIE_LEN];
-
- /** Rendezvous descriptor version that is used by a service. Used to
- * distinguish introduction and rendezvous points belonging to the same
- * rendezvous service ID, but different descriptor versions.
- */
- uint8_t rend_desc_version;
} rend_data_t;
/** Time interval for tracking possible replays of INTRODUCE2 cells.
@@ -1169,12 +1163,6 @@ typedef struct control_connection_t {
uint32_t event_mask; /**< Bitfield: which events does this controller
* care about? */
- unsigned int use_long_names:1; /**< True if we should use long nicknames
- * on this (v1) connection. Only settable
- * via v1 controllers. */
- /** For control connections only. If set, we send extended info with control
- * events as appropriate. */
- unsigned int use_extended_events:1;
/** True if we have sent a protocolinfo reply on this connection. */
unsigned int have_sent_protocolinfo:1;
@@ -2540,7 +2528,7 @@ typedef struct {
* the bridge authority guess which countries have blocked access to us. */
int BridgeRecordUsageByCountry;
-#ifdef ENABLE_GEOIP_STATS
+#if 0
/** If true, and Tor is built with GEOIP_STATS support, and we're a
* directory, record how many directory requests we get from each country. */
int DirRecordUsageByCountry;
@@ -2917,6 +2905,8 @@ int options_need_geoip_info(or_options_t *options, const char **reason_out);
int getinfo_helper_config(control_connection_t *conn,
const char *question, char **answer);
+const char *tor_get_digests(void);
+
#ifdef CONFIG_PRIVATE
/* Used only by config.c and test.c */
or_options_t *options_new(void);
@@ -2991,8 +2981,7 @@ connection_t *connection_get_by_type_addr_port_purpose(int type,
uint16_t port, int purpose);
connection_t *connection_get_by_type_state(int type, int state);
connection_t *connection_get_by_type_state_rendquery(int type, int state,
- const char *rendquery,
- int rendversion);
+ const char *rendquery);
#define connection_speaks_cells(conn) ((conn)->type == CONN_TYPE_OR)
int connection_is_listener(connection_t *conn);
@@ -3578,6 +3567,7 @@ int dns_resolve(edge_connection_t *exitconn);
void dns_launch_correctness_checks(void);
int dns_seems_to_be_broken(void);
void dns_reset_correctness_checks(void);
+void dump_dns_mem_usage(int severity);
/********************************* dnsserv.c ************************/
@@ -3593,6 +3583,15 @@ int dnsserv_launch_request(const char *name, int is_reverse);
/********************************* geoip.c **************************/
+/** Round all GeoIP results to the next multiple of this value, to avoid
+ * leaking information. */
+#define DIR_RECORD_USAGE_GRANULARITY 8
+/** Time interval: Flush geoip data to disk this often. */
+#define DIR_RECORD_USAGE_RETAIN_IPS (24*60*60)
+/** How long do we have to have observed per-country request history before
+ * we are willing to talk about it? */
+#define DIR_RECORD_USAGE_MIN_OBSERVATION_TIME (24*60*60)
+
#ifdef GEOIP_PRIVATE
int geoip_parse_entry(const char *line);
#endif
@@ -3624,7 +3623,6 @@ char *geoip_get_request_history(time_t now, geoip_client_action_t action);
int getinfo_helper_geoip(control_connection_t *control_conn,
const char *question, char **answer);
void geoip_free_all(void);
-void dump_geoip_stats(void);
/********************************* hibernate.c **********************/
@@ -4015,7 +4013,6 @@ void rend_client_introcirc_has_opened(origin_circuit_t *circ);
void rend_client_rendcirc_has_opened(origin_circuit_t *circ);
int rend_client_introduction_acked(origin_circuit_t *circ, const char *request,
size_t request_len);
-void rend_client_refetch_renddesc(const char *query);
void rend_client_refetch_v2_renddesc(const rend_data_t *rend_query);
int rend_client_remove_intro_point(extend_info_t *failed_intro,
const rend_data_t *rend_query);
@@ -4023,7 +4020,7 @@ int rend_client_rendezvous_acked(origin_circuit_t *circ, const char *request,
size_t request_len);
int rend_client_receive_rendezvous(origin_circuit_t *circ, const char *request,
size_t request_len);
-void rend_client_desc_trynow(const char *query, int rend_version);
+void rend_client_desc_trynow(const char *query);
extend_info_t *rend_client_get_random_intro(const rend_data_t *rend_query);
@@ -4090,10 +4087,6 @@ void rend_process_relay_cell(circuit_t *circ, const crypt_path_t *layer_hint,
int command, size_t length, const char *payload);
void rend_service_descriptor_free(rend_service_descriptor_t *desc);
-int rend_encode_service_descriptor(rend_service_descriptor_t *desc,
- crypto_pk_env_t *key,
- char **str_out,
- size_t *len_out);
rend_service_descriptor_t *rend_parse_service_descriptor(const char *str,
size_t len);
int rend_get_service_id(crypto_pk_env_t *pk, char *out);
diff --git a/src/or/relay.c b/src/or/relay.c
index 85cd8f6c82..4e09c0040b 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -1660,7 +1660,7 @@ prev_circ_on_conn_p(circuit_t *circ, or_connection_t *conn)
}
/** Add <b>circ</b> to the list of circuits with pending cells on
- * <b>conn</b>. No effect if <b>circ</b> is already unlinked. */
+ * <b>conn</b>. No effect if <b>circ</b> is already linked. */
void
make_circuit_active_on_conn(circuit_t *circ, or_connection_t *conn)
{
@@ -1686,7 +1686,7 @@ make_circuit_active_on_conn(circuit_t *circ, or_connection_t *conn)
assert_active_circuits_ok_paranoid(conn);
}
-/** Remove <b>circ</b> to the list of circuits with pending cells on
+/** Remove <b>circ</b> from the list of circuits with pending cells on
* <b>conn</b>. No effect if <b>circ</b> is already unlinked. */
void
make_circuit_inactive_on_conn(circuit_t *circ, or_connection_t *conn)
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index 784db9dadf..fb50e8dc00 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -80,8 +80,8 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
goto err;
}
- /* first 20 bytes of payload are the hash of Bob's pk */
- if (entry->parsed->version == 0) { /* un-versioned descriptor */
+ /* first 20 bytes of payload are the hash of bob's pk */
+ if (entry->parsed->version == 0) { /* unversioned descriptor */
intro_key = entry->parsed->pk;
} else { /* versioned descriptor */
intro_key = NULL;
diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c
index d21eb42efe..c813c4959d 100644
--- a/src/or/rendcommon.c
+++ b/src/or/rendcommon.c
@@ -655,61 +655,6 @@ rend_encode_v2_descriptors(smartlist_t *descs_out,
return seconds_valid;
}
-/** Encode a service descriptor for <b>desc</b>, and sign it with
- * <b>key</b>. Store the descriptor in *<b>str_out</b>, and set
- * *<b>len_out</b> to its length.
- */
-int
-rend_encode_service_descriptor(rend_service_descriptor_t *desc,
- crypto_pk_env_t *key,
- char **str_out, size_t *len_out)
-{
- char *cp;
- char *end;
- int i, r;
- size_t asn1len;
- size_t buflen =
- PK_BYTES*2*(smartlist_len(desc->intro_nodes)+2);/*Too long, but ok*/
- cp = *str_out = tor_malloc(buflen);
- end = cp + PK_BYTES*2*(smartlist_len(desc->intro_nodes)+1);
- r = crypto_pk_asn1_encode(desc->pk, cp+2, end-(cp+2));
- if (r < 0) {
- tor_free(*str_out);
- return -1;
- }
- asn1len = r;
- set_uint16(cp, htons((uint16_t)asn1len));
- cp += 2+asn1len;
- set_uint32(cp, htonl((uint32_t)desc->timestamp));
- cp += 4;
- set_uint16(cp, htons((uint16_t)smartlist_len(desc->intro_nodes)));
- cp += 2;
- for (i=0; i < smartlist_len(desc->intro_nodes); ++i) {
- rend_intro_point_t *intro = smartlist_get(desc->intro_nodes, i);
- char ipoint[HEX_DIGEST_LEN+2];
- const size_t ipoint_len = HEX_DIGEST_LEN+1;
- ipoint[0] = '$';
- base16_encode(ipoint+1, HEX_DIGEST_LEN+1,
- intro->extend_info->identity_digest,
- DIGEST_LEN);
- tor_assert(strlen(ipoint) == ipoint_len);
- /* Assert that appending ipoint and its NUL won't over overrun the
- * buffer. */
- tor_assert(cp + ipoint_len+1 < *str_out + buflen);
- memcpy(cp, ipoint, ipoint_len+1);
- cp += ipoint_len+1;
- }
- note_crypto_pk_op(REND_SERVER);
- r = crypto_pk_private_sign_digest(key, cp, *str_out, cp-*str_out);
- if (r<0) {
- tor_free(*str_out);
- return -1;
- }
- cp += r;
- *len_out = (size_t)(cp-*str_out);
- return 0;
-}
-
/** Parse a service descriptor at <b>str</b> (<b>len</b> bytes). On
* success, return a newly alloced service_descriptor_t. On failure,
* return NULL.
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index 2fd041d33e..e8330094fb 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -10,8 +10,7 @@
#include "or.h"
static origin_circuit_t *find_intro_circuit(rend_intro_point_t *intro,
- const char *pk_digest,
- int desc_version);
+ const char *pk_digest);
/** Represents the mapping from a virtual port of a rendezvous service to
* a real port on some IP.
@@ -42,8 +41,6 @@ typedef struct rend_service_t {
/* Fields specified in config file */
char *directory; /**< where in the filesystem it stores it */
smartlist_t *ports; /**< List of rend_service_port_config_t */
- int descriptor_version; /**< Rendezvous descriptor version that will be
- * published. */
rend_auth_type_t auth_type; /**< Client authorization type or 0 if no client
* authorization is performed. */
smartlist_t *clients; /**< List of rend_authorized_client_t's of
@@ -58,7 +55,7 @@ typedef struct rend_service_t {
* or are trying to establish. */
time_t intro_period_started; /**< Start of the current period to build
* introduction points. */
- int n_intro_circuits_launched; /**< count of intro circuits we have
+ int n_intro_circuits_launched; /**< Count of intro circuits we have
* established in this period. */
rend_service_descriptor_t *desc; /**< Current hidden service descriptor. */
time_t desc_is_dirty; /**< Time at which changes to the hidden service
@@ -156,36 +153,6 @@ rend_add_service(rend_service_t *service)
service->intro_nodes = smartlist_create();
- /* If the service is configured to publish unversioned (v0) and versioned
- * descriptors (v2 or higher), split it up into two separate services
- * (unless it is configured to perform client authorization). */
- if (service->descriptor_version == -1) {
- if (service->auth_type == REND_NO_AUTH) {
- rend_service_t *v0_service = tor_malloc_zero(sizeof(rend_service_t));
- v0_service->directory = tor_strdup(service->directory);
- v0_service->ports = smartlist_create();
- SMARTLIST_FOREACH(service->ports, rend_service_port_config_t *, p, {
- rend_service_port_config_t *copy =
- tor_malloc_zero(sizeof(rend_service_port_config_t));
- memcpy(copy, p, sizeof(rend_service_port_config_t));
- smartlist_add(v0_service->ports, copy);
- });
- v0_service->intro_period_started = service->intro_period_started;
- v0_service->descriptor_version = 0; /* Unversioned descriptor. */
- v0_service->auth_type = REND_NO_AUTH;
- rend_add_service(v0_service);
- }
-
- service->descriptor_version = 2; /* Versioned descriptor. */
- }
-
- if (service->auth_type != REND_NO_AUTH && !service->descriptor_version) {
- log_warn(LD_CONFIG, "Hidden service with client authorization and "
- "version 0 descriptors configured; ignoring.");
- rend_service_free(service);
- return;
- }
-
if (service->auth_type != REND_NO_AUTH &&
smartlist_len(service->clients) == 0) {
log_warn(LD_CONFIG, "Hidden service with client authorization but no "
@@ -307,7 +274,6 @@ rend_config_services(or_options_t *options, int validate_only)
service->directory = tor_strdup(line->value);
service->ports = smartlist_create();
service->intro_period_started = time(NULL);
- service->descriptor_version = -1; /**< All descriptor versions. */
continue;
}
if (!service) {
@@ -433,35 +399,13 @@ rend_config_services(or_options_t *options, int validate_only)
return -1;
}
} else {
- smartlist_t *versions;
- char *version_str;
- int i, version, ver_ok=1, versions_bitmask = 0;
tor_assert(!strcasecmp(line->key, "HiddenServiceVersion"));
- versions = smartlist_create();
- smartlist_split_string(versions, line->value, ",",
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- for (i = 0; i < smartlist_len(versions); i++) {
- version_str = smartlist_get(versions, i);
- if (strlen(version_str) != 1 || strspn(version_str, "02") != 1) {
- log_warn(LD_CONFIG,
- "HiddenServiceVersion can only be 0 and/or 2.");
- SMARTLIST_FOREACH(versions, char *, cp, tor_free(cp));
- smartlist_free(versions);
- rend_service_free(service);
- return -1;
- }
- version = (int)tor_parse_long(version_str, 10, 0, INT_MAX, &ver_ok,
- NULL);
- if (!ver_ok)
- continue;
- versions_bitmask |= 1 << version;
+ if (strcmp(line->value, "2")) {
+ log_warn(LD_CONFIG,
+ "The only supported HiddenServiceVersion is 2.");
+ rend_service_free(service);
+ return -1;
}
- /* If exactly one version is set, change descriptor_version to that
- * value; otherwise leave it at -1. */
- if (versions_bitmask == 1 << 0) service->descriptor_version = 0;
- if (versions_bitmask == 1 << 2) service->descriptor_version = 2;
- SMARTLIST_FOREACH(versions, char *, cp, tor_free(cp));
- smartlist_free(versions);
}
}
if (service) {
@@ -483,8 +427,7 @@ rend_config_services(or_options_t *options, int validate_only)
* probably ok? */
SMARTLIST_FOREACH(rend_service_list, rend_service_t *, new, {
SMARTLIST_FOREACH(old_service_list, rend_service_t *, old, {
- if (!strcmp(old->directory, new->directory) &&
- old->descriptor_version == new->descriptor_version) {
+ if (!strcmp(old->directory, new->directory)) {
smartlist_add_all(new->intro_nodes, old->intro_nodes);
smartlist_clear(old->intro_nodes);
smartlist_add(surviving_services, old);
@@ -507,18 +450,16 @@ rend_config_services(or_options_t *options, int validate_only)
tor_assert(oc->rend_data);
SMARTLIST_FOREACH(surviving_services, rend_service_t *, ptr, {
if (!memcmp(ptr->pk_digest, oc->rend_data->rend_pk_digest,
- DIGEST_LEN) &&
- ptr->descriptor_version == oc->rend_data->rend_desc_version) {
+ DIGEST_LEN)) {
keep_it = 1;
break;
}
});
if (keep_it)
continue;
- log_info(LD_REND, "Closing intro point %s for service %s version %d.",
+ log_info(LD_REND, "Closing intro point %s for service %s.",
safe_str(oc->build_state->chosen_exit->nickname),
- oc->rend_data->onion_address,
- oc->rend_data->rend_desc_version);
+ oc->rend_data->onion_address);
circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
/* XXXX Is there another reason we should use here? */
}
@@ -548,7 +489,6 @@ rend_service_update_descriptor(rend_service_t *service)
d = service->desc = tor_malloc_zero(sizeof(rend_service_descriptor_t));
d->pk = crypto_pk_dup_key(service->private_key);
d->timestamp = time(NULL);
- d->version = service->descriptor_version;
d->intro_nodes = smartlist_create();
/* Support intro protocols 2 and 3. */
d->protocols = (1 << 2) + (1 << 3);
@@ -556,7 +496,7 @@ rend_service_update_descriptor(rend_service_t *service)
for (i = 0; i < smartlist_len(service->intro_nodes); ++i) {
rend_intro_point_t *intro_svc = smartlist_get(service->intro_nodes, i);
rend_intro_point_t *intro_desc;
- circ = find_intro_circuit(intro_svc, service->pk_digest, d->version);
+ circ = find_intro_circuit(intro_svc, service->pk_digest);
if (!circ || circ->_base.purpose != CIRCUIT_PURPOSE_S_INTRO)
continue;
@@ -797,17 +737,15 @@ rend_service_load_keys(void)
return r;
}
-/** Return the service whose public key has a digest of <b>digest</b> and
- * which publishes the given descriptor <b>version</b>. Return NULL if no
- * such service exists.
+/** Return the service whose public key has a digest of <b>digest</b>, or
+ * NULL if no such service exists.
*/
static rend_service_t *
-rend_service_get_by_pk_digest_and_version(const char* digest,
- uint8_t version)
+rend_service_get_by_pk_digest(const char* digest)
{
SMARTLIST_FOREACH(rend_service_list, rend_service_t*, s,
- if (!memcmp(s->pk_digest,digest,DIGEST_LEN) &&
- s->descriptor_version == version) return s);
+ if (!memcmp(s->pk_digest,digest,DIGEST_LEN))
+ return s);
return NULL;
}
@@ -944,21 +882,16 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request,
}
/* look up service depending on circuit. */
- service = rend_service_get_by_pk_digest_and_version(
- circuit->rend_data->rend_pk_digest,
- circuit->rend_data->rend_desc_version);
+ service = rend_service_get_by_pk_digest(
+ circuit->rend_data->rend_pk_digest);
if (!service) {
log_warn(LD_REND, "Got an INTRODUCE2 cell for an unrecognized service %s.",
escaped(serviceid));
return -1;
}
- /* if descriptor version is 2, use intro key instead of service key. */
- if (circuit->rend_data->rend_desc_version == 0) {
- intro_key = service->private_key;
- } else {
- intro_key = circuit->intro_key;
- }
+ /* use intro key instead of service key. */
+ intro_key = circuit->intro_key;
/* first DIGEST_LEN bytes of request is intro or service pk digest */
crypto_pk_get_digest(intro_key, intro_key_digest);
@@ -1201,7 +1134,6 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request,
memcpy(launched->rend_data->rend_cookie, r_cookie, REND_COOKIE_LEN);
strlcpy(launched->rend_data->onion_address, service->service_id,
sizeof(launched->rend_data->onion_address));
- launched->rend_data->rend_desc_version = service->descriptor_version;
launched->build_state->pending_final_cpath = cpath =
tor_malloc_zero(sizeof(crypt_path_t));
cpath->magic = CRYPT_PATH_MAGIC;
@@ -1323,18 +1255,16 @@ rend_service_launch_establish_intro(rend_service_t *service,
strlcpy(launched->rend_data->onion_address, service->service_id,
sizeof(launched->rend_data->onion_address));
memcpy(launched->rend_data->rend_pk_digest, service->pk_digest, DIGEST_LEN);
- launched->rend_data->rend_desc_version = service->descriptor_version;
- if (service->descriptor_version == 2)
- launched->intro_key = crypto_pk_dup_key(intro->intro_key);
+ launched->intro_key = crypto_pk_dup_key(intro->intro_key);
if (launched->_base.state == CIRCUIT_STATE_OPEN)
rend_service_intro_has_opened(launched);
return 0;
}
/** Return the number of introduction points that are or have been
- * established for the given service address and rendezvous version. */
+ * established for the given service address in <b>query</b>. */
static int
-count_established_intro_points(const char *query, int rend_version)
+count_established_intro_points(const char *query)
{
int num_ipos = 0;
circuit_t *circ;
@@ -1345,7 +1275,6 @@ count_established_intro_points(const char *query, int rend_version)
circ->purpose == CIRCUIT_PURPOSE_S_INTRO)) {
origin_circuit_t *oc = TO_ORIGIN_CIRCUIT(circ);
if (oc->rend_data &&
- oc->rend_data->rend_desc_version == rend_version &&
!rend_cmp_service_ids(query, oc->rend_data->onion_address))
num_ipos++;
}
@@ -1375,9 +1304,8 @@ rend_service_intro_has_opened(origin_circuit_t *circuit)
base32_encode(serviceid, REND_SERVICE_ID_LEN_BASE32+1,
circuit->rend_data->rend_pk_digest, REND_SERVICE_ID_LEN);
- service = rend_service_get_by_pk_digest_and_version(
- circuit->rend_data->rend_pk_digest,
- circuit->rend_data->rend_desc_version);
+ service = rend_service_get_by_pk_digest(
+ circuit->rend_data->rend_pk_digest);
if (!service) {
log_warn(LD_REND, "Unrecognized service ID %s on introduction circuit %d.",
serviceid, circuit->_base.n_circ_id);
@@ -1387,8 +1315,7 @@ rend_service_intro_has_opened(origin_circuit_t *circuit)
/* If we already have enough introduction circuits for this service,
* redefine this one as a general circuit. */
- if (count_established_intro_points(serviceid,
- circuit->rend_data->rend_desc_version) > NUM_INTRO_POINTS) {
+ if (count_established_intro_points(serviceid) > NUM_INTRO_POINTS) {
log_info(LD_CIRC|LD_REND, "We have just finished an introduction "
"circuit, but we already have enough. Redefining purpose to "
"general.");
@@ -1401,13 +1328,8 @@ rend_service_intro_has_opened(origin_circuit_t *circuit)
"Established circuit %d as introduction point for service %s",
circuit->_base.n_circ_id, serviceid);
- /* If the introduction point will not be used in an unversioned
- * descriptor, use the intro key instead of the service key in
- * ESTABLISH_INTRO. */
- if (service->descriptor_version == 0)
- intro_key = service->private_key;
- else
- intro_key = circuit->intro_key;
+ /* Use the intro key instead of the service key in ESTABLISH_INTRO. */
+ intro_key = circuit->intro_key;
/* Build the payload for a RELAY_ESTABLISH_INTRO cell. */
r = crypto_pk_asn1_encode(intro_key, buf+2,
RELAY_PAYLOAD_SIZE-2);
@@ -1466,9 +1388,8 @@ rend_service_intro_established(origin_circuit_t *circuit, const char *request,
goto err;
}
tor_assert(circuit->rend_data);
- service = rend_service_get_by_pk_digest_and_version(
- circuit->rend_data->rend_pk_digest,
- circuit->rend_data->rend_desc_version);
+ service = rend_service_get_by_pk_digest(
+ circuit->rend_data->rend_pk_digest);
if (!service) {
log_warn(LD_REND, "Unknown service on introduction circuit %d.",
circuit->_base.n_circ_id);
@@ -1518,9 +1439,8 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit)
"cookie %s for service %s",
circuit->_base.n_circ_id, hexcookie, serviceid);
- service = rend_service_get_by_pk_digest_and_version(
- circuit->rend_data->rend_pk_digest,
- circuit->rend_data->rend_desc_version);
+ service = rend_service_get_by_pk_digest(
+ circuit->rend_data->rend_pk_digest);
if (!service) {
log_warn(LD_GENERAL, "Internal error: unrecognized service ID on "
"introduction circuit.");
@@ -1576,13 +1496,12 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit)
*/
/** Return the (possibly non-open) introduction circuit ending at
- * <b>intro</b> for the service whose public key is <b>pk_digest</b> and
- * which publishes descriptor of version <b>desc_version</b>. Return
- * NULL if no such service is found.
+ * <b>intro</b> for the service whose public key is <b>pk_digest</b>.
+ * (<b>desc_version</b> is ignored). Return NULL if no such service is
+ * found.
*/
static origin_circuit_t *
-find_intro_circuit(rend_intro_point_t *intro, const char *pk_digest,
- int desc_version)
+find_intro_circuit(rend_intro_point_t *intro, const char *pk_digest)
{
origin_circuit_t *circ = NULL;
@@ -1591,8 +1510,7 @@ find_intro_circuit(rend_intro_point_t *intro, const char *pk_digest,
CIRCUIT_PURPOSE_S_INTRO))) {
if (!memcmp(circ->build_state->chosen_exit->identity_digest,
intro->extend_info->identity_digest, DIGEST_LEN) &&
- circ->rend_data &&
- circ->rend_data->rend_desc_version == desc_version) {
+ circ->rend_data) {
return circ;
}
}
@@ -1602,8 +1520,7 @@ find_intro_circuit(rend_intro_point_t *intro, const char *pk_digest,
CIRCUIT_PURPOSE_S_ESTABLISH_INTRO))) {
if (!memcmp(circ->build_state->chosen_exit->identity_digest,
intro->extend_info->identity_digest, DIGEST_LEN) &&
- circ->rend_data &&
- circ->rend_data->rend_desc_version == desc_version) {
+ circ->rend_data) {
return circ;
}
}
@@ -1695,9 +1612,8 @@ directory_post_to_hs_dir(rend_service_descriptor_t *renddesc,
smartlist_free(successful_uploads);
}
-/** Encode and sign up-to-date v0 and/or v2 service descriptors for
- * <b>service</b>, and upload it/them to all the dirservers/to the
- * responsible hidden service directories.
+/** Encode and sign an up-to-date service descriptor for <b>service</b>,
+ * and upload it/them to the responsible hidden service directories.
*/
static void
upload_service_descriptor(rend_service_t *service)
@@ -1709,35 +1625,8 @@ upload_service_descriptor(rend_service_t *service)
rendpostperiod = get_options()->RendPostPeriod;
- /* Upload unversioned (v0) descriptor? */
- if (service->descriptor_version == 0 &&
- get_options()->PublishHidServDescriptors) {
- char *desc;
- size_t desc_len;
- /* Encode the descriptor. */
- if (rend_encode_service_descriptor(service->desc,
- service->private_key,
- &desc, &desc_len)<0) {
- log_warn(LD_BUG, "Internal error: couldn't encode service descriptor; "
- "not uploading.");
- return;
- }
-
- /* Post it to the dirservers */
- rend_get_service_id(service->desc->pk, serviceid);
- log_info(LD_REND, "Sending publish request for hidden service %s",
- serviceid);
- directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_RENDDESC,
- ROUTER_PURPOSE_GENERAL,
- HIDSERV_AUTHORITY, desc, desc_len, 0);
- tor_free(desc);
- service->next_upload_time = now + rendpostperiod;
- uploaded = 1;
- }
-
- /* Upload v2 descriptor? */
- if (service->descriptor_version == 2 &&
- get_options()->PublishHidServDescriptors) {
+ /* Upload descriptor? */
+ if (get_options()->PublishHidServDescriptors) {
networkstatus_t *c = networkstatus_get_latest_consensus();
if (c && smartlist_len(c->routerstatus_list) > 0) {
int seconds_valid, i, j, num_descs;
@@ -1876,8 +1765,7 @@ rend_services_introduce(void)
for (j=0; j < smartlist_len(service->intro_nodes); ++j) {
intro = smartlist_get(service->intro_nodes, j);
router = router_get_by_digest(intro->extend_info->identity_digest);
- if (!router || !find_intro_circuit(intro, service->pk_digest,
- service->descriptor_version)) {
+ if (!router || !find_intro_circuit(intro, service->pk_digest)) {
log_info(LD_REND,"Giving up on %s as intro point for %s.",
intro->extend_info->nickname, service->service_id);
if (service->desc) {
@@ -1941,10 +1829,8 @@ rend_services_introduce(void)
smartlist_add(intro_routers, router);
intro = tor_malloc_zero(sizeof(rend_intro_point_t));
intro->extend_info = extend_info_from_router(router);
- if (service->descriptor_version == 2) {
- intro->intro_key = crypto_new_pk_env();
- tor_assert(!crypto_pk_generate_key(intro->intro_key));
- }
+ intro->intro_key = crypto_new_pk_env();
+ tor_assert(!crypto_pk_generate_key(intro->intro_key));
smartlist_add(service->intro_nodes, intro);
log_info(LD_REND, "Picked router %s as an intro point for %s.",
router->nickname, service->service_id);
@@ -2037,8 +1923,7 @@ rend_consider_descriptor_republication(void)
for (i=0; i < smartlist_len(rend_service_list); ++i) {
service = smartlist_get(rend_service_list, i);
- if (service->descriptor_version && service->desc &&
- !service->desc->all_uploads_performed) {
+ if (service->desc && !service->desc->all_uploads_performed) {
/* If we failed in uploading a descriptor last time, try again *without*
* updating the descriptor's contents. */
upload_service_descriptor(service);
@@ -2066,8 +1951,7 @@ rend_service_dump_stats(int severity)
intro = smartlist_get(service->intro_nodes, j);
safe_name = safe_str(intro->extend_info->nickname);
- circ = find_intro_circuit(intro, service->pk_digest,
- service->descriptor_version);
+ circ = find_intro_circuit(intro, service->pk_digest);
if (!circ) {
log(severity, LD_GENERAL, " Intro point %d at %s: no circuit",
j, safe_name);
@@ -2098,9 +1982,8 @@ rend_service_set_connection_addr_port(edge_connection_t *conn,
log_debug(LD_REND,"beginning to hunt for addr/port");
base32_encode(serviceid, REND_SERVICE_ID_LEN_BASE32+1,
circ->rend_data->rend_pk_digest, REND_SERVICE_ID_LEN);
- service = rend_service_get_by_pk_digest_and_version(
- circ->rend_data->rend_pk_digest,
- circ->rend_data->rend_desc_version);
+ service = rend_service_get_by_pk_digest(
+ circ->rend_data->rend_pk_digest);
if (!service) {
log_warn(LD_REND, "Couldn't find any service associated with pk %s on "
"rendezvous circuit %d; closing.",
diff --git a/src/or/router.c b/src/or/router.c
index 658c567db1..a1a56b0d01 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -1915,10 +1915,13 @@ extrainfo_get_client_geoip_summary(time_t now)
static time_t last_purged_at = 0;
int geoip_purge_interval = 48*60*60;
#ifdef ENABLE_GEOIP_STATS
- if (get_options()->DirRecordUsageByCountry)
- geoip_purge_interval = get_options()->DirRecordUsageRetainIPs;
+ geoip_purge_interval = DIR_RECORD_USAGE_RETAIN_IPS;
#endif
if (now > last_purged_at+geoip_purge_interval) {
+ /* (Note that this also discards items in the client history with
+ * action GEOIP_CLIENT_NETWORKSTATUS{_V2}, which doesn't matter
+ * because bridge and directory stats are independent. Keep in mind
+ * for future extensions, though.) */
geoip_remove_old_clients(now-geoip_purge_interval);
last_purged_at = now;
}
diff --git a/src/or/test.c b/src/or/test.c
index 7b7411e2f8..d43eb8f225 100644
--- a/src/or/test.c
+++ b/src/or/test.c
@@ -4000,78 +4000,6 @@ test_policies(void)
}
}
-/** Run unit tests for basic rendezvous functions. */
-static void
-test_rend_fns(void)
-{
- char address1[] = "fooaddress.onion";
- char address2[] = "aaaaaaaaaaaaaaaa.onion";
- char address3[] = "fooaddress.exit";
- char address4[] = "www.torproject.org";
- rend_service_descriptor_t *d1 =
- tor_malloc_zero(sizeof(rend_service_descriptor_t));
- rend_service_descriptor_t *d2 = NULL;
- char *encoded = NULL;
- size_t len;
- time_t now;
- int i;
- crypto_pk_env_t *pk1 = pk_generate(0), *pk2 = pk_generate(1);
-
- /* Test unversioned (v0) descriptor */
- d1->pk = crypto_pk_dup_key(pk1);
- now = time(NULL);
- d1->timestamp = now;
- d1->version = 0;
- d1->intro_nodes = smartlist_create();
- for (i = 0; i < 3; i++) {
- rend_intro_point_t *intro = tor_malloc_zero(sizeof(rend_intro_point_t));
- intro->extend_info = tor_malloc_zero(sizeof(extend_info_t));
- crypto_rand(intro->extend_info->identity_digest, DIGEST_LEN);
- intro->extend_info->nickname[0] = '$';
- base16_encode(intro->extend_info->nickname+1, HEX_DIGEST_LEN+1,
- intro->extend_info->identity_digest, DIGEST_LEN);
- smartlist_add(d1->intro_nodes, intro);
- }
- test_assert(! rend_encode_service_descriptor(d1, pk1, &encoded, &len));
- d2 = rend_parse_service_descriptor(encoded, len);
- test_assert(d2);
-
- test_assert(!crypto_pk_cmp_keys(d1->pk, d2->pk));
- test_eq(d2->timestamp, now);
- test_eq(d2->version, 0);
- test_eq(d2->protocols, 1<<2);
- test_eq(smartlist_len(d2->intro_nodes), 3);
- for (i = 0; i < 3; i++) {
- rend_intro_point_t *intro1 = smartlist_get(d1->intro_nodes, i);
- rend_intro_point_t *intro2 = smartlist_get(d2->intro_nodes, i);
- test_streq(intro1->extend_info->nickname,
- intro2->extend_info->nickname);
- }
-
- test_assert(BAD_HOSTNAME == parse_extended_hostname(address1));
- test_assert(ONION_HOSTNAME == parse_extended_hostname(address2));
- test_assert(EXIT_HOSTNAME == parse_extended_hostname(address3));
- test_assert(NORMAL_HOSTNAME == parse_extended_hostname(address4));
-
- crypto_free_pk_env(pk1);
- crypto_free_pk_env(pk2);
- pk1 = pk2 = NULL;
- rend_service_descriptor_free(d1);
- rend_service_descriptor_free(d2);
- d1 = d2 = NULL;
-
- done:
- if (pk1)
- crypto_free_pk_env(pk1);
- if (pk2)
- crypto_free_pk_env(pk2);
- if (d1)
- rend_service_descriptor_free(d1);
- if (d2)
- rend_service_descriptor_free(d2);
- tor_free(encoded);
-}
-
/** Run AES performance benchmarks. */
static void
bench_aes(void)
@@ -4539,9 +4467,9 @@ test_crypto_base32_decode(void)
;
}
-/** Test encoding and parsing of v2 rendezvous service descriptors. */
+/** Test encoding and parsing of rendezvous service descriptors. */
static void
-test_rend_fns_v2(void)
+test_rend_fns(void)
{
rend_service_descriptor_t *generated = NULL, *parsed = NULL;
char service_id[DIGEST_LEN];
@@ -4556,6 +4484,16 @@ test_rend_fns_v2(void)
size_t intro_points_size;
size_t encoded_size;
int i;
+ char address1[] = "fooaddress.onion";
+ char address2[] = "aaaaaaaaaaaaaaaa.onion";
+ char address3[] = "fooaddress.exit";
+ char address4[] = "www.torproject.org";
+
+ test_assert(BAD_HOSTNAME == parse_extended_hostname(address1));
+ test_assert(ONION_HOSTNAME == parse_extended_hostname(address2));
+ test_assert(EXIT_HOSTNAME == parse_extended_hostname(address3));
+ test_assert(NORMAL_HOSTNAME == parse_extended_hostname(address4));
+
pk1 = pk_generate(0);
pk2 = pk_generate(1);
generated = tor_malloc_zero(sizeof(rend_service_descriptor_t));
@@ -4760,7 +4698,6 @@ static struct {
ENT(v3_networkstatus),
ENT(policies),
ENT(rend_fns),
- SUBENT(rend_fns, v2),
ENT(geoip),
DISABLED(bench_aes),
diff --git a/src/win32/orconfig.h b/src/win32/orconfig.h
index 65f21f6d37..08e601456b 100644
--- a/src/win32/orconfig.h
+++ b/src/win32/orconfig.h
@@ -226,6 +226,6 @@
#define USING_TWOS_COMPLEMENT
/* Version number of package */
-#define VERSION "0.2.1.15-rc-dev"
+#define VERSION "0.2.2.0-alpha-dev"
diff --git a/tor.spec.in b/tor.spec.in
index ec00415f48..6133ce6049 100644
--- a/tor.spec.in
+++ b/tor.spec.in
@@ -15,13 +15,6 @@
%define toruser @TORUSER@
%define torgroup @TORGROUP@
-## Target a specific arch and OS
-#
-# default is i386 linux
-
-## Override any system rpm macros
-#
-
## Version song and dance
#
# This should be the Tor version number, as it appears on the tarball,
@@ -54,14 +47,11 @@
%if %{is_fc}
%define ostag %(sed -e 's/^.*release /fc/' -e 's/ .*$//' -e 's/\\./_/g' < /etc/fedora-release)
-%else
+%endif
+
%if %{is_rh}
%define ostag %(sed -e 's/^.*release /rh/' -e 's/ .*$//' -e 's/\\./_/g' < /etc/redhat-release)
%endif
-%endif
-
-# These are probably wrong... just placeholders should we actually
-# end up supporting these distributions
%if %{is_mdk}
%define ostag mdk
@@ -290,6 +280,9 @@ exit 0
%changelog
+* Fri May 01 2009 Andrew Lewman <andrew@torproject.org>
+- clean up distro detection and remove dead comment blocks
+
* Sun Feb 22 2009 Andrew Lewman <andrew@torproject.org>
- update the description, vendor, and packager