GNUnet  0.10.x
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_MALLINFO
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 
113 
118 
123  struct sockaddr **addrs;
124 
128  const char *service_name;
129 
134 
138  void *task_cls;
139 
144 
149 
155 
161 
167 
171  socklen_t *addrlens;
172 
177 
182 
187 
191  int ret;
192 
199 
205 
212 
221 
226 };
227 
228 
229 /* ****************** message handlers ****************** */
230 
239 static size_t
240 write_test(void *cls, size_t size, void *buf)
241 {
242  struct GNUNET_SERVER_Client *client = cls;
243  struct GNUNET_MessageHeader *msg;
244 
245  if (size < sizeof(struct GNUNET_MessageHeader))
246  {
248  return 0; /* client disconnected */
249  }
250  msg = (struct GNUNET_MessageHeader *)buf;
251  msg->type = htons(GNUNET_MESSAGE_TYPE_TEST);
252  msg->size = htons(sizeof(struct GNUNET_MessageHeader));
254  return sizeof(struct GNUNET_MessageHeader);
255 }
256 
257 
265 static void
266 handle_test(void *cls,
267  struct GNUNET_SERVER_Client *client,
268  const struct GNUNET_MessageHeader *message)
269 {
270  /* simply bounce message back to acknowledge */
271  if (NULL ==
273  sizeof(struct GNUNET_MessageHeader),
275  &write_test,
276  client))
278 }
279 
280 
287 { { &handle_test,
288  NULL,
290  sizeof(struct GNUNET_MessageHeader) },
291  { NULL, NULL, 0, 0 } };
292 
293 
294 /* ****************** service core routines ************** */
295 
296 
307 static int
308 check_access(void *cls,
309  const struct GNUNET_CONNECTION_Credentials *uc,
310  const struct sockaddr *addr,
311  socklen_t addrlen)
312 {
313  struct LEGACY_SERVICE_Context *sctx = cls;
314  const struct sockaddr_in *i4;
315  const struct sockaddr_in6 *i6;
316  int ret;
317 
318  switch (addr->sa_family)
319  {
320  case AF_INET:
321  GNUNET_assert(addrlen == sizeof(struct sockaddr_in));
322  i4 = (const struct sockaddr_in *)addr;
323  ret = ((NULL == sctx->v4_allowed) ||
324  (check_ipv4_listed(sctx->v4_allowed, &i4->sin_addr))) &&
325  ((NULL == sctx->v4_denied) ||
326  (!check_ipv4_listed(sctx->v4_denied, &i4->sin_addr)));
327  break;
328 
329  case AF_INET6:
330  GNUNET_assert(addrlen == sizeof(struct sockaddr_in6));
331  i6 = (const struct sockaddr_in6 *)addr;
332  ret = ((NULL == sctx->v6_allowed) ||
333  (check_ipv6_listed(sctx->v6_allowed, &i6->sin6_addr))) &&
334  ((NULL == sctx->v6_denied) ||
335  (!check_ipv6_listed(sctx->v6_denied, &i6->sin6_addr)));
336  break;
337 
338  case AF_UNIX:
339  ret = GNUNET_OK; /* controlled using file-system ACL now */
340  break;
341 
342  default:
344  _("Unknown address family %d\n"),
345  addr->sa_family);
346  return GNUNET_SYSERR;
347  }
348  if (GNUNET_OK != ret)
349  {
351  _("Access from `%s' denied to service `%s'\n"),
352  GNUNET_a2s(addr, addrlen),
353  sctx->service_name);
354  }
355  return ret;
356 }
357 
358 
366 static char *
368 {
369  char *pif;
370 
372  sctx->service_name,
373  "PIDFILE",
374  &pif))
375  return NULL;
376  return pif;
377 }
378 
379 
389 static int
391  struct LEGACY_SERVICE_Context *sctx,
392  const char *option)
393 {
394  char *opt;
395 
396  if (!GNUNET_CONFIGURATION_have_value(sctx->cfg, sctx->service_name, option))
397  {
398  *ret = NULL;
399  return GNUNET_OK;
400  }
403  sctx->service_name,
404  option,
405  &opt));
406  if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy(opt)))
407  {
409  _("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
410  opt,
411  sctx->service_name,
412  option);
413  GNUNET_free(opt);
414  return GNUNET_SYSERR;
415  }
416  GNUNET_free(opt);
417  return GNUNET_OK;
418 }
419 
420 
430 static int
432  struct LEGACY_SERVICE_Context *sctx,
433  const char *option)
434 {
435  char *opt;
436 
437  if (!GNUNET_CONFIGURATION_have_value(sctx->cfg, sctx->service_name, option))
438  {
439  *ret = NULL;
440  return GNUNET_OK;
441  }
444  sctx->service_name,
445  option,
446  &opt));
447  if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy(opt)))
448  {
450  _("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
451  opt,
452  sctx->service_name,
453  option);
454  GNUNET_free(opt);
455  return GNUNET_SYSERR;
456  }
457  GNUNET_free(opt);
458  return GNUNET_OK;
459 }
460 
461 
472 static void
473 add_unixpath(struct sockaddr **saddrs,
474  socklen_t *saddrlens,
475  const char *unixpath,
476  int abstract)
477 {
478 #ifdef AF_UNIX
479  struct sockaddr_un *un;
480 
481  un = GNUNET_new(struct sockaddr_un);
482  un->sun_family = AF_UNIX;
483  GNUNET_strlcpy(un->sun_path, unixpath, sizeof(un->sun_path));
484 #ifdef LINUX
485  if (GNUNET_YES == abstract)
486  un->sun_path[0] = '\0';
487 #endif
488 #if HAVE_SOCKADDR_UN_SUN_LEN
489  un->sun_len = (u_char)sizeof(struct sockaddr_un);
490 #endif
491  *saddrs = (struct sockaddr *)un;
492  *saddrlens = sizeof(struct sockaddr_un);
493 #else
494  /* this function should never be called
495  * unless AF_UNIX is defined! */
496  GNUNET_assert(0);
497 #endif
498 }
499 
500 
521 int
523  const char *service_name,
524  const struct GNUNET_CONFIGURATION_Handle *cfg,
525  struct sockaddr ***addrs,
526  socklen_t **addr_lens)
527 {
528  int disablev6;
529  struct GNUNET_NETWORK_Handle *desc;
530  unsigned long long port;
531  char *unixpath;
532  struct addrinfo hints;
533  struct addrinfo *res;
534  struct addrinfo *pos;
535  struct addrinfo *next;
536  unsigned int i;
537  int resi;
538  int ret;
539  int abstract;
540  struct sockaddr **saddrs;
541  socklen_t *saddrlens;
542  char *hostname;
543 
544  *addrs = NULL;
545  *addr_lens = NULL;
546  desc = NULL;
547  if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "DISABLEV6"))
548  {
549  if (GNUNET_SYSERR ==
550  (disablev6 = GNUNET_CONFIGURATION_get_value_yesno(cfg,
551  service_name,
552  "DISABLEV6")))
553  return GNUNET_SYSERR;
554  }
555  else
556  disablev6 = GNUNET_NO;
557 
558  if (!disablev6)
559  {
560  /* probe IPv6 support */
561  desc = GNUNET_NETWORK_socket_create(PF_INET6, SOCK_STREAM, 0);
562  if (NULL == desc)
563  {
564  if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
565  (EACCES == errno))
566  {
568  return GNUNET_SYSERR;
569  }
571  _(
572  "Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
573  service_name,
574  strerror(errno));
575  disablev6 = GNUNET_YES;
576  }
577  else
578  {
580  desc = NULL;
581  }
582  }
583 
584  port = 0;
585  if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "PORT"))
586  {
588  service_name,
589  "PORT",
590  &port))
591  {
593  _("Require valid port number for service `%s' in configuration!\n"),
594  service_name);
595  }
596  if (port > 65535)
597  {
599  _("Require valid port number for service `%s' in configuration!\n"),
600  service_name);
601  return GNUNET_SYSERR;
602  }
603  }
604 
605  if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "BINDTO"))
606  {
609  service_name,
610  "BINDTO",
611  &hostname));
612  }
613  else
614  hostname = NULL;
615 
616  unixpath = NULL;
617  abstract = GNUNET_NO;
618 #ifdef AF_UNIX
619  if ((GNUNET_YES ==
620  GNUNET_CONFIGURATION_have_value(cfg, service_name, "UNIXPATH")) &&
622  service_name,
623  "UNIXPATH",
624  &unixpath)) &&
625  (0 < strlen(unixpath)))
626  {
627  /* probe UNIX support */
628  struct sockaddr_un s_un;
629 
630  if (strlen(unixpath) >= sizeof(s_un.sun_path))
631  {
633  _("UNIXPATH `%s' too long, maximum length is %llu\n"),
634  unixpath,
635  (unsigned long long)sizeof(s_un.sun_path));
636  unixpath = GNUNET_NETWORK_shorten_unixpath(unixpath);
637  LOG(GNUNET_ERROR_TYPE_INFO, _("Using `%s' instead\n"), unixpath);
638  }
639 #ifdef LINUX
641  "TESTING",
642  "USE_ABSTRACT_SOCKETS");
643  if (GNUNET_SYSERR == abstract)
644  abstract = GNUNET_NO;
645 #endif
646  if ((GNUNET_YES != abstract) &&
649  }
650  if (NULL != unixpath)
651  {
652  desc = GNUNET_NETWORK_socket_create(AF_UNIX, SOCK_STREAM, 0);
653  if (NULL == desc)
654  {
655  if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
656  (EACCES == errno))
657  {
659  GNUNET_free_non_null(hostname);
660  GNUNET_free(unixpath);
661  return GNUNET_SYSERR;
662  }
664  _(
665  "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
666  service_name,
667  strerror(errno));
668  GNUNET_free(unixpath);
669  unixpath = NULL;
670  }
671  else
672  {
674  desc = NULL;
675  }
676  }
677 #endif
678 
679  if ((0 == port) && (NULL == unixpath))
680  {
682  _(
683  "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
684  service_name);
685  GNUNET_free_non_null(hostname);
686  return GNUNET_SYSERR;
687  }
688  if (0 == port)
689  {
690  saddrs = GNUNET_malloc(2 * sizeof(struct sockaddr *));
691  saddrlens = GNUNET_malloc(2 * sizeof(socklen_t));
692  add_unixpath(saddrs, saddrlens, unixpath, abstract);
693  GNUNET_free_non_null(unixpath);
694  GNUNET_free_non_null(hostname);
695  *addrs = saddrs;
696  *addr_lens = saddrlens;
697  return 1;
698  }
699 
700  if (NULL != hostname)
701  {
703  "Resolving `%s' since that is where `%s' will bind to.\n",
704  hostname,
705  service_name);
706  memset(&hints, 0, sizeof(struct addrinfo));
707  if (disablev6)
708  hints.ai_family = AF_INET;
709  hints.ai_protocol = IPPROTO_TCP;
710  if ((0 != (ret = getaddrinfo(hostname, NULL, &hints, &res))) ||
711  (NULL == res))
712  {
714  _("Failed to resolve `%s': %s\n"),
715  hostname,
716  gai_strerror(ret));
717  GNUNET_free(hostname);
718  GNUNET_free_non_null(unixpath);
719  return GNUNET_SYSERR;
720  }
721  next = res;
722  i = 0;
723  while (NULL != (pos = next))
724  {
725  next = pos->ai_next;
726  if ((disablev6) && (pos->ai_family == AF_INET6))
727  continue;
728  i++;
729  }
730  if (0 == i)
731  {
733  _("Failed to find %saddress for `%s'.\n"),
734  disablev6 ? "IPv4 " : "",
735  hostname);
736  freeaddrinfo(res);
737  GNUNET_free(hostname);
738  GNUNET_free_non_null(unixpath);
739  return GNUNET_SYSERR;
740  }
741  resi = i;
742  if (NULL != unixpath)
743  resi++;
744  saddrs = GNUNET_malloc((resi + 1) * sizeof(struct sockaddr *));
745  saddrlens = GNUNET_malloc((resi + 1) * sizeof(socklen_t));
746  i = 0;
747  if (NULL != unixpath)
748  {
749  add_unixpath(saddrs, saddrlens, unixpath, abstract);
750  i++;
751  }
752  next = res;
753  while (NULL != (pos = next))
754  {
755  next = pos->ai_next;
756  if ((disablev6) && (AF_INET6 == pos->ai_family))
757  continue;
758  if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
759  continue; /* not TCP */
760  if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
761  continue; /* huh? */
763  "Service `%s' will bind to `%s'\n",
764  service_name,
765  GNUNET_a2s(pos->ai_addr, pos->ai_addrlen));
766  if (AF_INET == pos->ai_family)
767  {
768  GNUNET_assert(sizeof(struct sockaddr_in) == pos->ai_addrlen);
769  saddrlens[i] = pos->ai_addrlen;
770  saddrs[i] = GNUNET_malloc(saddrlens[i]);
771  GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]);
772  ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port);
773  }
774  else
775  {
776  GNUNET_assert(AF_INET6 == pos->ai_family);
777  GNUNET_assert(sizeof(struct sockaddr_in6) == pos->ai_addrlen);
778  saddrlens[i] = pos->ai_addrlen;
779  saddrs[i] = GNUNET_malloc(saddrlens[i]);
780  GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]);
781  ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port);
782  }
783  i++;
784  }
785  GNUNET_free(hostname);
786  freeaddrinfo(res);
787  resi = i;
788  }
789  else
790  {
791  /* will bind against everything, just set port */
792  if (disablev6)
793  {
794  /* V4-only */
795  resi = 1;
796  if (NULL != unixpath)
797  resi++;
798  i = 0;
799  saddrs = GNUNET_malloc((resi + 1) * sizeof(struct sockaddr *));
800  saddrlens = GNUNET_malloc((resi + 1) * sizeof(socklen_t));
801  if (NULL != unixpath)
802  {
803  add_unixpath(saddrs, saddrlens, unixpath, abstract);
804  i++;
805  }
806  saddrlens[i] = sizeof(struct sockaddr_in);
807  saddrs[i] = GNUNET_malloc(saddrlens[i]);
808 #if HAVE_SOCKADDR_IN_SIN_LEN
809  ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[i];
810 #endif
811  ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET;
812  ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port);
813  }
814  else
815  {
816  /* dual stack */
817  resi = 2;
818  if (NULL != unixpath)
819  resi++;
820  saddrs = GNUNET_malloc((resi + 1) * sizeof(struct sockaddr *));
821  saddrlens = GNUNET_malloc((resi + 1) * sizeof(socklen_t));
822  i = 0;
823  if (NULL != unixpath)
824  {
825  add_unixpath(saddrs, saddrlens, unixpath, abstract);
826  i++;
827  }
828  saddrlens[i] = sizeof(struct sockaddr_in6);
829  saddrs[i] = GNUNET_malloc(saddrlens[i]);
830 #if HAVE_SOCKADDR_IN_SIN_LEN
831  ((struct sockaddr_in6 *)saddrs[i])->sin6_len = saddrlens[0];
832 #endif
833  ((struct sockaddr_in6 *)saddrs[i])->sin6_family = AF_INET6;
834  ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port);
835  i++;
836  saddrlens[i] = sizeof(struct sockaddr_in);
837  saddrs[i] = GNUNET_malloc(saddrlens[i]);
838 #if HAVE_SOCKADDR_IN_SIN_LEN
839  ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[1];
840 #endif
841  ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET;
842  ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port);
843  }
844  }
845  GNUNET_free_non_null(unixpath);
846  *addrs = saddrs;
847  *addr_lens = saddrlens;
848  return resi;
849 }
850 
851 
870 static int
872 {
873  struct GNUNET_TIME_Relative idleout;
874  int tolerant;
875  const char *nfds;
876  unsigned int cnt;
877  int flags;
878 
880  sctx->service_name,
881  "TIMEOUT"))
882  {
884  sctx->service_name,
885  "TIMEOUT",
886  &idleout))
887  {
889  _("Specified value for `%s' of service `%s' is invalid\n"),
890  "TIMEOUT",
891  sctx->service_name);
892  return GNUNET_SYSERR;
893  }
894  sctx->timeout = idleout;
895  }
896  else
898 
900  sctx->service_name,
901  "TOLERANT"))
902  {
903  if (GNUNET_SYSERR ==
904  (tolerant = GNUNET_CONFIGURATION_get_value_yesno(sctx->cfg,
905  sctx->service_name,
906  "TOLERANT")))
907  {
909  _("Specified value for `%s' of service `%s' is invalid\n"),
910  "TOLERANT",
911  sctx->service_name);
912  return GNUNET_SYSERR;
913  }
914  }
915  else
916  tolerant = GNUNET_NO;
917 
918  errno = 0;
919  if ((NULL != (nfds = getenv("LISTEN_FDS"))) &&
920  (1 == sscanf(nfds, "%u", &cnt)) && (cnt > 0) && (cnt < FD_SETSIZE) &&
921  (cnt + 4 < FD_SETSIZE))
922  {
923  sctx->lsocks =
924  GNUNET_malloc(sizeof(struct GNUNET_NETWORK_Handle *) * (cnt + 1));
925  while (0 < cnt--)
926  {
927  flags = fcntl(3 + cnt, F_GETFD);
928  if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) ||
929  (NULL ==
930  (sctx->lsocks[cnt] = GNUNET_NETWORK_socket_box_native(3 + cnt))))
931  {
933  _(
934  "Could not access pre-bound socket %u, will try to bind myself\n"),
935  (unsigned int)3 + cnt);
936  cnt++;
937  while (sctx->lsocks[cnt] != NULL)
938  GNUNET_break(0 == GNUNET_NETWORK_socket_close(sctx->lsocks[cnt++]));
939  GNUNET_free(sctx->lsocks);
940  sctx->lsocks = NULL;
941  break;
942  }
943  }
944  unsetenv("LISTEN_FDS");
945  }
946 
947  if ((NULL == sctx->lsocks) &&
949  sctx->cfg,
950  &sctx->addrs,
951  &sctx->addrlens)))
952  return GNUNET_SYSERR;
953  sctx->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
955  sctx->service_name,
956  "UNIX_MATCH_UID");
958  sctx->service_name,
959  "UNIX_MATCH_GID");
960  process_acl4(&sctx->v4_denied, sctx, "REJECT_FROM");
961  process_acl4(&sctx->v4_allowed, sctx, "ACCEPT_FROM");
962  process_acl6(&sctx->v6_denied, sctx, "REJECT_FROM6");
963  process_acl6(&sctx->v6_allowed, sctx, "ACCEPT_FROM6");
964 
965  return GNUNET_OK;
966 }
967 
968 
976 static char *
978 {
979  char *un;
980 
982  sctx->service_name,
983  "USERNAME",
984  &un))
985  return NULL;
986  return un;
987 }
988 
989 
997 static int
999 {
1000  FILE *pidfd;
1001  char *pif;
1002  char *user;
1003  char *rdir;
1004  int len;
1005 
1006  if (NULL == (pif = get_pid_file_name(sctx)))
1007  return GNUNET_OK; /* no file desired */
1008  user = get_user_name(sctx);
1009  rdir = GNUNET_strdup(pif);
1010  len = strlen(rdir);
1011  while ((len > 0) && (rdir[len] != DIR_SEPARATOR))
1012  len--;
1013  rdir[len] = '\0';
1014  if (0 != access(rdir, F_OK))
1015  {
1016  /* we get to create a directory -- and claim it
1017  * as ours! */
1018  (void)GNUNET_DISK_directory_create(rdir);
1019  if ((NULL != user) && (0 < strlen(user)))
1020  GNUNET_DISK_file_change_owner(rdir, user);
1021  }
1022  if (0 != access(rdir, W_OK | X_OK))
1023  {
1024  LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_ERROR, "access", rdir);
1025  GNUNET_free(rdir);
1026  GNUNET_free_non_null(user);
1027  GNUNET_free(pif);
1028  return GNUNET_SYSERR;
1029  }
1030  GNUNET_free(rdir);
1031  pidfd = fopen(pif, "w");
1032  if (NULL == pidfd)
1033  {
1035  GNUNET_free(pif);
1036  GNUNET_free_non_null(user);
1037  return GNUNET_SYSERR;
1038  }
1039  if (0 > fprintf(pidfd, "%u", pid))
1041  GNUNET_break(0 == fclose(pidfd));
1042  if ((NULL != user) && (0 < strlen(user)))
1043  GNUNET_DISK_file_change_owner(pif, user);
1044  GNUNET_free_non_null(user);
1045  GNUNET_free(pif);
1046  return GNUNET_OK;
1047 }
1048 
1049 
1055 static void
1056 shutdown_task(void *cls)
1057 {
1058  struct LEGACY_SERVICE_Context *service = cls;
1059  struct GNUNET_SERVER_Handle *server = service->server;
1060 
1061  service->shutdown_task = NULL;
1062  if (0 != (service->options & LEGACY_SERVICE_OPTION_SOFT_SHUTDOWN))
1064  else
1065  GNUNET_SERVER_destroy(server);
1066 }
1067 
1068 
1074 static void
1075 service_task(void *cls)
1076 {
1077  struct LEGACY_SERVICE_Context *sctx = cls;
1078  unsigned int i;
1079 
1081  if (NULL != sctx->lsocks)
1083  sctx,
1084  sctx->lsocks,
1085  sctx->timeout,
1086  sctx->require_found);
1087  else
1089  sctx,
1090  sctx->addrs,
1091  sctx->addrlens,
1092  sctx->timeout,
1093  sctx->require_found);
1094  if (NULL == sctx->server)
1095  {
1096  if (NULL != sctx->addrs)
1097  for (i = 0; NULL != sctx->addrs[i]; i++)
1099  _("Failed to start `%s' at `%s'\n"),
1100  sctx->service_name,
1101  GNUNET_a2s(sctx->addrs[i], sctx->addrlens[i]));
1102  sctx->ret = GNUNET_SYSERR;
1103  return;
1104  }
1105 
1106  if (NULL != sctx->addrs)
1107  for (i = 0; NULL != sctx->addrs[i]; i++)
1108  if ((AF_UNIX == sctx->addrs[i]->sa_family) &&
1109  ('\0' != ((const struct sockaddr_un *)sctx->addrs[i])->sun_path[0]))
1110  GNUNET_DISK_fix_permissions(((const struct sockaddr_un *)
1111  sctx->addrs[i])
1112  ->sun_path,
1113  sctx->match_uid,
1114  sctx->match_gid);
1115 
1117  {
1118  /* install a task that will kill the server
1119  * process if the scheduler ever gets a shutdown signal */
1121  }
1122  sctx->my_handlers = GNUNET_malloc(sizeof(defhandlers));
1123  GNUNET_memcpy(sctx->my_handlers, defhandlers, sizeof(defhandlers));
1124  i = 0;
1125  while (NULL != sctx->my_handlers[i].callback)
1126  sctx->my_handlers[i++].callback_cls = sctx;
1128  if (-1 != sctx->ready_confirm_fd)
1129  {
1130  GNUNET_break(1 == write(sctx->ready_confirm_fd, ".", 1));
1131  GNUNET_break(0 == close(sctx->ready_confirm_fd));
1132  sctx->ready_confirm_fd = -1;
1133  write_pid_file(sctx, getpid());
1134  }
1135  if (NULL != sctx->addrs)
1136  {
1137  i = 0;
1138  while (NULL != sctx->addrs[i])
1139  {
1141  _("Service `%s' runs at %s\n"),
1142  sctx->service_name,
1143  GNUNET_a2s(sctx->addrs[i], sctx->addrlens[i]));
1144  i++;
1145  }
1146  }
1147  sctx->task(sctx->task_cls, sctx->server, sctx->cfg);
1148 }
1149 
1150 
1157 static int
1159 {
1160  pid_t pid;
1161  int nullfd;
1162  int filedes[2];
1163 
1164  if (0 != pipe(filedes))
1165  {
1167  return GNUNET_SYSERR;
1168  }
1169  pid = fork();
1170  if (pid < 0)
1171  {
1173  return GNUNET_SYSERR;
1174  }
1175  if (0 != pid)
1176  {
1177  /* Parent */
1178  char c;
1179 
1180  GNUNET_break(0 == close(filedes[1]));
1181  c = 'X';
1182  if (1 != read(filedes[0], &c, sizeof(char)))
1184  fflush(stdout);
1185  switch (c)
1186  {
1187  case '.':
1188  exit(0);
1189 
1190  case 'I':
1192  _("Service process failed to initialize\n"));
1193  break;
1194 
1195  case 'S':
1197  _("Service process could not initialize server function\n"));
1198  break;
1199 
1200  case 'X':
1202  _("Service process failed to report status\n"));
1203  break;
1204  }
1205  exit(1); /* child reported error */
1206  }
1207  GNUNET_break(0 == close(0));
1208  GNUNET_break(0 == close(1));
1209  GNUNET_break(0 == close(filedes[0]));
1210  nullfd = open("/dev/null", O_RDWR | O_APPEND);
1211  if (nullfd < 0)
1212  return GNUNET_SYSERR;
1213  /* set stdin/stdout to /dev/null */
1214  if ((dup2(nullfd, 0) < 0) || (dup2(nullfd, 1) < 0))
1215  {
1217  (void)close(nullfd);
1218  return GNUNET_SYSERR;
1219  }
1220  (void)close(nullfd);
1221  /* Detach from controlling terminal */
1222  pid = setsid();
1223  if (-1 == pid)
1225  sctx->ready_confirm_fd = filedes[1];
1226 
1227  return GNUNET_OK;
1228 }
1229 
1230 
1237 static int
1239 {
1240  char *user;
1241 
1242  if (NULL == (user = get_user_name(sctx)))
1243  return GNUNET_OK; /* keep */
1244 
1245  struct passwd *pws;
1246 
1247  errno = 0;
1248  pws = getpwnam(user);
1249  if (NULL == pws)
1250  {
1252  _("Cannot obtain information about user `%s': %s\n"),
1253  user,
1254  errno == 0 ? _("No such user") : strerror(errno));
1255  GNUNET_free(user);
1256  return GNUNET_SYSERR;
1257  }
1258  if ((0 != setgid(pws->pw_gid)) || (0 != setegid(pws->pw_gid)) ||
1259 #if HAVE_INITGROUPS
1260  (0 != initgroups(user, pws->pw_gid)) ||
1261 #endif
1262  (0 != setuid(pws->pw_uid)) || (0 != seteuid(pws->pw_uid)))
1263  {
1264  if ((0 != setregid(pws->pw_gid, pws->pw_gid)) ||
1265  (0 != setreuid(pws->pw_uid, pws->pw_uid)))
1266  {
1268  _("Cannot change user/group to `%s': %s\n"),
1269  user,
1270  strerror(errno));
1271  GNUNET_free(user);
1272  return GNUNET_SYSERR;
1273  }
1274  }
1275 
1276  GNUNET_free(user);
1277  return GNUNET_OK;
1278 }
1279 
1280 
1286 static void
1288 {
1289  char *pif = get_pid_file_name(sctx);
1290 
1291  if (NULL == pif)
1292  return; /* no PID file */
1293  if (0 != unlink(pif))
1295  GNUNET_free(pif);
1296 }
1297 
1298 
1312 int
1314  char *const *argv,
1315  const char *service_name,
1318  void *task_cls)
1319 {
1320 #define HANDLE_ERROR \
1321  do \
1322  { \
1323  GNUNET_break(0); \
1324  goto shutdown; \
1325  } while (0)
1326 
1327  int err;
1328  int ret;
1329  char *cfg_fn;
1330  char *opt_cfg_fn;
1331  char *loglev;
1332  char *logfile;
1333  int do_daemonize;
1334  unsigned int i;
1335  unsigned long long skew_offset;
1336  unsigned long long skew_variance;
1337  long long clock_offset;
1338  struct LEGACY_SERVICE_Context sctx;
1340  const char *xdg;
1341 
1342  struct GNUNET_GETOPT_CommandLineOption service_options[] =
1343  { GNUNET_GETOPT_option_cfgfile(&opt_cfg_fn),
1345  "daemonize",
1346  gettext_noop(
1347  "do daemonize (detach from terminal)"),
1348  &do_daemonize),
1351  GNUNET_GETOPT_option_logfile(&logfile),
1352  GNUNET_GETOPT_option_version(PACKAGE_VERSION " " VCS_VERSION),
1354  err = 1;
1355  do_daemonize = 0;
1356  logfile = NULL;
1357  loglev = NULL;
1358  opt_cfg_fn = NULL;
1359  xdg = getenv("XDG_CONFIG_HOME");
1360  if (NULL != xdg)
1361  GNUNET_asprintf(&cfg_fn,
1362  "%s%s%s",
1363  xdg,
1366  else
1367  cfg_fn = GNUNET_strdup(GNUNET_OS_project_data_get()->user_config_file);
1368  memset(&sctx, 0, sizeof(sctx));
1369  sctx.options = options;
1370  sctx.ready_confirm_fd = -1;
1371  sctx.ret = GNUNET_OK;
1373  sctx.task = task;
1374  sctx.task_cls = task_cls;
1375  sctx.service_name = service_name;
1376  sctx.cfg = cfg = GNUNET_CONFIGURATION_create();
1377 
1378  /* setup subsystems */
1379  ret = GNUNET_GETOPT_run(service_name, service_options, argc, argv);
1380  if (GNUNET_SYSERR == ret)
1381  goto shutdown;
1382  if (GNUNET_NO == ret)
1383  {
1384  err = 0;
1385  goto shutdown;
1386  }
1387  if (GNUNET_OK != GNUNET_log_setup(service_name, loglev, logfile))
1388  HANDLE_ERROR;
1389  if (NULL == opt_cfg_fn)
1390  opt_cfg_fn = GNUNET_strdup(cfg_fn);
1391  if (GNUNET_YES == GNUNET_DISK_file_test(opt_cfg_fn))
1392  {
1393  if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, opt_cfg_fn))
1394  {
1396  _("Malformed configuration file `%s', exit ...\n"),
1397  opt_cfg_fn);
1398  goto shutdown;
1399  }
1400  }
1401  else
1402  {
1403  if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, NULL))
1404  {
1406  _("Malformed configuration, exit ...\n"));
1407  goto shutdown;
1408  }
1409  if (0 != strcmp(opt_cfg_fn, cfg_fn))
1411  _("Could not access configuration file `%s'\n"),
1412  opt_cfg_fn);
1413  }
1414  if (GNUNET_OK != setup_service(&sctx))
1415  goto shutdown;
1416  if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal(&sctx)))
1417  HANDLE_ERROR;
1418  if (GNUNET_OK != set_user_id(&sctx))
1419  goto shutdown;
1421  "Service `%s' runs with configuration from `%s'\n",
1422  service_name,
1423  opt_cfg_fn);
1425  "TESTING",
1426  "SKEW_OFFSET",
1427  &skew_offset)) &&
1429  "TESTING",
1430  "SKEW_VARIANCE",
1431  &skew_variance)))
1432  {
1433  clock_offset = skew_offset - skew_variance;
1434  GNUNET_TIME_set_offset(clock_offset);
1435  LOG(GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset);
1436  }
1437  /* actually run service */
1438  err = 0;
1440  /* shutdown */
1441  if ((1 == do_daemonize) && (NULL != sctx.server))
1442  pid_file_delete(&sctx);
1444 
1445 shutdown:
1446  if (-1 != sctx.ready_confirm_fd)
1447  {
1448  if (1 != write(sctx.ready_confirm_fd, err ? "I" : "S", 1))
1450  GNUNET_break(0 == close(sctx.ready_confirm_fd));
1451  }
1452 #if HAVE_MALLINFO
1453  {
1454  char *counter;
1455 
1457  service_name,
1458  "GAUGER_HEAP")) &&
1460  service_name,
1461  "GAUGER_HEAP",
1462  &counter)))
1463  {
1464  struct mallinfo mi;
1465 
1466  mi = mallinfo();
1467  GAUGER(service_name, counter, mi.usmblks, "blocks");
1468  GNUNET_free(counter);
1469  }
1470  }
1471 #endif
1473  i = 0;
1474  if (NULL != sctx.addrs)
1475  while (NULL != sctx.addrs[i])
1476  GNUNET_free(sctx.addrs[i++]);
1479  GNUNET_free_non_null(logfile);
1480  GNUNET_free_non_null(loglev);
1481  GNUNET_free(cfg_fn);
1482  GNUNET_free_non_null(opt_cfg_fn);
1487 
1488  return err ? GNUNET_SYSERR : sctx.ret;
1489 }
1490 
1491 
1501 struct LEGACY_SERVICE_Context *
1503  const struct GNUNET_CONFIGURATION_Handle *cfg,
1505 {
1506  int i;
1507  struct LEGACY_SERVICE_Context *sctx;
1508 
1509  sctx = GNUNET_new(struct LEGACY_SERVICE_Context);
1510  sctx->ready_confirm_fd = -1; /* no daemonizing */
1511  sctx->ret = GNUNET_OK;
1513  sctx->service_name = service_name;
1514  sctx->cfg = cfg;
1515  sctx->options = options;
1516 
1517  /* setup subsystems */
1518  if (GNUNET_OK != setup_service(sctx))
1519  {
1520  LEGACY_SERVICE_stop(sctx);
1521  return NULL;
1522  }
1523  if (NULL != sctx->lsocks)
1525  sctx,
1526  sctx->lsocks,
1527  sctx->timeout,
1528  sctx->require_found);
1529  else
1531  sctx,
1532  sctx->addrs,
1533  sctx->addrlens,
1534  sctx->timeout,
1535  sctx->require_found);
1536 
1537  if (NULL == sctx->server)
1538  {
1539  LEGACY_SERVICE_stop(sctx);
1540  return NULL;
1541  }
1542 
1543  if (NULL != sctx->addrs)
1544  for (i = 0; NULL != sctx->addrs[i]; i++)
1545  if ((AF_UNIX == sctx->addrs[i]->sa_family) &&
1546  ('\0' != ((const struct sockaddr_un *)sctx->addrs[i])->sun_path[0]))
1547  GNUNET_DISK_fix_permissions(((const struct sockaddr_un *)
1548  sctx->addrs[i])
1549  ->sun_path,
1550  sctx->match_uid,
1551  sctx->match_gid);
1552 
1553  sctx->my_handlers = GNUNET_malloc(sizeof(defhandlers));
1554  GNUNET_memcpy(sctx->my_handlers, defhandlers, sizeof(defhandlers));
1555  i = 0;
1556  while ((sctx->my_handlers[i].callback != NULL))
1557  sctx->my_handlers[i++].callback_cls = sctx;
1559  return sctx;
1560 }
1561 
1562 
1570 struct GNUNET_SERVER_Handle *
1572 {
1573  return ctx->server;
1574 }
1575 
1576 
1584 struct GNUNET_NETWORK_Handle *const *
1586 {
1587  return ctx->lsocks;
1588 }
1589 
1590 
1596 void
1598 {
1599  unsigned int i;
1600 
1601 #if HAVE_MALLINFO
1602  {
1603  char *counter;
1604 
1606  sctx->service_name,
1607  "GAUGER_HEAP")) &&
1609  sctx->service_name,
1610  "GAUGER_HEAP",
1611  &counter)))
1612  {
1613  struct mallinfo mi;
1614 
1615  mi = mallinfo();
1616  GAUGER(sctx->service_name, counter, mi.usmblks, "blocks");
1617  GNUNET_free(counter);
1618  }
1619  }
1620 #endif
1621  if (NULL != sctx->shutdown_task)
1622  {
1624  sctx->shutdown_task = NULL;
1625  }
1626  if (NULL != sctx->server)
1629  if (NULL != sctx->addrs)
1630  {
1631  i = 0;
1632  while (NULL != sctx->addrs[i])
1633  GNUNET_free(sctx->addrs[i++]);
1634  GNUNET_free(sctx->addrs);
1635  }
1641  GNUNET_free(sctx);
1642 }
1643 
1644 
1645 /* end of service.c */
static char * get_user_name(struct LEGACY_SERVICE_Context *sctx)
Get the name of the user that&#39;ll be used to provide the service.
int 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:541
struct GNUNET_STRINGS_IPv4NetworkPolicy * GNUNET_STRINGS_parse_ipv4_policy(const char *routeListX)
Parse an IPv4 network policy.
Definition: strings.c:1519
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, parse options).
socklen_t * addrlens
Array of the lengths of the entries in addrs.
void GNUNET_SERVER_add_handlers(struct GNUNET_SERVER_Handle *server, const struct GNUNET_SERVER_MessageHandler *handlers)
Add additional handlers to an existing server.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
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.
int 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.
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 void handle_test(void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message)
Handler for TEST message.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
int 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.
const char * service_name
Name of our service.
GNUNET_SERVER_MessageCallback callback
Function to call for messages of "type".
struct GNUNET_SCHEDULER_Task * shutdown_task
Task ID of the shutdown task.
static int write_pid_file(struct LEGACY_SERVICE_Context *sctx, pid_t pid)
Write PID file.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_help(const char *about)
Defining the option to print the command line help text (-h option).
int GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:586
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, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1284
#define LOG(kind,...)
Definition: arm_api.c:33
struct GNUNET_STRINGS_IPv6NetworkPolicy * GNUNET_STRINGS_parse_ipv6_policy(const char *routeListX)
Parse an IPv6 network policy.
Definition: strings.c:1711
Do not trigger server shutdown on signal at all; instead, allow for the user to terminate the server ...
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
network in CIDR notation for IPV6.
static char * config_file
Set to the name of the config file used.
Definition: gnunet-arm.c:79
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 void service_task(void *cls)
Initial task for the service.
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.
static struct GNUNET_FS_UnindexContext * uc
static void pid_file_delete(struct LEGACY_SERVICE_Context *sctx)
Delete the PID file that was created by our parent.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
void GNUNET_SCHEDULER_run(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Initialize and run scheduler.
Definition: scheduler.c:707
static int set_user_id(struct LEGACY_SERVICE_Context *sctx)
Set user ID.
struct in_addr netmask
IPv4 netmask.
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:681
#define GNUNET_NO
Definition: gnunet_common.h:78
static const struct GNUNET_SERVER_MessageHandler defhandlers[]
Default handlers for all services.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct sockaddr ** addrs
NULL-terminated array of addresses to bind to, NULL if we got pre-bound listen sockets.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Definition of a command line option.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_create(void)
Create a new configuration object.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_TIME_set_offset(long long offset)
Set the timestamp offset for this instance.
Definition: time.c:53
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_logfile(char **logfn)
Allow user to specify log file name (-l option)
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
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.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
int GNUNET_CONFIGURATION_load(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Load configuration.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
void(* LEGACY_SERVICE_Main)(void *cls, struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *cfg)
Function called by the service&#39;s run method to run service-specific setup code.
struct GNUNET_SERVER_MessageHandler * my_handlers
My (default) message handlers.
struct in_addr network
IPv4 address.
#define LOG_STRERROR_FILE(kind, op, fn)
Definition: datacache.c:34
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_version(const char *version)
Define the option to print the version of the application (-v option)
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
void * task_cls
Closure for task.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_allowed
IPv6 addresses that are allowed to connect (if not set, all are allowed).
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_box_native(SOCKTYPE fd)
Box a native socket (and check that it is a socket).
Definition: network.c:624
#define DIR_SEPARATOR_STR
Definition: platform.h:168
Trigger a SOFT server shutdown on signals, allowing active non-monitor clients to complete their tran...
struct GNUNET_NETWORK_Handle ** lsocks
NULL-terminated array of listen sockets we should take over.
int 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.
static int process_acl4(struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, struct LEGACY_SERVICE_Context *sctx, const char *option)
Parse an IPv4 access control list.
struct GNUNET_SERVER_Handle * server
Handle for the server.
IPV4 network in CIDR notation.
void GNUNET_CONFIGURATION_destroy(struct GNUNET_CONFIGURATION_Handle *cfg)
Destroy configuration object.
static char * option
Name of the option.
Definition: gnunet-config.c:38
static char buf[2048]
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_loglevel(char **level)
Define the &#39;-L&#39; log level option.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
static int setup_service(struct LEGACY_SERVICE_Context *sctx)
Setup addr, addrlen, idle_timeout based on configuration!
handle for a server
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)...
static size_t write_test(void *cls, size_t size, void *buf)
Send a &#39;TEST&#39; message back to the client.
LEGACY_SERVICE_Options
Options for the service (bitmask).
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_allowed
IPv4 addresses that are allowed to connect (if not set, all are allowed).
int match_uid
Do we require a matching UID for UNIX domain socket connections? GNUNET_NO means that the UID does no...
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static int res
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.
struct GNUNET_SERVER_Handle * LEGACY_SERVICE_get_server(struct LEGACY_SERVICE_Context *ctx)
Obtain the server used by a service.
int 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.
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:886
#define DIR_SEPARATOR
Definition: platform.h:167
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).
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:66
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...
char * getenv()
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_denied
IPv6 addresses that are not allowed to connect.
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 int add
Desired action is to add a record.
int require_found
Do we close connections if we receive messages for which we have no handler?
#define GAUGER(category, counter, value, unit)
Definition: gauger.h:18
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_cfgfile(char **fn)
Allow user to specify configuration file name (-c option)
static char * hostname
Our hostname; we give this to all the peers we start.
#define HANDLE_ERROR
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
configuration data
Definition: configuration.c:83
Context for "service_task".
#define LOG_STRERROR(kind, syscall)
void LEGACY_SERVICE_stop(struct LEGACY_SERVICE_Context *sctx)
Stop a service that was started with "LEGACY_SERVICE_start".
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.
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:131
void GNUNET_SERVER_receive_done(struct GNUNET_SERVER_Client *client, int success)
Resume receiving from this client, we are done processing the current request.
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_get(void)
int GNUNET_DISK_file_change_owner(const char *filename, const char *user)
Change owner of a file.
Definition: disk.c:1163
Credentials for UNIX domain sockets.
int 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.
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:376
handle to a socket
Definition: network.c:46
int ready_confirm_fd
If we are daemonizing, this FD is set to the pipe to the parent.
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_denied
IPv4 addresses that are not allowed to connect.
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:151
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.
Header for all communications.
int match_gid
Do we require a matching GID for UNIX domain socket connections? Ignored if match_uid is GNUNET_YES...
LEGACY_SERVICE_Main task
Main service-specific task to run.
#define GNUNET_YES
Definition: gnunet_common.h:77
handle for a client of the server
int GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
static int detach_terminal(struct LEGACY_SERVICE_Context *sctx)
Detach from terminal.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
enum LEGACY_SERVICE_Options options
Our options.
int 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".
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.
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:219
void * callback_cls
Closure argument for callback.
void GNUNET_SERVER_destroy(struct GNUNET_SERVER_Handle *server)
Free resources held by this server.
void GNUNET_SERVER_stop_listening(struct GNUNET_SERVER_Handle *server)
Stop the listen socket and get ready to shutdown the server once only &#39;monitor&#39; clients are left...
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:548
static int list
Set if we should print a list of currently running services.
Definition: gnunet-arm.c:64
void GNUNET_RESOLVER_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create the connection to the resolver service.
Definition: resolver_api.c:252
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_MESSAGE_TYPE_TEST
Test if service is online.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_TIME_Relative timeout
Idle timeout for server.
Time for relative time used by GNUnet, in microseconds.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
#define gettext_noop(String)
Definition: gettext.h:69
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:900
static int process_acl6(struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, struct LEGACY_SERVICE_Context *sctx, const char *option)
Parse an IPv6 access control list.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
int ret
Overall success/failure of the service start.