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.c179
1 files changed, 117 insertions, 62 deletions
diff --git a/src/util/service.c b/src/util/service.c
index 034cff170..af17a7f3e 100644
--- a/src/util/service.c
+++ b/src/util/service.c
@@ -35,6 +35,8 @@
35#include "gnunet_server_lib.h" 35#include "gnunet_server_lib.h"
36#include "gnunet_service_lib.h" 36#include "gnunet_service_lib.h"
37 37
38#define DEBUG_SERVICE GNUNET_NO
39
38/* ******************* access control ******************** */ 40/* ******************* access control ******************** */
39 41
40/** 42/**
@@ -433,9 +435,9 @@ struct GNUNET_SERVICE_Context
433 struct GNUNET_SCHEDULER_Handle *sched; 435 struct GNUNET_SCHEDULER_Handle *sched;
434 436
435 /** 437 /**
436 * Address to bind to. 438 * NULL-terminated array of addresses to bind to.
437 */ 439 */
438 struct sockaddr *addr; 440 struct sockaddr **addrs;
439 441
440 /** 442 /**
441 * Name of our service. 443 * Name of our service.
@@ -519,9 +521,9 @@ struct GNUNET_SERVICE_Context
519 enum GNUNET_SERVICE_Options options; 521 enum GNUNET_SERVICE_Options options;
520 522
521 /** 523 /**
522 * Length of addr. 524 * Array of the lengths of the entries in addrs.
523 */ 525 */
524 socklen_t addrlen; 526 socklen_t * addrlens;
525 527
526}; 528};
527 529
@@ -766,8 +768,10 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
766 struct addrinfo hints; 768 struct addrinfo hints;
767 struct addrinfo *res; 769 struct addrinfo *res;
768 struct addrinfo *pos; 770 struct addrinfo *pos;
771 struct addrinfo *next;
769 int ret; 772 int ret;
770 int tolerant; 773 int tolerant;
774 unsigned int i;
771 struct GNUNET_NETWORK_Handle *desc; 775 struct GNUNET_NETWORK_Handle *desc;
772 776
773 if (GNUNET_CONFIGURATION_have_value (sctx->cfg, 777 if (GNUNET_CONFIGURATION_have_value (sctx->cfg,
@@ -884,6 +888,12 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
884 888
885 if (hostname != NULL) 889 if (hostname != NULL)
886 { 890 {
891#if DEBUG_SERVICE
892 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
893 "Resolving `%s' since that is where `%s' will bind to.\n",
894 hostname,
895 sctx->serviceName);
896#endif
887 memset (&hints, 0, sizeof (struct addrinfo)); 897 memset (&hints, 0, sizeof (struct addrinfo));
888 if (disablev6) 898 if (disablev6)
889 hints.ai_family = AF_INET; 899 hints.ai_family = AF_INET;
@@ -896,13 +906,16 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
896 GNUNET_free (hostname); 906 GNUNET_free (hostname);
897 return GNUNET_SYSERR; 907 return GNUNET_SYSERR;
898 } 908 }
899 pos = res; 909 next = res;
900 while ((NULL != pos) && 910 i = 0;
901 (((disablev6) && 911 while (NULL != (pos = next))
902 (pos->ai_family != AF_INET)) || 912 {
903 ((pos->ai_family != AF_INET) && (pos->ai_family != AF_INET6)))) 913 next = pos->ai_next;
904 pos = pos->ai_next; 914 if ( (disablev6) && (pos->ai_family == AF_INET6))
905 if (pos == NULL) 915 continue;
916 i++;
917 }
918 if (0 == i)
906 { 919 {
907 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 920 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
908 _("Failed to find %saddress for `%s'.\n"), 921 _("Failed to find %saddress for `%s'.\n"),
@@ -911,32 +924,42 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
911 GNUNET_free (hostname); 924 GNUNET_free (hostname);
912 return GNUNET_SYSERR; 925 return GNUNET_SYSERR;
913 } 926 }
927 sctx->addrs = GNUNET_malloc ((i+1) * sizeof(struct sockaddr*));
928 sctx->addrlens = GNUNET_malloc ((i+1) * sizeof (socklen_t));
929 i = 0;
930 next = res;
931 while (NULL != (pos = next))
932 {
933 next = pos->ai_next;
934 if ( (disablev6) && (pos->ai_family == AF_INET6))
935 continue;
936#if DEBUG_SERVICE
937 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
938 "Service `%s' will bind to `%s'\n",
939 sctx->serviceName,
940 GNUNET_a2s (pos->ai_addr,
941 pos->ai_addrlen));
942#endif
943 if (pos->ai_family == AF_INET)
944 {
945 GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in));
946 sctx->addrlens[i] = pos->ai_addrlen;
947 sctx->addrs[i] = GNUNET_malloc (sctx->addrlens[i]);
948 memcpy (sctx->addrs[i], pos->ai_addr, sctx->addrlens[i]);
949 ((struct sockaddr_in *) sctx->addrs[i])->sin_port = htons (port);
950 }
951 else
952 {
953 GNUNET_assert (pos->ai_family == AF_INET6);
954 GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in6));
955 sctx->addrlens[i] = pos->ai_addrlen;
956 sctx->addrs[i] = GNUNET_malloc (sctx->addrlens[i]);
957 memcpy (sctx->addrs[i], pos->ai_addr, sctx->addrlens[i]);
958 ((struct sockaddr_in6 *) sctx->addrs[i])->sin6_port = htons (port);
959 }
960 i++;
961 }
914 GNUNET_free (hostname); 962 GNUNET_free (hostname);
915 if (pos->ai_family == AF_INET)
916 {
917 GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in));
918 sctx->addrlen = pos->ai_addrlen;
919 sctx->addr = GNUNET_malloc (sctx->addrlen);
920 memcpy (sctx->addr, res->ai_addr, sctx->addrlen);
921 ((struct sockaddr_in *) sctx->addr)->sin_port = htons (port);
922 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
923 _
924 ("Configured to bind to %s address; %s connections to this service will fail!\n"),
925 "IPv4", "IPv6");
926 }
927 else
928 {
929 GNUNET_assert (pos->ai_family == AF_INET6);
930 GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in6));
931 sctx->addrlen = pos->ai_addrlen;
932 sctx->addr = GNUNET_malloc (sctx->addrlen);
933 memcpy (sctx->addr, res->ai_addr, sctx->addrlen);
934 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
935 _
936 ("Configured to bind to %s address; %s connections to this service will fail!\n"),
937 "IPv6", "IPv4");
938 ((struct sockaddr_in6 *) sctx->addr)->sin6_port = htons (port);
939 }
940 freeaddrinfo (res); 963 freeaddrinfo (res);
941 } 964 }
942 else 965 else
@@ -945,28 +968,38 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
945 if (disablev6) 968 if (disablev6)
946 { 969 {
947 /* V4-only */ 970 /* V4-only */
948 sctx->addrlen = sizeof (struct sockaddr_in); 971 sctx->addrs = GNUNET_malloc (2 * sizeof(struct sockaddr*));
949 sctx->addr = GNUNET_malloc (sctx->addrlen); 972 sctx->addrlens = GNUNET_malloc (2 * sizeof (socklen_t));
973 sctx->addrlens[0] = sizeof (struct sockaddr_in);
974 sctx->addrs[0] = GNUNET_malloc (sctx->addrlens[0]);
950#if HAVE_SOCKADDR_IN_SIN_LEN 975#if HAVE_SOCKADDR_IN_SIN_LEN
951 ((struct sockaddr_in *) sctx->addr)->sin_len = sctx->addrlen; 976 ((struct sockaddr_in *) sctx->addrs[0])->sin_len = sctx->addrlens[0];
952#endif 977#endif
953 ((struct sockaddr_in *) sctx->addr)->sin_family = AF_INET; 978 ((struct sockaddr_in *) sctx->addrs[0])->sin_family = AF_INET;
954 ((struct sockaddr_in *) sctx->addr)->sin_port = htons (port); 979 ((struct sockaddr_in *) sctx->addrs[0])->sin_port = htons (port);
955 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
956 _
957 ("Configured to bind to %s address; %s connections to this service will fail!\n"),
958 "IPv4", "IPv6");
959 } 980 }
960 else 981 else
961 { 982 {
962 /* dual stack */ 983 /* dual stack */
963 sctx->addrlen = sizeof (struct sockaddr_in6); 984 sctx->addrs = GNUNET_malloc (3 * sizeof(struct sockaddr*));
964 sctx->addr = GNUNET_malloc (sctx->addrlen); 985 sctx->addrlens = GNUNET_malloc (3 * sizeof (socklen_t));
986
987 sctx->addrlens[0] = sizeof (struct sockaddr_in6);
988 sctx->addrs[0] = GNUNET_malloc (sctx->addrlens[0]);
989#if HAVE_SOCKADDR_IN_SIN_LEN
990 ((struct sockaddr_in6 *) sctx->addrs[0])->sin6_len = sctx->addrlen[0];
991#endif
992 ((struct sockaddr_in6 *) sctx->addrs[0])->sin6_family = AF_INET6;
993 ((struct sockaddr_in6 *) sctx->addrs[0])->sin6_port = htons (port);
994
995 sctx->addrlens[1] = sizeof (struct sockaddr_in);
996 sctx->addrs[1] = GNUNET_malloc (sctx->addrlens[1]);
965#if HAVE_SOCKADDR_IN_SIN_LEN 997#if HAVE_SOCKADDR_IN_SIN_LEN
966 ((struct sockaddr_in6 *) sctx->addr)->sin6_len = sctx->addrlen; 998 ((struct sockaddr_in *) sctx->addrs[1])->sin_len = sctx->addrlens[1];
967#endif 999#endif
968 ((struct sockaddr_in6 *) sctx->addr)->sin6_family = AF_INET6; 1000 ((struct sockaddr_in *) sctx->addrs[1])->sin_family = AF_INET;
969 ((struct sockaddr_in6 *) sctx->addr)->sin6_port = htons (port); 1001 ((struct sockaddr_in *) sctx->addrs[1])->sin_port = htons (port);
1002
970 } 1003 }
971 } 1004 }
972 sctx->maxbuf = (size_t) maxbuf; 1005 sctx->maxbuf = (size_t) maxbuf;
@@ -1090,15 +1123,21 @@ service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1090 sctx->server = GNUNET_SERVER_create (tc->sched, 1123 sctx->server = GNUNET_SERVER_create (tc->sched,
1091 &check_access, 1124 &check_access,
1092 sctx, 1125 sctx,
1093 sctx->addr, 1126 sctx->addrs,
1094 sctx->addrlen, 1127 sctx->addrlens,
1095 sctx->maxbuf, 1128 sctx->maxbuf,
1096 sctx->timeout, sctx->require_found); 1129 sctx->timeout, sctx->require_found);
1097 if (sctx->server == NULL) 1130 if (sctx->server == NULL)
1098 { 1131 {
1099 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1132 i = 0;
1100 _("Failed to start `%s' at `%s'\n"), 1133 while (sctx->addrs[i] != NULL)
1101 sctx->serviceName, GNUNET_a2s (sctx->addr, sctx->addrlen)); 1134 {
1135 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1136 _("Failed to start `%s' at `%s'\n"),
1137 sctx->serviceName,
1138 GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
1139 i++;
1140 }
1102 sctx->ret = GNUNET_SYSERR; 1141 sctx->ret = GNUNET_SYSERR;
1103 return; 1142 return;
1104 } 1143 }
@@ -1123,9 +1162,15 @@ service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1123 sctx->ready_confirm_fd = -1; 1162 sctx->ready_confirm_fd = -1;
1124 write_pid_file (sctx, getpid ()); 1163 write_pid_file (sctx, getpid ());
1125 } 1164 }
1126 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1165 i = 0;
1127 _("Service `%s' runs at %s\n"), 1166 while (sctx->addrs[i] != NULL)
1128 sctx->serviceName, GNUNET_a2s (sctx->addr, sctx->addrlen)); 1167 {
1168 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1169 _("Service `%s' runs at %s\n"),
1170 sctx->serviceName,
1171 GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
1172 i++;
1173 }
1129 sctx->task (sctx->task_cls, tc->sched, sctx->server, sctx->cfg); 1174 sctx->task (sctx->task_cls, tc->sched, sctx->server, sctx->cfg);
1130} 1175}
1131 1176
@@ -1295,6 +1340,7 @@ GNUNET_SERVICE_run (int argc,
1295 char *loglev; 1340 char *loglev;
1296 char *logfile; 1341 char *logfile;
1297 int do_daemonize; 1342 int do_daemonize;
1343 unsigned int i;
1298 struct GNUNET_SERVICE_Context sctx; 1344 struct GNUNET_SERVICE_Context sctx;
1299 struct GNUNET_CONFIGURATION_Handle *cfg; 1345 struct GNUNET_CONFIGURATION_Handle *cfg;
1300 struct GNUNET_GETOPT_CommandLineOption service_options[] = { 1346 struct GNUNET_GETOPT_CommandLineOption service_options[] = {
@@ -1358,7 +1404,11 @@ shutdown:
1358 } 1404 }
1359 1405
1360 GNUNET_CONFIGURATION_destroy (cfg); 1406 GNUNET_CONFIGURATION_destroy (cfg);
1361 GNUNET_free_non_null (sctx.addr); 1407 i = 0;
1408 while (sctx.addrs[i] != NULL)
1409 GNUNET_free (sctx.addrs[i++]);
1410 GNUNET_free_non_null (sctx.addrs);
1411 GNUNET_free_non_null (sctx.addrlens);
1362 GNUNET_free_non_null (logfile); 1412 GNUNET_free_non_null (logfile);
1363 GNUNET_free (loglev); 1413 GNUNET_free (loglev);
1364 GNUNET_free (cfg_fn); 1414 GNUNET_free (cfg_fn);
@@ -1402,8 +1452,8 @@ GNUNET_SERVICE_start (const char *serviceName,
1402 (NULL == (sctx->server = GNUNET_SERVER_create (sched, 1452 (NULL == (sctx->server = GNUNET_SERVER_create (sched,
1403 &check_access, 1453 &check_access,
1404 sctx, 1454 sctx,
1405 sctx->addr, 1455 sctx->addrs,
1406 sctx->addrlen, 1456 sctx->addrlens,
1407 sctx->maxbuf, 1457 sctx->maxbuf,
1408 sctx->timeout, 1458 sctx->timeout,
1409 sctx->require_found)))) 1459 sctx->require_found))))
@@ -1442,10 +1492,15 @@ GNUNET_SERVICE_get_server (struct GNUNET_SERVICE_Context *ctx)
1442void 1492void
1443GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Context *sctx) 1493GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Context *sctx)
1444{ 1494{
1495 unsigned int i;
1445 if (NULL != sctx->server) 1496 if (NULL != sctx->server)
1446 GNUNET_SERVER_destroy (sctx->server); 1497 GNUNET_SERVER_destroy (sctx->server);
1447 GNUNET_free_non_null (sctx->my_handlers); 1498 GNUNET_free_non_null (sctx->my_handlers);
1448 GNUNET_free_non_null (sctx->addr); 1499 i = 0;
1500 while (sctx->addrs[i] != NULL)
1501 GNUNET_free (sctx->addrs[i++]);
1502 GNUNET_free_non_null (sctx->addrs);
1503 GNUNET_free_non_null (sctx->addrlens);
1449 GNUNET_free_non_null (sctx->v4_denied); 1504 GNUNET_free_non_null (sctx->v4_denied);
1450 GNUNET_free_non_null (sctx->v6_denied); 1505 GNUNET_free_non_null (sctx->v6_denied);
1451 GNUNET_free_non_null (sctx->v4_allowed); 1506 GNUNET_free_non_null (sctx->v4_allowed);