mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 23:53:32 +01:00
7137a57849
svn:r311
613 lines
26 KiB
Plaintext
613 lines
26 KiB
Plaintext
$Id$
|
|
|
|
TOR Spec
|
|
|
|
Note: This is an attempt to specify TOR as it exists as implemented in
|
|
early June, 2003. It is not recommended that others implement this
|
|
design as it stands; future versions of TOR will implement improved
|
|
protocols.
|
|
|
|
TODO: (very soon)
|
|
- Specify truncate/truncated
|
|
- Sendme w/stream0 is circuit sendme
|
|
- Integrate -NM and -RD comments
|
|
|
|
0. Notation:
|
|
|
|
PK -- a public key.
|
|
SK -- a private key
|
|
K -- a key for a symmetric cypher
|
|
|
|
a|b -- concatenation of 'a' with 'b'.
|
|
a[i:j] -- Bytes 'i' through 'j'-1 (inclusive) of the string a.
|
|
|
|
All numeric values are encoded in network (big-endian) order.
|
|
|
|
Unless otherwise specified, all symmetric ciphers are 3DES in OFB
|
|
mode, with an IV of all 0 bytes. Asymmetric ciphers are either RSA
|
|
with 1024-bit keys and exponents of 65537, or DH with the safe prime
|
|
from rfc2409, section 6.2, whose hex representation is:
|
|
|
|
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08"
|
|
"8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B"
|
|
"302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9"
|
|
"A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6"
|
|
"49286651ECE65381FFFFFFFFFFFFFFFF"
|
|
|
|
[We will move to AES once we can assume everybody will have it. -RD]
|
|
|
|
|
|
1. System overview
|
|
|
|
Tor is a connection-oriented anonymizing communication service. Users
|
|
build a path known as a "virtual circuit" through the network, in which
|
|
each node knows its predecessor and successor, but no others. Traffic
|
|
flowing down the circuit is unwrapped by a symmetric key at each node,
|
|
which reveals the downstream node.
|
|
|
|
|
|
2. Connections
|
|
|
|
2.1. Establishing OR connections
|
|
|
|
When one onion router opens a connection to another, the initiating
|
|
OR (called the 'client') and the listening OR (called the 'server')
|
|
perform the following handshake.
|
|
[or when an op wants to connect to or]
|
|
|
|
Before the handshake begins, the client and server know one
|
|
another's (1024-bit) public keys, IPV4 addresses, and ports.
|
|
|
|
1. Client connects to server:
|
|
|
|
The client generates a pair of 8-byte symmetric keys (one
|
|
[K_f] for the 'forward' stream from client to server, and one
|
|
[K_b] for the 'backward' stream from server to client.
|
|
|
|
The client then generates a 'Client authentication' message [M]
|
|
containing:
|
|
The number 2 to signify OR handshake [2 bytes]
|
|
The client's published IPV4 address [4 bytes]
|
|
The client's published port [2 bytes]
|
|
The server's published IPV4 address [4 bytes]
|
|
The server's published port [2 bytes]
|
|
The forward key (K_f) [16 bytes]
|
|
The backward key (K_f) [16 bytes]
|
|
The maximum bandwidth (bytes/s) [4 bytes]
|
|
[Total: 50 bytes]
|
|
|
|
The client then RSA-encrypts [M] with the server's public key
|
|
and PKCS1 padding to give an encrypted message.
|
|
|
|
The client then opens a TCP connection to the server, sends
|
|
the 128-byte RSA-encrypted data to the server, and waits for a
|
|
reply.
|
|
|
|
2. Server authenticates to client:
|
|
|
|
Upon receiving a TCP connection, the server waits to receive
|
|
128 bytes from the client. It decrypts the message with its
|
|
private key, and checks the PKCS1 padding. If the padding is
|
|
incorrect, or if the message's length is other than 50 bytes,
|
|
the server closes the TCP connection and stops handshaking.
|
|
|
|
The server then checks the list of known ORs for one with the
|
|
address and port given in the client's authentication. If no
|
|
such OR is known, or if the server is already connected to
|
|
that OR, the server closes the current TCP connection and
|
|
stops handshaking.
|
|
|
|
For later use, the server sets its keys for this connection,
|
|
setting K_f to the client's K_b, and K_b to the client's K_f.
|
|
|
|
The server then creates a server authentication message [M2] as
|
|
follows:
|
|
Modified client authentication [48 bytes]
|
|
A random nonce [N] [8 bytes]
|
|
[Total: 56 bytes]
|
|
The client authentication is generated from M by replacing
|
|
the client's preferred bandwidth [B_c] with the server's
|
|
preferred bandwidth [B_s], if B_s < B_c.
|
|
|
|
The server encrypts M2 with the client's public key (found
|
|
from the list of known routers), using PKCS1 padding.
|
|
|
|
The server sends the 128-byte encrypted message to the client,
|
|
and waits for a reply.
|
|
|
|
3. Client authenticates to server.
|
|
|
|
Once the client has received 128 bytes, it decrypts them with
|
|
its public key, and checks the PKCS1 padding. If the padding
|
|
is invalid, or the decrypted message's length is other than 56
|
|
bytes, the client closes the TCP connection.
|
|
|
|
The client checks that the addresses and keys in the reply
|
|
message are the same as the ones it originally sent. If not,
|
|
it closes the TCP connection.
|
|
|
|
The client updates the connection's bandwidth to that set by
|
|
the server, and generates the following authentication message [M3]:
|
|
The client's published IPV4 address [4 bytes]
|
|
The client's published port [2 bytes]
|
|
The server's published IPV4 address [4 bytes]
|
|
The server's published port [2 bytes]
|
|
The server-generated nonce [N] [8 bytes]
|
|
[Total: 20 bytes]
|
|
|
|
Once again, the client encrypts this message using the
|
|
server's public key and PKCS1 padding, and sends the resulting
|
|
128-byte message to the server.
|
|
|
|
4. Server checks client authentication
|
|
|
|
The server once again waits to receive 128 bytes from the
|
|
client, decrypts the message with its private key, and checks
|
|
the PKCS1 padding. If the padding is incorrect, or if the
|
|
message's length is other than 20 bytes, the server closes the
|
|
TCP connection and stops handshaking.
|
|
|
|
If the addresses in the decrypted message M3 match those in M
|
|
and M2, and if the nonce in M3 is the same as in M2, the
|
|
handshake is complete, and the client and server begin sending
|
|
cells to one another. Otherwise, the server closes the TCP
|
|
connection.
|
|
|
|
2.2. Establishing OP-to-OR connections
|
|
|
|
[wrap this with the above]
|
|
When an Onion Proxy (OP) needs to establish a connection to an OR,
|
|
the handshake is simpler because the OR does not need to verify the
|
|
OP's identity. The OP and OR establish the following steps:
|
|
|
|
1. OP connects to OR:
|
|
|
|
First, the OP generates a pair of 8-byte symmetric keys (one
|
|
[K_f] for the 'forward' stream from OP to OR, and one
|
|
[K_b] for the 'backward' stream from OR to OP).
|
|
|
|
The OP generates a message [M] in the following format:
|
|
The number 1 to signify OP handshake [2 bytes]
|
|
Maximum bandwidth (bytes/s) [4 bytes]
|
|
Forward key [K_f] [16 bytes]
|
|
Backward key [K_b] [16 bytes]
|
|
[Total: 38 bytes]
|
|
|
|
The OP encrypts M with the OR's public key and PKCS1 padding,
|
|
opens a TCP connection to the OR's TCP port, and sends the
|
|
resulting 128-byte encrypted message to the OR.
|
|
|
|
2. OR receives keys:
|
|
|
|
When the OR receives a connection from an OP [This is on a
|
|
different port, right? How does it know the difference? -NM],
|
|
[Correct. The 'or_port' config variable specifies the OR port,
|
|
and the op_port variable specified the OP port. -RD]
|
|
it waits for 128 bytes of data, and decrypts the resulting
|
|
data with its private key, checking the PKCS1 padding. If the
|
|
padding is invalid, or the message is not 38 bytes long, the
|
|
OR closes the connection.
|
|
|
|
Otherwise, the connection is established, and the OR is ready
|
|
to receive cells.
|
|
|
|
The server sets its keys for this connection, setting K_f to
|
|
the client's K_b, and K_b to the client's K_f.
|
|
|
|
2.3. Sending cells and link encryption
|
|
|
|
Once the handshake is complete, the ORs or OR and OP send cells
|
|
(specified below) to one another. Cells are sent serially,
|
|
encrypted with the 3DES-OFB keystream specified by the handshake
|
|
protocol. Over a connection, communicants encrypt outgoing cells
|
|
with the connection's K_f, and decrypt incoming cells with the
|
|
connection's K_b.
|
|
|
|
[Commentary: This means that OR/OP->OR connections are malleable; I
|
|
can flip bits in cells as they go across the wire, and see flipped
|
|
bits coming out the cells as they are decrypted at the next
|
|
server. I need to look more at the data format to see whether
|
|
this is exploitable, but if there's no integrity checking there
|
|
either, I suspect we may have an attack here. -NM]
|
|
[Yes, this protocol is open to tagging attacks. The payloads are
|
|
encrypted inside the network, so it's only at the edge node and beyond
|
|
that it's a worry. But adversaries can already count packets and
|
|
observe/modify timing. It's not worth putting in hashes; indeed, it
|
|
would be quite hard, because one of the sides of the circuit doesn't
|
|
know the keys that are used for de/encrypting at each hop, so couldn't
|
|
craft hashes anyway. See the Bandwidth Throttling (threat model)
|
|
thread on http://archives.seul.org/or/dev/Jul-2002/threads.html. -RD]
|
|
[Even if I don't control both sides of the connection, I can still
|
|
do evil stuff. For instance, if I can guess that a cell is a
|
|
TOPIC_COMMAND_BEGIN cell to www.slashdot.org:80 , I can change the
|
|
address and port to point to a machine I control. -NM]
|
|
|
|
|
|
3. Cell Packet format
|
|
|
|
The basic unit of communication for onion routers and onion
|
|
proxies is a fixed-width "cell". Each cell contains the following
|
|
fields:
|
|
|
|
ACI (anonymous circuit identifier) [2 bytes]
|
|
Command [1 byte]
|
|
Length [1 byte]
|
|
Sequence number (unused, set to 0) [4 bytes]
|
|
Payload (padded with 0 bytes) [248 bytes]
|
|
[Total size: 256 bytes]
|
|
|
|
The 'Command' field holds one of the following values:
|
|
0 -- PADDING (Padding) (See Sec 6.2)
|
|
1 -- CREATE (Create a circuit) (See Sec 4)
|
|
2 -- CREATED (Acknowledge create) (See Sec 4)
|
|
3 -- RELAY (End-to-end data) (See Sec 5)
|
|
4 -- DESTROY (Stop using a circuit) (See Sec 4)
|
|
|
|
The interpretation of 'Length' and 'Payload' depend on the type of
|
|
the cell.
|
|
PADDING: Neither field is used.
|
|
CREATE: Length is 144; the payload contains the first phase of the
|
|
DH handshake.
|
|
CREATED: Length is 128; the payload contains the second phase of
|
|
the DH handshake.
|
|
RELAY: Length is a value between 8 and 248; the first 'length'
|
|
bytes of payload contain useful data.
|
|
DESTROY: Neither field is used.
|
|
|
|
Unused fields are filled with 0 bytes. The payload is padded with
|
|
0 bytes.
|
|
|
|
PADDING cells are currently used to implement connection
|
|
keepalive. ORs and OPs send one another a PADDING cell every few
|
|
minutes.
|
|
|
|
CREATE and DESTROY cells are used to manage circuits; see section
|
|
4 below.
|
|
|
|
RELAY cells are used to send commands and data along a circuit; see
|
|
section 5 below.
|
|
|
|
|
|
4. Circuit management
|
|
|
|
4.1. CREATE and CREATED cells
|
|
|
|
Users set up circuits incrementally, one hop at a time. To create
|
|
a new circuit, users send a CREATE cell to the first node, with the
|
|
first half of the DH handshake; that node responds with a CREATED cell
|
|
with the second half of the DH handshake. To extend a circuit past
|
|
the first hop, the user sends an EXTEND relay cell (see section 5)
|
|
which instructs the last node in the circuit to send a CREATE cell
|
|
to extend the circuit.
|
|
|
|
The payload for a CREATE cell is an 'onion skin', consisting of:
|
|
RSA-encrypted data [128 bytes]
|
|
Symmetrically-encrypted data [16 bytes]
|
|
The RSA-encrypted portion contains:
|
|
Symmetric key [16 bytes]
|
|
First part of DH data (g^x) [112 bytes]
|
|
The symmetrically encrypted portion contains:
|
|
Second part of DH data (g^x) [16 bytes]
|
|
|
|
The two parts of the DH data, once decrypted and concatenated, form
|
|
g^x as calculated by the client.
|
|
|
|
The relay payload for an EXTEND relay cell consists of:
|
|
Address [4 bytes]
|
|
Port [2 bytes]
|
|
Onion skin [144 bytes]
|
|
|
|
The port and address field denote the IPV4 address and port of the
|
|
next onion router in the circuit.
|
|
|
|
4.2. Setting circuit keys
|
|
|
|
Once the handshake between the OP and an OR is completed, both
|
|
servers can now calculate g^xy with ordinary DH. They divide the
|
|
last 32 bytes of this shared secret into two 16-byte keys, the
|
|
first of which (called Kf) is used to encrypt the stream of data
|
|
going from the OP to the OR, and second of which (called Kb) is
|
|
used to encrypt the stream of data going from the OR to the OP.
|
|
|
|
4.3. Creating circuits
|
|
|
|
When creating a circuit through the network, the circuit creator
|
|
performs the following steps:
|
|
|
|
1. Choose a chain of N onion routers (R_1...R_N) to constitute
|
|
the path, such that no router appears in the path twice.
|
|
|
|
2. If not already connected to the first router in the chain,
|
|
open a new connection to that router.
|
|
|
|
3. Choose an ACI not already in use on the connection with the
|
|
first router in the chain. If our address/port pair is
|
|
numerically higher than the address/port pair of the other
|
|
side, then let the high bit of the ACI be 1, else 0.
|
|
|
|
4. Send a CREATE cell along the connection, to be received by
|
|
the first onion router.
|
|
|
|
5. Wait until a CREATED cell is received; finish the handshake
|
|
and extract the forward key Kf_1 and the back key Kb_1.
|
|
|
|
6. For each subsequent onion router R (R_2 through R_N), extend
|
|
the circuit to R.
|
|
|
|
To extend the circuit by a single onion router R_M, the circuit
|
|
creator performs these steps:
|
|
|
|
1. Create an onion skin, encrypting the RSA-encrypted part with
|
|
R's public key.
|
|
|
|
2. Encrypt and send the onion skin in a RELAY_CREATE cell along
|
|
the circuit (see section 5).
|
|
|
|
3. When a RELAY_CREATED cell is received, calculate the shared
|
|
keys. The circuit is now extended.
|
|
|
|
When an onion router receives an EXTEND relay cell, it sends a
|
|
CREATE cell to the next onion router, with the enclosed onion skin
|
|
as its payload. The initiating onion router chooses some random
|
|
ACI not yet used on the connection between the two onion routers.
|
|
|
|
When an onion router receives a CREATE cell, if it already has a
|
|
circuit on the given connection with the given ACI, it drops the
|
|
cell. Otherwise, sometime after receiving the CREATE cell, it completes
|
|
the DH handshake, and replies with a CREATED cell, containing g^y
|
|
as its [128 byte] payload. Upon receiving a CREATED cell, an onion
|
|
router packs it payload into an EXTENDED relay cell (see section 5),
|
|
and sends that cell up the circuit. Upon receiving the EXTENDED
|
|
relay cell, the OP can retrieve g^y.
|
|
|
|
(As an optimization, OR implementations may delay processing onions
|
|
until a break in traffic allows time to do so without harming
|
|
network latency too greatly.)
|
|
|
|
4.4. Tearing down circuits
|
|
|
|
Circuits are torn down when an unrecoverable error occurs along
|
|
the circuit, or when all streams on a circuit are closed and the
|
|
circuit's intended lifetime is over. Circuits may be torn down
|
|
either completely or hop-by-hop.
|
|
|
|
To tear down a circuit completely, an OR or OP sends a DESTROY
|
|
cell to the adjacent nodes on that circuit, using the appropriate
|
|
direction's ACI.
|
|
|
|
Upon receiving an outgoing DESTROY cell, an OR frees resources
|
|
associated with the corresponding circuit. If it's not the end of
|
|
the circuit, it sends a DESTROY cell for that circuit to the next OR
|
|
in the circuit. If the node is the end of the circuit, then it tears
|
|
down any associated edge connections (see section 5.1).
|
|
|
|
After a DESTROY cell has been processed, an OR ignores all data or
|
|
destroy cells for the corresponding circuit.
|
|
|
|
To tear down part of a circuit, the OP sends a RELAY_TRUNCATE cell
|
|
signaling a given OR (Stream ID zero). That OR sends a DESTROY
|
|
cell to the next node in the circuit, and replies to the OP with a
|
|
RELAY_TRUNCATED cell.
|
|
|
|
When an unrecoverable error occurs along one connection in a
|
|
circuit, the nodes on either side of the connection should, if they
|
|
are able, act as follows: the node closer to the OP should send a
|
|
RELAY_TRUNCATED cell towards the OP; the node farther from the OP
|
|
should send a DESTROY cell down the circuit.
|
|
|
|
[We'll have to reevaluate this section once we figure out cleaner
|
|
circuit/connection killing conventions. -RD]
|
|
|
|
4.5. Routing data cells
|
|
|
|
When an OR receives a RELAY cell, it checks the cell's ACI and
|
|
determines whether it has a corresponding circuit along that
|
|
connection. If not, the OR drops the RELAY cell.
|
|
|
|
Otherwise, if the OR is not at the OP edge of the circuit (that is,
|
|
either an 'exit node' or a non-edge node), it de/encrypts the length
|
|
field and the payload with 3DES/OFB, as follows:
|
|
'Forward' relay cell (same direction as CREATE):
|
|
Use Kf as key; encrypt.
|
|
'Back' relay cell (opposite direction from CREATE):
|
|
Use Kb as key; decrypt.
|
|
If the OR recognizes the stream ID on the cell (it is either the ID
|
|
of an open stream or the signaling (zero) ID), the OR processes the
|
|
contents of the relay cell. Otherwise, it passes the decrypted
|
|
relay cell along the circuit if the circuit continues, or drops the
|
|
cell if it's the end of the circuit. [Getting an unrecognized
|
|
relay cell at the end of the circuit must be allowed for now;
|
|
we can reexamine this once we've designed full tcp-style close
|
|
handshakes. -RD]
|
|
|
|
Otherwise, if the data cell is coming from the OP edge of the
|
|
circuit, the OP decrypts the length and payload fields with 3DES/OFB as
|
|
follows:
|
|
OP sends data cell to node R_M:
|
|
For I=1...M, decrypt with Kf_I.
|
|
|
|
Otherwise, if the data cell is arriving at the OP edge if the
|
|
circuit, the OP encrypts the length and payload fields with 3DES/OFB as
|
|
follows:
|
|
OP receives data cell:
|
|
For I=N...1,
|
|
Encrypt with Kb_I. If the stream ID is a recognized
|
|
stream for R_I, or if the stream ID is the signaling
|
|
ID (zero), then stop and process the payload.
|
|
|
|
For more information, see section 5 below.
|
|
|
|
5. Application connections and stream management
|
|
|
|
5.1. Streams
|
|
|
|
Within a circuit, the OP and the exit node use the contents of
|
|
RELAY packets to tunnel end-to-end commands and TCP connections
|
|
("Streams") across circuits. End-to-end commands can be initiated
|
|
by either edge; streams are initiated by the OP.
|
|
|
|
The first 8 bytes of each relay cell are reserved as follows:
|
|
Relay command [1 byte]
|
|
Stream ID [7 bytes]
|
|
|
|
The recognized relay commands are:
|
|
1 -- RELAY_BEGIN
|
|
2 -- RELAY_DATA
|
|
3 -- RELAY_END
|
|
4 -- RELAY_CONNECTED
|
|
5 -- RELAY_SENDME
|
|
6 -- RELAY_EXTEND
|
|
7 -- RELAY_EXTENDED
|
|
8 -- RELAY_TRUNCATE
|
|
9 -- RELAY_TRUNCATED
|
|
|
|
All RELAY cells pertaining to the same tunneled stream have the
|
|
same stream ID. Stream ID's are chosen randomly by the OP. A
|
|
stream ID is considered "recognized" on a circuit C by an OP or an
|
|
OR if it already has an existing stream established on that
|
|
circuit, or if the stream ID is equal to the signaling stream ID,
|
|
which is all zero: [00 00 00 00 00 00 00]
|
|
|
|
To create a new anonymized TCP connection, the OP sends a
|
|
RELAY_BEGIN data cell with a payload encoding the address and port
|
|
of the destination host. The stream ID is zero. The payload format is:
|
|
ADDRESS | ':' | PORT | '\000'
|
|
where ADDRESS may be a DNS hostname, or an IPv4 address in
|
|
dotted-quad format; and where PORT is encoded in decimal.
|
|
|
|
Upon receiving this packet, the exit node resolves the address as
|
|
necessary, and opens a new TCP connection to the target port. If
|
|
the address cannot be resolved, or a connection can't be
|
|
established, the exit node replies with a RELAY_END cell.
|
|
Otherwise, the exit node replies with a RELAY_CONNECTED cell.
|
|
|
|
The OP waits for a RELAY_CONNECTED cell before sending any data.
|
|
Once a connection has been established, the OP and exit node
|
|
package stream data in RELAY_DATA cells, and upon receiving such
|
|
cells, echo their contents to the corresponding TCP stream.
|
|
[XXX Mention zlib encoding. -NM]
|
|
|
|
When one side of the TCP stream is closed, the corresponding edge
|
|
node sends a RELAY_END cell along the circuit; upon receiving a
|
|
RELAY_END cell, the edge node closes its side of the corresponding
|
|
TCP stream (by sending a FIN packet), but continues to accept and
|
|
package incoming data until both sides of the TCP stream are
|
|
closed. At that point, the edge node sends a second RELAY_END
|
|
cell, and drops its record of the stream.
|
|
|
|
For creation and handling of RELAY_EXTEND and RELAY_EXTENDED cells,
|
|
see section 4. For creating and handling of RELAY_SENDME cells,
|
|
see section 6.
|
|
|
|
|
|
6. Flow control
|
|
|
|
6.1. Link throttling
|
|
|
|
As discussed above in section 2.1, ORs and OPs negotiate a maximum
|
|
bandwidth upon startup. The communicants only read up to that
|
|
number of bytes per second on average, though they may use mechanisms
|
|
to handle spikes (eg token buckets).
|
|
|
|
Communicants rely on TCP's default flow control to push back when they
|
|
stop reading, so nodes that don't obey this bandwidth limit can't do
|
|
too much damage.
|
|
|
|
6.2. Link padding
|
|
|
|
Currently nodes are not required to do any sort of link padding or
|
|
dummy traffic. Because strong attacks exist even with link padding,
|
|
and because link padding greatly increases the bandwidth requirements
|
|
for running a node, we plan to leave out link padding until this
|
|
tradeoff is better understood.
|
|
|
|
6.3. Circuit-level flow control
|
|
|
|
To control a circuit's bandwidth usage, each OR keeps track of
|
|
two 'windows', consisting of how many RELAY_DATA cells it is
|
|
allowed to package for transmission, and how many RELAY_DATA cells
|
|
it is willing to deliver to streams outside the network.
|
|
Each 'window' value is initially set to 1000 data cells
|
|
in each direction (cells that are not data cells do not affect
|
|
the window). When an OR is willing to deliver more cells, it sends a
|
|
RELAY_SENDME cell towards the OP, with Stream ID zero. When an OR
|
|
receives a RELAY_SENDME cell with stream ID zero, it increments its
|
|
packaging window.
|
|
|
|
Either of these cells increment the corresponding window by 100.
|
|
|
|
The OP behaves identically, except that it must track a packaging
|
|
window and a delivery window for every OR in the circuit.
|
|
|
|
An OR or OP sends cells to increment its delivery window when the
|
|
corresponding window value falls under some threshold (900).
|
|
|
|
If a packaging window reaches 0, the OR or OP stops reading from
|
|
TCP connections for all streams on the corresponding circuit, and
|
|
sends no more RELAY_DATA cells until receiving a RELAY_SENDME cell.
|
|
|
|
6.4. Stream-level flow control
|
|
|
|
Edge nodes use RELAY_SENDME cells to implement end-to-end flow
|
|
control for individual connections across circuits. Similarly to
|
|
circuit-level flow control, edge nodes begin with a window of cells
|
|
(500) per stream, and increment the window by a fixed value (50)
|
|
upon receiving a RELAY_SENDME cell. Edge nodes initiate RELAY_SENDME
|
|
cells when both a) the window is <= 450, and b) there are less than
|
|
ten cell payloads remaining to be flushed at that edge.
|
|
|
|
|
|
7. Directories and routers
|
|
|
|
7.1. Router descriptor format.
|
|
|
|
(Unless otherwise noted, tokens on the same line are space-separated.)
|
|
|
|
Router ::= Router-Line Public-Key Signing-Key? Exit-Policy NL
|
|
Router-Line ::= "router" address ORPort OPPort APPort DirPort bandwidth
|
|
NL
|
|
Public-key ::= a public key in PEM format NL
|
|
Signing-Key ::= "signing-key" NL signing key in PEM format NL
|
|
Exit-Policy ::= Exit-Line*
|
|
Exit-Line ::= ("accept"|"reject") string NL
|
|
|
|
ORport ::= port where the router listens for other routers (speaking cells)
|
|
OPPort ::= where the router listens for onion proxies (speaking cells)
|
|
APPort ::= where the router listens for applications (speaking socks)
|
|
DirPort ::= where the router listens for directory download requests
|
|
bandwidth ::= maximum bandwidth, in bytes/s
|
|
|
|
|
|
Example:
|
|
router moria.mit.edu 9001 9011 9021 9031 100000
|
|
-----BEGIN RSA PUBLIC KEY-----
|
|
MIGJAoGBAMBBuk1sYxEg5jLAJy86U3GGJ7EGMSV7yoA6mmcsEVU3pwTUrpbpCmwS
|
|
7BvovoY3z4zk63NZVBErgKQUDkn3pp8n83xZgEf4GI27gdWIIwaBjEimuJlEY+7K
|
|
nZ7kVMRoiXCbjL6VAtNa4Zy1Af/GOm0iCIDpholeujQ95xew7rQnAgMA//8=
|
|
-----END RSA PUBLIC KEY-----
|
|
signing-key
|
|
-----BEGIN RSA PUBLIC KEY-----
|
|
7BvovoY3z4zk63NZVBErgKQUDkn3pp8n83xZgEf4GI27gdWIIwaBjEimuJlEY+7K
|
|
MIGJAoGBAMBBuk1sYxEg5jLAJy86U3GGJ7EGMSV7yoA6mmcsEVU3pwTUrpbpCmwS
|
|
f/GOm0iCIDpholeujQ95xew7rnZ7kVMRoiXCbjL6VAtNa4Zy1AQnAgMA//8=
|
|
-----END RSA PUBLIC KEY-----
|
|
reject 18.0.0.0/24
|
|
|
|
Note: The extra newline at the end of the router block is intentional.
|
|
|
|
7.2. Directory format
|
|
|
|
Directory ::= Directory-Header Directory-Router Router* Signature
|
|
Directory-Header ::= "signed-directory" NL Software-Line NL
|
|
Software-Line: "recommended-software" comma-separated-version-list
|
|
Directory-Router ::= Router
|
|
Signature ::= "directory-signature" NL "-----BEGIN SIGNATURE-----" NL
|
|
Base-64-encoded-signature NL "-----END SIGNATURE-----" NL
|
|
|
|
Note: The router block for the directory server must appear first.
|
|
The signature is computed by computing the SHA-1 hash of the
|
|
directory, from the characters "signed-directory", through the newline
|
|
after "directory-signature". This digest is then padded with PKCS.1,
|
|
and signed with the directory server's signing key.
|
|
|