diff --git a/configs b/configs index 5eb7ce1631..a4a4be4004 160000 --- a/configs +++ b/configs @@ -1 +1 @@ -Subproject commit 5eb7ce16316971813ced45e4869167ec55a72b45 +Subproject commit a4a4be4004173c67c8ed160cc48fcea1cf57308a diff --git a/libc/Kconfig b/libc/Kconfig index 3f8e88b017..54df4e2ede 100644 --- a/libc/Kconfig +++ b/libc/Kconfig @@ -606,23 +606,54 @@ config NETDB_RESOLVCONF_PATH string "Path to host configuration file" default "/etc/resolv.conf" +config NETDB_RESOLVCONF_NONSTDPORT + bool "Non-standard port support" + default n + ---help--- + By default, the resolv.conf file will hold only records like: + + nameserver xx.xx.xx.xx + nameserver xxxx:::::::xxxx + + The default port of 53 is always assumed. + + If this option is selected, then OpenBSD style resolv.conf files + will be supported. This adds logic for a bracket port notation + like: + + nameserver [xx.xx.xx.xx]:ppppp + nameserver [xxxx:::::::xxxx]:ppppp + endif # NETDB_RESOLVCONF choice prompt "DNS server address type" - default NETDB_DNSSERVER_NOADDR + default NETDB_DNSSERVER_IPv4 if NET_IPv4 + default NETDB_DNSSERVER_IPv6 if !NET_IPv4 && NET_IPv6 + default NETDB_DNSSERVER_NOADDR if !NET_IPv4 && !NET_IPv6 depends on !NETDB_RESOLVCONF config NETDB_DNSSERVER_NOADDR bool "No default DNS server address" + ---help--- + There is not default DNS nameserver address. Application must call + dns_add_server() at runtime to add the DNS server address. config NETDB_DNSSERVER_IPv4 bool "IPv4 DNS server address" depends on NET_IPv4 + ---help--- + An IPv4 default DNS nameserver address will be provided. Application + may overwrite this start default server address by calling + dns_add_server() at runtime. config NETDB_DNSSERVER_IPv6 bool "IPv6 DNS server address" depends on NET_IPv6 + ---help--- + An IPv6 default DNS nameserver address will be provided. Application + may overwrite this start default server address by calling + dns_add_server() at runtime. endchoice # DNS server address type diff --git a/libc/netdb/lib_dns.h b/libc/netdb/lib_dns.h index 86287dc226..9a6f25b7e6 100644 --- a/libc/netdb/lib_dns.h +++ b/libc/netdb/lib_dns.h @@ -80,7 +80,8 @@ # define CONFIG_NETDB_RESOLVCONF_PATH "/etc/resolv.conf" #endif -#define DNS_MAX_LINE 80 +#define DNS_MAX_ADDRSTR 48 +#define DNS_MAX_LINE 64 #define NETDB_DNS_KEYWORD "nameserver" /**************************************************************************** diff --git a/libc/netdb/lib_dnsaddserver.c b/libc/netdb/lib_dnsaddserver.c index dfeff175c2..ff2436985a 100644 --- a/libc/netdb/lib_dnsaddserver.c +++ b/libc/netdb/lib_dnsaddserver.c @@ -80,7 +80,11 @@ bool g_dns_address; /* true: We have the address of the DNS server */ int dns_add_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen) { FAR FILE *stream; - char line[DNS_MAX_LINE]; + char addrstr[DNS_MAX_ADDRSTR]; +#ifdef CONFIG_NETDB_RESOLVCONF_NONSTDPORT + uint16_t port; +#endif + int status; int ret; stream = fopen(CONFIG_NETDB_RESOLVCONF_PATH, "at"); @@ -107,20 +111,26 @@ int dns_add_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen) { FAR struct sockaddr_in *in4 = (FAR struct sockaddr_in *)addr; - if (inet_ntop(AF_INET, &in4->sin_addr, line, DNS_MAX_LINE) == NULL) + if (inet_ntop(AF_INET, &in4->sin_addr, addrstr, DNS_MAX_ADDRSTR) == NULL) { ret = -errno; ndbg("ERROR: inet_ntop failed: %d\n", errcode); DEBUGASSERT(errcode < 0); goto errout; } + +#ifdef CONFIG_NETDB_RESOLVCONF_NONSTDPORT + /* Get the port number */ + + port = ntohs(in4->sin_port); +#endif } } else #endif #ifdef CONFIG_NET_IPv6 - /* Check for an IPv4 address */ + /* Check for an IPv6 address */ if (addr->sa_family == AF_INET6) { @@ -133,13 +143,19 @@ int dns_add_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen) { FAR struct sockaddr_in6 *in6 = (FAR struct sockaddr_in6 *)addr; - if (inet_ntop(AF_INET6, &in6->sin6_addr, line, DNS_MAX_LINE) == NULL) + if (inet_ntop(AF_INET6, &in6->sin6_addr, addrstr, DNS_MAX_ADDRSTR) == NULL) { ret = -errno; ndbg("ERROR: inet_ntop failed: %d\n", errcode); DEBUGASSERT(errcode < 0); goto errout; } + +#ifdef CONFIG_NETDB_RESOLVCONF_NONSTDPORT + /* Get the port number */ + + port = ntohs(in6->sin6_port); +#endif } } else @@ -151,9 +167,30 @@ int dns_add_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen) goto errout; } - /* Write the new record to the end of the resolv.conf file */ + /* Write the new record to the end of the resolv.conf file. */ - if (fprintf(stream, "%s %s\n", NETDB_DNS_KEYWORD, line) < 0) +#ifdef CONFIG_NETDB_RESOLVCONF_NONSTDPORT + /* The OpenBSD version supports a [host]:port syntax. When a non-standard + * port is specified the host address must be enclosed in square brackets. + * For example: + * + * nameserver [10.0.0.1]:5353 + * nameserver [::1]:5353 + */ + + if (port != 0 && port != DNS_DEFAULT_PORT) + { + status = fprintf(stream, "%s [%s]:%u\n", + NETDB_DNS_KEYWORD, addrstr, port); + } + else +#endif + { + status = fprintf(stream, "%s %s\n", + NETDB_DNS_KEYWORD, addrstr); + } + + if (status < 0) { ret = -errno; ndbg("ERROR: fprintf failed: %d\n", errcode); diff --git a/libc/netdb/lib_dnsforeach.c b/libc/netdb/lib_dnsforeach.c index 63ae1024e2..761cc441f3 100644 --- a/libc/netdb/lib_dnsforeach.c +++ b/libc/netdb/lib_dnsforeach.c @@ -40,6 +40,7 @@ #include #include +#include #include #include #include @@ -94,6 +95,7 @@ int dns_foreach_nameserver(dns_callback_t callback, FAR void *arg) char line[DNS_MAX_LINE]; FAR char *addrstr; FAR char *ptr; + uint16_t port; int keylen; int ret; @@ -133,9 +135,12 @@ int dns_foreach_nameserver(dns_callback_t callback, FAR void *arg) ptr = find_spaces(addrstr); *ptr = '\0'; - /* Convert the address string to a binary representation */ - /* REVISIT: We really need a customizable port number. The - * OpenBSD version supports a [host]:port syntax. When a + /* Convert the address string to a binary representation. */ + + port = HTONS(DNS_DEFAULT_PORT); + +#ifdef CONFIG_NETDB_RESOLVCONF_NONSTDPORT + /* The OpenBSD version supports a [host]:port syntax. When a * non-standard port is specified the host address must be * enclosed in square brackets. For example: * @@ -143,6 +148,46 @@ int dns_foreach_nameserver(dns_callback_t callback, FAR void *arg) * nameserver [::1]:5353 */ + if (*addrstr == '[') + { + /* Make sure that ther is a right bracket */ + + ptr = strchr(addrstr, ']'); + if (ptr == NULL) + { + ndbg("ERROR: Missing right bracket after %s\n", line); + continue; + } + + /* Replace the right bracket with a NULL terminator */ + + addrstr++; + *ptr++ = '\0'; + + /* Get the port number following the right bracket */ + + if (*ptr == ':') + { + FAR char *portstr; + int tmp; + + /* Isolate the port string */ + + portstr = ptr; + ptr = find_spaces(addrstr); + *ptr = '\0'; + + /* Get the port number */ + + tmp = atoi(portstr); + if (tmp != 0) + { + port = htons(tmp); + } + } + } +#endif /* CONFIG_NETDB_RESOLVCONF_NONSTDPORT */ + #ifdef CONFIG_NET_IPv4 /* Try to convert the IPv4 address */ @@ -152,10 +197,8 @@ int dns_foreach_nameserver(dns_callback_t callback, FAR void *arg) if (ret == 1) { - /* REVISIT: We really need a customizable port number */ - u.ipv4.sin_family = AF_INET; - u.ipv4.sin_port = HTONS(DNS_DEFAULT_PORT); + u.ipv4.sin_port = port; ret = callback(arg, (FAR struct sockaddr *)&u.ipv4, sizeof(struct sockaddr_in)); } @@ -173,10 +216,8 @@ int dns_foreach_nameserver(dns_callback_t callback, FAR void *arg) if (ret == 1) { - /* REVISIT: We really need a customizable port number */ - u.ipv6.sin6_family = AF_INET6; - u.ipv6.sin6_port = HTONS(DNS_DEFAULT_PORT); + u.ipv6.sin6_port = port; ret = callback(arg, (FAR struct sockaddr *)&u.ipv6, sizeof(struct sockaddr_in6)); }