aboutsummaryrefslogtreecommitdiff
path: root/src/feature
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2018-10-01 11:08:09 -0500
committerNick Mathewson <nickm@torproject.org>2018-10-01 11:17:19 -0500
commit35db3f8162f132cec7afc148eda8f7482dbeeb76 (patch)
tree7c00b06286d5c75f5ab5d854a201031c7e7a0f9a /src/feature
parent95e2eb9083d2cd9c79c3f4151850c86cbeaf4cc4 (diff)
downloadtor-35db3f8162f132cec7afc148eda8f7482dbeeb76.tar.gz
tor-35db3f8162f132cec7afc148eda8f7482dbeeb76.zip
Extract addr-policy parsing code.
Diffstat (limited to 'src/feature')
-rw-r--r--src/feature/dirparse/parsecommon.c4
-rw-r--r--src/feature/dirparse/parsecommon.h4
-rw-r--r--src/feature/dirparse/policy_parse.c218
-rw-r--r--src/feature/dirparse/policy_parse.h25
-rw-r--r--src/feature/dirparse/routerparse.c200
-rw-r--r--src/feature/dirparse/routerparse.h6
-rw-r--r--src/feature/nodelist/routerset.c2
7 files changed, 255 insertions, 204 deletions
diff --git a/src/feature/dirparse/parsecommon.c b/src/feature/dirparse/parsecommon.c
index ab815f585d..c12f199e4e 100644
--- a/src/feature/dirparse/parsecommon.c
+++ b/src/feature/dirparse/parsecommon.c
@@ -51,7 +51,7 @@ token_clear(directory_token_t *tok)
int
tokenize_string(memarea_t *area,
const char *start, const char *end, smartlist_t *out,
- token_rule_t *table, int flags)
+ const token_rule_t *table, int flags)
{
const char **s;
directory_token_t *tok = NULL;
@@ -257,7 +257,7 @@ token_check_object(memarea_t *area, const char *kwd,
*/
directory_token_t *
get_next_token(memarea_t *area,
- const char **s, const char *eos, token_rule_t *table)
+ const char **s, const char *eos, const token_rule_t *table)
{
/** Reject any object at least this big; it is probably an overflow, an
* attack, a bug, or some other nonsense. */
diff --git a/src/feature/dirparse/parsecommon.h b/src/feature/dirparse/parsecommon.h
index d0f3810c0b..f14862f04a 100644
--- a/src/feature/dirparse/parsecommon.h
+++ b/src/feature/dirparse/parsecommon.h
@@ -302,12 +302,12 @@ void token_clear(directory_token_t *tok);
int tokenize_string(struct memarea_t *area,
const char *start, const char *end,
struct smartlist_t *out,
- token_rule_t *table,
+ const token_rule_t *table,
int flags);
directory_token_t *get_next_token(struct memarea_t *area,
const char **s,
const char *eos,
- token_rule_t *table);
+ const token_rule_t *table);
directory_token_t *find_by_keyword_(struct smartlist_t *s,
directory_keyword keyword,
diff --git a/src/feature/dirparse/policy_parse.c b/src/feature/dirparse/policy_parse.c
new file mode 100644
index 0000000000..e102a62282
--- /dev/null
+++ b/src/feature/dirparse/policy_parse.c
@@ -0,0 +1,218 @@
+/* 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 policy_parse.c
+ * \brief Code to parse address policies.
+ **/
+
+#define EXPOSE_ROUTERDESC_TOKEN_TABLE
+
+#include "core/or/or.h"
+
+#include "core/or/policies.h"
+#include "feature/dirparse/parsecommon.h"
+#include "feature/dirparse/policy_parse.h"
+#include "feature/dirparse/routerparse.h"
+#include "feature/dirparse/unparseable.h"
+#include "lib/memarea/memarea.h"
+
+#include "core/or/addr_policy_st.h"
+
+static addr_policy_t *router_parse_addr_policy_private(directory_token_t *tok);
+
+/** Parse the addr policy in the string <b>s</b> and return it. If
+ * assume_action is nonnegative, then insert its action (ADDR_POLICY_ACCEPT or
+ * ADDR_POLICY_REJECT) for items that specify no action.
+ *
+ * Returns NULL on policy errors.
+ *
+ * Set *<b>malformed_list</b> to true if the entire policy list should be
+ * discarded. Otherwise, set it to false, and only this item should be ignored
+ * on error - the rest of the policy list can continue to be processed and
+ * used.
+ *
+ * The addr_policy_t returned by this function can have its address set to
+ * AF_UNSPEC for '*'. Use policy_expand_unspec() to turn this into a pair
+ * of AF_INET and AF_INET6 items.
+ */
+MOCK_IMPL(addr_policy_t *,
+router_parse_addr_policy_item_from_string,(const char *s, int assume_action,
+ int *malformed_list))
+{
+ directory_token_t *tok = NULL;
+ const char *cp, *eos;
+ /* Longest possible policy is
+ * "accept6 [ffff:ffff:..255]/128:10000-65535",
+ * which contains a max-length IPv6 address, plus 26 characters.
+ * But note that there can be an arbitrary amount of space between the
+ * accept and the address:mask/port element.
+ * We don't need to multiply TOR_ADDR_BUF_LEN by 2, as there is only one
+ * IPv6 address. But making the buffer shorter might cause valid long lines,
+ * which parsed in previous versions, to fail to parse in new versions.
+ * (These lines would have to have excessive amounts of whitespace.) */
+ char line[TOR_ADDR_BUF_LEN*2 + 32];
+ addr_policy_t *r;
+ memarea_t *area = NULL;
+
+ tor_assert(malformed_list);
+ *malformed_list = 0;
+
+ s = eat_whitespace(s);
+ /* We can only do assume_action on []-quoted IPv6, as "a" (accept)
+ * and ":" (port separator) are ambiguous */
+ if ((*s == '*' || *s == '[' || TOR_ISDIGIT(*s)) && assume_action >= 0) {
+ if (tor_snprintf(line, sizeof(line), "%s %s",
+ assume_action == ADDR_POLICY_ACCEPT?"accept":"reject", s)<0) {
+ log_warn(LD_DIR, "Policy %s is too long.", escaped(s));
+ return NULL;
+ }
+ cp = line;
+ tor_strlower(line);
+ } else { /* assume an already well-formed address policy line */
+ cp = s;
+ }
+
+ eos = cp + strlen(cp);
+ area = memarea_new();
+ tok = get_next_token(area, &cp, eos, routerdesc_token_table);
+ if (tok->tp == ERR_) {
+ log_warn(LD_DIR, "Error reading address policy: %s", tok->error);
+ goto err;
+ }
+ if (tok->tp != K_ACCEPT && tok->tp != K_ACCEPT6 &&
+ tok->tp != K_REJECT && tok->tp != K_REJECT6) {
+ log_warn(LD_DIR, "Expected 'accept' or 'reject'.");
+ goto err;
+ }
+
+ /* Use the extended interpretation of accept/reject *,
+ * expanding it into an IPv4 wildcard and an IPv6 wildcard.
+ * Also permit *4 and *6 for IPv4 and IPv6 only wildcards. */
+ r = router_parse_addr_policy(tok, TAPMP_EXTENDED_STAR);
+ if (!r) {
+ goto err;
+ }
+
+ /* Ensure that accept6/reject6 fields are followed by IPv6 addresses.
+ * AF_UNSPEC addresses are only permitted on the accept/reject field type.
+ * Unlike descriptors, torrcs exit policy accept/reject can be followed by
+ * either an IPv4 or IPv6 address. */
+ if ((tok->tp == K_ACCEPT6 || tok->tp == K_REJECT6) &&
+ tor_addr_family(&r->addr) != AF_INET6) {
+ /* This is a non-fatal error, just ignore this one entry. */
+ *malformed_list = 0;
+ log_warn(LD_DIR, "IPv4 address '%s' with accept6/reject6 field type in "
+ "exit policy. Ignoring, but continuing to parse rules. (Use "
+ "accept/reject with IPv4 addresses.)",
+ tok->n_args == 1 ? tok->args[0] : "");
+ addr_policy_free(r);
+ r = NULL;
+ goto done;
+ }
+
+ goto done;
+ err:
+ *malformed_list = 1;
+ r = NULL;
+ done:
+ token_clear(tok);
+ if (area) {
+ DUMP_AREA(area, "policy item");
+ memarea_drop_all(area);
+ }
+ return r;
+}
+
+/** Given a K_ACCEPT[6] or K_REJECT[6] token and a router, create and return
+ * a new exit_policy_t corresponding to the token. If TAPMP_EXTENDED_STAR
+ * is set in fmt_flags, K_ACCEPT6 and K_REJECT6 tokens followed by *
+ * expand to IPv6-only policies, otherwise they expand to IPv4 and IPv6
+ * policies */
+addr_policy_t *
+router_parse_addr_policy(directory_token_t *tok, unsigned fmt_flags)
+{
+ addr_policy_t newe;
+ char *arg;
+
+ tor_assert(tok->tp == K_REJECT || tok->tp == K_REJECT6 ||
+ tok->tp == K_ACCEPT || tok->tp == K_ACCEPT6);
+
+ if (tok->n_args != 1)
+ return NULL;
+ arg = tok->args[0];
+
+ if (!strcmpstart(arg,"private"))
+ return router_parse_addr_policy_private(tok);
+
+ memset(&newe, 0, sizeof(newe));
+
+ if (tok->tp == K_REJECT || tok->tp == K_REJECT6)
+ newe.policy_type = ADDR_POLICY_REJECT;
+ else
+ newe.policy_type = ADDR_POLICY_ACCEPT;
+
+ /* accept6/reject6 * produces an IPv6 wildcard address only.
+ * (accept/reject * produces rules for IPv4 and IPv6 wildcard addresses.) */
+ if ((fmt_flags & TAPMP_EXTENDED_STAR)
+ && (tok->tp == K_ACCEPT6 || tok->tp == K_REJECT6)) {
+ fmt_flags |= TAPMP_STAR_IPV6_ONLY;
+ }
+
+ if (tor_addr_parse_mask_ports(arg, fmt_flags, &newe.addr, &newe.maskbits,
+ &newe.prt_min, &newe.prt_max) < 0) {
+ log_warn(LD_DIR,"Couldn't parse line %s. Dropping", escaped(arg));
+ return NULL;
+ }
+
+ return addr_policy_get_canonical_entry(&newe);
+}
+
+/** Parse an exit policy line of the format "accept[6]/reject[6] private:...".
+ * This didn't exist until Tor 0.1.1.15, so nobody should generate it in
+ * router descriptors until earlier versions are obsolete.
+ *
+ * accept/reject and accept6/reject6 private all produce rules for both
+ * IPv4 and IPv6 addresses.
+ */
+static addr_policy_t *
+router_parse_addr_policy_private(directory_token_t *tok)
+{
+ const char *arg;
+ uint16_t port_min, port_max;
+ addr_policy_t result;
+
+ arg = tok->args[0];
+ if (strcmpstart(arg, "private"))
+ return NULL;
+
+ arg += strlen("private");
+ arg = (char*) eat_whitespace(arg);
+ if (!arg || *arg != ':')
+ return NULL;
+
+ if (parse_port_range(arg+1, &port_min, &port_max)<0)
+ return NULL;
+
+ memset(&result, 0, sizeof(result));
+ if (tok->tp == K_REJECT || tok->tp == K_REJECT6)
+ result.policy_type = ADDR_POLICY_REJECT;
+ else
+ result.policy_type = ADDR_POLICY_ACCEPT;
+ result.is_private = 1;
+ result.prt_min = port_min;
+ result.prt_max = port_max;
+
+ if (tok->tp == K_ACCEPT6 || tok->tp == K_REJECT6) {
+ log_warn(LD_GENERAL,
+ "'%s' expands into rules which apply to all private IPv4 and "
+ "IPv6 addresses. (Use accept/reject private:* for IPv4 and "
+ "IPv6.)", tok->n_args == 1 ? tok->args[0] : "");
+ }
+
+ return addr_policy_get_canonical_entry(&result);
+}
+
diff --git a/src/feature/dirparse/policy_parse.h b/src/feature/dirparse/policy_parse.h
new file mode 100644
index 0000000000..887aa9261b
--- /dev/null
+++ b/src/feature/dirparse/policy_parse.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 policy_parse.h
+ * \brief Header file for policy_parse.c.
+ **/
+
+#ifndef TOR_POLICY_PARSE_H
+#define TOR_POLICY_PARSE_H
+
+#include "lib/testsupport/testsupport.h"
+
+struct directory_token_t;
+
+MOCK_DECL(addr_policy_t *, router_parse_addr_policy_item_from_string,
+ (const char *s, int assume_action, int *malformed_list));
+
+addr_policy_t *router_parse_addr_policy(struct directory_token_t *tok,
+ unsigned fmt_flags);
+
+#endif /* !defined(TOR_POLICY_PARSE_H) */
diff --git a/src/feature/dirparse/routerparse.c b/src/feature/dirparse/routerparse.c
index 0e97735643..54c0e89480 100644
--- a/src/feature/dirparse/routerparse.c
+++ b/src/feature/dirparse/routerparse.c
@@ -51,6 +51,7 @@
**/
#define ROUTERPARSE_PRIVATE
+#define EXPOSE_ROUTERDESC_TOKEN_TABLE
#include "core/or/or.h"
#include "app/config/config.h"
@@ -61,6 +62,7 @@
#include "feature/dirauth/shared_random.h"
#include "feature/dircommon/voting_schedule.h"
#include "feature/dirparse/parsecommon.h"
+#include "feature/dirparse/policy_parse.h"
#include "feature/dirparse/routerparse.h"
#include "feature/hs_common/shared_random_client.h"
#include "feature/nodelist/authcert.h"
@@ -111,7 +113,7 @@
/****************************************************************************/
/** List of tokens recognized in router descriptors */
-static token_rule_t routerdesc_token_table[] = {
+const token_rule_t routerdesc_token_table[] = {
T0N("reject", K_REJECT, ARGS, NO_OBJ ),
T0N("accept", K_ACCEPT, ARGS, NO_OBJ ),
T0N("reject6", K_REJECT6, ARGS, NO_OBJ ),
@@ -197,10 +199,6 @@ static token_rule_t extrainfo_token_table[] = {
/* static function prototypes */
static int router_add_exit_policy(routerinfo_t *router,directory_token_t *tok);
-static addr_policy_t *router_parse_addr_policy(directory_token_t *tok,
- unsigned fmt_flags);
-static addr_policy_t *router_parse_addr_policy_private(directory_token_t *tok);
-
static smartlist_t *find_all_exitpolicy(smartlist_t *s);
/** Set <b>digest</b> to the SHA-1 digest of the hash of the first router in
@@ -1201,109 +1199,6 @@ extrainfo_parse_entry_from_string(const char *s, const char *end,
return extrainfo;
}
-/** Parse the addr policy in the string <b>s</b> and return it. If
- * assume_action is nonnegative, then insert its action (ADDR_POLICY_ACCEPT or
- * ADDR_POLICY_REJECT) for items that specify no action.
- *
- * Returns NULL on policy errors.
- *
- * Set *<b>malformed_list</b> to true if the entire policy list should be
- * discarded. Otherwise, set it to false, and only this item should be ignored
- * on error - the rest of the policy list can continue to be processed and
- * used.
- *
- * The addr_policy_t returned by this function can have its address set to
- * AF_UNSPEC for '*'. Use policy_expand_unspec() to turn this into a pair
- * of AF_INET and AF_INET6 items.
- */
-MOCK_IMPL(addr_policy_t *,
-router_parse_addr_policy_item_from_string,(const char *s, int assume_action,
- int *malformed_list))
-{
- directory_token_t *tok = NULL;
- const char *cp, *eos;
- /* Longest possible policy is
- * "accept6 [ffff:ffff:..255]/128:10000-65535",
- * which contains a max-length IPv6 address, plus 26 characters.
- * But note that there can be an arbitrary amount of space between the
- * accept and the address:mask/port element.
- * We don't need to multiply TOR_ADDR_BUF_LEN by 2, as there is only one
- * IPv6 address. But making the buffer shorter might cause valid long lines,
- * which parsed in previous versions, to fail to parse in new versions.
- * (These lines would have to have excessive amounts of whitespace.) */
- char line[TOR_ADDR_BUF_LEN*2 + 32];
- addr_policy_t *r;
- memarea_t *area = NULL;
-
- tor_assert(malformed_list);
- *malformed_list = 0;
-
- s = eat_whitespace(s);
- /* We can only do assume_action on []-quoted IPv6, as "a" (accept)
- * and ":" (port separator) are ambiguous */
- if ((*s == '*' || *s == '[' || TOR_ISDIGIT(*s)) && assume_action >= 0) {
- if (tor_snprintf(line, sizeof(line), "%s %s",
- assume_action == ADDR_POLICY_ACCEPT?"accept":"reject", s)<0) {
- log_warn(LD_DIR, "Policy %s is too long.", escaped(s));
- return NULL;
- }
- cp = line;
- tor_strlower(line);
- } else { /* assume an already well-formed address policy line */
- cp = s;
- }
-
- eos = cp + strlen(cp);
- area = memarea_new();
- tok = get_next_token(area, &cp, eos, routerdesc_token_table);
- if (tok->tp == ERR_) {
- log_warn(LD_DIR, "Error reading address policy: %s", tok->error);
- goto err;
- }
- if (tok->tp != K_ACCEPT && tok->tp != K_ACCEPT6 &&
- tok->tp != K_REJECT && tok->tp != K_REJECT6) {
- log_warn(LD_DIR, "Expected 'accept' or 'reject'.");
- goto err;
- }
-
- /* Use the extended interpretation of accept/reject *,
- * expanding it into an IPv4 wildcard and an IPv6 wildcard.
- * Also permit *4 and *6 for IPv4 and IPv6 only wildcards. */
- r = router_parse_addr_policy(tok, TAPMP_EXTENDED_STAR);
- if (!r) {
- goto err;
- }
-
- /* Ensure that accept6/reject6 fields are followed by IPv6 addresses.
- * AF_UNSPEC addresses are only permitted on the accept/reject field type.
- * Unlike descriptors, torrcs exit policy accept/reject can be followed by
- * either an IPv4 or IPv6 address. */
- if ((tok->tp == K_ACCEPT6 || tok->tp == K_REJECT6) &&
- tor_addr_family(&r->addr) != AF_INET6) {
- /* This is a non-fatal error, just ignore this one entry. */
- *malformed_list = 0;
- log_warn(LD_DIR, "IPv4 address '%s' with accept6/reject6 field type in "
- "exit policy. Ignoring, but continuing to parse rules. (Use "
- "accept/reject with IPv4 addresses.)",
- tok->n_args == 1 ? tok->args[0] : "");
- addr_policy_free(r);
- r = NULL;
- goto done;
- }
-
- goto done;
- err:
- *malformed_list = 1;
- r = NULL;
- done:
- token_clear(tok);
- if (area) {
- DUMP_AREA(area, "policy item");
- memarea_drop_all(area);
- }
- return r;
-}
-
/** Add an exit policy stored in the token <b>tok</b> to the router info in
* <b>router</b>. Return 0 on success, -1 on failure. */
static int
@@ -1340,95 +1235,6 @@ router_add_exit_policy(routerinfo_t *router, directory_token_t *tok)
return 0;
}
-/** Given a K_ACCEPT[6] or K_REJECT[6] token and a router, create and return
- * a new exit_policy_t corresponding to the token. If TAPMP_EXTENDED_STAR
- * is set in fmt_flags, K_ACCEPT6 and K_REJECT6 tokens followed by *
- * expand to IPv6-only policies, otherwise they expand to IPv4 and IPv6
- * policies */
-static addr_policy_t *
-router_parse_addr_policy(directory_token_t *tok, unsigned fmt_flags)
-{
- addr_policy_t newe;
- char *arg;
-
- tor_assert(tok->tp == K_REJECT || tok->tp == K_REJECT6 ||
- tok->tp == K_ACCEPT || tok->tp == K_ACCEPT6);
-
- if (tok->n_args != 1)
- return NULL;
- arg = tok->args[0];
-
- if (!strcmpstart(arg,"private"))
- return router_parse_addr_policy_private(tok);
-
- memset(&newe, 0, sizeof(newe));
-
- if (tok->tp == K_REJECT || tok->tp == K_REJECT6)
- newe.policy_type = ADDR_POLICY_REJECT;
- else
- newe.policy_type = ADDR_POLICY_ACCEPT;
-
- /* accept6/reject6 * produces an IPv6 wildcard address only.
- * (accept/reject * produces rules for IPv4 and IPv6 wildcard addresses.) */
- if ((fmt_flags & TAPMP_EXTENDED_STAR)
- && (tok->tp == K_ACCEPT6 || tok->tp == K_REJECT6)) {
- fmt_flags |= TAPMP_STAR_IPV6_ONLY;
- }
-
- if (tor_addr_parse_mask_ports(arg, fmt_flags, &newe.addr, &newe.maskbits,
- &newe.prt_min, &newe.prt_max) < 0) {
- log_warn(LD_DIR,"Couldn't parse line %s. Dropping", escaped(arg));
- return NULL;
- }
-
- return addr_policy_get_canonical_entry(&newe);
-}
-
-/** Parse an exit policy line of the format "accept[6]/reject[6] private:...".
- * This didn't exist until Tor 0.1.1.15, so nobody should generate it in
- * router descriptors until earlier versions are obsolete.
- *
- * accept/reject and accept6/reject6 private all produce rules for both
- * IPv4 and IPv6 addresses.
- */
-static addr_policy_t *
-router_parse_addr_policy_private(directory_token_t *tok)
-{
- const char *arg;
- uint16_t port_min, port_max;
- addr_policy_t result;
-
- arg = tok->args[0];
- if (strcmpstart(arg, "private"))
- return NULL;
-
- arg += strlen("private");
- arg = (char*) eat_whitespace(arg);
- if (!arg || *arg != ':')
- return NULL;
-
- if (parse_port_range(arg+1, &port_min, &port_max)<0)
- return NULL;
-
- memset(&result, 0, sizeof(result));
- if (tok->tp == K_REJECT || tok->tp == K_REJECT6)
- result.policy_type = ADDR_POLICY_REJECT;
- else
- result.policy_type = ADDR_POLICY_ACCEPT;
- result.is_private = 1;
- result.prt_min = port_min;
- result.prt_max = port_max;
-
- if (tok->tp == K_ACCEPT6 || tok->tp == K_REJECT6) {
- log_warn(LD_GENERAL,
- "'%s' expands into rules which apply to all private IPv4 and "
- "IPv6 addresses. (Use accept/reject private:* for IPv4 and "
- "IPv6.)", tok->n_args == 1 ? tok->args[0] : "");
- }
-
- return addr_policy_get_canonical_entry(&result);
-}
-
/** Return a newly allocated smartlist of all accept or reject tokens in
* <b>s</b>.
*/
diff --git a/src/feature/dirparse/routerparse.h b/src/feature/dirparse/routerparse.h
index 72f812ee4a..3022d60d36 100644
--- a/src/feature/dirparse/routerparse.h
+++ b/src/feature/dirparse/routerparse.h
@@ -34,8 +34,6 @@ struct digest_ri_map_t;
extrainfo_t *extrainfo_parse_entry_from_string(const char *s, const char *end,
int cache_copy, struct digest_ri_map_t *routermap,
int *can_dl_again_out);
-MOCK_DECL(addr_policy_t *, router_parse_addr_policy_item_from_string,
- (const char *s, int assume_action, int *malformed_list));
int find_single_ipv6_orport(const smartlist_t *list,
tor_addr_t *addr_out,
@@ -44,6 +42,10 @@ int find_single_ipv6_orport(const smartlist_t *list,
void routerparse_init(void);
void routerparse_free_all(void);
+#ifdef EXPOSE_ROUTERDESC_TOKEN_TABLE
+extern const struct token_rule_t routerdesc_token_table[];
+#endif
+
#define ED_DESC_SIGNATURE_PREFIX "Tor router descriptor signature v1"
#endif /* !defined(TOR_ROUTERPARSE_H) */
diff --git a/src/feature/nodelist/routerset.c b/src/feature/nodelist/routerset.c
index 59d6da97b1..45863de6e0 100644
--- a/src/feature/nodelist/routerset.c
+++ b/src/feature/nodelist/routerset.c
@@ -30,7 +30,7 @@ n * Copyright (c) 2001-2004, Roger Dingledine.
#include "core/or/or.h"
#include "core/or/policies.h"
#include "feature/client/bridges.h"
-#include "feature/dirparse/routerparse.h"
+#include "feature/dirparse/policy_parse.h"
#include "feature/nodelist/nickname.h"
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerset.h"