blob: e25c993d667a0fd0ffe5b3e9afa31e271b674099 [file] [log] [blame]
adamdunkels1e45c6d2003-09-02 21:47:27 +00001/**
adamdunkels0170b082003-10-01 11:25:37 +00002 * \addtogroup uip
3 * @{
4 */
5
6/**
7 * \defgroup uipdns uIP hostname resolver functions
8 * @{
9 *
10 * The uIP DNS resolver functions are used to lookup a hostname and
11 * map it to a numerical IP address. It maintains a list of resolved
12 * hostnames that can be queried with the resolv_lookup()
13 * function. New hostnames can be resolved using the resolv_query()
14 * function.
adamdunkels1e45c6d2003-09-02 21:47:27 +000015 *
16 * The signal resolv_signal_found is emitted when a hostname has been
17 * resolved. The signal is emitted to all processes listening for the
18 * signal, and it is up to the receiving process to determine if the
19 * correct hostname has been found by calling the resolv_lookup()
20 * function with the hostname.
21 */
22
adamdunkels0170b082003-10-01 11:25:37 +000023/**
24 * \file
25 * DNS host name to IP address resolver.
26 * \author Adam Dunkels <adam@dunkels.com>
27 *
28 * This file implements a DNS host name to IP address resolver.
29 */
30
adamdunkelsca9ddcb2003-03-19 14:13:31 +000031/*
adamdunkels1e45c6d2003-09-02 21:47:27 +000032 * Copyright (c) 2002-2003, Adam Dunkels.
adamdunkelsca9ddcb2003-03-19 14:13:31 +000033 * All rights reserved.
34 *
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
37 * are met:
38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
adamdunkels1e45c6d2003-09-02 21:47:27 +000043 * 3. The name of the author may not be used to endorse or promote
adamdunkelsca9ddcb2003-03-19 14:13:31 +000044 * products derived from this software without specific prior
45 * written permission.
46 *
47 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
48 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
51 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
53 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
54 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
55 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
56 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
57 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58 *
59 * This file is part of the uIP TCP/IP stack.
60 *
adamdunkels01385782003-11-27 15:53:48 +000061 * $Id: resolv.c,v 1.10 2003/11/27 15:53:48 adamdunkels Exp $
adamdunkelsca9ddcb2003-03-19 14:13:31 +000062 *
63 */
64
65#include "resolv.h"
66#include "dispatcher.h"
adamdunkelsbb2e93c2003-09-04 19:38:46 +000067#include "uip-signal.h"
adamdunkelsca9ddcb2003-03-19 14:13:31 +000068
69#ifndef NULL
70#define NULL (void *)0
71#endif /* NULL */
72
adamdunkels1e45c6d2003-09-02 21:47:27 +000073/** \internal The maximum number of retries when asking for a name. */
adamdunkelsca9ddcb2003-03-19 14:13:31 +000074#define MAX_RETRIES 8
75
adamdunkels1e45c6d2003-09-02 21:47:27 +000076/** \internal The DNS message header. */
adamdunkelsca9ddcb2003-03-19 14:13:31 +000077struct dns_hdr {
78 u16_t id;
79 u8_t flags1, flags2;
80#define DNS_FLAG1_RESPONSE 0x80
81#define DNS_FLAG1_OPCODE_STATUS 0x10
82#define DNS_FLAG1_OPCODE_INVERSE 0x08
83#define DNS_FLAG1_OPCODE_STANDARD 0x00
84#define DNS_FLAG1_AUTHORATIVE 0x04
85#define DNS_FLAG1_TRUNC 0x02
86#define DNS_FLAG1_RD 0x01
87#define DNS_FLAG2_RA 0x80
88#define DNS_FLAG2_ERR_MASK 0x0f
89#define DNS_FLAG2_ERR_NONE 0x00
90#define DNS_FLAG2_ERR_NAME 0x03
91 u16_t numquestions;
92 u16_t numanswers;
93 u16_t numauthrr;
94 u16_t numextrarr;
95};
96
adamdunkels1e45c6d2003-09-02 21:47:27 +000097/** \internal The DNS answer message structure. */
adamdunkelsca9ddcb2003-03-19 14:13:31 +000098struct dns_answer {
99 /* DNS answer record starts with either a domain name or a pointer
100 to a name already present somewhere in the packet. */
101 u16_t type;
102 u16_t class;
103 u16_t ttl[2];
104 u16_t len;
105 u16_t ipaddr[2];
106};
107
adamdunkels1e45c6d2003-09-02 21:47:27 +0000108struct namemap {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000109#define STATE_UNUSED 0
110#define STATE_NEW 1
111#define STATE_ASKING 2
112#define STATE_DONE 3
113#define STATE_ERROR 4
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000114 u8_t state;
115 u8_t tmr;
116 u8_t retries;
117 u8_t seqno;
118 u8_t err;
adamdunkels1d31c322003-08-24 22:40:32 +0000119 char name[32];
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000120 u16_t ipaddr[2];
121};
122
adamdunkelsbb2e93c2003-09-04 19:38:46 +0000123#ifndef UIP_CONF_RESOLV_ENTRIES
adamdunkels99dcf452003-08-15 18:50:36 +0000124#define RESOLV_ENTRIES 4
adamdunkelsbb2e93c2003-09-04 19:38:46 +0000125#else /* UIP_CONF_RESOLV_ENTRIES */
126#define RESOLV_ENTRIES UIP_CONF_RESOLV_ENTRIES
127#endif /* UIP_CONF_RESOLV_ENTRIES */
128
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000129
130static struct namemap names[RESOLV_ENTRIES];
131
132static u8_t seqno;
133
134static struct uip_udp_conn *resolv_conn = NULL;
135
adamdunkels0170b082003-10-01 11:25:37 +0000136ek_signal_t resolv_signal_found;
137
adamdunkels01385782003-11-27 15:53:48 +0000138static DISPATCHER_UIPCALL(udp_appcall, arg);
139static struct dispatcher_proc p =
140 {DISPATCHER_PROC("DNS resolver", NULL, NULL, udp_appcall)};
141static ek_id_t id = EK_ID_NONE;
142
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000143
144/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000145/** \internal
146 * Walk through a compact encoded DNS name and return the end of it.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000147 *
adamdunkels1e45c6d2003-09-02 21:47:27 +0000148 * \return The end of the name.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000149 */
adamdunkels1e45c6d2003-09-02 21:47:27 +0000150/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000151static unsigned char *
152parse_name(unsigned char *query)
153{
154 unsigned char n;
155
156 do {
157 n = *query++;
158
159 while(n > 0) {
160 /* printf("%c", *query);*/
161 ++query;
162 --n;
163 };
164 /* printf(".");*/
165 } while(*query != 0);
166 /* printf("\n");*/
167 return query + 1;
168}
169/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000170/** \internal
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000171 * Runs through the list of names to see if there are any that have
adamdunkels1e45c6d2003-09-02 21:47:27 +0000172 * not yet been queried and, if so, sends out a query.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000173 */
adamdunkels1e45c6d2003-09-02 21:47:27 +0000174/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000175static void
176check_entries(void)
177{
adamdunkels23664022003-08-05 13:51:50 +0000178 register struct dns_hdr *hdr;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000179 char *query, *nptr, *nameptr;
adamdunkels99dcf452003-08-15 18:50:36 +0000180 static u8_t i;
181 static u8_t n;
adamdunkels23664022003-08-05 13:51:50 +0000182 register struct namemap *namemapptr;
183
adamdunkels01385782003-11-27 15:53:48 +0000184 for(i = 0; i < RESOLV_ENTRIES; ++i) {
adamdunkels23664022003-08-05 13:51:50 +0000185 namemapptr = &names[i];
186 if(namemapptr->state == STATE_NEW ||
187 namemapptr->state == STATE_ASKING) {
188 if(namemapptr->state == STATE_ASKING) {
189 if(--namemapptr->tmr == 0) {
190 if(++namemapptr->retries == MAX_RETRIES) {
191 namemapptr->state = STATE_ERROR;
192 resolv_found(namemapptr->name, NULL);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000193 continue;
194 }
adamdunkels23664022003-08-05 13:51:50 +0000195 namemapptr->tmr = namemapptr->retries;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000196 } else {
adamdunkels23664022003-08-05 13:51:50 +0000197 /* printf("Timer %d\n", namemapptr->tmr);*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000198 /* Its timer has not run out, so we move on to next
199 entry. */
200 continue;
201 }
202 } else {
adamdunkels23664022003-08-05 13:51:50 +0000203 namemapptr->state = STATE_ASKING;
204 namemapptr->tmr = 1;
205 namemapptr->retries = 0;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000206 }
207 hdr = (struct dns_hdr *)uip_appdata;
adamdunkels99dcf452003-08-15 18:50:36 +0000208 memset(hdr, 0, sizeof(struct dns_hdr));
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000209 hdr->id = htons(i);
210 hdr->flags1 = DNS_FLAG1_RD;
adamdunkels47ec7fa2003-03-28 12:11:17 +0000211 hdr->numquestions = HTONS(1);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000212 query = (char *)uip_appdata + 12;
adamdunkels23664022003-08-05 13:51:50 +0000213 nameptr = namemapptr->name;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000214 --nameptr;
215 /* Convert hostname into suitable query format. */
216 do {
217 ++nameptr;
218 nptr = query;
219 ++query;
220 for(n = 0; *nameptr != '.' && *nameptr != 0; ++nameptr) {
221 *query = *nameptr;
222 ++query;
223 ++n;
224 }
225 *nptr = n;
226 } while(*nameptr != 0);
adamdunkels23664022003-08-05 13:51:50 +0000227 {
228 static unsigned char endquery[] =
229 {0,0,1,0,1};
230 memcpy(query, endquery, 5);
231 }
adamdunkels23664022003-08-05 13:51:50 +0000232 uip_udp_send((unsigned char)(query + 5 - (char *)uip_appdata));
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000233 break;
234 }
235 }
236}
237/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000238/** \internal
239 * Called when new UDP data arrives.
240 */
241/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000242static void
243newdata(void)
244{
245 char *nameptr;
246 struct dns_answer *ans;
247 struct dns_hdr *hdr;
adamdunkels99dcf452003-08-15 18:50:36 +0000248 static u8_t nquestions, nanswers;
249 static u8_t i;
adamdunkels23664022003-08-05 13:51:50 +0000250 register struct namemap *namemapptr;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000251
252 hdr = (struct dns_hdr *)uip_appdata;
253 /* printf("ID %d\n", htons(hdr->id));
254 printf("Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE);
255 printf("Error %d\n", hdr->flags2 & DNS_FLAG2_ERR_MASK);
256 printf("Num questions %d, answers %d, authrr %d, extrarr %d\n",
257 htons(hdr->numquestions),
258 htons(hdr->numanswers),
259 htons(hdr->numauthrr),
260 htons(hdr->numextrarr));
261 */
262
263 /* The ID in the DNS header should be our entry into the name
264 table. */
adamdunkels23664022003-08-05 13:51:50 +0000265 i = htons(hdr->id);
266 namemapptr = &names[i];
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000267 if(i < RESOLV_ENTRIES &&
adamdunkels23664022003-08-05 13:51:50 +0000268 namemapptr->state == STATE_ASKING) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000269
270 /* This entry is now finished. */
adamdunkels23664022003-08-05 13:51:50 +0000271 namemapptr->state = STATE_DONE;
272 namemapptr->err = hdr->flags2 & DNS_FLAG2_ERR_MASK;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000273
274 /* Check for error. If so, call callback to inform. */
adamdunkels23664022003-08-05 13:51:50 +0000275 if(namemapptr->err != 0) {
276 namemapptr->state = STATE_ERROR;
277 resolv_found(namemapptr->name, NULL);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000278 return;
279 }
280
281 /* We only care about the question(s) and the answers. The authrr
282 and the extrarr are simply discarded. */
283 nquestions = htons(hdr->numquestions);
284 nanswers = htons(hdr->numanswers);
285
286 /* Skip the name in the question. XXX: This should really be
287 checked agains the name in the question, to be sure that they
288 match. */
289 nameptr = parse_name((char *)uip_appdata + 12) + 4;
290
291 while(nanswers > 0) {
292 /* The first byte in the answer resource record determines if it
293 is a compressed record or a normal one. */
294 if(*nameptr & 0xc0) {
295 /* Compressed name. */
296 nameptr +=2;
297 /* printf("Compressed anwser\n");*/
298 } else {
299 /* Not compressed name. */
300 nameptr = parse_name((char *)nameptr);
301 }
302
303 ans = (struct dns_answer *)nameptr;
304 /* printf("Answer: type %x, class %x, ttl %x, length %x\n",
adamdunkels99dcf452003-08-15 18:50:36 +0000305 htons(ans->type), htons(ans->class), (htons(ans->ttl[0])
306 << 16) | htons(ans->ttl[1]), htons(ans->len));*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000307
308 /* Check for IP address type and Internet class. Others are
309 discarded. */
adamdunkels47ec7fa2003-03-28 12:11:17 +0000310 if(ans->type == HTONS(1) &&
311 ans->class == HTONS(1) &&
312 ans->len == HTONS(4)) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000313 /* printf("IP address %d.%d.%d.%d\n",
314 htons(ans->ipaddr[0]) >> 8,
315 htons(ans->ipaddr[0]) & 0xff,
316 htons(ans->ipaddr[1]) >> 8,
317 htons(ans->ipaddr[1]) & 0xff);*/
318 /* XXX: we should really check that this IP address is the one
319 we want. */
adamdunkels23664022003-08-05 13:51:50 +0000320 namemapptr->ipaddr[0] = ans->ipaddr[0];
321 namemapptr->ipaddr[1] = ans->ipaddr[1];
adamdunkels99dcf452003-08-15 18:50:36 +0000322
adamdunkels23664022003-08-05 13:51:50 +0000323 resolv_found(namemapptr->name, namemapptr->ipaddr);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000324 return;
325 } else {
326 nameptr = nameptr + 10 + htons(ans->len);
327 }
328 --nanswers;
329 }
330 }
331
332}
333/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000334/** \internal
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000335 * The main UDP function.
336 */
adamdunkels1e45c6d2003-09-02 21:47:27 +0000337/*-----------------------------------------------------------------------------------*/
adamdunkels01385782003-11-27 15:53:48 +0000338static void
339udp_appcall(void *arg)
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000340{
adamdunkels47ec7fa2003-03-28 12:11:17 +0000341 if(uip_udp_conn->rport == HTONS(53)) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000342 if(uip_poll()) {
343 check_entries();
344 }
345 if(uip_newdata()) {
346 newdata();
347 }
348 }
349}
350/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000351/**
352 * Queues a name so that a question for the name will be sent out.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000353 *
adamdunkels1e45c6d2003-09-02 21:47:27 +0000354 * \param name The hostname that is to be queried.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000355 */
adamdunkels1e45c6d2003-09-02 21:47:27 +0000356/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000357void
358resolv_query(char *name)
359{
adamdunkels99dcf452003-08-15 18:50:36 +0000360 static u8_t i;
361 static u8_t lseq, lseqi;
adamdunkels23664022003-08-05 13:51:50 +0000362 register struct namemap *nameptr;
363
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000364 lseq = lseqi = 0;
365
366 for(i = 0; i < RESOLV_ENTRIES; ++i) {
adamdunkels23664022003-08-05 13:51:50 +0000367 nameptr = &names[i];
368 if(nameptr->state == STATE_UNUSED) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000369 break;
370 }
adamdunkels23664022003-08-05 13:51:50 +0000371 if(seqno - nameptr->seqno > lseq) {
372 lseq = seqno - nameptr->seqno;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000373 lseqi = i;
374 }
375 }
376
377 if(i == RESOLV_ENTRIES) {
378 i = lseqi;
adamdunkels23664022003-08-05 13:51:50 +0000379 nameptr = &names[i];
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000380 }
381
adamdunkels01385782003-11-27 15:53:48 +0000382 strncpy(nameptr->name, name, sizeof(nameptr->name));
adamdunkels23664022003-08-05 13:51:50 +0000383 nameptr->state = STATE_NEW;
384 nameptr->seqno = seqno;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000385 ++seqno;
386
adamdunkels1e45c6d2003-09-02 21:47:27 +0000387 if(resolv_conn != NULL) {
adamdunkelsbb2e93c2003-09-04 19:38:46 +0000388 dispatcher_emit(uip_signal_poll_udp, resolv_conn, DISPATCHER_BROADCAST);
adamdunkels1e45c6d2003-09-02 21:47:27 +0000389 }
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000390}
391/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000392/**
393 * Look up a hostname in the array of known hostnames.
394 *
395 * \note This function only looks in the internal array of known
396 * hostnames, it does not send out a query for the hostname if none
397 * was found. The function resolv_query() can be used to send a query
398 * for a hostname.
399 *
400 * \return A pointer to a 4-byte representation of the hostname's IP
401 * address, or NULL if the hostname was not found in the array of
402 * hostnames.
403 */
404/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000405u16_t *
406resolv_lookup(char *name)
407{
adamdunkels99dcf452003-08-15 18:50:36 +0000408 static u8_t i;
adamdunkels23664022003-08-05 13:51:50 +0000409 struct namemap *nameptr;
410
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000411 /* Walk through the list to see if the name is in there. If it is
412 not, we return NULL. */
413 for(i = 0; i < RESOLV_ENTRIES; ++i) {
adamdunkels23664022003-08-05 13:51:50 +0000414 nameptr = &names[i];
415 if(nameptr->state == STATE_DONE &&
adamdunkels99dcf452003-08-15 18:50:36 +0000416 strcmp(name, nameptr->name) == 0) {
adamdunkels23664022003-08-05 13:51:50 +0000417 return nameptr->ipaddr;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000418 }
419 }
420 return NULL;
421}
422/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000423/**
424 * Obtain the currently configured DNS server.
425 *
426 * \return A pointer to a 4-byte representation of the IP address of
427 * the currently configured DNS server or NULL if no DNS server has
428 * been configured.
429 */
430/*-----------------------------------------------------------------------------------*/
adamdunkels66c6af62003-04-16 18:28:16 +0000431u16_t *
432resolv_getserver(void)
433{
434 if(resolv_conn == NULL) {
435 return NULL;
436 }
437 return resolv_conn->ripaddr;
438}
439/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000440/**
441 * Configure a DNS server.
442 *
443 * \param dnsserver A pointer to a 4-byte representation of the IP
444 * address of the DNS server to be configured.
445 */
446/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000447void
448resolv_conf(u16_t *dnsserver)
449{
450 if(resolv_conn != NULL) {
451 uip_udp_remove(resolv_conn);
452 }
453
adamdunkels01385782003-11-27 15:53:48 +0000454 resolv_conn = dispatcher_udp_new(dnsserver, 53, NULL);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000455}
456/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000457/**
458 * Initalize the resolver.
459 */
460/*-----------------------------------------------------------------------------------*/
adamdunkels01385782003-11-27 15:53:48 +0000461LOADER_INIT_FUNC(resolv_init, arg)
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000462{
adamdunkels01385782003-11-27 15:53:48 +0000463 static u8_t i;
464 arg_free(arg);
adamdunkels99dcf452003-08-15 18:50:36 +0000465
adamdunkels01385782003-11-27 15:53:48 +0000466 if(id == EK_ID_NONE) {
467 id = dispatcher_start(&p);
468
469 for(i = 0; i < RESOLV_ENTRIES; ++i) {
470 names[i].state = STATE_UNUSED;
471 }
472
473 resolv_signal_found = dispatcher_sigalloc();
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000474 }
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000475}
476/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000477/** \internal
478 * Callback function which is called when a hostname is found.
479 *
480 */
481/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000482void
483resolv_found(char *name, u16_t *ipaddr)
484{
485 dispatcher_emit(resolv_signal_found, name, DISPATCHER_BROADCAST);
486}
adamdunkels66c6af62003-04-16 18:28:16 +0000487/*-----------------------------------------------------------------------------------*/
adamdunkels0170b082003-10-01 11:25:37 +0000488
489/** @} */
490/** @} */