1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-24 14:03:55 +01:00

Merge pull request #18329 from miri64/gcoap_dns/enh/dns-caching

gcoap_dns: Add DNS cache support
This commit is contained in:
benpicco 2022-07-21 12:39:05 +02:00 committed by GitHub
commit 1787442d6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 6 deletions

View File

@ -23,6 +23,7 @@
#include "net/credman.h"
#include "net/gcoap.h"
#include "net/af.h"
#include "net/dns/cache.h"
#include "net/ipv4/addr.h"
#include "net/ipv6/addr.h"
#include "net/sock/dns.h"
@ -52,6 +53,14 @@ typedef struct {
* initialized.
*/
coap_pkt_t *pkt;
#if IS_USED(MODULE_DNS_CACHE) || defined(DOXYGEN)
/**
* @brief The queried hostname
*
* Only required for DNS caching and thus only available with module @ref net_dns_cache
*/
const char *domain_name;
#endif
void *dns_buf; /**< The buffer for the DNS message exchange */
void *addr_out; /**< Pointer to the resulting address */
/**
@ -113,9 +122,14 @@ static ssize_t _send(const void *buf, size_t len, const sock_udp_ep_t *remote,
int gcoap_dns_query(const char *domain_name, void *addr_out, int family)
{
int res;
if ((res = dns_cache_query(domain_name, addr_out, family)) > 0) {
return res;
}
static uint8_t coap_buf[CONFIG_GCOAP_DNS_PDU_BUF_SIZE];
static uint8_t dns_buf[CONFIG_DNS_MSG_LEN];
int res;
coap_pkt_t pdu;
_req_ctx_t req_ctx = {
.resp_wait = MUTEX_INIT,
@ -598,6 +612,9 @@ static int _dns_query(const char *domain_name, _req_ctx_t *req_ctx)
domain_name,
req_ctx->family
);
#if IS_USED(MODULE_DNS_CACHE)
req_ctx->domain_name = domain_name;
#endif
#if IS_USED(MODULE_GCOAP_DTLS)
req_ctx->req_tag = _req_tag++;
#endif
@ -611,6 +628,16 @@ static int _dns_query(const char *domain_name, _req_ctx_t *req_ctx)
return res;
}
static const char *_domain_name_from_ctx(_req_ctx_t *context)
{
#if IS_USED(MODULE_DNS_CACHE)
return context->domain_name;
#else
(void)context;
return NULL;
#endif
}
static void _resp_handler(const gcoap_request_memo_t *memo, coap_pkt_t *pdu,
const sock_udp_ep_t *remote)
{
@ -710,14 +737,20 @@ static void _resp_handler(const gcoap_request_memo_t *memo, coap_pkt_t *pdu,
}
switch (coap_get_content_type(pdu)) {
case COAP_FORMAT_DNS_MESSAGE:
case COAP_FORMAT_NONE:
case COAP_FORMAT_NONE: {
uint32_t ttl;
context->res = dns_msg_parse_reply(data, data_len, family,
context->addr_out, NULL);
if ((ENABLE_DEBUG) && (context->res < 0)) {
context->addr_out, &ttl);
if (context->res > 0) {
dns_cache_add(_domain_name_from_ctx(context), context->addr_out, context->res, ttl);
}
else if (ENABLE_DEBUG && (context->res < 0)) {
DEBUG("gcoap_dns: Unable to parse DNS reply: %d\n",
context->res);
}
break;
}
default:
context->res = -ENOMSG;
break;

View File

@ -533,6 +533,19 @@ static int _resp(int argc, char **argv)
return 0;
}
static int _has_dns_cache(int argc, char **argv)
{
(void)argc;
(void)argv;
if (IS_USED(MODULE_DNS_CACHE)) {
puts("DNS cache exists");
}
else {
puts("DNS cache does not exist");
}
return 0;
}
static const coap_resource_t _resources[] = {
{ "/", COAP_FETCH, _mock_dns_server, NULL },
};
@ -553,6 +566,7 @@ static const shell_command_t _shell_commands[] = {
{ "proxy", "Sets proxy URI for DoC queries", _proxy},
{ "query", "Sends DoC query for a hostname", _query},
{ "resp", "Set static response for mock DoC server", _resp},
{ "has_dns_cache", "Check if DNS cache is activated", _has_dns_cache},
{ NULL, NULL, NULL }
};

View File

@ -18,6 +18,11 @@ from testrunner.unittest import PexpectTestCase
class TestGCoAPDNS(PexpectTestCase):
LOGFILE = sys.stdout
def has_dns_cache(self):
self.spawn.sendline("has_dns_cache")
res = self.spawn.expect(["DNS cache does not exist", "DNS cache exists"])
return bool(res)
def test_embedded_unittests(self):
self.spawn.sendline("unittests")
check_unittests(self.spawn)
@ -162,8 +167,14 @@ class TestGCoAPDNS(PexpectTestCase):
self.spawn.expect_exact(
"Hostname example.org resolves to 192.0.0.1 (IPv4)"
)
self.spawn.sendline("query example.org inet6")
self.spawn.expect_exact("Bad message")
if self.has_dns_cache():
self.spawn.sendline("query example.org inet6")
self.spawn.expect_exact(
"Hostname example.org resolves to 2001:db8::1 (IPv6)"
)
else:
self.spawn.sendline("query example.org inet6")
self.spawn.expect_exact("Bad message")
def _expect_od_dump_of(self, hexbytes):
for i in range((len(hexbytes) // 32) + 1):