GNUnet  0.10.x
service.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2016 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 
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_protocols.h"
30 #include "gnunet_constants.h"
32 #include "speedup.h"
33 
34 #if HAVE_MALLINFO
35 #include <malloc.h>
36 #include "gauger.h"
37 #endif
38 
39 
40 #define LOG(kind, ...) GNUNET_log_from(kind, "util-service", __VA_ARGS__)
41 
42 #define LOG_STRERROR(kind, syscall) \
43  GNUNET_log_from_strerror(kind, "util-service", syscall)
44 
45 #define LOG_STRERROR_FILE(kind, syscall, filename) \
46  GNUNET_log_from_strerror_file(kind, "util-service", syscall, filename)
47 
48 
57 
62 
67 
72 
77 };
78 
79 
88 
93 
98 
103 
108 };
109 
110 
119 
123  const char *service_name;
124 
129 
134 
139 
143  void *cb_cls;
144 
149 
154 
159 
164 
169 
173  void *task_cls;
174 
179 
184 
190 
196 
203 
212 
216  enum SuspendReason suspend_state;
217 
222 
229 
233  int ret;
234 
240 };
241 
242 
251 
256 
261 
266 
271 
276 
282 
288 
294 
299 
303  const struct GNUNET_MessageHeader *msg;
304 
310 
315  struct GNUNET_TIME_Absolute warn_start;
316 
320  size_t msg_pos;
321 
327  int persist;
328 
335 
340 
344  uint16_t warn_type;
345 };
346 
347 
355 static int
357 {
358  for (struct GNUNET_SERVICE_Client *client = sh->clients_head; NULL != client;
359  client = client->next)
360  {
361  if (client->is_monitor)
362  continue;
363  return GNUNET_YES;
364  }
365  return GNUNET_NO;
366 }
367 
368 
376 static void
378 {
379  struct ServiceListenContext *slc;
380 
381  GNUNET_assert(0 == (sh->suspend_state & sr));
382  sh->suspend_state |= sr;
383  for (slc = sh->slc_head; NULL != slc; slc = slc->next)
384  {
385  if (NULL != slc->listen_task)
386  {
388  slc->listen_task = NULL;
389  }
390  }
391 }
392 
393 
402 static void
404 {
405  struct GNUNET_SERVICE_Handle *sh = cls;
406 
407  switch (sh->options)
408  {
411  break;
412 
414  /* This task should never be run if we are using
415  the manual shutdown. */
416  GNUNET_assert(0);
417  break;
418 
420  if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN))
424  break;
425  }
426 }
427 
428 
436 static int
438  const struct in_addr *add)
439 {
440  unsigned int i;
441 
442  if (NULL == list)
443  return GNUNET_NO;
444  i = 0;
445  while ((0 != list[i].network.s_addr) || (0 != list[i].netmask.s_addr))
446  {
447  if ((add->s_addr & list[i].netmask.s_addr) ==
448  (list[i].network.s_addr & list[i].netmask.s_addr))
449  return GNUNET_YES;
450  i++;
451  }
452  return GNUNET_NO;
453 }
454 
455 
463 static int
465  const struct in6_addr *ip)
466 {
467  unsigned int i;
468  unsigned int j;
469 
470  if (NULL == list)
471  return GNUNET_NO;
472  i = 0;
473 NEXT:
474  while (0 != GNUNET_is_zero(&list[i].network))
475  {
476  for (j = 0; j < sizeof(struct in6_addr) / sizeof(int); j++)
477  if (((((int *)ip)[j] & ((int *)&list[i].netmask)[j])) !=
478  (((int *)&list[i].network)[j] & ((int *)&list[i].netmask)[j]))
479  {
480  i++;
481  goto NEXT;
482  }
483  return GNUNET_YES;
484  }
485  return GNUNET_NO;
486 }
487 
488 
495 static void
496 do_send(void *cls)
497 {
498  struct GNUNET_SERVICE_Client *client = cls;
499  ssize_t ret;
500  size_t left;
501  const char *buf;
502 
504  "service: sending message with type %u\n",
505  ntohs(client->msg->type));
506 
507 
508  client->send_task = NULL;
509  buf = (const char *)client->msg;
510  left = ntohs(client->msg->size) - client->msg_pos;
511  ret = GNUNET_NETWORK_socket_send(client->sock, &buf[client->msg_pos], left);
512  GNUNET_assert(ret <= (ssize_t)left);
513  if (0 == ret)
514  {
515  LOG(GNUNET_ERROR_TYPE_DEBUG, "no data send");
517  return;
518  }
519  if (-1 == ret)
520  {
521  if ((EAGAIN == errno) || (EINTR == errno))
522  {
523  /* ignore */
524  ret = 0;
525  }
526  else
527  {
528  if (EPIPE != errno)
531  "socket send returned with error code %i",
532  errno);
534  return;
535  }
536  }
537  if (0 == client->msg_pos)
538  {
540  }
541  client->msg_pos += ret;
542  if (left > (size_t)ret)
543  {
544  GNUNET_assert(NULL == client->drop_task);
545  client->send_task =
547  client->sock,
548  &do_send,
549  client);
550  return;
551  }
553 }
554 
555 
564 static void
566  const struct GNUNET_MessageHeader *msg,
567  void *impl_state)
568 {
569  struct GNUNET_SERVICE_Client *client = impl_state;
570 
571  (void)mq;
572  if (NULL != client->drop_task)
573  return; /* we're going down right now, do not try to send */
574  GNUNET_assert(NULL == client->send_task);
576  "Sending message of type %u and size %u to client\n",
577  ntohs(msg->type),
578  ntohs(msg->size));
579  client->msg = msg;
580  client->msg_pos = 0;
581  client->send_task =
583  client->sock,
584  &do_send,
585  client);
586 }
587 
588 
595 static void
596 service_mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
597 {
598  struct GNUNET_SERVICE_Client *client = impl_state;
599 
600  (void)mq;
601  GNUNET_assert(0 == client->msg_pos);
602  client->msg = NULL;
604  client->send_task = NULL;
605 }
606 
607 
617 static void
619 {
620  struct GNUNET_SERVICE_Client *client = cls;
621  struct GNUNET_SERVICE_Handle *sh = client->sh;
622 
623  if ((GNUNET_MQ_ERROR_NO_MATCH == error) && (GNUNET_NO == sh->require_found))
624  {
626  "No handler for message of type %u found\n",
627  (unsigned int)client->warn_type);
629  return; /* ignore error */
630  }
632 }
633 
634 
640 static void
642 {
643  struct GNUNET_SERVICE_Client *client = cls;
644 
645  GNUNET_break(
646  0 !=
647  client->warn_type); /* type should never be 0 here, as we don't use 0 */
650  client);
651  LOG(
653  _(
654  "Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"),
655  (unsigned int)client->warn_type,
657  client->warn_start),
658  GNUNET_YES));
659 }
660 
661 
673 static int
674 service_client_mst_cb(void *cls, const struct GNUNET_MessageHeader *message)
675 {
676  struct GNUNET_SERVICE_Client *client = cls;
677 
679  "Received message of type %u and size %u from client\n",
680  ntohs(message->type),
681  ntohs(message->size));
683  client->needs_continue = GNUNET_YES;
684  client->warn_type = ntohs(message->type);
686  GNUNET_assert(NULL == client->warn_task);
689  client);
690  GNUNET_MQ_inject_message(client->mq, message);
691  if (NULL != client->drop_task)
692  return GNUNET_SYSERR;
693  return GNUNET_OK;
694 }
695 
696 
703 static void
705 {
706  struct GNUNET_SERVICE_Client *client = cls;
707  int ret;
708 
709  client->recv_task = NULL;
710  ret = GNUNET_MST_read(client->mst, client->sock, GNUNET_NO, GNUNET_YES);
711  if (GNUNET_SYSERR == ret)
712  {
713  /* client closed connection (or IO error) */
714  if (NULL == client->drop_task)
715  {
718  }
719  return;
720  }
721  if (GNUNET_NO == ret)
722  return; /* more messages in buffer, wait for application
723  to be done processing */
724  GNUNET_assert(GNUNET_OK == ret);
725  if (GNUNET_YES == client->needs_continue)
726  return;
727  if (NULL != client->recv_task)
728  return;
729  /* MST needs more data, re-schedule read job */
730  client->recv_task =
732  client->sock,
734  client);
735 }
736 
737 
745 static void
747  struct GNUNET_NETWORK_Handle *csock)
748 {
749  struct GNUNET_SERVICE_Client *client;
750 
751  client = GNUNET_new(struct GNUNET_SERVICE_Client);
753  client->sh = sh;
754  client->sock = csock;
756  NULL,
758  client,
759  sh->handlers,
761  client);
762  client->mst = GNUNET_MST_create(&service_client_mst_cb, client);
763  if (NULL != sh->connect_cb)
764  client->user_context = sh->connect_cb(sh->cb_cls, client, client->mq);
766  client->recv_task =
768  client->sock,
770  client);
771 }
772 
773 
780 static void
781 accept_client(void *cls)
782 {
783  struct ServiceListenContext *slc = cls;
784  struct GNUNET_SERVICE_Handle *sh = slc->sh;
785 
786  slc->listen_task = NULL;
787  while (1)
788  {
789  struct GNUNET_NETWORK_Handle *sock;
790  const struct sockaddr_in *v4;
791  const struct sockaddr_in6 *v6;
792  struct sockaddr_storage sa;
793  socklen_t addrlen;
794  int ok;
795 
796  addrlen = sizeof(sa);
798  (struct sockaddr *)&sa,
799  &addrlen);
800  if (NULL == sock)
801  {
802  if (EMFILE == errno)
804  else if (EAGAIN != errno)
806  break;
807  }
808  switch (sa.ss_family)
809  {
810  case AF_INET:
811  GNUNET_assert(addrlen == sizeof(struct sockaddr_in));
812  v4 = (const struct sockaddr_in *)&sa;
813  ok = (((NULL == sh->v4_allowed) ||
814  (check_ipv4_listed(sh->v4_allowed, &v4->sin_addr))) &&
815  ((NULL == sh->v4_denied) ||
816  (!check_ipv4_listed(sh->v4_denied, &v4->sin_addr))));
817  break;
818 
819  case AF_INET6:
820  GNUNET_assert(addrlen == sizeof(struct sockaddr_in6));
821  v6 = (const struct sockaddr_in6 *)&sa;
822  ok = (((NULL == sh->v6_allowed) ||
823  (check_ipv6_listed(sh->v6_allowed, &v6->sin6_addr))) &&
824  ((NULL == sh->v6_denied) ||
825  (!check_ipv6_listed(sh->v6_denied, &v6->sin6_addr))));
826  break;
827 
828  case AF_UNIX:
829  ok = GNUNET_OK; /* controlled using file-system ACL now */
830  break;
831 
832  default:
834  _("Unknown address family %d\n"),
835  sa.ss_family);
836  return;
837  }
838  if (!ok)
839  {
841  "Service rejected incoming connection from %s due to policy.\n",
842  GNUNET_a2s((const struct sockaddr *)&sa, addrlen));
844  continue;
845  }
847  "Service accepted incoming connection from %s.\n",
848  GNUNET_a2s((const struct sockaddr *)&sa, addrlen));
849  start_client(slc->sh, sock);
850  }
851  if (0 != sh->suspend_state)
852  return;
853  slc->listen_task =
855  slc->listen_socket,
856  &accept_client,
857  slc);
858 }
859 
860 
868 static void
870 {
871  struct ServiceListenContext *slc;
872 
873  GNUNET_assert((SUSPEND_STATE_NONE == sr) || (0 != (sh->suspend_state & sr)));
874  sh->suspend_state -= sr;
876  return;
877  for (slc = sh->slc_head; NULL != slc; slc = slc->next)
878  {
879  GNUNET_assert(NULL == slc->listen_task);
880  slc->listen_task =
882  slc->listen_socket,
883  &accept_client,
884  slc);
885  }
886 }
887 
888 
896 static void
897 service_main(void *cls)
898 {
899  struct GNUNET_SERVICE_Handle *sh = cls;
900 
904 
905  if (-1 != sh->ready_confirm_fd)
906  {
907  GNUNET_break(1 == write(sh->ready_confirm_fd, ".", 1));
908  GNUNET_break(0 == close(sh->ready_confirm_fd));
909  sh->ready_confirm_fd = -1;
910  }
911 
912  if (NULL != sh->service_init_cb)
913  sh->service_init_cb(sh->cb_cls, sh->cfg, sh);
914 }
915 
916 
926 static int
928  struct GNUNET_SERVICE_Handle *sh,
929  const char *option)
930 {
931  char *opt;
932 
933  if (!GNUNET_CONFIGURATION_have_value(sh->cfg, sh->service_name, option))
934  {
935  *ret = NULL;
936  return GNUNET_OK;
937  }
940  sh->service_name,
941  option,
942  &opt));
943  if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy(opt)))
944  {
946  _("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
947  opt,
948  sh->service_name,
949  option);
950  GNUNET_free(opt);
951  return GNUNET_SYSERR;
952  }
953  GNUNET_free(opt);
954  return GNUNET_OK;
955 }
956 
957 
967 static int
969  struct GNUNET_SERVICE_Handle *sh,
970  const char *option)
971 {
972  char *opt;
973 
974  if (!GNUNET_CONFIGURATION_have_value(sh->cfg, sh->service_name, option))
975  {
976  *ret = NULL;
977  return GNUNET_OK;
978  }
981  sh->service_name,
982  option,
983  &opt));
984  if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy(opt)))
985  {
987  _("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
988  opt,
989  sh->service_name,
990  option);
991  GNUNET_free(opt);
992  return GNUNET_SYSERR;
993  }
994  GNUNET_free(opt);
995  return GNUNET_OK;
996 }
997 
998 
1009 static void
1010 add_unixpath(struct sockaddr **saddrs,
1011  socklen_t *saddrlens,
1012  const char *unixpath,
1013  int abstract)
1014 {
1015 #ifdef AF_UNIX
1016  struct sockaddr_un *un;
1017 
1018  un = GNUNET_new(struct sockaddr_un);
1019  un->sun_family = AF_UNIX;
1020  GNUNET_strlcpy(un->sun_path, unixpath, sizeof(un->sun_path));
1021 #ifdef LINUX
1022  if (GNUNET_YES == abstract)
1023  un->sun_path[0] = '\0';
1024 #endif
1025 #if HAVE_SOCKADDR_UN_SUN_LEN
1026  un->sun_len = (u_char)sizeof(struct sockaddr_un);
1027 #endif
1028  *saddrs = (struct sockaddr *)un;
1029  *saddrlens = sizeof(struct sockaddr_un);
1030 #else
1031  /* this function should never be called
1032  * unless AF_UNIX is defined! */
1033  GNUNET_assert(0);
1034 #endif
1035 }
1036 
1037 
1058 static int
1060  const struct GNUNET_CONFIGURATION_Handle *cfg,
1061  struct sockaddr ***addrs,
1062  socklen_t **addr_lens)
1063 {
1064  int disablev6;
1065  struct GNUNET_NETWORK_Handle *desc;
1066  unsigned long long port;
1067  char *unixpath;
1068  struct addrinfo hints;
1069  struct addrinfo *res;
1070  struct addrinfo *pos;
1071  struct addrinfo *next;
1072  unsigned int i;
1073  int resi;
1074  int ret;
1075  int abstract;
1076  struct sockaddr **saddrs;
1077  socklen_t *saddrlens;
1078  char *hostname;
1079 
1080  *addrs = NULL;
1081  *addr_lens = NULL;
1082  desc = NULL;
1083  disablev6 = GNUNET_NO;
1084  if ((GNUNET_NO == GNUNET_NETWORK_test_pf(PF_INET6)) ||
1085  (GNUNET_YES ==
1086  GNUNET_CONFIGURATION_get_value_yesno(cfg, service_name, "DISABLEV6")))
1087  disablev6 = GNUNET_YES;
1088 
1089  port = 0;
1090  if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "PORT"))
1091  {
1093  service_name,
1094  "PORT",
1095  &port))
1096  {
1098  _("Require valid port number for service `%s' in configuration!\n"),
1099  service_name);
1100  }
1101  if (port > 65535)
1102  {
1104  _("Require valid port number for service `%s' in configuration!\n"),
1105  service_name);
1106  return GNUNET_SYSERR;
1107  }
1108  }
1109 
1110  if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "BINDTO"))
1111  {
1114  service_name,
1115  "BINDTO",
1116  &hostname));
1117  }
1118  else
1119  hostname = NULL;
1120 
1121  unixpath = NULL;
1122  abstract = GNUNET_NO;
1123 #ifdef AF_UNIX
1124  if ((GNUNET_YES ==
1125  GNUNET_CONFIGURATION_have_value(cfg, service_name, "UNIXPATH")) &&
1127  service_name,
1128  "UNIXPATH",
1129  &unixpath)) &&
1130  (0 < strlen(unixpath)))
1131  {
1132  /* probe UNIX support */
1133  struct sockaddr_un s_un;
1134 
1135  if (strlen(unixpath) >= sizeof(s_un.sun_path))
1136  {
1138  _("UNIXPATH `%s' too long, maximum length is %llu\n"),
1139  unixpath,
1140  (unsigned long long)sizeof(s_un.sun_path));
1141  unixpath = GNUNET_NETWORK_shorten_unixpath(unixpath);
1142  LOG(GNUNET_ERROR_TYPE_INFO, _("Using `%s' instead\n"), unixpath);
1143  }
1144 #ifdef LINUX
1145  abstract = GNUNET_CONFIGURATION_get_value_yesno(cfg,
1146  "TESTING",
1147  "USE_ABSTRACT_SOCKETS");
1148  if (GNUNET_SYSERR == abstract)
1149  abstract = GNUNET_NO;
1150 #endif
1151  if ((GNUNET_YES != abstract) &&
1154  }
1155  if (NULL != unixpath)
1156  {
1157  desc = GNUNET_NETWORK_socket_create(AF_UNIX, SOCK_STREAM, 0);
1158  if (NULL == desc)
1159  {
1160  if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
1161  (EACCES == errno))
1162  {
1164  GNUNET_free_non_null(hostname);
1165  GNUNET_free(unixpath);
1166  return GNUNET_SYSERR;
1167  }
1169  _(
1170  "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
1171  service_name,
1172  strerror(errno));
1173  GNUNET_free(unixpath);
1174  unixpath = NULL;
1175  }
1176  else
1177  {
1179  desc = NULL;
1180  }
1181  }
1182 #endif
1183 
1184  if ((0 == port) && (NULL == unixpath))
1185  {
1187  _(
1188  "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
1189  service_name);
1190  GNUNET_free_non_null(hostname);
1191  return GNUNET_SYSERR;
1192  }
1193  if (0 == port)
1194  {
1195  saddrs = GNUNET_new_array(2, struct sockaddr *);
1196  saddrlens = GNUNET_new_array(2, socklen_t);
1197  add_unixpath(saddrs, saddrlens, unixpath, abstract);
1198  GNUNET_free_non_null(unixpath);
1199  GNUNET_free_non_null(hostname);
1200  *addrs = saddrs;
1201  *addr_lens = saddrlens;
1202  return 1;
1203  }
1204 
1205  if (NULL != hostname)
1206  {
1208  "Resolving `%s' since that is where `%s' will bind to.\n",
1209  hostname,
1210  service_name);
1211  memset(&hints, 0, sizeof(struct addrinfo));
1212  if (disablev6)
1213  hints.ai_family = AF_INET;
1214  hints.ai_protocol = IPPROTO_TCP;
1215  if ((0 != (ret = getaddrinfo(hostname, NULL, &hints, &res))) ||
1216  (NULL == res))
1217  {
1219  _("Failed to resolve `%s': %s\n"),
1220  hostname,
1221  gai_strerror(ret));
1222  GNUNET_free(hostname);
1223  GNUNET_free_non_null(unixpath);
1224  return GNUNET_SYSERR;
1225  }
1226  next = res;
1227  i = 0;
1228  while (NULL != (pos = next))
1229  {
1230  next = pos->ai_next;
1231  if ((disablev6) && (pos->ai_family == AF_INET6))
1232  continue;
1233  i++;
1234  }
1235  if (0 == i)
1236  {
1238  _("Failed to find %saddress for `%s'.\n"),
1239  disablev6 ? "IPv4 " : "",
1240  hostname);
1241  freeaddrinfo(res);
1242  GNUNET_free(hostname);
1243  GNUNET_free_non_null(unixpath);
1244  return GNUNET_SYSERR;
1245  }
1246  resi = i;
1247  if (NULL != unixpath)
1248  resi++;
1249  saddrs = GNUNET_new_array(resi + 1, struct sockaddr *);
1250  saddrlens = GNUNET_new_array(resi + 1, socklen_t);
1251  i = 0;
1252  if (NULL != unixpath)
1253  {
1254  add_unixpath(saddrs, saddrlens, unixpath, abstract);
1255  i++;
1256  }
1257  next = res;
1258  while (NULL != (pos = next))
1259  {
1260  next = pos->ai_next;
1261  if ((disablev6) && (AF_INET6 == pos->ai_family))
1262  continue;
1263  if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
1264  continue; /* not TCP */
1265  if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
1266  continue; /* huh? */
1268  "Service `%s' will bind to `%s'\n",
1269  service_name,
1270  GNUNET_a2s(pos->ai_addr, pos->ai_addrlen));
1271  if (AF_INET == pos->ai_family)
1272  {
1273  GNUNET_assert(sizeof(struct sockaddr_in) == pos->ai_addrlen);
1274  saddrlens[i] = pos->ai_addrlen;
1275  saddrs[i] = GNUNET_malloc(saddrlens[i]);
1276  GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]);
1277  ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port);
1278  }
1279  else
1280  {
1281  GNUNET_assert(AF_INET6 == pos->ai_family);
1282  GNUNET_assert(sizeof(struct sockaddr_in6) == pos->ai_addrlen);
1283  saddrlens[i] = pos->ai_addrlen;
1284  saddrs[i] = GNUNET_malloc(saddrlens[i]);
1285  GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]);
1286  ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port);
1287  }
1288  i++;
1289  }
1290  GNUNET_free(hostname);
1291  freeaddrinfo(res);
1292  resi = i;
1293  }
1294  else
1295  {
1296  /* will bind against everything, just set port */
1297  if (disablev6)
1298  {
1299  /* V4-only */
1300  resi = 1;
1301  if (NULL != unixpath)
1302  resi++;
1303  i = 0;
1304  saddrs = GNUNET_new_array(resi + 1, struct sockaddr *);
1305  saddrlens = GNUNET_new_array(resi + 1, socklen_t);
1306  if (NULL != unixpath)
1307  {
1308  add_unixpath(saddrs, saddrlens, unixpath, abstract);
1309  i++;
1310  }
1311  saddrlens[i] = sizeof(struct sockaddr_in);
1312  saddrs[i] = GNUNET_malloc(saddrlens[i]);
1313 #if HAVE_SOCKADDR_IN_SIN_LEN
1314  ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[i];
1315 #endif
1316  ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET;
1317  ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port);
1318  }
1319  else
1320  {
1321  /* dual stack */
1322  resi = 2;
1323  if (NULL != unixpath)
1324  resi++;
1325  saddrs = GNUNET_new_array(resi + 1, struct sockaddr *);
1326  saddrlens = GNUNET_new_array(resi + 1, socklen_t);
1327  i = 0;
1328  if (NULL != unixpath)
1329  {
1330  add_unixpath(saddrs, saddrlens, unixpath, abstract);
1331  i++;
1332  }
1333  saddrlens[i] = sizeof(struct sockaddr_in6);
1334  saddrs[i] = GNUNET_malloc(saddrlens[i]);
1335 #if HAVE_SOCKADDR_IN_SIN_LEN
1336  ((struct sockaddr_in6 *)saddrs[i])->sin6_len = saddrlens[0];
1337 #endif
1338  ((struct sockaddr_in6 *)saddrs[i])->sin6_family = AF_INET6;
1339  ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port);
1340  i++;
1341  saddrlens[i] = sizeof(struct sockaddr_in);
1342  saddrs[i] = GNUNET_malloc(saddrlens[i]);
1343 #if HAVE_SOCKADDR_IN_SIN_LEN
1344  ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[1];
1345 #endif
1346  ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET;
1347  ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port);
1348  }
1349  }
1350  GNUNET_free_non_null(unixpath);
1351  *addrs = saddrs;
1352  *addr_lens = saddrlens;
1353  return resi;
1354 }
1355 
1356 
1364 static struct GNUNET_NETWORK_Handle *
1365 open_listen_socket(const struct sockaddr *server_addr, socklen_t socklen)
1366 {
1367  struct GNUNET_NETWORK_Handle *sock;
1368  uint16_t port;
1369  int eno;
1370 
1371  switch (server_addr->sa_family)
1372  {
1373  case AF_INET:
1374  port = ntohs(((const struct sockaddr_in *)server_addr)->sin_port);
1375  break;
1376 
1377  case AF_INET6:
1378  port = ntohs(((const struct sockaddr_in6 *)server_addr)->sin6_port);
1379  break;
1380 
1381  case AF_UNIX:
1382  port = 0;
1383  break;
1384 
1385  default:
1386  GNUNET_break(0);
1387  port = 0;
1388  break;
1389  }
1390  sock = GNUNET_NETWORK_socket_create(server_addr->sa_family, SOCK_STREAM, 0);
1391  if (NULL == sock)
1392  {
1394  errno = 0;
1395  return NULL;
1396  }
1397  /* bind the socket */
1398  if (GNUNET_OK != GNUNET_NETWORK_socket_bind(sock, server_addr, socklen))
1399  {
1400  eno = errno;
1401  if (EADDRINUSE != errno)
1402  {
1403  /* we don't log 'EADDRINUSE' here since an IPv4 bind may
1404  * fail if we already took the port on IPv6; if both IPv4 and
1405  * IPv6 binds fail, then our caller will log using the
1406  * errno preserved in 'eno' */
1407  if (0 != port)
1409  _("`%s' failed for port %d (%s).\n"),
1410  "bind",
1411  port,
1412  (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1413  else
1415  eno = 0;
1416  }
1417  else
1418  {
1419  if (0 != port)
1421  _("`%s' failed for port %d (%s): address already in use\n"),
1422  "bind",
1423  port,
1424  (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1425  else if (AF_UNIX == server_addr->sa_family)
1426  {
1428  _("`%s' failed for `%s': address already in use\n"),
1429  "bind",
1430  GNUNET_a2s(server_addr, socklen));
1431  }
1432  }
1434  errno = eno;
1435  return NULL;
1436  }
1437  if (GNUNET_OK != GNUNET_NETWORK_socket_listen(sock, 5))
1438  {
1441  errno = 0;
1442  return NULL;
1443  }
1444  if (0 != port)
1446  "Server starts to listen on port %u.\n",
1447  port);
1448  return sock;
1449 }
1450 
1451 
1468 static int
1470 {
1471  int tolerant;
1472  struct GNUNET_NETWORK_Handle **lsocks;
1473  const char *nfds;
1474  unsigned int cnt;
1475  int flags;
1476  char dummy[2];
1477 
1478  if (GNUNET_CONFIGURATION_have_value(sh->cfg, sh->service_name, "TOLERANT"))
1479  {
1480  if (GNUNET_SYSERR ==
1481  (tolerant = GNUNET_CONFIGURATION_get_value_yesno(sh->cfg,
1482  sh->service_name,
1483  "TOLERANT")))
1484  {
1486  _("Specified value for `%s' of service `%s' is invalid\n"),
1487  "TOLERANT",
1488  sh->service_name);
1489  return GNUNET_SYSERR;
1490  }
1491  }
1492  else
1493  tolerant = GNUNET_NO;
1494 
1495  lsocks = NULL;
1496 
1497  errno = 0;
1498  if ((NULL != (nfds = getenv("LISTEN_FDS"))) &&
1499  (1 == sscanf(nfds, "%u%1s", &cnt, dummy)) && (cnt > 0) &&
1500  (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE))
1501  {
1502  lsocks = GNUNET_new_array(cnt + 1, struct GNUNET_NETWORK_Handle *);
1503  while (0 < cnt--)
1504  {
1505  flags = fcntl(3 + cnt, F_GETFD);
1506  if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) ||
1507  (NULL == (lsocks[cnt] = GNUNET_NETWORK_socket_box_native(3 + cnt))))
1508  {
1510  _(
1511  "Could not access pre-bound socket %u, will try to bind myself\n"),
1512  (unsigned int)3 + cnt);
1513  cnt++;
1514  while (NULL != lsocks[cnt])
1516  GNUNET_NETWORK_socket_close(lsocks[cnt++]));
1517  GNUNET_free(lsocks);
1518  lsocks = NULL;
1519  break;
1520  }
1521  }
1522  unsetenv("LISTEN_FDS");
1523  }
1524 
1525  if (NULL != lsocks)
1526  {
1527  /* listen only on inherited sockets if we have any */
1528  struct GNUNET_NETWORK_Handle **ls;
1529 
1530  for (ls = lsocks; NULL != *ls; ls++)
1531  {
1532  struct ServiceListenContext *slc;
1533 
1534  slc = GNUNET_new(struct ServiceListenContext);
1535  slc->sh = sh;
1536  slc->listen_socket = *ls;
1538  }
1539  GNUNET_free(lsocks);
1540  }
1541  else
1542  {
1543  struct sockaddr **addrs;
1544  socklen_t *addrlens;
1545  int num;
1546 
1547  num = get_server_addresses(sh->service_name, sh->cfg, &addrs, &addrlens);
1548  if (GNUNET_SYSERR == num)
1549  return GNUNET_SYSERR;
1550 
1551  for (int i = 0; i < num; i++)
1552  {
1553  struct ServiceListenContext *slc;
1554 
1555  slc = GNUNET_new(struct ServiceListenContext);
1556  slc->sh = sh;
1557  slc->listen_socket = open_listen_socket(addrs[i], addrlens[i]);
1558  GNUNET_free(addrs[i]);
1559  if (NULL == slc->listen_socket)
1560  {
1562  GNUNET_free(slc);
1563  continue;
1564  }
1566  }
1567  GNUNET_free_non_null(addrlens);
1568  GNUNET_free_non_null(addrs);
1569  if ((0 != num) && (NULL == sh->slc_head))
1570  {
1571  /* All attempts to bind failed, hard failure */
1572  GNUNET_log(
1574  _(
1575  "Could not bind to any of the ports I was supposed to, refusing to run!\n"));
1576  return GNUNET_SYSERR;
1577  }
1578  }
1579 
1580  sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
1582  sh->service_name,
1583  "UNIX_MATCH_UID");
1585  sh->service_name,
1586  "UNIX_MATCH_GID");
1587  process_acl4(&sh->v4_denied, sh, "REJECT_FROM");
1588  process_acl4(&sh->v4_allowed, sh, "ACCEPT_FROM");
1589  process_acl6(&sh->v6_denied, sh, "REJECT_FROM6");
1590  process_acl6(&sh->v6_allowed, sh, "ACCEPT_FROM6");
1591  return GNUNET_OK;
1592 }
1593 
1594 
1602 static char *
1604 {
1605  char *un;
1606 
1608  sh->service_name,
1609  "USERNAME",
1610  &un))
1611  return NULL;
1612  return un;
1613 }
1614 
1615 
1622 static int
1624 {
1625  char *user;
1626 
1627  if (NULL == (user = get_user_name(sh)))
1628  return GNUNET_OK; /* keep */
1629 
1630  struct passwd *pws;
1631 
1632  errno = 0;
1633  pws = getpwnam(user);
1634  if (NULL == pws)
1635  {
1637  _("Cannot obtain information about user `%s': %s\n"),
1638  user,
1639  errno == 0 ? _("No such user") : strerror(errno));
1640  GNUNET_free(user);
1641  return GNUNET_SYSERR;
1642  }
1643  if ((0 != setgid(pws->pw_gid)) || (0 != setegid(pws->pw_gid)) ||
1644 #if HAVE_INITGROUPS
1645  (0 != initgroups(user, pws->pw_gid)) ||
1646 #endif
1647  (0 != setuid(pws->pw_uid)) || (0 != seteuid(pws->pw_uid)))
1648  {
1649  if ((0 != setregid(pws->pw_gid, pws->pw_gid)) ||
1650  (0 != setreuid(pws->pw_uid, pws->pw_uid)))
1651  {
1653  _("Cannot change user/group to `%s': %s\n"),
1654  user,
1655  strerror(errno));
1656  GNUNET_free(user);
1657  return GNUNET_SYSERR;
1658  }
1659  }
1660 
1661  GNUNET_free(user);
1662  return GNUNET_OK;
1663 }
1664 
1665 
1673 static char *
1675 {
1676  char *pif;
1677 
1679  sh->service_name,
1680  "PIDFILE",
1681  &pif))
1682  return NULL;
1683  return pif;
1684 }
1685 
1686 
1692 static void
1694 {
1695  char *pif = get_pid_file_name(sh);
1696 
1697  if (NULL == pif)
1698  return; /* no PID file */
1699  if (0 != unlink(pif))
1701  GNUNET_free(pif);
1702 }
1703 
1704 
1711 static int
1713 {
1714  pid_t pid;
1715  int nullfd;
1716  int filedes[2];
1717 
1718  if (0 != pipe(filedes))
1719  {
1721  return GNUNET_SYSERR;
1722  }
1723  pid = fork();
1724  if (pid < 0)
1725  {
1727  return GNUNET_SYSERR;
1728  }
1729  if (0 != pid)
1730  {
1731  /* Parent */
1732  char c;
1733 
1734  GNUNET_break(0 == close(filedes[1]));
1735  c = 'X';
1736  if (1 != read(filedes[0], &c, sizeof(char)))
1738  fflush(stdout);
1739  switch (c)
1740  {
1741  case '.':
1742  exit(0);
1743 
1744  case 'I':
1746  _("Service process failed to initialize\n"));
1747  break;
1748 
1749  case 'S':
1751  _("Service process could not initialize server function\n"));
1752  break;
1753 
1754  case 'X':
1756  _("Service process failed to report status\n"));
1757  break;
1758  }
1759  exit(1); /* child reported error */
1760  }
1761  GNUNET_break(0 == close(0));
1762  GNUNET_break(0 == close(1));
1763  GNUNET_break(0 == close(filedes[0]));
1764  nullfd = open("/dev/null", O_RDWR | O_APPEND);
1765  if (nullfd < 0)
1766  return GNUNET_SYSERR;
1767  /* set stdin/stdout to /dev/null */
1768  if ((dup2(nullfd, 0) < 0) || (dup2(nullfd, 1) < 0))
1769  {
1771  (void)close(nullfd);
1772  return GNUNET_SYSERR;
1773  }
1774  (void)close(nullfd);
1775  /* Detach from controlling terminal */
1776  pid = setsid();
1777  if (-1 == pid)
1779  sh->ready_confirm_fd = filedes[1];
1780 
1781  return GNUNET_OK;
1782 }
1783 
1784 
1791 static void
1793 {
1794  struct ServiceListenContext *slc;
1795 
1800  while (NULL != (slc = sh->slc_head))
1801  {
1803  if (NULL != slc->listen_task)
1807  GNUNET_free(slc);
1808  }
1809 }
1810 
1811 
1818 static void
1819 return_agpl(void *cls, const struct GNUNET_MessageHeader *msg)
1820 {
1821  struct GNUNET_SERVICE_Client *client = cls;
1822  struct GNUNET_MQ_Handle *mq;
1823  struct GNUNET_MQ_Envelope *env;
1824  struct GNUNET_MessageHeader *res;
1825  size_t slen;
1826 
1827  (void)msg;
1828  slen = strlen(GNUNET_AGPL_URL) + 1;
1830  memcpy(&res[1], GNUNET_AGPL_URL, slen);
1831  mq = GNUNET_SERVICE_client_get_mq(client);
1832  GNUNET_MQ_send(mq, env);
1834 }
1835 
1836 
1873 struct GNUNET_SERVICE_Handle *
1875  const struct GNUNET_CONFIGURATION_Handle *cfg,
1878  void *cls,
1879  const struct GNUNET_MQ_MessageHandler *handlers)
1880 {
1881  struct GNUNET_SERVICE_Handle *sh;
1882 
1883  sh = GNUNET_new(struct GNUNET_SERVICE_Handle);
1884  sh->service_name = service_name;
1885  sh->cfg = cfg;
1886  sh->connect_cb = connect_cb;
1888  sh->cb_cls = cls;
1889  sh->handlers = GNUNET_MQ_copy_handlers2(handlers, &return_agpl, NULL);
1890  if (GNUNET_OK != setup_service(sh))
1891  {
1893  GNUNET_free(sh);
1894  return NULL;
1895  }
1897  return sh;
1898 }
1899 
1900 
1906 void
1908 {
1909  struct GNUNET_SERVICE_Client *client;
1910 
1912  while (NULL != (client = srv->clients_head))
1914  teardown_service(srv);
1916  GNUNET_free(srv);
1917 }
1918 
1919 
1961 int
1963  char *const *argv,
1964  const char *service_name,
1966  GNUNET_SERVICE_InitCallback service_init_cb,
1969  void *cls,
1970  const struct GNUNET_MQ_MessageHandler *handlers)
1971 {
1972  struct GNUNET_SERVICE_Handle sh;
1973 
1974 #if ENABLE_NLS
1975  char *path;
1976 #endif
1977  char *cfg_filename;
1978  char *opt_cfg_filename;
1979  char *loglev;
1980  const char *xdg;
1981  char *logfile;
1982  int do_daemonize;
1983  unsigned long long skew_offset;
1984  unsigned long long skew_variance;
1985  long long clock_offset;
1987  int ret;
1988  int err;
1990 
1991  struct GNUNET_GETOPT_CommandLineOption service_options[] =
1992  { GNUNET_GETOPT_option_cfgfile(&opt_cfg_filename),
1994  "daemonize",
1995  gettext_noop(
1996  "do daemonize (detach from terminal)"),
1997  &do_daemonize),
2000  GNUNET_GETOPT_option_logfile(&logfile),
2003 
2004  err = 1;
2005  memset(&sh, 0, sizeof(sh));
2006  xdg = getenv("XDG_CONFIG_HOME");
2007  if (NULL != xdg)
2008  GNUNET_asprintf(&cfg_filename,
2009  "%s%s%s",
2010  xdg,
2012  pd->config_file);
2013  else
2014  cfg_filename = GNUNET_strdup(pd->user_config_file);
2015  sh.ready_confirm_fd = -1;
2016  sh.options = options;
2017  sh.cfg = cfg = GNUNET_CONFIGURATION_create();
2018  sh.service_init_cb = service_init_cb;
2019  sh.connect_cb = connect_cb;
2021  sh.cb_cls = cls;
2022  sh.handlers = GNUNET_MQ_copy_handlers(handlers);
2024  sh.ret = 0;
2025  /* setup subsystems */
2026  loglev = NULL;
2027  logfile = NULL;
2028  opt_cfg_filename = NULL;
2029  do_daemonize = 0;
2030 #if ENABLE_NLS
2031  if (NULL != pd->gettext_domain)
2032  {
2033  setlocale(LC_ALL, "");
2034  path = (NULL == pd->gettext_path) ?
2037  if (NULL != path)
2038  {
2039  bindtextdomain(pd->gettext_domain, path);
2040  GNUNET_free(path);
2041  }
2043  }
2044 #endif
2045  ret = GNUNET_GETOPT_run(service_name, service_options, argc, argv);
2046  if (GNUNET_SYSERR == ret)
2047  goto shutdown;
2048  if (GNUNET_NO == ret)
2049  {
2050  err = 0;
2051  goto shutdown;
2052  }
2053  if (GNUNET_OK != GNUNET_log_setup(service_name, loglev, logfile))
2054  {
2055  GNUNET_break(0);
2056  goto shutdown;
2057  }
2058  if (NULL != opt_cfg_filename)
2059  {
2060  if ((GNUNET_YES != GNUNET_DISK_file_test(opt_cfg_filename)) ||
2061  (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, opt_cfg_filename)))
2062  {
2064  _("Malformed configuration file `%s', exit ...\n"),
2065  opt_cfg_filename);
2066  goto shutdown;
2067  }
2068  }
2069  else
2070  {
2071  if (GNUNET_YES == GNUNET_DISK_file_test(cfg_filename))
2072  {
2073  if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, cfg_filename))
2074  {
2076  _("Malformed configuration file `%s', exit ...\n"),
2077  cfg_filename);
2078  goto shutdown;
2079  }
2080  }
2081  else
2082  {
2083  if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, NULL))
2084  {
2086  _("Malformed configuration, exit ...\n"));
2087  goto shutdown;
2088  }
2089  }
2090  }
2091  if (GNUNET_OK != setup_service(&sh))
2092  goto shutdown;
2093  if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal(&sh)))
2094  {
2095  GNUNET_break(0);
2096  goto shutdown;
2097  }
2098  if (GNUNET_OK != set_user_id(&sh))
2099  goto shutdown;
2101  "Service `%s' runs with configuration from `%s'\n",
2102  service_name,
2103  (NULL != opt_cfg_filename) ? opt_cfg_filename : cfg_filename);
2105  "TESTING",
2106  "SKEW_OFFSET",
2107  &skew_offset)) &&
2109  "TESTING",
2110  "SKEW_VARIANCE",
2111  &skew_variance)))
2112  {
2113  clock_offset = skew_offset - skew_variance;
2114  GNUNET_TIME_set_offset(clock_offset);
2115  LOG(GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset);
2116  }
2118 
2119  /* actually run service */
2120  err = 0;
2122  /* shutdown */
2123  if (1 == do_daemonize)
2124  pid_file_delete(&sh);
2125 
2126 shutdown:
2127  if (-1 != sh.ready_confirm_fd)
2128  {
2129  if (1 != write(sh.ready_confirm_fd, err ? "I" : "S", 1))
2131  GNUNET_break(0 == close(sh.ready_confirm_fd));
2132  }
2133 #if HAVE_MALLINFO
2134  {
2135  char *counter;
2136 
2138  service_name,
2139  "GAUGER_HEAP")) &&
2141  service_name,
2142  "GAUGER_HEAP",
2143  &counter)))
2144  {
2145  struct mallinfo mi;
2146 
2147  mi = mallinfo();
2148  GAUGER(service_name, counter, mi.usmblks, "blocks");
2149  GNUNET_free(counter);
2150  }
2151  }
2152 #endif
2153  teardown_service(&sh);
2157  GNUNET_free_non_null(logfile);
2158  GNUNET_free_non_null(loglev);
2159  GNUNET_free(cfg_filename);
2160  GNUNET_free_non_null(opt_cfg_filename);
2161 
2162  return err ? GNUNET_SYSERR : sh.ret;
2163 }
2164 
2165 
2172 void
2174 {
2176 }
2177 
2178 
2184 void
2186 {
2188 }
2189 
2190 
2197 static void
2199 {
2200  struct GNUNET_SERVICE_Client *c = cls;
2201  int ret;
2202 
2203  c->recv_task = NULL;
2204  /* first, check if there is still something in the buffer */
2205  ret = GNUNET_MST_next(c->mst, GNUNET_YES);
2206  if (GNUNET_SYSERR == ret)
2207  {
2208  if (NULL == c->drop_task)
2210  return;
2211  }
2212  if (GNUNET_NO == ret)
2213  return; /* done processing, wait for more later */
2214  GNUNET_assert(GNUNET_OK == ret);
2215  if (GNUNET_YES == c->needs_continue)
2216  return; /* #GNUNET_MST_next() did give a message to the client */
2217  /* need to receive more data from the network first */
2218  if (NULL != c->recv_task)
2219  return;
2221  c->sock,
2223  c);
2224 }
2225 
2226 
2233 void
2235 {
2236  GNUNET_assert(NULL == c->drop_task);
2238  GNUNET_assert(NULL == c->recv_task);
2240  if (NULL != c->warn_task)
2241  {
2243  c->warn_task = NULL;
2244  }
2246 }
2247 
2248 
2257 void
2259 {
2260  GNUNET_break(NULL != c->warn_task);
2261  if (NULL != c->warn_task)
2262  {
2264  c->warn_task = NULL;
2265  }
2266 }
2267 
2268 
2274 static void
2276 {
2277  struct GNUNET_SERVICE_Client *c = cls;
2278  struct GNUNET_SERVICE_Handle *sh = c->sh;
2279 
2280  c->drop_task = NULL;
2281  GNUNET_assert(NULL == c->send_task);
2282  GNUNET_assert(NULL == c->recv_task);
2283  GNUNET_assert(NULL == c->warn_task);
2284  GNUNET_MST_destroy(c->mst);
2285  GNUNET_MQ_destroy(c->mq);
2286  if (GNUNET_NO == c->persist)
2287  {
2289  if ((0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) &&
2290  (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)))
2292  }
2293  else
2294  {
2296  }
2297  GNUNET_free(c);
2298  if ((0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) &&
2301 }
2302 
2303 
2314 void
2316 {
2317  struct GNUNET_SERVICE_Handle *sh = c->sh;
2318 
2320  "Client dropped: %p (MQ: %p)\n",
2321  c,
2322  c->mq);
2323 #if EXECINFO
2324  {
2325  void *backtrace_array[MAX_TRACE_DEPTH];
2326  int num_backtrace_strings = backtrace(backtrace_array, MAX_TRACE_DEPTH);
2327  char **backtrace_strings =
2328  backtrace_symbols(backtrace_array, t->num_backtrace_strings);
2329  for (unsigned int i = 0; i < num_backtrace_strings; i++)
2331  "client drop trace %u: %s\n",
2332  i,
2333  backtrace_strings[i]);
2334  }
2335 #endif
2336  if (NULL != c->drop_task)
2337  {
2338  /* asked to drop twice! */
2339  GNUNET_assert(0);
2340  return;
2341  }
2343  if (NULL != sh->disconnect_cb)
2344  sh->disconnect_cb(sh->cb_cls, c, c->user_context);
2345  if (NULL != c->warn_task)
2346  {
2348  c->warn_task = NULL;
2349  }
2350  if (NULL != c->recv_task)
2351  {
2353  c->recv_task = NULL;
2354  }
2355  if (NULL != c->send_task)
2356  {
2358  c->send_task = NULL;
2359  }
2361 }
2362 
2363 
2369 void
2371 {
2372  struct GNUNET_SERVICE_Client *client;
2373 
2374  if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN))
2376  while (NULL != (client = sh->clients_head))
2378 }
2379 
2380 
2393 void
2395 {
2396  c->is_monitor = GNUNET_YES;
2397  if (((0 != (SUSPEND_STATE_SHUTDOWN & c->sh->suspend_state)) &&
2400 }
2401 
2402 
2410 void
2412 {
2413  c->persist = GNUNET_YES;
2414 }
2415 
2416 
2423 struct GNUNET_MQ_Handle *
2425 {
2426  return c->mq;
2427 }
2428 
2429 
2430 /* end of service_new.c */
static void service_mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implementation function that cancels the currently sent message.
Definition: service.c:596
static void * connect_cb(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
Functions of this type are called upon new cadet connection from other peers.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
int GNUNET_NETWORK_socket_listen(const struct GNUNET_NETWORK_Handle *desc, int backlog)
Listen on a socket.
Definition: network.c:696
static void return_agpl(void *cls, const struct GNUNET_MessageHeader *msg)
Function to return link to AGPL source upon request.
Definition: service.c:1819
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
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).
Definition: service.c:1010
struct GNUNET_STRINGS_IPv4NetworkPolicy * GNUNET_STRINGS_parse_ipv4_policy(const char *routeListX)
Parse an IPv4 network policy.
Definition: strings.c:1519
struct ServiceListenContext * slc_head
DLL of listen sockets used to accept new connections.
Definition: service.c:148
static void resume_client_receive(void *cls)
Task run to resume receiving data from the client after the client called GNUNET_SERVICE_client_conti...
Definition: service.c:2198
static char * cfg_filename
Name of the configuration file.
Return the directory where translations are installed (share/locale/)
const char * config_file
Configuration file name (in $XDG_CONFIG_HOME) to use.
static int 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.
Definition: service.c:1059
int match_uid
Do we require a matching UID for UNIX domain socket connections? GNUNET_NO means that the UID does no...
Definition: service.c:202
struct ServiceListenContext * prev
Kept in a DLL.
Definition: service.c:61
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
enum SuspendReason suspend_state
Are we suspended, and if so, why?
Definition: service.c:216
char * gettext_domain
Gettext domain for localisation, e.g.
struct GNUNET_MQ_MessageHandler * handlers
Message handlers to use for all clients.
Definition: service.c:168
Project-specific data used to help the OS subsystem find installation paths.
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.
struct GNUNET_SERVICE_Client * clients_head
Our clients, kept in a DLL.
Definition: service.c:158
int is_monitor
Is this client a &#39;monitor&#39; client that should not be counted when deciding on destroying the server d...
Definition: service.c:334
struct GNUNET_SERVICE_Client * clients_tail
Our clients, kept in a DLL.
Definition: service.c:163
void GNUNET_MQ_inject_error(struct GNUNET_MQ_Handle *mq, enum GNUNET_MQ_Error error)
Call the error handler of a message queue with the given error code.
Definition: mq.c:298
GNUNET_SERVICE_InitCallback service_init_cb
Main service-specific task to run.
Definition: service.c:128
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
ssize_t GNUNET_NETWORK_socket_send(const struct GNUNET_NETWORK_Handle *desc, const void *buffer, size_t length)
Send data (always non-blocking).
Definition: network.c:804
struct GNUNET_SCHEDULER_Task * send_task
Task that transmit data to the client.
Definition: service.c:298
char * gettext_path
Gettext directory, e.g.
void GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh)
Resume accepting connections from the listen socket.
Definition: service.c:2185
int match_gid
Do we require a matching GID for UNIX domain socket connections? Ignored if match_uid is GNUNET_YES...
Definition: service.c:211
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
Handle to a service.
Definition: service.c:114
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.
Definition: service.c:437
struct ServiceListenContext * next
Kept in a DLL.
Definition: service.c:56
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_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2424
GNUNET_SERVICE_Options
Options for the service (bitmask).
GNUNET_MQ_Error
Error codes for the queue.
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
static int setup_service(struct GNUNET_SERVICE_Handle *sh)
Setup service handle.
Definition: service.c:1469
#define GNUNET_TIME_UNIT_MINUTES
One minute.
static void disconnect_cb(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called by cadet when a client disconnects.
We received a message for which we have no matching handler.
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 ...
static void accept_client(void *cls)
We have a client.
Definition: service.c:781
static void do_suspend(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
Suspend accepting connections from the listen socket temporarily.
Definition: service.c:377
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_MQ_MessageHandler * GNUNET_MQ_copy_handlers(const struct GNUNET_MQ_MessageHandler *handlers)
Copy an array of handlers.
Definition: mq.c:1211
network in CIDR notation for IPV6.
int require_found
If GNUNET_YES, consider unknown message types an error where the client is disconnected.
Definition: service.c:239
Both reasons, APP and EMFILE apply.
Definition: service.c:102
int GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition: network.c:474
struct GNUNET_SERVICE_Client * prev
Kept in a DLL.
Definition: service.c:255
struct GNUNET_NETWORK_Handle * listen_socket
Socket we are listening on.
Definition: service.c:71
int GNUNET_MST_next(struct GNUNET_MessageStreamTokenizer *mst, int one_shot)
Obtain the next message from the mst, assuming that there are more unprocessed messages in the intern...
Definition: mst.c:393
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_write_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *wfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1537
static int ok
Return value from &#39;main&#39; (0 == success)
#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
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
struct GNUNET_SERVICE_Handle * GNUNET_SERVICE_start(const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_SERVICE_ConnectHandler connect_cb, GNUNET_SERVICE_DisconnectHandler disconnect_cb, void *cls, const struct GNUNET_MQ_MessageHandler *handlers)
Low-level function to start a service if the scheduler is already running.
Definition: service.c:1874
const char * user_config_file
Configuration file name to use (if $XDG_CONFIG_HOME is not set).
#define GNUNET_NO
Definition: gnunet_common.h:78
#define bindtextdomain(Domainname, Dirname)
Definition: gettext.h:57
enum GNUNET_SERVICE_Options options
Our options.
Definition: service.c:221
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#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.
static int process_acl6(struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, struct GNUNET_SERVICE_Handle *sh, const char *option)
Parse an IPv6 access control list.
Definition: service.c:968
Definition of a command line option.
static void service_main(void *cls)
First task run by any service.
Definition: service.c:897
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_create(void)
Create a new configuration object.
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_denied
IPv6 addresses that are not allowed to connect.
Definition: service.c:183
static struct GNUNET_SCHEDULER_Task * t
Main task.
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
static int ret
Final status code.
Definition: gnunet-arm.c:89
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct GNUNET_MQ_Handle * mq
Message queue for the client.
Definition: service.c:270
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_logfile(char **logfn)
Allow user to specify log file name (-l option)
We are running normally.
Definition: service.c:87
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static int service_client_mst_cb(void *cls, const struct GNUNET_MessageHeader *message)
Functions with this signature are called whenever a complete message is received by the tokenizer for...
Definition: service.c:674
static void pid_file_delete(struct GNUNET_SERVICE_Handle *sh)
Delete the PID file that was created by our parent.
Definition: service.c:1693
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
static int set_user_id(struct GNUNET_SERVICE_Handle *sh)
Set user ID.
Definition: service.c:1623
struct GNUNET_MessageStreamTokenizer * mst
Tokenizer we use for processing incoming data.
Definition: service.c:275
int GNUNET_CONFIGURATION_load(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Load configuration.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
static void do_send(void *cls)
Task run when we are ready to transmit data to the client.
Definition: service.c:496
Handle to a client that is connected to a service.
Definition: service.c:246
const char * version
String identifying the current project version.
struct in_addr network
IPv4 address.
void GNUNET_NETWORK_socket_free_memory_only_(struct GNUNET_NETWORK_Handle *desc)
Only free memory of a socket, keep the file descriptor untouched.
Definition: network.c:610
#define textdomain(Domainname)
Definition: gettext.h:56
static void service_mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
Definition: service.c:618
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_accept(const struct GNUNET_NETWORK_Handle *desc, struct sockaddr *address, socklen_t *address_len)
Accept a new connection on a socket.
Definition: network.c:420
void GNUNET_MQ_set_handlers_closure(struct GNUNET_MQ_Handle *mq, void *handlers_cls)
Change the closure argument in all of the handlers of the mq.
Definition: mq.c:581
int ready_confirm_fd
If we are daemonizing, this FD is set to the pipe to the parent.
Definition: service.c:228
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_strerror(level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
void * user_context
User context value, value returned from the connect callback.
Definition: service.c:309
void GNUNET_MQ_impl_send_in_flight(struct GNUNET_MQ_Handle *mq)
Call the send notification for the current message, but do not try to send the next message until #gn...
Definition: mq.c:517
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
struct GNUNET_TIME_Absolute warn_start
Time when we last gave a message from this client to the application.
Definition: service.c:315
static void finish_client_drop(void *cls)
Asynchronously finish dropping the client.
Definition: service.c:2275
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1237
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
struct GNUNET_MQ_Handle * GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send, GNUNET_MQ_DestroyImpl destroy, GNUNET_MQ_CancelImpl cancel, void *impl_state, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *cls)
Create a message queue for the specified handlers.
Definition: mq.c:550
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
void *(* GNUNET_SERVICE_ConnectHandler)(void *cls, struct GNUNET_SERVICE_Client *c, struct GNUNET_MQ_Handle *mq)
Callback to be called when a client connects to the service.
struct GNUNET_SERVICE_Client * next
Kept in a DLL.
Definition: service.c:250
size_t msg_pos
Current position in msg at which we are transmitting.
Definition: service.c:320
void(* GNUNET_SERVICE_DisconnectHandler)(void *cls, struct GNUNET_SERVICE_Client *c, void *internal_cls)
Callback to be called when a client disconnected from the service.
struct GNUNET_SERVICE_Handle * sh
Service this listen context belongs to.
Definition: service.c:66
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:410
#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_SCHEDULER_Task * warn_task
Task that warns about missing calls to GNUNET_SERVICE_client_continue().
Definition: service.c:281
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
Trigger a SOFT server shutdown on signals, allowing active non-monitor clients to complete their tran...
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1264
#define DIR_SEPARATOR_STR
Definition: platform.h:168
FIXME: document!
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.
Handle to a message stream tokenizer.
Definition: mst.c:43
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.
Definition: service.c:464
char * GNUNET_OS_installation_get_path(enum GNUNET_OS_InstallationPathKind dirkind)
Get the path to a specific GNUnet installation directory or, with GNUNET_OS_IPK_SELF_PREFIX, the current running apps installation directory.
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:686
static char * get_pid_file_name(struct GNUNET_SERVICE_Handle *sh)
Get the name of the file where we will write the PID of the service.
Definition: service.c:1674
static char * get_user_name(struct GNUNET_SERVICE_Handle *sh)
Get the name of the user that&#39;ll be used to provide the service.
Definition: service.c:1603
static char * service_name
Option -s: service name (hash to get service descriptor)
Definition: gnunet-vpn.c:51
IPV4 network in CIDR notation.
struct ServiceListenContext * slc_tail
DLL of listen sockets used to accept new connections.
Definition: service.c:153
static void teardown_service(struct GNUNET_SERVICE_Handle *sh)
Tear down the service, closing the listen sockets and freeing the ACLs.
Definition: service.c:1792
void GNUNET_CONFIGURATION_destroy(struct GNUNET_CONFIGURATION_Handle *cfg)
Destroy configuration object.
uint16_t warn_type
Type of last message processed (for warn_no_receive_done).
Definition: service.c:344
static char * option
Name of the option.
Definition: gnunet-config.c:38
static char buf[2048]
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
int persist
Persist the file handle for this client no matter what happens, force the OS to close once the proces...
Definition: service.c:327
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:84
void * task_cls
Closure for task.
Definition: service.c:173
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_loglevel(char **level)
Define the &#39;-L&#39; log level option.
Information the service tracks per listen operation.
Definition: service.c:52
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
GNUNET_SERVICE_ConnectHandler connect_cb
Function to call when clients connect.
Definition: service.c:133
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)...
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the &#39;monitor&#39; flag on this client.
Definition: service.c:2394
void GNUNET_MQ_inject_message(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *mh)
Call the message message handler that was registered for the type of the given message in the given m...
Definition: mq.c:200
static void service_shutdown(void *cls)
Shutdown task triggered when a service should be terminated.
Definition: service.c:403
struct GNUNET_MQ_MessageHandler * GNUNET_MQ_copy_handlers2(const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_MessageCallback agpl_handler, void *agpl_cls)
Copy an array of handlers, appending AGPL handler.
Definition: mq.c:1241
void GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv)
Stops a service that was started with GNUNET_SERVICE_start().
Definition: service.c:1907
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_denied
IPv4 addresses that are not allowed to connect.
Definition: service.c:178
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2315
Message handler for a specific message type.
static int res
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
static struct GNUNET_NETWORK_Handle * open_listen_socket(const struct sockaddr *server_addr, socklen_t socklen)
Create and initialize a listen socket for the server.
Definition: service.c:1365
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.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
struct GNUNET_SCHEDULER_Task * listen_task
Task scheduled to do the listening.
Definition: service.c:76
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 GNUNET_SYSERR
Definition: gnunet_common.h:76
#define GNUNET_MESSAGE_TYPE_RESPONSE_AGPL
Source code link.
char * getenv()
static int process_acl4(struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, struct GNUNET_SERVICE_Handle *sh, const char *option)
Parse an IPv4 access control list.
Definition: service.c:927
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static void do_resume(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
Resume accepting connections from the listen socket.
Definition: service.c:869
static int add
Desired action is to add a record.
static struct GNUNET_NETWORK_Handle * ls
Listen socket for STUN processing.
Definition: gnunet-nat.c:85
#define GNUNET_is_zero(a)
Check that memory in a is all zeros.
#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 struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
#define LOG_STRERROR_FILE(kind, syscall, filename)
Definition: service.c:45
Handle to a message queue.
Definition: mq.c:84
static void warn_no_client_continue(void *cls)
Task run to warn about missing calls to GNUNET_SERVICE_client_continue().
Definition: service.c:641
SuspendReason
Reasons why we might be suspended.
Definition: service.c:83
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_allowed
IPv6 addresses that are allowed to connect (if not set, all are allowed).
Definition: service.c:195
static char * hostname
Our hostname; we give this to all the peers we start.
#define LOG(kind,...)
Definition: service.c:40
int GNUNET_SERVICE_run_(int argc, char *const *argv, const char *service_name, enum GNUNET_SERVICE_Options options, GNUNET_SERVICE_InitCallback service_init_cb, GNUNET_SERVICE_ConnectHandler connect_cb, GNUNET_SERVICE_DisconnectHandler disconnect_cb, void *cls, const struct GNUNET_MQ_MessageHandler *handlers)
Creates the "main" function for a GNUnet service.
Definition: service.c:1962
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
configuration data
Definition: configuration.c:83
static void start_client(struct GNUNET_SERVICE_Handle *sh, struct GNUNET_NETWORK_Handle *csock)
We have successfully accepted a connection from a client.
Definition: service.c:746
static void service_mq_send(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
Signature of functions implementing the sending functionality of a message queue. ...
Definition: service.c:565
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:373
static void service_client_recv(void *cls)
A client sent us data.
Definition: service.c:704
const struct GNUNET_MessageHeader * msg
Pointer to the message to be transmitted by send_task.
Definition: service.c:303
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_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
struct GNUNET_SERVICE_Handle * sh
Service that this client belongs to.
Definition: service.c:260
Entry in list of pending tasks.
Definition: scheduler.c:131
int needs_continue
Are we waiting for the application to call GNUNET_SERVICE_client_continue()?
Definition: service.c:339
int GNUNET_MST_read(struct GNUNET_MessageStreamTokenizer *mst, struct GNUNET_NETWORK_Handle *sock, int purge, int one_shot)
Add incoming data to the receive buffer and call the callback for all complete messages.
Definition: mst.c:344
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_get(void)
#define GNUNET_AGPL_URL
NOTE: You MUST adjust this URL to point to the location of a publicly accessible repository (or TGZ) ...
int ret
Overall success/failure of the service start.
Definition: service.c:233
const char * service_name
Name of our service.
Definition: service.c:123
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.
handle to a socket
Definition: network.c:46
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
Suspension because service was permanently shutdown.
Definition: service.c:107
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_allowed
IPv4 addresses that are allowed to connect (if not set, all are allowed).
Definition: service.c:189
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:821
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1467
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:351
OS ran out of file descriptors.
Definition: service.c:97
struct GNUNET_NETWORK_Handle * sock
Socket of this client.
Definition: service.c:265
int GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
void GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh)
Suspend accepting connections from the listen socket temporarily.
Definition: service.c:2173
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: service.c:118
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
void GNUNET_SERVICE_client_disable_continue_warning(struct GNUNET_SERVICE_Client *c)
Disable the warning the server issues if a message is not acknowledged in a timely fashion...
Definition: service.c:2258
GNUNET_SERVICE_DisconnectHandler disconnect_cb
Function to call when clients disconnect / are disconnected.
Definition: service.c:138
Application requested it.
Definition: service.c:92
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".
#define LOG_STRERROR(kind, syscall)
Definition: service.c:42
static int detach_terminal(struct GNUNET_SERVICE_Handle *sh)
Detach from terminal.
Definition: service.c:1712
void GNUNET_MQ_impl_send_continue(struct GNUNET_MQ_Handle *mq)
Call the send implementation for the next queued message, if any.
Definition: mq.c:484
void(* GNUNET_SERVICE_InitCallback)(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SERVICE_Handle *sh)
Callback to initialize a service, called exactly once when the service is run.
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:219
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2234
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
struct GNUNET_SCHEDULER_Task * recv_task
Task that receives data from the client to pass it to the handlers.
Definition: service.c:293
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.
struct GNUNET_SCHEDULER_Task * drop_task
Task run to finish dropping the client after the stack has properly unwound.
Definition: service.c:287
int GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:78
static int have_non_monitor_clients(struct GNUNET_SERVICE_Handle *sh)
Check if any of the clients we have left are unrelated to monitoring.
Definition: service.c:356
void * cb_cls
Closure for service_init_cb, connect_cb, disconnect_cb.
Definition: service.c:143
void GNUNET_SERVICE_client_persist(struct GNUNET_SERVICE_Client *c)
Set the persist option on this client.
Definition: service.c:2411
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh)
Explicitly stops the service.
Definition: service.c:2370
#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
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
void GNUNET_SPEEDUP_stop_()
Stop tasks that modify clock behavior.
Definition: speedup.c:105