summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarel Slany <karel.slany@nic.cz>2016-05-25 13:16:49 +0200
committerOndřej Surý <ondrej@sury.org>2016-08-11 14:06:45 +0200
commit7e4918918588b342a75133491f5e081335c7d2e0 (patch)
tree2bbb3fe9c586c62643a665dee738d47046afe29b
parentResolution fails when receiving invalid cookies. (diff)
downloadknot-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.c13
-rw-r--r--lib/rplan.h4
-rw-r--r--modules/cookies/cookies.c22
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. */