From 12ae722863120883ce32311916fd61c729770546 Mon Sep 17 00:00:00 2001 From: Lorenzo Consolaro Date: Thu, 19 Dec 2024 09:29:29 +0100 Subject: [PATCH] feat(dhcps): Support for multiple DNS servers --- components/esp_netif/lwip/esp_netif_lwip.c | 11 ++-- components/lwip/apps/dhcpserver/dhcpserver.c | 53 +++++++++++++------ .../lwip/include/apps/dhcpserver/dhcpserver.h | 15 ++++-- 3 files changed, 56 insertions(+), 23 deletions(-) diff --git a/components/esp_netif/lwip/esp_netif_lwip.c b/components/esp_netif/lwip/esp_netif_lwip.c index ea084e0ceb99..9af25f747498 100644 --- a/components/esp_netif/lwip/esp_netif_lwip.c +++ b/components/esp_netif/lwip/esp_netif_lwip.c @@ -1984,11 +1984,14 @@ static esp_err_t esp_netif_set_dns_info_api(esp_netif_api_msg_t *msg) if (esp_netif && esp_netif->flags & ESP_NETIF_DHCP_SERVER) { #if ESP_DHCPS // if DHCP server configured to set DNS in dhcps API - if (type != ESP_NETIF_DNS_MAIN) { + if (type >= ESP_NETIF_DNS_FALLBACK) + { ESP_LOGD(TAG, "set dns invalid type"); return ESP_ERR_ESP_NETIF_INVALID_PARAMS; - } else { - dhcps_dns_setserver(esp_netif->dhcps, &lwip_ip); + } + else + { + dhcps_dns_setserver(esp_netif->dhcps, &lwip_ip, (dns_type_t)type); } #else LOG_NETIF_DISABLED_AND_DO("DHCP Server", return ESP_ERR_NOT_SUPPORTED); @@ -2047,7 +2050,7 @@ static esp_err_t esp_netif_get_dns_info_api(esp_netif_api_msg_t *msg) if (esp_netif && esp_netif->flags & ESP_NETIF_DHCP_SERVER) { #if ESP_DHCPS ip4_addr_t dns_ip; - dhcps_dns_getserver(esp_netif->dhcps, &dns_ip); + dhcps_dns_getserver(esp_netif->dhcps, &dns_ip, (dns_type_t)type); memcpy(&dns->ip.u_addr.ip4, &dns_ip, sizeof(ip4_addr_t)); dns->ip.type = ESP_IPADDR_TYPE_V4; #else diff --git a/components/lwip/apps/dhcpserver/dhcpserver.c b/components/lwip/apps/dhcpserver/dhcpserver.c index 8859e52c63bf..0be4f08c3062 100644 --- a/components/lwip/apps/dhcpserver/dhcpserver.c +++ b/components/lwip/apps/dhcpserver/dhcpserver.c @@ -126,7 +126,7 @@ struct dhcps_t { struct netif *dhcps_netif; ip4_addr_t broadcast_dhcps; ip4_addr_t server_address; - ip4_addr_t dns_server; + ip4_addr_t dns_server[DNS_TYPE_MAX]; ip4_addr_t client_address; ip4_addr_t client_address_plus; ip4_addr_t dhcps_mask; @@ -155,7 +155,11 @@ dhcps_t *dhcps_new(void) return NULL; } dhcps->dhcps_netif = NULL; - dhcps->dns_server.addr = 0; + + for (int i = 0; i < DNS_TYPE_MAX; i++) + { + dhcps->dns_server[i].addr = 0; + } #ifdef USE_CLASS_B_NET dhcps->dhcps_mask.addr = PP_HTONL(LWIP_MAKEU32(255, 240, 0, 0)); #else @@ -454,16 +458,31 @@ static u8_t *add_offer_options(dhcps_t *dhcps, u8_t *optptr) } } + // In order of preference + *optptr++ = DHCP_OPTION_DNS_SERVER; if (dhcps_dns_enabled(dhcps->dhcps_dns)) { - *optptr++ = DHCP_OPTION_DNS_SERVER; - *optptr++ = 4; - *optptr++ = ip4_addr1(&dhcps->dns_server); - *optptr++ = ip4_addr2(&dhcps->dns_server); - *optptr++ = ip4_addr3(&dhcps->dns_server); - *optptr++ = ip4_addr4(&dhcps->dns_server); + uint8_t size = 4; + + if (dhcps->dns_server[DNS_TYPE_BACKUP].addr) + { + size += 4; + } + *optptr++ = size; + + *optptr++ = ip4_addr1(&dhcps->dns_server[DNS_TYPE_MAIN]); + *optptr++ = ip4_addr2(&dhcps->dns_server[DNS_TYPE_MAIN]); + *optptr++ = ip4_addr3(&dhcps->dns_server[DNS_TYPE_MAIN]); + *optptr++ = ip4_addr4(&dhcps->dns_server[DNS_TYPE_MAIN]); + + if (dhcps->dns_server[DNS_TYPE_BACKUP].addr) + { + *optptr++ = ip4_addr1(&dhcps->dns_server[DNS_TYPE_BACKUP]); + *optptr++ = ip4_addr2(&dhcps->dns_server[DNS_TYPE_BACKUP]); + *optptr++ = ip4_addr3(&dhcps->dns_server[DNS_TYPE_BACKUP]); + *optptr++ = ip4_addr4(&dhcps->dns_server[DNS_TYPE_BACKUP]); + } #ifdef CONFIG_LWIP_DHCPS_ADD_DNS }else { - *optptr++ = DHCP_OPTION_DNS_SERVER; *optptr++ = 4; *optptr++ = ip4_addr1(&ipadd); *optptr++ = ip4_addr2(&ipadd); @@ -1535,17 +1554,18 @@ bool dhcp_search_ip_on_mac(dhcps_t *dhcps, u8_t *mac, ip4_addr_t *ip) * FunctionName : dhcps_dns_setserver * Description : set DNS server address for dhcpserver * Parameters : dnsserver -- The DNS server address + * type -- The DNS type * Returns : ERR_ARG if invalid handle, ERR_OK on success *******************************************************************************/ -err_t dhcps_dns_setserver(dhcps_t *dhcps, const ip_addr_t *dnsserver) +err_t dhcps_dns_setserver(dhcps_t *dhcps, const ip_addr_t *dnsserver, dns_type_t type) { if (dhcps == NULL) { return ERR_ARG; } if (dnsserver != NULL) { - dhcps->dns_server = *(ip_2_ip4(dnsserver)); + dhcps->dns_server[type] = *(ip_2_ip4(dnsserver)); } else { - dhcps->dns_server = *(ip_2_ip4(IP_ADDR_ANY)); + dhcps->dns_server[type] = *(ip_2_ip4(IP_ADDR_ANY)); } return ERR_OK; } @@ -1553,13 +1573,14 @@ err_t dhcps_dns_setserver(dhcps_t *dhcps, const ip_addr_t *dnsserver) /****************************************************************************** * FunctionName : dhcps_dns_getserver * Description : get DNS server address for dhcpserver - * Parameters : none - * Returns : ip4_addr_t + * Parameters : dnsserver -- The DNS server address + * type -- The DNS type + * Returns : ERR_ARG if invalid handle, ERR_OK on success *******************************************************************************/ -err_t dhcps_dns_getserver(dhcps_t *dhcps, ip4_addr_t *dnsserver) +err_t dhcps_dns_getserver(dhcps_t *dhcps, ip4_addr_t *dnsserver, dns_type_t type) { if (dhcps) { - *dnsserver = dhcps->dns_server; + *dnsserver = dhcps->dns_server[type]; return ERR_OK; } return ERR_ARG; diff --git a/components/lwip/include/apps/dhcpserver/dhcpserver.h b/components/lwip/include/apps/dhcpserver/dhcpserver.h index 479c528009f5..e297cf3e40da 100644 --- a/components/lwip/include/apps/dhcpserver/dhcpserver.h +++ b/components/lwip/include/apps/dhcpserver/dhcpserver.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -47,6 +47,13 @@ enum dhcps_offer_option{ OFFER_END }; +typedef enum +{ + DNS_TYPE_MAIN = 0, /**< DNS main server address*/ + DNS_TYPE_BACKUP, /**< DNS backup server address (Wi-Fi STA and Ethernet only) */ + DNS_TYPE_MAX +} dns_type_t; + /** @brief DHCP server's description of compile time configuration values in dhcpserver.c * * - DHCPS_DEBUG: Prints very detailed debug messages if set to 1, hardcoded to 0 @@ -164,17 +171,19 @@ bool dhcp_search_ip_on_mac(dhcps_t *dhcps, u8_t *mac, ip4_addr_t *ip); * @brief Sets DNS server address for the DHCP server * @param dhcps Pointer to the DHCP handle * @param dnsserver Address of the DNS server + * @param type Type of the DNS server * @return ERR_ARG if invalid handle, ERR_OK on success */ -err_t dhcps_dns_setserver(dhcps_t *dhcps, const ip_addr_t *dnsserver); +err_t dhcps_dns_setserver(dhcps_t *dhcps, const ip_addr_t *dnsserver, dns_type_t type); /** * @brief Gets DNS server associated with this DHCP server * @param dhcps Pointer to the DHCP handle * @param dnsserver Address of the DNS server + * @param type Type of the DNS server * @return ERR_ARG if invalid handle, ERR_OK on success */ -err_t dhcps_dns_getserver(dhcps_t *dhcps, ip4_addr_t *dnsserver); +err_t dhcps_dns_getserver(dhcps_t *dhcps, ip4_addr_t *dnsserver, dns_type_t type); /** * @brief Sets callback on assigning an IP to the connected client