netdb/lib_dnsdelserver.c: support delete the DNS server address
Build Documentation / build-html (push) Has been cancelled

by index or address

 - dns_del_nameserver()
 - dns_del_nameserver_by_index()

Update the "DNS function" section in 11_network.rst, and create
the netlib API documentation in netlib/index.rst

Signed-off-by: nuttxs <zhaoqing.zhang@sony.com>
This commit is contained in:
nuttxs
2025-11-05 17:59:11 +08:00
committed by Alan C. Assis
parent cc2cb394fa
commit 65e318421d
6 changed files with 1015 additions and 3 deletions
File diff suppressed because it is too large Load Diff
+111
View File
@@ -413,3 +413,114 @@ the following paragraphs.
- ``NOBUFS``. Insufficient resources are available in the system to
complete the call.
=============
DNS Functions
=============
NuttX provides DNS resolver functions for configuring and managing DNS
servers. These functions are defined in ``nuttx/net/dns.h`` and allow
applications to add, remove, and query DNS nameservers.
- :c:func:`dns_add_nameserver`
- :c:func:`dns_del_nameserver`
- :c:func:`dns_del_nameserver_by_index`
- :c:func:`dns_default_nameserver`
- :c:func:`dns_foreach_nameserver`
- :c:func:`dns_register_notify`
- :c:func:`dns_unregister_notify`
- :c:func:`dns_set_queryfamily`
.. c:function:: int dns_add_nameserver(const struct sockaddr *addr, socklen_t addrlen);
Configure a DNS server to use for queries. Set the port number to zero
to use the default DNS server port (53).
:param addr: Address of the DNS server (sockaddr_in or sockaddr_in6).
:param addrlen: Length of the address structure.
:return: 0 on success; -1 on error with ``errno`` set appropriately:
- ``EINVAL``. Invalid argument.
- ``ENOMEM``. Insufficient memory to add the new DNS server.
.. c:function:: int dns_del_nameserver(const struct sockaddr *addr, socklen_t addrlen);
Remove a DNS server from the list by address.
:param addr: Address of the DNS server to remove.
:param addrlen: Length of the address structure.
:return: 0 on success; -1 on error with ``errno`` set appropriately:
- ``EINVAL``. Invalid argument.
- ``ENOENT``. The specified DNS server was not found.
.. c:function:: int dns_del_nameserver_by_index(int index);
Remove a DNS server from the list by index (0-based).
:param index: Index of the DNS server in the list (0-based).
:return: 0 on success; -1 on error with ``errno`` set appropriately:
- ``EINVAL``. Invalid index.
.. c:function:: int dns_default_nameserver(void);
Reset the resolver to use only the default DNS server, if any. This function
clears all added DNS servers and restores the default configuration.
:return: 0 on success; -1 on error.
.. c:function:: int dns_foreach_nameserver(dns_callback_t callback, void *arg);
Traverse each nameserver entry and perform the provided callback.
:param callback: Callback function to invoke for each DNS server. The callback
prototype is: ``int (*callback)(void *arg, struct sockaddr *addr, socklen_t addrlen)``
:param arg: User argument to pass to the callback function.
:return: 0 on success; -1 on error with ``errno`` set appropriately.
If the callback returns a non-zero value, traversal stops and that value is returned.
- ``EINVAL``. Callback function pointer is NULL.
.. c:function:: int dns_register_notify(dns_callback_t callback, void *arg);
Register a callback function to receive nameserver change notifications. When the
DNS server list changes (servers added or removed), registered callbacks will be invoked.
:param callback: Callback function to invoke on nameserver changes.
:param arg: User argument to pass to the callback function.
:return: 0 on success; -1 on error with ``errno`` set appropriately:
- ``EINVAL``. Callback function pointer is NULL.
- ``ENOMEM``. Insufficient memory to register the notification.
.. c:function:: int dns_unregister_notify(dns_callback_t callback, void *arg);
Unsubscribe from nameserver change notifications.
:param callback: Callback function to unregister.
:param arg: User argument provided during registration.
:return: 0 on success; -1 on error with ``errno`` set appropriately:
- ``EINVAL``. Callback function pointer is NULL.
- ``ENOENT``. The specified callback was not found.
.. c:function:: int dns_set_queryfamily(sa_family_t family);
Configure the address family to be used for queries.
:param family: Address family, can be:
- ``AF_INET``: Use IPv4 for DNS queries.
- ``AF_INET6``: Use IPv6 for DNS queries.
- ``AF_UNSPEC``: Automatic selection (prefer IPv6, fallback to IPv4).
:return: 0 on success; -1 on error with ``errno`` set appropriately:
- ``EINVAL``. Unsupported address family.
+24 -1
View File
@@ -2,7 +2,10 @@
* include/nuttx/net/dns.h
*
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-FileCopyrightText: 2007-2009, 2011-2012, 2014-2015, 2018 Gregory Nutt. All rights reserved.
* SPDX-FileCopyrightText: 2018 Gregory Nutt. All rights reserved.
* SPDX-FileCopyrightText: 2014-2015 Gregory Nutt. All rights reserved.
* SPDX-FileCopyrightText: 2011-2012 Gregory Nutt. All rights reserved.
* SPDX-FileCopyrightText: 2007-2009 Gregory Nutt. All rights reserved.
* SPDX-FileCopyrightText: 2002-2003, Adam Dunkels. All rights reserved.
* SPDX-FileContributor: Gregory Nutt <gnutt@nuttx.org>
* SPDX-FileContributor: Adam Dunkels <adam@dunkels.com>
@@ -203,6 +206,26 @@ extern "C"
int dns_add_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen);
/****************************************************************************
* Name: dns_del_nameserver
*
* Description:
* Remove a DNS server from the list by address.
*
****************************************************************************/
int dns_del_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen);
/****************************************************************************
* Name: dns_del_nameserver_by_index
*
* Description:
* Remove a DNS server from the list by index (0-based).
*
****************************************************************************/
int dns_del_nameserver_by_index(int index);
/****************************************************************************
* Name: dns_default_nameserver
*
+2 -1
View File
@@ -59,7 +59,8 @@ if(CONFIG_LIBC_NETDB)
if(CONFIG_NETDB_DNSCLIENT)
list(APPEND SRCS lib_dnsinit.c lib_dnsbind.c lib_dnsquery.c)
list(APPEND SRCS lib_dnsaddserver.c lib_dnsdefaultserver.c)
list(APPEND SRCS lib_dnsaddserver.c lib_dnsdelserver.c
lib_dnsdefaultserver.c)
list(APPEND SRCS lib_dnsforeach.c lib_dnsnotify.c)
list(APPEND SRCS lib_dnsqueryfamily.c)
+1 -1
View File
@@ -44,7 +44,7 @@ endif
ifeq ($(CONFIG_NETDB_DNSCLIENT),y)
CSRCS += lib_dnsinit.c lib_dnsbind.c lib_dnsquery.c
CSRCS += lib_dnsaddserver.c lib_dnsdefaultserver.c
CSRCS += lib_dnsaddserver.c lib_dnsdelserver.c lib_dnsdefaultserver.c
CSRCS += lib_dnsforeach.c lib_dnsnotify.c
CSRCS += lib_dnsqueryfamily.c
+227
View File
@@ -0,0 +1,227 @@
/****************************************************************************
* libs/libc/netdb/lib_dnsdelserver.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/net/ip.h>
#include <nuttx/net/dns.h>
#include "netdb/lib_dns.h"
#ifdef CONFIG_NETDB_DNSCLIENT
/****************************************************************************
* Private Functions
****************************************************************************/
#ifndef CONFIG_NETDB_RESOLVCONF
static int dns_find_nameserver_index(FAR const struct sockaddr *addr,
socklen_t addrlen)
{
size_t cmplen = 0;
int i;
#ifdef CONFIG_NET_IPv4
if (addr->sa_family == AF_INET)
{
cmplen = sizeof(struct sockaddr_in);
}
#endif
#ifdef CONFIG_NET_IPv6
if (addr->sa_family == AF_INET6)
{
cmplen = sizeof(struct sockaddr_in6);
}
#endif
if (cmplen == 0)
{
/* Unsupported address family */
return -ENOSYS;
}
if (addrlen < cmplen)
{
return -EINVAL;
}
dns_lock();
/* Search for the matching nameserver in the array */
for (i = 0; i < g_dns_nservers; i++)
{
if (g_dns_servers[i].addr.sa_family == addr->sa_family)
{
#ifdef CONFIG_NET_IPv4
if (addr->sa_family == AF_INET)
{
FAR struct sockaddr_in *in1 =
(FAR struct sockaddr_in *)&g_dns_servers[i].addr;
FAR struct sockaddr_in *in2 =
(FAR struct sockaddr_in *)addr;
/* Compare only the IP address part, ignore port and padding */
if (net_ipv4addr_cmp(in1->sin_addr.s_addr,
in2->sin_addr.s_addr))
{
dns_unlock();
return i;
}
}
#endif
#ifdef CONFIG_NET_IPv6
if (addr->sa_family == AF_INET6)
{
FAR struct sockaddr_in6 *in6_1 =
(FAR struct sockaddr_in6 *)&g_dns_servers[i].addr;
FAR struct sockaddr_in6 *in6_2 =
(FAR struct sockaddr_in6 *)addr;
/* Compare only the IPv6 address part */
if (net_ipv6addr_cmp(in6_1->sin6_addr.s6_addr,
in6_2->sin6_addr.s6_addr))
{
dns_unlock();
return i;
}
}
#endif
}
}
dns_unlock();
return -ENOENT;
}
#endif /* !CONFIG_NETDB_RESOLVCONF */
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: dns_del_nameserver
*
* Description:
* Remove a DNS server from the list by matching the address
*
****************************************************************************/
#ifdef CONFIG_NETDB_RESOLVCONF
int dns_del_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen)
{
/* Not implemented for CONFIG_NETDB_RESOLVCONF */
return -ENOSYS;
}
int dns_del_nameserver_by_index(int index)
{
/* For resolv.conf mode, removing requires rewriting the file */
return -ENOSYS;
}
#else /* !CONFIG_NETDB_RESOLVCONF */
int dns_del_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen)
{
int index;
if (addr == NULL)
{
return -EINVAL;
}
/* Find the nameserver in the array */
index = dns_find_nameserver_index(addr, addrlen);
if (index < 0)
{
return index; /* Return the error code */
}
/* Remove the server by index */
return dns_del_nameserver_by_index(index);
}
int dns_del_nameserver_by_index(int index)
{
int i;
if (index < 0 || index >= CONFIG_NETDB_DNSSERVER_NAMESERVERS)
{
return -EINVAL;
}
dns_lock();
if (index >= g_dns_nservers)
{
dns_unlock();
return -ENOENT;
}
/* Shift all subsequent entries down by one position */
for (i = index; i < g_dns_nservers - 1; i++)
{
memcpy(&g_dns_servers[i], &g_dns_servers[i + 1],
sizeof(union dns_addr_u));
}
memset(&g_dns_servers[g_dns_nservers - 1], 0, sizeof(union dns_addr_u));
/* Decrement the server count */
g_dns_nservers--;
dns_unlock();
#if CONFIG_NETDB_DNSCLIENT_ENTRIES > 0
/* Clear the DNS cache after removing a server */
dns_clear_answer();
#endif
return OK;
}
#endif /* CONFIG_NETDB_RESOLVCONF */
#endif /* CONFIG_NETDB_DNSCLIENT */