diff --git a/src/core/dns.c b/src/core/dns.c index 9d2f61ed..121ea12b 100644 --- a/src/core/dns.c +++ b/src/core/dns.c @@ -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; } } diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index d39ed50f..da586c2a 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -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__