mirror of
https://github.com/NLnetLabs/unbound.git
synced 2024-09-21 06:37:08 +00:00
- For #762: Introduce stat counters for downstream DNS Cookies per
thread and total: num.queries_cookie_valid, num.queries_cookie_client, num.queries.cookie_invalid.
This commit is contained in:
parent
49e4258102
commit
bab5ad623c
@ -672,6 +672,12 @@ print_stats(RES* ssl, const char* nm, struct ub_stats_info* s)
|
||||
(unsigned long)s->svr.num_queries)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.queries_ip_ratelimited"SQ"%lu\n", nm,
|
||||
(unsigned long)s->svr.num_queries_ip_ratelimited)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.queries_cookie_valid"SQ"%lu\n", nm,
|
||||
(unsigned long)s->svr.num_queries_cookie_valid)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.queries_cookie_client"SQ"%lu\n", nm,
|
||||
(unsigned long)s->svr.num_queries_cookie_client)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.queries_cookie_invalid"SQ"%lu\n", nm,
|
||||
(unsigned long)s->svr.num_queries_cookie_invalid)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.cachehits"SQ"%lu\n", nm,
|
||||
(unsigned long)(s->svr.num_queries
|
||||
- s->svr.num_queries_missed_cache))) return 0;
|
||||
|
@ -435,6 +435,9 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
|
||||
{
|
||||
total->svr.num_queries += a->svr.num_queries;
|
||||
total->svr.num_queries_ip_ratelimited += a->svr.num_queries_ip_ratelimited;
|
||||
total->svr.num_queries_cookie_valid += a->svr.num_queries_cookie_valid;
|
||||
total->svr.num_queries_cookie_client += a->svr.num_queries_cookie_client;
|
||||
total->svr.num_queries_cookie_invalid += a->svr.num_queries_cookie_invalid;
|
||||
total->svr.num_queries_missed_cache += a->svr.num_queries_missed_cache;
|
||||
total->svr.num_queries_prefetch += a->svr.num_queries_prefetch;
|
||||
total->svr.num_queries_timed_out += a->svr.num_queries_timed_out;
|
||||
@ -568,3 +571,16 @@ void server_stats_insrcode(struct ub_server_stats* stats, sldns_buffer* buf)
|
||||
stats->ans_rcode_nodata ++;
|
||||
}
|
||||
}
|
||||
|
||||
void server_stats_downstream_cookie(struct ub_server_stats* stats,
|
||||
struct edns_data* edns)
|
||||
{
|
||||
if(!(edns->edns_present && edns->cookie_present)) return;
|
||||
if(edns->cookie_valid) {
|
||||
stats->num_queries_cookie_valid++;
|
||||
} else if(edns->cookie_client) {
|
||||
stats->num_queries_cookie_client++;
|
||||
} else {
|
||||
stats->num_queries_cookie_invalid++;
|
||||
}
|
||||
}
|
||||
|
@ -126,4 +126,11 @@ void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
|
||||
*/
|
||||
void server_stats_insrcode(struct ub_server_stats* stats, struct sldns_buffer* buf);
|
||||
|
||||
/**
|
||||
* Add DNS Cookie stats for this query
|
||||
* @param stats: the stats
|
||||
* @param edns: edns record
|
||||
*/
|
||||
void server_stats_downstream_cookie(struct ub_server_stats* stats,
|
||||
struct edns_data* edns);
|
||||
#endif /* DAEMON_STATS_H */
|
||||
|
@ -1602,6 +1602,9 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
}
|
||||
}
|
||||
|
||||
/* Get stats for cookies */
|
||||
server_stats_downstream_cookie(&worker->stats, &edns);
|
||||
|
||||
/* If the IP rate limiting check was postponed, check now. */
|
||||
if(!pre_edns_ip_ratelimit) {
|
||||
/* NOTE: we always check the repinfo->client_address.
|
||||
|
@ -369,6 +369,15 @@ number of queries received by thread
|
||||
.I threadX.num.queries_ip_ratelimited
|
||||
number of queries rate limited by thread
|
||||
.TP
|
||||
.I threadX.num.queries_cookie_valid
|
||||
number of queries with a valid DNS Cookie by thread
|
||||
.TP
|
||||
.I threadX.num.queries_cookie_client
|
||||
number of queries with a client part only DNS Cookie by thread
|
||||
.TP
|
||||
.I threadX.num.queries_cookie_invalid
|
||||
number of queries with an invalid DNS Cookie by thread
|
||||
.TP
|
||||
.I threadX.num.cachehits
|
||||
number of queries that were successfully answered using a cache lookup
|
||||
.TP
|
||||
@ -446,6 +455,18 @@ buffers are full.
|
||||
.I total.num.queries
|
||||
summed over threads.
|
||||
.TP
|
||||
.I total.num.queries_ip_ratelimited
|
||||
summed over threads.
|
||||
.TP
|
||||
.I total.num.queries_cookie_valid
|
||||
summed over threads.
|
||||
.TP
|
||||
.I total.num.queries_cookie_client
|
||||
summed over threads.
|
||||
.TP
|
||||
.I total.num.queries_cookie_invalid
|
||||
summed over threads.
|
||||
.TP
|
||||
.I total.num.cachehits
|
||||
summed over threads.
|
||||
.TP
|
||||
@ -611,7 +632,7 @@ ratelimiting.
|
||||
.TP
|
||||
.I num.query.dnscrypt.shared_secret.cachemiss
|
||||
The number of dnscrypt queries that did not find a shared secret in the cache.
|
||||
The can be use to compute the shared secret hitrate.
|
||||
This can be used to compute the shared secret hitrate.
|
||||
.TP
|
||||
.I num.query.dnscrypt.replay
|
||||
The number of dnscrypt queries that found a nonce hit in the nonce cache and
|
||||
|
@ -695,6 +695,12 @@ struct ub_server_stats {
|
||||
long long num_queries;
|
||||
/** number of queries that have been dropped/ratelimited by ip. */
|
||||
long long num_queries_ip_ratelimited;
|
||||
/** number of queries with a valid DNS Cookie. */
|
||||
long long num_queries_cookie_valid;
|
||||
/** number of queries with only the client part of the DNS Cookie. */
|
||||
long long num_queries_cookie_client;
|
||||
/** number of queries with invalid DNS Cookie. */
|
||||
long long num_queries_cookie_invalid;
|
||||
/** number of queries that had a cache-miss. */
|
||||
long long num_queries_missed_cache;
|
||||
/** number of prefetch queries - cachehits with prefetch */
|
||||
|
@ -204,6 +204,12 @@ static void pr_stats(const char* nm, struct ub_stats_info* s)
|
||||
PR_UL_NM("num.queries", s->svr.num_queries);
|
||||
PR_UL_NM("num.queries_ip_ratelimited",
|
||||
s->svr.num_queries_ip_ratelimited);
|
||||
PR_UL_NM("num.queries_cookie_valid",
|
||||
s->svr.num_queries_cookie_valid);
|
||||
PR_UL_NM("num.queries_cookie_client",
|
||||
s->svr.num_queries_cookie_client);
|
||||
PR_UL_NM("num.queries_cookie_invalid",
|
||||
s->svr.num_queries_cookie_invalid);
|
||||
PR_UL_NM("num.cachehits",
|
||||
s->svr.num_queries - s->svr.num_queries_missed_cache);
|
||||
PR_UL_NM("num.cachemiss", s->svr.num_queries_missed_cache);
|
||||
|
@ -557,7 +557,7 @@ edns_cookie_invalid_version(void)
|
||||
memcpy(buf + 16, "\306\063\144\144", 4);
|
||||
unit_assert(edns_cookie_server_validate(client_cookie,
|
||||
sizeof(client_cookie), server_secret, sizeof(server_secret), 1,
|
||||
buf, timestamp) == 0);
|
||||
buf, timestamp) == COOKIE_STATUS_INVALID);
|
||||
edns_cookie_server_write(buf, server_secret, 1, timestamp);
|
||||
unit_assert(memcmp(server_cookie, buf, 24) == 0);
|
||||
}
|
||||
@ -587,7 +587,7 @@ edns_cookie_invalid_hash(void)
|
||||
memcpy(buf + 16, "\313\000\161\313", 4);
|
||||
unit_assert(edns_cookie_server_validate(client_cookie,
|
||||
sizeof(client_cookie), server_secret, sizeof(server_secret), 1,
|
||||
buf, timestamp) == 0);
|
||||
buf, timestamp) == COOKIE_STATUS_INVALID);
|
||||
edns_cookie_server_write(buf, server_secret, 1, timestamp);
|
||||
unit_assert(memcmp(server_cookie, buf, 24) == 0);
|
||||
}
|
||||
@ -620,13 +620,13 @@ edns_cookie_rfc9018_a3_better(void)
|
||||
memcpy(buf + 16, "\313\000\161\313", 4);
|
||||
unit_assert(edns_cookie_server_validate(client_cookie,
|
||||
sizeof(client_cookie), server_secret, sizeof(server_secret), 1,
|
||||
buf, timestamp) == -1);
|
||||
buf, timestamp) == COOKIE_STATUS_VALID_RENEW);
|
||||
edns_cookie_server_write(buf, server_secret, 1, timestamp);
|
||||
unit_assert(memcmp(server_cookie, buf, 24) == 0);
|
||||
}
|
||||
|
||||
/* Complete hash-valid client cookie; more than 60 minutes old; needs a
|
||||
* refreshed server cookie. */
|
||||
/* Complete hash-valid client cookie; more than 60 minutes old (expired);
|
||||
* needs a refreshed server cookie. */
|
||||
static void
|
||||
edns_cookie_rfc9018_a3(void)
|
||||
{
|
||||
@ -651,7 +651,7 @@ edns_cookie_rfc9018_a3(void)
|
||||
memcpy(buf + 16, "\313\000\161\313", 4);
|
||||
unit_assert(edns_cookie_server_validate(client_cookie,
|
||||
sizeof(client_cookie), server_secret, sizeof(server_secret), 1,
|
||||
buf, timestamp) == 0);
|
||||
buf, timestamp) == COOKIE_STATUS_EXPIRED);
|
||||
edns_cookie_server_write(buf, server_secret, 1, timestamp);
|
||||
unit_assert(memcmp(server_cookie, buf, 24) == 0);
|
||||
}
|
||||
@ -682,7 +682,7 @@ edns_cookie_rfc9018_a2(void)
|
||||
memcpy(buf + 16, "\306\063\144\144", 4);
|
||||
unit_assert(edns_cookie_server_validate(client_cookie,
|
||||
sizeof(client_cookie), server_secret, sizeof(server_secret), 1,
|
||||
buf, timestamp) == -1);
|
||||
buf, timestamp) == COOKIE_STATUS_VALID_RENEW);
|
||||
edns_cookie_server_write(buf, server_secret, 1, timestamp);
|
||||
unit_assert(memcmp(server_cookie, buf, 24) == 0);
|
||||
}
|
||||
@ -711,7 +711,7 @@ edns_cookie_rfc9018_a1(void)
|
||||
sizeof(client_cookie),
|
||||
/* these will not be used; it will return invalid
|
||||
* because of the size. */
|
||||
NULL, 0, 1, NULL, 0) == 0);
|
||||
NULL, 0, 1, NULL, 0) == COOKIE_STATUS_CLIENT_ONLY);
|
||||
edns_cookie_server_write(buf, server_secret, 1, timestamp);
|
||||
unit_assert(memcmp(server_cookie, buf, 24) == 0);
|
||||
}
|
||||
|
1
testdata/stat_values.tdir/stat_values.pre
vendored
1
testdata/stat_values.tdir/stat_values.pre
vendored
@ -37,6 +37,7 @@ echo "FWD_EXPIRED_PID=$FWD_EXPIRED_PID" >> .tpkg.var.test
|
||||
# make config file
|
||||
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@EXPIREDPORT\@/'$FWD_EXPIRED_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < stat_values.conf > ub.conf
|
||||
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@EXPIREDPORT\@/'$FWD_EXPIRED_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < stat_values_cachedb.conf > ub_cachedb.conf
|
||||
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < stat_values_downstream_cookies.conf > ub_downstream_cookies.conf
|
||||
# start unbound in the background
|
||||
$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
|
||||
UNBOUND_PID=$!
|
||||
|
91
testdata/stat_values.tdir/stat_values.test
vendored
91
testdata/stat_values.tdir/stat_values.test
vendored
@ -414,6 +414,97 @@ rrset.cache.count=3
|
||||
infra.cache.count=2"
|
||||
|
||||
|
||||
# Bring the downstream DNS Cookies configured Unbound up
|
||||
kill_pid $UNBOUND_PID # kill current Unbound
|
||||
$PRE/unbound -d -c ub_downstream_cookies.conf >unbound.log 2>&1 &
|
||||
UNBOUND_PID=$!
|
||||
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
|
||||
wait_unbound_up unbound.log
|
||||
|
||||
echo
|
||||
echo "[ Get a DNS Cookie. ]"
|
||||
echo "> dig www.local.zone +tcp +ednsopt=10:0102030405060708"
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT +tcp +ednsopt=10:0102030405060708 +retry=0 +time=1 www.local.zone. | tee outfile
|
||||
echo "> check answer"
|
||||
if grep "192.0.2.1" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
end 1
|
||||
fi
|
||||
# Save valid cookie
|
||||
valid_cookie=`grep "COOKIE: " outfile | cut -d ' ' -f 3`
|
||||
invalid_cookie=`echo $valid_cookie | tr '0' '4'`
|
||||
check_stats "\
|
||||
total.num.queries=1
|
||||
total.num.queries_cookie_client=1
|
||||
total.num.cachehits=1
|
||||
num.query.type.A=1
|
||||
num.query.class.IN=1
|
||||
num.query.opcode.QUERY=1
|
||||
num.query.flags.RD=1
|
||||
num.query.flags.AD=1
|
||||
num.query.edns.present=1
|
||||
num.query.tcp=1
|
||||
num.answer.rcode.NOERROR=1"
|
||||
|
||||
echo
|
||||
echo "[ Present the valid DNS Cookie. ]"
|
||||
echo "> dig www.local.zone +ednsopt=10:valid_cookie"
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT +ednsopt=10:$valid_cookie +retry=0 +time=1 www.local.zone. | tee outfile
|
||||
echo "> check answer"
|
||||
if grep "192.0.2.1" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
end 1
|
||||
fi
|
||||
check_stats "\
|
||||
total.num.queries=1
|
||||
total.num.queries_cookie_valid=1
|
||||
total.num.cachehits=1
|
||||
num.query.type.A=1
|
||||
num.query.class.IN=1
|
||||
num.query.opcode.QUERY=1
|
||||
num.query.flags.RD=1
|
||||
num.query.flags.AD=1
|
||||
num.query.edns.present=1
|
||||
num.answer.rcode.NOERROR=1"
|
||||
|
||||
echo
|
||||
echo "[ Present an invalid DNS Cookie. ]"
|
||||
echo "> dig www.local.zone +ednsopt=10:invalid_cookie"
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT +ednsopt=10:$invalid_cookie +retry=0 +time=1 www.local.zone. | tee outfile
|
||||
echo "> check answer"
|
||||
if grep "192.0.2.1" outfile; then
|
||||
end 1
|
||||
else
|
||||
echo "OK"
|
||||
fi
|
||||
# A lot of stats are missing since BADCOOKIE error response is before
|
||||
# those stat calculations.
|
||||
# BADCOOKIE is an extended error code; we record YXRRSET below.
|
||||
check_stats "\
|
||||
total.num.queries=1
|
||||
total.num.queries_cookie_invalid=1
|
||||
total.num.cachehits=1
|
||||
num.answer.rcode.YXRRSET=1"
|
||||
|
||||
echo
|
||||
echo "[ Present no DNS Cookie. ]"
|
||||
echo "> dig www.local.zone +ignore"
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT +ignore +retry=0 +time=1 www.local.zone. | tee outfile
|
||||
echo "> check answer"
|
||||
if grep "192.0.2.1" outfile; then
|
||||
end 1
|
||||
else
|
||||
echo "OK"
|
||||
fi
|
||||
# A lot of stats are missing since REFUSED error response because of no DNS
|
||||
# Cookie is before those stat calculations.
|
||||
check_stats "\
|
||||
total.num.queries=1
|
||||
total.num.cachehits=1
|
||||
num.answer.rcode.REFUSED=1"
|
||||
|
||||
if test x$USE_CACHEDB = "x1"; then
|
||||
|
||||
# Bring the cachedb configured Unbound up
|
||||
|
32
testdata/stat_values.tdir/stat_values_downstream_cookies.conf
vendored
Normal file
32
testdata/stat_values.tdir/stat_values_downstream_cookies.conf
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
server:
|
||||
verbosity: 5
|
||||
module-config: "iterator"
|
||||
num-threads: 1
|
||||
interface: 127.0.0.1
|
||||
port: @PORT@
|
||||
use-syslog: no
|
||||
directory: ""
|
||||
pidfile: "unbound.pid"
|
||||
chroot: ""
|
||||
username: ""
|
||||
extended-statistics: yes
|
||||
identity: "stat_values"
|
||||
outbound-msg-retry: 0
|
||||
root-key-sentinel: no
|
||||
trust-anchor-signaling: no
|
||||
|
||||
local-zone: local.zone static
|
||||
local-data: "www.local.zone A 192.0.2.1"
|
||||
|
||||
answer-cookie: yes
|
||||
access-control: 127.0.0.1 allow_cookie
|
||||
|
||||
remote-control:
|
||||
control-enable: yes
|
||||
control-interface: 127.0.0.1
|
||||
# control-interface: ::1
|
||||
control-port: @CONTROL_PORT@
|
||||
server-key-file: "unbound_server.key"
|
||||
server-cert-file: "unbound_server.pem"
|
||||
control-key-file: "unbound_control.key"
|
||||
control-cert-file: "unbound_control.pem"
|
@ -971,7 +971,7 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
||||
uint16_t opt_code = sldns_read_uint16(rdata_ptr);
|
||||
uint16_t opt_len = sldns_read_uint16(rdata_ptr+2);
|
||||
uint8_t server_cookie[40];
|
||||
int cookie_is_valid;
|
||||
enum edns_cookie_val_status cookie_val_status;
|
||||
int cookie_is_v4 = 1;
|
||||
|
||||
rdata_ptr += 4;
|
||||
@ -1064,12 +1064,14 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
||||
&((struct sockaddr_in6*)&repinfo->remote_addr)->sin6_addr, 16);
|
||||
}
|
||||
|
||||
cookie_is_valid = edns_cookie_server_validate(
|
||||
cookie_val_status = edns_cookie_server_validate(
|
||||
rdata_ptr, opt_len, cfg->cookie_secret,
|
||||
cfg->cookie_secret_len, cookie_is_v4,
|
||||
server_cookie, now);
|
||||
if(cookie_is_valid != 0) edns->cookie_valid = 1;
|
||||
if(cookie_is_valid == 1) {
|
||||
switch(cookie_val_status) {
|
||||
case COOKIE_STATUS_VALID:
|
||||
case COOKIE_STATUS_VALID_RENEW:
|
||||
edns->cookie_valid = 1;
|
||||
/* Reuse cookie */
|
||||
if(!edns_opt_list_append(
|
||||
&edns->opt_list_out, LDNS_EDNS_COOKIE,
|
||||
@ -1081,13 +1083,22 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
||||
* options. Done!
|
||||
*/
|
||||
break;
|
||||
}
|
||||
edns_cookie_server_write(server_cookie,
|
||||
cfg->cookie_secret, cookie_is_v4, now);
|
||||
if(!edns_opt_list_append(&edns->opt_list_out,
|
||||
LDNS_EDNS_COOKIE, 24, server_cookie, region)) {
|
||||
log_err("out of memory");
|
||||
return LDNS_RCODE_SERVFAIL;
|
||||
case COOKIE_STATUS_CLIENT_ONLY:
|
||||
edns->cookie_client = 1;
|
||||
/* fallthrough */
|
||||
case COOKIE_STATUS_FUTURE:
|
||||
case COOKIE_STATUS_EXPIRED:
|
||||
case COOKIE_STATUS_INVALID:
|
||||
default:
|
||||
edns_cookie_server_write(server_cookie,
|
||||
cfg->cookie_secret, cookie_is_v4, now);
|
||||
if(!edns_opt_list_append(&edns->opt_list_out,
|
||||
LDNS_EDNS_COOKIE, 24, server_cookie,
|
||||
region)) {
|
||||
log_err("out of memory");
|
||||
return LDNS_RCODE_SERVFAIL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -243,6 +243,8 @@ struct edns_data {
|
||||
unsigned int cookie_present : 1;
|
||||
/** if the cookie validated */
|
||||
unsigned int cookie_valid : 1;
|
||||
/** if the cookie holds only the client part */
|
||||
unsigned int cookie_client : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
|
22
util/edns.c
22
util/edns.c
@ -153,7 +153,7 @@ edns_cookie_server_write(uint8_t* buf, const uint8_t* secret, int v4,
|
||||
memcpy(buf + 16, hash, 8);
|
||||
}
|
||||
|
||||
int
|
||||
enum edns_cookie_val_status
|
||||
edns_cookie_server_validate(const uint8_t* cookie, size_t cookie_len,
|
||||
const uint8_t* secret, size_t secret_len, int v4,
|
||||
const uint8_t* hash_input, uint32_t now)
|
||||
@ -162,26 +162,28 @@ edns_cookie_server_validate(const uint8_t* cookie, size_t cookie_len,
|
||||
uint32_t timestamp;
|
||||
uint32_t subt_1982 = 0; /* Initialize for the compiler; unused value */
|
||||
int comp_1982;
|
||||
if(cookie_len != 24 || /* RFC9018 cookies are 24 bytes long */
|
||||
secret_len != 16 || /* RFC9018 cookies have 16 byte secrets */
|
||||
cookie[8] != 1) /* RFC9018 cookies are cookie version 1 */
|
||||
return 0;
|
||||
if(cookie_len != 24)
|
||||
/* RFC9018 cookies are 24 bytes long */
|
||||
return COOKIE_STATUS_CLIENT_ONLY;
|
||||
if(secret_len != 16 || /* RFC9018 cookies have 16 byte secrets */
|
||||
cookie[8] != 1) /* RFC9018 cookies are cookie version 1 */
|
||||
return COOKIE_STATUS_INVALID;
|
||||
timestamp = sldns_read_uint32(cookie + 12);
|
||||
if((comp_1982 = compare_1982(now, timestamp)) > 0
|
||||
&& (subt_1982 = subtract_1982(timestamp, now)) > 3600)
|
||||
/* Cookie is older than 1 hour (see RFC9018 Section 4.3.) */
|
||||
return 0;
|
||||
return COOKIE_STATUS_EXPIRED;
|
||||
if(comp_1982 <= 0 && subtract_1982(now, timestamp) > 300)
|
||||
/* Cookie time is more than 5 minutes in the future.
|
||||
* (see RFC9018 Section 4.3.) */
|
||||
return 0;
|
||||
return COOKIE_STATUS_FUTURE;
|
||||
if(memcmp(edns_cookie_server_hash(hash_input, secret, v4, hash),
|
||||
cookie + 16, 8) != 0)
|
||||
/* Hashes do not match */
|
||||
return 0;
|
||||
return COOKIE_STATUS_INVALID;
|
||||
if(comp_1982 > 0 && subt_1982 > 1800)
|
||||
/* Valid cookie but older than 30 minutes, so create a new one
|
||||
* anyway */
|
||||
return -1;
|
||||
return 1;
|
||||
return COOKIE_STATUS_VALID_RENEW;
|
||||
return COOKIE_STATUS_VALID;
|
||||
}
|
||||
|
16
util/edns.h
16
util/edns.h
@ -75,6 +75,15 @@ struct edns_string_addr {
|
||||
size_t string_len;
|
||||
};
|
||||
|
||||
enum edns_cookie_val_status {
|
||||
COOKIE_STATUS_CLIENT_ONLY = -3,
|
||||
COOKIE_STATUS_FUTURE = -2,
|
||||
COOKIE_STATUS_EXPIRED = -1,
|
||||
COOKIE_STATUS_INVALID = 0,
|
||||
COOKIE_STATUS_VALID = 1,
|
||||
COOKIE_STATUS_VALID_RENEW = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* Create structure to hold EDNS strings
|
||||
* @return: newly created edns_strings, NULL on alloc failure.
|
||||
@ -149,10 +158,11 @@ void edns_cookie_server_write(uint8_t* buf, const uint8_t* secret, int v4,
|
||||
* @param hash_input: pointer to the hash input for validation. It needs to be:
|
||||
* Client Cookie | Version | Reserved | Timestamp | Client-IP
|
||||
* @param now: the current time.
|
||||
* return 1 if valid, -1 if valid but a new one SHOULD be generated, else 0.
|
||||
* return edns_cookie_val_status with the cookie validation status i.e.,
|
||||
* <=0 for invalid, else valid.
|
||||
*/
|
||||
int edns_cookie_server_validate(const uint8_t* cookie, size_t cookie_len,
|
||||
const uint8_t* secret, size_t secret_len, int v4,
|
||||
enum edns_cookie_val_status edns_cookie_server_validate(const uint8_t* cookie,
|
||||
size_t cookie_len, const uint8_t* secret, size_t secret_len, int v4,
|
||||
const uint8_t* hash_input, uint32_t now);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user