feat(dns): Add ESP DNS module with support for UDP, TCP, DoT, and DoH protocols

This commit introduces a custom DNS module for ESP32, enabling DNS resolution capabilities
over various protocols including UDP, TCP, DNS over TLS (DoT), and DNS over HTTPS (DoH).
The module includes initialization and cleanup functionalities, along with
protocol-specific implementations for each DNS type.
This commit is contained in:
Abhik Roy
2025-03-14 21:50:53 +11:00
parent 03dd8006b2
commit 57cd60807e
27 changed files with 2794 additions and 2 deletions

View File

@@ -0,0 +1,8 @@
# For more information about build system see
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(esp_dns_example)

View File

@@ -0,0 +1,152 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
# ESP DNS Example
This example demonstrates how to use the ESP DNS component in an ESP32 application. The example resolves domain names using various DNS protocols including standard UDP, TCP, DNS over TLS (DoT), and DNS over HTTPS (DoH).
## Features
- **Standard UDP DNS**: Traditional DNS resolution over UDP
- **DNS over TCP**: DNS resolution using TCP transport
- **DNS over TLS (DoT)**: Secure DNS resolution using TLS encryption
- **DNS over HTTPS (DoH)**: Secure DNS resolution using HTTPS
## Certificate Options
This example provides two certificate options for secure DNS protocols (DoT and DoH):
1. **Certificate Bundle (Default)**: Uses the ESP-IDF certificate bundle, making it easy to get started with popular DNS providers like Google.
2. **Custom Certificate**: Uses a specific certificate for the DNS server. The example includes a Google DNS certificate.
## How It Works
1. **Network Initialization**: The application initializes the network interfaces (Wi-Fi or Ethernet) and establishes a connection.
2. **DNS Resolution Tests**: The example performs DNS resolution using different protocols:
- Native UDP DNS (system default)
- ESP DNS with UDP protocol
- ESP DNS with TCP protocol
- ESP DNS with DoT protocol (using server certificate)
- ESP DNS with DoT protocol (using certificate bundle)
- ESP DNS with DoH protocol (using server certificate)
- ESP DNS with DoH protocol (using certificate bundle)
3. **Domain Resolution**: For each protocol, the application resolves several domain names including:
- yahoo.com
- www.google.com
- IP addresses (0.0.0.0 and IPv6 address)
## How to use example
Before project configuration and build, be sure to set the correct chip target using `idf.py set-target <chip_name>`.
### Hardware Required
* A development board with ESP32/ESP32-S2/ESP32-C3 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.)
* A USB cable for power supply and programming
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
idf.py -p PORT flash monitor
(Replace PORT with the name of the serial port to use.)
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
## Troubleshooting Tips
* **Connectivity**:
Ensure that the network connection details are accurate. For example, verify the Wi-Fi SSID and password or check that the Ethernet connection is secure and not faulty.
* **Memory Issues**:
If you encounter memory-related errors, check the system information output which displays free heap and stack high water mark. You may need to increase task stack sizes for more complex DNS operations.
* **Certificate Issues**:
For DoT and DoH protocols, ensure that the certificates are valid for the DNS server you're using. The example includes Google DNS certificates, but these may need to be updated if they expire.
## Example Output
```
I (4583) example_esp_dns: Executing DNS without initializing ESP_DNS module
I (4603) wifi:<ba-add>idx:1 (ifx:0, a0:36:bc:0e:c4:f0), tid:7, ssn:3, winSize:64
I (4613) example_esp_dns: Hostname: yahoo.com: 98.137.11.163(IPv4)
I (4613) example_esp_dns: Hostname: yahoo.com: 74.6.143.26(IPv4)
I (4613) example_esp_dns: Hostname: yahoo.com: 74.6.231.20(IPv4)
I (4613) wifi:<ba-del>idx:0, tid:6
I (4623) example_esp_dns: Hostname: yahoo.com: 74.6.231.21(IPv4)
I (4623) wifi:<ba-add>idx:0 (ifx:0, a0:36:bc:0e:c4:f0), tid:0, ssn:1, winSize:64
I (4643) example_esp_dns: Hostname: www.google.com: 2404:6800:4015:803::2004(IPv6)
I (4643) example_esp_dns: Hostname: 0.0.0.0: 0.0.0.0(IPv4)
I (4643) example_esp_dns: Hostname: fe80:0000:0000:0000:5abf:25ff:fee0:4100: FE80::5ABF:25FF:FEE0:4100(IPv6)
I (4653) example_esp_dns: Free Heap: 215292 bytes, Min Free Heap: 206008 bytes, Stack High Water Mark: 1220 bytes
I (4663) example_esp_dns: Executing UDP DNS
I (4673) example_esp_dns: Hostname: yahoo.com: 98.137.11.163(IPv4)
I (4673) example_esp_dns: Hostname: yahoo.com: 74.6.143.26(IPv4)
I (4683) example_esp_dns: Hostname: yahoo.com: 74.6.231.20(IPv4)
I (4683) example_esp_dns: Hostname: yahoo.com: 74.6.231.21(IPv4)
I (4693) example_esp_dns: Hostname: www.google.com: 2404:6800:4015:803::2004(IPv6)
I (4703) example_esp_dns: Hostname: 0.0.0.0: 0.0.0.0(IPv4)
I (4703) example_esp_dns: Hostname: fe80:0000:0000:0000:5abf:25ff:fee0:4100: FE80::5ABF:25FF:FEE0:4100(IPv6)
I (4713) example_esp_dns: Free Heap: 215116 bytes, Min Free Heap: 206008 bytes, Stack High Water Mark: 1220 bytes
I (4723) example_esp_dns: Executing TCP DNS
I (4763) example_esp_dns: Hostname: yahoo.com: 98.137.11.163(IPv4)
I (4763) example_esp_dns: Hostname: yahoo.com: 74.6.143.26(IPv4)
I (4763) example_esp_dns: Hostname: yahoo.com: 98.137.11.164(IPv4)
I (4763) example_esp_dns: Hostname: yahoo.com: 74.6.231.21(IPv4)
I (4793) example_esp_dns: Hostname: www.google.com: 2404:6800:4015:803::2004(IPv6)
I (4793) example_esp_dns: Hostname: 0.0.0.0: 0.0.0.0(IPv4)
I (4793) example_esp_dns: Hostname: fe80:0000:0000:0000:5abf:25ff:fee0:4100: FE80::5ABF:25FF:FEE0:4100(IPv6)
I (4803) example_esp_dns: Free Heap: 214580 bytes, Min Free Heap: 206008 bytes, Stack High Water Mark: 1220 bytes
I (4813) example_esp_dns: Executing DNS over TLS
I (5963) example_esp_dns: Hostname: yahoo.com: 74.6.143.25(IPv4)
I (5963) example_esp_dns: Hostname: yahoo.com: 98.137.11.163(IPv4)
I (5963) example_esp_dns: Hostname: yahoo.com: 74.6.231.21(IPv4)
I (5973) example_esp_dns: Hostname: yahoo.com: 74.6.231.20(IPv4)
I (7083) example_esp_dns: Hostname: www.google.com: 2404:6800:4015:803::2004(IPv6)
I (7083) example_esp_dns: Hostname: 0.0.0.0: 0.0.0.0(IPv4)
I (7083) example_esp_dns: Hostname: fe80:0000:0000:0000:5abf:25ff:fee0:4100: FE80::5ABF:25FF:FEE0:4100(IPv6)
I (7093) example_esp_dns: Free Heap: 213504 bytes, Min Free Heap: 165308 bytes, Stack High Water Mark: 1220 bytes
I (7103) example_esp_dns: Executing DNS over TLS
I (7413) esp-x509-crt-bundle: Certificate validated
I (8233) example_esp_dns: Hostname: yahoo.com: 98.137.11.164(IPv4)
I (8233) example_esp_dns: Hostname: yahoo.com: 74.6.231.21(IPv4)
I (8233) example_esp_dns: Hostname: yahoo.com: 98.137.11.163(IPv4)
I (8243) example_esp_dns: Hostname: yahoo.com: 74.6.231.20(IPv4)
I (8553) esp-x509-crt-bundle: Certificate validated
I (9363) example_esp_dns: Hostname: www.google.com: 2404:6800:4015:803::2004(IPv6)
I (9363) example_esp_dns: Hostname: 0.0.0.0: 0.0.0.0(IPv4)
I (9363) example_esp_dns: Hostname: fe80:0000:0000:0000:5abf:25ff:fee0:4100: FE80::5ABF:25FF:FEE0:4100(IPv6)
I (9373) example_esp_dns: Free Heap: 213120 bytes, Min Free Heap: 165308 bytes, Stack High Water Mark: 1220 bytes
I (9383) example_esp_dns: Executing DNS over HTTPS
I (10563) example_esp_dns: Hostname: yahoo.com: 74.6.143.26(IPv4)
I (10563) example_esp_dns: Hostname: yahoo.com: 74.6.231.20(IPv4)
I (10563) example_esp_dns: Hostname: yahoo.com: 74.6.143.25(IPv4)
I (10573) example_esp_dns: Hostname: yahoo.com: 74.6.231.21(IPv4)
I (11713) example_esp_dns: Hostname: www.google.com: 2404:6800:4015:803::2004(IPv6)
I (11713) example_esp_dns: Hostname: 0.0.0.0: 0.0.0.0(IPv4)
I (11723) example_esp_dns: Hostname: fe80:0000:0000:0000:5abf:25ff:fee0:4100: FE80::5ABF:25FF:FEE0:4100(IPv6)
I (11723) example_esp_dns: Free Heap: 212664 bytes, Min Free Heap: 162780 bytes, Stack High Water Mark: 1220 bytes
I (11733) example_esp_dns: Executing DNS over HTTPS
I (12033) esp-x509-crt-bundle: Certificate validated
I (12863) example_esp_dns: Hostname: yahoo.com: 74.6.231.21(IPv4)
I (12863) example_esp_dns: Hostname: yahoo.com: 98.137.11.163(IPv4)
I (12863) example_esp_dns: Hostname: yahoo.com: 98.137.11.164(IPv4)
I (12873) example_esp_dns: Hostname: yahoo.com: 74.6.143.25(IPv4)
I (13153) esp-x509-crt-bundle: Certificate validated
I (13993) example_esp_dns: Hostname: www.google.com: 2404:6800:4015:803::2004(IPv6)
I (13993) example_esp_dns: Hostname: 0.0.0.0: 0.0.0.0(IPv4)
I (13993) example_esp_dns: Hostname: fe80:0000:0000:0000:5abf:25ff:fee0:4100: FE80::5ABF:25FF:FEE0:4100(IPv6)
I (14003) example_esp_dns: Free Heap: 212044 bytes, Min Free Heap: 162780 bytes, Stack High Water Mark: 1220 bytes
I (14013) main_task: Returned from app_main()
```

