From 51e02176da8af853961264c82cbb9371efefc62b Mon Sep 17 00:00:00 2001 From: goldsimon Date: Tue, 21 Apr 2009 18:35:18 +0000 Subject: [PATCH] task #7507, patch #6786: DNS supports static hosts table. New configuration options DNS_LOCAL_HOSTLIST and DNS_LOCAL_HOSTLIST_IS_DYNAMIC. --- CHANGELOG | 5 ++ src/core/dns.c | 160 ++++++++++++++++++++++++++++++++++++++++- src/core/init.c | 3 + src/include/lwip/dns.h | 6 ++ src/include/lwip/opt.h | 18 ++++- 5 files changed, 188 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index edb3bc8a..c5cfbbd3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,11 @@ HISTORY ++ New features: + 2009-04-21 Simon Goldschmidt + * dns.c, init.c, dns.h, opt.h: task #7507, patch #6786: DNS supports static + hosts table. New configuration options DNS_LOCAL_HOSTLIST and + DNS_LOCAL_HOSTLIST_IS_DYNAMIC. + 2009-04-15 Simon Goldschmidt * dhcp.c: patch #6763: Global DHCP XID can be redefined to something more unique diff --git a/src/core/dns.c b/src/core/dns.c index ec39c75a..88897f87 100644 --- a/src/core/dns.c +++ b/src/core/dns.c @@ -193,6 +193,27 @@ struct dns_table_entry { void *arg; }; +#ifdef DNS_LOCAL_HOSTLIST +/** struct used for local host-list */ +struct local_hostlist_entry { + /** static hostname */ + const char *name; + /** static host address in network byteorder */ + u32_t addr; + struct local_hostlist_entry *next; +}; + +#if !DNS_LOCAL_HOSTLIST_IS_DYNAMIC +static struct local_hostlist_entry local_hostlist_static[] = DNS_LOCAL_HOSTLIST_INIT; +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +/** Local host-list. For hostnames in this list, no + * external name resolution is performed */ +static struct local_hostlist_entry *local_hostlist; + +static void dns_init_local(); +#endif /* DNS_LOCAL_HOSTLIST */ + /* forward declarations */ static void dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port); @@ -244,6 +265,9 @@ dns_init() dns_setserver(0, &dnsserver); } } +#if DNS_LOCAL_HOSTLIST + dns_init_local(); +#endif } /** @@ -291,6 +315,129 @@ dns_tmr(void) } } +#if DNS_LOCAL_HOSTLIST +static void +dns_init_local() +{ +#ifdef DNS_LOCAL_HOSTLIST_INIT + int i; + struct local_hostlist_entry *entry; +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC + /* Dynamic: copy entries from DNS_LOCAL_HOSTLIST_INIT to list */ + struct local_hostlist_entry local_hostlist_init[] = DNS_LOCAL_HOSTLIST_INIT; + for (i = 0; i < sizeof(local_hostlist_init) / sizeof(struct local_hostlist_entry); i++) { + entry = mem_malloc(sizeof(struct local_hostlist_entry)); + LWIP_ASSERT("mem-error in dns_init_local", entry != NULL); + if (entry != NULL) { + struct local_hostlist_entry *init_entry = &local_hostlist_init[i]; + entry->name = init_entry->name; + entry->addr = init_entry->addr; + entry->next = local_hostlist; + local_hostlist = entry; + } + } +#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + /* Static: only adjust the 'next' pointers */ + entry = NULL; + local_hostlist = local_hostlist_static; + for (i = sizeof(local_hostlist_static) / sizeof(struct local_hostlist_entry) - 1; i >= 0; i--) { + local_hostlist_static[i].next = entry; + entry = &local_hostlist_static[i]; + } +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ +#endif /* DNS_LOCAL_HOSTLIST_INIT */ +} + +static u32_t +dns_lookup_static(const char *name) +{ + struct local_hostlist_entry *entry = local_hostlist; + while(entry != NULL) { + if(strcmp(entry->name, name) == 0) { + return htons(entry->addr); + } + entry = entry->next; + } + return INADDR_NONE; +} + +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC +/** Remove all entries from the local host-list for a specific hostname + * + * @param hostname hostname for which entries shall be removed from the local + * host-list + * @return the number of removed entries + */ +int +dns_local_removehostname(const char *hostname) +{ + int removed = 0; + struct local_hostlist_entry *entry = local_hostlist; + struct local_hostlist_entry *last_entry = NULL; + while (entry != NULL) { + if (!strcmp(entry->name, hostname)) { + if (last_entry != NULL) { + last_entry->next = entry->next; + } else { + local_hostlist = entry->next; + } + mem_free(entry); + removed++; + } + last_entry = entry; + entry = entry->next; + } + return removed; +} + +/** Remove all entries from the local host-list for a specific address + * + * @param addr address for which entries shall be removed from the local + * host-list + * @return the number of removed entries + */ +int +dns_local_removehostaddr(const struct ip_addr *addr) +{ + int removed = 0; + struct local_hostlist_entry *entry = local_hostlist; + struct local_hostlist_entry *last_entry = NULL; + while (entry != NULL) { + if (entry->addr == addr->addr) { + struct local_hostlist_entry *removed_entry = entry; + if (last_entry != NULL) { + last_entry->next = entry->next; + } else { + local_hostlist = entry->next; + } + entry = entry->next; + mem_free(removed_entry); + removed++; + } else { + last_entry = entry; + entry = entry->next; + } + } + return removed; +} + +err_t +dns_local_addhost(const char *hostname, const struct ip_addr *addr) +{ + struct local_hostlist_entry *entry; + entry = mem_malloc(sizeof(struct local_hostlist_entry)); + if (entry == NULL) { + return ERR_MEM; + } + entry->name = hostname; + entry->addr = addr->addr; + entry->next = local_hostlist; + local_hostlist = entry; + return ERR_OK; +} +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC*/ +#endif /* DNS_LOCAL_HOSTLIST */ + /** * Look up a hostname in the array of known hostnames. * @@ -301,13 +448,20 @@ dns_tmr(void) * * @param name the hostname to look up * @return the hostname's IP address, as u32_t (instead of struct ip_addr to - * better check for failure: != 0) or 0 if the hostname was not found - * in the cached dns_table. + * better check for failure: != INADDR_NONE) or INADDR_NONE if the hostname + * was not found in the cached dns_table. */ static u32_t dns_lookup(const char *name) { u8_t i; + u32_t addr; + +#if DNS_LOCAL_HOSTLIST + if ((addr = dns_lookup_static(name)) != INADDR_NONE) { + return addr; + } +#endif /* DNS_LOCAL_HOSTLIST */ /* Walk through name list, return entry if found. If not, return NULL. */ for (i = 0; i < DNS_TABLE_SIZE; ++i) { @@ -806,7 +960,7 @@ dns_gethostbyname(const char *hostname, struct ip_addr *addr, dns_found_callback /* host name already in octet notation? set ip addr and return ERR_OK * already have this address cached? */ if (((addr->addr = inet_addr(hostname)) != INADDR_NONE) || - ((addr->addr = dns_lookup(hostname)) != 0)) { + ((addr->addr = dns_lookup(hostname)) != INADDR_NONE)) { return ERR_OK; } diff --git a/src/core/init.c b/src/core/init.c index ae7698b2..2dcfbdfc 100644 --- a/src/core/init.c +++ b/src/core/init.c @@ -161,6 +161,9 @@ #if (TCP_QUEUE_OOSEQ && !LWIP_TCP) #error "TCP_QUEUE_OOSEQ requires LWIP_TCP" #endif +#if (DNS_LOCAL_HOSTLIST && !(defined(DNS_LOCAL_HOSTLIST_INIT))) + #error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST" +#endif /* Compile-time checks for deprecated options. diff --git a/src/include/lwip/dns.h b/src/include/lwip/dns.h index 61967429..91c84fa8 100644 --- a/src/include/lwip/dns.h +++ b/src/include/lwip/dns.h @@ -87,6 +87,12 @@ struct ip_addr dns_getserver(u8_t numdns); err_t dns_gethostbyname(const char *hostname, struct ip_addr *addr, dns_found_callback found, void *callback_arg); +#if DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC +int dns_local_removehostname(const char *hostname); +int dns_local_removehostaddr(const struct ip_addr *addr); +err_t dns_local_addhost(const char *hostname, const struct ip_addr *addr); +#endif /* DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + #endif /* LWIP_DNS */ #endif /* __LWIP_DNS_H__ */ diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 08f8bb8d..984d0235 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -148,7 +148,7 @@ /** * MEM_USE_POOLS==1: Use an alternative to malloc() by allocating from a set * of memory pools of various sizes. When mem_malloc is called, an element of - * the smallest pool that can provide the lenght needed is returned. + * the smallest pool that can provide the length needed is returned. */ #ifndef MEM_USE_POOLS #define MEM_USE_POOLS 0 @@ -635,6 +635,22 @@ #define DNS_MSG_SIZE 512 #endif +/** DNS_LOCAL_HOSTLIST: Implements a local host-to-address list. If enabled, + * you have to define + * #define DNS_LOCAL_HOSTLIST_INIT {{"host1", 0x123}, {"host2", 0x234}} + * (an array of structs name/address, where address is an u32_t in network + * byte order). + */ +#ifndef DNS_LOCAL_HOSTLIST +#define DNS_LOCAL_HOSTLIST 0 +#endif /* DNS_LOCAL_HOSTLIST */ + +/** If this is turned on, the local host-list can be dynamically changed + * at runtime. */ +#ifndef DNS_LOCAL_HOSTLIST_IS_DYNAMIC +#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0 +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + /* --------------------------------- ---------- UDP options ----------