[tor-dev] Proposal: Tor bandwidth measurements document format
juga
juga at riseup.net
Tue May 1 17:08:00 UTC 2018
Hi,
Thanks Nick for the comments, i'm replaying only to the parts where i
give an answer or i've more questions. I'd accept the rest of your
suggestions unless there will be further comments.
Nick Mathewson:
> Hi, Juga!
>
> This is a review of the document from
> https://raw.githubusercontent.com/juga0/torspec/c7f06023dd1d5d47adad128de541f8eba2a13bfb/bandwidth-file-spec.txt
> , which I *think* is the same as the document you have below.
Yes, it is.
>
> I'm reviewing this as though it were a fully new format, since I'm not sure
> how much we already have locked-in based on existing code, and how much is
> new. We might decide that backward compatibility is more important than
> consistency, and if so, we won't want to take all of my recommendations
> here.
>
>
>> Tor Bandwidth Measurements Document Format
>> juga
>> teor
>>
>> 1. Scope and preliminaries
>>
>> This document describes the format of Tor's bandwidth measurements
>> document, version 1.0.0 and later.
>
> Suggestion: Maybe explicitly say "1.0.0, 1.1.0, and later"?
>
>> Since Tor version 0.2.4.12-alpha the directory
>> authorities use the bandwidth measurements document called
>> "V3BandwidthsFile" and produced by Torflow [1]
>> (format described in README.spec.txt [2]).
>
> Recommendation: "Format described in Torflow's README.spec.txt".
>
> Explanation needed: Is this a new format, or a new specification of the
> existing format? Let's say so here.
New version of existing format. Though old version (Torflow's), didn't
have an specification in the sense this specification is being made).
> Question: If this is a different format, and we're calling it version
> 1.0.0, what should we call the old one? But later it seems that we're
> introducing 1.1.0, and we're calling the old one 1.0.0.
yeah, this would be 1.1.0, the old one (Torflow's) would be 1.0.0
> Suggestion: let's be explicit that we're only describing the format
> here, and *not* describing how bwauths generate their data.
>
>
>> The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
>> NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
>> "OPTIONAL" in this document are to be interpreted as described in
>> RFC 2119.
>>
>> 1.2. Acknowledgements
>>
>> The original bandwidth measurement scanner (Torflow) and format was
>> created by mike. Teor suggested to write this specification while
>> contributing on pastly's new bandwidth scanner implementation.
>>
>> This specification was revised after feedback from:
>>
>> XXX
>>
>> 1.3 Outline
>>
>> The bandwidth measurements mentioned in sections 3.4.1 and 3.4.2
>> of "Tor directory protocol" (dir-spec.txt) [3] are obtained
>> by bandwidth authorities, which generate a file storing information
>> on relays' measured bandwidth capacities.
>>
>> 1.4. Format Versions
>>
>> 1.0.0 - The legacy fallback bandwidth measurements document format
>>
>> 1.1.0 - Adds key_value lines to the header, format version,
>> optional ones and section separator.
>
> Information: Let's repeat in this section which versions of Tor can
> consume these versions.
>
>> 2. Format details
>>
>> Bandwidth measurements MUST contain the following sections:
>> - Header (exactly once)
>> - Relays measurements (zero or more times)
>
> Grammar suggestion: "Relay measurements".
>
>
>
>> 2.1. Definitions
>>
>> The following nonterminals are defined in dir-spec.txt, sections
>> 1.2., 2.1.1., 2.1.3.:
>>
>> Int
>> SP (space)
>> NL (newline)
>> Keyword
>> ArgumentChar
>> fingerprint (hexdigest)
>
> Does this have to start with a "$" ? I think it does. Maybe we should be
> explicit about that.
Yes
>> nickname
>>
>> Nonterminals defined in "Tor Directory List Format" (dir-list-spec.txt),
>> section 2.2.1.:
>>
>> version_number
>>
>> We define the following nonterminals:
>>
>> value ::= ArgumentChar+
>> key_value ::= Keyword "=" value
>> line ::= ArgumentChar* NL
>> timestamp ::= Int
>> bandwidth ::= Int
>> relay_line ::= key_value (SP key_value)* NL
>>
>> 2.2. Header format
One more thing that teor pointed at me: any line MUST be shorter than
512 characters (legacy restriction).
Teor pointed at me, i thought it was only for timestamp, but then i
realized it's for any line.
>> Some header lines MUST appear in specific positions, as documented below.
>> All other lines can appear in any order.
>>
>> There MUST NOT be multiple key_value header lines with the same key.
>
> Maybe this line belongs below in the key_value section?
>
>> It consists of:
>>
>> timestamp NL
>>
>> [At start, exactly once.]
>>
>> The Unix Epoch time in seconds when the file was created.
>
> Question: Why no keyword and equal sign here? Is this a legacy thing?
Yes, because of the way Tor [0] parses it, and the way Torflow generates it.
>
> Also, wouldn't it be more standard to have it be in YYYY-MM-DDTHH:MM:SS
> format?
In this case we would need to patch current versions to accept it. Would
be that ok?. In that case we could also make it key_value.
We need one path right now: change function in [0] to accept additional
headers (ticket #25960).
>
>> "version=" version_number NL
>>
>> [In second position, zero or one time.]
>>
>> The specification document format version.
>> It uses semantic versioning [5].
>>
>> This line has been added in version 1.1.0 of this specification.
>>
>> Version 1.0.0 documents do not contain this line, and the
>> version_number is considered to be "1.0.0".
>
> General concern: I question the use of = signs here in the headers. If
> we use "SP" instead, then we can reuse a lot of the same machinery tor
> currently uses to parse other documents.
I guess we should see then how much we should refactor function in [0]
to reuse parsecommon.c (as you pointed me at by IRC).
>> "software=" value NL
>>
>> [Zero or one time.]
>>
>> The name of the software that created the document.
>>
>> This line has been added in version 1.1.0 of this specification.
>>
>> Version 1.0.0 documents do not contain this line, and the software is
>> considered to be "torflow".
>>
>> "software_version=" value NL
>>
>> [Zero or one time.]
>>
>> The version of the software that created the document.
>> The version may be a version_number, a git commit, or some other
>> version scheme.
>>
>> This line has been added in version 1.1.0 of this specification.
>>
>> "scanner_started=" timestamp NL
>>
>> [Zero or one time.]
>>
>> The Unix Epoch time in seconds when the scanner that generates the
>> measurements document started.
>>
>> This line has been added in version 1.1.0 of this specification.
>
> See note above about time format. YYYY-MM-DDTHH:MM:SS is how we specify
> times elsewhere in Tor.
Since this is new, then no problem on changing to this format.
>> "earliest_measurement=" timestamp NL
>>
>> [Zero or one time.]
>>
>> The Unix Epoch time in seconds when the first relay measurement
>> was obtained.
>>
>> This line has been added in version 1.1.0 of this specification.
>
> See note above about time format.
>
>> key_value NL
>>
>> [Zero or more times.]
>>
>> Future format versions may include additional key_value header lines.
>> Additional header lines will be accompanied by a minor version
> increment.
>>
>> Implementations MAY add additional header lines as needed. This
>> specification SHOULD be updated to avoid conflicting meanings for the
>> same header keys.
>>
>> Parsers MUST NOT rely on the order of these additional lines.
>>
>> Additional header lines MUST NOT use any keywords specified in the
>> relay measurements format.
>>
>> If a header line does not conform to this format, the line SHOULD be
>> ignored by parsers.
>
> Suggestion: say what recipients of this document should do with
> unrecognized data. In general, it's good for forward compatibility to
> say something like, "Recipients MUST ignore key_value lines if they do
> not recognize the keyword. Recipients MUST ignore any extra material in
> a line that they do not recognize."
>
> Also see suggestion above about using SP as our separator rather than
> "=" for consistency with other documents Tor parses.
>
>> NL
>>
>> [Zero or one time.]
>>
>> The header ends.
>>
>> This line has been added in version 1.1.0 of this specification.
>>
>> For version 1.0.0 documents, the header ends when the first relay
>> measurement line is found conforming to the next section.
>
> Suggestion: Replace this empty line with an explicit keyword, for
> consistency with other documents.
Also to avoid interpreting section ends when there was just garbage.
Any suggestion on which one to use?, dir-list-spec.txt uses "=====",
don't know which ones other documents use.
>> 2.3. Relay measurements format
As in 2.2, to be compatible with current implementations, it MUST be
shorter than 512 characters.
>> It consists of zero or more relay_line with the measurement results
>> of relays in arbitrary order.
>>
>> There can be at most one relay_line per relay identity (fingerprint).
>>
>> There MUST NOT be multiple key_value pairs with the same key in the same
>> relay_line.
>>
>> Each relay_line MUST include the following key_value in arbitrary order:
>
> Do existing implementations accept arbitrary order here?
Good question, it seems like bw must be behind node_id, but they can
have things in front and behind. I probably should create a ticket to
add more test lines in [1] or include them in #25960.
>> "node_id=" fingerprint
>>
>> [Exactly once.]
>>
>> The fingerprint of the relay being measured.
>
> Suggestion: Add a field to hold the Ed25519 Identity of the relay being
> measured. Say that implementations SHOULD include both RSA fingerprint
> and Ed25519 identity, and that implementations SHOULD accept lines that
> contain at least one of them.
>
>> "bw=" bandwidth
>>
>> [Exactly once.]
>>
>> The measured bandwidth of this relay.
>>
>> Tor accepts zero bandwidths, but they trigger bugs in older Tor
>> implementations. Therefore, implementations SHOULD NOT produce zero
>> bandwidths. Instead, they SHOULD use one as their minimum bandwidth.
>>
>> Multiple measurements can be aggregated using an averaging scheme,
> such
>> as a mean, median, or decaying average.
>>
>> Torflow scales bandwidths to kilobytes per second. Other
> implementations
>> SHOULD use kilobytes per second for their initial bandwidth scaling.
>>
>> If different implementations or configurations are used in votes for
> the
>> same network, their measurements MAY need further scaling. See
> Appendix B
>> for information about scaling, and one possible scaling method.
>>
>> key_value
>>
>> [Zero or more times.]
>
> Technically, this isn't a key_value, because a "value" is made of
> ArgumentChar, and ArgumentChar can contain spaces. So if we were
> parsing
> "foo=abc bar=def"
> we might be parsing either one key_value ("foo", "abc bar=def") or two
> ("foo", "abc"), ("bar, "def").
>
You're right. The closest from dir-spec.txt is KeywordChar, but that
doesn't include colon, for instance. So, we would need to define what is
accepted here (unless it is defined in some other document).
>> Future format versions may include additional key_value pairs on a
> relay_line.
>> Additional key_value pairs will be accompanied by a minor version
> increment.
>>
>> Implementations MAY add additional relay key_value pairs as needed.
> This
>> specification SHOULD be updated to avoid conflicting meanings for the
>> same relay keys.
>>
>> Parsers MUST NOT rely on the order of these additional key_value
> pairs.
>>
>> Additional key_value pairs MUST NOT use any keywords specified in the
>> header format.
>
> As above, let's say that a parser should ignore key_value entries with
> keywords that it doesn't recognize.
>
>>
>> If a relay line does not conform to this format, the line SHOULD be
>> ignored by parsers.
>>
>> 2.4. Implementation notes
>>
>> 2.4.1. Simple Bandwidth Scanner
>>
>> Every relay measurement in sbws version 0.1.0 consists of:
>>
>> "node_id=" fingerprint SP
>>
>> As above.
>>
>> "bw=" bandwidth SP
>>
>> As above.
>>
>> "nick=" nickname SP
>>
>> [Exactly once.]
>>
>> The relay nickname.
>>
>> "rtt=" Int SP
>>
>> [Exactly once.]
>>
>> The Round Trip Time in milliseconds to obtain 1 byte of data.
>>
>> "time=" timestamp NL
>>
>> [Exactly once.]
>>
>> The Unix Epoch time in seconds when the last measurement was
> performed.
>>
>> 2.4.2. Torflow
>>
>> Torflow relay lines include node_id and bw, and other key_value pairs [2].
>>
>> References:
>>
>> 1. https://gitweb.torproject.org/torflow.git
>> 2.
> https://gitweb.torproject.org/torflow.git/tree/NetworkScanners/BwAuthority/README.spec.txt#n332
>> 3. https://gitweb.torproject.org/torspec.git/tree/dir-spec.txt
>> 4. https://metrics.torproject.org/onionoo.html#details
>> 5. https://semver.org/
>>
>> A. Sample data
>>
>> The following has not been obtained from any real measurement.
>>
>> A.1. Generated by Torflow
>>
>> This an example version 1.0.0 document:
>>
>> 1523911758
>> node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=760 nick=Test
> measured_at=1523911725 updated_at=1523911725 pid_error=4.11374090719
> pid_error_sum=4.11374090719 pid_bw=57136645 pid_delta=2.12168374577
> circ_fail=0.2 scanner=/filepath
>> node_id=$96C15995F30895689291F455587BD94CA427B6FC bw=189 nick=Test2
> measured_at=1523911623 updated_at=1523911623 pid_error=3.96703337994
> pid_error_sum=3.96703337994 pid_bw=47422125 pid_delta=2.65469736988
> circ_fail=0.0 scanner=/filepath
>>
>> A.2. Generated by sbws version 0.1.0
>>
>> 1523911758
>> version=1.1.0
>> software=sbws
>> software_version=0.1.0
>> scanner_started=1523911756
>> earliest_measurement=1523911757
>>
>> node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 bw=760 nick=Test
> rtt=380 time=1523911725
>> node_id=$96C15995F30895689291F455587BD94CA427B6FC bw=189 nick=Test2
> rtt=378 time=1523911623
>>
>> B. Scaling bandwidths
>>
>> B.1. Scaling requirements
>>
>> Tor accepts zero bandwidths, but they trigger bugs in older Tor
>> implementations. Therefore, scaling methods SHOULD perform the
>> following checks:
>> * If the total bandwidth is zero, all relays should be given equal
>> bandwidths.
>> * If the scaled bandwidth is zero, it should be rounded up to one.
>>
>> Initial experiments indicate that scaling may not be needed for
>> torflow and sbws, because their measured bandwidths are similar
>> enough already.
>>
>> B.2. A linear scaling method
>>
>> If scaling is required, here is a simple linear bandwith scaling
>> method, which ensures that all bandwidth votes contain approximately
>> the same total bandwidth:
>>
>> 1. Calculate the relay quota by dividing the total measured bandwidth
>> in all votes, by the number of relays with measured bandwidth
>> votes. In the public tor network, this is approximately 7500 as of
>> April 2018. The quota should be a consensus parameter, so it can be
>> adjusted for all scanners on the network.
>>
>> 2. Calculate a vote quota by multiplying the relay quota by the number
>> of relays this bandwidth authority has measured
>> bandwidths for.
>>
>> 3. Calculate a scaling factor by dividing the vote quota by the
>> total unscaled measured bandwidth in this bandwidth
>> authority's upcoming vote.
>>
>> 4. Multiply each unscaled measured bandwidth by the scaling
>> factor.
>>
>> Now, the total scaled bandwidth in the upcoming vote is
>> approximately equal to the quota.
>>
>> B.3. Quota changes
>>
>> If all scanners are using scaling, the quota can be gradually
>> reduced or increased as needed. Smaller quotas decrease the size
>> of uncompressed consensuses, and may decrease the size of
>> consensus diffs and compressed consensuses. But if the relay
>> quota is too small, some relays may be over- or under-weighted.
>
>
[0] https://gitweb.torproject.org/tor.git/tree/src/or/dirserv.c#n2563
[1] https://gitweb.torproject.org/torspec.git/tree/dir-list-spec.txt#n131
[2] https://gitweb.torproject.org/tor.git/tree/src/test/test_dir.c#n1495
More information about the tor-dev
mailing list