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