GitLab is used only for code review, issue tracking and project management. Canonical locations for source code are still https://gitweb.torproject.org/ https://git.torproject.org/ and git-rw.torproject.org.

Commit d1108bfc authored by Nick Mathewson's avatar Nick Mathewson 🐝

Allow extra dirport URLs to be configured for authorities.

parent ae0aff87
Pipeline #3170 passed with stage
in 18 minutes and 53 seconds
......@@ -5437,6 +5437,71 @@ pt_parse_transport_line(const or_options_t *options,
return r;
}
/**
* Parse a flag describing an extra dirport for a directory authority.
*
* Right now, the supported format is exactly:
* `{upload,download,voting}=http://[IP:PORT]/`.
* Other URL schemes, and other suffixes, might be supported in the future.
*
* Only call this function if `flag` starts with one of the above strings.
*
* Return 0 on success, and -1 on failure.
*
* If `ds` is provided, then add any parsed dirport to `ds`. If `ds` is NULL,
* take no action other than parsing.
**/
static int
parse_dirauth_dirport(dir_server_t *ds, const char *flag)
{
tor_assert(flag);
auth_dirport_usage_t usage;
if (!strcasecmpstart(flag, "upload=")) {
usage = AUTH_USAGE_UPLOAD;
} else if (!strcasecmpstart(flag, "download=")) {
usage = AUTH_USAGE_DOWNLOAD;
} else if (!strcasecmpstart(flag, "voting=")) {
usage = AUTH_USAGE_DOWNLOAD;
} else {
tor_assert_nonfatal_unreached();
return -1;
}
const char *eq = strchr(flag, '=');
tor_assert(eq);
const char *target = eq + 1;
if (strcmpstart(target, "http://")) {
log_warn(LD_CONFIG, "Unsupported URL scheme in authority flag %s", flag);
return -1;
}
const char *addr = target + strlen("http://");
const char *eos = strchr(addr, '/');
size_t addr_len;
if (eos && strcmp(eos, "/")) {
log_warn(LD_CONFIG, "Unsupported URL prefix in authority flag %s", flag);
return -1;
} else if (eos) {
addr_len = eos - addr;
} else {
addr_len = strlen(addr);
}
char *addr_string = tor_strndup(addr, addr_len);
tor_addr_port_t dirport;
memset(&dirport, 0, sizeof(dirport));
int rv = tor_addr_port_parse(LOG_WARN, addr_string,
&dirport.addr, &dirport.port, -1);
if (ds != NULL && rv == 0) {
trusted_dir_server_add_dirport(ds, usage, &dirport);
}
tor_free(addr_string);
return rv;
}
/** Read the contents of a DirAuthority line from <b>line</b>. If
* <b>validate_only</b> is 0, and the line is well-formed, and it
* shares any bits with <b>required_type</b> or <b>required_type</b>
......@@ -5457,6 +5522,7 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
char v3_digest[DIGEST_LEN];
dirinfo_type_t type = 0;
double weight = 1.0;
smartlist_t *extra_dirports = smartlist_new();
memset(v3_digest, 0, sizeof(v3_digest));
......@@ -5525,6 +5591,11 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
}
ipv6_addrport_ptr = &ipv6_addrport;
}
} else if (!strcasecmpstart(flag, "upload=") ||
!strcasecmpstart(flag, "download=") ||
!strcasecmpstart(flag, "vote=")) {
// We'll handle these after creating the authority object.
smartlist_add(extra_dirports, flag);
} else {
log_warn(LD_CONFIG, "Unrecognized flag '%s' on DirAuthority line",
flag);
......@@ -5568,6 +5639,13 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
goto err;
}
if (validate_only) {
SMARTLIST_FOREACH_BEGIN(extra_dirports, const char *, cp) {
if (parse_dirauth_dirport(NULL, cp) < 0)
goto err;
} SMARTLIST_FOREACH_END(cp);
}
if (!validate_only && (!required_type || required_type & type)) {
dir_server_t *ds;
if (required_type)
......@@ -5579,6 +5657,11 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
ipv6_addrport_ptr,
digest, v3_digest, type, weight)))
goto err;
SMARTLIST_FOREACH_BEGIN(extra_dirports, const char *, cp) {
if (parse_dirauth_dirport(ds, cp) < 0)
goto err;
} SMARTLIST_FOREACH_END(cp);
dir_server_add(ds);
}
......@@ -5588,7 +5671,9 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
err:
r = -1;
done:
done:
smartlist_free(extra_dirports); // no need to free individual elements; they
// alias elements in 'items'
SMARTLIST_FOREACH(items, char*, s, tor_free(s));
smartlist_free(items);
tor_free(addrport);
......
Markdown is supported
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