DNS: Allow a DNS look-up with a trailing dot in the name

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
This commit is contained in:
Craig McQueen 2018-11-16 03:15:29 +01:00 committed by Simon Goldschmidt
parent 9071db11af
commit ef76bbe3f0
2 changed files with 43 additions and 15 deletions

View File

@ -277,7 +277,7 @@ DNS_LOCAL_HOSTLIST_STORAGE_PRE struct local_hostlist_entry local_hostlist_static
#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
static void dns_init_local(void);
static err_t dns_lookup_local(const char *hostname, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype));
static err_t dns_lookup_local(const char *hostname, size_t hostnamelen, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype));
#endif /* DNS_LOCAL_HOSTLIST */
@ -476,18 +476,32 @@ dns_local_iterate(dns_found_callback iterator_fn, void *iterator_arg)
err_t
dns_local_lookup(const char *hostname, ip_addr_t *addr, u8_t dns_addrtype)
{
size_t hostnamelen;
LWIP_UNUSED_ARG(dns_addrtype);
return dns_lookup_local(hostname, addr LWIP_DNS_ADDRTYPE_ARG(dns_addrtype));
if ((addr == NULL) ||
(!hostname) || (!hostname[0])) {
return ERR_ARG;
}
hostnamelen = strlen(hostname);
if (hostname[hostnamelen - 1] == '.') {
hostnamelen--;
}
if (hostnamelen >= DNS_MAX_NAME_LENGTH) {
LWIP_DEBUGF(DNS_DEBUG, ("dns_local_lookup: name too long to resolve"));
return ERR_ARG;
}
return dns_lookup_local(hostname, hostnamelen, addr LWIP_DNS_ADDRTYPE_ARG(dns_addrtype));
}
/* Internal implementation for dns_local_lookup and dns_lookup */
static err_t
dns_lookup_local(const char *hostname, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype))
dns_lookup_local(const char *hostname, size_t hostnamelen, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype))
{
#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC
struct local_hostlist_entry *entry = local_hostlist_dynamic;
while (entry != NULL) {
if ((lwip_stricmp(entry->name, hostname) == 0) &&
if ((lwip_strnicmp(entry->name, hostname, hostnamelen) == 0) &&
!entry->name[hostnamelen] &&
LWIP_DNS_ADDRTYPE_MATCH_IP(dns_addrtype, entry->addr)) {
if (addr) {
ip_addr_copy(*addr, entry->addr);
@ -499,7 +513,8 @@ dns_lookup_local(const char *hostname, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_
#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
size_t i;
for (i = 0; i < LWIP_ARRAYSIZE(local_hostlist_static); i++) {
if ((lwip_stricmp(local_hostlist_static[i].name, hostname) == 0) &&
if ((lwip_strnicmp(local_hostlist_static[i].name, hostname, hostnamelen) == 0) &&
!local_hostlist_static[i].name[hostnamelen] &&
LWIP_DNS_ADDRTYPE_MATCH_IP(dns_addrtype, local_hostlist_static[i].addr)) {
if (addr) {
ip_addr_copy(*addr, local_hostlist_static[i].addr);
@ -593,30 +608,34 @@ dns_local_addhost(const char *hostname, const ip_addr_t *addr)
* for a hostname.
*
* @param name the hostname to look up
* @param hostnamelen length of the hostname
* @param addr the hostname's IP address, as u32_t (instead of ip_addr_t to
* better check for failure: != IPADDR_NONE) or IPADDR_NONE if the hostname
* was not found in the cached dns_table.
* @return ERR_OK if found, ERR_ARG if not found
*/
static err_t
dns_lookup(const char *name, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype))
dns_lookup(const char *name, size_t hostnamelen, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype))
{
size_t namelen;
u8_t i;
#if DNS_LOCAL_HOSTLIST
if (dns_lookup_local(name, addr LWIP_DNS_ADDRTYPE_ARG(dns_addrtype)) == ERR_OK) {
if (dns_lookup_local(name, hostnamelen, addr LWIP_DNS_ADDRTYPE_ARG(dns_addrtype)) == ERR_OK) {
return ERR_OK;
}
#endif /* DNS_LOCAL_HOSTLIST */
#ifdef DNS_LOOKUP_LOCAL_EXTERN
if (DNS_LOOKUP_LOCAL_EXTERN(name, addr, LWIP_DNS_ADDRTYPE_ARG_OR_ZERO(dns_addrtype)) == ERR_OK) {
if (DNS_LOOKUP_LOCAL_EXTERN(name, hostnamelen, addr, LWIP_DNS_ADDRTYPE_ARG_OR_ZERO(dns_addrtype)) == ERR_OK) {
return ERR_OK;
}
#endif /* DNS_LOOKUP_LOCAL_EXTERN */
namelen = LWIP_MIN(hostnamelen, DNS_MAX_NAME_LENGTH - 1);
/* Walk through name list, return entry if found. If not, return NULL. */
for (i = 0; i < DNS_TABLE_SIZE; ++i) {
if ((dns_table[i].state == DNS_STATE_DONE) &&
(lwip_strnicmp(name, dns_table[i].name, sizeof(dns_table[i].name)) == 0) &&
(lwip_strnicmp(name, dns_table[i].name, namelen) == 0) &&
!dns_table[i].name[namelen] &&
LWIP_DNS_ADDRTYPE_MATCH_IP(dns_addrtype, dns_table[i].ipaddr)) {
LWIP_DEBUGF(DNS_DEBUG, ("dns_lookup: \"%s\": found = ", name));
ip_addr_debug_print_val(DNS_DEBUG, dns_table[i].ipaddr);
@ -1380,13 +1399,18 @@ dns_enqueue(const char *name, size_t hostnamelen, dns_found_callback found,
struct dns_table_entry *entry = NULL;
size_t namelen;
struct dns_req_entry *req;
#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0)
u8_t r;
#endif
namelen = LWIP_MIN(hostnamelen, DNS_MAX_NAME_LENGTH - 1);
#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0)
/* check for duplicate entries */
for (i = 0; i < DNS_TABLE_SIZE; i++) {
if ((dns_table[i].state == DNS_STATE_ASKING) &&
(lwip_strnicmp(name, dns_table[i].name, sizeof(dns_table[i].name)) == 0)) {
(lwip_strnicmp(name, dns_table[i].name, namelen) == 0) &&
!dns_table[i].name[namelen]) {
#if LWIP_IPV4 && LWIP_IPV6
if (dns_table[i].reqaddrtype != dns_addrtype) {
/* requested address types don't match
@ -1473,7 +1497,6 @@ dns_enqueue(const char *name, size_t hostnamelen, dns_found_callback found,
LWIP_DNS_SET_ADDRTYPE(req->reqaddrtype, dns_addrtype);
req->found = found;
req->arg = callback_arg;
namelen = LWIP_MIN(hostnamelen, DNS_MAX_NAME_LENGTH - 1);
MEMCPY(entry->name, name, namelen);
entry->name[namelen] = 0;
@ -1563,6 +1586,9 @@ dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, dns_found_call
}
#endif
hostnamelen = strlen(hostname);
if (hostname[hostnamelen - 1] == '.') {
hostnamelen--;
}
if (hostnamelen >= DNS_MAX_NAME_LENGTH) {
LWIP_DEBUGF(DNS_DEBUG, ("dns_gethostbyname: name too long to resolve"));
return ERR_ARG;
@ -1587,7 +1613,7 @@ dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, dns_found_call
}
}
/* already have this address cached? */
if (dns_lookup(hostname, addr LWIP_DNS_ADDRTYPE_ARG(dns_addrtype)) == ERR_OK) {
if (dns_lookup(hostname, hostnamelen, addr LWIP_DNS_ADDRTYPE_ARG(dns_addrtype)) == ERR_OK) {
return ERR_OK;
}
#if LWIP_IPV4 && LWIP_IPV6
@ -1599,7 +1625,7 @@ dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, dns_found_call
} else {
fallback = LWIP_DNS_ADDRTYPE_IPV4;
}
if (dns_lookup(hostname, addr LWIP_DNS_ADDRTYPE_ARG(fallback)) == ERR_OK) {
if (dns_lookup(hostname, hostnamelen, addr LWIP_DNS_ADDRTYPE_ARG(fallback)) == ERR_OK) {
return ERR_OK;
}
}

View File

@ -1178,7 +1178,9 @@
* DNS_LOCAL_HOSTLIST_ELEM("host_ip6", IPADDR6_INIT_HOST(123, 234, 345, 456)}
*
* Instead, you can also use an external function:
* \#define DNS_LOOKUP_LOCAL_EXTERN(x) extern err_t my_lookup_function(const char *name, ip_addr_t *addr, u8_t dns_addrtype)
* \#define DNS_LOOKUP_LOCAL_EXTERN(name, namelen, addr, dns_addrtype) my_lookup_function(name, namelen, addr, dns_addrtype)
* with function signature:
* extern err_t my_lookup_function(const char *name, size_t namelen, ip_addr_t *addr, u8_t dns_addrtype)
* that looks up the IP address and returns ERR_OK if found (LWIP_DNS_ADDRTYPE_xxx is passed in dns_addrtype).
*/
#if !defined DNS_LOCAL_HOSTLIST || defined __DOXYGEN__