View File

@@ -0,0 +1,3 @@
idf_component_register(SRCS "esp_dns_example.c"
INCLUDE_DIRS "."
EMBED_TXTFILES "cert_google_root.pem")

View File

@@ -0,0 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw
CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA
A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo
27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w
Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw
TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl
qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH
szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8
Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk
MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92
wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p
aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN
VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID
AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb
C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe
QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy
h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4
7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J
ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef
MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/
Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT
6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ
0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm
2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb
bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c
-----END CERTIFICATE-----

View File

@@ -0,0 +1,324 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <unistd.h>
#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "esp_timer.h"
#include "lwip/opt.h"
#include "protocol_examples_common.h"
#include "esp_dns.h"
#if defined(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE)
#include "esp_crt_bundle.h"
#endif
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN INET_ADDRSTRLEN
#endif
#define TAG "example_esp_dns"
extern const char server_root_cert_pem_start[] asm("_binary_cert_google_root_pem_start");
extern const char server_root_cert_pem_end[] asm("_binary_cert_google_root_pem_end");
/**
* @brief Performs DNS lookup for a given hostname and address family
* @param hostname The hostname to resolve
* @param family The address family (AF_INET, AF_INET6, or AF_UNSPEC)
*/
static void do_getaddrinfo(char *hostname, int family)
{
struct addrinfo hints, *res, *p;
int status;
char ipstr[INET6_ADDRSTRLEN];
void *addr = NULL;
char *ipver = NULL;
/* Initialize the hints structure */
memset(&hints, 0, sizeof hints);
hints.ai_family = family;
hints.ai_socktype = SOCK_DGRAM; /* UDP datagram sockets */
/* Get address information */
if ((status = getaddrinfo(hostname, NULL, &hints, &res)) != 0) {
ESP_LOGE(TAG, "getaddrinfo error: %d", status);
goto cleanup;
}
/* Loop through all the results */
for (p = res; p != NULL; p = p->ai_next) {
/* Get pointer to the address itself */
#if defined(CONFIG_LWIP_IPV4)
if (p->ai_family == AF_INET) { /* IPv4 */
struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
addr = &(ipv4->sin_addr);
ipver = "IPv4";
/* Convert the IP to a string and print it */
inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
ESP_LOGI(TAG, "Hostname: %s: %s(%s)", hostname, ipstr, ipver);
}
#endif
#if defined(CONFIG_LWIP_IPV6)
if (p->ai_family == AF_INET6) { /* IPv6 */
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
addr = &(ipv6->sin6_addr);
ipver = "IPv6";
/* Convert the IP to a string and print it */
inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
ESP_LOGI(TAG, "Hostname: %s: %s(%s)", hostname, ipstr, ipver);
}
#endif
}
cleanup:
freeaddrinfo(res); /* Free the linked list */
}
/**
* @brief Task that performs DNS lookups for various hostnames
* @param pvParameters Parent task handle for notification
*/
static void addr_info_task(void *pvParameters)
{
TaskHandle_t parent_handle = (TaskHandle_t)pvParameters;
do_getaddrinfo("yahoo.com", AF_UNSPEC);
do_getaddrinfo("www.google.com", AF_INET6);
do_getaddrinfo("0.0.0.0", AF_UNSPEC);
do_getaddrinfo("fe80:0000:0000:0000:5abf:25ff:fee0:4100", AF_UNSPEC);
/* Notify parent task before deleting */
if (parent_handle) {
xTaskNotifyGive(parent_handle);
}
vTaskDelete(NULL);
}
/**
* @brief Prints system information including heap and stack usage
*/
void print_system_info(void)
{
/* Get the free heap size */
uint32_t free_heap = esp_get_free_heap_size();
uint32_t min_free_heap = esp_get_minimum_free_heap_size();
/* Get the stack high water mark for the current task */
UBaseType_t stack_high_water_mark = uxTaskGetStackHighWaterMark(NULL);
ESP_LOGI(TAG, "Free Heap: %lu bytes, Min Free Heap: %lu bytes, Stack High Water Mark: %u bytes\n",
free_heap, min_free_heap, stack_high_water_mark);
}
/**
* @brief Creates and runs the DNS query task
*/
static void run_dns_query_task(void)
{
TaskHandle_t task_handle = NULL;
TaskHandle_t parent_handle = xTaskGetCurrentTaskHandle();
xTaskCreate(addr_info_task, "AddressInfo", 4 * 1024, parent_handle, 5, &task_handle);
/* Wait for task to complete */
if (task_handle != NULL) {
xTaskNotifyWait(0, 0, NULL, portMAX_DELAY);
}
print_system_info();
}
/**
* @brief Performs DNS queries using UDP protocol
*/
void perform_esp_dns_udp_query(void)
{
esp_dns_handle_t dns_handle;
ESP_LOGI(TAG, "Executing UDP DNS");
/* Initialize with UDP DNS configuration */
esp_dns_config_t udp_config = {
.dns_server = "dns.google", /* Google DNS */
};
/* Initialize UDP DNS module */
dns_handle = esp_dns_init_udp(&udp_config);
if (!dns_handle) {
ESP_LOGE(TAG, "Failed to initialize UDP DNS module");
return;
}
run_dns_query_task();
/* Cleanup */
esp_dns_cleanup_udp(dns_handle);
}
/**
* @brief Performs DNS queries using TCP protocol
*/
void perform_esp_dns_tcp_query(void)
{
esp_dns_handle_t dns_handle;
ESP_LOGI(TAG, "Executing TCP DNS");
/* Initialize with TCP DNS configuration */
esp_dns_config_t tcp_config = {
.dns_server = "dns.google",
.port = ESP_DNS_DEFAULT_TCP_PORT,
.timeout_ms = ESP_DNS_DEFAULT_TIMEOUT_MS,
};
/* Initialize TCP DNS module */
dns_handle = esp_dns_init_tcp(&tcp_config);
if (!dns_handle) {
ESP_LOGE(TAG, "Failed to initialize TCP DNS module");
return;
}
run_dns_query_task();
/* Cleanup */
esp_dns_cleanup_tcp(dns_handle);
}
/**
* @brief Performs DNS queries using DNS over TLS protocol
* @param val_type Type of certificate validation ("cert" or "bndl")
*/
void perform_esp_dns_dot_query(char *val_type)
{
esp_dns_handle_t dns_handle;
ESP_LOGI(TAG, "Executing DNS over TLS");
/* Initialize with DNS over TLS configuration */
esp_dns_config_t dot_config = {
.dns_server = "dns.google",
.port = ESP_DNS_DEFAULT_DOT_PORT,
.timeout_ms = ESP_DNS_DEFAULT_TIMEOUT_MS,
};
if (strcmp(val_type, "cert") == 0) {
dot_config.tls_config.cert_pem = server_root_cert_pem_start;
} else if (strcmp(val_type, "bndl") == 0) {
dot_config.tls_config.crt_bundle_attach = esp_crt_bundle_attach;
}
/* Initialize DoT DNS module */
dns_handle = esp_dns_init_dot(&dot_config);
if (!dns_handle) {
ESP_LOGE(TAG, "Failed to initialize DoT DNS module");
return;
}
run_dns_query_task();
/* Cleanup */
esp_dns_cleanup_dot(dns_handle);
}
/**
* @brief Performs DNS queries using DNS over HTTPS protocol
* @param val_type Type of certificate validation ("cert" or "bndl")
*/
void perform_esp_dns_doh_query(char *val_type)
{
esp_dns_handle_t dns_handle;
ESP_LOGI(TAG, "Executing DNS over HTTPS");
/* Initialize with DNS over HTTPS configuration */
esp_dns_config_t doh_config = {
.dns_server = "dns.google",
.port = ESP_DNS_DEFAULT_DOH_PORT,
.protocol_config.doh_config = {
.url_path = "/dns-query",
},
};
if (strcmp(val_type, "cert") == 0) {
doh_config.tls_config.cert_pem = server_root_cert_pem_start;
} else if (strcmp(val_type, "bndl") == 0) {
doh_config.tls_config.crt_bundle_attach = esp_crt_bundle_attach;
}
/* Initialize DoH DNS module */
dns_handle = esp_dns_init_doh(&doh_config);
if (!dns_handle) {
ESP_LOGE(TAG, "Failed to initialize DoH DNS module");
return;
}
run_dns_query_task();
/* Cleanup */
esp_dns_cleanup_doh(dns_handle);
}
void app_main(void)
{
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_err_t ret = nvs_flash_init(); /* Initialize NVS */
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
* Read "Establishing Wi-Fi or Ethernet Connection" section in
* examples/protocols/README.md for more information about this function.
*/
ESP_ERROR_CHECK(example_connect());
/* Test Without ESP_DNS module */
ESP_LOGI(TAG, "Executing DNS without initializing ESP_DNS module");
run_dns_query_task();
/* DNS over UDP Test */
perform_esp_dns_udp_query();
/* DNS over TCP Test */
perform_esp_dns_tcp_query();
/* DNS over TLS Test with cert */
perform_esp_dns_dot_query("cert");
/* DNS over TLS Test with cert bundle */
perform_esp_dns_dot_query("bndl");
/* DNS over HTTPS Test with cert */
perform_esp_dns_doh_query("cert");
/* DNS over HTTPS Test with cert bundle */
perform_esp_dns_doh_query("bndl");
}

