From e2cd201f6a368b83f3f9379eeda46db77e0cfc93 Mon Sep 17 00:00:00 2001 From: goldsimon Date: Fri, 16 Nov 2007 17:16:17 +0000 Subject: [PATCH] Added sequential dns resolver function for netconn api (netconn_gethostbyname) --- CHANGELOG | 4 +++ src/api/api_lib.c | 36 +++++++++++++++++++++++++ src/api/api_msg.c | 54 ++++++++++++++++++++++++++++++++++++++ src/include/lwip/api.h | 3 +++ src/include/lwip/api_msg.h | 15 +++++++++++ 5 files changed, 112 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index f7cdd1c2..ecde64ad 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,10 @@ HISTORY ++ New features: + 2007-11-16 Simon Goldschmidt + * api.h, api_msg.h, api_lib.c, api_msg.c: Added sequential dns resolver + function for netconn api (netconn_gethostbyname). + 2007-11-15 Jim Pettinato, Frédéric Bernon * opt.h, init.c, tcpip.c, dhcp.c, dns.h, dns.c: add DNS client for simple name requests with RAW api interface. Initialization is done in lwip_init() with diff --git a/src/api/api_lib.c b/src/api/api_lib.c index 4762c551..d24a793b 100644 --- a/src/api/api_lib.c +++ b/src/api/api_lib.c @@ -566,4 +566,40 @@ netconn_join_leave_group(struct netconn *conn, } #endif /* LWIP_IGMP */ +#if LWIP_DNS +/** + * Execute a DNS query, only one IP address is returned + * + * @param name a string representation of the DNS host name to query + * @param addr a preallocated struct ip_addr where to store the resolved IP address + * @return an error returned by the dns module, ERR_OK if resolving succeeded + */ +err_t +netconn_gethostbyname(const char *name, struct ip_addr *addr) +{ + struct dns_api_msg msg; + err_t err; + sys_sem_t sem; + + LWIP_ERROR("netconn_gethostbyname: invalid name", (name != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_gethostbyname: invalid addr", (addr != NULL), return ERR_ARG;); + + sem = sys_sem_new(0); + if (sem == SYS_SEM_NULL) { + return ERR_MEM; + } + + msg.name = name; + msg.addr = addr; + msg.err = &err; + msg.sem = sem; + + tcpip_callback(do_gethostbyname, &msg); + sys_sem_wait(sem); + sys_sem_free(sem); + + return err; +} +#endif /* LWIP_DNS*/ + #endif /* LWIP_NETCONN */ diff --git a/src/api/api_msg.c b/src/api/api_msg.c index 948937d6..2fa04d2e 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -50,6 +50,7 @@ #include "lwip/memp.h" #include "lwip/tcpip.h" #include "lwip/igmp.h" +#include "lwip/dns.h" /* forward declarations */ #if LWIP_TCP @@ -989,5 +990,58 @@ do_join_leave_group(struct api_msg_msg *msg) } #endif /* LWIP_IGMP */ +#if LWIP_DNS +/** + * Callback function that is called when DNS name is resolved + * (or on timeout). + */ +static void +do_dns_found(const char *name, struct ip_addr *ipaddr, void *arg) +{ + struct dns_api_msg *msg = (struct dns_api_msg*)arg; + + LWIP_ASSERT("DNS response for wrong host name", strcmp(msg->name, name) == 0); + + if (ipaddr == NULL) { + /* timeout or memory error */ + *msg->err = ERR_VAL; + } else { + /* address was resolved */ + *msg->err = ERR_OK; + *msg->addr = *ipaddr; + } + /* wake up the application task waiting in netconn_gethostbyname */ + sys_sem_signal(msg->sem); +} + +/** + * Execute a DNS query + * Called from netconn_gethostbyname + * + * @param msg the dns_api_msg pointing to the query + */ +void +do_gethostbyname(void *arg) +{ + DNS_RESULT res; + struct dns_api_msg *msg = (struct dns_api_msg*)arg; + + res = dns_gethostbyname(msg->name, msg->addr, do_dns_found, msg); + if (res != DNS_QUERY_QUEUED) { + /* If not queued, return to app thread directly */ + if (res == DNS_QUERY_INVALID) { + /* some error occurred */ + *msg->err = ERR_ARG; + } else if (res == DNS_COMPLETE) { + /* name was already in octet notation or cached */ + *msg->err = ERR_OK; + } + /* on error or immediate success, wake up the application + * task waiting in netconn_gethostbyname */ + sys_sem_signal(msg->sem); + } +} +#endif /* LWIP_DNS */ + #endif /* LWIP_NETCONN */ diff --git a/src/include/lwip/api.h b/src/include/lwip/api.h index b006859c..f384de47 100644 --- a/src/include/lwip/api.h +++ b/src/include/lwip/api.h @@ -181,6 +181,9 @@ err_t netconn_join_leave_group (struct netconn *conn, struct ip_addr *interface, enum netconn_igmp join_or_leave); #endif /* LWIP_IGMP */ +#if LWIP_DNS +err_t netconn_gethostbyname(const char *name, struct ip_addr *addr); +#endif /* LWIP_DNS */ #define netconn_err(conn) ((conn)->err) #define netconn_recv_bufsize(conn) ((conn)->recv_bufsize) diff --git a/src/include/lwip/api_msg.h b/src/include/lwip/api_msg.h index fc95f8ff..25a002d1 100644 --- a/src/include/lwip/api_msg.h +++ b/src/include/lwip/api_msg.h @@ -37,6 +37,8 @@ #if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ #include "lwip/ip_addr.h" +#include "lwip/err.h" +#include "lwip/sys.h" #ifdef __cplusplus extern "C" { @@ -86,6 +88,15 @@ struct api_msg { struct api_msg_msg msg; }; +#if LWIP_DNS +struct dns_api_msg { + const char *name; + struct ip_addr *addr; + sys_sem_t sem; + err_t *err; +}; +#endif /* LWIP_DNS */ + void do_newconn ( struct api_msg_msg *msg); void do_delconn ( struct api_msg_msg *msg); void do_bind ( struct api_msg_msg *msg); @@ -101,6 +112,10 @@ void do_close ( struct api_msg_msg *msg); void do_join_leave_group( struct api_msg_msg *msg); #endif /* LWIP_IGMP */ +#if LWIP_DNS +void do_gethostbyname(void *arg); +#endif /* LWIP_DNS */ + #ifdef __cplusplus } #endif