aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-09-18 09:14:29 +0000
committerChristian Grothoff <christian@grothoff.org>2016-09-18 09:14:29 +0000
commit1e880e697c98d6dc8c35d2160cdc4bd0270692c1 (patch)
tree3530a18da4d1c6ba12f7cf297d0b4ab6d475d579 /src/util
parent271b944f00a551d9b9ebb7a57197c22d1d33ff56 (diff)
downloadgnunet-1e880e697c98d6dc8c35d2160cdc4bd0270692c1.tar.gz
gnunet-1e880e697c98d6dc8c35d2160cdc4bd0270692c1.zip
getting service_new.c to compile, albeit it is not yet complete
Diffstat (limited to 'src/util')
-rw-r--r--src/util/Makefile.am1
-rw-r--r--src/util/service_new.c780
2 files changed, 625 insertions, 156 deletions
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 6822d539d..b7e60022f 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -109,6 +109,7 @@ libgnunetutil_la_SOURCES = \
109 server_nc.c \ 109 server_nc.c \
110 server_tc.c \ 110 server_tc.c \
111 service.c \ 111 service.c \
112 service_new.c \
112 signal.c \ 113 signal.c \
113 strings.c \ 114 strings.c \
114 time.c \ 115 time.c \
diff --git a/src/util/service_new.c b/src/util/service_new.c
index 9608fbf22..e11d7687e 100644
--- a/src/util/service_new.c
+++ b/src/util/service_new.c
@@ -28,6 +28,19 @@
28#include "gnunet_protocols.h" 28#include "gnunet_protocols.h"
29#include "gnunet_constants.h" 29#include "gnunet_constants.h"
30#include "gnunet_resolver_service.h" 30#include "gnunet_resolver_service.h"
31#include "speedup.h"
32
33#if HAVE_MALLINFO
34#include <malloc.h>
35#include "gauger.h"
36#endif
37
38
39#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
40
41#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall)
42
43#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
31 44
32 45
33/** 46/**
@@ -191,13 +204,6 @@ struct GNUNET_SERVICE_Handle
191 int ret; 204 int ret;
192 205
193 /** 206 /**
194 * Inherited listening sockets, only
195 * used during initialization.
196 * FIXME: remove from struct
197 */
198 struct GNUNET_NETWORK_Handle **lsocks;
199
200 /**
201 * If GNUNET_YES, consider unknown message types an error where the 207 * If GNUNET_YES, consider unknown message types an error where the
202 * client is disconnected. 208 * client is disconnected.
203 * FIXME: remove? 209 * FIXME: remove?
@@ -320,8 +326,6 @@ static void
320service_shutdown (void *cls) 326service_shutdown (void *cls)
321{ 327{
322 struct GNUNET_SERVICE_Handle *sh = cls; 328 struct GNUNET_SERVICE_Handle *sh = cls;
323 struct GNUNET_SERVICE_Client *client;
324 int alive;
325 329
326 switch (sh->options) 330 switch (sh->options)
327 { 331 {
@@ -394,7 +398,9 @@ process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret,
394 { 398 {
395 LOG (GNUNET_ERROR_TYPE_WARNING, 399 LOG (GNUNET_ERROR_TYPE_WARNING,
396 _("Could not parse IPv4 network specification `%s' for `%s:%s'\n"), 400 _("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
397 opt, sh->service_name, option); 401 opt,
402 sh->service_name,
403 option);
398 GNUNET_free (opt); 404 GNUNET_free (opt);
399 return GNUNET_SYSERR; 405 return GNUNET_SYSERR;
400 } 406 }
@@ -442,6 +448,45 @@ process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret,
442 448
443 449
444/** 450/**
451 * Add the given UNIX domain path as an address to the
452 * list (as the first entry).
453 *
454 * @param saddrs array to update
455 * @param saddrlens where to store the address length
456 * @param unixpath path to add
457 * @param abstract #GNUNET_YES to add an abstract UNIX domain socket. This
458 * parameter is ignore on systems other than LINUX
459 */
460static void
461add_unixpath (struct sockaddr **saddrs,
462 socklen_t *saddrlens,
463 const char *unixpath,
464 int abstract)
465{
466#ifdef AF_UNIX
467 struct sockaddr_un *un;
468
469 un = GNUNET_new (struct sockaddr_un);
470 un->sun_family = AF_UNIX;
471 strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1);
472#ifdef LINUX
473 if (GNUNET_YES == abstract)
474 un->sun_path[0] = '\0';
475#endif
476#if HAVE_SOCKADDR_IN_SIN_LEN
477 un->sun_len = (u_char) sizeof (struct sockaddr_un);
478#endif
479 *saddrs = (struct sockaddr *) un;
480 *saddrlens = sizeof (struct sockaddr_un);
481#else
482 /* this function should never be called
483 * unless AF_UNIX is defined! */
484 GNUNET_assert (0);
485#endif
486}
487
488
489/**
445 * Get the list of addresses that a server for the given service 490 * Get the list of addresses that a server for the given service
446 * should bind to. 491 * should bind to.
447 * 492 *
@@ -463,9 +508,9 @@ process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret,
463 */ 508 */
464static int 509static int
465get_server_addresses (const char *service_name, 510get_server_addresses (const char *service_name,
466 const struct GNUNET_CONFIGURATION_Handle *cfg, 511 const struct GNUNET_CONFIGURATION_Handle *cfg,
467 struct sockaddr ***addrs, 512 struct sockaddr ***addrs,
468 socklen_t ** addr_lens) 513 socklen_t **addr_lens)
469{ 514{
470 int disablev6; 515 int disablev6;
471 struct GNUNET_NETWORK_Handle *desc; 516 struct GNUNET_NETWORK_Handle *desc;
@@ -486,11 +531,15 @@ get_server_addresses (const char *service_name,
486 *addrs = NULL; 531 *addrs = NULL;
487 *addr_lens = NULL; 532 *addr_lens = NULL;
488 desc = NULL; 533 desc = NULL;
489 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "DISABLEV6")) 534 if (GNUNET_CONFIGURATION_have_value (cfg,
535 service_name,
536 "DISABLEV6"))
490 { 537 {
491 if (GNUNET_SYSERR == 538 if (GNUNET_SYSERR ==
492 (disablev6 = 539 (disablev6 =
493 GNUNET_CONFIGURATION_get_value_yesno (cfg, service_name, "DISABLEV6"))) 540 GNUNET_CONFIGURATION_get_value_yesno (cfg,
541 service_name,
542 "DISABLEV6")))
494 return GNUNET_SYSERR; 543 return GNUNET_SYSERR;
495 } 544 }
496 else 545 else
@@ -499,18 +548,24 @@ get_server_addresses (const char *service_name,
499 if (! disablev6) 548 if (! disablev6)
500 { 549 {
501 /* probe IPv6 support */ 550 /* probe IPv6 support */
502 desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0); 551 desc = GNUNET_NETWORK_socket_create (PF_INET6,
552 SOCK_STREAM,
553 0);
503 if (NULL == desc) 554 if (NULL == desc)
504 { 555 {
505 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || 556 if ((ENOBUFS == errno) ||
557 (ENOMEM == errno) ||
558 (ENFILE == errno) ||
506 (EACCES == errno)) 559 (EACCES == errno))
507 { 560 {
508 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket"); 561 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
562 "socket");
509 return GNUNET_SYSERR; 563 return GNUNET_SYSERR;
510 } 564 }
511 LOG (GNUNET_ERROR_TYPE_INFO, 565 LOG (GNUNET_ERROR_TYPE_INFO,
512 _("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"), 566 _("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
513 service_name, STRERROR (errno)); 567 service_name,
568 STRERROR (errno));
514 disablev6 = GNUNET_YES; 569 disablev6 = GNUNET_YES;
515 } 570 }
516 else 571 else
@@ -521,11 +576,15 @@ get_server_addresses (const char *service_name,
521 } 576 }
522 577
523 port = 0; 578 port = 0;
524 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT")) 579 if (GNUNET_CONFIGURATION_have_value (cfg,
580 service_name,
581 "PORT"))
525 { 582 {
526 if (GNUNET_OK != 583 if (GNUNET_OK !=
527 GNUNET_CONFIGURATION_get_value_number (cfg, service_name, 584 GNUNET_CONFIGURATION_get_value_number (cfg,
528 "PORT", &port)) 585 service_name,
586 "PORT",
587 &port))
529 { 588 {
530 LOG (GNUNET_ERROR_TYPE_ERROR, 589 LOG (GNUNET_ERROR_TYPE_ERROR,
531 _("Require valid port number for service `%s' in configuration!\n"), 590 _("Require valid port number for service `%s' in configuration!\n"),
@@ -540,11 +599,15 @@ get_server_addresses (const char *service_name,
540 } 599 }
541 } 600 }
542 601
543 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO")) 602 if (GNUNET_CONFIGURATION_have_value (cfg,
603 service_name,
604 "BINDTO"))
544 { 605 {
545 GNUNET_break (GNUNET_OK == 606 GNUNET_break (GNUNET_OK ==
546 GNUNET_CONFIGURATION_get_value_string (cfg, service_name, 607 GNUNET_CONFIGURATION_get_value_string (cfg,
547 "BINDTO", &hostname)); 608 service_name,
609 "BINDTO",
610 &hostname));
548 } 611 }
549 else 612 else
550 hostname = NULL; 613 hostname = NULL;
@@ -553,10 +616,14 @@ get_server_addresses (const char *service_name,
553 abstract = GNUNET_NO; 616 abstract = GNUNET_NO;
554#ifdef AF_UNIX 617#ifdef AF_UNIX
555 if ((GNUNET_YES == 618 if ((GNUNET_YES ==
556 GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) && 619 GNUNET_CONFIGURATION_have_value (cfg,
620 service_name,
621 "UNIXPATH")) &&
557 (GNUNET_OK == 622 (GNUNET_OK ==
558 GNUNET_CONFIGURATION_get_value_filename (cfg, service_name, "UNIXPATH", 623 GNUNET_CONFIGURATION_get_value_filename (cfg,
559 &unixpath)) && 624 service_name,
625 "UNIXPATH",
626 &unixpath)) &&
560 (0 < strlen (unixpath))) 627 (0 < strlen (unixpath)))
561 { 628 {
562 /* probe UNIX support */ 629 /* probe UNIX support */
@@ -565,7 +632,8 @@ get_server_addresses (const char *service_name,
565 if (strlen (unixpath) >= sizeof (s_un.sun_path)) 632 if (strlen (unixpath) >= sizeof (s_un.sun_path))
566 { 633 {
567 LOG (GNUNET_ERROR_TYPE_WARNING, 634 LOG (GNUNET_ERROR_TYPE_WARNING,
568 _("UNIXPATH `%s' too long, maximum length is %llu\n"), unixpath, 635 _("UNIXPATH `%s' too long, maximum length is %llu\n"),
636 unixpath,
569 (unsigned long long) sizeof (s_un.sun_path)); 637 (unsigned long long) sizeof (s_un.sun_path));
570 unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath); 638 unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
571 LOG (GNUNET_ERROR_TYPE_INFO, 639 LOG (GNUNET_ERROR_TYPE_INFO,
@@ -588,13 +656,18 @@ get_server_addresses (const char *service_name,
588 } 656 }
589 if (NULL != unixpath) 657 if (NULL != unixpath)
590 { 658 {
591 desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0); 659 desc = GNUNET_NETWORK_socket_create (AF_UNIX,
660 SOCK_STREAM,
661 0);
592 if (NULL == desc) 662 if (NULL == desc)
593 { 663 {
594 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || 664 if ((ENOBUFS == errno) ||
665 (ENOMEM == errno) ||
666 (ENFILE == errno) ||
595 (EACCES == errno)) 667 (EACCES == errno))
596 { 668 {
597 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket"); 669 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
670 "socket");
598 GNUNET_free_non_null (hostname); 671 GNUNET_free_non_null (hostname);
599 GNUNET_free (unixpath); 672 GNUNET_free (unixpath);
600 return GNUNET_SYSERR; 673 return GNUNET_SYSERR;
@@ -624,9 +697,14 @@ get_server_addresses (const char *service_name,
624 } 697 }
625 if (0 == port) 698 if (0 == port)
626 { 699 {
627 saddrs = GNUNET_malloc (2 * sizeof (struct sockaddr *)); 700 saddrs = GNUNET_new_array (2,
628 saddrlens = GNUNET_malloc (2 * sizeof (socklen_t)); 701 struct sockaddr *);
629 add_unixpath (saddrs, saddrlens, unixpath, abstract); 702 saddrlens = GNUNET_new_array (2,
703 socklen_t);
704 add_unixpath (saddrs,
705 saddrlens,
706 unixpath,
707 abstract);
630 GNUNET_free_non_null (unixpath); 708 GNUNET_free_non_null (unixpath);
631 GNUNET_free_non_null (hostname); 709 GNUNET_free_non_null (hostname);
632 *addrs = saddrs; 710 *addrs = saddrs;
@@ -640,11 +718,16 @@ get_server_addresses (const char *service_name,
640 "Resolving `%s' since that is where `%s' will bind to.\n", 718 "Resolving `%s' since that is where `%s' will bind to.\n",
641 hostname, 719 hostname,
642 service_name); 720 service_name);
643 memset (&hints, 0, sizeof (struct addrinfo)); 721 memset (&hints,
722 0,
723 sizeof (struct addrinfo));
644 if (disablev6) 724 if (disablev6)
645 hints.ai_family = AF_INET; 725 hints.ai_family = AF_INET;
646 hints.ai_protocol = IPPROTO_TCP; 726 hints.ai_protocol = IPPROTO_TCP;
647 if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) || 727 if ((0 != (ret = getaddrinfo (hostname,
728 NULL,
729 &hints,
730 &res))) ||
648 (NULL == res)) 731 (NULL == res))
649 { 732 {
650 LOG (GNUNET_ERROR_TYPE_ERROR, 733 LOG (GNUNET_ERROR_TYPE_ERROR,
@@ -660,7 +743,8 @@ get_server_addresses (const char *service_name,
660 while (NULL != (pos = next)) 743 while (NULL != (pos = next))
661 { 744 {
662 next = pos->ai_next; 745 next = pos->ai_next;
663 if ((disablev6) && (pos->ai_family == AF_INET6)) 746 if ( (disablev6) &&
747 (pos->ai_family == AF_INET6) )
664 continue; 748 continue;
665 i++; 749 i++;
666 } 750 }
@@ -678,32 +762,45 @@ get_server_addresses (const char *service_name,
678 resi = i; 762 resi = i;
679 if (NULL != unixpath) 763 if (NULL != unixpath)
680 resi++; 764 resi++;
681 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *)); 765 saddrs = GNUNET_new_array (resi + 1,
682 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t)); 766 struct sockaddr *);
767 saddrlens = GNUNET_new_array (resi + 1,
768 socklen_t);
683 i = 0; 769 i = 0;
684 if (NULL != unixpath) 770 if (NULL != unixpath)
685 { 771 {
686 add_unixpath (saddrs, saddrlens, unixpath, abstract); 772 add_unixpath (saddrs,
773 saddrlens,
774 unixpath,
775 abstract);
687 i++; 776 i++;
688 } 777 }
689 next = res; 778 next = res;
690 while (NULL != (pos = next)) 779 while (NULL != (pos = next))
691 { 780 {
692 next = pos->ai_next; 781 next = pos->ai_next;
693 if ((disablev6) && (AF_INET6 == pos->ai_family)) 782 if ( (disablev6) &&
783 (AF_INET6 == pos->ai_family) )
694 continue; 784 continue;
695 if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol)) 785 if ( (IPPROTO_TCP != pos->ai_protocol) &&
786 (0 != pos->ai_protocol) )
696 continue; /* not TCP */ 787 continue; /* not TCP */
697 if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype)) 788 if ( (SOCK_STREAM != pos->ai_socktype) &&
789 (0 != pos->ai_socktype) )
698 continue; /* huh? */ 790 continue; /* huh? */
699 LOG (GNUNET_ERROR_TYPE_DEBUG, "Service `%s' will bind to `%s'\n", 791 LOG (GNUNET_ERROR_TYPE_DEBUG,
700 service_name, GNUNET_a2s (pos->ai_addr, pos->ai_addrlen)); 792 "Service `%s' will bind to `%s'\n",
793 service_name,
794 GNUNET_a2s (pos->ai_addr,
795 pos->ai_addrlen));
701 if (AF_INET == pos->ai_family) 796 if (AF_INET == pos->ai_family)
702 { 797 {
703 GNUNET_assert (sizeof (struct sockaddr_in) == pos->ai_addrlen); 798 GNUNET_assert (sizeof (struct sockaddr_in) == pos->ai_addrlen);
704 saddrlens[i] = pos->ai_addrlen; 799 saddrlens[i] = pos->ai_addrlen;
705 saddrs[i] = GNUNET_malloc (saddrlens[i]); 800 saddrs[i] = GNUNET_malloc (saddrlens[i]);
706 GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); 801 GNUNET_memcpy (saddrs[i],
802 pos->ai_addr,
803 saddrlens[i]);
707 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); 804 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
708 } 805 }
709 else 806 else
@@ -712,7 +809,9 @@ get_server_addresses (const char *service_name,
712 GNUNET_assert (sizeof (struct sockaddr_in6) == pos->ai_addrlen); 809 GNUNET_assert (sizeof (struct sockaddr_in6) == pos->ai_addrlen);
713 saddrlens[i] = pos->ai_addrlen; 810 saddrlens[i] = pos->ai_addrlen;
714 saddrs[i] = GNUNET_malloc (saddrlens[i]); 811 saddrs[i] = GNUNET_malloc (saddrlens[i]);
715 GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); 812 GNUNET_memcpy (saddrs[i],
813 pos->ai_addr,
814 saddrlens[i]);
716 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port); 815 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
717 } 816 }
718 i++; 817 i++;
@@ -731,11 +830,16 @@ get_server_addresses (const char *service_name,
731 if (NULL != unixpath) 830 if (NULL != unixpath)
732 resi++; 831 resi++;
733 i = 0; 832 i = 0;
734 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *)); 833 saddrs = GNUNET_new_array (resi + 1,
735 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t)); 834 struct sockaddr *);
835 saddrlens = GNUNET_new_array (resi + 1,
836 socklen_t);
736 if (NULL != unixpath) 837 if (NULL != unixpath)
737 { 838 {
738 add_unixpath (saddrs, saddrlens, unixpath, abstract); 839 add_unixpath (saddrs,
840 saddrlens,
841 unixpath,
842 abstract);
739 i++; 843 i++;
740 } 844 }
741 saddrlens[i] = sizeof (struct sockaddr_in); 845 saddrlens[i] = sizeof (struct sockaddr_in);
@@ -752,12 +856,17 @@ get_server_addresses (const char *service_name,
752 resi = 2; 856 resi = 2;
753 if (NULL != unixpath) 857 if (NULL != unixpath)
754 resi++; 858 resi++;
755 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *)); 859 saddrs = GNUNET_new_array (resi + 1,
756 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t)); 860 struct sockaddr *);
861 saddrlens = GNUNET_new_array (resi + 1,
862 socklen_t);
757 i = 0; 863 i = 0;
758 if (NULL != unixpath) 864 if (NULL != unixpath)
759 { 865 {
760 add_unixpath (saddrs, saddrlens, unixpath, abstract); 866 add_unixpath (saddrs,
867 saddrlens,
868 unixpath,
869 abstract);
761 i++; 870 i++;
762 } 871 }
763 saddrlens[i] = sizeof (struct sockaddr_in6); 872 saddrlens[i] = sizeof (struct sockaddr_in6);
@@ -789,12 +898,13 @@ get_server_addresses (const char *service_name,
789 * Read listen sockets from the parent process (ARM). 898 * Read listen sockets from the parent process (ARM).
790 * 899 *
791 * @param sh service context to initialize 900 * @param sh service context to initialize
792 * @return #GNUNET_YES if ok, #GNUNET_NO if not ok (must bind yourself), 901 * @return NULL-terminated array of sockets on success,
793 * and #GNUNET_SYSERR on error. 902 * NULL if not ok (must bind yourself)
794 */ 903 */
795static int 904static struct GNUNET_NETWORK_Handle **
796receive_sockets_from_parent (struct GNUNET_SERVICE_Handle *sh) 905receive_sockets_from_parent (struct GNUNET_SERVICE_Handle *sh)
797{ 906{
907 static struct GNUNET_NETWORK_Handle **lsocks;
798 const char *env_buf; 908 const char *env_buf;
799 int fail; 909 int fail;
800 uint64_t count; 910 uint64_t count;
@@ -802,15 +912,19 @@ receive_sockets_from_parent (struct GNUNET_SERVICE_Handle *sh)
802 HANDLE lsocks_pipe; 912 HANDLE lsocks_pipe;
803 913
804 env_buf = getenv ("GNUNET_OS_READ_LSOCKS"); 914 env_buf = getenv ("GNUNET_OS_READ_LSOCKS");
805 if ((NULL == env_buf) || (strlen (env_buf) <= 0)) 915 if ( (NULL == env_buf) ||
806 return GNUNET_NO; 916 (strlen (env_buf) <= 0) )
917 return NULL;
807 /* Using W32 API directly here, because this pipe will 918 /* Using W32 API directly here, because this pipe will
808 * never be used outside of this function, and it's just too much of a bother 919 * never be used outside of this function, and it's just too much of a bother
809 * to create a GNUnet API that boxes a HANDLE (the way it is done with socks) 920 * to create a GNUnet API that boxes a HANDLE (the way it is done with socks)
810 */ 921 */
811 lsocks_pipe = (HANDLE) strtoul (env_buf, NULL, 10); 922 lsocks_pipe = (HANDLE) strtoul (env_buf,
812 if ( (0 == lsocks_pipe) || (INVALID_HANDLE_VALUE == lsocks_pipe)) 923 NULL,
813 return GNUNET_NO; 924 10);
925 if ( (0 == lsocks_pipe) ||
926 (INVALID_HANDLE_VALUE == lsocks_pipe))
927 return NULL;
814 fail = 1; 928 fail = 1;
815 do 929 do
816 { 930 {
@@ -818,11 +932,17 @@ receive_sockets_from_parent (struct GNUNET_SERVICE_Handle *sh)
818 int fail2; 932 int fail2;
819 DWORD rd; 933 DWORD rd;
820 934
821 ret = ReadFile (lsocks_pipe, &count, sizeof (count), &rd, NULL); 935 ret = ReadFile (lsocks_pipe,
822 if ((0 == ret) || (sizeof (count) != rd) || (0 == count)) 936 &count,
937 sizeof (count),
938 &rd,
939 NULL);
940 if ( (0 == ret) ||
941 (sizeof (count) != rd) ||
942 (0 == count) )
823 break; 943 break;
824 sh->lsocks = 944 lsocks = GNUNET_new_array (count + 1,
825 GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (count + 1)); 945 struct GNUNET_NETWORK_Handle *);
826 946
827 fail2 = 1; 947 fail2 = 1;
828 for (i = 0; i < count; i++) 948 for (i = 0; i < count; i++)
@@ -831,39 +951,53 @@ receive_sockets_from_parent (struct GNUNET_SERVICE_Handle *sh)
831 uint64_t size; 951 uint64_t size;
832 SOCKET s; 952 SOCKET s;
833 953
834 ret = ReadFile (lsocks_pipe, &size, sizeof (size), &rd, NULL); 954 ret = ReadFile (lsocks_pipe,
835 if ( (0 == ret) || (sizeof (size) != rd) || (sizeof (pi) != size) ) 955 &size,
956 sizeof (size),
957 &rd,
958 NULL);
959 if ( (0 == ret) ||
960 (sizeof (size) != rd) ||
961 (sizeof (pi) != size) )
836 break; 962 break;
837 ret = ReadFile (lsocks_pipe, &pi, sizeof (pi), &rd, NULL); 963 ret = ReadFile (lsocks_pipe,
838 if ( (0 == ret) || (sizeof (pi) != rd)) 964 &pi,
965 sizeof (pi),
966 &rd,
967 NULL);
968 if ( (0 == ret) ||
969 (sizeof (pi) != rd))
839 break; 970 break;
840 s = WSASocketA (pi.iAddressFamily, pi.iSocketType, pi.iProtocol, &pi, 0, WSA_FLAG_OVERLAPPED); 971 s = WSASocketA (pi.iAddressFamily,
841 sh->lsocks[i] = GNUNET_NETWORK_socket_box_native (s); 972 pi.iSocketType,
842 if (NULL == sh->lsocks[i]) 973 pi.iProtocol,
974 &pi,
975 0,
976 WSA_FLAG_OVERLAPPED);
977 lsocks[i] = GNUNET_NETWORK_socket_box_native (s);
978 if (NULL == lsocks[i])
843 break; 979 break;
844 else if (i == count - 1) 980 else if (i == count - 1)
845 fail2 = 0; 981 fail2 = 0;
846 } 982 }
847 if (fail2) 983 if (fail2)
848 break; 984 break;
849 sh->lsocks[count] = NULL; 985 lsocks[count] = NULL;
850 fail = 0; 986 fail = 0;
851 } 987 }
852 while (fail); 988 while (fail);
853
854 CloseHandle (lsocks_pipe); 989 CloseHandle (lsocks_pipe);
855 990
856 if (fail) 991 if (fail)
857 { 992 {
858 LOG (GNUNET_ERROR_TYPE_ERROR, 993 LOG (GNUNET_ERROR_TYPE_ERROR,
859 _("Could not access a pre-bound socket, will try to bind myself\n")); 994 _("Could not access a pre-bound socket, will try to bind myself\n"));
860 for (i = 0; (i < count) && (NULL != sh->lsocks[i]); i++) 995 for (i = 0; (i < count) && (NULL != lsocks[i]); i++)
861 GNUNET_break (0 == GNUNET_NETWORK_socket_close (sh->lsocks[i])); 996 GNUNET_break (0 == GNUNET_NETWORK_socket_close (lsocks[i]));
862 GNUNET_free_non_null (sh->lsocks); 997 GNUNET_free (lsocks);
863 sh->lsocks = NULL; 998 return NULL;
864 return GNUNET_NO;
865 } 999 }
866 return GNUNET_YES; 1000 return lsocks;
867} 1001}
868#endif 1002#endif
869 1003
@@ -899,15 +1033,20 @@ open_listen_socket (const struct sockaddr *server_addr,
899 port = 0; 1033 port = 0;
900 break; 1034 break;
901 } 1035 }
902 sock = GNUNET_NETWORK_socket_create (server_addr->sa_family, SOCK_STREAM, 0); 1036 sock = GNUNET_NETWORK_socket_create (server_addr->sa_family,
1037 SOCK_STREAM,
1038 0);
903 if (NULL == sock) 1039 if (NULL == sock)
904 { 1040 {
905 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket"); 1041 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1042 "socket");
906 errno = 0; 1043 errno = 0;
907 return NULL; 1044 return NULL;
908 } 1045 }
909 /* bind the socket */ 1046 /* bind the socket */
910 if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, server_addr, socklen)) 1047 if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock,
1048 server_addr,
1049 socklen))
911 { 1050 {
912 eno = errno; 1051 eno = errno;
913 if (EADDRINUSE != errno) 1052 if (EADDRINUSE != errno)
@@ -945,7 +1084,8 @@ open_listen_socket (const struct sockaddr *server_addr,
945 errno = eno; 1084 errno = eno;
946 return NULL; 1085 return NULL;
947 } 1086 }
948 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5)) 1087 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock,
1088 5))
949 { 1089 {
950 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, 1090 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
951 "listen"); 1091 "listen");
@@ -961,8 +1101,6 @@ open_listen_socket (const struct sockaddr *server_addr,
961} 1101}
962 1102
963 1103
964
965
966/** 1104/**
967 * Setup service handle 1105 * Setup service handle
968 * 1106 *
@@ -982,9 +1120,8 @@ open_listen_socket (const struct sockaddr *server_addr,
982static int 1120static int
983setup_service (struct GNUNET_SERVICE_Handle *sh) 1121setup_service (struct GNUNET_SERVICE_Handle *sh)
984{ 1122{
985 struct GNUNET_TIME_Relative idleout;
986 int tolerant; 1123 int tolerant;
987 1124 struct GNUNET_NETWORK_Handle **lsocks;
988#ifndef MINGW 1125#ifndef MINGW
989 const char *nfds; 1126 const char *nfds;
990 unsigned int cnt; 1127 unsigned int cnt;
@@ -992,72 +1129,85 @@ setup_service (struct GNUNET_SERVICE_Handle *sh)
992#endif 1129#endif
993 1130
994 if (GNUNET_CONFIGURATION_have_value 1131 if (GNUNET_CONFIGURATION_have_value
995 (sh->cfg, sh->service_name, "TOLERANT")) 1132 (sh->cfg,
1133 sh->service_name,
1134 "TOLERANT"))
996 { 1135 {
997 if (GNUNET_SYSERR == 1136 if (GNUNET_SYSERR ==
998 (tolerant = 1137 (tolerant =
999 GNUNET_CONFIGURATION_get_value_yesno (sh->cfg, sh->service_name, 1138 GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
1139 sh->service_name,
1000 "TOLERANT"))) 1140 "TOLERANT")))
1001 { 1141 {
1002 LOG (GNUNET_ERROR_TYPE_ERROR, 1142 LOG (GNUNET_ERROR_TYPE_ERROR,
1003 _("Specified value for `%s' of service `%s' is invalid\n"), 1143 _("Specified value for `%s' of service `%s' is invalid\n"),
1004 "TOLERANT", sh->service_name); 1144 "TOLERANT",
1145 sh->service_name);
1005 return GNUNET_SYSERR; 1146 return GNUNET_SYSERR;
1006 } 1147 }
1007 } 1148 }
1008 else 1149 else
1009 tolerant = GNUNET_NO; 1150 tolerant = GNUNET_NO;
1010 1151
1152 lsocks = NULL;
1011#ifndef MINGW 1153#ifndef MINGW
1012 errno = 0; 1154 errno = 0;
1013 if ((NULL != (nfds = getenv ("LISTEN_FDS"))) && 1155 if ( (NULL != (nfds = getenv ("LISTEN_FDS"))) &&
1014 (1 == SSCANF (nfds, "%u", &cnt)) && (cnt > 0) && (cnt < FD_SETSIZE) && 1156 (1 == SSCANF (nfds,
1015 (cnt + 4 < FD_SETSIZE)) 1157 "%u",
1158 &cnt)) &&
1159 (cnt > 0) &&
1160 (cnt < FD_SETSIZE) &&
1161 (cnt + 4 < FD_SETSIZE) )
1016 { 1162 {
1017 sh->lsocks = 1163 lsocks = GNUNET_new_array (cnt + 1,
1018 GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (cnt + 1)); 1164 struct GNUNET_NETWORK_Handle *);
1019 while (0 < cnt--) 1165 while (0 < cnt--)
1020 { 1166 {
1021 flags = fcntl (3 + cnt, F_GETFD); 1167 flags = fcntl (3 + cnt,
1022 if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) || 1168 F_GETFD);
1023 (NULL == 1169 if ( (flags < 0) ||
1024 (sh->lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt)))) 1170 (0 != (flags & FD_CLOEXEC)) ||
1171 (NULL ==
1172 (lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt))))
1025 { 1173 {
1026 LOG (GNUNET_ERROR_TYPE_ERROR, 1174 LOG (GNUNET_ERROR_TYPE_ERROR,
1027 _ 1175 _("Could not access pre-bound socket %u, will try to bind myself\n"),
1028 ("Could not access pre-bound socket %u, will try to bind myself\n"),
1029 (unsigned int) 3 + cnt); 1176 (unsigned int) 3 + cnt);
1030 cnt++; 1177 cnt++;
1031 while (sh->lsocks[cnt] != NULL) 1178 while (NULL != lsocks[cnt])
1032 GNUNET_break (0 == GNUNET_NETWORK_socket_close (sh->lsocks[cnt++])); 1179 GNUNET_break (0 == GNUNET_NETWORK_socket_close (lsocks[cnt++]));
1033 GNUNET_free (sh->lsocks); 1180 GNUNET_free (lsocks);
1034 sh->lsocks = NULL; 1181 lsocks = NULL;
1035 break; 1182 break;
1036 } 1183 }
1037 } 1184 }
1038 unsetenv ("LISTEN_FDS"); 1185 unsetenv ("LISTEN_FDS");
1039 } 1186 }
1040#else 1187#else
1041 if (getenv ("GNUNET_OS_READ_LSOCKS") != NULL) 1188 if (NULL != getenv ("GNUNET_OS_READ_LSOCKS"))
1042 { 1189 {
1043 receive_sockets_from_parent (sh); 1190 lsocks = receive_sockets_from_parent (sh);
1044 putenv ("GNUNET_OS_READ_LSOCKS="); 1191 putenv ("GNUNET_OS_READ_LSOCKS=");
1045 } 1192 }
1046#endif 1193#endif
1047 1194
1048 if (NULL != sh->lsocks) 1195 if (NULL != lsocks)
1049 { 1196 {
1050 /* listen only on inherited sockets if we have any */ 1197 /* listen only on inherited sockets if we have any */
1051 struct GNUNET_NETWORK_Handle **ls = sh->lsocks; 1198 struct GNUNET_NETWORK_Handle **ls;
1052 for (; NULL != *ls; ls++) 1199
1200 for (ls = lsocks; NULL != *ls; ls++)
1053 { 1201 {
1054 struct ServiceListenContext *slc; 1202 struct ServiceListenContext *slc;
1055 1203
1056 slc = GNUNET_new (struct ServiceListenContext); 1204 slc = GNUNET_new (struct ServiceListenContext);
1057 slc->listen_socket = *ls; 1205 slc->listen_socket = *ls;
1058 GNUNET_CONTAINER_DLL_insert (sh->slc_head, sh->slc_tail, slc); 1206 GNUNET_CONTAINER_DLL_insert (sh->slc_head,
1207 sh->slc_tail,
1208 slc);
1059 } 1209 }
1060 GNUNET_free_non_null (sh->lsocks); 1210 GNUNET_free (lsocks);
1061 } 1211 }
1062 else 1212 else
1063 { 1213 {
@@ -1065,8 +1215,10 @@ setup_service (struct GNUNET_SERVICE_Handle *sh)
1065 socklen_t *addrlens; 1215 socklen_t *addrlens;
1066 int num; 1216 int num;
1067 1217
1068 num = get_server_addresses (sh->service_name, sh->cfg, 1218 num = get_server_addresses (sh->service_name,
1069 &addrs, &addrlens); 1219 sh->cfg,
1220 &addrs,
1221 &addrlens);
1070 if (GNUNET_SYSERR == num) 1222 if (GNUNET_SYSERR == num)
1071 return GNUNET_SYSERR; 1223 return GNUNET_SYSERR;
1072 1224
@@ -1075,24 +1227,246 @@ setup_service (struct GNUNET_SERVICE_Handle *sh)
1075 struct ServiceListenContext *slc; 1227 struct ServiceListenContext *slc;
1076 1228
1077 slc = GNUNET_new (struct ServiceListenContext); 1229 slc = GNUNET_new (struct ServiceListenContext);
1078 slc->listen_socket = open_listen_socket (addrs[i], addrlens[i]); 1230 slc->listen_socket = open_listen_socket (addrs[i],
1231 addrlens[i]);
1079 GNUNET_break (NULL != slc->listen_socket); 1232 GNUNET_break (NULL != slc->listen_socket);
1080 GNUNET_CONTAINER_DLL_insert (sh->slc_head, sh->slc_tail, slc); 1233 GNUNET_CONTAINER_DLL_insert (sh->slc_head,
1234 sh->slc_tail,
1235 slc);
1081 } 1236 }
1082 } 1237 }
1083 1238
1084 sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES; 1239 sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
1085 sh->match_uid = 1240 sh->match_uid =
1086 GNUNET_CONFIGURATION_get_value_yesno (sh->cfg, sh->service_name, 1241 GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
1242 sh->service_name,
1087 "UNIX_MATCH_UID"); 1243 "UNIX_MATCH_UID");
1088 sh->match_gid = 1244 sh->match_gid =
1089 GNUNET_CONFIGURATION_get_value_yesno (sh->cfg, sh->service_name, 1245 GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
1246 sh->service_name,
1090 "UNIX_MATCH_GID"); 1247 "UNIX_MATCH_GID");
1091 process_acl4 (&sh->v4_denied, sh, "REJECT_FROM"); 1248 process_acl4 (&sh->v4_denied,
1092 process_acl4 (&sh->v4_allowed, sh, "ACCEPT_FROM"); 1249 sh,
1093 process_acl6 (&sh->v6_denied, sh, "REJECT_FROM6"); 1250 "REJECT_FROM");
1094 process_acl6 (&sh->v6_allowed, sh, "ACCEPT_FROM6"); 1251 process_acl4 (&sh->v4_allowed,
1252 sh,
1253 "ACCEPT_FROM");
1254 process_acl6 (&sh->v6_denied,
1255 sh,
1256 "REJECT_FROM6");
1257 process_acl6 (&sh->v6_allowed,
1258 sh,
1259 "ACCEPT_FROM6");
1260 return GNUNET_OK;
1261}
1262
1263
1264/**
1265 * Get the name of the user that'll be used
1266 * to provide the service.
1267 *
1268 * @param sh service context
1269 * @return value of the 'USERNAME' option
1270 */
1271static char *
1272get_user_name (struct GNUNET_SERVICE_Handle *sh)
1273{
1274 char *un;
1275
1276 if (GNUNET_OK !=
1277 GNUNET_CONFIGURATION_get_value_filename (sh->cfg,
1278 sh->service_name,
1279 "USERNAME",
1280 &un))
1281 return NULL;
1282 return un;
1283}
1284
1285
1286/**
1287 * Set user ID.
1288 *
1289 * @param sh service context
1290 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1291 */
1292static int
1293set_user_id (struct GNUNET_SERVICE_Handle *sh)
1294{
1295 char *user;
1296
1297 if (NULL == (user = get_user_name (sh)))
1298 return GNUNET_OK; /* keep */
1299#ifndef MINGW
1300 struct passwd *pws;
1301
1302 errno = 0;
1303 pws = getpwnam (user);
1304 if (NULL == pws)
1305 {
1306 LOG (GNUNET_ERROR_TYPE_ERROR,
1307 _("Cannot obtain information about user `%s': %s\n"),
1308 user,
1309 errno == 0 ? _("No such user") : STRERROR (errno));
1310 GNUNET_free (user);
1311 return GNUNET_SYSERR;
1312 }
1313 if ( (0 != setgid (pws->pw_gid)) ||
1314 (0 != setegid (pws->pw_gid)) ||
1315#if HAVE_INITGROUPS
1316 (0 != initgroups (user,
1317 pws->pw_gid)) ||
1318#endif
1319 (0 != setuid (pws->pw_uid)) ||
1320 (0 != seteuid (pws->pw_uid)))
1321 {
1322 if ((0 != setregid (pws->pw_gid,
1323 pws->pw_gid)) ||
1324 (0 != setreuid (pws->pw_uid,
1325 pws->pw_uid)))
1326 {
1327 LOG (GNUNET_ERROR_TYPE_ERROR,
1328 _("Cannot change user/group to `%s': %s\n"),
1329 user,
1330 STRERROR (errno));
1331 GNUNET_free (user);
1332 return GNUNET_SYSERR;
1333 }
1334 }
1335#endif
1336 GNUNET_free (user);
1337 return GNUNET_OK;
1338}
1339
1340
1341/**
1342 * Get the name of the file where we will
1343 * write the PID of the service.
1344 *
1345 * @param sh service context
1346 * @return name of the file for the process ID
1347 */
1348static char *
1349get_pid_file_name (struct GNUNET_SERVICE_Handle *sh)
1350{
1351 char *pif;
1352
1353 if (GNUNET_OK !=
1354 GNUNET_CONFIGURATION_get_value_filename (sh->cfg,
1355 sh->service_name,
1356 "PIDFILE",
1357 &pif))
1358 return NULL;
1359 return pif;
1360}
1361
1362
1363/**
1364 * Delete the PID file that was created by our parent.
1365 *
1366 * @param sh service context
1367 */
1368static void
1369pid_file_delete (struct GNUNET_SERVICE_Handle *sh)
1370{
1371 char *pif = get_pid_file_name (sh);
1372
1373 if (NULL == pif)
1374 return; /* no PID file */
1375 if (0 != UNLINK (pif))
1376 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING,
1377 "unlink",
1378 pif);
1379 GNUNET_free (pif);
1380}
1381
1095 1382
1383/**
1384 * Detach from terminal.
1385 *
1386 * @param sh service context
1387 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1388 */
1389static int
1390detach_terminal (struct GNUNET_SERVICE_Handle *sh)
1391{
1392#ifndef MINGW
1393 pid_t pid;
1394 int nullfd;
1395 int filedes[2];
1396
1397 if (0 != PIPE (filedes))
1398 {
1399 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1400 "pipe");
1401 return GNUNET_SYSERR;
1402 }
1403 pid = fork ();
1404 if (pid < 0)
1405 {
1406 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1407 "fork");
1408 return GNUNET_SYSERR;
1409 }
1410 if (0 != pid)
1411 {
1412 /* Parent */
1413 char c;
1414
1415 GNUNET_break (0 == CLOSE (filedes[1]));
1416 c = 'X';
1417 if (1 != READ (filedes[0],
1418 &c,
1419 sizeof (char)))
1420 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
1421 "read");
1422 fflush (stdout);
1423 switch (c)
1424 {
1425 case '.':
1426 exit (0);
1427 case 'I':
1428 LOG (GNUNET_ERROR_TYPE_INFO,
1429 _("Service process failed to initialize\n"));
1430 break;
1431 case 'S':
1432 LOG (GNUNET_ERROR_TYPE_INFO,
1433 _("Service process could not initialize server function\n"));
1434 break;
1435 case 'X':
1436 LOG (GNUNET_ERROR_TYPE_INFO,
1437 _("Service process failed to report status\n"));
1438 break;
1439 }
1440 exit (1); /* child reported error */
1441 }
1442 GNUNET_break (0 == CLOSE (0));
1443 GNUNET_break (0 == CLOSE (1));
1444 GNUNET_break (0 == CLOSE (filedes[0]));
1445 nullfd = OPEN ("/dev/null",
1446 O_RDWR | O_APPEND);
1447 if (nullfd < 0)
1448 return GNUNET_SYSERR;
1449 /* set stdin/stdout to /dev/null */
1450 if ( (dup2 (nullfd, 0) < 0) ||
1451 (dup2 (nullfd, 1) < 0) )
1452 {
1453 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1454 "dup2");
1455 (void) CLOSE (nullfd);
1456 return GNUNET_SYSERR;
1457 }
1458 (void) CLOSE (nullfd);
1459 /* Detach from controlling terminal */
1460 pid = setsid ();
1461 if (-1 == pid)
1462 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1463 "setsid");
1464 sh->ready_confirm_fd = filedes[1];
1465#else
1466 /* FIXME: we probably need to do something else
1467 * elsewhere in order to fork the process itself... */
1468 FreeConsole ();
1469#endif
1096 return GNUNET_OK; 1470 return GNUNET_OK;
1097} 1471}
1098 1472
@@ -1156,7 +1530,6 @@ GNUNET_SERVICE_ruN_ (int argc,
1156 const char *xdg; 1530 const char *xdg;
1157 char *logfile; 1531 char *logfile;
1158 int do_daemonize; 1532 int do_daemonize;
1159 unsigned int i;
1160 unsigned long long skew_offset; 1533 unsigned long long skew_offset;
1161 unsigned long long skew_variance; 1534 unsigned long long skew_variance;
1162 long long clock_offset; 1535 long long clock_offset;
@@ -1195,7 +1568,10 @@ GNUNET_SERVICE_ruN_ (int argc,
1195 sh.handlers = handlers; 1568 sh.handlers = handlers;
1196 1569
1197 /* setup subsystems */ 1570 /* setup subsystems */
1198 ret = GNUNET_GETOPT_run (service_name, service_options, argc, argv); 1571 ret = GNUNET_GETOPT_run (service_name,
1572 service_options,
1573 argc,
1574 argv);
1199 if (GNUNET_SYSERR == ret) 1575 if (GNUNET_SYSERR == ret)
1200 goto shutdown; 1576 goto shutdown;
1201 if (GNUNET_NO == ret) 1577 if (GNUNET_NO == ret)
@@ -1203,7 +1579,9 @@ GNUNET_SERVICE_ruN_ (int argc,
1203 err = 0; 1579 err = 0;
1204 goto shutdown; 1580 goto shutdown;
1205 } 1581 }
1206 if (GNUNET_OK != GNUNET_log_setup (service_name, loglev, logfile)) 1582 if (GNUNET_OK != GNUNET_log_setup (service_name,
1583 loglev,
1584 logfile))
1207 { 1585 {
1208 GNUNET_break (0); 1586 GNUNET_break (0);
1209 goto shutdown; 1587 goto shutdown;
@@ -1212,7 +1590,8 @@ GNUNET_SERVICE_ruN_ (int argc,
1212 opt_cfg_filename = GNUNET_strdup (cfg_filename); 1590 opt_cfg_filename = GNUNET_strdup (cfg_filename);
1213 if (GNUNET_YES == GNUNET_DISK_file_test (opt_cfg_filename)) 1591 if (GNUNET_YES == GNUNET_DISK_file_test (opt_cfg_filename))
1214 { 1592 {
1215 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_filename)) 1593 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg,
1594 opt_cfg_filename))
1216 { 1595 {
1217 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1596 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1218 _("Malformed configuration file `%s', exit ...\n"), 1597 _("Malformed configuration file `%s', exit ...\n"),
@@ -1222,20 +1601,23 @@ GNUNET_SERVICE_ruN_ (int argc,
1222 } 1601 }
1223 else 1602 else
1224 { 1603 {
1225 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL)) 1604 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg,
1605 NULL))
1226 { 1606 {
1227 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1607 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1228 _("Malformed configuration, exit ...\n")); 1608 _("Malformed configuration, exit ...\n"));
1229 goto shutdown; 1609 goto shutdown;
1230 } 1610 }
1231 if (0 != strcmp (opt_cfg_filename, cfg_filename)) 1611 if (0 != strcmp (opt_cfg_filename,
1612 cfg_filename))
1232 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1613 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1233 _("Could not access configuration file `%s'\n"), 1614 _("Could not access configuration file `%s'\n"),
1234 opt_cfg_filename); 1615 opt_cfg_filename);
1235 } 1616 }
1236 if (GNUNET_OK != setup_service (&sh)) 1617 if (GNUNET_OK != setup_service (&sh))
1237 goto shutdown; 1618 goto shutdown;
1238 if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sh))) 1619 if ( (1 == do_daemonize) &&
1620 (GNUNET_OK != detach_terminal (&sh)) )
1239 { 1621 {
1240 GNUNET_break (0); 1622 GNUNET_break (0);
1241 goto shutdown; 1623 goto shutdown;
@@ -1247,19 +1629,26 @@ GNUNET_SERVICE_ruN_ (int argc,
1247 service_name, 1629 service_name,
1248 opt_cfg_filename); 1630 opt_cfg_filename);
1249 if ((GNUNET_OK == 1631 if ((GNUNET_OK ==
1250 GNUNET_CONFIGURATION_get_value_number (sh.cfg, "TESTING", 1632 GNUNET_CONFIGURATION_get_value_number (sh.cfg,
1251 "SKEW_OFFSET", &skew_offset)) && 1633 "TESTING",
1634 "SKEW_OFFSET",
1635 &skew_offset)) &&
1252 (GNUNET_OK == 1636 (GNUNET_OK ==
1253 GNUNET_CONFIGURATION_get_value_number (sh.cfg, "TESTING", 1637 GNUNET_CONFIGURATION_get_value_number (sh.cfg,
1254 "SKEW_VARIANCE", &skew_variance))) 1638 "TESTING",
1639 "SKEW_VARIANCE",
1640 &skew_variance)))
1255 { 1641 {
1256 clock_offset = skew_offset - skew_variance; 1642 clock_offset = skew_offset - skew_variance;
1257 GNUNET_TIME_set_offset (clock_offset); 1643 GNUNET_TIME_set_offset (clock_offset);
1258 LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset); 1644 LOG (GNUNET_ERROR_TYPE_DEBUG,
1645 "Skewing clock by %dll ms\n",
1646 clock_offset);
1259 } 1647 }
1260 /* actually run service */ 1648 /* actually run service */
1261 err = 0; 1649 err = 0;
1262 GNUNET_SCHEDULER_run (&service_main, &sh); 1650 GNUNET_SCHEDULER_run (&service_main,
1651 &sh);
1263 /* shutdown */ 1652 /* shutdown */
1264 if (1 == do_daemonize) 1653 if (1 == do_daemonize)
1265 pid_file_delete (&sh); 1654 pid_file_delete (&sh);
@@ -1276,17 +1665,22 @@ shutdown:
1276 char *counter; 1665 char *counter;
1277 1666
1278 if ( (GNUNET_YES == 1667 if ( (GNUNET_YES ==
1279 GNUNET_CONFIGURATION_have_value (sh.cfg, service_name, 1668 GNUNET_CONFIGURATION_have_value (sh.cfg,
1669 service_name,
1280 "GAUGER_HEAP")) && 1670 "GAUGER_HEAP")) &&
1281 (GNUNET_OK == 1671 (GNUNET_OK ==
1282 GNUNET_CONFIGURATION_get_value_string (sh.cfg, service_name, 1672 GNUNET_CONFIGURATION_get_value_string (sh.cfg,
1673 service_name,
1283 "GAUGER_HEAP", 1674 "GAUGER_HEAP",
1284 &counter)) ) 1675 &counter)) )
1285 { 1676 {
1286 struct mallinfo mi; 1677 struct mallinfo mi;
1287 1678
1288 mi = mallinfo (); 1679 mi = mallinfo ();
1289 GAUGER (service_name, counter, mi.usmblks, "blocks"); 1680 GAUGER (service_name,
1681 counter,
1682 mi.usmblks,
1683 "blocks");
1290 GNUNET_free (counter); 1684 GNUNET_free (counter);
1291 } 1685 }
1292 } 1686 }
@@ -1297,6 +1691,7 @@ shutdown:
1297 while (NULL != sh.slc_head) 1691 while (NULL != sh.slc_head)
1298 { 1692 {
1299 struct ServiceListenContext *slc = sh.slc_head; 1693 struct ServiceListenContext *slc = sh.slc_head;
1694
1300 sh.slc_head = slc->next; 1695 sh.slc_head = slc->next;
1301 // FIXME: destroy slc 1696 // FIXME: destroy slc
1302 GNUNET_free (slc); 1697 GNUNET_free (slc);
@@ -1329,10 +1724,10 @@ GNUNET_SERVICE_suspend (struct GNUNET_SERVICE_Handle *sh)
1329 for (slc = sh->slc_head; NULL != slc; slc = slc->next) 1724 for (slc = sh->slc_head; NULL != slc; slc = slc->next)
1330 { 1725 {
1331 if (NULL != slc->listen_task) 1726 if (NULL != slc->listen_task)
1332 { 1727 {
1333 GNUNET_SCHEDULER_cancel (slc->listen_task); 1728 GNUNET_SCHEDULER_cancel (slc->listen_task);
1334 slc->listen_task = NULL; 1729 slc->listen_task = NULL;
1335 } 1730 }
1336 } 1731 }
1337} 1732}
1338 1733
@@ -1470,9 +1865,78 @@ start_client (struct GNUNET_SERVICE_Handle *sh,
1470 client->mq); 1865 client->mq);
1471 GNUNET_MQ_set_handlers_closure (client->mq, 1866 GNUNET_MQ_set_handlers_closure (client->mq,
1472 client->user_context); 1867 client->user_context);
1473 client->recv_task = GNUNET_SCHEDULER_add_read (client->sock, 1868 client->recv_task
1474 &service_client_recv, 1869 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1475 client); 1870 client->sock,
1871 &service_client_recv,
1872 client);
1873}
1874
1875
1876/**
1877 * Check if the given IP address is in the list of IP addresses.
1878 *
1879 * @param list a list of networks
1880 * @param add the IP to check (in network byte order)
1881 * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
1882 */
1883static int
1884check_ipv4_listed (const struct GNUNET_STRINGS_IPv4NetworkPolicy *list,
1885 const struct in_addr *add)
1886{
1887 unsigned int i;
1888
1889 if (NULL == list)
1890 return GNUNET_NO;
1891 i = 0;
1892 while ( (0 != list[i].network.s_addr) ||
1893 (0 != list[i].netmask.s_addr) )
1894 {
1895 if ((add->s_addr & list[i].netmask.s_addr) ==
1896 (list[i].network.s_addr & list[i].netmask.s_addr))
1897 return GNUNET_YES;
1898 i++;
1899 }
1900 return GNUNET_NO;
1901}
1902
1903
1904/**
1905 * Check if the given IP address is in the list of IP addresses.
1906 *
1907 * @param list a list of networks
1908 * @param ip the IP to check (in network byte order)
1909 * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
1910 */
1911static int
1912check_ipv6_listed (const struct GNUNET_STRINGS_IPv6NetworkPolicy *list,
1913 const struct in6_addr *ip)
1914{
1915 unsigned int i;
1916 unsigned int j;
1917 struct in6_addr zero;
1918
1919 if (NULL == list)
1920 return GNUNET_NO;
1921 memset (&zero,
1922 0,
1923 sizeof (struct in6_addr));
1924 i = 0;
1925NEXT:
1926 while (0 != memcmp (&zero,
1927 &list[i].network,
1928 sizeof (struct in6_addr)))
1929 {
1930 for (j = 0; j < sizeof (struct in6_addr) / sizeof (int); j++)
1931 if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
1932 (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
1933 {
1934 i++;
1935 goto NEXT;
1936 }
1937 return GNUNET_YES;
1938 }
1939 return GNUNET_NO;
1476} 1940}
1477 1941
1478 1942
@@ -1492,8 +1956,8 @@ accept_client (void *cls)
1492 while (1) 1956 while (1)
1493 { 1957 {
1494 struct GNUNET_NETWORK_Handle *sock; 1958 struct GNUNET_NETWORK_Handle *sock;
1495 struct sockaddr_in *v4; 1959 const struct sockaddr_in *v4;
1496 struct sockaddr_in6 *v6; 1960 const struct sockaddr_in6 *v6;
1497 struct sockaddr_storage sa; 1961 struct sockaddr_storage sa;
1498 socklen_t addrlen; 1962 socklen_t addrlen;
1499 int ok; 1963 int ok;
@@ -1535,7 +1999,7 @@ accept_client (void *cls)
1535 LOG (GNUNET_ERROR_TYPE_WARNING, 1999 LOG (GNUNET_ERROR_TYPE_WARNING,
1536 _("Unknown address family %d\n"), 2000 _("Unknown address family %d\n"),
1537 sa.ss_family); 2001 sa.ss_family);
1538 return GNUNET_SYSERR; 2002 return;
1539 } 2003 }
1540 if (! ok) 2004 if (! ok)
1541 { 2005 {
@@ -1553,9 +2017,11 @@ accept_client (void *cls)
1553 start_client (slc->sh, 2017 start_client (slc->sh,
1554 sock); 2018 sock);
1555 } 2019 }
1556 slc->listen_task = GNUNET_SCHEDULER_add_read (slc->listen_socket, 2020 slc->listen_task
1557 &accept_client, 2021 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1558 slc); 2022 slc->listen_socket,
2023 &accept_client,
2024 slc);
1559} 2025}
1560 2026
1561 2027
@@ -1572,9 +2038,11 @@ GNUNET_SERVICE_resume (struct GNUNET_SERVICE_Handle *sh)
1572 for (slc = sh->slc_head; NULL != slc; slc = slc->next) 2038 for (slc = sh->slc_head; NULL != slc; slc = slc->next)
1573 { 2039 {
1574 GNUNET_assert (NULL == slc->listen_task); 2040 GNUNET_assert (NULL == slc->listen_task);
1575 slc->listen_task = GNUNET_SCHEDULER_add_read (slc->listen_socket, 2041 slc->listen_task
1576 &accept_client, 2042 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1577 slc); 2043 slc->listen_socket,
2044 &accept_client,
2045 slc);
1578 } 2046 }
1579} 2047}
1580 2048