summaryrefslogtreecommitdiff
path: root/src/feature/nodelist
diff options
context:
space:
mode:
Diffstat (limited to 'src/feature/nodelist')
-rw-r--r--src/feature/nodelist/authcert.c3
-rw-r--r--src/feature/nodelist/describe.c183
-rw-r--r--src/feature/nodelist/describe.h25
-rw-r--r--src/feature/nodelist/dirlist.c1
-rw-r--r--src/feature/nodelist/networkstatus.c50
-rw-r--r--src/feature/nodelist/nickname.c62
-rw-r--r--src/feature/nodelist/nickname.h19
-rw-r--r--src/feature/nodelist/node_select.c4
-rw-r--r--src/feature/nodelist/nodelist.c29
-rw-r--r--src/feature/nodelist/routerinfo.c79
-rw-r--r--src/feature/nodelist/routerinfo.h27
-rw-r--r--src/feature/nodelist/routerlist.c16
-rw-r--r--src/feature/nodelist/routerparse.c33
-rw-r--r--src/feature/nodelist/routerset.c6
-rw-r--r--src/feature/nodelist/torcert.c37
-rw-r--r--src/feature/nodelist/torcert.h6
16 files changed, 515 insertions, 65 deletions
diff --git a/src/feature/nodelist/authcert.c b/src/feature/nodelist/authcert.c
index e070cb1424..2624ed5eef 100644
--- a/src/feature/nodelist/authcert.c
+++ b/src/feature/nodelist/authcert.c
@@ -23,6 +23,7 @@
#include "core/mainloop/mainloop.h"
#include "core/or/policies.h"
#include "feature/client/bridges.h"
+#include "feature/dirauth/authmode.h"
#include "feature/dircommon/directory.h"
#include "feature/dirclient/dirclient.h"
#include "feature/dirclient/dlstatus.h"
@@ -34,7 +35,7 @@
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerlist.h"
#include "feature/nodelist/routerparse.h"
-#include "feature/relay/router.h"
+#include "feature/relay/routermode.h"
#include "core/or/connection_st.h"
#include "feature/dirclient/dir_server_st.h"
diff --git a/src/feature/nodelist/describe.c b/src/feature/nodelist/describe.c
new file mode 100644
index 0000000000..6df3da1965
--- /dev/null
+++ b/src/feature/nodelist/describe.c
@@ -0,0 +1,183 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file describe.c
+ * \brief Format short descriptions of relays.
+ */
+
+#include "core/or/or.h"
+#include "feature/nodelist/describe.h"
+#include "feature/nodelist/routerinfo.h"
+
+#include "core/or/extend_info_st.h"
+#include "feature/nodelist/node_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+#include "feature/nodelist/routerstatus_st.h"
+
+/**
+ * Longest allowed output of format_node_description, plus 1 character for
+ * NUL. This allows space for:
+ * "$FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF~xxxxxxxxxxxxxxxxxxx at"
+ * " [ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255]"
+ * plus a terminating NUL.
+ */
+#define NODE_DESC_BUF_LEN (MAX_VERBOSE_NICKNAME_LEN+4+TOR_ADDR_BUF_LEN)
+
+/** Use <b>buf</b> (which must be at least NODE_DESC_BUF_LEN bytes long) to
+ * hold a human-readable description of a node with identity digest
+ * <b>id_digest</b>, named-status <b>is_named</b>, nickname <b>nickname</b>,
+ * and address <b>addr</b> or <b>addr32h</b>.
+ *
+ * The <b>nickname</b> and <b>addr</b> fields are optional and may be set to
+ * NULL. The <b>addr32h</b> field is optional and may be set to 0.
+ *
+ * Return a pointer to the front of <b>buf</b>.
+ */
+static const char *
+format_node_description(char *buf,
+ const char *id_digest,
+ int is_named,
+ const char *nickname,
+ const tor_addr_t *addr,
+ uint32_t addr32h)
+{
+ char *cp;
+
+ if (!buf)
+ return "<NULL BUFFER>";
+
+ buf[0] = '$';
+ base16_encode(buf+1, HEX_DIGEST_LEN+1, id_digest, DIGEST_LEN);
+ cp = buf+1+HEX_DIGEST_LEN;
+ if (nickname) {
+ buf[1+HEX_DIGEST_LEN] = is_named ? '=' : '~';
+ strlcpy(buf+1+HEX_DIGEST_LEN+1, nickname, MAX_NICKNAME_LEN+1);
+ cp += strlen(cp);
+ }
+ if (addr32h || addr) {
+ memcpy(cp, " at ", 4);
+ cp += 4;
+ if (addr) {
+ tor_addr_to_str(cp, addr, TOR_ADDR_BUF_LEN, 0);
+ } else {
+ struct in_addr in;
+ in.s_addr = htonl(addr32h);
+ tor_inet_ntoa(&in, cp, INET_NTOA_BUF_LEN);
+ }
+ }
+ return buf;
+}
+
+/** Return a human-readable description of the routerinfo_t <b>ri</b>.
+ *
+ * This function is not thread-safe. Each call to this function invalidates
+ * previous values returned by this function.
+ */
+const char *
+router_describe(const routerinfo_t *ri)
+{
+ static char buf[NODE_DESC_BUF_LEN];
+
+ if (!ri)
+ return "<null>";
+ return format_node_description(buf,
+ ri->cache_info.identity_digest,
+ 0,
+ ri->nickname,
+ NULL,
+ ri->addr);
+}
+
+/** Return a human-readable description of the node_t <b>node</b>.
+ *
+ * This function is not thread-safe. Each call to this function invalidates
+ * previous values returned by this function.
+ */
+const char *
+node_describe(const node_t *node)
+{
+ static char buf[NODE_DESC_BUF_LEN];
+ const char *nickname = NULL;
+ uint32_t addr32h = 0;
+ int is_named = 0;
+
+ if (!node)
+ return "<null>";
+
+ if (node->rs) {
+ nickname = node->rs->nickname;
+ is_named = node->rs->is_named;
+ addr32h = node->rs->addr;
+ } else if (node->ri) {
+ nickname = node->ri->nickname;
+ addr32h = node->ri->addr;
+ }
+
+ return format_node_description(buf,
+ node->identity,
+ is_named,
+ nickname,
+ NULL,
+ addr32h);
+}
+
+/** Return a human-readable description of the routerstatus_t <b>rs</b>.
+ *
+ * This function is not thread-safe. Each call to this function invalidates
+ * previous values returned by this function.
+ */
+const char *
+routerstatus_describe(const routerstatus_t *rs)
+{
+ static char buf[NODE_DESC_BUF_LEN];
+
+ if (!rs)
+ return "<null>";
+ return format_node_description(buf,
+ rs->identity_digest,
+ rs->is_named,
+ rs->nickname,
+ NULL,
+ rs->addr);
+}
+
+/** Return a human-readable description of the extend_info_t <b>ei</b>.
+ *
+ * This function is not thread-safe. Each call to this function invalidates
+ * previous values returned by this function.
+ */
+const char *
+extend_info_describe(const extend_info_t *ei)
+{
+ static char buf[NODE_DESC_BUF_LEN];
+
+ if (!ei)
+ return "<null>";
+ return format_node_description(buf,
+ ei->identity_digest,
+ 0,
+ ei->nickname,
+ &ei->addr,
+ 0);
+}
+
+/** Set <b>buf</b> (which must have MAX_VERBOSE_NICKNAME_LEN+1 bytes) to the
+ * verbose representation of the identity of <b>router</b>. The format is:
+ * A dollar sign.
+ * The upper-case hexadecimal encoding of the SHA1 hash of router's identity.
+ * A "=" if the router is named (no longer implemented); a "~" if it is not.
+ * The router's nickname.
+ **/
+void
+router_get_verbose_nickname(char *buf, const routerinfo_t *router)
+{
+ buf[0] = '$';
+ base16_encode(buf+1, HEX_DIGEST_LEN+1, router->cache_info.identity_digest,
+ DIGEST_LEN);
+ buf[1+HEX_DIGEST_LEN] = '~';
+ strlcpy(buf+1+HEX_DIGEST_LEN+1, router->nickname, MAX_NICKNAME_LEN+1);
+}
diff --git a/src/feature/nodelist/describe.h b/src/feature/nodelist/describe.h
new file mode 100644
index 0000000000..e5723bb933
--- /dev/null
+++ b/src/feature/nodelist/describe.h
@@ -0,0 +1,25 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file describe.h
+ * \brief Header file for describe.c.
+ **/
+
+#ifndef TOR_DESCRIBE_H
+#define TOR_DESCRIBE_H
+
+struct extend_info_t;
+struct node_t;
+struct routerinfo_t;
+struct routerstatus_t;
+
+const char *extend_info_describe(const struct extend_info_t *ei);
+const char *node_describe(const struct node_t *node);
+const char *router_describe(const struct routerinfo_t *ri);
+const char *routerstatus_describe(const struct routerstatus_t *ri);
+
+#endif
diff --git a/src/feature/nodelist/dirlist.c b/src/feature/nodelist/dirlist.c
index 0935145d88..c14d7df0f0 100644
--- a/src/feature/nodelist/dirlist.c
+++ b/src/feature/nodelist/dirlist.c
@@ -29,6 +29,7 @@
#include "app/config/config.h"
#include "core/or/policies.h"
#include "feature/control/control.h"
+#include "feature/dirauth/authmode.h"
#include "feature/dircommon/directory.h"
#include "feature/nodelist/dirlist.h"
#include "feature/nodelist/networkstatus.h"
diff --git a/src/feature/nodelist/networkstatus.c b/src/feature/nodelist/networkstatus.c
index c6a51aefc7..67b5a1d046 100644
--- a/src/feature/nodelist/networkstatus.c
+++ b/src/feature/nodelist/networkstatus.c
@@ -38,48 +38,50 @@
#define NETWORKSTATUS_PRIVATE
#include "core/or/or.h"
-#include "feature/client/bridges.h"
+#include "app/config/config.h"
+#include "core/mainloop/connection.h"
+#include "core/mainloop/mainloop.h"
+#include "core/mainloop/netstatus.h"
#include "core/or/channel.h"
+#include "core/or/channelpadding.h"
#include "core/or/circuitmux.h"
#include "core/or/circuitmux_ewma.h"
#include "core/or/circuitstats.h"
-#include "app/config/config.h"
-#include "core/mainloop/connection.h"
#include "core/or/connection_edge.h"
#include "core/or/connection_or.h"
-#include "feature/dircache/consdiffmgr.h"
+#include "core/or/dos.h"
+#include "core/or/protover.h"
+#include "core/or/relay.h"
+#include "core/or/scheduler.h"
+#include "feature/client/bridges.h"
+#include "feature/client/entrynodes.h"
+#include "feature/client/transports.h"
#include "feature/control/control.h"
-#include "lib/crypt_ops/crypto_rand.h"
-#include "lib/crypt_ops/crypto_util.h"
-#include "feature/dircommon/directory.h"
+#include "feature/dirauth/reachability.h"
+#include "feature/dircache/consdiffmgr.h"
+#include "feature/dircache/dirserv.h"
#include "feature/dirclient/dirclient.h"
#include "feature/dirclient/dlstatus.h"
-#include "feature/dircache/dirserv.h"
-#include "feature/dirauth/reachability.h"
-#include "core/or/dos.h"
-#include "feature/client/entrynodes.h"
+#include "feature/dircommon/directory.h"
+#include "feature/dircommon/voting_schedule.h"
#include "feature/hibernate/hibernate.h"
-#include "core/mainloop/mainloop.h"
-#include "feature/nodelist/microdesc.h"
-#include "feature/nodelist/networkstatus.h"
-#include "feature/nodelist/nodelist.h"
-#include "core/or/protover.h"
-#include "core/or/relay.h"
-#include "feature/relay/router.h"
#include "feature/nodelist/authcert.h"
#include "feature/nodelist/dirlist.h"
+#include "feature/nodelist/fmt_routerstatus.h"
+#include "feature/nodelist/microdesc.h"
+#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/node_select.h"
+#include "feature/nodelist/nodelist.h"
+#include "feature/nodelist/routerinfo.h"
#include "feature/nodelist/routerlist.h"
#include "feature/nodelist/routerparse.h"
-#include "core/or/scheduler.h"
-#include "feature/client/transports.h"
#include "feature/nodelist/torcert.h"
-#include "core/or/channelpadding.h"
-#include "feature/dircommon/voting_schedule.h"
-#include "feature/nodelist/fmt_routerstatus.h"
+#include "feature/relay/routermode.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "lib/crypt_ops/crypto_util.h"
#include "feature/dirauth/dirvote.h"
-#include "feature/dirauth/mode.h"
+#include "feature/dirauth/authmode.h"
#include "feature/dirauth/shared_random.h"
#include "feature/dirauth/voteflags.h"
diff --git a/src/feature/nodelist/nickname.c b/src/feature/nodelist/nickname.c
new file mode 100644
index 0000000000..7b0b29a934
--- /dev/null
+++ b/src/feature/nodelist/nickname.c
@@ -0,0 +1,62 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file nickname.c
+ * \brief Check and manipulate relay nicknames.
+ */
+
+#include "core/or/or.h"
+#include "feature/nodelist/nickname.h"
+
+/** Return true iff <b>s</b> is a valid server nickname. (That is, a string
+ * containing between 1 and MAX_NICKNAME_LEN characters from
+ * LEGAL_NICKNAME_CHARACTERS.) */
+int
+is_legal_nickname(const char *s)
+{
+ size_t len;
+ tor_assert(s);
+ len = strlen(s);
+ return len > 0 && len <= MAX_NICKNAME_LEN &&
+ strspn(s,LEGAL_NICKNAME_CHARACTERS) == len;
+}
+
+/** Return true iff <b>s</b> is a valid server nickname or
+ * hex-encoded identity-key digest. */
+int
+is_legal_nickname_or_hexdigest(const char *s)
+{
+ if (*s!='$')
+ return is_legal_nickname(s);
+ else
+ return is_legal_hexdigest(s);
+}
+
+/** Return true iff <b>s</b> is a valid hex-encoded identity-key
+ * digest. (That is, an optional $, followed by 40 hex characters,
+ * followed by either nothing, or = or ~ followed by a nickname, or
+ * a character other than =, ~, or a hex character.)
+ */
+int
+is_legal_hexdigest(const char *s)
+{
+ size_t len;
+ tor_assert(s);
+ if (s[0] == '$') s++;
+ len = strlen(s);
+ if (len > HEX_DIGEST_LEN) {
+ if (s[HEX_DIGEST_LEN] == '=' ||
+ s[HEX_DIGEST_LEN] == '~') {
+ if (!is_legal_nickname(s+HEX_DIGEST_LEN+1))
+ return 0;
+ } else {
+ return 0;
+ }
+ }
+ return (len >= HEX_DIGEST_LEN &&
+ strspn(s,HEX_CHARACTERS)==HEX_DIGEST_LEN);
+}
diff --git a/src/feature/nodelist/nickname.h b/src/feature/nodelist/nickname.h
new file mode 100644
index 0000000000..86d4309918
--- /dev/null
+++ b/src/feature/nodelist/nickname.h
@@ -0,0 +1,19 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file nickname.h
+ * \brief Header file for nickname.c.
+ **/
+
+#ifndef TOR_NICKNAME_H
+#define TOR_NICKNAME_H
+
+int is_legal_nickname(const char *s);
+int is_legal_nickname_or_hexdigest(const char *s);
+int is_legal_hexdigest(const char *s);
+
+#endif
diff --git a/src/feature/nodelist/node_select.c b/src/feature/nodelist/node_select.c
index aab0bbe9f5..04a24de9a1 100644
--- a/src/feature/nodelist/node_select.c
+++ b/src/feature/nodelist/node_select.c
@@ -18,8 +18,9 @@
#include "core/or/policies.h"
#include "core/or/reasons.h"
#include "feature/client/entrynodes.h"
-#include "feature/dircommon/directory.h"
#include "feature/dirclient/dirclient.h"
+#include "feature/dircommon/directory.h"
+#include "feature/nodelist/describe.h"
#include "feature/nodelist/dirlist.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
@@ -28,6 +29,7 @@
#include "feature/nodelist/routerlist.h"
#include "feature/nodelist/routerset.h"
#include "feature/relay/router.h"
+#include "feature/relay/routermode.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/math/fp.h"
diff --git a/src/feature/nodelist/nodelist.c b/src/feature/nodelist/nodelist.c
index ce77d71c64..e3b77d562c 100644
--- a/src/feature/nodelist/nodelist.c
+++ b/src/feature/nodelist/nodelist.c
@@ -41,35 +41,36 @@
#define NODELIST_PRIVATE
#include "core/or/or.h"
-#include "lib/net/address.h"
+#include "app/config/config.h"
+#include "core/mainloop/mainloop.h"
+#include "core/mainloop/netstatus.h"
#include "core/or/address_set.h"
+#include "core/or/policies.h"
+#include "core/or/protover.h"
#include "feature/client/bridges.h"
-#include "app/config/config.h"
+#include "feature/client/entrynodes.h"
#include "feature/control/control.h"
-#include "feature/dircache/dirserv.h"
#include "feature/dirauth/process_descs.h"
-#include "feature/client/entrynodes.h"
-#include "feature/stats/geoip.h"
-#include "feature/hs/hs_common.h"
+#include "feature/dircache/dirserv.h"
#include "feature/hs/hs_client.h"
-#include "core/mainloop/mainloop.h"
+#include "feature/hs/hs_common.h"
+#include "feature/nodelist/describe.h"
+#include "feature/nodelist/dirlist.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
-#include "feature/nodelist/nodelist.h"
-#include "core/or/policies.h"
-#include "core/or/protover.h"
-#include "feature/rend/rendservice.h"
-#include "feature/relay/router.h"
-#include "feature/nodelist/dirlist.h"
#include "feature/nodelist/node_select.h"
+#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerlist.h"
#include "feature/nodelist/routerparse.h"
#include "feature/nodelist/routerset.h"
#include "feature/nodelist/torcert.h"
+#include "feature/rend/rendservice.h"
+#include "feature/stats/geoip.h"
+#include "lib/net/address.h"
#include <string.h>
-#include "feature/dirauth/mode.h"
+#include "feature/dirauth/authmode.h"
#include "feature/dirclient/dir_server_st.h"
#include "feature/nodelist/microdesc_st.h"
diff --git a/src/feature/nodelist/routerinfo.c b/src/feature/nodelist/routerinfo.c
new file mode 100644
index 0000000000..601de78d60
--- /dev/null
+++ b/src/feature/nodelist/routerinfo.c
@@ -0,0 +1,79 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "core/or/or.h"
+
+#include "feature/nodelist/nodelist.h"
+#include "feature/nodelist/routerinfo.h"
+
+#include "feature/nodelist/node_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+
+/** Copy the primary (IPv4) OR port (IP address and TCP port) for
+ * <b>router</b> into *<b>ap_out</b>. */
+void
+router_get_prim_orport(const routerinfo_t *router, tor_addr_port_t *ap_out)
+{
+ tor_assert(ap_out != NULL);
+ tor_addr_from_ipv4h(&ap_out->addr, router->addr);
+ ap_out->port = router->or_port;
+}
+
+int
+router_has_orport(const routerinfo_t *router, const tor_addr_port_t *orport)
+{
+ return
+ (tor_addr_eq_ipv4h(&orport->addr, router->addr) &&
+ orport->port == router->or_port) ||
+ (tor_addr_eq(&orport->addr, &router->ipv6_addr) &&
+ orport->port == router->ipv6_orport);
+}
+
+/** Return a smartlist of tor_addr_port_t's with all the OR ports of
+ <b>ri</b>. Note that freeing of the items in the list as well as
+ the smartlist itself is the callers responsibility. */
+smartlist_t *
+router_get_all_orports(const routerinfo_t *ri)
+{
+ tor_assert(ri);
+ node_t fake_node;
+ memset(&fake_node, 0, sizeof(fake_node));
+ /* we don't modify ri, fake_node is passed as a const node_t *
+ */
+ fake_node.ri = (routerinfo_t *)ri;
+ return node_get_all_orports(&fake_node);
+}
+
+/** Given a router purpose, convert it to a string. Don't call this on
+ * ROUTER_PURPOSE_UNKNOWN: The whole point of that value is that we don't
+ * know its string representation. */
+const char *
+router_purpose_to_string(uint8_t p)
+{
+ switch (p)
+ {
+ case ROUTER_PURPOSE_GENERAL: return "general";
+ case ROUTER_PURPOSE_BRIDGE: return "bridge";
+ case ROUTER_PURPOSE_CONTROLLER: return "controller";
+ default:
+ tor_assert(0);
+ }
+ return NULL;
+}
+
+/** Given a string, convert it to a router purpose. */
+uint8_t
+router_purpose_from_string(const char *s)
+{
+ if (!strcmp(s, "general"))
+ return ROUTER_PURPOSE_GENERAL;
+ else if (!strcmp(s, "bridge"))
+ return ROUTER_PURPOSE_BRIDGE;
+ else if (!strcmp(s, "controller"))
+ return ROUTER_PURPOSE_CONTROLLER;
+ else
+ return ROUTER_PURPOSE_UNKNOWN;
+}
diff --git a/src/feature/nodelist/routerinfo.h b/src/feature/nodelist/routerinfo.h
new file mode 100644
index 0000000000..b4b245bb23
--- /dev/null
+++ b/src/feature/nodelist/routerinfo.h
@@ -0,0 +1,27 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file routerinfo.h
+ * \brief Header file for routerinfo.c.
+ **/
+
+#ifndef TOR_ROUTERINFO_H
+#define TOR_ROUTERINFO_H
+
+void router_get_prim_orport(const routerinfo_t *router,
+ tor_addr_port_t *addr_port_out);
+int router_has_orport(const routerinfo_t *router,
+ const tor_addr_port_t *orport);
+
+void router_get_verbose_nickname(char *buf, const routerinfo_t *router);
+
+smartlist_t *router_get_all_orports(const routerinfo_t *ri);
+
+const char *router_purpose_to_string(uint8_t p);
+uint8_t router_purpose_from_string(const char *s);
+
+#endif
diff --git a/src/feature/nodelist/routerlist.c b/src/feature/nodelist/routerlist.c
index 5c6a104779..20956d8cca 100644
--- a/src/feature/nodelist/routerlist.c
+++ b/src/feature/nodelist/routerlist.c
@@ -68,24 +68,26 @@
#include "core/or/policies.h"
#include "feature/client/bridges.h"
#include "feature/control/control.h"
-#include "feature/dirauth/mode.h"
-#include "feature/dircommon/directory.h"
-#include "feature/dirclient/dirclient.h"
+#include "feature/dirauth/authmode.h"
+#include "feature/dirauth/process_descs.h"
+#include "feature/dirauth/reachability.h"
#include "feature/dircache/dirserv.h"
+#include "feature/dirclient/dirclient.h"
#include "feature/dirclient/dlstatus.h"
-#include "feature/dirauth/reachability.h"
-#include "feature/dirauth/process_descs.h"
+#include "feature/dircommon/directory.h"
#include "feature/nodelist/authcert.h"
+#include "feature/nodelist/describe.h"
#include "feature/nodelist/dirlist.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
-#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/node_select.h"
+#include "feature/nodelist/nodelist.h"
+#include "feature/nodelist/routerinfo.h"
#include "feature/nodelist/routerlist.h"
#include "feature/nodelist/routerparse.h"
#include "feature/nodelist/routerset.h"
#include "feature/nodelist/torcert.h"
-#include "feature/relay/router.h"
+#include "feature/relay/routermode.h"
#include "feature/stats/rephist.h"
#include "lib/crypt_ops/crypto_format.h"
#include "lib/crypt_ops/crypto_rand.h"
diff --git a/src/feature/nodelist/routerparse.c b/src/feature/nodelist/routerparse.c
index a72cf98f56..c12f411e87 100644
--- a/src/feature/nodelist/routerparse.c
+++ b/src/feature/nodelist/routerparse.c
@@ -56,29 +56,32 @@
#define ROUTERPARSE_PRIVATE
#include "core/or/or.h"
-#include "core/or/circuitstats.h"
#include "app/config/config.h"
-#include "lib/crypt_ops/crypto_format.h"
-#include "lib/crypt_ops/crypto_util.h"
-#include "feature/dirauth/shared_random.h"
+#include "core/or/circuitstats.h"
+#include "core/or/policies.h"
+#include "core/or/protover.h"
#include "feature/client/entrynodes.h"
-#include "lib/memarea/memarea.h"
+#include "feature/dirauth/shared_random.h"
+#include "feature/dircommon/voting_schedule.h"
+#include "feature/hs_common/shared_random_client.h"
+#include "feature/nodelist/authcert.h"
+#include "feature/nodelist/describe.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
+#include "feature/nodelist/nickname.h"
#include "feature/nodelist/parsecommon.h"
-#include "core/or/policies.h"
-#include "core/or/protover.h"
-#include "feature/rend/rendcommon.h"
-#include "feature/stats/rephist.h"
-#include "feature/relay/router.h"
-#include "feature/relay/routerkeys.h"
+#include "feature/nodelist/routerinfo.h"
#include "feature/nodelist/routerlist.h"
#include "feature/nodelist/routerparse.h"
-#include "feature/nodelist/authcert.h"
-#include "lib/sandbox/sandbox.h"
-#include "feature/hs_common/shared_random_client.h"
#include "feature/nodelist/torcert.h"
-#include "feature/dircommon/voting_schedule.h"
+#include "feature/relay/router.h"
+#include "feature/relay/routerkeys.h"
+#include "feature/rend/rendcommon.h"
+#include "feature/stats/rephist.h"
+#include "lib/crypt_ops/crypto_format.h"
+#include "lib/crypt_ops/crypto_util.h"
+#include "lib/memarea/memarea.h"
+#include "lib/sandbox/sandbox.h"
#include "feature/dirauth/dirvote.h"
diff --git a/src/feature/nodelist/routerset.c b/src/feature/nodelist/routerset.c
index cd42697748..08124835ae 100644
--- a/src/feature/nodelist/routerset.c
+++ b/src/feature/nodelist/routerset.c
@@ -28,13 +28,13 @@ n * Copyright (c) 2001-2004, Roger Dingledine.
#define ROUTERSET_PRIVATE
#include "core/or/or.h"
+#include "core/or/policies.h"
#include "feature/client/bridges.h"
-#include "feature/stats/geoip.h"
+#include "feature/nodelist/nickname.h"
#include "feature/nodelist/nodelist.h"
-#include "core/or/policies.h"
-#include "feature/relay/router.h"
#include "feature/nodelist/routerparse.h"
#include "feature/nodelist/routerset.h"
+#include "feature/stats/geoip.h"
#include "core/or/addr_policy_st.h"
#include "core/or/extend_info_st.h"
diff --git a/src/feature/nodelist/torcert.c b/src/feature/nodelist/torcert.c
index fe67e56403..675d5c97b7 100644
--- a/src/feature/nodelist/torcert.c
+++ b/src/feature/nodelist/torcert.c
@@ -638,6 +638,43 @@ or_handshake_certs_ed25519_ok(int severity,
return 1;
}
+/** Check whether an RSA-TAP cross-certification is correct. Return 0 if it
+ * is, -1 if it isn't. */
+MOCK_IMPL(int,
+check_tap_onion_key_crosscert,(const uint8_t *crosscert,
+ int crosscert_len,
+ const crypto_pk_t *onion_pkey,
+ const ed25519_public_key_t *master_id_pkey,
+ const uint8_t *rsa_id_digest))
+{
+ uint8_t *cc = tor_malloc(crypto_pk_keysize(onion_pkey));
+ int cc_len =
+ crypto_pk_public_checksig(onion_pkey,
+ (char*)cc,
+ crypto_pk_keysize(onion_pkey),
+ (const char*)crosscert,
+ crosscert_len);
+ if (cc_len < 0) {
+ goto err;
+ }
+ if (cc_len < DIGEST_LEN + ED25519_PUBKEY_LEN) {
+ log_warn(LD_DIR, "Short signature on cross-certification with TAP key");
+ goto err;
+ }
+ if (tor_memneq(cc, rsa_id_digest, DIGEST_LEN) ||
+ tor_memneq(cc + DIGEST_LEN, master_id_pkey->pubkey,
+ ED25519_PUBKEY_LEN)) {
+ log_warn(LD_DIR, "Incorrect cross-certification with TAP key");
+ goto err;
+ }
+
+ tor_free(cc);
+ return 0;
+ err:
+ tor_free(cc);
+ return -1;
+}
+
/**
* Check the Ed certificates and/or the RSA certificates, as appropriate. If
* we obtained an Ed25519 identity, set *ed_id_out. If we obtained an RSA
diff --git a/src/feature/nodelist/torcert.h b/src/feature/nodelist/torcert.h
index 5fa97679df..cb5e23cc33 100644
--- a/src/feature/nodelist/torcert.h
+++ b/src/feature/nodelist/torcert.h
@@ -107,4 +107,10 @@ void or_handshake_certs_check_both(int severity,
int tor_cert_encode_ed22519(const tor_cert_t *cert, char **cert_str_out);
+MOCK_DECL(int, check_tap_onion_key_crosscert,(const uint8_t *crosscert,
+ int crosscert_len,
+ const crypto_pk_t *onion_pkey,
+ const ed25519_public_key_t *master_id_pkey,
+ const uint8_t *rsa_id_digest));
+
#endif /* !defined(TORCERT_H_INCLUDED) */