Add a consensus method in which md families get canonicalized.

Implements prop298. Closes ticket 28266.
This commit is contained in:
Nick Mathewson 2018-11-24 11:51:41 -05:00
parent d29e3a02d5
commit 0a0c612b79
4 changed files with 60 additions and 4 deletions

5
changes/ticket28266 Normal file
View file

@ -0,0 +1,5 @@
o Minor features (directory authority):
- Directory authorities support a new consensus algorithm,
under which microdescriptor entries are encoded in a canonical
form. This improves their compressibility in transit and on the client.
Closes ticket 28266; implements proposal 298.

View file

@ -28,6 +28,7 @@
#include "feature/nodelist/fmt_routerstatus.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodefamily.h"
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerlist.h"
#include "feature/relay/router.h"
@ -3799,8 +3800,16 @@ dirvote_create_microdescriptor(const routerinfo_t *ri, int consensus_method)
smartlist_add_asprintf(chunks, "a %s\n",
fmt_addrport(&ri->ipv6_addr, ri->ipv6_orport));
if (family)
if (family) {
if (consensus_method < MIN_METHOD_FOR_CANONICAL_FAMILIES_IN_MICRODESCS) {
smartlist_add_asprintf(chunks, "family %s\n", family);
} else {
const uint8_t *id = (const uint8_t *)ri->cache_info.identity_digest;
char *canonical_family = nodefamily_canonicalize(family, id, 0);
smartlist_add_asprintf(chunks, "family %s\n", canonical_family);
tor_free(canonical_family);
}
}
if (summary && strcmp(summary, "reject 1-65535"))
smartlist_add_asprintf(chunks, "p %s\n", summary);
@ -3898,7 +3907,10 @@ static const struct consensus_method_range_t {
int high;
} microdesc_consensus_methods[] = {
{MIN_SUPPORTED_CONSENSUS_METHOD, MIN_METHOD_FOR_NO_A_LINES_IN_MICRODESC - 1},
{MIN_METHOD_FOR_NO_A_LINES_IN_MICRODESC, MAX_SUPPORTED_CONSENSUS_METHOD},
{MIN_METHOD_FOR_NO_A_LINES_IN_MICRODESC,
MIN_METHOD_FOR_CANONICAL_FAMILIES_IN_MICRODESCS - 1},
{MIN_METHOD_FOR_CANONICAL_FAMILIES_IN_MICRODESCS,
MAX_SUPPORTED_CONSENSUS_METHOD},
{-1, -1}
};

View file

@ -57,7 +57,7 @@
#define MIN_SUPPORTED_CONSENSUS_METHOD 25
/** The highest consensus method that we currently support. */
#define MAX_SUPPORTED_CONSENSUS_METHOD 28
#define MAX_SUPPORTED_CONSENSUS_METHOD 29
/** Lowest consensus method where authorities vote on required/recommended
* protocols. */
@ -79,6 +79,12 @@
* addresses. See #23828 and #20916. */
#define MIN_METHOD_FOR_NO_A_LINES_IN_MICRODESC 28
/**
* Lowest consensus method where microdescriptor lines are put in canonical
* form for improved compressibility and ease of storage. See proposal 298.
**/
#define MIN_METHOD_FOR_CANONICAL_FAMILIES_IN_MICRODESCS 29
/** Default bandwidth to clip unmeasured bandwidths to using method >=
* MIN_METHOD_TO_CLIP_UNMEASURED_BW. (This is not a consensus method; do not
* get confused with the above macros.) */

View file

@ -421,6 +421,28 @@ static const char test_md2_21[] =
"ntor-onion-key hbxdRnfVUJJY7+KcT4E3Rs7/zuClbN3hJrjSBiEGMgI=\n"
"id ed25519 wqfLzgfCtRfYNg88LsL1QpzxS0itapJ1aj6TbnByx/Q\n";
static const char test_md2_withfamily_28[] =
"onion-key\n"
"-----BEGIN RSA PUBLIC KEY-----\n"
"MIGJAoGBAL2R8EfubUcahxha4u02P4VAR0llQIMwFAmrHPjzcK7apcQgDOf2ovOA\n"
"+YQnJFxlpBmCoCZC6ssCi+9G0mqo650lFuTMP5I90BdtjotfzESfTykHLiChyvhd\n"
"l0dlqclb2SU/GKem/fLRXH16aNi72CdSUu/1slKs/70ILi34QixRAgMBAAE=\n"
"-----END RSA PUBLIC KEY-----\n"
"ntor-onion-key hbxdRnfVUJJY7+KcT4E3Rs7/zuClbN3hJrjSBiEGMgI=\n"
"family OtherNode !Strange\n"
"id ed25519 wqfLzgfCtRfYNg88LsL1QpzxS0itapJ1aj6TbnByx/Q\n";
static const char test_md2_withfamily_29[] =
"onion-key\n"
"-----BEGIN RSA PUBLIC KEY-----\n"
"MIGJAoGBAL2R8EfubUcahxha4u02P4VAR0llQIMwFAmrHPjzcK7apcQgDOf2ovOA\n"
"+YQnJFxlpBmCoCZC6ssCi+9G0mqo650lFuTMP5I90BdtjotfzESfTykHLiChyvhd\n"
"l0dlqclb2SU/GKem/fLRXH16aNi72CdSUu/1slKs/70ILi34QixRAgMBAAE=\n"
"-----END RSA PUBLIC KEY-----\n"
"ntor-onion-key hbxdRnfVUJJY7+KcT4E3Rs7/zuClbN3hJrjSBiEGMgI=\n"
"family !Strange $B7E27F104213C36F13E7E9829182845E495997A0 othernode\n"
"id ed25519 wqfLzgfCtRfYNg88LsL1QpzxS0itapJ1aj6TbnByx/Q\n";
static void
test_md_generate(void *arg)
{
@ -451,6 +473,17 @@ test_md_generate(void *arg)
tt_assert(ed25519_pubkey_eq(md->ed25519_identity_pkey,
&ri->cache_info.signing_key_cert->signing_key));
// Try family encoding.
microdesc_free(md);
ri->declared_family = smartlist_new();
smartlist_add_strdup(ri->declared_family, "OtherNode !Strange");
md = dirvote_create_microdescriptor(ri, 28);
tt_str_op(md->body, OP_EQ, test_md2_withfamily_28);
microdesc_free(md);
md = dirvote_create_microdescriptor(ri, 29);
tt_str_op(md->body, OP_EQ, test_md2_withfamily_29);
done:
microdesc_free(md);
routerinfo_free(ri);