From: Matt Rogers Date: Thu, 25 Aug 2016 16:57:09 +0000 (-0400) Subject: Support multiple URI answers X-Git-Tag: resolv_wrapper-1.1.5~2 X-Git-Url: http://git.samba.org/?p=resolv_wrapper.git;a=commitdiff_plain;h=cc7e8b01f88d68c30c84ea9045f8a123f6f30720 Support multiple URI answers Add URI record use of recursion to rwrap_get_record(), for collecting multiple URI answers under a single query. Increase the RWRAP_MAX_RECURSION limit to handle more URI records. Signed-off-by: Matt Rogers Reviewed-by: Andreas Schneider Reviewed-by: Michael Adam --- diff --git a/src/resolv_wrapper.c b/src/resolv_wrapper.c index 7a3c9b7..c6f06e3 100644 --- a/src/resolv_wrapper.c +++ b/src/resolv_wrapper.c @@ -151,7 +151,7 @@ static void rwrap_log(enum rwrap_dbglvl_e dbglvl, } \ } while(0); -#define RWRAP_MAX_RECURSION 5 +#define RWRAP_MAX_RECURSION 64 /* Priority and weight can be omitted from the hosts file, but need to be part * of the output @@ -786,6 +786,19 @@ static int rwrap_get_record(const char *hostfile, unsigned recursion, const char *query, int type, struct rwrap_fake_rr *rr); +static int rwrap_uri_recurse(const char *hostfile, unsigned recursion, + const char *query, struct rwrap_fake_rr *rr) +{ + int rc; + + rc = rwrap_get_record(hostfile, recursion, query, ns_t_uri, rr); + if (rc == ENOENT) { + rc = 0; + } + + return rc; +} + static int rwrap_srv_recurse(const char *hostfile, unsigned recursion, const char *query, struct rwrap_fake_rr *rr) { @@ -826,6 +839,7 @@ static int rwrap_get_record(const char *hostfile, unsigned recursion, char *key = NULL; char *value = NULL; int rc = ENOENT; + unsigned num_uris = 0; if (recursion >= RWRAP_MAX_RECURSION) { RWRAP_LOG(RWRAP_LOG_ERROR, "Recursed too deep!\n"); @@ -867,6 +881,18 @@ static int rwrap_get_record(const char *hostfile, unsigned recursion, } q[0] = '\0'; + if (type == ns_t_uri && recursion > 0) { + /* Skip non-URI records. */ + if (!TYPE_MATCH(type, ns_t_uri, rec_type, "URI", key, query)) { + continue; + } + /* Skip previous records based on the recurse depth. */ + num_uris++; + if (num_uris <= recursion) { + continue; + } + } + if (TYPE_MATCH(type, ns_t_a, rec_type, "A", key, query)) { rc = rwrap_create_fake_a_rr(key, value, rr); break; @@ -890,6 +916,10 @@ static int rwrap_get_record(const char *hostfile, unsigned recursion, } else if (TYPE_MATCH(type, ns_t_uri, rec_type, "URI", key, query)) { rc = rwrap_create_fake_uri_rr(key, value, rr); + if (rc == 0) { + /* Recurse to collect multiple URI answers under a single key. */ + rc = rwrap_uri_recurse(hostfile, recursion + 1, key, rr + 1); + } break; } else if (TYPE_MATCH(type, ns_t_soa, rec_type, "SOA", key, query)) { @@ -977,6 +1007,17 @@ static int rwrap_ancount(struct rwrap_fake_rr *rrs, int qtype) int i; int ancount = 0; + /* For URI return the number of URIs. */ + if (qtype == ns_t_uri) { + for (i = 0; i < RWRAP_MAX_RECURSION; i++) { + if (rwrap_known_type(rrs[i].type) && + rrs[i].type == qtype) { + ancount++; + } + } + return ancount; + } + /* Include all RRs in the stack until the sought type * in the answer section. This is the case i.e. when looking * up an A record but the name points to a CNAME