aboutsummaryrefslogtreecommitdiff
path: root/src/util/service.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/service.c')
-rw-r--r--src/util/service.c2181
1 files changed, 1097 insertions, 1084 deletions
diff --git a/src/util/service.c b/src/util/service.c
index b0f4ea289..21b99547c 100644
--- a/src/util/service.c
+++ b/src/util/service.c
@@ -37,19 +37,20 @@
37#endif 37#endif
38 38
39 39
40#define LOG(kind, ...) GNUNET_log_from(kind, "util-service", __VA_ARGS__) 40#define LOG(kind, ...) GNUNET_log_from (kind, "util-service", __VA_ARGS__)
41 41
42#define LOG_STRERROR(kind, syscall) \ 42#define LOG_STRERROR(kind, syscall) \
43 GNUNET_log_from_strerror(kind, "util-service", syscall) 43 GNUNET_log_from_strerror (kind, "util-service", syscall)
44 44
45#define LOG_STRERROR_FILE(kind, syscall, filename) \ 45#define LOG_STRERROR_FILE(kind, syscall, filename) \
46 GNUNET_log_from_strerror_file(kind, "util-service", syscall, filename) 46 GNUNET_log_from_strerror_file (kind, "util-service", syscall, filename)
47 47
48 48
49/** 49/**
50 * Information the service tracks per listen operation. 50 * Information the service tracks per listen operation.
51 */ 51 */
52struct ServiceListenContext { 52struct ServiceListenContext
53{
53 /** 54 /**
54 * Kept in a DLL. 55 * Kept in a DLL.
55 */ 56 */
@@ -80,7 +81,8 @@ struct ServiceListenContext {
80/** 81/**
81 * Reasons why we might be suspended. 82 * Reasons why we might be suspended.
82 */ 83 */
83enum SuspendReason { 84enum SuspendReason
85{
84 /** 86 /**
85 * We are running normally. 87 * We are running normally.
86 */ 88 */
@@ -111,7 +113,8 @@ enum SuspendReason {
111/** 113/**
112 * Handle to a service. 114 * Handle to a service.
113 */ 115 */
114struct GNUNET_SERVICE_Handle { 116struct GNUNET_SERVICE_Handle
117{
115 /** 118 /**
116 * Our configuration. 119 * Our configuration.
117 */ 120 */
@@ -172,6 +175,7 @@ struct GNUNET_SERVICE_Handle {
172 */ 175 */
173 void *task_cls; 176 void *task_cls;
174 177
178
175 /** 179 /**
176 * IPv4 addresses that are not allowed to connect. 180 * IPv4 addresses that are not allowed to connect.
177 */ 181 */
@@ -243,7 +247,8 @@ struct GNUNET_SERVICE_Handle {
243/** 247/**
244 * Handle to a client that is connected to a service. 248 * Handle to a client that is connected to a service.
245 */ 249 */
246struct GNUNET_SERVICE_Client { 250struct GNUNET_SERVICE_Client
251{
247 /** 252 /**
248 * Kept in a DLL. 253 * Kept in a DLL.
249 */ 254 */
@@ -353,15 +358,15 @@ struct GNUNET_SERVICE_Client {
353 * @return #GNUNET_YES if we have non-monitoring clients left 358 * @return #GNUNET_YES if we have non-monitoring clients left
354 */ 359 */
355static int 360static int
356have_non_monitor_clients(struct GNUNET_SERVICE_Handle *sh) 361have_non_monitor_clients (struct GNUNET_SERVICE_Handle *sh)
357{ 362{
358 for (struct GNUNET_SERVICE_Client *client = sh->clients_head; NULL != client; 363 for (struct GNUNET_SERVICE_Client *client = sh->clients_head; NULL != client;
359 client = client->next) 364 client = client->next)
360 { 365 {
361 if (client->is_monitor) 366 if (client->is_monitor)
362 continue; 367 continue;
363 return GNUNET_YES; 368 return GNUNET_YES;
364 } 369 }
365 return GNUNET_NO; 370 return GNUNET_NO;
366} 371}
367 372
@@ -374,20 +379,20 @@ have_non_monitor_clients(struct GNUNET_SERVICE_Handle *sh)
374 * @param sr reason for suspending accepting connections 379 * @param sr reason for suspending accepting connections
375 */ 380 */
376static void 381static void
377do_suspend(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) 382do_suspend (struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
378{ 383{
379 struct ServiceListenContext *slc; 384 struct ServiceListenContext *slc;
380 385
381 GNUNET_assert(0 == (sh->suspend_state & sr)); 386 GNUNET_assert (0 == (sh->suspend_state & sr));
382 sh->suspend_state |= sr; 387 sh->suspend_state |= sr;
383 for (slc = sh->slc_head; NULL != slc; slc = slc->next) 388 for (slc = sh->slc_head; NULL != slc; slc = slc->next)
389 {
390 if (NULL != slc->listen_task)
384 { 391 {
385 if (NULL != slc->listen_task) 392 GNUNET_SCHEDULER_cancel (slc->listen_task);
386 { 393 slc->listen_task = NULL;
387 GNUNET_SCHEDULER_cancel(slc->listen_task);
388 slc->listen_task = NULL;
389 }
390 } 394 }
395 }
391} 396}
392 397
393 398
@@ -400,29 +405,27 @@ do_suspend(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
400 * @param cls our `struct GNUNET_SERVICE_Handle` 405 * @param cls our `struct GNUNET_SERVICE_Handle`
401 */ 406 */
402static void 407static void
403service_shutdown(void *cls) 408service_shutdown (void *cls)
404{ 409{
405 struct GNUNET_SERVICE_Handle *sh = cls; 410 struct GNUNET_SERVICE_Handle *sh = cls;
406 411
407 switch (sh->options) 412 switch (sh->options & GNUNET_SERVICE_OPTION_SHUTDOWN_BITMASK)
408 { 413 {
409 case GNUNET_SERVICE_OPTION_NONE: 414 case GNUNET_SERVICE_OPTION_NONE:
410 GNUNET_SERVICE_shutdown(sh); 415 GNUNET_SERVICE_shutdown (sh);
411 break; 416 break;
412 417 case GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN:
413 case GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN: 418 /* This task should never be run if we are using
414 /* This task should never be run if we are using 419 the manual shutdown. */
415 the manual shutdown. */ 420 GNUNET_assert (0);
416 GNUNET_assert(0); 421 break;
417 break; 422 case GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN:
418 423 if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN))
419 case GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN: 424 do_suspend (sh, SUSPEND_STATE_SHUTDOWN);
420 if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) 425 if (GNUNET_NO == have_non_monitor_clients (sh))
421 do_suspend(sh, SUSPEND_STATE_SHUTDOWN); 426 GNUNET_SERVICE_shutdown (sh);
422 if (GNUNET_NO == have_non_monitor_clients(sh)) 427 break;
423 GNUNET_SERVICE_shutdown(sh); 428 }
424 break;
425 }
426} 429}
427 430
428 431
@@ -434,8 +437,8 @@ service_shutdown(void *cls)
434 * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is 437 * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
435 */ 438 */
436static int 439static int
437check_ipv4_listed(const struct GNUNET_STRINGS_IPv4NetworkPolicy *list, 440check_ipv4_listed (const struct GNUNET_STRINGS_IPv4NetworkPolicy *list,
438 const struct in_addr *add) 441 const struct in_addr *add)
439{ 442{
440 unsigned int i; 443 unsigned int i;
441 444
@@ -443,12 +446,12 @@ check_ipv4_listed(const struct GNUNET_STRINGS_IPv4NetworkPolicy *list,
443 return GNUNET_NO; 446 return GNUNET_NO;
444 i = 0; 447 i = 0;
445 while ((0 != list[i].network.s_addr) || (0 != list[i].netmask.s_addr)) 448 while ((0 != list[i].network.s_addr) || (0 != list[i].netmask.s_addr))
446 { 449 {
447 if ((add->s_addr & list[i].netmask.s_addr) == 450 if ((add->s_addr & list[i].netmask.s_addr) ==
448 (list[i].network.s_addr & list[i].netmask.s_addr)) 451 (list[i].network.s_addr & list[i].netmask.s_addr))
449 return GNUNET_YES; 452 return GNUNET_YES;
450 i++; 453 i++;
451 } 454 }
452 return GNUNET_NO; 455 return GNUNET_NO;
453} 456}
454 457
@@ -461,8 +464,8 @@ check_ipv4_listed(const struct GNUNET_STRINGS_IPv4NetworkPolicy *list,
461 * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is 464 * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
462 */ 465 */
463static int 466static int
464check_ipv6_listed(const struct GNUNET_STRINGS_IPv6NetworkPolicy *list, 467check_ipv6_listed (const struct GNUNET_STRINGS_IPv6NetworkPolicy *list,
465 const struct in6_addr *ip) 468 const struct in6_addr *ip)
466{ 469{
467 unsigned int i; 470 unsigned int i;
468 unsigned int j; 471 unsigned int j;
@@ -471,17 +474,17 @@ check_ipv6_listed(const struct GNUNET_STRINGS_IPv6NetworkPolicy *list,
471 return GNUNET_NO; 474 return GNUNET_NO;
472 i = 0; 475 i = 0;
473NEXT: 476NEXT:
474 while (0 != GNUNET_is_zero(&list[i].network)) 477 while (0 != GNUNET_is_zero (&list[i].network))
475 { 478 {
476 for (j = 0; j < sizeof(struct in6_addr) / sizeof(int); j++) 479 for (j = 0; j < sizeof(struct in6_addr) / sizeof(int); j++)
477 if (((((int *)ip)[j] & ((int *)&list[i].netmask)[j])) != 480 if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
478 (((int *)&list[i].network)[j] & ((int *)&list[i].netmask)[j])) 481 (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
479 { 482 {
480 i++; 483 i++;
481 goto NEXT; 484 goto NEXT;
482 } 485 }
483 return GNUNET_YES; 486 return GNUNET_YES;
484 } 487 }
485 return GNUNET_NO; 488 return GNUNET_NO;
486} 489}
487 490
@@ -493,63 +496,63 @@ NEXT:
493 * @param cls the `struct GNUNET_SERVICE_Client *` to send to 496 * @param cls the `struct GNUNET_SERVICE_Client *` to send to
494 */ 497 */
495static void 498static void
496do_send(void *cls) 499do_send (void *cls)
497{ 500{
498 struct GNUNET_SERVICE_Client *client = cls; 501 struct GNUNET_SERVICE_Client *client = cls;
499 ssize_t ret; 502 ssize_t ret;
500 size_t left; 503 size_t left;
501 const char *buf; 504 const char *buf;
502 505
503 LOG(GNUNET_ERROR_TYPE_DEBUG, 506 LOG (GNUNET_ERROR_TYPE_DEBUG,
504 "service: sending message with type %u\n", 507 "service: sending message with type %u\n",
505 ntohs(client->msg->type)); 508 ntohs (client->msg->type));
506 509
507 510
508 client->send_task = NULL; 511 client->send_task = NULL;
509 buf = (const char *)client->msg; 512 buf = (const char *) client->msg;
510 left = ntohs(client->msg->size) - client->msg_pos; 513 left = ntohs (client->msg->size) - client->msg_pos;
511 ret = GNUNET_NETWORK_socket_send(client->sock, &buf[client->msg_pos], left); 514 ret = GNUNET_NETWORK_socket_send (client->sock, &buf[client->msg_pos], left);
512 GNUNET_assert(ret <= (ssize_t)left); 515 GNUNET_assert (ret <= (ssize_t) left);
513 if (0 == ret) 516 if (0 == ret)
514 { 517 {
515 LOG(GNUNET_ERROR_TYPE_DEBUG, "no data send"); 518 LOG (GNUNET_ERROR_TYPE_DEBUG, "no data send");
516 GNUNET_MQ_inject_error(client->mq, GNUNET_MQ_ERROR_WRITE); 519 GNUNET_MQ_inject_error (client->mq, GNUNET_MQ_ERROR_WRITE);
517 return; 520 return;
518 } 521 }
519 if (-1 == ret) 522 if (-1 == ret)
523 {
524 if ((EAGAIN == errno) || (EINTR == errno))
520 { 525 {
521 if ((EAGAIN == errno) || (EINTR == errno)) 526 /* ignore */
522 { 527 ret = 0;
523 /* ignore */
524 ret = 0;
525 }
526 else
527 {
528 if (EPIPE != errno)
529 GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "send");
530 LOG(GNUNET_ERROR_TYPE_DEBUG,
531 "socket send returned with error code %i",
532 errno);
533 GNUNET_MQ_inject_error(client->mq, GNUNET_MQ_ERROR_WRITE);
534 return;
535 }
536 }
537 if (0 == client->msg_pos)
538 {
539 GNUNET_MQ_impl_send_in_flight(client->mq);
540 } 528 }
541 client->msg_pos += ret; 529 else
542 if (left > (size_t)ret)
543 { 530 {
544 GNUNET_assert(NULL == client->drop_task); 531 if (EPIPE != errno)
545 client->send_task = 532 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send");
546 GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL, 533 LOG (GNUNET_ERROR_TYPE_DEBUG,
547 client->sock, 534 "socket send returned with error code %i",
548 &do_send, 535 errno);
549 client); 536 GNUNET_MQ_inject_error (client->mq, GNUNET_MQ_ERROR_WRITE);
550 return; 537 return;
551 } 538 }
552 GNUNET_MQ_impl_send_continue(client->mq); 539 }
540 if (0 == client->msg_pos)
541 {
542 GNUNET_MQ_impl_send_in_flight (client->mq);
543 }
544 client->msg_pos += ret;
545 if (left > (size_t) ret)
546 {
547 GNUNET_assert (NULL == client->drop_task);
548 client->send_task =
549 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
550 client->sock,
551 &do_send,
552 client);
553 return;
554 }
555 GNUNET_MQ_impl_send_continue (client->mq);
553} 556}
554 557
555 558
@@ -562,27 +565,27 @@ do_send(void *cls)
562 * @param impl_state our `struct GNUNET_SERVICE_Client *` 565 * @param impl_state our `struct GNUNET_SERVICE_Client *`
563 */ 566 */
564static void 567static void
565service_mq_send(struct GNUNET_MQ_Handle *mq, 568service_mq_send (struct GNUNET_MQ_Handle *mq,
566 const struct GNUNET_MessageHeader *msg, 569 const struct GNUNET_MessageHeader *msg,
567 void *impl_state) 570 void *impl_state)
568{ 571{
569 struct GNUNET_SERVICE_Client *client = impl_state; 572 struct GNUNET_SERVICE_Client *client = impl_state;
570 573
571 (void)mq; 574 (void) mq;
572 if (NULL != client->drop_task) 575 if (NULL != client->drop_task)
573 return; /* we're going down right now, do not try to send */ 576 return; /* we're going down right now, do not try to send */
574 GNUNET_assert(NULL == client->send_task); 577 GNUNET_assert (NULL == client->send_task);
575 LOG(GNUNET_ERROR_TYPE_DEBUG, 578 LOG (GNUNET_ERROR_TYPE_DEBUG,
576 "Sending message of type %u and size %u to client\n", 579 "Sending message of type %u and size %u to client\n",
577 ntohs(msg->type), 580 ntohs (msg->type),
578 ntohs(msg->size)); 581 ntohs (msg->size));
579 client->msg = msg; 582 client->msg = msg;
580 client->msg_pos = 0; 583 client->msg_pos = 0;
581 client->send_task = 584 client->send_task =
582 GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL, 585 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
583 client->sock, 586 client->sock,
584 &do_send, 587 &do_send,
585 client); 588 client);
586} 589}
587 590
588 591
@@ -593,14 +596,14 @@ service_mq_send(struct GNUNET_MQ_Handle *mq,
593 * @param impl_state state specific to the implementation 596 * @param impl_state state specific to the implementation
594 */ 597 */
595static void 598static void
596service_mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state) 599service_mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
597{ 600{
598 struct GNUNET_SERVICE_Client *client = impl_state; 601 struct GNUNET_SERVICE_Client *client = impl_state;
599 602
600 (void)mq; 603 (void) mq;
601 GNUNET_assert(0 == client->msg_pos); 604 GNUNET_assert (0 == client->msg_pos);
602 client->msg = NULL; 605 client->msg = NULL;
603 GNUNET_SCHEDULER_cancel(client->send_task); 606 GNUNET_SCHEDULER_cancel (client->send_task);
604 client->send_task = NULL; 607 client->send_task = NULL;
605} 608}
606 609
@@ -615,20 +618,20 @@ service_mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
615 * @param error error code 618 * @param error error code
616 */ 619 */
617static void 620static void
618service_mq_error_handler(void *cls, enum GNUNET_MQ_Error error) 621service_mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
619{ 622{
620 struct GNUNET_SERVICE_Client *client = cls; 623 struct GNUNET_SERVICE_Client *client = cls;
621 struct GNUNET_SERVICE_Handle *sh = client->sh; 624 struct GNUNET_SERVICE_Handle *sh = client->sh;
622 625
623 if ((GNUNET_MQ_ERROR_NO_MATCH == error) && (GNUNET_NO == sh->require_found)) 626 if ((GNUNET_MQ_ERROR_NO_MATCH == error) && (GNUNET_NO == sh->require_found))
624 { 627 {
625 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 628 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
626 "No handler for message of type %u found\n", 629 "No handler for message of type %u found\n",
627 (unsigned int)client->warn_type); 630 (unsigned int) client->warn_type);
628 GNUNET_SERVICE_client_continue(client); 631 GNUNET_SERVICE_client_continue (client);
629 return; /* ignore error */ 632 return; /* ignore error */
630 } 633 }
631 GNUNET_SERVICE_client_drop(client); 634 GNUNET_SERVICE_client_drop (client);
632} 635}
633 636
634 637
@@ -638,24 +641,24 @@ service_mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
638 * @param cls our `struct GNUNET_SERVICE_Client *` to process more requests from 641 * @param cls our `struct GNUNET_SERVICE_Client *` to process more requests from
639 */ 642 */
640static void 643static void
641warn_no_client_continue(void *cls) 644warn_no_client_continue (void *cls)
642{ 645{
643 struct GNUNET_SERVICE_Client *client = cls; 646 struct GNUNET_SERVICE_Client *client = cls;
644 647
645 GNUNET_break( 648 GNUNET_break (
646 0 != 649 0 !=
647 client->warn_type); /* type should never be 0 here, as we don't use 0 */ 650 client->warn_type); /* type should never be 0 here, as we don't use 0 */
648 client->warn_task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_MINUTES, 651 client->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
649 &warn_no_client_continue, 652 &warn_no_client_continue,
650 client); 653 client);
651 LOG( 654 LOG (
652 GNUNET_ERROR_TYPE_WARNING, 655 GNUNET_ERROR_TYPE_WARNING,
653 _( 656 _ (
654 "Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"), 657 "Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"),
655 (unsigned int)client->warn_type, 658 (unsigned int) client->warn_type,
656 GNUNET_STRINGS_relative_time_to_string(GNUNET_TIME_absolute_get_duration( 659 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (
657 client->warn_start), 660 client->warn_start),
658 GNUNET_YES)); 661 GNUNET_YES));
659} 662}
660 663
661 664
@@ -671,23 +674,23 @@ warn_no_client_continue(void *cls)
671 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the client was dropped 674 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the client was dropped
672 */ 675 */
673static int 676static int
674service_client_mst_cb(void *cls, const struct GNUNET_MessageHeader *message) 677service_client_mst_cb (void *cls, const struct GNUNET_MessageHeader *message)
675{ 678{
676 struct GNUNET_SERVICE_Client *client = cls; 679 struct GNUNET_SERVICE_Client *client = cls;
677 680
678 LOG(GNUNET_ERROR_TYPE_DEBUG, 681 LOG (GNUNET_ERROR_TYPE_DEBUG,
679 "Received message of type %u and size %u from client\n", 682 "Received message of type %u and size %u from client\n",
680 ntohs(message->type), 683 ntohs (message->type),
681 ntohs(message->size)); 684 ntohs (message->size));
682 GNUNET_assert(GNUNET_NO == client->needs_continue); 685 GNUNET_assert (GNUNET_NO == client->needs_continue);
683 client->needs_continue = GNUNET_YES; 686 client->needs_continue = GNUNET_YES;
684 client->warn_type = ntohs(message->type); 687 client->warn_type = ntohs (message->type);
685 client->warn_start = GNUNET_TIME_absolute_get(); 688 client->warn_start = GNUNET_TIME_absolute_get ();
686 GNUNET_assert(NULL == client->warn_task); 689 GNUNET_assert (NULL == client->warn_task);
687 client->warn_task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_MINUTES, 690 client->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
688 &warn_no_client_continue, 691 &warn_no_client_continue,
689 client); 692 client);
690 GNUNET_MQ_inject_message(client->mq, message); 693 GNUNET_MQ_inject_message (client->mq, message);
691 if (NULL != client->drop_task) 694 if (NULL != client->drop_task)
692 return GNUNET_SYSERR; 695 return GNUNET_SYSERR;
693 return GNUNET_OK; 696 return GNUNET_OK;
@@ -701,37 +704,37 @@ service_client_mst_cb(void *cls, const struct GNUNET_MessageHeader *message)
701 * @param cls the `struct GNUNET_SERVICE_Client` that sent us data. 704 * @param cls the `struct GNUNET_SERVICE_Client` that sent us data.
702 */ 705 */
703static void 706static void
704service_client_recv(void *cls) 707service_client_recv (void *cls)
705{ 708{
706 struct GNUNET_SERVICE_Client *client = cls; 709 struct GNUNET_SERVICE_Client *client = cls;
707 int ret; 710 int ret;
708 711
709 client->recv_task = NULL; 712 client->recv_task = NULL;
710 ret = GNUNET_MST_read(client->mst, client->sock, GNUNET_NO, GNUNET_YES); 713 ret = GNUNET_MST_read (client->mst, client->sock, GNUNET_NO, GNUNET_YES);
711 if (GNUNET_SYSERR == ret) 714 if (GNUNET_SYSERR == ret)
715 {
716 /* client closed connection (or IO error) */
717 if (NULL == client->drop_task)
712 { 718 {
713 /* client closed connection (or IO error) */ 719 GNUNET_assert (GNUNET_NO == client->needs_continue);
714 if (NULL == client->drop_task) 720 GNUNET_SERVICE_client_drop (client);
715 {
716 GNUNET_assert(GNUNET_NO == client->needs_continue);
717 GNUNET_SERVICE_client_drop(client);
718 }
719 return;
720 } 721 }
722 return;
723 }
721 if (GNUNET_NO == ret) 724 if (GNUNET_NO == ret)
722 return; /* more messages in buffer, wait for application 725 return; /* more messages in buffer, wait for application
723 to be done processing */ 726 to be done processing */
724 GNUNET_assert(GNUNET_OK == ret); 727 GNUNET_assert (GNUNET_OK == ret);
725 if (GNUNET_YES == client->needs_continue) 728 if (GNUNET_YES == client->needs_continue)
726 return; 729 return;
727 if (NULL != client->recv_task) 730 if (NULL != client->recv_task)
728 return; 731 return;
729 /* MST needs more data, re-schedule read job */ 732 /* MST needs more data, re-schedule read job */
730 client->recv_task = 733 client->recv_task =
731 GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, 734 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
732 client->sock, 735 client->sock,
733 &service_client_recv, 736 &service_client_recv,
734 client); 737 client);
735} 738}
736 739
737 740
@@ -743,31 +746,31 @@ service_client_recv(void *cls)
743 * @param sock socket associated with the client 746 * @param sock socket associated with the client
744 */ 747 */
745static void 748static void
746start_client(struct GNUNET_SERVICE_Handle *sh, 749start_client (struct GNUNET_SERVICE_Handle *sh,
747 struct GNUNET_NETWORK_Handle *csock) 750 struct GNUNET_NETWORK_Handle *csock)
748{ 751{
749 struct GNUNET_SERVICE_Client *client; 752 struct GNUNET_SERVICE_Client *client;
750 753
751 client = GNUNET_new(struct GNUNET_SERVICE_Client); 754 client = GNUNET_new (struct GNUNET_SERVICE_Client);
752 GNUNET_CONTAINER_DLL_insert(sh->clients_head, sh->clients_tail, client); 755 GNUNET_CONTAINER_DLL_insert (sh->clients_head, sh->clients_tail, client);
753 client->sh = sh; 756 client->sh = sh;
754 client->sock = csock; 757 client->sock = csock;
755 client->mq = GNUNET_MQ_queue_for_callbacks(&service_mq_send, 758 client->mq = GNUNET_MQ_queue_for_callbacks (&service_mq_send,
756 NULL, 759 NULL,
757 &service_mq_cancel, 760 &service_mq_cancel,
758 client, 761 client,
759 sh->handlers, 762 sh->handlers,
760 &service_mq_error_handler, 763 &service_mq_error_handler,
761 client); 764 client);
762 client->mst = GNUNET_MST_create(&service_client_mst_cb, client); 765 client->mst = GNUNET_MST_create (&service_client_mst_cb, client);
763 if (NULL != sh->connect_cb) 766 if (NULL != sh->connect_cb)
764 client->user_context = sh->connect_cb(sh->cb_cls, client, client->mq); 767 client->user_context = sh->connect_cb (sh->cb_cls, client, client->mq);
765 GNUNET_MQ_set_handlers_closure(client->mq, client->user_context); 768 GNUNET_MQ_set_handlers_closure (client->mq, client->user_context);
766 client->recv_task = 769 client->recv_task =
767 GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, 770 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
768 client->sock, 771 client->sock,
769 &service_client_recv, 772 &service_client_recv,
770 client); 773 client);
771} 774}
772 775
773 776
@@ -778,83 +781,83 @@ start_client(struct GNUNET_SERVICE_Handle *sh,
778 * @param cls the `struct ServiceListenContext` of the ready listen socket 781 * @param cls the `struct ServiceListenContext` of the ready listen socket
779 */ 782 */
780static void 783static void
781accept_client(void *cls) 784accept_client (void *cls)
782{ 785{
783 struct ServiceListenContext *slc = cls; 786 struct ServiceListenContext *slc = cls;
784 struct GNUNET_SERVICE_Handle *sh = slc->sh; 787 struct GNUNET_SERVICE_Handle *sh = slc->sh;
785 788
786 slc->listen_task = NULL; 789 slc->listen_task = NULL;
787 while (1) 790 while (1)
791 {
792 struct GNUNET_NETWORK_Handle *sock;
793 const struct sockaddr_in *v4;
794 const struct sockaddr_in6 *v6;
795 struct sockaddr_storage sa;
796 socklen_t addrlen;
797 int ok;
798
799 addrlen = sizeof(sa);
800 sock = GNUNET_NETWORK_socket_accept (slc->listen_socket,
801 (struct sockaddr *) &sa,
802 &addrlen);
803 if (NULL == sock)
804 {
805 if (EMFILE == errno)
806 do_suspend (sh, SUSPEND_STATE_EMFILE);
807 else if (EAGAIN != errno)
808 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "accept");
809 break;
810 }
811 switch (sa.ss_family)
788 { 812 {
789 struct GNUNET_NETWORK_Handle *sock; 813 case AF_INET:
790 const struct sockaddr_in *v4; 814 GNUNET_assert (addrlen == sizeof(struct sockaddr_in));
791 const struct sockaddr_in6 *v6; 815 v4 = (const struct sockaddr_in *) &sa;
792 struct sockaddr_storage sa; 816 ok = (((NULL == sh->v4_allowed) ||
793 socklen_t addrlen; 817 (check_ipv4_listed (sh->v4_allowed, &v4->sin_addr))) &&
794 int ok; 818 ((NULL == sh->v4_denied) ||
795 819 (! check_ipv4_listed (sh->v4_denied, &v4->sin_addr))));
796 addrlen = sizeof(sa); 820 break;
797 sock = GNUNET_NETWORK_socket_accept(slc->listen_socket, 821
798 (struct sockaddr *)&sa, 822 case AF_INET6:
799 &addrlen); 823 GNUNET_assert (addrlen == sizeof(struct sockaddr_in6));
800 if (NULL == sock) 824 v6 = (const struct sockaddr_in6 *) &sa;
801 { 825 ok = (((NULL == sh->v6_allowed) ||
802 if (EMFILE == errno) 826 (check_ipv6_listed (sh->v6_allowed, &v6->sin6_addr))) &&
803 do_suspend(sh, SUSPEND_STATE_EMFILE); 827 ((NULL == sh->v6_denied) ||
804 else if (EAGAIN != errno) 828 (! check_ipv6_listed (sh->v6_denied, &v6->sin6_addr))));
805 GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "accept"); 829 break;
806 break; 830
807 } 831 case AF_UNIX:
808 switch (sa.ss_family) 832 ok = GNUNET_OK; /* controlled using file-system ACL now */
809 { 833 break;
810 case AF_INET: 834
811 GNUNET_assert(addrlen == sizeof(struct sockaddr_in)); 835 default:
812 v4 = (const struct sockaddr_in *)&sa; 836 LOG (GNUNET_ERROR_TYPE_WARNING,
813 ok = (((NULL == sh->v4_allowed) || 837 _ ("Unknown address family %d\n"),
814 (check_ipv4_listed(sh->v4_allowed, &v4->sin_addr))) && 838 sa.ss_family);
815 ((NULL == sh->v4_denied) || 839 return;
816 (!check_ipv4_listed(sh->v4_denied, &v4->sin_addr)))); 840 }
817 break; 841 if (! ok)
818 842 {
819 case AF_INET6: 843 LOG (GNUNET_ERROR_TYPE_DEBUG,
820 GNUNET_assert(addrlen == sizeof(struct sockaddr_in6)); 844 "Service rejected incoming connection from %s due to policy.\n",
821 v6 = (const struct sockaddr_in6 *)&sa; 845 GNUNET_a2s ((const struct sockaddr *) &sa, addrlen));
822 ok = (((NULL == sh->v6_allowed) || 846 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
823 (check_ipv6_listed(sh->v6_allowed, &v6->sin6_addr))) && 847 continue;
824 ((NULL == sh->v6_denied) ||
825 (!check_ipv6_listed(sh->v6_denied, &v6->sin6_addr))));
826 break;
827
828 case AF_UNIX:
829 ok = GNUNET_OK; /* controlled using file-system ACL now */
830 break;
831
832 default:
833 LOG(GNUNET_ERROR_TYPE_WARNING,
834 _("Unknown address family %d\n"),
835 sa.ss_family);
836 return;
837 }
838 if (!ok)
839 {
840 LOG(GNUNET_ERROR_TYPE_DEBUG,
841 "Service rejected incoming connection from %s due to policy.\n",
842 GNUNET_a2s((const struct sockaddr *)&sa, addrlen));
843 GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock));
844 continue;
845 }
846 LOG(GNUNET_ERROR_TYPE_DEBUG,
847 "Service accepted incoming connection from %s.\n",
848 GNUNET_a2s((const struct sockaddr *)&sa, addrlen));
849 start_client(slc->sh, sock);
850 } 848 }
849 LOG (GNUNET_ERROR_TYPE_DEBUG,
850 "Service accepted incoming connection from %s.\n",
851 GNUNET_a2s ((const struct sockaddr *) &sa, addrlen));
852 start_client (slc->sh, sock);
853 }
851 if (0 != sh->suspend_state) 854 if (0 != sh->suspend_state)
852 return; 855 return;
853 slc->listen_task = 856 slc->listen_task =
854 GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, 857 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
855 slc->listen_socket, 858 slc->listen_socket,
856 &accept_client, 859 &accept_client,
857 slc); 860 slc);
858} 861}
859 862
860 863
@@ -866,23 +869,23 @@ accept_client(void *cls)
866 * or #SUSPEND_STATE_NONE on first startup 869 * or #SUSPEND_STATE_NONE on first startup
867 */ 870 */
868static void 871static void
869do_resume(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) 872do_resume (struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
870{ 873{
871 struct ServiceListenContext *slc; 874 struct ServiceListenContext *slc;
872 875
873 GNUNET_assert((SUSPEND_STATE_NONE == sr) || (0 != (sh->suspend_state & sr))); 876 GNUNET_assert ((SUSPEND_STATE_NONE == sr) || (0 != (sh->suspend_state & sr)));
874 sh->suspend_state -= sr; 877 sh->suspend_state -= sr;
875 if (SUSPEND_STATE_NONE != sh->suspend_state) 878 if (SUSPEND_STATE_NONE != sh->suspend_state)
876 return; 879 return;
877 for (slc = sh->slc_head; NULL != slc; slc = slc->next) 880 for (slc = sh->slc_head; NULL != slc; slc = slc->next)
878 { 881 {
879 GNUNET_assert(NULL == slc->listen_task); 882 GNUNET_assert (NULL == slc->listen_task);
880 slc->listen_task = 883 slc->listen_task =
881 GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, 884 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
882 slc->listen_socket, 885 slc->listen_socket,
883 &accept_client, 886 &accept_client,
884 slc); 887 slc);
885 } 888 }
886} 889}
887 890
888 891
@@ -894,23 +897,24 @@ do_resume(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
894 * @param cls our `struct GNUNET_SERVICE_Handle` 897 * @param cls our `struct GNUNET_SERVICE_Handle`
895 */ 898 */
896static void 899static void
897service_main(void *cls) 900service_main (void *cls)
898{ 901{
899 struct GNUNET_SERVICE_Handle *sh = cls; 902 struct GNUNET_SERVICE_Handle *sh = cls;
900 903
901 if (GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN != sh->options) 904 if (GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN !=
902 GNUNET_SCHEDULER_add_shutdown(&service_shutdown, sh); 905 (sh->options & GNUNET_SERVICE_OPTION_SHUTDOWN_BITMASK))
903 do_resume(sh, SUSPEND_STATE_NONE); 906 GNUNET_SCHEDULER_add_shutdown (&service_shutdown, sh);
907 do_resume (sh, SUSPEND_STATE_NONE);
904 908
905 if (-1 != sh->ready_confirm_fd) 909 if (-1 != sh->ready_confirm_fd)
906 { 910 {
907 GNUNET_break(1 == write(sh->ready_confirm_fd, ".", 1)); 911 GNUNET_break (1 == write (sh->ready_confirm_fd, ".", 1));
908 GNUNET_break(0 == close(sh->ready_confirm_fd)); 912 GNUNET_break (0 == close (sh->ready_confirm_fd));
909 sh->ready_confirm_fd = -1; 913 sh->ready_confirm_fd = -1;
910 } 914 }
911 915
912 if (NULL != sh->service_init_cb) 916 if (NULL != sh->service_init_cb)
913 sh->service_init_cb(sh->cb_cls, sh->cfg, sh); 917 sh->service_init_cb (sh->cb_cls, sh->cfg, sh);
914} 918}
915 919
916 920
@@ -924,33 +928,33 @@ service_main(void *cls)
924 * no ACL configured) 928 * no ACL configured)
925 */ 929 */
926static int 930static int
927process_acl4(struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, 931process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret,
928 struct GNUNET_SERVICE_Handle *sh, 932 struct GNUNET_SERVICE_Handle *sh,
929 const char *option) 933 const char *option)
930{ 934{
931 char *opt; 935 char *opt;
932 936
933 if (!GNUNET_CONFIGURATION_have_value(sh->cfg, sh->service_name, option)) 937 if (! GNUNET_CONFIGURATION_have_value (sh->cfg, sh->service_name, option))
934 { 938 {
935 *ret = NULL; 939 *ret = NULL;
936 return GNUNET_OK; 940 return GNUNET_OK;
937 } 941 }
938 GNUNET_break(GNUNET_OK == 942 GNUNET_break (GNUNET_OK ==
939 GNUNET_CONFIGURATION_get_value_string(sh->cfg, 943 GNUNET_CONFIGURATION_get_value_string (sh->cfg,
940 sh->service_name, 944 sh->service_name,
941 option, 945 option,
942 &opt)); 946 &opt));
943 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy(opt))) 947 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy (opt)))
944 { 948 {
945 LOG(GNUNET_ERROR_TYPE_WARNING, 949 LOG (GNUNET_ERROR_TYPE_WARNING,
946 _("Could not parse IPv4 network specification `%s' for `%s:%s'\n"), 950 _ ("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
947 opt, 951 opt,
948 sh->service_name, 952 sh->service_name,
949 option); 953 option);
950 GNUNET_free(opt); 954 GNUNET_free (opt);
951 return GNUNET_SYSERR; 955 return GNUNET_SYSERR;
952 } 956 }
953 GNUNET_free(opt); 957 GNUNET_free (opt);
954 return GNUNET_OK; 958 return GNUNET_OK;
955} 959}
956 960
@@ -965,33 +969,33 @@ process_acl4(struct GNUNET_STRINGS_IPv4NetworkPolicy **ret,
965 * no ACL configured) 969 * no ACL configured)
966 */ 970 */
967static int 971static int
968process_acl6(struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, 972process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret,
969 struct GNUNET_SERVICE_Handle *sh, 973 struct GNUNET_SERVICE_Handle *sh,
970 const char *option) 974 const char *option)
971{ 975{
972 char *opt; 976 char *opt;
973 977
974 if (!GNUNET_CONFIGURATION_have_value(sh->cfg, sh->service_name, option)) 978 if (! GNUNET_CONFIGURATION_have_value (sh->cfg, sh->service_name, option))
975 { 979 {
976 *ret = NULL; 980 *ret = NULL;
977 return GNUNET_OK; 981 return GNUNET_OK;
978 } 982 }
979 GNUNET_break(GNUNET_OK == 983 GNUNET_break (GNUNET_OK ==
980 GNUNET_CONFIGURATION_get_value_string(sh->cfg, 984 GNUNET_CONFIGURATION_get_value_string (sh->cfg,
981 sh->service_name, 985 sh->service_name,
982 option, 986 option,
983 &opt)); 987 &opt));
984 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy(opt))) 988 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy (opt)))
985 { 989 {
986 LOG(GNUNET_ERROR_TYPE_WARNING, 990 LOG (GNUNET_ERROR_TYPE_WARNING,
987 _("Could not parse IPv6 network specification `%s' for `%s:%s'\n"), 991 _ ("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
988 opt, 992 opt,
989 sh->service_name, 993 sh->service_name,
990 option); 994 option);
991 GNUNET_free(opt); 995 GNUNET_free (opt);
992 return GNUNET_SYSERR; 996 return GNUNET_SYSERR;
993 } 997 }
994 GNUNET_free(opt); 998 GNUNET_free (opt);
995 return GNUNET_OK; 999 return GNUNET_OK;
996} 1000}
997 1001
@@ -1003,34 +1007,27 @@ process_acl6(struct GNUNET_STRINGS_IPv6NetworkPolicy **ret,
1003 * @param saddrs array to update 1007 * @param saddrs array to update
1004 * @param saddrlens where to store the address length 1008 * @param saddrlens where to store the address length
1005 * @param unixpath path to add 1009 * @param unixpath path to add
1006 * @param abstract #GNUNET_YES to add an abstract UNIX domain socket. This
1007 * parameter is ignore on systems other than LINUX
1008 */ 1010 */
1009static void 1011static void
1010add_unixpath(struct sockaddr **saddrs, 1012add_unixpath (struct sockaddr **saddrs,
1011 socklen_t *saddrlens, 1013 socklen_t *saddrlens,
1012 const char *unixpath, 1014 const char *unixpath)
1013 int abstract)
1014{ 1015{
1015#ifdef AF_UNIX 1016#ifdef AF_UNIX
1016 struct sockaddr_un *un; 1017 struct sockaddr_un *un;
1017 1018
1018 un = GNUNET_new(struct sockaddr_un); 1019 un = GNUNET_new (struct sockaddr_un);
1019 un->sun_family = AF_UNIX; 1020 un->sun_family = AF_UNIX;
1020 GNUNET_strlcpy(un->sun_path, unixpath, sizeof(un->sun_path)); 1021 GNUNET_strlcpy (un->sun_path, unixpath, sizeof(un->sun_path));
1021#ifdef LINUX
1022 if (GNUNET_YES == abstract)
1023 un->sun_path[0] = '\0';
1024#endif
1025#if HAVE_SOCKADDR_UN_SUN_LEN 1022#if HAVE_SOCKADDR_UN_SUN_LEN
1026 un->sun_len = (u_char)sizeof(struct sockaddr_un); 1023 un->sun_len = (u_char) sizeof(struct sockaddr_un);
1027#endif 1024#endif
1028 *saddrs = (struct sockaddr *)un; 1025 *saddrs = (struct sockaddr *) un;
1029 *saddrlens = sizeof(struct sockaddr_un); 1026 *saddrlens = sizeof(struct sockaddr_un);
1030#else 1027#else
1031 /* this function should never be called 1028 /* this function should never be called
1032 * unless AF_UNIX is defined! */ 1029 * unless AF_UNIX is defined! */
1033 GNUNET_assert(0); 1030 GNUNET_assert (0);
1034#endif 1031#endif
1035} 1032}
1036 1033
@@ -1056,10 +1053,10 @@ add_unixpath(struct sockaddr **saddrs,
1056 * set to NULL). 1053 * set to NULL).
1057 */ 1054 */
1058static int 1055static int
1059get_server_addresses(const char *service_name, 1056get_server_addresses (const char *service_name,
1060 const struct GNUNET_CONFIGURATION_Handle *cfg, 1057 const struct GNUNET_CONFIGURATION_Handle *cfg,
1061 struct sockaddr ***addrs, 1058 struct sockaddr ***addrs,
1062 socklen_t **addr_lens) 1059 socklen_t **addr_lens)
1063{ 1060{
1064 int disablev6; 1061 int disablev6;
1065 struct GNUNET_NETWORK_Handle *desc; 1062 struct GNUNET_NETWORK_Handle *desc;
@@ -1072,7 +1069,6 @@ get_server_addresses(const char *service_name,
1072 unsigned int i; 1069 unsigned int i;
1073 int resi; 1070 int resi;
1074 int ret; 1071 int ret;
1075 int abstract;
1076 struct sockaddr **saddrs; 1072 struct sockaddr **saddrs;
1077 socklen_t *saddrlens; 1073 socklen_t *saddrlens;
1078 char *hostname; 1074 char *hostname;
@@ -1081,273 +1077,264 @@ get_server_addresses(const char *service_name,
1081 *addr_lens = NULL; 1077 *addr_lens = NULL;
1082 desc = NULL; 1078 desc = NULL;
1083 disablev6 = GNUNET_NO; 1079 disablev6 = GNUNET_NO;
1084 if ((GNUNET_NO == GNUNET_NETWORK_test_pf(PF_INET6)) || 1080 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
1085 (GNUNET_YES == 1081 (GNUNET_YES ==
1086 GNUNET_CONFIGURATION_get_value_yesno(cfg, service_name, "DISABLEV6"))) 1082 GNUNET_CONFIGURATION_get_value_yesno (cfg, service_name, "DISABLEV6")))
1087 disablev6 = GNUNET_YES; 1083 disablev6 = GNUNET_YES;
1088 1084
1089 port = 0; 1085 port = 0;
1090 if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "PORT")) 1086 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT"))
1087 {
1088 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
1089 service_name,
1090 "PORT",
1091 &port))
1091 { 1092 {
1092 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number(cfg, 1093 LOG (GNUNET_ERROR_TYPE_ERROR,
1093 service_name, 1094 _ ("Require valid port number for service `%s' in configuration!\n"),
1094 "PORT", 1095 service_name);
1095 &port))
1096 {
1097 LOG(GNUNET_ERROR_TYPE_ERROR,
1098 _("Require valid port number for service `%s' in configuration!\n"),
1099 service_name);
1100 }
1101 if (port > 65535)
1102 {
1103 LOG(GNUNET_ERROR_TYPE_ERROR,
1104 _("Require valid port number for service `%s' in configuration!\n"),
1105 service_name);
1106 return GNUNET_SYSERR;
1107 }
1108 } 1096 }
1109 1097 if (port > 65535)
1110 if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "BINDTO"))
1111 { 1098 {
1112 GNUNET_break(GNUNET_OK == 1099 LOG (GNUNET_ERROR_TYPE_ERROR,
1113 GNUNET_CONFIGURATION_get_value_string(cfg, 1100 _ ("Require valid port number for service `%s' in configuration!\n"),
1101 service_name);
1102 return GNUNET_SYSERR;
1103 }
1104 }
1105
1106 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO"))
1107 {
1108 GNUNET_break (GNUNET_OK ==
1109 GNUNET_CONFIGURATION_get_value_string (cfg,
1114 service_name, 1110 service_name,
1115 "BINDTO", 1111 "BINDTO",
1116 &hostname)); 1112 &hostname));
1117 } 1113 }
1118 else 1114 else
1119 hostname = NULL; 1115 hostname = NULL;
1120 1116
1121 unixpath = NULL; 1117 unixpath = NULL;
1122 abstract = GNUNET_NO;
1123#ifdef AF_UNIX 1118#ifdef AF_UNIX
1124 if ((GNUNET_YES == 1119 if ((GNUNET_YES ==
1125 GNUNET_CONFIGURATION_have_value(cfg, service_name, "UNIXPATH")) && 1120 GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) &&
1126 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename(cfg, 1121 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg,
1127 service_name, 1122 service_name,
1128 "UNIXPATH", 1123 "UNIXPATH",
1129 &unixpath)) && 1124 &unixpath)) &&
1130 (0 < strlen(unixpath))) 1125 (0 < strlen (unixpath)))
1126 {
1127 /* probe UNIX support */
1128 struct sockaddr_un s_un;
1129
1130 if (strlen (unixpath) >= sizeof(s_un.sun_path))
1131 { 1131 {
1132 /* probe UNIX support */ 1132 LOG (GNUNET_ERROR_TYPE_WARNING,
1133 struct sockaddr_un s_un; 1133 _ ("UNIXPATH `%s' too long, maximum length is %llu\n"),
1134 1134 unixpath,
1135 if (strlen(unixpath) >= sizeof(s_un.sun_path)) 1135 (unsigned long long) sizeof(s_un.sun_path));
1136 { 1136 unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
1137 LOG(GNUNET_ERROR_TYPE_WARNING, 1137 LOG (GNUNET_ERROR_TYPE_INFO, _ ("Using `%s' instead\n"), unixpath);
1138 _("UNIXPATH `%s' too long, maximum length is %llu\n"),
1139 unixpath,
1140 (unsigned long long)sizeof(s_un.sun_path));
1141 unixpath = GNUNET_NETWORK_shorten_unixpath(unixpath);
1142 LOG(GNUNET_ERROR_TYPE_INFO, _("Using `%s' instead\n"), unixpath);
1143 }
1144#ifdef LINUX
1145 abstract = GNUNET_CONFIGURATION_get_value_yesno(cfg,
1146 "TESTING",
1147 "USE_ABSTRACT_SOCKETS");
1148 if (GNUNET_SYSERR == abstract)
1149 abstract = GNUNET_NO;
1150#endif
1151 if ((GNUNET_YES != abstract) &&
1152 (GNUNET_OK != GNUNET_DISK_directory_create_for_file(unixpath)))
1153 GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_ERROR, "mkdir", unixpath);
1154 } 1138 }
1139 if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (unixpath))
1140 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "mkdir", unixpath);
1141 }
1155 if (NULL != unixpath) 1142 if (NULL != unixpath)
1143 {
1144 desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
1145 if (NULL == desc)
1156 { 1146 {
1157 desc = GNUNET_NETWORK_socket_create(AF_UNIX, SOCK_STREAM, 0); 1147 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
1158 if (NULL == desc) 1148 (EACCES == errno))
1159 { 1149 {
1160 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || 1150 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
1161 (EACCES == errno)) 1151 GNUNET_free_non_null (hostname);
1162 { 1152 GNUNET_free (unixpath);
1163 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "socket"); 1153 return GNUNET_SYSERR;
1164 GNUNET_free_non_null(hostname); 1154 }
1165 GNUNET_free(unixpath); 1155 LOG (GNUNET_ERROR_TYPE_INFO,
1166 return GNUNET_SYSERR; 1156 _ (
1167 } 1157 "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
1168 LOG(GNUNET_ERROR_TYPE_INFO, 1158 service_name,
1169 _( 1159 strerror (errno));
1170 "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"), 1160 GNUNET_free (unixpath);
1171 service_name, 1161 unixpath = NULL;
1172 strerror(errno));
1173 GNUNET_free(unixpath);
1174 unixpath = NULL;
1175 }
1176 else
1177 {
1178 GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(desc));
1179 desc = NULL;
1180 }
1181 } 1162 }
1163 else
1164 {
1165 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
1166 desc = NULL;
1167 }
1168 }
1182#endif 1169#endif
1183 1170
1184 if ((0 == port) && (NULL == unixpath)) 1171 if ((0 == port) && (NULL == unixpath))
1172 {
1173 LOG (GNUNET_ERROR_TYPE_ERROR,
1174 _ (
1175 "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
1176 service_name);
1177 GNUNET_free_non_null (hostname);
1178 return GNUNET_SYSERR;
1179 }
1180 if (0 == port)
1181 {
1182 saddrs = GNUNET_new_array (2, struct sockaddr *);
1183 saddrlens = GNUNET_new_array (2, socklen_t);
1184 add_unixpath (saddrs, saddrlens, unixpath);
1185 GNUNET_free_non_null (unixpath);
1186 GNUNET_free_non_null (hostname);
1187 *addrs = saddrs;
1188 *addr_lens = saddrlens;
1189 return 1;
1190 }
1191
1192 if (NULL != hostname)
1193 {
1194 LOG (GNUNET_ERROR_TYPE_DEBUG,
1195 "Resolving `%s' since that is where `%s' will bind to.\n",
1196 hostname,
1197 service_name);
1198 memset (&hints, 0, sizeof(struct addrinfo));
1199 if (disablev6)
1200 hints.ai_family = AF_INET;
1201 hints.ai_protocol = IPPROTO_TCP;
1202 if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
1203 (NULL == res))
1185 { 1204 {
1186 LOG(GNUNET_ERROR_TYPE_ERROR, 1205 LOG (GNUNET_ERROR_TYPE_ERROR,
1187 _( 1206 _ ("Failed to resolve `%s': %s\n"),
1188 "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"), 1207 hostname,
1189 service_name); 1208 gai_strerror (ret));
1190 GNUNET_free_non_null(hostname); 1209 GNUNET_free (hostname);
1210 GNUNET_free_non_null (unixpath);
1191 return GNUNET_SYSERR; 1211 return GNUNET_SYSERR;
1192 } 1212 }
1193 if (0 == port) 1213 next = res;
1214 i = 0;
1215 while (NULL != (pos = next))
1194 { 1216 {
1195 saddrs = GNUNET_new_array(2, struct sockaddr *); 1217 next = pos->ai_next;
1196 saddrlens = GNUNET_new_array(2, socklen_t); 1218 if ((disablev6) && (pos->ai_family == AF_INET6))
1197 add_unixpath(saddrs, saddrlens, unixpath, abstract); 1219 continue;
1198 GNUNET_free_non_null(unixpath); 1220 i++;
1199 GNUNET_free_non_null(hostname);
1200 *addrs = saddrs;
1201 *addr_lens = saddrlens;
1202 return 1;
1203 } 1221 }
1204 1222 if (0 == i)
1205 if (NULL != hostname)
1206 { 1223 {
1207 LOG(GNUNET_ERROR_TYPE_DEBUG, 1224 LOG (GNUNET_ERROR_TYPE_ERROR,
1208 "Resolving `%s' since that is where `%s' will bind to.\n", 1225 _ ("Failed to find %saddress for `%s'.\n"),
1209 hostname, 1226 disablev6 ? "IPv4 " : "",
1210 service_name); 1227 hostname);
1211 memset(&hints, 0, sizeof(struct addrinfo)); 1228 freeaddrinfo (res);
1212 if (disablev6) 1229 GNUNET_free (hostname);
1213 hints.ai_family = AF_INET; 1230 GNUNET_free_non_null (unixpath);
1214 hints.ai_protocol = IPPROTO_TCP; 1231 return GNUNET_SYSERR;
1215 if ((0 != (ret = getaddrinfo(hostname, NULL, &hints, &res))) || 1232 }
1216 (NULL == res)) 1233 resi = i;
1217 { 1234 if (NULL != unixpath)
1218 LOG(GNUNET_ERROR_TYPE_ERROR, 1235 resi++;
1219 _("Failed to resolve `%s': %s\n"), 1236 saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
1220 hostname, 1237 saddrlens = GNUNET_new_array (resi + 1, socklen_t);
1221 gai_strerror(ret)); 1238 i = 0;
1222 GNUNET_free(hostname); 1239 if (NULL != unixpath)
1223 GNUNET_free_non_null(unixpath); 1240 {
1224 return GNUNET_SYSERR; 1241 add_unixpath (saddrs, saddrlens, unixpath);
1225 } 1242 i++;
1226 next = res; 1243 }
1227 i = 0; 1244 next = res;
1228 while (NULL != (pos = next)) 1245 while (NULL != (pos = next))
1229 { 1246 {
1230 next = pos->ai_next; 1247 next = pos->ai_next;
1231 if ((disablev6) && (pos->ai_family == AF_INET6)) 1248 if ((disablev6) && (AF_INET6 == pos->ai_family))
1232 continue; 1249 continue;
1233 i++; 1250 if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
1234 } 1251 continue; /* not TCP */
1235 if (0 == i) 1252 if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
1236 { 1253 continue; /* huh? */
1237 LOG(GNUNET_ERROR_TYPE_ERROR, 1254 LOG (GNUNET_ERROR_TYPE_DEBUG,
1238 _("Failed to find %saddress for `%s'.\n"), 1255 "Service `%s' will bind to `%s'\n",
1239 disablev6 ? "IPv4 " : "", 1256 service_name,
1240 hostname); 1257 GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
1241 freeaddrinfo(res); 1258 if (AF_INET == pos->ai_family)
1242 GNUNET_free(hostname); 1259 {
1243 GNUNET_free_non_null(unixpath); 1260 GNUNET_assert (sizeof(struct sockaddr_in) == pos->ai_addrlen);
1244 return GNUNET_SYSERR; 1261 saddrlens[i] = pos->ai_addrlen;
1245 } 1262 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1246 resi = i; 1263 GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
1264 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1265 }
1266 else
1267 {
1268 GNUNET_assert (AF_INET6 == pos->ai_family);
1269 GNUNET_assert (sizeof(struct sockaddr_in6) == pos->ai_addrlen);
1270 saddrlens[i] = pos->ai_addrlen;
1271 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1272 GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
1273 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
1274 }
1275 i++;
1276 }
1277 GNUNET_free (hostname);
1278 freeaddrinfo (res);
1279 resi = i;
1280 }
1281 else
1282 {
1283 /* will bind against everything, just set port */
1284 if (disablev6)
1285 {
1286 /* V4-only */
1287 resi = 1;
1247 if (NULL != unixpath) 1288 if (NULL != unixpath)
1248 resi++; 1289 resi++;
1249 saddrs = GNUNET_new_array(resi + 1, struct sockaddr *);
1250 saddrlens = GNUNET_new_array(resi + 1, socklen_t);
1251 i = 0; 1290 i = 0;
1291 saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
1292 saddrlens = GNUNET_new_array (resi + 1, socklen_t);
1252 if (NULL != unixpath) 1293 if (NULL != unixpath)
1253 { 1294 {
1254 add_unixpath(saddrs, saddrlens, unixpath, abstract); 1295 add_unixpath (saddrs, saddrlens, unixpath);
1255 i++; 1296 i++;
1256 } 1297 }
1257 next = res; 1298 saddrlens[i] = sizeof(struct sockaddr_in);
1258 while (NULL != (pos = next)) 1299 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1259 {
1260 next = pos->ai_next;
1261 if ((disablev6) && (AF_INET6 == pos->ai_family))
1262 continue;
1263 if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
1264 continue; /* not TCP */
1265 if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
1266 continue; /* huh? */
1267 LOG(GNUNET_ERROR_TYPE_DEBUG,
1268 "Service `%s' will bind to `%s'\n",
1269 service_name,
1270 GNUNET_a2s(pos->ai_addr, pos->ai_addrlen));
1271 if (AF_INET == pos->ai_family)
1272 {
1273 GNUNET_assert(sizeof(struct sockaddr_in) == pos->ai_addrlen);
1274 saddrlens[i] = pos->ai_addrlen;
1275 saddrs[i] = GNUNET_malloc(saddrlens[i]);
1276 GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]);
1277 ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port);
1278 }
1279 else
1280 {
1281 GNUNET_assert(AF_INET6 == pos->ai_family);
1282 GNUNET_assert(sizeof(struct sockaddr_in6) == pos->ai_addrlen);
1283 saddrlens[i] = pos->ai_addrlen;
1284 saddrs[i] = GNUNET_malloc(saddrlens[i]);
1285 GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]);
1286 ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port);
1287 }
1288 i++;
1289 }
1290 GNUNET_free(hostname);
1291 freeaddrinfo(res);
1292 resi = i;
1293 }
1294 else
1295 {
1296 /* will bind against everything, just set port */
1297 if (disablev6)
1298 {
1299 /* V4-only */
1300 resi = 1;
1301 if (NULL != unixpath)
1302 resi++;
1303 i = 0;
1304 saddrs = GNUNET_new_array(resi + 1, struct sockaddr *);
1305 saddrlens = GNUNET_new_array(resi + 1, socklen_t);
1306 if (NULL != unixpath)
1307 {
1308 add_unixpath(saddrs, saddrlens, unixpath, abstract);
1309 i++;
1310 }
1311 saddrlens[i] = sizeof(struct sockaddr_in);
1312 saddrs[i] = GNUNET_malloc(saddrlens[i]);
1313#if HAVE_SOCKADDR_IN_SIN_LEN 1300#if HAVE_SOCKADDR_IN_SIN_LEN
1314 ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[i]; 1301 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
1315#endif 1302#endif
1316 ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET; 1303 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
1317 ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port); 1304 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1318 } 1305 }
1319 else 1306 else
1320 { 1307 {
1321 /* dual stack */ 1308 /* dual stack */
1322 resi = 2; 1309 resi = 2;
1323 if (NULL != unixpath) 1310 if (NULL != unixpath)
1324 resi++; 1311 resi++;
1325 saddrs = GNUNET_new_array(resi + 1, struct sockaddr *); 1312 saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
1326 saddrlens = GNUNET_new_array(resi + 1, socklen_t); 1313 saddrlens = GNUNET_new_array (resi + 1, socklen_t);
1327 i = 0; 1314 i = 0;
1328 if (NULL != unixpath) 1315 if (NULL != unixpath)
1329 { 1316 {
1330 add_unixpath(saddrs, saddrlens, unixpath, abstract); 1317 add_unixpath (saddrs, saddrlens, unixpath);
1331 i++; 1318 i++;
1332 } 1319 }
1333 saddrlens[i] = sizeof(struct sockaddr_in6); 1320 saddrlens[i] = sizeof(struct sockaddr_in6);
1334 saddrs[i] = GNUNET_malloc(saddrlens[i]); 1321 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1335#if HAVE_SOCKADDR_IN_SIN_LEN 1322#if HAVE_SOCKADDR_IN_SIN_LEN
1336 ((struct sockaddr_in6 *)saddrs[i])->sin6_len = saddrlens[0]; 1323 ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
1337#endif 1324#endif
1338 ((struct sockaddr_in6 *)saddrs[i])->sin6_family = AF_INET6; 1325 ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
1339 ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port); 1326 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
1340 i++; 1327 i++;
1341 saddrlens[i] = sizeof(struct sockaddr_in); 1328 saddrlens[i] = sizeof(struct sockaddr_in);
1342 saddrs[i] = GNUNET_malloc(saddrlens[i]); 1329 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1343#if HAVE_SOCKADDR_IN_SIN_LEN 1330#if HAVE_SOCKADDR_IN_SIN_LEN
1344 ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[1]; 1331 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
1345#endif 1332#endif
1346 ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET; 1333 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
1347 ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port); 1334 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1348 }
1349 } 1335 }
1350 GNUNET_free_non_null(unixpath); 1336 }
1337 GNUNET_free_non_null (unixpath);
1351 *addrs = saddrs; 1338 *addrs = saddrs;
1352 *addr_lens = saddrlens; 1339 *addr_lens = saddrlens;
1353 return resi; 1340 return resi;
@@ -1362,89 +1349,93 @@ get_server_addresses(const char *service_name,
1362 * @return NULL on error, otherwise the listen socket 1349 * @return NULL on error, otherwise the listen socket
1363 */ 1350 */
1364static struct GNUNET_NETWORK_Handle * 1351static struct GNUNET_NETWORK_Handle *
1365open_listen_socket(const struct sockaddr *server_addr, socklen_t socklen) 1352open_listen_socket (const struct sockaddr *server_addr,
1353 socklen_t socklen)
1366{ 1354{
1367 struct GNUNET_NETWORK_Handle *sock; 1355 struct GNUNET_NETWORK_Handle *sock;
1368 uint16_t port; 1356 uint16_t port;
1369 int eno; 1357 int eno;
1370 1358
1371 switch (server_addr->sa_family) 1359 switch (server_addr->sa_family)
1372 { 1360 {
1373 case AF_INET: 1361 case AF_INET:
1374 port = ntohs(((const struct sockaddr_in *)server_addr)->sin_port); 1362 port = ntohs (((const struct sockaddr_in *) server_addr)->sin_port);
1375 break; 1363 break;
1376 1364 case AF_INET6:
1377 case AF_INET6: 1365 port = ntohs (((const struct sockaddr_in6 *) server_addr)->sin6_port);
1378 port = ntohs(((const struct sockaddr_in6 *)server_addr)->sin6_port); 1366 break;
1379 break; 1367 case AF_UNIX:
1380 1368 port = 0;
1381 case AF_UNIX: 1369 break;
1382 port = 0; 1370 default:
1383 break; 1371 GNUNET_break (0);
1384 1372 port = 0;
1385 default: 1373 break;
1386 GNUNET_break(0); 1374 }
1387 port = 0; 1375 sock = GNUNET_NETWORK_socket_create (server_addr->sa_family,
1388 break; 1376 SOCK_STREAM,
1389 } 1377 0);
1390 sock = GNUNET_NETWORK_socket_create(server_addr->sa_family, SOCK_STREAM, 0);
1391 if (NULL == sock) 1378 if (NULL == sock)
1392 { 1379 {
1393 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "socket"); 1380 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1394 errno = 0; 1381 "socket");
1395 return NULL; 1382 errno = 0;
1396 } 1383 return NULL;
1384 }
1397 /* bind the socket */ 1385 /* bind the socket */
1398 if (GNUNET_OK != GNUNET_NETWORK_socket_bind(sock, server_addr, socklen)) 1386 if (GNUNET_OK !=
1387 GNUNET_NETWORK_socket_bind (sock,
1388 server_addr,
1389 socklen))
1390 {
1391 eno = errno;
1392 if (EADDRINUSE != errno)
1399 { 1393 {
1400 eno = errno; 1394 /* we don't log 'EADDRINUSE' here since an IPv4 bind may
1401 if (EADDRINUSE != errno) 1395 * fail if we already took the port on IPv6; if both IPv4 and
1402 { 1396 * IPv6 binds fail, then our caller will log using the
1403 /* we don't log 'EADDRINUSE' here since an IPv4 bind may 1397 * errno preserved in 'eno' */
1404 * fail if we already took the port on IPv6; if both IPv4 and 1398 if (0 != port)
1405 * IPv6 binds fail, then our caller will log using the 1399 LOG (GNUNET_ERROR_TYPE_ERROR,
1406 * errno preserved in 'eno' */ 1400 _ ("`%s' failed for port %d (%s).\n"),
1407 if (0 != port) 1401 "bind",
1408 LOG(GNUNET_ERROR_TYPE_ERROR, 1402 port,
1409 _("`%s' failed for port %d (%s).\n"), 1403 (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1410 "bind",
1411 port,
1412 (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1413 else
1414 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "bind");
1415 eno = 0;
1416 }
1417 else 1404 else
1418 { 1405 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "bind");
1419 if (0 != port) 1406 eno = 0;
1420 LOG(GNUNET_ERROR_TYPE_WARNING,
1421 _("`%s' failed for port %d (%s): address already in use\n"),
1422 "bind",
1423 port,
1424 (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1425 else if (AF_UNIX == server_addr->sa_family)
1426 {
1427 LOG(GNUNET_ERROR_TYPE_WARNING,
1428 _("`%s' failed for `%s': address already in use\n"),
1429 "bind",
1430 GNUNET_a2s(server_addr, socklen));
1431 }
1432 }
1433 GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock));
1434 errno = eno;
1435 return NULL;
1436 } 1407 }
1437 if (GNUNET_OK != GNUNET_NETWORK_socket_listen(sock, 5)) 1408 else
1438 { 1409 {
1439 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "listen"); 1410 if (0 != port)
1440 GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock)); 1411 LOG (GNUNET_ERROR_TYPE_WARNING,
1441 errno = 0; 1412 _ ("`%s' failed for port %d (%s): address already in use\n"),
1442 return NULL; 1413 "bind",
1414 port,
1415 (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1416 else if (AF_UNIX == server_addr->sa_family)
1417 {
1418 LOG (GNUNET_ERROR_TYPE_WARNING,
1419 _ ("`%s' failed for `%s': address already in use\n"),
1420 "bind",
1421 GNUNET_a2s (server_addr, socklen));
1422 }
1443 } 1423 }
1424 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
1425 errno = eno;
1426 return NULL;
1427 }
1428 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5))
1429 {
1430 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "listen");
1431 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
1432 errno = 0;
1433 return NULL;
1434 }
1444 if (0 != port) 1435 if (0 != port)
1445 LOG(GNUNET_ERROR_TYPE_DEBUG, 1436 LOG (GNUNET_ERROR_TYPE_DEBUG,
1446 "Server starts to listen on port %u.\n", 1437 "Server starts to listen on port %u.\n",
1447 port); 1438 port);
1448 return sock; 1439 return sock;
1449} 1440}
1450 1441
@@ -1466,128 +1457,141 @@ open_listen_socket(const struct sockaddr *server_addr, socklen_t socklen)
1466 * @return #GNUNET_OK if configuration succeeded 1457 * @return #GNUNET_OK if configuration succeeded
1467 */ 1458 */
1468static int 1459static int
1469setup_service(struct GNUNET_SERVICE_Handle *sh) 1460setup_service (struct GNUNET_SERVICE_Handle *sh)
1470{ 1461{
1471 int tolerant; 1462 int tolerant;
1463 struct GNUNET_NETWORK_Handle **csocks = NULL;
1472 struct GNUNET_NETWORK_Handle **lsocks; 1464 struct GNUNET_NETWORK_Handle **lsocks;
1473 const char *nfds; 1465 const char *nfds;
1474 unsigned int cnt; 1466 unsigned int cnt;
1475 int flags; 1467 int flags;
1476 char dummy[2]; 1468 char dummy[2];
1477 1469
1478 if (GNUNET_CONFIGURATION_have_value(sh->cfg, sh->service_name, "TOLERANT")) 1470 if (GNUNET_CONFIGURATION_have_value (sh->cfg,
1471 sh->service_name,
1472 "TOLERANT"))
1473 {
1474 if (GNUNET_SYSERR ==
1475 (tolerant = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
1476 sh->service_name,
1477 "TOLERANT")))
1479 { 1478 {
1480 if (GNUNET_SYSERR == 1479 LOG (GNUNET_ERROR_TYPE_ERROR,
1481 (tolerant = GNUNET_CONFIGURATION_get_value_yesno(sh->cfg, 1480 _ ("Specified value for `%s' of service `%s' is invalid\n"),
1482 sh->service_name, 1481 "TOLERANT",
1483 "TOLERANT"))) 1482 sh->service_name);
1484 { 1483 return GNUNET_SYSERR;
1485 LOG(GNUNET_ERROR_TYPE_ERROR,
1486 _("Specified value for `%s' of service `%s' is invalid\n"),
1487 "TOLERANT",
1488 sh->service_name);
1489 return GNUNET_SYSERR;
1490 }
1491 } 1484 }
1485 }
1492 else 1486 else
1493 tolerant = GNUNET_NO; 1487 tolerant = GNUNET_NO;
1494 1488
1495 lsocks = NULL; 1489 lsocks = NULL;
1496
1497 errno = 0; 1490 errno = 0;
1498 if ((NULL != (nfds = getenv("LISTEN_FDS"))) && 1491 if ((NULL != (nfds = getenv ("LISTEN_FDS"))) &&
1499 (1 == sscanf(nfds, "%u%1s", &cnt, dummy)) && (cnt > 0) && 1492 (1 == sscanf (nfds, "%u%1s", &cnt, dummy)) && (cnt > 0) &&
1500 (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE)) 1493 (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE))
1494 {
1495 lsocks = GNUNET_new_array (cnt + 1, struct GNUNET_NETWORK_Handle *);
1496 while (0 < cnt--)
1501 { 1497 {
1502 lsocks = GNUNET_new_array(cnt + 1, struct GNUNET_NETWORK_Handle *); 1498 flags = fcntl (3 + cnt, F_GETFD);
1503 while (0 < cnt--) 1499 if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) ||
1504 { 1500 (NULL == (lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt))))
1505 flags = fcntl(3 + cnt, F_GETFD); 1501 {
1506 if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) || 1502 LOG (GNUNET_ERROR_TYPE_ERROR,
1507 (NULL == (lsocks[cnt] = GNUNET_NETWORK_socket_box_native(3 + cnt)))) 1503 _ (
1508 { 1504 "Could not access pre-bound socket %u, will try to bind myself\n"),
1509 LOG(GNUNET_ERROR_TYPE_ERROR, 1505 (unsigned int) 3 + cnt);
1510 _( 1506 cnt++;
1511 "Could not access pre-bound socket %u, will try to bind myself\n"), 1507 while (NULL != lsocks[cnt])
1512 (unsigned int)3 + cnt); 1508 GNUNET_break (GNUNET_OK ==
1513 cnt++; 1509 GNUNET_NETWORK_socket_close (lsocks[cnt++]));
1514 while (NULL != lsocks[cnt]) 1510 GNUNET_free (lsocks);
1515 GNUNET_break(GNUNET_OK == 1511 lsocks = NULL;
1516 GNUNET_NETWORK_socket_close(lsocks[cnt++])); 1512 break;
1517 GNUNET_free(lsocks); 1513 }
1518 lsocks = NULL;
1519 break;
1520 }
1521 }
1522 unsetenv("LISTEN_FDS");
1523 } 1514 }
1515 unsetenv ("LISTEN_FDS");
1516 }
1517 if ( (0 != (GNUNET_SERVICE_OPTION_CLOSE_LSOCKS & sh->options)) &&
1518 (NULL != lsocks) )
1519 {
1520 csocks = lsocks;
1521 lsocks = NULL;
1522 }
1524 1523
1525 if (NULL != lsocks) 1524 if (NULL != lsocks)
1525 {
1526 /* listen only on inherited sockets if we have any */
1527 for (struct GNUNET_NETWORK_Handle **ls = lsocks; NULL != *ls; ls++)
1526 { 1528 {
1527 /* listen only on inherited sockets if we have any */ 1529 struct ServiceListenContext *slc;
1528 struct GNUNET_NETWORK_Handle **ls; 1530
1529 1531 slc = GNUNET_new (struct ServiceListenContext);
1530 for (ls = lsocks; NULL != *ls; ls++) 1532 slc->sh = sh;
1531 { 1533 slc->listen_socket = *ls;
1532 struct ServiceListenContext *slc; 1534 GNUNET_CONTAINER_DLL_insert (sh->slc_head, sh->slc_tail, slc);
1533
1534 slc = GNUNET_new(struct ServiceListenContext);
1535 slc->sh = sh;
1536 slc->listen_socket = *ls;
1537 GNUNET_CONTAINER_DLL_insert(sh->slc_head, sh->slc_tail, slc);
1538 }
1539 GNUNET_free(lsocks);
1540 } 1535 }
1536 GNUNET_free (lsocks);
1537 }
1541 else 1538 else
1542 { 1539 {
1543 struct sockaddr **addrs; 1540 struct sockaddr **addrs;
1544 socklen_t *addrlens; 1541 socklen_t *addrlens;
1545 int num; 1542 int num;
1546 1543
1547 num = get_server_addresses(sh->service_name, sh->cfg, &addrs, &addrlens); 1544 num = get_server_addresses (sh->service_name, sh->cfg, &addrs, &addrlens);
1548 if (GNUNET_SYSERR == num) 1545 if (GNUNET_SYSERR == num)
1549 return GNUNET_SYSERR; 1546 return GNUNET_SYSERR;
1550 1547
1551 for (int i = 0; i < num; i++) 1548 for (int i = 0; i < num; i++)
1552 { 1549 {
1553 struct ServiceListenContext *slc; 1550 struct ServiceListenContext *slc;
1554
1555 slc = GNUNET_new(struct ServiceListenContext);
1556 slc->sh = sh;
1557 slc->listen_socket = open_listen_socket(addrs[i], addrlens[i]);
1558 GNUNET_free(addrs[i]);
1559 if (NULL == slc->listen_socket)
1560 {
1561 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "bind");
1562 GNUNET_free(slc);
1563 continue;
1564 }
1565 GNUNET_CONTAINER_DLL_insert(sh->slc_head, sh->slc_tail, slc);
1566 }
1567 GNUNET_free_non_null(addrlens);
1568 GNUNET_free_non_null(addrs);
1569 if ((0 != num) && (NULL == sh->slc_head))
1570 {
1571 /* All attempts to bind failed, hard failure */
1572 GNUNET_log(
1573 GNUNET_ERROR_TYPE_ERROR,
1574 _(
1575 "Could not bind to any of the ports I was supposed to, refusing to run!\n"));
1576 return GNUNET_SYSERR;
1577 }
1578 }
1579 1551
1552 slc = GNUNET_new (struct ServiceListenContext);
1553 slc->sh = sh;
1554 slc->listen_socket = open_listen_socket (addrs[i], addrlens[i]);
1555 GNUNET_free (addrs[i]);
1556 if (NULL == slc->listen_socket)
1557 {
1558 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
1559 GNUNET_free (slc);
1560 continue;
1561 }
1562 GNUNET_CONTAINER_DLL_insert (sh->slc_head, sh->slc_tail, slc);
1563 }
1564 GNUNET_free_non_null (addrlens);
1565 GNUNET_free_non_null (addrs);
1566 if ((0 != num) && (NULL == sh->slc_head))
1567 {
1568 /* All attempts to bind failed, hard failure */
1569 GNUNET_log (
1570 GNUNET_ERROR_TYPE_ERROR,
1571 _ (
1572 "Could not bind to any of the ports I was supposed to, refusing to run!\n"));
1573 GNUNET_free_non_null (csocks);
1574 return GNUNET_SYSERR;
1575 }
1576 }
1577 if (NULL != csocks)
1578 {
1579 /* close inherited sockets to signal parent that we are ready */
1580 for (struct GNUNET_NETWORK_Handle **ls = csocks; NULL != *ls; ls++)
1581 GNUNET_NETWORK_socket_close (*ls);
1582 GNUNET_free (csocks);
1583 }
1580 sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES; 1584 sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
1581 sh->match_uid = GNUNET_CONFIGURATION_get_value_yesno(sh->cfg, 1585 sh->match_uid = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
1582 sh->service_name, 1586 sh->service_name,
1583 "UNIX_MATCH_UID"); 1587 "UNIX_MATCH_UID");
1584 sh->match_gid = GNUNET_CONFIGURATION_get_value_yesno(sh->cfg, 1588 sh->match_gid = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
1585 sh->service_name, 1589 sh->service_name,
1586 "UNIX_MATCH_GID"); 1590 "UNIX_MATCH_GID");
1587 process_acl4(&sh->v4_denied, sh, "REJECT_FROM"); 1591 process_acl4 (&sh->v4_denied, sh, "REJECT_FROM");
1588 process_acl4(&sh->v4_allowed, sh, "ACCEPT_FROM"); 1592 process_acl4 (&sh->v4_allowed, sh, "ACCEPT_FROM");
1589 process_acl6(&sh->v6_denied, sh, "REJECT_FROM6"); 1593 process_acl6 (&sh->v6_denied, sh, "REJECT_FROM6");
1590 process_acl6(&sh->v6_allowed, sh, "ACCEPT_FROM6"); 1594 process_acl6 (&sh->v6_allowed, sh, "ACCEPT_FROM6");
1591 return GNUNET_OK; 1595 return GNUNET_OK;
1592} 1596}
1593 1597
@@ -1600,14 +1604,14 @@ setup_service(struct GNUNET_SERVICE_Handle *sh)
1600 * @return value of the 'USERNAME' option 1604 * @return value of the 'USERNAME' option
1601 */ 1605 */
1602static char * 1606static char *
1603get_user_name(struct GNUNET_SERVICE_Handle *sh) 1607get_user_name (struct GNUNET_SERVICE_Handle *sh)
1604{ 1608{
1605 char *un; 1609 char *un;
1606 1610
1607 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(sh->cfg, 1611 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (sh->cfg,
1608 sh->service_name, 1612 sh->service_name,
1609 "USERNAME", 1613 "USERNAME",
1610 &un)) 1614 &un))
1611 return NULL; 1615 return NULL;
1612 return un; 1616 return un;
1613} 1617}
@@ -1620,45 +1624,45 @@ get_user_name(struct GNUNET_SERVICE_Handle *sh)
1620 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 1624 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1621 */ 1625 */
1622static int 1626static int
1623set_user_id(struct GNUNET_SERVICE_Handle *sh) 1627set_user_id (struct GNUNET_SERVICE_Handle *sh)
1624{ 1628{
1625 char *user; 1629 char *user;
1626 1630
1627 if (NULL == (user = get_user_name(sh))) 1631 if (NULL == (user = get_user_name (sh)))
1628 return GNUNET_OK; /* keep */ 1632 return GNUNET_OK; /* keep */
1629 1633
1630 struct passwd *pws; 1634 struct passwd *pws;
1631 1635
1632 errno = 0; 1636 errno = 0;
1633 pws = getpwnam(user); 1637 pws = getpwnam (user);
1634 if (NULL == pws) 1638 if (NULL == pws)
1635 { 1639 {
1636 LOG(GNUNET_ERROR_TYPE_ERROR, 1640 LOG (GNUNET_ERROR_TYPE_ERROR,
1637 _("Cannot obtain information about user `%s': %s\n"), 1641 _ ("Cannot obtain information about user `%s': %s\n"),
1638 user, 1642 user,
1639 errno == 0 ? _("No such user") : strerror(errno)); 1643 errno == 0 ? _ ("No such user") : strerror (errno));
1640 GNUNET_free(user); 1644 GNUNET_free (user);
1641 return GNUNET_SYSERR; 1645 return GNUNET_SYSERR;
1642 } 1646 }
1643 if ((0 != setgid(pws->pw_gid)) || (0 != setegid(pws->pw_gid)) || 1647 if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) ||
1644#if HAVE_INITGROUPS 1648#if HAVE_INITGROUPS
1645 (0 != initgroups(user, pws->pw_gid)) || 1649 (0 != initgroups (user, pws->pw_gid)) ||
1646#endif 1650#endif
1647 (0 != setuid(pws->pw_uid)) || (0 != seteuid(pws->pw_uid))) 1651 (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid)))
1652 {
1653 if ((0 != setregid (pws->pw_gid, pws->pw_gid)) ||
1654 (0 != setreuid (pws->pw_uid, pws->pw_uid)))
1648 { 1655 {
1649 if ((0 != setregid(pws->pw_gid, pws->pw_gid)) || 1656 LOG (GNUNET_ERROR_TYPE_ERROR,
1650 (0 != setreuid(pws->pw_uid, pws->pw_uid))) 1657 _ ("Cannot change user/group to `%s': %s\n"),
1651 { 1658 user,
1652 LOG(GNUNET_ERROR_TYPE_ERROR, 1659 strerror (errno));
1653 _("Cannot change user/group to `%s': %s\n"), 1660 GNUNET_free (user);
1654 user, 1661 return GNUNET_SYSERR;
1655 strerror(errno));
1656 GNUNET_free(user);
1657 return GNUNET_SYSERR;
1658 }
1659 } 1662 }
1663 }
1660 1664
1661 GNUNET_free(user); 1665 GNUNET_free (user);
1662 return GNUNET_OK; 1666 return GNUNET_OK;
1663} 1667}
1664 1668
@@ -1671,14 +1675,14 @@ set_user_id(struct GNUNET_SERVICE_Handle *sh)
1671 * @return name of the file for the process ID 1675 * @return name of the file for the process ID
1672 */ 1676 */
1673static char * 1677static char *
1674get_pid_file_name(struct GNUNET_SERVICE_Handle *sh) 1678get_pid_file_name (struct GNUNET_SERVICE_Handle *sh)
1675{ 1679{
1676 char *pif; 1680 char *pif;
1677 1681
1678 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(sh->cfg, 1682 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (sh->cfg,
1679 sh->service_name, 1683 sh->service_name,
1680 "PIDFILE", 1684 "PIDFILE",
1681 &pif)) 1685 &pif))
1682 return NULL; 1686 return NULL;
1683 return pif; 1687 return pif;
1684} 1688}
@@ -1690,15 +1694,15 @@ get_pid_file_name(struct GNUNET_SERVICE_Handle *sh)
1690 * @param sh service context 1694 * @param sh service context
1691 */ 1695 */
1692static void 1696static void
1693pid_file_delete(struct GNUNET_SERVICE_Handle *sh) 1697pid_file_delete (struct GNUNET_SERVICE_Handle *sh)
1694{ 1698{
1695 char *pif = get_pid_file_name(sh); 1699 char *pif = get_pid_file_name (sh);
1696 1700
1697 if (NULL == pif) 1701 if (NULL == pif)
1698 return; /* no PID file */ 1702 return; /* no PID file */
1699 if (0 != unlink(pif)) 1703 if (0 != unlink (pif))
1700 LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_WARNING, "unlink", pif); 1704 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", pif);
1701 GNUNET_free(pif); 1705 GNUNET_free (pif);
1702} 1706}
1703 1707
1704 1708
@@ -1709,73 +1713,73 @@ pid_file_delete(struct GNUNET_SERVICE_Handle *sh)
1709 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 1713 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1710 */ 1714 */
1711static int 1715static int
1712detach_terminal(struct GNUNET_SERVICE_Handle *sh) 1716detach_terminal (struct GNUNET_SERVICE_Handle *sh)
1713{ 1717{
1714 pid_t pid; 1718 pid_t pid;
1715 int nullfd; 1719 int nullfd;
1716 int filedes[2]; 1720 int filedes[2];
1717 1721
1718 if (0 != pipe(filedes)) 1722 if (0 != pipe (filedes))
1719 { 1723 {
1720 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "pipe"); 1724 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "pipe");
1721 return GNUNET_SYSERR; 1725 return GNUNET_SYSERR;
1722 } 1726 }
1723 pid = fork(); 1727 pid = fork ();
1724 if (pid < 0) 1728 if (pid < 0)
1725 { 1729 {
1726 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "fork"); 1730 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork");
1727 return GNUNET_SYSERR; 1731 return GNUNET_SYSERR;
1728 } 1732 }
1729 if (0 != pid) 1733 if (0 != pid)
1734 {
1735 /* Parent */
1736 char c;
1737
1738 GNUNET_break (0 == close (filedes[1]));
1739 c = 'X';
1740 if (1 != read (filedes[0], &c, sizeof(char)))
1741 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "read");
1742 fflush (stdout);
1743 switch (c)
1730 { 1744 {
1731 /* Parent */ 1745 case '.':
1732 char c; 1746 exit (0);
1733 1747
1734 GNUNET_break(0 == close(filedes[1])); 1748 case 'I':
1735 c = 'X'; 1749 LOG (GNUNET_ERROR_TYPE_INFO,
1736 if (1 != read(filedes[0], &c, sizeof(char))) 1750 _ ("Service process failed to initialize\n"));
1737 LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "read"); 1751 break;
1738 fflush(stdout); 1752
1739 switch (c) 1753 case 'S':
1740 { 1754 LOG (GNUNET_ERROR_TYPE_INFO,
1741 case '.': 1755 _ ("Service process could not initialize server function\n"));
1742 exit(0); 1756 break;
1743 1757
1744 case 'I': 1758 case 'X':
1745 LOG(GNUNET_ERROR_TYPE_INFO, 1759 LOG (GNUNET_ERROR_TYPE_INFO,
1746 _("Service process failed to initialize\n")); 1760 _ ("Service process failed to report status\n"));
1747 break; 1761 break;
1748
1749 case 'S':
1750 LOG(GNUNET_ERROR_TYPE_INFO,
1751 _("Service process could not initialize server function\n"));
1752 break;
1753
1754 case 'X':
1755 LOG(GNUNET_ERROR_TYPE_INFO,
1756 _("Service process failed to report status\n"));
1757 break;
1758 }
1759 exit(1); /* child reported error */
1760 } 1762 }
1761 GNUNET_break(0 == close(0)); 1763 exit (1); /* child reported error */
1762 GNUNET_break(0 == close(1)); 1764 }
1763 GNUNET_break(0 == close(filedes[0])); 1765 GNUNET_break (0 == close (0));
1764 nullfd = open("/dev/null", O_RDWR | O_APPEND); 1766 GNUNET_break (0 == close (1));
1767 GNUNET_break (0 == close (filedes[0]));
1768 nullfd = open ("/dev/null", O_RDWR | O_APPEND);
1765 if (nullfd < 0) 1769 if (nullfd < 0)
1766 return GNUNET_SYSERR; 1770 return GNUNET_SYSERR;
1767 /* set stdin/stdout to /dev/null */ 1771 /* set stdin/stdout to /dev/null */
1768 if ((dup2(nullfd, 0) < 0) || (dup2(nullfd, 1) < 0)) 1772 if ((dup2 (nullfd, 0) < 0) || (dup2 (nullfd, 1) < 0))
1769 { 1773 {
1770 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "dup2"); 1774 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2");
1771 (void)close(nullfd); 1775 (void) close (nullfd);
1772 return GNUNET_SYSERR; 1776 return GNUNET_SYSERR;
1773 } 1777 }
1774 (void)close(nullfd); 1778 (void) close (nullfd);
1775 /* Detach from controlling terminal */ 1779 /* Detach from controlling terminal */
1776 pid = setsid(); 1780 pid = setsid ();
1777 if (-1 == pid) 1781 if (-1 == pid)
1778 LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "setsid"); 1782 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "setsid");
1779 sh->ready_confirm_fd = filedes[1]; 1783 sh->ready_confirm_fd = filedes[1];
1780 1784
1781 return GNUNET_OK; 1785 return GNUNET_OK;
@@ -1789,23 +1793,23 @@ detach_terminal(struct GNUNET_SERVICE_Handle *sh)
1789 * @param sh handle to the service to tear down. 1793 * @param sh handle to the service to tear down.
1790 */ 1794 */
1791static void 1795static void
1792teardown_service(struct GNUNET_SERVICE_Handle *sh) 1796teardown_service (struct GNUNET_SERVICE_Handle *sh)
1793{ 1797{
1794 struct ServiceListenContext *slc; 1798 struct ServiceListenContext *slc;
1795 1799
1796 GNUNET_free_non_null(sh->v4_denied); 1800 GNUNET_free_non_null (sh->v4_denied);
1797 GNUNET_free_non_null(sh->v6_denied); 1801 GNUNET_free_non_null (sh->v6_denied);
1798 GNUNET_free_non_null(sh->v4_allowed); 1802 GNUNET_free_non_null (sh->v4_allowed);
1799 GNUNET_free_non_null(sh->v6_allowed); 1803 GNUNET_free_non_null (sh->v6_allowed);
1800 while (NULL != (slc = sh->slc_head)) 1804 while (NULL != (slc = sh->slc_head))
1801 { 1805 {
1802 GNUNET_CONTAINER_DLL_remove(sh->slc_head, sh->slc_tail, slc); 1806 GNUNET_CONTAINER_DLL_remove (sh->slc_head, sh->slc_tail, slc);
1803 if (NULL != slc->listen_task) 1807 if (NULL != slc->listen_task)
1804 GNUNET_SCHEDULER_cancel(slc->listen_task); 1808 GNUNET_SCHEDULER_cancel (slc->listen_task);
1805 GNUNET_break(GNUNET_OK == 1809 GNUNET_break (GNUNET_OK ==
1806 GNUNET_NETWORK_socket_close(slc->listen_socket)); 1810 GNUNET_NETWORK_socket_close (slc->listen_socket));
1807 GNUNET_free(slc); 1811 GNUNET_free (slc);
1808 } 1812 }
1809} 1813}
1810 1814
1811 1815
@@ -1816,7 +1820,7 @@ teardown_service(struct GNUNET_SERVICE_Handle *sh)
1816 * @param msg AGPL request 1820 * @param msg AGPL request
1817 */ 1821 */
1818static void 1822static void
1819return_agpl(void *cls, const struct GNUNET_MessageHeader *msg) 1823return_agpl (void *cls, const struct GNUNET_MessageHeader *msg)
1820{ 1824{
1821 struct GNUNET_SERVICE_Client *client = cls; 1825 struct GNUNET_SERVICE_Client *client = cls;
1822 struct GNUNET_MQ_Handle *mq; 1826 struct GNUNET_MQ_Handle *mq;
@@ -1824,13 +1828,13 @@ return_agpl(void *cls, const struct GNUNET_MessageHeader *msg)
1824 struct GNUNET_MessageHeader *res; 1828 struct GNUNET_MessageHeader *res;
1825 size_t slen; 1829 size_t slen;
1826 1830
1827 (void)msg; 1831 (void) msg;
1828 slen = strlen(GNUNET_AGPL_URL) + 1; 1832 slen = strlen (GNUNET_AGPL_URL) + 1;
1829 env = GNUNET_MQ_msg_extra(res, GNUNET_MESSAGE_TYPE_RESPONSE_AGPL, slen); 1833 env = GNUNET_MQ_msg_extra (res, GNUNET_MESSAGE_TYPE_RESPONSE_AGPL, slen);
1830 memcpy(&res[1], GNUNET_AGPL_URL, slen); 1834 memcpy (&res[1], GNUNET_AGPL_URL, slen);
1831 mq = GNUNET_SERVICE_client_get_mq(client); 1835 mq = GNUNET_SERVICE_client_get_mq (client);
1832 GNUNET_MQ_send(mq, env); 1836 GNUNET_MQ_send (mq, env);
1833 GNUNET_SERVICE_client_continue(client); 1837 GNUNET_SERVICE_client_continue (client);
1834} 1838}
1835 1839
1836 1840
@@ -1871,29 +1875,29 @@ return_agpl(void *cls, const struct GNUNET_MessageHeader *msg)
1871 * @return NULL on error 1875 * @return NULL on error
1872 */ 1876 */
1873struct GNUNET_SERVICE_Handle * 1877struct GNUNET_SERVICE_Handle *
1874GNUNET_SERVICE_start(const char *service_name, 1878GNUNET_SERVICE_start (const char *service_name,
1875 const struct GNUNET_CONFIGURATION_Handle *cfg, 1879 const struct GNUNET_CONFIGURATION_Handle *cfg,
1876 GNUNET_SERVICE_ConnectHandler connect_cb, 1880 GNUNET_SERVICE_ConnectHandler connect_cb,
1877 GNUNET_SERVICE_DisconnectHandler disconnect_cb, 1881 GNUNET_SERVICE_DisconnectHandler disconnect_cb,
1878 void *cls, 1882 void *cls,
1879 const struct GNUNET_MQ_MessageHandler *handlers) 1883 const struct GNUNET_MQ_MessageHandler *handlers)
1880{ 1884{
1881 struct GNUNET_SERVICE_Handle *sh; 1885 struct GNUNET_SERVICE_Handle *sh;
1882 1886
1883 sh = GNUNET_new(struct GNUNET_SERVICE_Handle); 1887 sh = GNUNET_new (struct GNUNET_SERVICE_Handle);
1884 sh->service_name = service_name; 1888 sh->service_name = service_name;
1885 sh->cfg = cfg; 1889 sh->cfg = cfg;
1886 sh->connect_cb = connect_cb; 1890 sh->connect_cb = connect_cb;
1887 sh->disconnect_cb = disconnect_cb; 1891 sh->disconnect_cb = disconnect_cb;
1888 sh->cb_cls = cls; 1892 sh->cb_cls = cls;
1889 sh->handlers = GNUNET_MQ_copy_handlers2(handlers, &return_agpl, NULL); 1893 sh->handlers = GNUNET_MQ_copy_handlers2 (handlers, &return_agpl, NULL);
1890 if (GNUNET_OK != setup_service(sh)) 1894 if (GNUNET_OK != setup_service (sh))
1891 { 1895 {
1892 GNUNET_free_non_null(sh->handlers); 1896 GNUNET_free_non_null (sh->handlers);
1893 GNUNET_free(sh); 1897 GNUNET_free (sh);
1894 return NULL; 1898 return NULL;
1895 } 1899 }
1896 do_resume(sh, SUSPEND_STATE_NONE); 1900 do_resume (sh, SUSPEND_STATE_NONE);
1897 return sh; 1901 return sh;
1898} 1902}
1899 1903
@@ -1904,16 +1908,16 @@ GNUNET_SERVICE_start(const char *service_name,
1904 * @param srv service to stop 1908 * @param srv service to stop
1905 */ 1909 */
1906void 1910void
1907GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv) 1911GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Handle *srv)
1908{ 1912{
1909 struct GNUNET_SERVICE_Client *client; 1913 struct GNUNET_SERVICE_Client *client;
1910 1914
1911 GNUNET_SERVICE_suspend(srv); 1915 GNUNET_SERVICE_suspend (srv);
1912 while (NULL != (client = srv->clients_head)) 1916 while (NULL != (client = srv->clients_head))
1913 GNUNET_SERVICE_client_drop(client); 1917 GNUNET_SERVICE_client_drop (client);
1914 teardown_service(srv); 1918 teardown_service (srv);
1915 GNUNET_free_non_null(srv->handlers); 1919 GNUNET_free_non_null (srv->handlers);
1916 GNUNET_free(srv); 1920 GNUNET_free (srv);
1917} 1921}
1918 1922
1919 1923
@@ -1959,15 +1963,15 @@ GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv)
1959 * @return 0 on success, non-zero on error 1963 * @return 0 on success, non-zero on error
1960 */ 1964 */
1961int 1965int
1962GNUNET_SERVICE_run_(int argc, 1966GNUNET_SERVICE_run_ (int argc,
1963 char *const *argv, 1967 char *const *argv,
1964 const char *service_name, 1968 const char *service_name,
1965 enum GNUNET_SERVICE_Options options, 1969 enum GNUNET_SERVICE_Options options,
1966 GNUNET_SERVICE_InitCallback service_init_cb, 1970 GNUNET_SERVICE_InitCallback service_init_cb,
1967 GNUNET_SERVICE_ConnectHandler connect_cb, 1971 GNUNET_SERVICE_ConnectHandler connect_cb,
1968 GNUNET_SERVICE_DisconnectHandler disconnect_cb, 1972 GNUNET_SERVICE_DisconnectHandler disconnect_cb,
1969 void *cls, 1973 void *cls,
1970 const struct GNUNET_MQ_MessageHandler *handlers) 1974 const struct GNUNET_MQ_MessageHandler *handlers)
1971{ 1975{
1972 struct GNUNET_SERVICE_Handle sh; 1976 struct GNUNET_SERVICE_Handle sh;
1973 1977
@@ -1986,40 +1990,40 @@ GNUNET_SERVICE_run_(int argc,
1986 struct GNUNET_CONFIGURATION_Handle *cfg; 1990 struct GNUNET_CONFIGURATION_Handle *cfg;
1987 int ret; 1991 int ret;
1988 int err; 1992 int err;
1989 const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get(); 1993 const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get ();
1990 1994 struct GNUNET_GETOPT_CommandLineOption service_options[] = {
1991 struct GNUNET_GETOPT_CommandLineOption service_options[] = 1995 GNUNET_GETOPT_option_cfgfile (&opt_cfg_filename),
1992 { GNUNET_GETOPT_option_cfgfile(&opt_cfg_filename), 1996 GNUNET_GETOPT_option_flag ('d',
1993 GNUNET_GETOPT_option_flag('d', 1997 "daemonize",
1994 "daemonize", 1998 gettext_noop (
1995 gettext_noop( 1999 "do daemonize (detach from terminal)"),
1996 "do daemonize (detach from terminal)"), 2000 &do_daemonize),
1997 &do_daemonize), 2001 GNUNET_GETOPT_option_help (NULL),
1998 GNUNET_GETOPT_option_help(NULL), 2002 GNUNET_GETOPT_option_loglevel (&loglev),
1999 GNUNET_GETOPT_option_loglevel(&loglev), 2003 GNUNET_GETOPT_option_logfile (&logfile),
2000 GNUNET_GETOPT_option_logfile(&logfile), 2004 GNUNET_GETOPT_option_version (pd->version),
2001 GNUNET_GETOPT_option_version(pd->version), 2005 GNUNET_GETOPT_OPTION_END
2002 GNUNET_GETOPT_OPTION_END }; 2006 };
2003 2007
2004 err = 1; 2008 err = 1;
2005 memset(&sh, 0, sizeof(sh)); 2009 memset (&sh, 0, sizeof(sh));
2006 xdg = getenv("XDG_CONFIG_HOME"); 2010 xdg = getenv ("XDG_CONFIG_HOME");
2007 if (NULL != xdg) 2011 if (NULL != xdg)
2008 GNUNET_asprintf(&cfg_filename, 2012 GNUNET_asprintf (&cfg_filename,
2009 "%s%s%s", 2013 "%s%s%s",
2010 xdg, 2014 xdg,
2011 DIR_SEPARATOR_STR, 2015 DIR_SEPARATOR_STR,
2012 pd->config_file); 2016 pd->config_file);
2013 else 2017 else
2014 cfg_filename = GNUNET_strdup(pd->user_config_file); 2018 cfg_filename = GNUNET_strdup (pd->user_config_file);
2015 sh.ready_confirm_fd = -1; 2019 sh.ready_confirm_fd = -1;
2016 sh.options = options; 2020 sh.options = options;
2017 sh.cfg = cfg = GNUNET_CONFIGURATION_create(); 2021 sh.cfg = cfg = GNUNET_CONFIGURATION_create ();
2018 sh.service_init_cb = service_init_cb; 2022 sh.service_init_cb = service_init_cb;
2019 sh.connect_cb = connect_cb; 2023 sh.connect_cb = connect_cb;
2020 sh.disconnect_cb = disconnect_cb; 2024 sh.disconnect_cb = disconnect_cb;
2021 sh.cb_cls = cls; 2025 sh.cb_cls = cls;
2022 sh.handlers = GNUNET_MQ_copy_handlers(handlers); 2026 sh.handlers = GNUNET_MQ_copy_handlers (handlers);
2023 sh.service_name = service_name; 2027 sh.service_name = service_name;
2024 sh.ret = 0; 2028 sh.ret = 0;
2025 /* setup subsystems */ 2029 /* setup subsystems */
@@ -2029,135 +2033,140 @@ GNUNET_SERVICE_run_(int argc,
2029 do_daemonize = 0; 2033 do_daemonize = 0;
2030#if ENABLE_NLS 2034#if ENABLE_NLS
2031 if (NULL != pd->gettext_domain) 2035 if (NULL != pd->gettext_domain)
2036 {
2037 setlocale (LC_ALL, "");
2038 path = (NULL == pd->gettext_path) ?
2039 GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LOCALEDIR) :
2040 GNUNET_strdup (pd->gettext_path);
2041 if (NULL != path)
2032 { 2042 {
2033 setlocale(LC_ALL, ""); 2043 bindtextdomain (pd->gettext_domain, path);
2034 path = (NULL == pd->gettext_path) ? 2044 GNUNET_free (path);
2035 GNUNET_OS_installation_get_path(GNUNET_OS_IPK_LOCALEDIR) :
2036 GNUNET_strdup(pd->gettext_path);
2037 if (NULL != path)
2038 {
2039 bindtextdomain(pd->gettext_domain, path);
2040 GNUNET_free(path);
2041 }
2042 textdomain(pd->gettext_domain);
2043 } 2045 }
2046 textdomain (pd->gettext_domain);
2047 }
2044#endif 2048#endif
2045 ret = GNUNET_GETOPT_run(service_name, service_options, argc, argv); 2049 ret = GNUNET_GETOPT_run (service_name,
2050 service_options,
2051 argc,
2052 argv);
2046 if (GNUNET_SYSERR == ret) 2053 if (GNUNET_SYSERR == ret)
2047 goto shutdown; 2054 goto shutdown;
2048 if (GNUNET_NO == ret) 2055 if (GNUNET_NO == ret)
2049 { 2056 {
2050 err = 0; 2057 err = 0;
2051 goto shutdown; 2058 goto shutdown;
2052 } 2059 }
2053 if (GNUNET_OK != GNUNET_log_setup(service_name, loglev, logfile)) 2060 if (GNUNET_OK != GNUNET_log_setup (service_name,
2054 { 2061 loglev,
2055 GNUNET_break(0); 2062 logfile))
2056 goto shutdown; 2063 {
2057 } 2064 GNUNET_break (0);
2065 goto shutdown;
2066 }
2058 if (NULL != opt_cfg_filename) 2067 if (NULL != opt_cfg_filename)
2068 {
2069 if ((GNUNET_YES != GNUNET_DISK_file_test (opt_cfg_filename)) ||
2070 (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_filename)))
2059 { 2071 {
2060 if ((GNUNET_YES != GNUNET_DISK_file_test(opt_cfg_filename)) || 2072 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2061 (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, opt_cfg_filename))) 2073 _ ("Malformed configuration file `%s', exit ...\n"),
2062 { 2074 opt_cfg_filename);
2063 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 2075 goto shutdown;
2064 _("Malformed configuration file `%s', exit ...\n"),
2065 opt_cfg_filename);
2066 goto shutdown;
2067 }
2068 } 2076 }
2077 }
2069 else 2078 else
2079 {
2080 if (GNUNET_YES == GNUNET_DISK_file_test (cfg_filename))
2070 { 2081 {
2071 if (GNUNET_YES == GNUNET_DISK_file_test(cfg_filename)) 2082 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cfg_filename))
2072 { 2083 {
2073 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, cfg_filename)) 2084 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2074 { 2085 _ ("Malformed configuration file `%s', exit ...\n"),
2075 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 2086 cfg_filename);
2076 _("Malformed configuration file `%s', exit ...\n"), 2087 goto shutdown;
2077 cfg_filename); 2088 }
2078 goto shutdown;
2079 }
2080 }
2081 else
2082 {
2083 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, NULL))
2084 {
2085 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
2086 _("Malformed configuration, exit ...\n"));
2087 goto shutdown;
2088 }
2089 }
2090 } 2089 }
2091 if (GNUNET_OK != setup_service(&sh)) 2090 else
2092 goto shutdown;
2093 if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal(&sh)))
2094 { 2091 {
2095 GNUNET_break(0); 2092 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL))
2096 goto shutdown; 2093 {
2094 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2095 _ ("Malformed configuration, exit ...\n"));
2096 goto shutdown;
2097 }
2097 } 2098 }
2098 if (GNUNET_OK != set_user_id(&sh)) 2099 }
2100 if (GNUNET_OK != setup_service (&sh))
2099 goto shutdown; 2101 goto shutdown;
2100 LOG(GNUNET_ERROR_TYPE_DEBUG, 2102 if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sh)))
2101 "Service `%s' runs with configuration from `%s'\n", 2103 {
2102 service_name, 2104 GNUNET_break (0);
2103 (NULL != opt_cfg_filename) ? opt_cfg_filename : cfg_filename); 2105 goto shutdown;
2104 if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(sh.cfg, 2106 }
2105 "TESTING", 2107 if (GNUNET_OK != set_user_id (&sh))
2106 "SKEW_OFFSET", 2108 goto shutdown;
2107 &skew_offset)) && 2109 LOG (GNUNET_ERROR_TYPE_DEBUG,
2108 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(sh.cfg, 2110 "Service `%s' runs with configuration from `%s'\n",
2109 "TESTING", 2111 service_name,
2110 "SKEW_VARIANCE", 2112 (NULL != opt_cfg_filename) ? opt_cfg_filename : cfg_filename);
2111 &skew_variance))) 2113 if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (sh.cfg,
2112 { 2114 "TESTING",
2113 clock_offset = skew_offset - skew_variance; 2115 "SKEW_OFFSET",
2114 GNUNET_TIME_set_offset(clock_offset); 2116 &skew_offset)) &&
2115 LOG(GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset); 2117 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (sh.cfg,
2116 } 2118 "TESTING",
2117 GNUNET_RESOLVER_connect(sh.cfg); 2119 "SKEW_VARIANCE",
2120 &skew_variance)))
2121 {
2122 clock_offset = skew_offset - skew_variance;
2123 GNUNET_TIME_set_offset (clock_offset);
2124 LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset);
2125 }
2126 GNUNET_RESOLVER_connect (sh.cfg);
2118 2127
2119 /* actually run service */ 2128 /* actually run service */
2120 err = 0; 2129 err = 0;
2121 GNUNET_SCHEDULER_run(&service_main, &sh); 2130 GNUNET_SCHEDULER_run (&service_main, &sh);
2122 /* shutdown */ 2131 /* shutdown */
2123 if (1 == do_daemonize) 2132 if (1 == do_daemonize)
2124 pid_file_delete(&sh); 2133 pid_file_delete (&sh);
2125 2134
2126shutdown: 2135shutdown:
2127 if (-1 != sh.ready_confirm_fd) 2136 if (-1 != sh.ready_confirm_fd)
2128 { 2137 {
2129 if (1 != write(sh.ready_confirm_fd, err ? "I" : "S", 1)) 2138 if (1 != write (sh.ready_confirm_fd, err ? "I" : "S", 1))
2130 LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "write"); 2139 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "write");
2131 GNUNET_break(0 == close(sh.ready_confirm_fd)); 2140 GNUNET_break (0 == close (sh.ready_confirm_fd));
2132 } 2141 }
2133#if HAVE_MALLINFO 2142#if HAVE_MALLINFO
2134 { 2143 {
2135 char *counter; 2144 char *counter;
2136 2145
2137 if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value(sh.cfg, 2146 if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value (sh.cfg,
2138 service_name, 2147 service_name,
2139 "GAUGER_HEAP")) && 2148 "GAUGER_HEAP")) &&
2140 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(sh.cfg, 2149 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (sh.cfg,
2141 service_name, 2150 service_name,
2142 "GAUGER_HEAP", 2151 "GAUGER_HEAP",
2143 &counter))) 2152 &counter)))
2144 { 2153 {
2145 struct mallinfo mi; 2154 struct mallinfo mi;
2146 2155
2147 mi = mallinfo(); 2156 mi = mallinfo ();
2148 GAUGER(service_name, counter, mi.usmblks, "blocks"); 2157 GAUGER (service_name, counter, mi.usmblks, "blocks");
2149 GNUNET_free(counter); 2158 GNUNET_free (counter);
2150 } 2159 }
2151 } 2160 }
2152#endif 2161#endif
2153 teardown_service(&sh); 2162 teardown_service (&sh);
2154 GNUNET_free_non_null(sh.handlers); 2163 GNUNET_free_non_null (sh.handlers);
2155 GNUNET_SPEEDUP_stop_(); 2164 GNUNET_SPEEDUP_stop_ ();
2156 GNUNET_CONFIGURATION_destroy(cfg); 2165 GNUNET_CONFIGURATION_destroy (cfg);
2157 GNUNET_free_non_null(logfile); 2166 GNUNET_free_non_null (logfile);
2158 GNUNET_free_non_null(loglev); 2167 GNUNET_free_non_null (loglev);
2159 GNUNET_free(cfg_filename); 2168 GNUNET_free (cfg_filename);
2160 GNUNET_free_non_null(opt_cfg_filename); 2169 GNUNET_free_non_null (opt_cfg_filename);
2161 2170
2162 return err ? GNUNET_SYSERR : sh.ret; 2171 return err ? GNUNET_SYSERR : sh.ret;
2163} 2172}
@@ -2170,9 +2179,9 @@ shutdown:
2170 * @param sh service to stop accepting connections. 2179 * @param sh service to stop accepting connections.
2171 */ 2180 */
2172void 2181void
2173GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh) 2182GNUNET_SERVICE_suspend (struct GNUNET_SERVICE_Handle *sh)
2174{ 2183{
2175 do_suspend(sh, SUSPEND_STATE_APP); 2184 do_suspend (sh, SUSPEND_STATE_APP);
2176} 2185}
2177 2186
2178 2187
@@ -2182,9 +2191,9 @@ GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh)
2182 * @param sh service to resume accepting connections. 2191 * @param sh service to resume accepting connections.
2183 */ 2192 */
2184void 2193void
2185GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh) 2194GNUNET_SERVICE_resume (struct GNUNET_SERVICE_Handle *sh)
2186{ 2195{
2187 do_resume(sh, SUSPEND_STATE_APP); 2196 do_resume (sh, SUSPEND_STATE_APP);
2188} 2197}
2189 2198
2190 2199
@@ -2195,32 +2204,32 @@ GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh)
2195 * @param cls our `struct GNUNET_SERVICE_Client` 2204 * @param cls our `struct GNUNET_SERVICE_Client`
2196 */ 2205 */
2197static void 2206static void
2198resume_client_receive(void *cls) 2207resume_client_receive (void *cls)
2199{ 2208{
2200 struct GNUNET_SERVICE_Client *c = cls; 2209 struct GNUNET_SERVICE_Client *c = cls;
2201 int ret; 2210 int ret;
2202 2211
2203 c->recv_task = NULL; 2212 c->recv_task = NULL;
2204 /* first, check if there is still something in the buffer */ 2213 /* first, check if there is still something in the buffer */
2205 ret = GNUNET_MST_next(c->mst, GNUNET_YES); 2214 ret = GNUNET_MST_next (c->mst, GNUNET_YES);
2206 if (GNUNET_SYSERR == ret) 2215 if (GNUNET_SYSERR == ret)
2207 { 2216 {
2208 if (NULL == c->drop_task) 2217 if (NULL == c->drop_task)
2209 GNUNET_SERVICE_client_drop(c); 2218 GNUNET_SERVICE_client_drop (c);
2210 return; 2219 return;
2211 } 2220 }
2212 if (GNUNET_NO == ret) 2221 if (GNUNET_NO == ret)
2213 return; /* done processing, wait for more later */ 2222 return; /* done processing, wait for more later */
2214 GNUNET_assert(GNUNET_OK == ret); 2223 GNUNET_assert (GNUNET_OK == ret);
2215 if (GNUNET_YES == c->needs_continue) 2224 if (GNUNET_YES == c->needs_continue)
2216 return; /* #GNUNET_MST_next() did give a message to the client */ 2225 return; /* #GNUNET_MST_next() did give a message to the client */
2217 /* need to receive more data from the network first */ 2226 /* need to receive more data from the network first */
2218 if (NULL != c->recv_task) 2227 if (NULL != c->recv_task)
2219 return; 2228 return;
2220 c->recv_task = GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, 2229 c->recv_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2221 c->sock, 2230 c->sock,
2222 &service_client_recv, 2231 &service_client_recv,
2223 c); 2232 c);
2224} 2233}
2225 2234
2226 2235
@@ -2231,18 +2240,18 @@ resume_client_receive(void *cls)
2231 * @param c the client to continue receiving from 2240 * @param c the client to continue receiving from
2232 */ 2241 */
2233void 2242void
2234GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c) 2243GNUNET_SERVICE_client_continue (struct GNUNET_SERVICE_Client *c)
2235{ 2244{
2236 GNUNET_assert(NULL == c->drop_task); 2245 GNUNET_assert (NULL == c->drop_task);
2237 GNUNET_assert(GNUNET_YES == c->needs_continue); 2246 GNUNET_assert (GNUNET_YES == c->needs_continue);
2238 GNUNET_assert(NULL == c->recv_task); 2247 GNUNET_assert (NULL == c->recv_task);
2239 c->needs_continue = GNUNET_NO; 2248 c->needs_continue = GNUNET_NO;
2240 if (NULL != c->warn_task) 2249 if (NULL != c->warn_task)
2241 { 2250 {
2242 GNUNET_SCHEDULER_cancel(c->warn_task); 2251 GNUNET_SCHEDULER_cancel (c->warn_task);
2243 c->warn_task = NULL; 2252 c->warn_task = NULL;
2244 } 2253 }
2245 c->recv_task = GNUNET_SCHEDULER_add_now(&resume_client_receive, c); 2254 c->recv_task = GNUNET_SCHEDULER_add_now (&resume_client_receive, c);
2246} 2255}
2247 2256
2248 2257
@@ -2255,14 +2264,14 @@ GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
2255 * @param c client for which to disable the warning 2264 * @param c client for which to disable the warning
2256 */ 2265 */
2257void 2266void
2258GNUNET_SERVICE_client_disable_continue_warning(struct GNUNET_SERVICE_Client *c) 2267GNUNET_SERVICE_client_disable_continue_warning (struct GNUNET_SERVICE_Client *c)
2259{ 2268{
2260 GNUNET_break(NULL != c->warn_task); 2269 GNUNET_break (NULL != c->warn_task);
2261 if (NULL != c->warn_task) 2270 if (NULL != c->warn_task)
2262 { 2271 {
2263 GNUNET_SCHEDULER_cancel(c->warn_task); 2272 GNUNET_SCHEDULER_cancel (c->warn_task);
2264 c->warn_task = NULL; 2273 c->warn_task = NULL;
2265 } 2274 }
2266} 2275}
2267 2276
2268 2277
@@ -2272,32 +2281,32 @@ GNUNET_SERVICE_client_disable_continue_warning(struct GNUNET_SERVICE_Client *c)
2272 * @param cls the `struct GNUNET_SERVICE_Client`. 2281 * @param cls the `struct GNUNET_SERVICE_Client`.
2273 */ 2282 */
2274static void 2283static void
2275finish_client_drop(void *cls) 2284finish_client_drop (void *cls)
2276{ 2285{
2277 struct GNUNET_SERVICE_Client *c = cls; 2286 struct GNUNET_SERVICE_Client *c = cls;
2278 struct GNUNET_SERVICE_Handle *sh = c->sh; 2287 struct GNUNET_SERVICE_Handle *sh = c->sh;
2279 2288
2280 c->drop_task = NULL; 2289 c->drop_task = NULL;
2281 GNUNET_assert(NULL == c->send_task); 2290 GNUNET_assert (NULL == c->send_task);
2282 GNUNET_assert(NULL == c->recv_task); 2291 GNUNET_assert (NULL == c->recv_task);
2283 GNUNET_assert(NULL == c->warn_task); 2292 GNUNET_assert (NULL == c->warn_task);
2284 GNUNET_MST_destroy(c->mst); 2293 GNUNET_MST_destroy (c->mst);
2285 GNUNET_MQ_destroy(c->mq); 2294 GNUNET_MQ_destroy (c->mq);
2286 if (GNUNET_NO == c->persist) 2295 if (GNUNET_NO == c->persist)
2287 { 2296 {
2288 GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(c->sock)); 2297 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (c->sock));
2289 if ((0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) && 2298 if ((0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) &&
2290 (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state))) 2299 (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)))
2291 do_resume(sh, SUSPEND_STATE_EMFILE); 2300 do_resume (sh, SUSPEND_STATE_EMFILE);
2292 } 2301 }
2293 else 2302 else
2294 { 2303 {
2295 GNUNET_NETWORK_socket_free_memory_only_(c->sock); 2304 GNUNET_NETWORK_socket_free_memory_only_ (c->sock);
2296 } 2305 }
2297 GNUNET_free(c); 2306 GNUNET_free (c);
2298 if ((0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) && 2307 if ((0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) &&
2299 (GNUNET_NO == have_non_monitor_clients(sh))) 2308 (GNUNET_NO == have_non_monitor_clients (sh)))
2300 GNUNET_SERVICE_shutdown(sh); 2309 GNUNET_SERVICE_shutdown (sh);
2301} 2310}
2302 2311
2303 2312
@@ -2312,52 +2321,56 @@ finish_client_drop(void *cls)
2312 * @param c client to disconnect now 2321 * @param c client to disconnect now
2313 */ 2322 */
2314void 2323void
2315GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c) 2324GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client *c)
2316{ 2325{
2317 struct GNUNET_SERVICE_Handle *sh = c->sh; 2326 struct GNUNET_SERVICE_Handle *sh = c->sh;
2318 2327
2319 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 2328 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2320 "Client dropped: %p (MQ: %p)\n", 2329 "Client dropped: %p (MQ: %p)\n",
2321 c, 2330 c,
2322 c->mq); 2331 c->mq);
2323#if EXECINFO 2332#if EXECINFO
2324 { 2333 {
2325 void *backtrace_array[MAX_TRACE_DEPTH]; 2334 void *backtrace_array[MAX_TRACE_DEPTH];
2326 int num_backtrace_strings = backtrace(backtrace_array, MAX_TRACE_DEPTH); 2335 int num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH);
2327 char **backtrace_strings = 2336 char **backtrace_strings =
2328 backtrace_symbols(backtrace_array, t->num_backtrace_strings); 2337 backtrace_symbols (backtrace_array, t->num_backtrace_strings);
2329 for (unsigned int i = 0; i < num_backtrace_strings; i++) 2338 for (unsigned int i = 0; i < num_backtrace_strings; i++)
2330 LOG(GNUNET_ERROR_TYPE_DEBUG, 2339 LOG (GNUNET_ERROR_TYPE_DEBUG,
2331 "client drop trace %u: %s\n", 2340 "client drop trace %u: %s\n",
2332 i, 2341 i,
2333 backtrace_strings[i]); 2342 backtrace_strings[i]);
2334 } 2343 }
2335#endif 2344#endif
2336 if (NULL != c->drop_task) 2345 if (NULL != c->drop_task)
2337 { 2346 {
2338 /* asked to drop twice! */ 2347 /* asked to drop twice! */
2339 GNUNET_assert(0); 2348 GNUNET_assert (0);
2340 return; 2349 return;
2341 } 2350 }
2342 GNUNET_CONTAINER_DLL_remove(sh->clients_head, sh->clients_tail, c); 2351 GNUNET_CONTAINER_DLL_remove (sh->clients_head,
2352 sh->clients_tail,
2353 c);
2343 if (NULL != sh->disconnect_cb) 2354 if (NULL != sh->disconnect_cb)
2344 sh->disconnect_cb(sh->cb_cls, c, c->user_context); 2355 sh->disconnect_cb (sh->cb_cls,
2356 c,
2357 c->user_context);
2345 if (NULL != c->warn_task) 2358 if (NULL != c->warn_task)
2346 { 2359 {
2347 GNUNET_SCHEDULER_cancel(c->warn_task); 2360 GNUNET_SCHEDULER_cancel (c->warn_task);
2348 c->warn_task = NULL; 2361 c->warn_task = NULL;
2349 } 2362 }
2350 if (NULL != c->recv_task) 2363 if (NULL != c->recv_task)
2351 { 2364 {
2352 GNUNET_SCHEDULER_cancel(c->recv_task); 2365 GNUNET_SCHEDULER_cancel (c->recv_task);
2353 c->recv_task = NULL; 2366 c->recv_task = NULL;
2354 } 2367 }
2355 if (NULL != c->send_task) 2368 if (NULL != c->send_task)
2356 { 2369 {
2357 GNUNET_SCHEDULER_cancel(c->send_task); 2370 GNUNET_SCHEDULER_cancel (c->send_task);
2358 c->send_task = NULL; 2371 c->send_task = NULL;
2359 } 2372 }
2360 c->drop_task = GNUNET_SCHEDULER_add_now(&finish_client_drop, c); 2373 c->drop_task = GNUNET_SCHEDULER_add_now (&finish_client_drop, c);
2361} 2374}
2362 2375
2363 2376
@@ -2367,14 +2380,14 @@ GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
2367 * @param sh server to shutdown 2380 * @param sh server to shutdown
2368 */ 2381 */
2369void 2382void
2370GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh) 2383GNUNET_SERVICE_shutdown (struct GNUNET_SERVICE_Handle *sh)
2371{ 2384{
2372 struct GNUNET_SERVICE_Client *client; 2385 struct GNUNET_SERVICE_Client *client;
2373 2386
2374 if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) 2387 if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN))
2375 do_suspend(sh, SUSPEND_STATE_SHUTDOWN); 2388 do_suspend (sh, SUSPEND_STATE_SHUTDOWN);
2376 while (NULL != (client = sh->clients_head)) 2389 while (NULL != (client = sh->clients_head))
2377 GNUNET_SERVICE_client_drop(client); 2390 GNUNET_SERVICE_client_drop (client);
2378} 2391}
2379 2392
2380 2393
@@ -2391,12 +2404,12 @@ GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh)
2391 * @param c client to mark as a monitor 2404 * @param c client to mark as a monitor
2392 */ 2405 */
2393void 2406void
2394GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c) 2407GNUNET_SERVICE_client_mark_monitor (struct GNUNET_SERVICE_Client *c)
2395{ 2408{
2396 c->is_monitor = GNUNET_YES; 2409 c->is_monitor = GNUNET_YES;
2397 if (((0 != (SUSPEND_STATE_SHUTDOWN & c->sh->suspend_state)) && 2410 if (((0 != (SUSPEND_STATE_SHUTDOWN & c->sh->suspend_state)) &&
2398 (GNUNET_NO == have_non_monitor_clients(c->sh)))) 2411 (GNUNET_NO == have_non_monitor_clients (c->sh))))
2399 GNUNET_SERVICE_shutdown(c->sh); 2412 GNUNET_SERVICE_shutdown (c->sh);
2400} 2413}
2401 2414
2402 2415
@@ -2408,7 +2421,7 @@ GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
2408 * @param c client to persist the socket (never to be closed) 2421 * @param c client to persist the socket (never to be closed)
2409 */ 2422 */
2410void 2423void
2411GNUNET_SERVICE_client_persist(struct GNUNET_SERVICE_Client *c) 2424GNUNET_SERVICE_client_persist (struct GNUNET_SERVICE_Client *c)
2412{ 2425{
2413 c->persist = GNUNET_YES; 2426 c->persist = GNUNET_YES;
2414} 2427}
@@ -2421,10 +2434,10 @@ GNUNET_SERVICE_client_persist(struct GNUNET_SERVICE_Client *c)
2421 * @return the message queue of @a c 2434 * @return the message queue of @a c
2422 */ 2435 */
2423struct GNUNET_MQ_Handle * 2436struct GNUNET_MQ_Handle *
2424GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c) 2437GNUNET_SERVICE_client_get_mq (struct GNUNET_SERVICE_Client *c)
2425{ 2438{
2426 return c->mq; 2439 return c->mq;
2427} 2440}
2428 2441
2429 2442
2430/* end of service_new.c */ 2443/* end of service.c */