View File

@@ -0,0 +1,8 @@
dependencies:
idf:
version: ">=5.1"
protocol_examples_common:
path: ${IDF_PATH}/examples/common_components/protocol_examples_common
esp_dns:
version: "*"
override_path: '../../../'

View File

@@ -0,0 +1,28 @@
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
# -*- coding: utf-8 -*-
import pytest
@pytest.mark.esp32
def test_esp_dns_resolution(dut):
"""
Test DNS resolution for different protocols (UDP, TCP, DoT, DoH).
"""
dut.expect('Executing UDP DNS', timeout=10)
dut.expect('Executing TCP DNS', timeout=10)
dut.expect('Executing DNS over TLS', timeout=10)
dut.expect('Executing DNS over HTTPS', timeout=10)
# Check for successful DNS resolution
dut.expect('Hostname: yahoo.com:', timeout=10)
dut.expect('Hostname: www.google.com:', timeout=10)
dut.expect('Hostname: 0.0.0.0:', timeout=10)
dut.expect('Hostname: fe80:0000:0000:0000:5abf:25ff:fee0:4100', timeout=10)
# Check for system information logs
dut.expect('Free Heap:', timeout=10)
dut.expect('Min Free Heap:', timeout=10)
dut.expect('Stack High Water Mark:', timeout=10)

View File

@@ -0,0 +1,7 @@
# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) 5.5.0 Project Minimal Configuration
#
CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y
CONFIG_LWIP_DNS_MAX_HOST_IP=4
CONFIG_LWIP_USE_ESP_GETADDRINFO=y
CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM=y