GNUnet  0.19.4
tcp_service_legacy.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2009, 2012 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_protocols.h"
29 #include "gnunet_constants.h"
31 
32 #if HAVE_MALLINFO2
33 #include <malloc.h>
34 #include "gauger.h"
35 #endif
36 
37 
38 /* ******************* access control ******************** */
39 
47 static int
49  const struct in_addr *add)
50 {
51  unsigned int i;
52 
53  if (NULL == list)
54  return GNUNET_NO;
55  i = 0;
56  while ((list[i].network.s_addr != 0) || (list[i].netmask.s_addr != 0))
57  {
58  if ((add->s_addr & list[i].netmask.s_addr) ==
59  (list[i].network.s_addr & list[i].netmask.s_addr))
60  return GNUNET_YES;
61  i++;
62  }
63  return GNUNET_NO;
64 }
65 
66 
74 static int
76  const struct in6_addr *ip)
77 {
78  unsigned int i;
79  unsigned int j;
80  struct in6_addr zero;
81 
82  if (NULL == list)
83  return GNUNET_NO;
84  memset (&zero, 0, sizeof(struct in6_addr));
85  i = 0;
86 NEXT:
87  while (0 != memcmp (&zero, &list[i].network, sizeof(struct in6_addr)))
88  {
89  for (j = 0; j < sizeof(struct in6_addr) / sizeof(int); j++)
90  if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
91  (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
92  {
93  i++;
94  goto NEXT;
95  }
96  return GNUNET_YES;
97  }
98  return GNUNET_NO;
99 }
100 
101 
102 /* ****************** service struct ****************** */
103 
104 
109 {
114 
119 
124  struct sockaddr **addrs;
125 
129  const char *service_name;
130 
135 
139  void *task_cls;
140 
145 
150 
156 
162 
168 
172  socklen_t *addrlens;
173 
178 
183 
188 
192  int ret;
193 
200 
206 
213 
222 
227 };
228 
229 
230 /* ****************** message handlers ****************** */
231 
240 static size_t
241 write_test (void *cls, size_t size, void *buf)
242 {
243  struct GNUNET_SERVER_Client *client = cls;
244  struct GNUNET_MessageHeader *msg;
245 
246  if (size < sizeof(struct GNUNET_MessageHeader))
247  {
249  return 0; /* client disconnected */
250  }
251  msg = (struct GNUNET_MessageHeader *) buf;
252  msg->type = htons (GNUNET_MESSAGE_TYPE_TEST);
253  msg->size = htons (sizeof(struct GNUNET_MessageHeader));
255  return sizeof(struct GNUNET_MessageHeader);
256 }
257 
258 
266 static void
267 handle_test (void *cls,
268  struct GNUNET_SERVER_Client *client,
269  const struct GNUNET_MessageHeader *message)
270 {
271  /* simply bounce message back to acknowledge */
272  if (NULL ==
274  sizeof(struct GNUNET_MessageHeader),
276  &write_test,
277  client))
279 }
280 
281 
287 static const struct GNUNET_SERVER_MessageHandler defhandlers[] =
288 { { &handle_test,
289  NULL,
291  sizeof(struct GNUNET_MessageHeader) },
292  { NULL, NULL, 0, 0 } };
293 
294 
295 /* ****************** service core routines ************** */
296 
297 
308 static int
309 check_access (void *cls,
310  const struct GNUNET_CONNECTION_Credentials *uc,
311  const struct sockaddr *addr,
312  socklen_t addrlen)
313 {
314  struct LEGACY_SERVICE_Context *sctx = cls;
315  const struct sockaddr_in *i4;
316  const struct sockaddr_in6 *i6;
317  int ret;
318 
319  switch (addr->sa_family)
320  {
321  case AF_INET:
322  GNUNET_assert (addrlen == sizeof(struct sockaddr_in));
323  i4 = (const struct sockaddr_in *) addr;
324  ret = ((NULL == sctx->v4_allowed) ||
325  (check_ipv4_listed (sctx->v4_allowed, &i4->sin_addr))) &&
326  ((NULL == sctx->v4_denied) ||
327  (! check_ipv4_listed (sctx->v4_denied, &i4->sin_addr)));
328  break;
329 
330  case AF_INET6:
331  GNUNET_assert (addrlen == sizeof(struct sockaddr_in6));
332  i6 = (const struct sockaddr_in6 *) addr;
333  ret = ((NULL == sctx->v6_allowed) ||
334  (check_ipv6_listed (sctx->v6_allowed, &i6->sin6_addr))) &&
335  ((NULL == sctx->v6_denied) ||
336  (! check_ipv6_listed (sctx->v6_denied, &i6->sin6_addr)));
337  break;
338 
339  case AF_UNIX:
340  ret = GNUNET_OK; /* controlled using file-system ACL now */
341  break;
342 
343  default:
345  _ ("Unknown address family %d\n"),
346  addr->sa_family);
347  return GNUNET_SYSERR;
348  }
349  if (GNUNET_OK != ret)
350  {
352  _ ("Access from `%s' denied to service `%s'\n"),
353  GNUNET_a2s (addr, addrlen),
354  sctx->service_name);
355  }
356  return ret;
357 }
358 
359 
367 static char *
369 {
370  char *pif;
371 
373  sctx->service_name,
374  "PIDFILE",
375  &pif))
376  return NULL;
377  return pif;
378 }
379 
380 
390 static int
392  struct LEGACY_SERVICE_Context *sctx,
393  const char *option)
394 {
395  char *opt;
396 
397  if (! GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, option))
398  {
399  *ret = NULL;
400  return GNUNET_OK;
401  }
404  sctx->service_name,
405  option,
406  &opt));
407  if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy (opt)))
408  {
410  _ ("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
411  opt,
412  sctx->service_name,
413  option);
414  GNUNET_free (opt);
415  return GNUNET_SYSERR;
416  }
417  GNUNET_free (opt);
418  return GNUNET_OK;
419 }
420 
421 
431 static int
433  struct LEGACY_SERVICE_Context *sctx,
434  const char *option)
435 {
436  char *opt;
437 
438  if (! GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, option))
439  {
440  *ret = NULL;
441  return GNUNET_OK;
442  }
445  sctx->service_name,
446  option,
447  &opt));
448  if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy (opt)))
449  {
451  _ ("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
452  opt,
453  sctx->service_name,
454  option);
455  GNUNET_free (opt);
456  return GNUNET_SYSERR;
457  }
458  GNUNET_free (opt);
459  return GNUNET_OK;
460 }
461 
462 
473 static void
474 add_unixpath (struct sockaddr **saddrs,
475  socklen_t *saddrlens,
476  const char *unixpath,
477  int abstract)
478 {
479 #ifdef AF_UNIX
480  struct sockaddr_un *un;
481 
482  un = GNUNET_new (struct sockaddr_un);
483  un->sun_family = AF_UNIX;
484  GNUNET_strlcpy (un->sun_path, unixpath, sizeof(un->sun_path));
485 #ifdef __linux__
486  if (GNUNET_YES == abstract)
487  un->sun_path[0] = '\0';
488 #endif
489 #if HAVE_SOCKADDR_UN_SUN_LEN
490  un->sun_len = (u_char) sizeof(struct sockaddr_un);
491 #endif
492  *saddrs = (struct sockaddr *) un;
493  *saddrlens = sizeof(struct sockaddr_un);
494 #else
495  /* this function should never be called
496  * unless AF_UNIX is defined! */
497  GNUNET_assert (0);
498 #endif
499 }
500 
501 
522 int
524  const char *service_name,
525  const struct GNUNET_CONFIGURATION_Handle *cfg,
526  struct sockaddr ***addrs,
527  socklen_t **addr_lens)
528 {
529  int disablev6;
530  struct GNUNET_NETWORK_Handle *desc;
531  unsigned long long port;
532  char *unixpath;
533  struct addrinfo hints;
534  struct addrinfo *res;
535  struct addrinfo *pos;
536  struct addrinfo *next;
537  unsigned int i;
538  int resi;
539  int ret;
540  int abstract;
541  struct sockaddr **saddrs;
542  socklen_t *saddrlens;
543  char *hostname;
544 
545  *addrs = NULL;
546  *addr_lens = NULL;
547  desc = NULL;
549  {
550  if (GNUNET_SYSERR ==
552  service_name,
553  "DISABLEV6")))
554  return GNUNET_SYSERR;
555  }
556  else
557  disablev6 = GNUNET_NO;
558 
559  if (! disablev6)
560  {
561  /* probe IPv6 support */
562  desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
563  if (NULL == desc)
564  {
565  if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
566  (EACCES == errno))
567  {
569  return GNUNET_SYSERR;
570  }
572  _ (
573  "Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
574  service_name,
575  strerror (errno));
576  disablev6 = GNUNET_YES;
577  }
578  else
579  {
581  desc = NULL;
582  }
583  }
584 
585  port = 0;
587  {
589  service_name,
590  "PORT",
591  &port))
592  {
594  _ ("Require valid port number for service `%s' in configuration!\n"),
595  service_name);
596  }
597  if (port > 65535)
598  {
600  _ ("Require valid port number for service `%s' in configuration!\n"),
601  service_name);
602  return GNUNET_SYSERR;
603  }
604  }
605 
607  {
610  service_name,
611  "BINDTO",
612  &hostname));
613  }
614  else
615  hostname = NULL;
616 
617  unixpath = NULL;
618  abstract = GNUNET_NO;
619 #ifdef AF_UNIX
620  if ((GNUNET_YES ==
623  service_name,
624  "UNIXPATH",
625  &unixpath)) &&
626  (0 < strlen (unixpath)))
627  {
628  /* probe UNIX support */
629  struct sockaddr_un s_un;
630 
631  if (strlen (unixpath) >= sizeof(s_un.sun_path))
632  {
634  _ ("UNIXPATH `%s' too long, maximum length is %llu\n"),
635  unixpath,
636  (unsigned long long) sizeof(s_un.sun_path));
637  unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
638  LOG (GNUNET_ERROR_TYPE_INFO, _ ("Using `%s' instead\n"), unixpath);
639  }
640 #ifdef __linux__
642  "TESTING",
643  "USE_ABSTRACT_SOCKETS");
644  if (GNUNET_SYSERR == abstract)
645  abstract = GNUNET_NO;
646 #endif
647  if ((GNUNET_YES != abstract) &&
650  }
651  if (NULL != unixpath)
652  {
653  desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
654  if (NULL == desc)
655  {
656  if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
657  (EACCES == errno))
658  {
661  GNUNET_free (unixpath);
662  return GNUNET_SYSERR;
663  }
665  _ (
666  "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
667  service_name,
668  strerror (errno));
669  GNUNET_free (unixpath);
670  unixpath = NULL;
671  }
672  else
673  {
675  desc = NULL;
676  }
677  }
678 #endif
679 
680  if ((0 == port) && (NULL == unixpath))
681  {
683  _ (
684  "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
685  service_name);
687  return GNUNET_SYSERR;
688  }
689  if (0 == port)
690  {
691  saddrs = GNUNET_malloc (2 * sizeof(struct sockaddr *));
692  saddrlens = GNUNET_malloc (2 * sizeof(socklen_t));
693  add_unixpath (saddrs, saddrlens, unixpath, abstract);
694  GNUNET_free (unixpath);
696  *addrs = saddrs;
697  *addr_lens = saddrlens;
698  return 1;
699  }
700 
701  if (NULL != hostname)
702  {
704  "Resolving `%s' since that is where `%s' will bind to.\n",
705  hostname,
706  service_name);
707  memset (&hints, 0, sizeof(struct addrinfo));
708  if (disablev6)
709  hints.ai_family = AF_INET;
710  hints.ai_protocol = IPPROTO_TCP;
711  if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
712  (NULL == res))
713  {
715  _ ("Failed to resolve `%s': %s\n"),
716  hostname,
717  gai_strerror (ret));
719  GNUNET_free (unixpath);
720  return GNUNET_SYSERR;
721  }
722  next = res;
723  i = 0;
724  while (NULL != (pos = next))
725  {
726  next = pos->ai_next;
727  if ((disablev6) && (pos->ai_family == AF_INET6))
728  continue;
729  i++;
730  }
731  if (0 == i)
732  {
734  _ ("Failed to find %saddress for `%s'.\n"),
735  disablev6 ? "IPv4 " : "",
736  hostname);
737  freeaddrinfo (res);
739  GNUNET_free (unixpath);
740  return GNUNET_SYSERR;
741  }
742  resi = i;
743  if (NULL != unixpath)
744  resi++;
745  saddrs = GNUNET_malloc ((resi + 1) * sizeof(struct sockaddr *));
746  saddrlens = GNUNET_malloc ((resi + 1) * sizeof(socklen_t));
747  i = 0;
748  if (NULL != unixpath)
749  {
750  add_unixpath (saddrs, saddrlens, unixpath, abstract);
751  i++;
752  }
753  next = res;
754  while (NULL != (pos = next))
755  {
756  next = pos->ai_next;
757  if ((disablev6) && (AF_INET6 == pos->ai_family))
758  continue;
759  if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
760  continue; /* not TCP */
761  if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
762  continue; /* huh? */
764  "Service `%s' will bind to `%s'\n",
765  service_name,
766  GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
767  if (AF_INET == pos->ai_family)
768  {
769  GNUNET_assert (sizeof(struct sockaddr_in) == pos->ai_addrlen);
770  saddrlens[i] = pos->ai_addrlen;
771  saddrs[i] = GNUNET_malloc (saddrlens[i]);
772  GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
773  ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
774  }
775  else
776  {
777  GNUNET_assert (AF_INET6 == pos->ai_family);
778  GNUNET_assert (sizeof(struct sockaddr_in6) == pos->ai_addrlen);
779  saddrlens[i] = pos->ai_addrlen;
780  saddrs[i] = GNUNET_malloc (saddrlens[i]);
781  GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
782  ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
783  }
784  i++;
785  }
787  freeaddrinfo (res);
788  resi = i;
789  }
790  else
791  {
792  /* will bind against everything, just set port */
793  if (disablev6)
794  {
795  /* V4-only */
796  resi = 1;
797  if (NULL != unixpath)
798  resi++;
799  i = 0;
800  saddrs = GNUNET_malloc ((resi + 1) * sizeof(struct sockaddr *));
801  saddrlens = GNUNET_malloc ((resi + 1) * sizeof(socklen_t));
802  if (NULL != unixpath)
803  {
804  add_unixpath (saddrs, saddrlens, unixpath, abstract);
805  i++;
806  }
807  saddrlens[i] = sizeof(struct sockaddr_in);
808  saddrs[i] = GNUNET_malloc (saddrlens[i]);
809 #if HAVE_SOCKADDR_IN_SIN_LEN
810  ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
811 #endif
812  ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
813  ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
814  }
815  else
816  {
817  /* dual stack */
818  resi = 2;
819  if (NULL != unixpath)
820  resi++;
821  saddrs = GNUNET_malloc ((resi + 1) * sizeof(struct sockaddr *));
822  saddrlens = GNUNET_malloc ((resi + 1) * sizeof(socklen_t));
823  i = 0;
824  if (NULL != unixpath)
825  {
826  add_unixpath (saddrs, saddrlens, unixpath, abstract);
827  i++;
828  }
829  saddrlens[i] = sizeof(struct sockaddr_in6);
830  saddrs[i] = GNUNET_malloc (saddrlens[i]);
831 #if HAVE_SOCKADDR_IN_SIN_LEN
832  ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
833 #endif
834  ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
835  ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
836  i++;
837  saddrlens[i] = sizeof(struct sockaddr_in);
838  saddrs[i] = GNUNET_malloc (saddrlens[i]);
839 #if HAVE_SOCKADDR_IN_SIN_LEN
840  ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
841 #endif
842  ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
843  ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
844  }
845  }
846  GNUNET_free (unixpath);
847  *addrs = saddrs;
848  *addr_lens = saddrlens;
849  return resi;
850 }
851 
852 
871 static int
873 {
874  struct GNUNET_TIME_Relative idleout;
875  int tolerant;
876  const char *nfds;
877  unsigned int cnt;
878  int flags;
879 
881  sctx->service_name,
882  "TIMEOUT"))
883  {
885  sctx->service_name,
886  "TIMEOUT",
887  &idleout))
888  {
890  _ ("Specified value for `%s' of service `%s' is invalid\n"),
891  "TIMEOUT",
892  sctx->service_name);
893  return GNUNET_SYSERR;
894  }
895  sctx->timeout = idleout;
896  }
897  else
899 
901  sctx->service_name,
902  "TOLERANT"))
903  {
904  if (GNUNET_SYSERR ==
905  (tolerant = GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg,
906  sctx->service_name,
907  "TOLERANT")))
908  {
910  _ ("Specified value for `%s' of service `%s' is invalid\n"),
911  "TOLERANT",
912  sctx->service_name);
913  return GNUNET_SYSERR;
914  }
915  }
916  else
917  tolerant = GNUNET_NO;
918 
919  errno = 0;
920  if ((NULL != (nfds = getenv ("LISTEN_FDS"))) &&
921  (1 == sscanf (nfds, "%u", &cnt)) && (cnt > 0) && (cnt < FD_SETSIZE) &&
922  (cnt + 4 < FD_SETSIZE))
923  {
924  sctx->lsocks =
925  GNUNET_malloc (sizeof(struct GNUNET_NETWORK_Handle *) * (cnt + 1));
926  while (0 < cnt--)
927  {
928  flags = fcntl (3 + cnt, F_GETFD);
929  if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) ||
930  (NULL ==
931  (sctx->lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt))))
932  {
934  _ (
935  "Could not access pre-bound socket %u, will try to bind myself\n"),
936  (unsigned int) 3 + cnt);
937  cnt++;
938  while (sctx->lsocks[cnt] != NULL)
939  GNUNET_break (0 == GNUNET_NETWORK_socket_close (sctx->lsocks[cnt++]));
940  GNUNET_free (sctx->lsocks);
941  sctx->lsocks = NULL;
942  break;
943  }
944  }
945  unsetenv ("LISTEN_FDS");
946  }
947 
948  if ((NULL == sctx->lsocks) &&
950  sctx->cfg,
951  &sctx->addrs,
952  &sctx->addrlens)))
953  return GNUNET_SYSERR;
954  sctx->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
956  sctx->service_name,
957  "UNIX_MATCH_UID");
959  sctx->service_name,
960  "UNIX_MATCH_GID");
961  process_acl4 (&sctx->v4_denied, sctx, "REJECT_FROM");
962  process_acl4 (&sctx->v4_allowed, sctx, "ACCEPT_FROM");
963  process_acl6 (&sctx->v6_denied, sctx, "REJECT_FROM6");
964  process_acl6 (&sctx->v6_allowed, sctx, "ACCEPT_FROM6");
965 
966  return GNUNET_OK;
967 }
968 
969 
977 static char *
979 {
980  char *un;
981 
983  sctx->service_name,
984  "USERNAME",
985  &un))
986  return NULL;
987  return un;
988 }
989 
990 
998 static int
1000 {
1001  FILE *pidfd;
1002  char *pif;
1003  char *user;
1004  char *rdir;
1005  int len;
1006 
1007  if (NULL == (pif = get_pid_file_name (sctx)))
1008  return GNUNET_OK; /* no file desired */
1009  user = get_user_name (sctx);
1010  rdir = GNUNET_strdup (pif);
1011  len = strlen (rdir);
1012  while ((len > 0) && (rdir[len] != DIR_SEPARATOR))
1013  len--;
1014  rdir[len] = '\0';
1015  if (0 != access (rdir, F_OK))
1016  {
1017  /* we get to create a directory -- and claim it
1018  * as ours! */
1019  (void) GNUNET_DISK_directory_create (rdir);
1020  if ((NULL != user) && (0 < strlen (user)))
1021  GNUNET_DISK_file_change_owner (rdir, user);
1022  }
1023  if (0 != access (rdir, W_OK | X_OK))
1024  {
1025  LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", rdir);
1026  GNUNET_free (rdir);
1027  GNUNET_free (user);
1028  GNUNET_free (pif);
1029  return GNUNET_SYSERR;
1030  }
1031  GNUNET_free (rdir);
1032  pidfd = fopen (pif, "w");
1033  if (NULL == pidfd)
1034  {
1036  GNUNET_free (pif);
1037  GNUNET_free (user);
1038  return GNUNET_SYSERR;
1039  }
1040  if (0 > fprintf (pidfd, "%u", pid))
1041  LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fprintf", pif);
1042  GNUNET_break (0 == fclose (pidfd));
1043  if ((NULL != user) && (0 < strlen (user)))
1044  GNUNET_DISK_file_change_owner (pif, user);
1045  GNUNET_free (user);
1046  GNUNET_free (pif);
1047  return GNUNET_OK;
1048 }
1049 
1050 
1056 static void
1057 shutdown_task (void *cls)
1058 {
1059  struct LEGACY_SERVICE_Context *service = cls;
1060  struct GNUNET_SERVER_Handle *server = service->server;
1061 
1062  service->shutdown_task = NULL;
1065  else
1066  GNUNET_SERVER_destroy (server);
1067 }
1068 
1069 
1075 static void
1076 service_task (void *cls)
1077 {
1078  struct LEGACY_SERVICE_Context *sctx = cls;
1079  unsigned int i;
1080 
1081  GNUNET_RESOLVER_connect (sctx->cfg);
1082  if (NULL != sctx->lsocks)
1084  sctx,
1085  sctx->lsocks,
1086  sctx->timeout,
1087  sctx->require_found);
1088  else
1090  sctx,
1091  sctx->addrs,
1092  sctx->addrlens,
1093  sctx->timeout,
1094  sctx->require_found);
1095  if (NULL == sctx->server)
1096  {
1097  if (NULL != sctx->addrs)
1098  for (i = 0; NULL != sctx->addrs[i]; i++)
1100  _ ("Failed to start `%s' at `%s'\n"),
1101  sctx->service_name,
1102  GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
1103  sctx->ret = GNUNET_SYSERR;
1104  return;
1105  }
1106 
1107  if (NULL != sctx->addrs)
1108  for (i = 0; NULL != sctx->addrs[i]; i++)
1109  if ((AF_UNIX == sctx->addrs[i]->sa_family) &&
1110  ('\0' != ((const struct sockaddr_un *) sctx->addrs[i])->sun_path[0]))
1111  GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)
1112  sctx->addrs[i])
1113  ->sun_path,
1114  sctx->match_uid,
1115  sctx->match_gid);
1116 
1118  {
1119  /* install a task that will kill the server
1120  * process if the scheduler ever gets a shutdown signal */
1122  }
1123  sctx->my_handlers = GNUNET_malloc (sizeof(defhandlers));
1125  i = 0;
1126  while (NULL != sctx->my_handlers[i].callback)
1127  sctx->my_handlers[i++].callback_cls = sctx;
1129  if (-1 != sctx->ready_confirm_fd)
1130  {
1131  GNUNET_break (1 == write (sctx->ready_confirm_fd, ".", 1));
1132  GNUNET_break (0 == close (sctx->ready_confirm_fd));
1133  sctx->ready_confirm_fd = -1;
1134  write_pid_file (sctx, getpid ());
1135  }
1136  if (NULL != sctx->addrs)
1137  {
1138  i = 0;
1139  while (NULL != sctx->addrs[i])
1140  {
1142  _ ("Service `%s' runs at %s\n"),
1143  sctx->service_name,
1144  GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
1145  i++;
1146  }
1147  }
1148  sctx->task (sctx->task_cls, sctx->server, sctx->cfg);
1149 }
1150 
1151 
1158 static int
1160 {
1161  pid_t pid;
1162  int nullfd;
1163  int filedes[2];
1164 
1165  if (0 != pipe (filedes))
1166  {
1168  return GNUNET_SYSERR;
1169  }
1170  pid = fork ();
1171  if (pid < 0)
1172  {
1174  return GNUNET_SYSERR;
1175  }
1176  if (0 != pid)
1177  {
1178  /* Parent */
1179  char c;
1180 
1181  GNUNET_break (0 == close (filedes[1]));
1182  c = 'X';
1183  if (1 != read (filedes[0], &c, sizeof(char)))
1185  fflush (stdout);
1186  switch (c)
1187  {
1188  case '.':
1189  exit (0);
1190 
1191  case 'I':
1193  _ ("Service process failed to initialize\n"));
1194  break;
1195 
1196  case 'S':
1198  _ ("Service process could not initialize server function\n"));
1199  break;
1200 
1201  case 'X':
1203  _ ("Service process failed to report status\n"));
1204  break;
1205  }
1206  exit (1); /* child reported error */
1207  }
1208  GNUNET_break (0 == close (0));
1209  GNUNET_break (0 == close (1));
1210  GNUNET_break (0 == close (filedes[0]));
1211  nullfd = open ("/dev/null", O_RDWR | O_APPEND);
1212  if (nullfd < 0)
1213  return GNUNET_SYSERR;
1214  /* set stdin/stdout to /dev/null */
1215  if ((dup2 (nullfd, 0) < 0) || (dup2 (nullfd, 1) < 0))
1216  {
1218  (void) close (nullfd);
1219  return GNUNET_SYSERR;
1220  }
1221  (void) close (nullfd);
1222  /* Detach from controlling terminal */
1223  pid = setsid ();
1224  if (-1 == pid)
1226  sctx->ready_confirm_fd = filedes[1];
1227 
1228  return GNUNET_OK;
1229 }
1230 
1231 
1238 static int
1240 {
1241  char *user;
1242 
1243  if (NULL == (user = get_user_name (sctx)))
1244  return GNUNET_OK; /* keep */
1245 
1246  struct passwd *pws;
1247 
1248  errno = 0;
1249  pws = getpwnam (user);
1250  if (NULL == pws)
1251  {
1253  _ ("Cannot obtain information about user `%s': %s\n"),
1254  user,
1255  errno == 0 ? _ ("No such user") : strerror (errno));
1256  GNUNET_free (user);
1257  return GNUNET_SYSERR;
1258  }
1259  if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) ||
1260 #if HAVE_INITGROUPS
1261  (0 != initgroups (user, pws->pw_gid)) ||
1262 #endif
1263  (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid)))
1264  {
1265  if ((0 != setregid (pws->pw_gid, pws->pw_gid)) ||
1266  (0 != setreuid (pws->pw_uid, pws->pw_uid)))
1267  {
1269  _ ("Cannot change user/group to `%s': %s\n"),
1270  user,
1271  strerror (errno));
1272  GNUNET_free (user);
1273  return GNUNET_SYSERR;
1274  }
1275  }
1276 
1277  GNUNET_free (user);
1278  return GNUNET_OK;
1279 }
1280 
1281 
1287 static void
1289 {
1290  char *pif = get_pid_file_name (sctx);
1291 
1292  if (NULL == pif)
1293  return; /* no PID file */
1294  if (0 != unlink (pif))
1296  GNUNET_free (pif);
1297 }
1298 
1299 
1313 int
1315  char *const *argv,
1316  const char *service_name,
1318  LEGACY_SERVICE_Main task,
1319  void *task_cls)
1320 {
1321 #define HANDLE_ERROR \
1322  do \
1323  { \
1324  GNUNET_break (0); \
1325  goto shutdown; \
1326  } while (0)
1327 
1328  int err;
1329  int ret;
1330  char *cfg_fn;
1331  char *opt_cfg_fn;
1332  char *loglev;
1333  char *logfile;
1334  int do_daemonize;
1335  unsigned int i;
1336  unsigned long long skew_offset;
1337  unsigned long long skew_variance;
1338  long long clock_offset;
1339  struct LEGACY_SERVICE_Context sctx;
1341  const char *xdg;
1342 
1343  struct GNUNET_GETOPT_CommandLineOption service_options[] =
1344  { GNUNET_GETOPT_option_cfgfile (&opt_cfg_fn),
1346  "daemonize",
1347  gettext_noop (
1348  "do daemonize (detach from terminal)"),
1349  &do_daemonize),
1352  GNUNET_GETOPT_option_logfile (&logfile),
1353  GNUNET_GETOPT_option_version (PACKAGE_VERSION " " VCS_VERSION),
1355  err = 1;
1356  do_daemonize = 0;
1357  logfile = NULL;
1358  loglev = NULL;
1359  opt_cfg_fn = NULL;
1360  xdg = getenv ("XDG_CONFIG_HOME");
1361  if (NULL != xdg)
1362  GNUNET_asprintf (&cfg_fn,
1363  "%s%s%s",
1364  xdg,
1367  else
1368  cfg_fn = GNUNET_strdup (GNUNET_OS_project_data_get ()->user_config_file);
1369  memset (&sctx, 0, sizeof(sctx));
1370  sctx.options = options;
1371  sctx.ready_confirm_fd = -1;
1372  sctx.ret = GNUNET_OK;
1374  sctx.task = task;
1375  sctx.task_cls = task_cls;
1376  sctx.service_name = service_name;
1377  sctx.cfg = cfg = GNUNET_CONFIGURATION_create ();
1378 
1379  /* setup subsystems */
1380  ret = GNUNET_GETOPT_run (service_name, service_options, argc, argv);
1381  if (GNUNET_SYSERR == ret)
1382  goto shutdown;
1383  if (GNUNET_NO == ret)
1384  {
1385  err = 0;
1386  goto shutdown;
1387  }
1388  if (GNUNET_OK != GNUNET_log_setup (service_name, loglev, logfile))
1389  HANDLE_ERROR;
1390  if (NULL == opt_cfg_fn)
1391  opt_cfg_fn = GNUNET_strdup (cfg_fn);
1392  if (GNUNET_YES == GNUNET_DISK_file_test (opt_cfg_fn))
1393  {
1394  if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_fn))
1395  {
1397  _ ("Malformed configuration file `%s', exit ...\n"),
1398  opt_cfg_fn);
1399  goto shutdown;
1400  }
1401  }
1402  else
1403  {
1405  {
1407  _ ("Malformed configuration, exit ...\n"));
1408  goto shutdown;
1409  }
1410  if (0 != strcmp (opt_cfg_fn, cfg_fn))
1412  _ ("Could not access configuration file `%s'\n"),
1413  opt_cfg_fn);
1414  }
1415  if (GNUNET_OK != setup_service (&sctx))
1416  goto shutdown;
1417  if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sctx)))
1418  HANDLE_ERROR;
1419  if (GNUNET_OK != set_user_id (&sctx))
1420  goto shutdown;
1422  "Service `%s' runs with configuration from `%s'\n",
1423  service_name,
1424  opt_cfg_fn);
1426  "TESTING",
1427  "SKEW_OFFSET",
1428  &skew_offset)) &&
1430  "TESTING",
1431  "SKEW_VARIANCE",
1432  &skew_variance)))
1433  {
1434  clock_offset = skew_offset - skew_variance;
1435  GNUNET_TIME_set_offset (clock_offset);
1436  LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %lld ms\n", clock_offset);
1437  }
1438  /* actually run service */
1439  err = 0;
1441  /* shutdown */
1442  if ((1 == do_daemonize) && (NULL != sctx.server))
1443  pid_file_delete (&sctx);
1444  GNUNET_free (sctx.my_handlers);
1445 
1446 shutdown:
1447  if (-1 != sctx.ready_confirm_fd)
1448  {
1449  if (1 != write (sctx.ready_confirm_fd, err ? "I" : "S", 1))
1451  GNUNET_break (0 == close (sctx.ready_confirm_fd));
1452  }
1453 #if HAVE_MALLINFO2
1454  {
1455  char *counter;
1456 
1458  service_name,
1459  "GAUGER_HEAP")) &&
1461  service_name,
1462  "GAUGER_HEAP",
1463  &counter)))
1464  {
1465  struct mallinfo2 mi;
1466 
1467  mi = mallinfo2 ();
1468  GAUGER (service_name, counter, mi.usmblks, "blocks");
1469  GNUNET_free (counter);
1470  }
1471  }
1472 #endif
1474  i = 0;
1475  if (NULL != sctx.addrs)
1476  while (NULL != sctx.addrs[i])
1477  GNUNET_free_nz (sctx.addrs[i++]);
1478  GNUNET_free (sctx.addrs);
1479  GNUNET_free (sctx.addrlens);
1480  GNUNET_free (logfile);
1481  GNUNET_free (loglev);
1482  GNUNET_free (cfg_fn);
1483  GNUNET_free (opt_cfg_fn);
1484  GNUNET_free (sctx.v4_denied);
1485  GNUNET_free (sctx.v6_denied);
1486  GNUNET_free (sctx.v4_allowed);
1487  GNUNET_free (sctx.v6_allowed);
1488 
1489  return err ? GNUNET_SYSERR : sctx.ret;
1490 }
1491 
1492 
1502 struct LEGACY_SERVICE_Context *
1504  const struct GNUNET_CONFIGURATION_Handle *cfg,
1506 {
1507  int i;
1508  struct LEGACY_SERVICE_Context *sctx;
1509 
1510  sctx = GNUNET_new (struct LEGACY_SERVICE_Context);
1511  sctx->ready_confirm_fd = -1; /* no daemonizing */
1512  sctx->ret = GNUNET_OK;
1514  sctx->service_name = service_name;
1515  sctx->cfg = cfg;
1516  sctx->options = options;
1517 
1518  /* setup subsystems */
1519  if (GNUNET_OK != setup_service (sctx))
1520  {
1521  LEGACY_SERVICE_stop (sctx);
1522  return NULL;
1523  }
1524  if (NULL != sctx->lsocks)
1526  sctx,
1527  sctx->lsocks,
1528  sctx->timeout,
1529  sctx->require_found);
1530  else
1532  sctx,
1533  sctx->addrs,
1534  sctx->addrlens,
1535  sctx->timeout,
1536  sctx->require_found);
1537 
1538  if (NULL == sctx->server)
1539  {
1540  LEGACY_SERVICE_stop (sctx);
1541  return NULL;
1542  }
1543 
1544  if (NULL != sctx->addrs)
1545  for (i = 0; NULL != sctx->addrs[i]; i++)
1546  if ((AF_UNIX == sctx->addrs[i]->sa_family) &&
1547  ('\0' != ((const struct sockaddr_un *) sctx->addrs[i])->sun_path[0]))
1548  GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)
1549  sctx->addrs[i])
1550  ->sun_path,
1551  sctx->match_uid,
1552  sctx->match_gid);
1553 
1554  sctx->my_handlers = GNUNET_malloc (sizeof(defhandlers));
1556  i = 0;
1557  while ((sctx->my_handlers[i].callback != NULL))
1558  sctx->my_handlers[i++].callback_cls = sctx;
1560  return sctx;
1561 }
1562 
1563 
1571 struct GNUNET_SERVER_Handle *
1573 {
1574  return ctx->server;
1575 }
1576 
1577 
1585 struct GNUNET_NETWORK_Handle *const *
1587 {
1588  return ctx->lsocks;
1589 }
1590 
1591 
1597 void
1599 {
1600  unsigned int i;
1601 
1602 #if HAVE_MALLINFO2
1603  {
1604  char *counter;
1605 
1607  sctx->service_name,
1608  "GAUGER_HEAP")) &&
1610  sctx->service_name,
1611  "GAUGER_HEAP",
1612  &counter)))
1613  {
1614  struct mallinfo2 mi;
1615 
1616  mi = mallinfo2 ();
1617  GAUGER (sctx->service_name, counter, mi.usmblks, "blocks");
1618  GNUNET_free (counter);
1619  }
1620  }
1621 #endif
1622  if (NULL != sctx->shutdown_task)
1623  {
1625  sctx->shutdown_task = NULL;
1626  }
1627  if (NULL != sctx->server)
1628  GNUNET_SERVER_destroy (sctx->server);
1629  GNUNET_free (sctx->my_handlers);
1630  if (NULL != sctx->addrs)
1631  {
1632  i = 0;
1633  while (NULL != sctx->addrs[i])
1634  GNUNET_free_nz (sctx->addrs[i++]);
1635  GNUNET_free (sctx->addrs);
1636  }
1637  GNUNET_free (sctx->addrlens);
1638  GNUNET_free (sctx->v4_denied);
1639  GNUNET_free (sctx->v6_denied);
1640  GNUNET_free (sctx->v4_allowed);
1641  GNUNET_free (sctx->v6_allowed);
1642  GNUNET_free (sctx);
1643 }
1644 
1645 
1646 /* end of service.c */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
#define LOG(kind,...)
Definition: abd_api.c:38
#define LOG_STRERROR_FILE(kind, op, fn)
Definition: datacache.c:34
#define GAUGER(category, counter, value, unit)
Definition: gauger.h:19
char * getenv()
#define gettext_noop(String)
Definition: gettext.h:70
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static int list
Set if we should print a list of currently running services.
Definition: gnunet-arm.c:69
static char * config_file
Set to the name of the config file used.
Definition: gnunet-arm.c:84
static int res
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static int add
Desired action is to add a record.
#define LOG_STRERROR(kind, syscall)
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static const struct GNUNET_IDENTITY_PrivateKey zero
Public key of all zeros.
static char * hostname
Our hostname; we give this to all the peers we start.
static char buf[2048]
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_FS_UnindexContext * uc
static char * service_name
Option -s: service name (hash to get service descriptor)
Definition: gnunet-vpn.c:50
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
Constants for network protocols.
Functions related to doing DNS lookups.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_create(void)
Create a new configuration object.
void GNUNET_CONFIGURATION_destroy(struct GNUNET_CONFIGURATION_Handle *cfg)
Destroy configuration object.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_load(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Load configuration.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_have_value(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Test if we have a value for a particular option.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_change_owner(const char *filename, const char *user)
Change owner of a file.
Definition: disk.c:1213
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory).
Definition: disk.c:482
void GNUNET_DISK_fix_permissions(const char *fn, int require_uid_match, int require_gid_match)
Update POSIX permissions mask of a file on disk.
Definition: disk.c:320
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:582
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:496
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_cfgfile(char **fn)
Allow user to specify configuration file name (-c option)
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_logfile(char **logfn)
Allow user to specify log file name (-l option)
int GNUNET_GETOPT_run(const char *binaryOptions, const struct GNUNET_GETOPT_CommandLineOption *allOptions, unsigned int argc, char *const *argv)
Parse the command line.
Definition: getopt.c:884
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_help(const char *about)
Defining the option to print the command line help text (-h option).
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_loglevel(char **level)
Define the '-L' log level option.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_flag(char shortName, const char *name, const char *description, int *val)
Allow user to specify a flag (which internally means setting an integer to 1/GNUNET_YES/GNUNET_OK.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_version(const char *version)
Define the option to print the version of the application (-v option)
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
int GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages).
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_free_nz(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:832
char * GNUNET_NETWORK_shorten_unixpath(char *unixpath)
Given a unixpath that is too long (larger than UNIX_PATH_MAX), shorten it to an acceptable length whi...
Definition: network.c:143
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_box_native(int fd)
Box a native socket (and check that it is a socket).
Definition: network.c:579
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_get(void)
#define GNUNET_MESSAGE_TYPE_TEST
Test if service is online.
void GNUNET_RESOLVER_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create the connection to the resolver service.
Definition: resolver_api.c:258
void GNUNET_SCHEDULER_run(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Initialize and run scheduler.
Definition: scheduler.c:720
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1334
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
struct GNUNET_STRINGS_IPv6NetworkPolicy * GNUNET_STRINGS_parse_ipv6_policy(const char *routeListX)
Parse an IPv6 network policy.
Definition: strings.c:1471
struct GNUNET_STRINGS_IPv4NetworkPolicy * GNUNET_STRINGS_parse_ipv4_policy(const char *routeListX)
Parse an IPv4 network policy.
Definition: strings.c:1290
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:138
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
void GNUNET_TIME_set_offset(long long offset)
Set the timestamp offset for this instance.
Definition: time.c:49
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define DIR_SEPARATOR
Definition: platform.h:165
#define DIR_SEPARATOR_STR
Definition: platform.h:166
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
void(* LEGACY_SERVICE_Main)(void *cls, struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *cfg)
Function called by the service's run method to run service-specific setup code.
void GNUNET_SERVER_destroy(struct GNUNET_SERVER_Handle *server)
Free resources held by this server.
LEGACY_SERVICE_Options
Options for the service (bitmask).
@ LEGACY_SERVICE_OPTION_SOFT_SHUTDOWN
Trigger a SOFT server shutdown on signals, allowing active non-monitor clients to complete their tran...
@ LEGACY_SERVICE_OPTION_MANUAL_SHUTDOWN
Do not trigger server shutdown on signal at all; instead, allow for the user to terminate the server ...
struct GNUNET_SERVER_TransmitHandle * GNUNET_SERVER_notify_transmit_ready(struct GNUNET_SERVER_Client *client, size_t size, struct GNUNET_TIME_Relative timeout, GNUNET_CONNECTION_TransmitReadyNotify callback, void *callback_cls)
Notify us when the server has enough space to transmit a message of the given size to the given clien...
Credentials for UNIX domain sockets.
Definition of a command line option.
Header for all communications.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
handle to a socket
Definition: network.c:53
Entry in list of pending tasks.
Definition: scheduler.c:136
handle for a client of the server
handle for a server
GNUNET_SERVER_MessageCallback callback
Function to call for messages of "type".
void * callback_cls
Closure argument for callback.
enum GNUNET_SERVICE_Options options
Our options.
Definition: service.c:226
IPV4 network in CIDR notation.
network in CIDR notation for IPV6.
Time for relative time used by GNUnet, in microseconds.
Context for "service_task".
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_allowed
IPv4 addresses that are allowed to connect (if not set, all are allowed).
LEGACY_SERVICE_Main task
Main service-specific task to run.
struct sockaddr ** addrs
NULL-terminated array of addresses to bind to, NULL if we got pre-bound listen sockets.
void * task_cls
Closure for task.
struct GNUNET_TIME_Relative timeout
Idle timeout for server.
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_denied
IPv4 addresses that are not allowed to connect.
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_denied
IPv6 addresses that are not allowed to connect.
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_allowed
IPv6 addresses that are allowed to connect (if not set, all are allowed).
int ret
Overall success/failure of the service start.
int ready_confirm_fd
If we are daemonizing, this FD is set to the pipe to the parent.
struct GNUNET_SERVER_Handle * server
Handle for the server.
int require_found
Do we close connections if we receive messages for which we have no handler?
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
int match_uid
Do we require a matching UID for UNIX domain socket connections? GNUNET_NO means that the UID does no...
const char * service_name
Name of our service.
struct GNUNET_SCHEDULER_Task * shutdown_task
Task ID of the shutdown task.
int match_gid
Do we require a matching GID for UNIX domain socket connections? Ignored if match_uid is GNUNET_YES.
struct GNUNET_NETWORK_Handle ** lsocks
NULL-terminated array of listen sockets we should take over.
struct GNUNET_SERVER_MessageHandler * my_handlers
My (default) message handlers.
socklen_t * addrlens
Array of the lengths of the entries in addrs.
enum LEGACY_SERVICE_Options options
Our options.
void GNUNET_SERVER_add_handlers(struct GNUNET_SERVER_Handle *server, const struct GNUNET_SERVER_MessageHandler *handlers)
Add additional handlers to an existing server.
struct GNUNET_SERVER_Handle * GNUNET_SERVER_create_with_sockets(GNUNET_CONNECTION_AccessCheck access_cb, void *access_cb_cls, struct GNUNET_NETWORK_Handle **lsocks, struct GNUNET_TIME_Relative idle_timeout, int require_found)
Create a new server.
void GNUNET_SERVER_receive_done(struct GNUNET_SERVER_Client *client, int success)
Resume receiving from this client, we are done processing the current request.
void GNUNET_SERVER_stop_listening(struct GNUNET_SERVER_Handle *server)
Stop the listen socket and get ready to shutdown the server once only 'monitor' clients are left.
struct GNUNET_SERVER_Handle * GNUNET_SERVER_create(GNUNET_CONNECTION_AccessCheck access_cb, void *access_cb_cls, struct sockaddr *const *server_addr, const socklen_t *socklen, struct GNUNET_TIME_Relative idle_timeout, int require_found)
Create a new server.
void LEGACY_SERVICE_stop(struct LEGACY_SERVICE_Context *sctx)
Stop a service that was started with "LEGACY_SERVICE_start".
static int write_pid_file(struct LEGACY_SERVICE_Context *sctx, pid_t pid)
Write PID file.
static int check_access(void *cls, const struct GNUNET_CONNECTION_Credentials *uc, const struct sockaddr *addr, socklen_t addrlen)
Check if access to the service is allowed from the given address.
static int detach_terminal(struct LEGACY_SERVICE_Context *sctx)
Detach from terminal.
static void add_unixpath(struct sockaddr **saddrs, socklen_t *saddrlens, const char *unixpath, int abstract)
Add the given UNIX domain path as an address to the list (as the first entry).
static const struct GNUNET_SERVER_MessageHandler defhandlers[]
Default handlers for all services.
static int set_user_id(struct LEGACY_SERVICE_Context *sctx)
Set user ID.
static void handle_test(void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message)
Handler for TEST message.
static void service_task(void *cls)
Initial task for the service.
static int setup_service(struct LEGACY_SERVICE_Context *sctx)
Setup addr, addrlen, idle_timeout based on configuration!
#define HANDLE_ERROR
static void shutdown_task(void *cls)
Task run during shutdown.
static int check_ipv6_listed(const struct GNUNET_STRINGS_IPv6NetworkPolicy *list, const struct in6_addr *ip)
Check if the given IP address is in the list of IP addresses.
static char * get_user_name(struct LEGACY_SERVICE_Context *sctx)
Get the name of the user that'll be used to provide the service.
struct GNUNET_SERVER_Handle * LEGACY_SERVICE_get_server(struct LEGACY_SERVICE_Context *ctx)
Obtain the server used by a service.
struct GNUNET_NETWORK_Handle *const * LEGACY_SERVICE_get_listen_sockets(struct LEGACY_SERVICE_Context *ctx)
Get the NULL-terminated array of listen sockets for this service.
static size_t write_test(void *cls, size_t size, void *buf)
Send a 'TEST' message back to the client.
static int process_acl4(struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, struct LEGACY_SERVICE_Context *sctx, const char *option)
Parse an IPv4 access control list.
struct LEGACY_SERVICE_Context * LEGACY_SERVICE_start(const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg, enum LEGACY_SERVICE_Options options)
Run a service startup sequence within an existing initialized system.
static int process_acl6(struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, struct LEGACY_SERVICE_Context *sctx, const char *option)
Parse an IPv6 access control list.
static int check_ipv4_listed(const struct GNUNET_STRINGS_IPv4NetworkPolicy *list, const struct in_addr *add)
Check if the given IP address is in the list of IP addresses.
static char * get_pid_file_name(struct LEGACY_SERVICE_Context *sctx)
Get the name of the file where we will write the PID of the service.
static void pid_file_delete(struct LEGACY_SERVICE_Context *sctx)
Delete the PID file that was created by our parent.
int LEGACY_SERVICE_get_server_addresses(const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg, struct sockaddr ***addrs, socklen_t **addr_lens)
Get the list of addresses that a server for the given service should bind to.
int LEGACY_SERVICE_run(int argc, char *const *argv, const char *service_name, enum LEGACY_SERVICE_Options options, LEGACY_SERVICE_Main task, void *task_cls)
Run a standard GNUnet service startup sequence (initialize loggers and configuration,...