aboutsummaryrefslogtreecommitdiff
path: root/src/util/gnunet-service-resolver.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-09-19 13:26:44 +0000
committerChristian Grothoff <christian@grothoff.org>2016-09-19 13:26:44 +0000
commit64fda257bdaf166ed3d96dce3a01ea14017a2a3e (patch)
treee33c077dcb46d06755fb4d0b37f829d7f6a0731e /src/util/gnunet-service-resolver.c
parent08f1726b6552ac29830637e9f7be4d42e2ea4294 (diff)
downloadgnunet-64fda257bdaf166ed3d96dce3a01ea14017a2a3e.tar.gz
gnunet-64fda257bdaf166ed3d96dce3a01ea14017a2a3e.zip
misc minor fixes for new service MQ API, implementing resolver using new service API
Diffstat (limited to 'src/util/gnunet-service-resolver.c')
-rw-r--r--src/util/gnunet-service-resolver.c410
1 files changed, 266 insertions, 144 deletions
diff --git a/src/util/gnunet-service-resolver.c b/src/util/gnunet-service-resolver.c
index a87b1f5d0..12e484845 100644
--- a/src/util/gnunet-service-resolver.c
+++ b/src/util/gnunet-service-resolver.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2007-2013 GNUnet e.V. 3 Copyright (C) 2007-2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -197,6 +197,22 @@ cache_resolve (struct IPCache *cache)
197 197
198 198
199/** 199/**
200 * Function called after the replies for the request have all
201 * been transmitted to the client, and we can now read the next
202 * request from the client.
203 *
204 * @param cls the `struct GNUNET_SERVICE_Client` to continue with
205 */
206static void
207notify_service_client_done (void *cls)
208{
209 struct GNUNET_SERVICE_Client *client = cls;
210
211 GNUNET_SERVICE_client_continue (client);
212}
213
214
215/**
200 * Get an IP address as a string (works for both IPv4 and IPv6). Note 216 * Get an IP address as a string (works for both IPv4 and IPv6). Note
201 * that the resolution happens asynchronously and that the first call 217 * that the resolution happens asynchronously and that the first call
202 * may not immediately result in the FQN (but instead in a 218 * may not immediately result in the FQN (but instead in a
@@ -207,16 +223,19 @@ cache_resolve (struct IPCache *cache)
207 * @param ip `struct in_addr` or `struct in6_addr` 223 * @param ip `struct in_addr` or `struct in6_addr`
208 */ 224 */
209static void 225static void
210get_ip_as_string (struct GNUNET_SERVER_Client *client, 226get_ip_as_string (struct GNUNET_SERVICE_Client *client,
211 int af, 227 int af,
212 const void *ip) 228 const void *ip)
213{ 229{
214 struct IPCache *pos; 230 struct IPCache *pos;
215 struct IPCache *next; 231 struct IPCache *next;
216 struct GNUNET_TIME_Absolute now; 232 struct GNUNET_TIME_Absolute now;
217 struct GNUNET_SERVER_TransmitContext *tc; 233 struct GNUNET_MQ_Envelope *env;
234 struct GNUNET_MQ_Handle *mq;
235 struct GNUNET_MessageHeader *msg;
218 size_t ip_len; 236 size_t ip_len;
219 struct in6_addr ix; 237 struct in6_addr ix;
238 size_t alen;
220 239
221 switch (af) 240 switch (af)
222 { 241 {
@@ -267,7 +286,9 @@ get_ip_as_string (struct GNUNET_SERVER_Client *client,
267 { 286 {
268 pos = GNUNET_malloc (sizeof (struct IPCache) + ip_len); 287 pos = GNUNET_malloc (sizeof (struct IPCache) + ip_len);
269 pos->ip = &pos[1]; 288 pos->ip = &pos[1];
270 GNUNET_memcpy (&pos[1], ip, ip_len); 289 GNUNET_memcpy (&pos[1],
290 ip,
291 ip_len);
271 pos->last_request = now; 292 pos->last_request = now;
272 pos->last_refresh = now; 293 pos->last_refresh = now;
273 pos->ip_len = ip_len; 294 pos->ip_len = ip_len;
@@ -277,29 +298,41 @@ get_ip_as_string (struct GNUNET_SERVER_Client *client,
277 pos); 298 pos);
278 cache_resolve (pos); 299 cache_resolve (pos);
279 } 300 }
280 tc = GNUNET_SERVER_transmit_context_create (client);
281 if (NULL != pos->addr) 301 if (NULL != pos->addr)
282 GNUNET_SERVER_transmit_context_append_data (tc, pos->addr, 302 alen = strlen (pos->addr) + 1;
283 strlen (pos->addr) + 1,
284 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
285 else 303 else
286 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 304 alen = 0;
287 "Reverse lookup failed\n"); 305 mq = GNUNET_SERVICE_client_get_mq (client);
288 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, 306 env = GNUNET_MQ_msg_extra (msg,
289 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); 307 alen,
290 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); 308 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
309 GNUNET_memcpy (&msg[1],
310 pos->addr,
311 alen);
312 GNUNET_MQ_send (mq,
313 env);
314 env = GNUNET_MQ_msg (msg,
315 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
316 GNUNET_MQ_notify_sent (env,
317 &notify_service_client_done,
318 client);
319 GNUNET_MQ_send (mq,
320 env);
291} 321}
292 322
293 323
294#if HAVE_GETADDRINFO 324#if HAVE_GETADDRINFO
295static int 325static int
296getaddrinfo_resolve (struct GNUNET_SERVER_TransmitContext *tc, 326getaddrinfo_resolve (struct GNUNET_MQ_Handle *mq,
297 const char *hostname, int af) 327 const char *hostname,
328 int af)
298{ 329{
299 int s; 330 int s;
300 struct addrinfo hints; 331 struct addrinfo hints;
301 struct addrinfo *result; 332 struct addrinfo *result;
302 struct addrinfo *pos; 333 struct addrinfo *pos;
334 struct GNUNET_MessageHeader *msg;
335 struct GNUNET_MQ_Envelope *env;
303 336
304#ifdef WINDOWS 337#ifdef WINDOWS
305 /* Due to a bug, getaddrinfo will not return a mix of different families */ 338 /* Due to a bug, getaddrinfo will not return a mix of different families */
@@ -307,21 +340,32 @@ getaddrinfo_resolve (struct GNUNET_SERVER_TransmitContext *tc,
307 { 340 {
308 int ret1; 341 int ret1;
309 int ret2; 342 int ret2;
310 ret1 = getaddrinfo_resolve (tc, hostname, AF_INET); 343 ret1 = getaddrinfo_resolve (mq,
311 ret2 = getaddrinfo_resolve (tc, hostname, AF_INET6); 344 hostname,
312 if ((ret1 == GNUNET_OK) || (ret2 == GNUNET_OK)) 345 AF_INET);
346 ret2 = getaddrinfo_resolve (mq,
347 hostname,
348 AF_INET6);
349 if ( (ret1 == GNUNET_OK) ||
350 (ret2 == GNUNET_OK) )
313 return GNUNET_OK; 351 return GNUNET_OK;
314 if ((ret1 == GNUNET_SYSERR) || (ret2 == GNUNET_SYSERR)) 352 if ( (ret1 == GNUNET_SYSERR) ||
353 (ret2 == GNUNET_SYSERR) )
315 return GNUNET_SYSERR; 354 return GNUNET_SYSERR;
316 return GNUNET_NO; 355 return GNUNET_NO;
317 } 356 }
318#endif 357#endif
319 358
320 memset (&hints, 0, sizeof (struct addrinfo)); 359 memset (&hints,
360 0,
361 sizeof (struct addrinfo));
321 hints.ai_family = af; 362 hints.ai_family = af;
322 hints.ai_socktype = SOCK_STREAM; /* go for TCP */ 363 hints.ai_socktype = SOCK_STREAM; /* go for TCP */
323 364
324 if (0 != (s = getaddrinfo (hostname, NULL, &hints, &result))) 365 if (0 != (s = getaddrinfo (hostname,
366 NULL,
367 &hints,
368 &result)))
325 { 369 {
326 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 370 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
327 _("Could not resolve `%s' (%s): %s\n"), 371 _("Could not resolve `%s' (%s): %s\n"),
@@ -329,13 +373,11 @@ getaddrinfo_resolve (struct GNUNET_SERVER_TransmitContext *tc,
329 (af == 373 (af ==
330 AF_INET) ? "IPv4" : ((af == AF_INET6) ? "IPv6" : "any"), 374 AF_INET) ? "IPv4" : ((af == AF_INET6) ? "IPv6" : "any"),
331 gai_strerror (s)); 375 gai_strerror (s));
332 if ((s == EAI_BADFLAGS) || (s == EAI_MEMORY) 376 if ( (s == EAI_BADFLAGS) ||
333#ifndef WINDOWS 377#ifndef WINDOWS
334 || (s == EAI_SYSTEM) 378 (s == EAI_SYSTEM) ||
335#else
336 || 1
337#endif 379#endif
338 ) 380 (s == EAI_MEMORY) )
339 return GNUNET_NO; /* other function may still succeed */ 381 return GNUNET_NO; /* other function may still succeed */
340 return GNUNET_SYSERR; 382 return GNUNET_SYSERR;
341 } 383 }
@@ -346,16 +388,24 @@ getaddrinfo_resolve (struct GNUNET_SERVER_TransmitContext *tc,
346 switch (pos->ai_family) 388 switch (pos->ai_family)
347 { 389 {
348 case AF_INET: 390 case AF_INET:
349 GNUNET_SERVER_transmit_context_append_data (tc, 391 env = GNUNET_MQ_msg_extra (msg,
350 &((struct sockaddr_in*) pos->ai_addr)->sin_addr, 392 sizeof (struct in_addr),
351 sizeof (struct in_addr), 393 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
352 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); 394 GNUNET_memcpy (&msg[1],
395 &((struct sockaddr_in*) pos->ai_addr)->sin_addr,
396 sizeof (struct in_addr));
397 GNUNET_MQ_send (mq,
398 env);
353 break; 399 break;
354 case AF_INET6: 400 case AF_INET6:
355 GNUNET_SERVER_transmit_context_append_data (tc, 401 env = GNUNET_MQ_msg_extra (msg,
356 &((struct sockaddr_in6*) pos->ai_addr)->sin6_addr, 402 sizeof (struct in6_addr),
357 sizeof (struct in6_addr), 403 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
358 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); 404 GNUNET_memcpy (&msg[1],
405 &((struct sockaddr_in6*) pos->ai_addr)->sin6_addr,
406 sizeof (struct in6_addr));
407 GNUNET_MQ_send (mq,
408 env);
359 break; 409 break;
360 default: 410 default:
361 /* unsupported, skip */ 411 /* unsupported, skip */
@@ -371,13 +421,15 @@ getaddrinfo_resolve (struct GNUNET_SERVER_TransmitContext *tc,
371 421
372 422
373static int 423static int
374gethostbyname2_resolve (struct GNUNET_SERVER_TransmitContext *tc, 424gethostbyname2_resolve (struct GNUNET_MQ_Handle *mq,
375 const char *hostname, 425 const char *hostname,
376 int af) 426 int af)
377{ 427{
378 struct hostent *hp; 428 struct hostent *hp;
379 int ret1; 429 int ret1;
380 int ret2; 430 int ret2;
431 struct GNUNET_MQ_Envelope *env;
432 struct GNUNET_MessageHeader *msg;
381 433
382#ifdef WINDOWS 434#ifdef WINDOWS
383 /* gethostbyname2() in plibc is a compat dummy that calls gethostbyname(). */ 435 /* gethostbyname2() in plibc is a compat dummy that calls gethostbyname(). */
@@ -386,19 +438,27 @@ gethostbyname2_resolve (struct GNUNET_SERVER_TransmitContext *tc,
386 438
387 if (af == AF_UNSPEC) 439 if (af == AF_UNSPEC)
388 { 440 {
389 ret1 = gethostbyname2_resolve (tc, hostname, AF_INET); 441 ret1 = gethostbyname2_resolve (mq,
390 ret2 = gethostbyname2_resolve (tc, hostname, AF_INET6); 442 hostname,
391 if ((ret1 == GNUNET_OK) || (ret2 == GNUNET_OK)) 443 AF_INET);
444 ret2 = gethostbyname2_resolve (mq,
445 hostname,
446 AF_INET6);
447 if ( (ret1 == GNUNET_OK) ||
448 (ret2 == GNUNET_OK) )
392 return GNUNET_OK; 449 return GNUNET_OK;
393 if ((ret1 == GNUNET_SYSERR) || (ret2 == GNUNET_SYSERR)) 450 if ( (ret1 == GNUNET_SYSERR) ||
451 (ret2 == GNUNET_SYSERR) )
394 return GNUNET_SYSERR; 452 return GNUNET_SYSERR;
395 return GNUNET_NO; 453 return GNUNET_NO;
396 } 454 }
397 hp = gethostbyname2 (hostname, af); 455 hp = gethostbyname2 (hostname,
456 af);
398 if (hp == NULL) 457 if (hp == NULL)
399 { 458 {
400 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 459 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
401 _("Could not find IP of host `%s': %s\n"), hostname, 460 _("Could not find IP of host `%s': %s\n"),
461 hostname,
402 hstrerror (h_errno)); 462 hstrerror (h_errno));
403 return GNUNET_SYSERR; 463 return GNUNET_SYSERR;
404 } 464 }
@@ -407,17 +467,25 @@ gethostbyname2_resolve (struct GNUNET_SERVER_TransmitContext *tc,
407 { 467 {
408 case AF_INET: 468 case AF_INET:
409 GNUNET_assert (hp->h_length == sizeof (struct in_addr)); 469 GNUNET_assert (hp->h_length == sizeof (struct in_addr));
410 GNUNET_SERVER_transmit_context_append_data (tc, 470 env = GNUNET_MQ_msg_extra (msg,
411 hp->h_addr_list[0], 471 hp->h_length,
412 hp->h_length, 472 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
413 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); 473 GNUNET_memcpy (&msg[1],
474 hp->h_addr_list[0],
475 hp->h_length);
476 GNUNET_MQ_send (mq,
477 env);
414 break; 478 break;
415 case AF_INET6: 479 case AF_INET6:
416 GNUNET_assert (hp->h_length == sizeof (struct in6_addr)); 480 GNUNET_assert (hp->h_length == sizeof (struct in6_addr));
417 GNUNET_SERVER_transmit_context_append_data (tc, 481 env = GNUNET_MQ_msg_extra (msg,
418 hp->h_addr_list[0], 482 hp->h_length,
419 hp->h_length, 483 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
420 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); 484 GNUNET_memcpy (&msg[1],
485 hp->h_addr_list[0],
486 hp->h_length);
487 GNUNET_MQ_send (mq,
488 env);
421 break; 489 break;
422 default: 490 default:
423 GNUNET_break (0); 491 GNUNET_break (0);
@@ -430,10 +498,12 @@ gethostbyname2_resolve (struct GNUNET_SERVER_TransmitContext *tc,
430 498
431 499
432static int 500static int
433gethostbyname_resolve (struct GNUNET_SERVER_TransmitContext *tc, 501gethostbyname_resolve (struct GNUNET_MQ_Handle *mq,
434 const char *hostname) 502 const char *hostname)
435{ 503{
436 struct hostent *hp; 504 struct hostent *hp;
505 struct GNUNET_MessageHeader *msg;
506 struct GNUNET_MQ_Envelope *env;
437 507
438 hp = GETHOSTBYNAME (hostname); 508 hp = GETHOSTBYNAME (hostname);
439 if (NULL == hp) 509 if (NULL == hp)
@@ -450,10 +520,14 @@ gethostbyname_resolve (struct GNUNET_SERVER_TransmitContext *tc,
450 return GNUNET_SYSERR; 520 return GNUNET_SYSERR;
451 } 521 }
452 GNUNET_assert (hp->h_length == sizeof (struct in_addr)); 522 GNUNET_assert (hp->h_length == sizeof (struct in_addr));
453 GNUNET_SERVER_transmit_context_append_data (tc, 523 env = GNUNET_MQ_msg_extra (msg,
454 hp->h_addr_list[0], 524 hp->h_length,
455 hp->h_length, 525 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
456 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); 526 GNUNET_memcpy (&msg[1],
527 hp->h_addr_list[0],
528 hp->h_length);
529 GNUNET_MQ_send (mq,
530 env);
457 return GNUNET_OK; 531 return GNUNET_OK;
458} 532}
459#endif 533#endif
@@ -467,168 +541,197 @@ gethostbyname_resolve (struct GNUNET_SERVER_TransmitContext *tc,
467 * @param af AF_INET or AF_INET6; use AF_UNSPEC for "any" 541 * @param af AF_INET or AF_INET6; use AF_UNSPEC for "any"
468 */ 542 */
469static void 543static void
470get_ip_from_hostname (struct GNUNET_SERVER_Client *client, 544get_ip_from_hostname (struct GNUNET_SERVICE_Client *client,
471 const char *hostname, 545 const char *hostname,
472 int af) 546 int af)
473{ 547{
474 int ret; 548 int ret;
475 struct GNUNET_SERVER_TransmitContext *tc; 549 struct GNUNET_MQ_Handle *mq;
550 struct GNUNET_MQ_Envelope *env;
551 struct GNUNET_MessageHeader *msg;
476 552
477 tc = GNUNET_SERVER_transmit_context_create (client); 553 mq = GNUNET_SERVICE_client_get_mq (client);
478 ret = GNUNET_NO; 554 ret = GNUNET_NO;
479#if HAVE_GETADDRINFO 555#if HAVE_GETADDRINFO
480 if (ret == GNUNET_NO) 556 if (ret == GNUNET_NO)
481 ret = getaddrinfo_resolve (tc, hostname, af); 557 ret = getaddrinfo_resolve (mq,
558 hostname,
559 af);
482#elif HAVE_GETHOSTBYNAME2 560#elif HAVE_GETHOSTBYNAME2
483 if (ret == GNUNET_NO) 561 if (ret == GNUNET_NO)
484 ret = gethostbyname2_resolve (tc, hostname, af); 562 ret = gethostbyname2_resolve (mq,
563 hostname,
564 af);
485#elif HAVE_GETHOSTBYNAME 565#elif HAVE_GETHOSTBYNAME
486 if ((ret == GNUNET_NO) && ((af == AF_UNSPEC) || (af == PF_INET))) 566 if ( (ret == GNUNET_NO) &&
487 gethostbyname_resolve (tc, hostname); 567 ( (af == AF_UNSPEC) ||
568 (af == PF_INET) ) )
569 gethostbyname_resolve (mq,
570 hostname);
488#endif 571#endif
489 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, 572 env = GNUNET_MQ_msg (msg,
490 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); 573 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
491 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); 574 GNUNET_MQ_notify_sent (env,
575 &notify_service_client_done,
576 client);
577 GNUNET_MQ_send (mq,
578 env);
492} 579}
493 580
494 581
495/** 582/**
496 * Handle GET-message. 583 * Verify well-formedness of GET-message.
497 * 584 *
498 * @param cls closure 585 * @param cls closure
499 * @param client identification of the client 586 * @param get the actual message
500 * @param message the actual message 587 * @return #GNUNET_OK if @a get is well-formed
501 */ 588 */
502static void 589static int
503handle_get (void *cls, 590check_get (void *cls,
504 struct GNUNET_SERVER_Client *client, 591 const struct GNUNET_RESOLVER_GetMessage *get)
505 const struct GNUNET_MessageHeader *message)
506{ 592{
507 uint16_t msize;
508 const struct GNUNET_RESOLVER_GetMessage *msg;
509 const void *ip;
510 uint16_t size; 593 uint16_t size;
511 int direction; 594 int direction;
512 int af; 595 int af;
513 596
514 msize = ntohs (message->size); 597 size = ntohs (get->header.size) - sizeof (*get);
515 if (msize < sizeof (struct GNUNET_RESOLVER_GetMessage)) 598 direction = ntohl (get->direction);
516 {
517 GNUNET_break (0);
518 GNUNET_SERVER_receive_done (client,
519 GNUNET_SYSERR);
520 return;
521 }
522 msg = (const struct GNUNET_RESOLVER_GetMessage *) message;
523 size = msize - sizeof (struct GNUNET_RESOLVER_GetMessage);
524 direction = ntohl (msg->direction);
525 af = ntohl (msg->af);
526 if (GNUNET_NO == direction) 599 if (GNUNET_NO == direction)
527 { 600 {
528 /* IP from hostname */ 601 /* IP from hostname */
529 const char *hostname; 602 const char *hostname;
530 603
531 hostname = (const char *) &msg[1]; 604 hostname = (const char *) &get[1];
532 if (hostname[size - 1] != '\0') 605 if (hostname[size - 1] != '\0')
533 { 606 {
534 GNUNET_break (0); 607 GNUNET_break (0);
535 GNUNET_SERVER_receive_done (client, 608 return GNUNET_SYSERR;
536 GNUNET_SYSERR);
537 return;
538 } 609 }
539 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 610 return GNUNET_OK;
540 "Resolver asked to look up `%s'.\n",
541 hostname);
542 get_ip_from_hostname (client, hostname, af);
543 return;
544 } 611 }
545 ip = &msg[1]; 612 af = ntohl (get->af);
546 switch (af) 613 switch (af)
547 { 614 {
548 case AF_INET: 615 case AF_INET:
549 if (size != sizeof (struct in_addr)) 616 if (size != sizeof (struct in_addr))
550 { 617 {
551 GNUNET_break (0); 618 GNUNET_break (0);
552 GNUNET_SERVER_receive_done (client, 619 return GNUNET_SYSERR;
553 GNUNET_SYSERR);
554 return;
555 } 620 }
556 break; 621 break;
557 case AF_INET6: 622 case AF_INET6:
558 if (size != sizeof (struct in6_addr)) 623 if (size != sizeof (struct in6_addr))
559 { 624 {
560 GNUNET_break (0); 625 GNUNET_break (0);
561 GNUNET_SERVER_receive_done (client, 626 return GNUNET_SYSERR;
562 GNUNET_SYSERR);
563 return;
564 } 627 }
565 break; 628 break;
566 default: 629 default:
567 GNUNET_break (0); 630 GNUNET_break (0);
568 GNUNET_SERVER_receive_done (client, 631 return GNUNET_SYSERR;
569 GNUNET_SYSERR); 632 }
633 return GNUNET_OK;
634}
635
636
637/**
638 * Handle GET-message.
639 *
640 * @param cls identification of the client
641 * @param msg the actual message
642 */
643static void
644handle_get (void *cls,
645 const struct GNUNET_RESOLVER_GetMessage *msg)
646{
647 struct GNUNET_SERVICE_Client *client = cls;
648 const void *ip;
649 int direction;
650 int af;
651
652 direction = ntohl (msg->direction);
653 af = ntohl (msg->af);
654 if (GNUNET_NO == direction)
655 {
656 /* IP from hostname */
657 const char *hostname;
658
659 hostname = (const char *) &msg[1];
660 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
661 "Resolver asked to look up `%s'.\n",
662 hostname);
663 get_ip_from_hostname (client,
664 hostname,
665 af);
570 return; 666 return;
571 } 667 }
668 ip = &msg[1];
572 { 669 {
573 char buf[INET6_ADDRSTRLEN]; 670 char buf[INET6_ADDRSTRLEN];
574 671
575 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 672 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
576 "Resolver asked to look up IP address `%s'.\n", 673 "Resolver asked to look up IP address `%s'.\n",
577 inet_ntop (af, ip, buf, sizeof (buf))); 674 inet_ntop (af,
675 ip,
676 buf,
677 sizeof (buf)));
578 } 678 }
579 get_ip_as_string (client, af, ip); 679 get_ip_as_string (client,
680 af,
681 ip);
580} 682}
581 683
582 684
583/** 685/**
584 * Process resolver requests. 686 * Callback called when a client connects to the service.
585 * 687 *
586 * @param cls closure 688 * @param cls closure for the service
587 * @param server the initialized server 689 * @param c the new client that connected to the service
588 * @param cfg configuration to use 690 * @param mq the message queue used to send messages to the client
691 * @return @a c
589 */ 692 */
590static void 693static void *
591run (void *cls, struct GNUNET_SERVER_Handle *server, 694connect_cb (void *cls,
592 const struct GNUNET_CONFIGURATION_Handle *cfg) 695 struct GNUNET_SERVICE_Client *c,
696 struct GNUNET_MQ_Handle *mq)
593{ 697{
594 static const struct GNUNET_SERVER_MessageHandler handlers[] = { 698 return c;
595 {&handle_get, NULL, GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST, 0},
596 {NULL, NULL, 0, 0}
597 };
598 GNUNET_SERVER_add_handlers (server, handlers);
599} 699}
600 700
601 701
602/** 702/**
603 * The main function for the resolver service. 703 * Callback called when a client disconnected from the service
604 * 704 *
605 * @param argc number of arguments from the command line 705 * @param cls closure for the service
606 * @param argv command line arguments 706 * @param c the client that disconnected
607 * @return 0 ok, 1 on error 707 * @param internal_cls should be equal to @a c
608 */ 708 */
609int 709static void
610main (int argc, char *const *argv) 710disconnect_cb (void *cls,
711 struct GNUNET_SERVICE_Client *c,
712 void *internal_cls)
611{ 713{
612 struct IPCache *pos; 714 GNUNET_assert (c == internal_cls);
613 int ret;
614
615 ret =
616 (GNUNET_OK ==
617 GNUNET_SERVICE_run (argc, argv,
618 "resolver",
619 GNUNET_SERVICE_OPTION_NONE,
620 &run, NULL)) ? 0 : 1;
621 while (NULL != (pos = cache_head))
622 {
623 GNUNET_CONTAINER_DLL_remove (cache_head,
624 cache_tail,
625 pos);
626 GNUNET_free_non_null (pos->addr);
627 GNUNET_free (pos);
628 }
629 return ret;
630} 715}
631 716
717
718/**
719 * Define "main" method using service macro.
720 */
721GNUNET_SERVICE_MAIN
722("resolver",
723 GNUNET_SERVICE_OPTION_NONE,
724 NULL,
725 &connect_cb,
726 &disconnect_cb,
727 NULL,
728 GNUNET_MQ_hd_var_size (get,
729 GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST,
730 struct GNUNET_RESOLVER_GetMessage,
731 NULL),
732 GNUNET_MQ_handler_end ());
733
734
632#if defined(LINUX) && defined(__GLIBC__) 735#if defined(LINUX) && defined(__GLIBC__)
633#include <malloc.h> 736#include <malloc.h>
634 737
@@ -636,7 +739,7 @@ main (int argc, char *const *argv)
636 * MINIMIZE heap size (way below 128k) since this process doesn't need much. 739 * MINIMIZE heap size (way below 128k) since this process doesn't need much.
637 */ 740 */
638void __attribute__ ((constructor)) 741void __attribute__ ((constructor))
639GNUNET_ARM_memory_init () 742GNUNET_RESOLVER_memory_init ()
640{ 743{
641 mallopt (M_TRIM_THRESHOLD, 4 * 1024); 744 mallopt (M_TRIM_THRESHOLD, 4 * 1024);
642 mallopt (M_TOP_PAD, 1 * 1024); 745 mallopt (M_TOP_PAD, 1 * 1024);
@@ -645,4 +748,23 @@ GNUNET_ARM_memory_init ()
645#endif 748#endif
646 749
647 750
751/**
752 * Free globals on exit.
753 */
754void __attribute__ ((destructor))
755GNUNET_RESOLVER_memory_done ()
756{
757 struct IPCache *pos;
758
759 while (NULL != (pos = cache_head))
760 {
761 GNUNET_CONTAINER_DLL_remove (cache_head,
762 cache_tail,
763 pos);
764 GNUNET_free_non_null (pos->addr);
765 GNUNET_free (pos);
766 }
767}
768
769
648/* end of gnunet-service-resolver.c */ 770/* end of gnunet-service-resolver.c */