summaryrefslogtreecommitdiff
path: root/util/data
diff options
context:
space:
mode:
authorCy Schubert <cy@FreeBSD.org>2024-08-16 16:41:16 +0000
committerCy Schubert <cy@FreeBSD.org>2024-08-16 16:41:16 +0000
commit96ef46e5cff01648c80c09c4364d10bc6f58119d (patch)
treea759010619ad11a8eaaaed7269bb06a9dfc2fa16 /util/data
parentc2a80056864d6eda0398fd127dc0ae515b39752b (diff)
Diffstat (limited to 'util/data')
-rw-r--r--util/data/dname.h2
-rw-r--r--util/data/msgparse.c50
-rw-r--r--util/data/msgparse.h5
3 files changed, 45 insertions, 12 deletions
diff --git a/util/data/dname.h b/util/data/dname.h
index cb0f6735d924..15e28bd973bb 100644
--- a/util/data/dname.h
+++ b/util/data/dname.h
@@ -225,7 +225,7 @@ int dname_strict_subdomain(uint8_t* d1, int labs1, uint8_t* d2, int labs2);
int dname_strict_subdomain_c(uint8_t* d1, uint8_t* d2);
/**
- * Counts labels. Tests is d1 is a subdomain of d2.
+ * Counts labels. Tests if d1 is a subdomain of d2.
* @param d1: domain name, uncompressed wireformat
* @param d2: domain name, uncompressed wireformat
* @return true if d1 is a subdomain of d2.
diff --git a/util/data/msgparse.c b/util/data/msgparse.c
index d06b7bb25e6e..6963d850171e 100644
--- a/util/data/msgparse.c
+++ b/util/data/msgparse.c
@@ -947,7 +947,8 @@ parse_packet(sldns_buffer* pkt, struct msg_parse* msg, struct regional* region)
static int
parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
struct edns_data* edns, struct config_file* cfg, struct comm_point* c,
- struct comm_reply* repinfo, uint32_t now, struct regional* region)
+ struct comm_reply* repinfo, uint32_t now, struct regional* region,
+ struct cookie_secrets* cookie_secrets)
{
/* To respond with a Keepalive option, the client connection must have
* received one message with a TCP Keepalive EDNS option, and that
@@ -1070,13 +1071,24 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
&((struct sockaddr_in6*)&repinfo->remote_addr)->sin6_addr, 16);
}
- 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(cfg->cookie_secret_file &&
+ cfg->cookie_secret_file[0]) {
+ /* Loop over the active and staging cookies. */
+ cookie_val_status =
+ cookie_secrets_server_validate(
+ rdata_ptr, opt_len, cookie_secrets,
+ cookie_is_v4, server_cookie, now);
+ } else {
+ /* Use the cookie option value to 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_val_status == COOKIE_STATUS_VALID_RENEW)
+ edns->cookie_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(
@@ -1091,13 +1103,30 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
break;
case COOKIE_STATUS_CLIENT_ONLY:
edns->cookie_client = 1;
+ ATTR_FALLTHROUGH
/* fallthrough */
+ case COOKIE_STATUS_VALID_RENEW:
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(cfg->cookie_secret_file &&
+ cfg->cookie_secret_file[0]) {
+ if(!cookie_secrets)
+ break;
+ lock_basic_lock(&cookie_secrets->lock);
+ if(cookie_secrets->cookie_count < 1) {
+ lock_basic_unlock(&cookie_secrets->lock);
+ break;
+ }
+ edns_cookie_server_write(server_cookie,
+ cookie_secrets->cookie_secrets[0].cookie_secret,
+ cookie_is_v4, now);
+ lock_basic_unlock(&cookie_secrets->lock);
+ } else {
+ 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)) {
@@ -1239,7 +1268,8 @@ skip_pkt_rrs(sldns_buffer* pkt, int num)
int
parse_edns_from_query_pkt(sldns_buffer* pkt, struct edns_data* edns,
struct config_file* cfg, struct comm_point* c,
- struct comm_reply* repinfo, time_t now, struct regional* region)
+ struct comm_reply* repinfo, time_t now, struct regional* region,
+ struct cookie_secrets* cookie_secrets)
{
size_t rdata_len;
uint8_t* rdata_ptr;
@@ -1285,7 +1315,7 @@ parse_edns_from_query_pkt(sldns_buffer* pkt, struct edns_data* edns,
rdata_ptr = sldns_buffer_current(pkt);
/* ignore rrsigs */
return parse_edns_options_from_query(rdata_ptr, rdata_len, edns, cfg,
- c, repinfo, now, region);
+ c, repinfo, now, region, cookie_secrets);
}
void
diff --git a/util/data/msgparse.h b/util/data/msgparse.h
index 656e0d285dcd..aebd48efac34 100644
--- a/util/data/msgparse.h
+++ b/util/data/msgparse.h
@@ -73,6 +73,7 @@ struct edns_option;
struct config_file;
struct comm_point;
struct comm_reply;
+struct cookie_secrets;
/** number of buckets in parse rrset hash table. Must be power of 2. */
#define PARSE_TABLE_SIZE 32
@@ -322,12 +323,14 @@ int skip_pkt_rrs(struct sldns_buffer* pkt, int num);
* @param repinfo: commreply to determine the client address
* @param now: current time
* @param region: region to alloc results in (edns option contents)
+ * @param cookie_secrets: the cookie secrets for EDNS COOKIE validation.
* @return: 0 on success, or an RCODE on error.
* RCODE formerr if OPT is badly formatted and so on.
*/
int parse_edns_from_query_pkt(struct sldns_buffer* pkt, struct edns_data* edns,
struct config_file* cfg, struct comm_point* c,
- struct comm_reply* repinfo, time_t now, struct regional* region);
+ struct comm_reply* repinfo, time_t now, struct regional* region,
+ struct cookie_secrets* cookie_secrets);
/**
* Calculate hash value for rrset in packet.