Files
esp-protocols/components/esp_dns/esp_dns_utils.h
Abhik Roy 57cd60807e 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.
2025-04-16 21:30:06 +10:00

140 lines
4.2 KiB
C

/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "freertos/FreeRTOS.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_tls.h"
#include "sdkconfig.h"
#include "lwip/prot/dns.h"
#include "lwip/api.h"
#include "lwip/opt.h"
#include "lwip/dns.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief DNS header structure
*
* Contains the basic fields of a DNS message header as defined in RFC 1035
*/
typedef struct {
uint16_t id; /* Identification - unique identifier for the query */
uint16_t flags; /* Flags - control bits for the DNS message */
uint16_t qdcount; /* Number of questions in the question section */
uint16_t ancount; /* Number of answers in the answer section */
uint16_t nscount; /* Number of authority records in the authority section */
uint16_t arcount; /* Number of additional records in the additional section */
} dns_header_t;
/**
* @brief DNS question structure
*
* Represents a single question in the question section of a DNS message
*/
typedef struct {
uint16_t qtype; /* Question type (e.g., A, AAAA, MX) */
uint16_t qclass; /* Question class (e.g., IN for internet) */
} dns_question_t;
/**
* @brief DNS answer message structure
*
* Represents a single resource record in the answer section of a DNS message
* No packing needed as it's only used locally on the stack
*/
typedef struct {
uint16_t type; /* Resource record type (e.g., A, AAAA, MX) */
uint16_t class; /* Resource record class (e.g., IN for internet) */
uint32_t ttl; /* Time-to-live in seconds */
uint16_t data_len; /* Length of the resource data */
} dns_answer_t;
#define SIZEOF_DNS_ANSWER_FIXED 10 /* Size of dns_answer_t structure in bytes */
/** Maximum TTL value for DNS resource records (one week) */
#define DNS_MAX_TTL 604800
#ifndef CONFIG_LWIP_DNS_MAX_HOST_IP
#define CONFIG_LWIP_DNS_MAX_HOST_IP 1
#endif
/** Maximum number of answers that can be stored */
#define MAX_ANSWERS (CONFIG_LWIP_DNS_MAX_HOST_IP)
#define ESP_DNS_BUFFER_SIZE 512
/**
* @brief Structure to store a single DNS answer
*/
typedef struct {
err_t status; /* Status of the answer */
ip_addr_t ip; /* IP address from the answer */
} dns_answer_storage_t;
/**
* @brief Structure to store a complete DNS response
*/
typedef struct {
err_t status_code; /* Overall status of the DNS response */
uint16_t id; /* Transaction ID */
int num_answers; /* Number of valid answers */
dns_answer_storage_t answers[MAX_ANSWERS]; /* Array of answers */
} dns_response_t;
/**
* @brief Buffer structure for DNS response processing
*/
typedef struct {
char *buffer; /* Pointer to response data buffer */
int length; /* Current length of data in buffer */
dns_response_t dns_response; /* Parsed DNS response information */
} response_buffer_t;
/**
* @brief Creates a DNS query for A and AAAA records
*
* @param buffer Buffer to store the query
* @param buffer_size Size of the buffer
* @param hostname Hostname to query
* @param addrtype Address type (A or AAAA)
* @param id_o Pointer to store the generated query ID
*
* @return size_t Size of the created query, or -1 on error
*/
size_t esp_dns_create_query(uint8_t *buffer, size_t buffer_size, const char *hostname, int addrtype, uint16_t *id_o);
/**
* @brief Parses a DNS response message
*
* @param buffer Buffer containing the DNS response
* @param response_size Size of the response
* @param dns_response Structure to store parsed response
*/
void esp_dns_parse_response(uint8_t *buffer, size_t response_size, dns_response_t *dns_response);
/**
* @brief Converts a dns_response_t to an array of IP addresses.
*
* This function iterates over the DNS response and extracts valid
* IPv4 and IPv6 addresses, storing them in the provided array.
*
* @param response The DNS response to process.
* @param ipaddr An array to store the extracted IP addresses.
*
* @return err Status of dns response parsing
*/
err_t esp_dns_extract_ip_addresses_from_response(const dns_response_t *response, ip_addr_t ipaddr[]);
#ifdef __cplusplus
}
#endif