diff options
author | Karel Slany <karel.slany@nic.cz> | 2016-05-25 13:16:49 +0200 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2016-08-11 14:06:45 +0200 |
commit | 7e4918918588b342a75133491f5e081335c7d2e0 (patch) | |
tree | 2bbb3fe9c586c62643a665dee738d47046afe29b | |
parent | Resolution fails when receiving invalid cookies. (diff) | |
download | knot-resolver-7e4918918588b342a75133491f5e081335c7d2e0.tar.xz knot-resolver-7e4918918588b342a75133491f5e081335c7d2e0.zip |
Response origin address is stored in the query context.
This simplifies the response source identification on the cookie module.
-rw-r--r-- | lib/resolve.c | 13 | ||||
-rw-r--r-- | lib/rplan.h | 4 | ||||
-rw-r--r-- | modules/cookies/cookies.c | 22 |
3 files changed, 37 insertions, 2 deletions
diff --git a/lib/resolve.c b/lib/resolve.c index 189a5fe8..375edc62 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -469,6 +469,19 @@ int kr_resolve_consume(struct kr_request *request, const struct sockaddr *src, k /* Track RTT for iterative answers */ if (src && !(qry->flags & QUERY_CACHED)) { + /* Track response source. */ + switch (src->sa_family) { + case AF_INET: + qry->rsource.ip4 = *(struct sockaddr_in *) src; + break; + case AF_INET6: + qry->rsource.ip6 = *(struct sockaddr_in6 *) src; + break; + default: + qry->rsource.ip4.sin_family = AF_UNSPEC; + break; + } + /* Sucessful answer, track RTT and lift any address resolution requests. */ if (request->state != KNOT_STATE_FAIL) { /* Do not track in safe mode. */ diff --git a/lib/rplan.h b/lib/rplan.h index ed347916..4720a518 100644 --- a/lib/rplan.h +++ b/lib/rplan.h @@ -75,6 +75,10 @@ struct kr_query { struct kr_zonecut zone_cut; struct kr_nsrep ns; struct kr_layer_pickle *deferred; + union { + struct sockaddr_in ip4; + struct sockaddr_in6 ip6; + } rsource; /**< Response source address. */ }; /** @cond internal Array of queries. */ diff --git a/modules/cookies/cookies.c b/modules/cookies/cookies.c index 9d944665..2c79de0c 100644 --- a/modules/cookies/cookies.c +++ b/modules/cookies/cookies.c @@ -181,11 +181,29 @@ static int check_response(knot_layer_t *ctx, knot_pkt_t *pkt) DEBUG_MSG(NULL, "%s\n", "checking response for received cookies"); + /* Try obtaining response origin address from query context. */ const struct sockaddr *srvr_sockaddr = NULL; + if (qry->rsource.ip4.sin_family == AF_INET || + qry->rsource.ip4.sin_family == AF_INET6) { + srvr_sockaddr = (struct sockaddr *) &qry->rsource.ip4; + WITH_DEBUG { + char addr_str[INET6_ADDRSTRLEN]; + (void *) &qry->rsource.ip4.sin_addr; + (void *) &qry->rsource.ip6.sin6_addr; + inet_ntop(srvr_sockaddr->sa_family, + (srvr_sockaddr->sa_family == AF_INET) ? + (void *) &qry->rsource.ip4.sin_addr : + (void *) &qry->rsource.ip6.sin6_addr, + addr_str, sizeof(addr_str)); + DEBUG_MSG(NULL, "response address '%s' %d\n", addr_str, ret); + } + } /* Abusing name server reputation mechanism to obtain IP addresses. */ - srvr_sockaddr = guess_server_addr(cc, ns, - kr_cookies_control.current_cs); + if (!srvr_sockaddr) { + srvr_sockaddr = guess_server_addr(cc, ns, + kr_cookies_control.current_cs); + } bool returned_current = (srvr_sockaddr != NULL); if (!srvr_sockaddr && kr_cookies_control.recent_cs) { /* Try recent client secret to check obtained cookie. */ |