Skip to content

Commit

Permalink
EDNS(0) Client Subnet
Browse files Browse the repository at this point in the history
- Add indexer `edns_ecs_subnet`
  • Loading branch information
jelu committed Jul 5, 2023
1 parent f6dab4a commit a666c04
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/dns_message.c
Expand Up @@ -120,6 +120,7 @@ static indexer indexers[] = {
{ "edns_ecs_source_prefix", indexer_want_edns_options, edns_ecs_source_prefix_indexer, edns_ecs_source_prefix_iterator, edns_ecs_source_prefix_reset },
{ "edns_ecs_scope_prefix", indexer_want_edns_options, edns_ecs_scope_prefix_indexer, edns_ecs_scope_prefix_iterator, edns_ecs_scope_prefix_reset },
{ "edns_ecs_address", indexer_want_edns_options, edns_ecs_address_indexer, edns_ecs_address_iterator, edns_ecs_address_reset },
{ "edns_ecs_subnet", indexer_want_edns_options, edns_ecs_subnet_indexer, edns_ecs_subnet_iterator, edns_ecs_subnet_reset },
{ "edns_ede", indexer_want_edns_options, edns_ede_indexer, edns_ede_iterator },
{ "edns_ede_code", indexer_want_edns_options, edns_ede_code_indexer, edns_ede_code_iterator, edns_ede_code_reset },
{ "edns_ede_textlen", indexer_want_edns_options, edns_ede_textlen_indexer, edns_ede_textlen_iterator, edns_ede_textlen_reset },
Expand Down
3 changes: 3 additions & 0 deletions src/dsc.conf.5.in
Expand Up @@ -538,6 +538,9 @@ The EDNS(0) Client Subnet scope prefix-length.
\fBedns_ecs_address\fR
The EDNS(0) Client Subnet address bytes as a hexadecimal string.
.TP
\fBedns_ecs_subnet\fR
The EDNS(0) Client Subnet address as an IPv4/IPv6 textual address.
.TP
\fBedns_ede\fR
Indicates whether or not a EDNS(0) Extended DNS Errors (RFC8914) was present with "yes" or "no".
.TP
Expand Down
91 changes: 91 additions & 0 deletions src/edns_ecs_index.c
Expand Up @@ -39,8 +39,10 @@
#include "edns_ecs_index.h"
#include "xmalloc.h"
#include "hashtbl.h"
#include "inX_addr.h"

#include <string.h>
#include <sys/socket.h> // For AF_ on BSDs

// edns_ecs

Expand Down Expand Up @@ -289,3 +291,92 @@ void edns_ecs_address_reset()
addressHash = NULL;
address_next_idx = 0;
}

// edns_ecs_subnet

static hashtbl* subnetHash = NULL;
static int subnet_next_idx = 0;

typedef struct
{
inX_addr addr;
int index;
} subnetobj;

static unsigned int
subnet_hashfunc(const void* key)
{
return inXaddr_hash((const inX_addr*)key);
}

static int
subnet_cmpfunc(const void* a, const void* b)
{
return inXaddr_cmp((const inX_addr*)a, (const inX_addr*)b);
}

int edns_ecs_subnet_indexer(const dns_message* m)
{
subnetobj* obj;
inX_addr addr = { 0 };

if (m->malformed || !m->edns.ecs.address)
return -1;
switch (m->edns.ecs.family) { // IANA Address Family Numbers
case 1:
if (m->edns.ecs.len > sizeof(addr.in4))
return -1;
addr.family = AF_INET;
memcpy(&addr.in4, m->edns.ecs.address, m->edns.ecs.len);
break;
case 2:
if (m->edns.ecs.len > sizeof(addr.in6))
return -1;
addr.family = AF_INET6;
memcpy(&addr.in6, m->edns.ecs.address, m->edns.ecs.len);
break;
default:
return -1;
}
if (NULL == subnetHash) {
subnetHash = hash_create(MAX_ARRAY_SZ, subnet_hashfunc, subnet_cmpfunc, 1, NULL, afree);
if (NULL == subnetHash)
return -1;
}
if ((obj = hash_find(&addr, subnetHash)))
return obj->index;
obj = acalloc(1, sizeof(*obj));
if (NULL == obj)
return -1;
obj->addr = addr;
obj->index = subnet_next_idx;
if (0 != hash_add(&obj->addr, obj, subnetHash)) {
afree(obj);
return -1;
}
subnet_next_idx++;
return obj->index;
}

int edns_ecs_subnet_iterator(const char** label)
{
subnetobj* obj;
static char label_buf[128];
if (0 == subnet_next_idx)
return -1;
if (NULL == label) {
hash_iter_init(subnetHash);
return subnet_next_idx;
}
if ((obj = hash_iterate(subnetHash)) == NULL)
return -1;
inXaddr_ntop(&obj->addr, label_buf, 128);
*label = label_buf;
return obj->index;
}

void edns_ecs_subnet_reset()
{
subnetHash = NULL;
subnet_next_idx = 0;
}
4 changes: 4 additions & 0 deletions src/edns_ecs_index.h
Expand Up @@ -58,4 +58,8 @@ int edns_ecs_address_indexer(const dns_message*);
int edns_ecs_address_iterator(const char** label);
void edns_ecs_address_reset(void);

int edns_ecs_subnet_indexer(const dns_message*);
int edns_ecs_subnet_iterator(const char** label);
void edns_ecs_subnet_reset(void);

#endif /* __dsc_edns_ecs_index_h */
1 change: 1 addition & 0 deletions src/test/test_291.conf
Expand Up @@ -16,6 +16,7 @@ dataset edns_ecs_family dns All:null edns_ecs_family:edns_ecs_family edns0-only;
dataset edns_ecs_source_prefix dns All:null edns_ecs_source_prefix:edns_ecs_source_prefix edns0-only;
dataset edns_ecs_scope_prefix dns All:null edns_ecs_scope_prefix:edns_ecs_scope_prefix edns0-only;
dataset edns_ecs_address dns All:null edns_ecs_address:edns_ecs_address edns0-only;
dataset edns_ecs_subnet dns All:null edns_ecs_subnet:edns_ecs_subnet edns0-only;
dataset edns_ede dns All:null edns_ede:edns_ede;
dataset edns_ede_code dns All:null edns_ede_code:edns_ede_code edns0-only;
dataset edns_ede_textlen dns All:null edns_ede_textlen:edns_ede_textlen edns0-only;
Expand Down
9 changes: 9 additions & 0 deletions src/test/test_291.xml_gold
Expand Up @@ -47,6 +47,15 @@
</All>
</data>
</array>
<array name="edns_ecs_subnet" dimensions="2" start_time="1688541698" stop_time="1688541706">
<dimension number="1" type="All"/>
<dimension number="2" type="edns_ecs_subnet"/>
<data>
<All val="ALL">
<edns_ecs_subnet val="172.17.0.0" count="2"/>
</All>
</data>
</array>
<array name="edns_ecs_address" dimensions="2" start_time="1688541698" stop_time="1688541706">
<dimension number="1" type="All"/>
<dimension number="2" type="edns_ecs_address"/>
Expand Down

0 comments on commit a666c04

Please sign in to comment.