Commit cb2c43d7 authored by Nick Mathewson's avatar Nick Mathewson
Browse files

Finish spec update


svn:r309
parent e75dc941
......@@ -346,44 +346,14 @@ which reveals the downstream node.
3. When a RELAY_CREATED cell is received, calculate the shared
keys. The circuit is now extended.
[ This next part is old. Update it. -NM]
Upon receiving a CREATE cell along a connection, an OR performs
the following steps:
1. If we already have an 'open' circuit along this connection
with this ACI, drop the cell.
Otherwise, if we have no circuit along this connection with
this ACI, let L = the integer value of the first 4 bytes of
the payload. Create a half-open circuit with this ACI, and
begin queueing CREATE cells for this circuit.
Otherwise, we have a half-open circuit. If the total payload
length of the CREATE cells for this circuit is exactly equal
to the onion length specified in the first cell (minus 4), then
process the onion. If it is more, then tear down the circuit.
2. Once we have a complete onion, decrypt the first 128 bytes
of the onion with this OR's RSA private key, and extract
the outmost onion layer. If the version, back cipher, or
forward cipher is unrecognized, or the expiration time is
in the past, then tear down the circuit (see section 4.2).
Compute K1 through K3 as above. Use K1 to decrypt the rest
of the onion using 3DES/OFB.
If we are not the exit node, remove the first layer from the
decrypted onion, and send the remainder to the next OR
on the circuit, as specified above. (Note that we'll
choose a different ACI for this circuit on the connection
with the next OR.)
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.
Some time after receiving a create cell, an onion router completes
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, some time after receiving the CREATE cell, 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),
......@@ -396,15 +366,13 @@ which reveals the downstream node.
4.4. Tearing down circuits
[Note: this section is untouched; the code doesn't seem to match
what I remembered discussing. Let's sort it out. -NM]
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.
circuit's intended lifetime is over. Circuits may be torn down
either completely or hop-by-hop.
To tear down a circuit, an OR or OP sends a DESTROY cell with that
direction's ACI to the adjacent nodes on that circuit.
To tear down a circuit completely, an OR or OP sends a DESTROY cell
with that direction's ACI to an adjacent nodes on that circuit.
Upon receiving a DESTROY cell, an OR frees resources associated
with the corresponding circuit. If it's not the start or end of the
......@@ -415,6 +383,17 @@ which reveals the downstream node.
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.
4.5. Routing data cells
When an OR receives a RELAY cell, it checks the cell's ACI and
......@@ -475,6 +454,8 @@ which reveals the downstream node.
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
......@@ -502,18 +483,13 @@ which reveals the downstream node.
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 the corresponding TCP stream.
[This should probably become:
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 topic. -NM]
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,
......@@ -543,36 +519,29 @@ which reveals the downstream node.
6.3. Circuit flow control
To control a circuit's bandwidth usage, each node keeps track of
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 a stream outside the network.
it is willing to deliver to streams outside the network.
Each 'window' value is initially set to 500 data cells
in each direction (cells that are not data cells do not affect
the window).
[Note: I'm not touching the rest of this section... it looks in the
code as if RELAY_COMMAND_SENDME is now doing double duty for both
stream flow control and circuit flow control. I thought we wanted
two different notions of windows. -NM]
[We do have two different 'levels' of windows. The relay sendme command
is talking about a stream for non-zero stream id, and talking about
the circuit for zero stream id. -RD]
Each edge node on a circuit sends a SENDME cell
(with length=100) every time it has received 100 data cells on the
circuit. When a node receives a SENDME cell for a circuit, it increases
the circuit's window in the corresponding direction (that is, for
sending data cells back in the direction from which the sendme arrived)
by the value of the cell's length field. If it's not an edge node,
it passes an equivalent SENDME cell to the next node in the circuit.
If the window value reaches 0 at the edge of a circuit, the OR stops
reading from the edge connections. (It may finish processing what
it's already read, and queue those cells for when a SENDME cell
arrives.) Otherwise (when not at the edge of a circuit), if the
window value is 0 and a data cell arrives, the node must tear down
the circuit.
the window). When an OR wants 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 and
delivery windows 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 (400), and
the node is ready to process more cells on that circuit.
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. Topic flow control
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment