aboutsummaryrefslogtreecommitdiff
path: root/src/util/service.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/service.c')
-rw-r--r--src/util/service.c190
1 files changed, 154 insertions, 36 deletions
diff --git a/src/util/service.c b/src/util/service.c
index 82e7070a1..9ab99de3e 100644
--- a/src/util/service.c
+++ b/src/util/service.c
@@ -612,6 +612,10 @@ check_access (void *cls, const struct sockaddr *addr, socklen_t addrlen)
612 && ((sctx->v6_denied == NULL) || 612 && ((sctx->v6_denied == NULL) ||
613 (!check_ipv6_listed (sctx->v6_denied, &i6->sin6_addr))); 613 (!check_ipv6_listed (sctx->v6_denied, &i6->sin6_addr)));
614 break; 614 break;
615 case AF_UNIX:
616 /* FIXME: support checking UID/GID in the future... */
617 ret = GNUNET_OK; /* always OK for now */
618 break;
615 default: 619 default:
616 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 620 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
617 _("Unknown address family %d\n"), addr->sa_family); 621 _("Unknown address family %d\n"), addr->sa_family);
@@ -702,6 +706,46 @@ process_acl6 (struct IPv6NetworkSet **ret,
702 return GNUNET_OK; 706 return GNUNET_OK;
703} 707}
704 708
709/**
710 * Add the given UNIX domain path as an address to the
711 * list (as the first entry).
712 *
713 * @param saddrs array to update
714 * @param saddrlens where to store the address length
715 * @param unixpath path to add
716 */
717static void
718add_unixpath (struct sockaddr **saddrs,
719 socklen_t *saddrlens,
720 const char *unixpath)
721{
722#ifdef AF_UNIX
723 struct sockaddr_un *un;
724 size_t slen;
725
726 un = GNUNET_malloc (sizeof (struct sockaddr_un));
727 un->sun_family = AF_UNIX;
728 slen = strlen (unixpath) + 1;
729 if (slen >= sizeof (un->sun_path))
730 slen = sizeof (un->sun_path) - 1;
731 memcpy (un->sun_path,
732 unixpath,
733 slen);
734 un->sun_path[slen] = '\0';
735 slen += sizeof (sa_family_t);
736#if LINUX
737 un->sun_path[0] = '\0';
738 slen = sizeof (struct sockaddr_un);
739#endif
740 *saddrs = (struct sockaddr*) un;
741 *saddrlens = slen;
742#else
743 /* this function should never be called
744 unless AF_UNIX is defined! */
745 GNUNET_assert (0);
746#endif
747}
748
705 749
706/** 750/**
707 * Get the list of addresses that a server for the given service 751 * Get the list of addresses that a server for the given service
@@ -732,6 +776,7 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
732 int disablev6; 776 int disablev6;
733 struct GNUNET_NETWORK_Handle *desc; 777 struct GNUNET_NETWORK_Handle *desc;
734 unsigned long long port; 778 unsigned long long port;
779 char *unixpath;
735 struct addrinfo hints; 780 struct addrinfo hints;
736 struct addrinfo *res; 781 struct addrinfo *res;
737 struct addrinfo *pos; 782 struct addrinfo *pos;
@@ -781,19 +826,25 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
781 } 826 }
782 } 827 }
783 828
784 829 port = 0;
785 if ((GNUNET_OK != 830 if (GNUNET_CONFIGURATION_have_value (cfg,
786 GNUNET_CONFIGURATION_get_value_number (cfg, 831 serviceName, "PORT"))
787 serviceName,
788 "PORT",
789 &port)) || (port > 65535))
790 { 832 {
791 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 833 GNUNET_break (GNUNET_OK ==
792 _ 834 GNUNET_CONFIGURATION_get_value_number (cfg,
793 ("Require valid port number for service `%s' in configuration!\n"), 835 serviceName,
794 serviceName); 836 "PORT",
795 return GNUNET_SYSERR; 837 &port));
838 if (port > 65535)
839 {
840 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
841 _
842 ("Require valid port number for service `%s' in configuration!\n"),
843 serviceName);
844 return GNUNET_SYSERR;
845 }
796 } 846 }
847
797 if (GNUNET_CONFIGURATION_have_value (cfg, 848 if (GNUNET_CONFIGURATION_have_value (cfg,
798 serviceName, "BINDTO")) 849 serviceName, "BINDTO"))
799 { 850 {
@@ -806,6 +857,49 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
806 else 857 else
807 hostname = NULL; 858 hostname = NULL;
808 859
860#ifdef AF_UNIX
861 if (GNUNET_CONFIGURATION_have_value (cfg,
862 serviceName, "UNIXPATH"))
863 {
864 GNUNET_break (GNUNET_OK ==
865 GNUNET_CONFIGURATION_get_value_string (cfg,
866 serviceName,
867 "UNIXPATH",
868 &unixpath));
869
870 /* probe UNIX support */
871 desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
872 if (NULL == desc)
873 {
874 if ((errno == ENOBUFS) ||
875 (errno == ENOMEM) || (errno == ENFILE) || (errno == EACCES))
876 {
877 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
878 return GNUNET_SYSERR;
879 }
880 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
881 _
882 ("Disabling UNIX domainn socket support for service `%s', failed to create UNIX domain socket: %s\n"),
883 serviceName, STRERROR (errno));
884 GNUNET_free (unixpath);
885 unixpath = NULL;
886 }
887 }
888 else
889 unixpath = NULL;
890#else
891 unixpath = NULL;
892#endif
893
894 if ( (port == 0) &&
895 (unixpath == NULL) )
896 {
897 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
898 _("Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
899 serviceName);
900 return GNUNET_SYSERR;
901 }
902
809 if (hostname != NULL) 903 if (hostname != NULL)
810 { 904 {
811#if DEBUG_SERVICE 905#if DEBUG_SERVICE
@@ -845,9 +939,16 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
845 return GNUNET_SYSERR; 939 return GNUNET_SYSERR;
846 } 940 }
847 resi = i; 941 resi = i;
848 saddrs = GNUNET_malloc ((i+1) * sizeof(struct sockaddr*)); 942 if (NULL != unixpath)
849 saddrlens = GNUNET_malloc ((i+1) * sizeof (socklen_t)); 943 resi++;
944 saddrs = GNUNET_malloc ((resi+1) * sizeof(struct sockaddr*));
945 saddrlens = GNUNET_malloc ((resi+1) * sizeof (socklen_t));
850 i = 0; 946 i = 0;
947 if (NULL != unixpath)
948 {
949 add_unixpath (saddrs, saddrlens, unixpath);
950 i++;
951 }
851 next = res; 952 next = res;
852 while (NULL != (pos = next)) 953 while (NULL != (pos = next))
853 { 954 {
@@ -890,40 +991,56 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
890 { 991 {
891 /* V4-only */ 992 /* V4-only */
892 resi = 1; 993 resi = 1;
893 saddrs = GNUNET_malloc (2 * sizeof(struct sockaddr*)); 994 if (NULL != unixpath)
894 saddrlens = GNUNET_malloc (2 * sizeof (socklen_t)); 995 resi++;
895 saddrlens[0] = sizeof (struct sockaddr_in); 996 i = 0;
896 saddrs[0] = GNUNET_malloc (saddrlens[0]); 997 saddrs = GNUNET_malloc ((resi+1) * sizeof(struct sockaddr*));
998 saddrlens = GNUNET_malloc ((resi+1) * sizeof (socklen_t));
999 if (NULL != unixpath)
1000 {
1001 add_unixpath (saddrs, saddrlens, unixpath);
1002 i++;
1003 }
1004 saddrlens[i] = sizeof (struct sockaddr_in);
1005 saddrs[i] = GNUNET_malloc (saddrlens[i]);
897#if HAVE_SOCKADDR_IN_SIN_LEN 1006#if HAVE_SOCKADDR_IN_SIN_LEN
898 ((struct sockaddr_in *) saddrs[0])->sin_len = saddrlens[0]; 1007 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
899#endif 1008#endif
900 ((struct sockaddr_in *) saddrs[0])->sin_family = AF_INET; 1009 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
901 ((struct sockaddr_in *) saddrs[0])->sin_port = htons (port); 1010 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
902 } 1011 }
903 else 1012 else
904 { 1013 {
905 /* dual stack */ 1014 /* dual stack */
906 resi = 2; 1015 resi = 2;
907 saddrs = GNUNET_malloc (3 * sizeof(struct sockaddr*)); 1016 if (NULL != unixpath)
908 saddrlens = GNUNET_malloc (3 * sizeof (socklen_t)); 1017 resi++;
909 1018 saddrs = GNUNET_malloc ((resi+1) * sizeof(struct sockaddr*));
910 saddrlens[0] = sizeof (struct sockaddr_in6); 1019 saddrlens = GNUNET_malloc ((resi+1) * sizeof (socklen_t));
911 saddrs[0] = GNUNET_malloc (saddrlens[0]); 1020 i = 0;
1021 if (NULL != unixpath)
1022 {
1023 add_unixpath (saddrs, saddrlens, unixpath);
1024 i++;
1025 }
1026 saddrlens[i] = sizeof (struct sockaddr_in6);
1027 saddrs[i] = GNUNET_malloc (saddrlens[i]);
912#if HAVE_SOCKADDR_IN_SIN_LEN 1028#if HAVE_SOCKADDR_IN_SIN_LEN
913 ((struct sockaddr_in6 *) saddrs[0])->sin6_len = saddrlens[0]; 1029 ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
914#endif 1030#endif
915 ((struct sockaddr_in6 *) saddrs[0])->sin6_family = AF_INET6; 1031 ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
916 ((struct sockaddr_in6 *) saddrs[0])->sin6_port = htons (port); 1032 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
917 1033 i++;
918 saddrlens[1] = sizeof (struct sockaddr_in); 1034 saddrlens[i] = sizeof (struct sockaddr_in);
919 saddrs[1] = GNUNET_malloc (saddrlens[1]); 1035 saddrs[i] = GNUNET_malloc (saddrlens[i]);
920#if HAVE_SOCKADDR_IN_SIN_LEN 1036#if HAVE_SOCKADDR_IN_SIN_LEN
921 ((struct sockaddr_in *) saddrs[1])->sin_len = saddrlens[1]; 1037 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
922#endif 1038#endif
923 ((struct sockaddr_in *) saddrs[1])->sin_family = AF_INET; 1039 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
924 ((struct sockaddr_in *) saddrs[1])->sin_port = htons (port); 1040 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
925 } 1041 }
926 } 1042 }
1043 GNUNET_free_non_null (unixpath);
927 *addrs = saddrs; 1044 *addrs = saddrs;
928 *addr_lens = saddrlens; 1045 *addr_lens = saddrlens;
929 return resi; 1046 return resi;
@@ -934,8 +1051,9 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
934 * Setup addr, addrlen, maxbuf, idle_timeout 1051 * Setup addr, addrlen, maxbuf, idle_timeout
935 * based on configuration! 1052 * based on configuration!
936 * 1053 *
937 * Configuration must specify a "PORT". It may 1054 * Configuration may specify:
938 * specify: 1055 * - PORT (where to bind to for TCP)
1056 * - UNIXPATH (where to bind to for UNIX domain sockets)
939 * - TIMEOUT (after how many ms does an inactive service timeout); 1057 * - TIMEOUT (after how many ms does an inactive service timeout);
940 * - MAXBUF (maximum incoming message size supported) 1058 * - MAXBUF (maximum incoming message size supported)
941 * - DISABLEV6 (disable support for IPv6, otherwise we use dual-stack) 1059 * - DISABLEV6 (disable support for IPv6, otherwise we use dual-stack)