aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--padding-spec.txt85
-rw-r--r--proposals/000-index.txt8
-rw-r--r--proposals/266-removing-current-obsolete-clients.txt8
-rw-r--r--proposals/275-md-published-time-is-silly.txt2
-rw-r--r--proposals/326-tor-relay-well-known-uri-rfc8615.md51
-rw-r--r--proposals/327-pow-over-intro.txt5
-rw-r--r--proposals/339-udp-over-tor.md13
-rw-r--r--proposals/340-packed-and-fragmented.md325
-rw-r--r--proposals/BY_INDEX.md3
-rw-r--r--proposals/README.md3
-rw-r--r--tor-spec.txt10
11 files changed, 448 insertions, 65 deletions
diff --git a/padding-spec.txt b/padding-spec.txt
index 825f1d7..511ea01 100644
--- a/padding-spec.txt
+++ b/padding-spec.txt
@@ -143,6 +143,12 @@ Table of Contents
user traffic in that time period is multiplexed over a single connection
(as it is with Tor).
+ Though flow measurement in principle can be bidirectional (counting cells
+ sent in both directions between a pair of IPs) or unidirectional (counting
+ only cells sent from one IP to another), we assume for safety that all
+ measurement is unidirectional, and so traffic must be sent by both parties
+ in order to prevent record splitting.
+
2.2. Implementation
Tor clients currently maintain one TLS connection to their Guard node to
@@ -154,35 +160,41 @@ Table of Contents
connections, and pad them, but otherwise not pad between normal relays.
Both clients and Guards will maintain a timer for all application (ie:
- non-directory) TLS connections. Every time a non-padding packet is sent or
- received by either end, that endpoint will sample a timeout value from
- between 1.5 seconds and 9.5 seconds using the max(X,X) distribution
- described in Section 2.3. The time range is subject to consensus
+ non-directory) TLS connections. Every time a padding packet sent by an
+ endpoint, that endpoint will sample a timeout value from
+ the max(X,X) distribution described in Section 2.3. The default
+ range is from 1.5 seconds to 9.5 seconds time range, subject to consensus
parameters as specified in Section 2.6.
- If the connection becomes active for any reason before this timer
- expires, the timer is reset to a new random value between 1.5 and 9.5
- seconds. If the connection remains inactive until the timer expires, a
- single CELL_PADDING cell will be sent on that connection.
+ (The timing is randomized to avoid making it obvious which cells are
+ padding.)
- In this way, the connection will only be padded in the event that it is
- idle, and will always transmit a packet before the minimum 10 second inactive
- timeout.
+ If another cell is sent for any reason before this timer expires, the timer
+ is reset to a new random value.
-2.3. Padding Cell Timeout Distribution Statistics
+ If the connection remains inactive until the timer expires, a
+ single CELL_PADDING cell will be sent on that connection (which will
+ also start a new timer).
+
+ In this way, the connection will only be padded in a given direction in
+ the event that it is idle in that direction, and will always transmit a
+ packet before the minimum 10 second inactive timeout.
- It turns out that because the padding is bidirectional, and because both
- endpoints are maintaining timers, this creates the situation where the time
- before sending a padding packet in either direction is actually
- min(client_timeout, server_timeout).
+ (In practice, an implementation may not be able to determine when,
+ exactly, a cell is sent on a given channel. For example, even though the
+ cell has been given to the kernel via a call to `send(2)`, the kernel may
+ still be buffering that cell. In cases such as these, implementations
+ should use a reasonable proxy for the time at which a cell is sent: for
+ example, when the cell is queued. If this strategy is used,
+ implementations should try to observe the innermost (closest to the wire)
+ queue that they practically can, and if this queue is already nonempty,
+ padding should not be scheduled until after the queue does become empty.)
- If client_timeout and server_timeout are uniformly sampled, then the
- distribution of min(client_timeout,server_timeout) is no longer uniform, and
- the resulting average timeout (Exp[min(X,X)]) is much lower than the
- midpoint of the timeout range.
+2.3. Padding Cell Timeout Distribution Statistics
- To compensate for this, instead of sampling each endpoint timeout uniformly,
- we instead sample it from max(X,X), where X is uniformly distributed.
+ To limit the amount of padding sent, instead of sampling each endpoint
+ timeout uniformly, we instead sample it from max(X,X), where X is
+ uniformly distributed.
If X is a random variable uniform from 0..R-1 (where R=high-low), then the
random variable Y = max(X,X) has Prob(Y == i) = (2.0*i + 1)/(R*R).
@@ -206,9 +218,6 @@ Table of Contents
15000 7499.5 7995 4999.5 9999.5
20000 9900.5 10661 6666.2 13332.8
- In this way, we maintain the property that the midpoint of the timeout range
- is the expected mean time before a padding packet is sent in either
- direction.
2.4. Maximum overhead bounds
@@ -253,6 +262,13 @@ Table of Contents
CELL_PADDING_NEGOTIATE to instruct the relay not to pad, and then does not
send any further padding itself.
+ Currently, clients negotiate padding only when a channel is created,
+ immediately after sending their NETINFO cell. Recipients SHOULD, however,
+ accept padding negotiation messages at any time.
+
+ Clients and bridges MUST reject padding negotiation messages from relays,
+ and close the channel if they receive one.
+
2.6. Consensus Parameters Governing Behavior
Connection-level padding is controlled by the following consensus parameters:
@@ -277,11 +293,22 @@ Table of Contents
- Default: 14000
* nf_conntimeout_clients
- - The number of seconds to keep circuits opened and available for
- clients to use. Note that the actual client timeout is randomized
- uniformly from this value to twice this value. This governs client
- OR conn lifespan. Reduced padding clients use half the consensus
+ - The number of seconds to keep never-used circuits opened and
+ available for clients to use. Note that the actual client timeout is
+ randomized uniformly from this value to twice this value.
+ - The number of seconds to keep idle (not currently used) canonical
+ channels are open and available. (We do this to ensure a sufficient
+ time duration of padding, which is the ultimate goal.)
+ - This value is also used to determine how long, after a port has been
+ used, we should attempt to keep building predicted circuits for that
+ port. (See path-spec.txt section 2.1.1.) This behavior was
+ originally added to work around implementation limitations, but it
+ serves as a reasonable default regardless of implementation.
+ - For all use cases, reduced padding clients use half the consensus
value.
+ - Implementations MAY mark circuits held open past the reduced padding
+ quantity (half the consensus value) as "not to be used for streams",
+ to prevent their use from becoming a distinguisher.
- Default: 1800
* nf_pad_before_usage
diff --git a/proposals/000-index.txt b/proposals/000-index.txt
index 4692f07..7d518c1 100644
--- a/proposals/000-index.txt
+++ b/proposals/000-index.txt
@@ -259,7 +259,8 @@ Proposals by number:
336 Randomized schedule for guard retries [ACCEPTED]
337 A simpler way to decide, "Is this guard usable?" [ACCEPTED]
338 Use an 8-byte timestamp in NETINFO cells [ACCEPTED]
-339 UDP traffic over Tor [DRAFT]
+339 UDP traffic over Tor [ACCEPTED]
+340 Packed and fragmented relay messages [OPEN]
Proposals by status:
@@ -270,7 +271,6 @@ Proposals by status:
327 A First Take at PoW Over Introduction Circuits
329 Overcoming Tor's Bottlenecks with Traffic Splitting
331 Res tokens: Anonymous Credentials for Onion Service DoS Resilience
- 339 UDP traffic over Tor
NEEDS-REVISION:
212 Increase Acceptable Consensus Age [for 0.2.4.x+]
219 Support for full DNS and DNSSEC resolution in Tor [for 0.2.5.x]
@@ -300,6 +300,7 @@ Proposals by status:
325 Packed relay cells: saving space on small commands
326 The "tor-relay" Well-Known Resource Identifier
330 Modernizing authority contact entries
+ 340 Packed and fragmented relay messages
ACCEPTED:
265 Load Balancing with Overhead Parameters [for 0.2.9.x]
282 Remove "Named" and "Unnamed" handling from consensus voting [for 0.3.3.x]
@@ -312,6 +313,7 @@ Proposals by status:
336 Randomized schedule for guard retries
337 A simpler way to decide, "Is this guard usable?"
338 Use an 8-byte timestamp in NETINFO cells
+ 339 UDP traffic over Tor
META:
000 Index of Tor Proposals
001 The Tor Proposal Process
@@ -409,7 +411,7 @@ Proposals by status:
271 Another algorithm for guard selection [in 0.3.0.1-alpha]
272 Listed routers should be Valid, Running, and treated as such [in 0.2.9.3-alpha, 0.2.9.4-alpha]
274 Rotate onion keys less frequently [in 0.3.1.1-alpha]
- 275 Stop including meaningful "published" time in microdescriptor consensus [for 0.3.1.x-alpha] [in 0.4.7.3-alpha]
+ 275 Stop including meaningful "published" time in microdescriptor consensus [for 0.3.1.x-alpha] [in 0.4.8.1-alpha]
278 Directory Compression Scheme Negotiation [in 0.3.1.1-alpha]
283 Move IPv6 ORPorts from microdescriptors to the microdesc consensus [for 0.3.3.x] [in 0.3.3.1-alpha]
284 Hidden Service v3 Control Port
diff --git a/proposals/266-removing-current-obsolete-clients.txt b/proposals/266-removing-current-obsolete-clients.txt
index bc3592b..a4cc75c 100644
--- a/proposals/266-removing-current-obsolete-clients.txt
+++ b/proposals/266-removing-current-obsolete-clients.txt
@@ -110,7 +110,7 @@ Superseded-by: 264, 272.
2.1. Dropping connections based on link protocols.
- Tor versions before before 0.2.3.6-alpha use a renegotiation-based
+ Tor versions before 0.2.3.6-alpha use a renegotiation-based
handshake instead of our current handshake. We could detect these
handshakes and close the connection at the relay side if the client
attempts to renegotiate.
@@ -137,7 +137,7 @@ Superseded-by: 264, 272.
behavior would probably be the same, though.)
If we throttled connections rather than closing them, we'd only get
- one connnection per authority per hour, but authorities would have to
+ one connection per authority per hour, but authorities would have to
keep open a potentially huge number of sockets.
2.2. Blocking circuit creation under certain circumstances
@@ -210,7 +210,7 @@ A. How to "pull the switch."
TIME 0:
Implement the client/relay side of proposal 264, backported
- to every currently existant Tor version that we still
+ to every currently extant Tor version that we still
support.
At the same time, add support for the new consensus type to
@@ -227,7 +227,7 @@ A. How to "pull the switch."
LATER:
- At some point after nearly all clients and relays hav
+ At some point after nearly all clients and relays have
upgraded to the versions released at Time 0 or later, we
could make the switchover to publishing the new consensus
type.
diff --git a/proposals/275-md-published-time-is-silly.txt b/proposals/275-md-published-time-is-silly.txt
index 12a762d..e08e9a8 100644
--- a/proposals/275-md-published-time-is-silly.txt
+++ b/proposals/275-md-published-time-is-silly.txt
@@ -4,7 +4,7 @@ Author: Nick Mathewson
Created: 20-Feb-2017
Status: Closed
Target: 0.3.1.x-alpha
-Implemented-In: 0.4.7.3-alpha
+Implemented-In: 0.4.8.1-alpha
0. Status:
diff --git a/proposals/326-tor-relay-well-known-uri-rfc8615.md b/proposals/326-tor-relay-well-known-uri-rfc8615.md
index 4f13835..2f820ea 100644
--- a/proposals/326-tor-relay-well-known-uri-rfc8615.md
+++ b/proposals/326-tor-relay-well-known-uri-rfc8615.md
@@ -10,22 +10,23 @@ Status: Open
This is a specification for a well-known [registry](https://www.iana.org/assignments/well-known-uris/) entry according to [RFC8615](https://tools.ietf.org/html/rfc8615).
-This resource identifier can be used for serving and finding proofs related to [Tor](https://www.torproject.org/) relay contact information.
-It can also be used for autodiscovery of Tor relays run by a given entity, if the entity domain is known.
-It solves the issue that Tor relay contact information is an unidirectional and unverified claim by nature.
+This resource identifier can be used for serving and finding proofs related to [Tor](https://www.torproject.org/) relay and bridge contact information.
+It can also be used for autodiscovery of Tor relays run by a given entity, if the entity's domain is known.
+It solves the issue that Tor relay/bridge contact information is an unidirectional and unverified claim by nature.
This well-known URI aims to allow the verification of the unidirectional claim.
-It aims to reduce the risk of impersonation attacks, where a Tor relay claims to be operated by a certain entity, but actually isn't.
-The automated verification will also support the [visualization of relay groups](https://gitlab.torproject.org/tpo/metrics/relay-search/-/issues/40001).
+It aims to reduce the risk of impersonation attacks, where a Tor relay/bridge claims to be operated by a certain entity, but actually isn't.
+The automated verification will also support the [visualization of relay/bridge groups](https://gitlab.torproject.org/tpo/metrics/relay-search/-/issues/40001).
-* An initially (unverified) Tor relay contact information might claim to be related to an
-organization by pointing to its website: Tor relay contact information field -> website
-* The "tor-relay" URI allows for the verification of that claim by fetching the files containing Tor relay ID(s) under the specified URI,
-because attackers can not easily place these files at the given location.
+* An initially (unverified) Tor relay or bridge contact information might claim to be related to an
+organization by pointing to its website: Tor relay/bridge contact information field -> website
+* The "tor-relay" URI allows for the verification of that claim by fetching the files containing Tor relay ID(s) or hashed bridge fingerprints
+under the specified URI, because attackers can not easily place these files at the given location.
-* By publishing Tor relay IDs under this URI the website operator claims to be the responsible entity for these Tor relays.
-The verification of listed Tor relay IDs only succeeds if the claim can be verified bidirectionally (website -> relay and relay -> website).
+* By publishing Tor relay IDs or hashed bridge IDs under this URI the website operator claims to be the responsible entity for these Tor relays/bridges.
+The verification of listed Tor relay/bridge IDs only succeeds if the claim can be verified bidirectionally
+(website -> relay/bridge and relay/bridge -> website).
-* This URI is not related to Tor bridges or Tor onion services.
+* This URI is not related to Tor onion services.
* The URL MUST be HTTPS and use a valid TLS certificate from a generally trusted root CA. Plain HTTP MUST not be used.
@@ -34,13 +35,13 @@ The verification of listed Tor relay IDs only succeeds if the claim can be verif
## /.well-known/tor-relay/rsa-fingerprint.txt
* The file contains one or more Tor relay RSA SHA1 fingerprints operated by the entity in control of this website.
-* Each line contains one fingerprint.
+* Each line contains one relay fingerprint.
+* The file MUST NOT contain fingerprints of Tor bridges (or hashes of bridge fingerprints). For bridges see the file `hashed-bridge-rsa-fingerprint.txt`.
* The file may contain comments (starting with #).
* Non-comment lines must be exactly 40 characters long and consist of the following characters [a-fA-F0-9].
* Fingerprints are not case-sensitive.
* Each fingerprint MUST appear at most once.
* The file MUST not be larger than one MByte.
-* The file MUST NOT contain fingerprints of Tor bridges (or hashes of bridge fingerprints).
* The content MUST be a media type of "text/plain".
Example file content:
@@ -55,6 +56,7 @@ The RSA SHA1 relay fingerprint can be found in the file named "fingerprint" loca
## /.well-known/tor-relay/ed25519-master-pubkey.txt
* The file contains one or more ed25519 Tor relay public master keys of relays operated by the entity in control of this website.
+* This file is not relevant for bridges.
* Each line contains one public ed25519 master key in its base64 encoded form.
* The file may contain comments (starting with #).
* Non-comment lines must be exactly 43 characters long and consist of the following characters [a-zA-z0-9/+].
@@ -73,6 +75,27 @@ bHzOT41w56KHh+w6TYwUhN4KrGwPWQWJX04/+tw/+RU
The base64 encoded ed25519 public master key can be found in the file named "fingerprint-ed25519" located in the Tor data directory on the relay.
+## /.well-known/tor-relay/hashed-bridge-rsa-fingerprint.txt
+
+* The file contains one or more SHA1 hashed Tor bridge SHA1 fingerprints operated by the entity in control of this website.
+* Each line contains one hashed bridge fingerprint.
+* The file may contain comments (starting with #).
+* Non-comment lines must be exactly 40 characters long and consist of the following characters [a-fA-F0-9].
+* Hashed fingerprints are not case-sensitive.
+* Each hashed fingerprint MUST appear at most once.
+* The file MUST not be larger than one MByte.
+* The file MUST NOT contain fingerprints of Tor relays.
+* The content MUST be a media type of "text/plain".
+
+Example file content:
+
+```
+# we operate these Tor bridges
+1234567890123456789012345678901234567ABC
+4234567890123456789012345678901234567890
+```
+
+The hashed Tor bridge fingerprint can be found in the file named "hashed-fingerprint" located in the Tor data directory on the bridge.
# Change Controller
diff --git a/proposals/327-pow-over-intro.txt b/proposals/327-pow-over-intro.txt
index fb58a7d..0fb528f 100644
--- a/proposals/327-pow-over-intro.txt
+++ b/proposals/327-pow-over-intro.txt
@@ -207,7 +207,8 @@ Status: Draft
This whole protocol starts with the service encoding the PoW parameters in
the 'encrypted' (inner) part of the v3 descriptor. As follows:
- "pow-params" SP type SP seed-b64 SP expiration-time NL
+ "pow-params" SP type SP seed-b64 SP suggested-effort
+ SP expiration-time NL
[At most once]
@@ -277,7 +278,7 @@ Status: Draft
We propose a new EXT_FIELD_TYPE value:
- [01] -- PROOF_OF_WORK
+ [02] -- PROOF_OF_WORK
The EXT_FIELD content format is:
diff --git a/proposals/339-udp-over-tor.md b/proposals/339-udp-over-tor.md
index 2dbe3b5..3c1a1d4 100644
--- a/proposals/339-udp-over-tor.md
+++ b/proposals/339-udp-over-tor.md
@@ -3,7 +3,7 @@ Filename: 339-udp-over-tor.md
Title: UDP traffic over Tor
Author: Nick Mathewson
Created: 11 May 2020
-Status: Draft
+Status: Accepted
```
# Introduction
@@ -198,12 +198,6 @@ format.
```
struct udp_connected_body {
- /* 5 bytes to distinguish from other CONNECTED_UDP cells. This is not
- * strictly necessary, since we can distinguish by context, but
- * it's nice to have a way to tell them apart at the parsing stage.
- */
- u32 zero IN [0];
- u8 ff IN [0xFF];
/* The address that the relay has bound locally. This might not
* be an address that is advertised in the relay's descriptor. */
struct address our_address;
@@ -216,7 +210,7 @@ struct udp_connected_body {
}
/* Note that this is a subset of the allowable address parts of a CONNECT_UDP
- message */
+ * message */
struct address {
u8 tag IN [T_IPV4, T_IPV6];
u8 len;
@@ -233,8 +227,7 @@ struct address {
```
struct datagram_body {
/* The datagram body is the entire body of the message.
- This length is in the relay message header.
- */
+ * This length is in the relay message header. */
u8 body[..];
}
```
diff --git a/proposals/340-packed-and-fragmented.md b/proposals/340-packed-and-fragmented.md
new file mode 100644
index 0000000..e7f08f4
--- /dev/null
+++ b/proposals/340-packed-and-fragmented.md
@@ -0,0 +1,325 @@
+```
+Filename: 340-packed-and-fragmented.md
+Title: Packed and fragmented relay messages
+Author: Nick Mathewson
+Created: 31 May 2022
+Status: Open
+```
+
+# Introduction
+
+Tor sends long-distance messages on circuits via _relay cells_. The
+current relay cell format allows one _relay message_ (e.g., "BEGIN" or
+"DATA" or "END") per relay cell. We want to relax this 1:1 requirement,
+between messages and cells, for two reasons:
+
+ * To support relay messages that are longer than the current 498-byte
+ limit. Applications would include wider handshake messages for
+ postquantum crypto, UDP messages, and SNIP transfer in walking
+ onions.
+
+ * To transmit small messages more efficiently. Several message types
+ (notably `SENDME`, `XON`, `XOFF`, and several types from
+ [proposal 329](./329-traffic-splitting.txt)) are much smaller than
+ the relay cell size, and could be sent comparatively often.
+
+In this proposal, we describe a way to decouple relay cells from relay
+messages. Relay messages can now be packed into multiple cells or split
+across multiple cells.
+
+This proposal combines ideas from
+[proposal 319](./319-wide-everything.md) (fragmentation) and
+[proposal 325](./325-packed-relay-cells.md) (packed cells). It requires
+[ntor v3](./332-ntor-v3-with-extra-data.md) and prepares for
+[next-generation relay cryptography](./308-counter-galois-onion).
+
+## A preliminary change: Relay encryption, version 1.5
+
+We are fairly sure that, whatever we do for our next batch of relay
+cryptography, we will want to increase the size of the data used to
+authenticate relay cells to 128 bits. (Currently it uses a 4-byte tag
+plus 2 bytes of zeros.)
+
+To avoid proliferating formats, I'm going to suggest that we make the
+other changes in this proposal changes concurrently with a change in our
+relay cryptography, so that we do not have too many incompatible cell
+formats going on at the same time.
+
+The new format for a decrypted relay _cell_ will be:
+
+ recognized [2 bytes]
+ digest [14 bytes]
+ body [509 - 16 = 493 bytes]
+
+"Digest" and "recognized" are computed as before; the only difference
+is that they occur _before_ the rest of the cell, and that "digest" is
+truncated to 14 bytes instead of 4.
+
+If we are lucky, we won't have to build this encryption at all, and we
+can just move to some version of GCM-UIV or other RPRP that reserves 16
+bytes for an authentication tag or similar cryptographic object.
+
+## New relay message packing
+
+Relay _messages_ now follow the following format:
+
+ Header
+ command u8
+ length u16
+ stream_id u16
+ Body
+ data u8[length]
+
+We require that "command" is never 0.
+
+Messages can be split across relay cells; multiple messages can occur in
+a single relay cell. We enforce the following rules:
+
+ * Headers may not be split across cells.
+ * If a 0 byte follows any relay message, there are no more messages in
+ that cell.
+ * A relay cell may not be "empty": it must have at least some part of
+ some message.
+
+Unless specified elsewhere, **all** message types may be packed, and
+**all** message types may be fragmented.
+
+Every command has an associated maximum length for its messages. If not
+specified elsewhere, the maximum length for every message is 498 bytes
+(for legacy reasons).
+
+Receivers MUST validate that headers are well-formed and have valid
+lengths while handling the cell in which the header is encoded. If the
+header is invalid, the receiver must destroy the circuit.
+
+### Some examples
+
+
+## Negotiation
+
+This message format requires a new `Relay` subprotocol version to
+indicate support. If a client wants to indicate support for this
+format, it sends the following extension as part of its `ntor3`
+handshake:
+
+ RELAY_PROTOCOL
+ version u8
+
+The `version` field is the `Relay` subprotocol version that the client
+wants to use. The relay must send back the same extension in its ntor3
+handshake to acknowledge support.
+
+## Migration
+
+We add a consensus parameter, "streamed-relay-messages", with default
+value 0, minimum value 0, and maximum value 1.
+
+If this value is 0, then clients will not (by default) negotiate this
+relay protocol. If it is 1, then clients will negotiate it when relays
+support it.
+
+For testing, clients can override this setting. Once enough relays
+support this proposal, we'll change the consensus parameter to 1.
+Later, we'll change the default to 1 as well.
+
+## Packing decisions
+
+We specify the following greedy algorithm for making decisions about
+fragmentation and packing. Other algorithms are possible, but this one
+is fairly simple, and using it will help avoid distinguishability
+issues:
+
+Whenever a client or relay is about to send a cell that would leave
+at least 32 bytes unused in a relay cell, it checks to see whether there
+is any pending data to be sent in the same circuit (in a data cell). If
+there is, then it adds a DATA message to the end of the current cell,
+with as much data as possible. Otherwise, the client sends the cell
+with no packed data.
+
+## Onion services
+
+Negotiating this for onion services will happen in a separate proposal;
+it is not a current priority, since there is nothing sent over
+rendezvous circuits that we currently need to fragment or pack.
+
+## Miscellany
+
+### Handling `RELAY_EARLY`
+
+The `RELAY_EARLY` status for a command is determined based on the relay
+cell in which the command's _header_ appeared.
+
+### Handling `SENDME`s
+
+SENDME messages may not be fragmented; the body and the command must
+appear in the same cell. (This is necessary so authenticated sendmes
+can have a reasonable implementation.)
+
+### An exception for `DATA`.
+
+Data messages may not be fragmented. (There is never a reason to do
+this.)
+
+### Extending message-length maxima
+
+For now, the maximum length for every message is 498 bytes, except as
+follows:
+
+ - `DATAGRAM` messages (see proposal 339) have a maximum body length
+ of 1967 bytes. (This works out to four relay cells, and
+ accommodates most reasonable MTU choices)
+
+Any increase in maximum length for any other message type requires a new
+Relay subprotocol version. (For example, if we later want to allow
+EXTEND2 messages to be 2000 bytes long, we need to add a new proposal
+saying so, and reserving a new subprotocol version.)
+
+# Appendix: Example cells
+
+
+Here is an example of the simplest case: one message, sent in one relay
+cell. Here it is a BEGIN message.
+
+```
+ Cell 1:
+ Cell header
+ circid .. [4 bytes]
+ command RELAY [1 byte]
+ relay cell header
+ recognized 0 [2 bytes]
+ digest (...) [14 bytes]
+ message header:
+ command BEGIN [1 byte]
+ length 23 [2 bytes]
+ stream_id (...) [2 bytes]
+ message body
+ "www.torproject.org:443\0" [23 bytes]
+ end-of-messages marker
+ 0 [1 byte]
+ padding up to end of cell
+ random [464 bytes]
+
+```
+
+Here's an example with fragmentation only: a large EXTEND2 message split
+across two relay cells.
+
+```
+ Cell 1:
+ Cell header
+ circid .. [4 bytes]
+ command RELAY_EARLY [1 byte]
+ relay cell header
+ recognized 0 [2 bytes]
+ digest (...) [14 bytes]
+ message header:
+ command EXTEND [1 byte]
+ length 800 [2 bytes]
+ stream_id 0 [2 bytes]
+ message body
+ (extend body, part 1) [488 bytes]
+
+ Cell 2:
+ Cell header
+ circid .. [4 bytes]
+ command RELAY [1 byte]
+ relay cell header
+ recognized 0 [2 bytes]
+ digest (...) [14 bytes]
+ message body, continued
+ (extend body, part 2) [312 bytes]
+ end-of-messages marker
+ 0 [1 byte]
+ padding up to end of cell
+ random [180 bytes]
+
+```
+
+Here is an example with packing only: A begin_dir message and a data
+message in the same cell.
+
+```
+ Cell 1:
+ Cell header
+ circid .. [4 bytes]
+ command RELAY [1 byte]
+ relay cell header
+ recognized 0 [2 bytes]
+ digest (...) [14 bytes]
+ message header:
+ command BEGIN_DIR [1 byte]
+ length 0 [2 bytes]
+ stream_id 32 [2 bytes]
+ message body:
+ (empty) --- [0 bytes]
+ message header:
+ command DATA [1 byte]
+ length 25 [2 bytes]
+ stream_id 32 [2 bytes]
+ message body:
+ "HTTP/1.0 GET /tor/foo\r\n\r\n" [25 bytes]
+ end-of-messages marker
+ 0 [1 byte]
+ padding up to end of cell
+ random [457 bytes]
+
+```
+
+Here is an example with packing and fragmentation: a large DATAGRAM cell, a
+SENDME cell, and an XON cell. (Note that this sequence of cells would not
+actually be generated by the algorithm described in "Packing decisions"
+above; this is only an example of what parties need to accept.)
+
+```
+ Cell 1:
+ Cell header
+ circid .. [4 bytes]
+ command RELAY [1 byte]
+ relay cell header
+ recognized 0 [2 bytes]
+ digest (...) [14 bytes]
+ message header:
+ command DATAGRAM [1 byte]
+ length 1200 [2 bytes]
+ stream_id 99 [2 bytes]
+ message body
+ (datagram body, part 1) [488 bytes]
+
+ Cell 2:
+ Cell header
+ circid .. [4 bytes]
+ command RELAY [1 byte]
+ relay cell header
+ recognized 0 [2 bytes]
+ digest (...) [14 bytes]
+ message body, continued
+ (datagram body, part 2) [493 bytes]
+
+ Cell 3:
+ Cell header
+ circid .. [4 bytes]
+ command RELAY [1 byte]
+ relay cell header
+ recognized 0 [2 bytes]
+ digest (...) [14 bytes]
+ message body, continued
+ (datagram body, part 3) [219 bytes] (488+493+219=1200)
+ message header:
+ command SENDME [1 byte]
+ length 23 [2 bytes]
+ stream_id 0 [2 bytes]
+ message body:
+ version 1 [1 byte]
+ datalen 20 [2 bytes]
+ data (digest to ack) [20 bytes]
+ message header:
+ command XON [1 byte]
+ length 1 [2 bytes]
+ stream_id 50 [2 bytes]
+ message body:
+ version 1 [1 byte]
+ end-of-messages marker
+ 0 [1 byte]
+ padding up to end of cell
+ random [239 bytes]
+```
diff --git a/proposals/BY_INDEX.md b/proposals/BY_INDEX.md
index 0e9aa1d..9383351 100644
--- a/proposals/BY_INDEX.md
+++ b/proposals/BY_INDEX.md
@@ -256,5 +256,6 @@ Below are a list of proposals sorted by their proposal number. See
* [`336-randomize-guard-retries.md`](/proposals/336-randomize-guard-retries.md): Randomized schedule for guard retries [ACCEPTED]
* [`337-simpler-guard-usability.md`](/proposals/337-simpler-guard-usability.md): A simpler way to decide, "Is this guard usable?" [ACCEPTED]
* [`338-netinfo-y2038.md`](/proposals/338-netinfo-y2038.md): Use an 8-byte timestamp in NETINFO cells [ACCEPTED]
-* [`339-udp-over-tor.md`](/proposals/339-udp-over-tor.md): UDP traffic over Tor [DRAFT]
+* [`339-udp-over-tor.md`](/proposals/339-udp-over-tor.md): UDP traffic over Tor [ACCEPTED]
+* [`340-packed-and-fragmented.md`](/proposals/340-packed-and-fragmented.md): Packed and fragmented relay messages [OPEN]
diff --git a/proposals/README.md b/proposals/README.md
index 643cf53..1431e8d 100644
--- a/proposals/README.md
+++ b/proposals/README.md
@@ -39,6 +39,7 @@ for discussion.
* [`325-packed-relay-cells.md`](/proposals/325-packed-relay-cells.md): Packed relay cells: saving space on small commands
* [`326-tor-relay-well-known-uri-rfc8615.md`](/proposals/326-tor-relay-well-known-uri-rfc8615.md): The "tor-relay" Well-Known Resource Identifier
* [`330-authority-contact.md`](/proposals/330-authority-contact.md): Modernizing authority contact entries
+* [`340-packed-and-fragmented.md`](/proposals/340-packed-and-fragmented.md): Packed and fragmented relay messages
## ACCEPTED proposals: slated for implementation
@@ -58,6 +59,7 @@ implementation.
* [`336-randomize-guard-retries.md`](/proposals/336-randomize-guard-retries.md): Randomized schedule for guard retries
* [`337-simpler-guard-usability.md`](/proposals/337-simpler-guard-usability.md): A simpler way to decide, "Is this guard usable?"
* [`338-netinfo-y2038.md`](/proposals/338-netinfo-y2038.md): Use an 8-byte timestamp in NETINFO cells
+* [`339-udp-over-tor.md`](/proposals/339-udp-over-tor.md): UDP traffic over Tor
## FINISHED proposals: implemented, specs not merged
@@ -106,7 +108,6 @@ discussion.
* [`327-pow-over-intro.txt`](/proposals/327-pow-over-intro.txt): A First Take at PoW Over Introduction Circuits
* [`329-traffic-splitting.txt`](/proposals/329-traffic-splitting.txt): Overcoming Tor's Bottlenecks with Traffic Splitting
* [`331-res-tokens-for-anti-dos.md`](/proposals/331-res-tokens-for-anti-dos.md): Res tokens: Anonymous Credentials for Onion Service DoS Resilience
-* [`339-udp-over-tor.md`](/proposals/339-udp-over-tor.md): UDP traffic over Tor
## NEEDS-REVISION proposals: ideas that we can't implement as-is
diff --git a/tor-spec.txt b/tor-spec.txt
index 49516f4..234d209 100644
--- a/tor-spec.txt
+++ b/tor-spec.txt
@@ -1684,6 +1684,8 @@ see tor-design.pdf.
14 -- RELAY_EXTEND2 [forward] [control]
15 -- RELAY_EXTENDED2 [backward] [control]
+ 16..18 -- Reserved for UDP; Not yet in use, see prop339.
+
32..40 -- Used for hidden services; see rend-spec-{v2,v3}.txt.
41..42 -- Used for circuit padding; see Section 3 of padding-spec.txt.
@@ -2435,3 +2437,11 @@ see tor-design.pdf.
"2" -- supports congestion control by the Exits which implies a new SENDME
format and algorithm. See proposal 324 for more details. Advertised
in tor 0.4.7.3-alpha.
+
+9.13. "Datagram"
+
+ Describes the UDP protocol capabilities of a relay.
+
+ "1" -- [RESERVED] supports UDP by an Exit as in the relay command
+ CONNECT_UDP, CONNECTED_UDP and DATAGRAM. See proposal
+ 339 for more details. (Not yet advertised, reserved)