GNUnet  0.11.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 
53 {
58 
63 
68 
73 
78 };
79 
80 
85 {
90 
95 
100 
105 
110 };
111 
112 
117 {
122 
126  const char *service_name;
127 
132 
137 
142 
146  void *cb_cls;
147 
152 
157 
162 
167 
172 
176  void *task_cls;
177 
178 
183 
188 
194 
200 
207 
216 
220  enum SuspendReason suspend_state;
221 
226 
233 
237  int ret;
238 
244 };
245 
246 
251 {
256 
261 
266 
271 
276 
281 
287 
293 
299 
304 
308  const struct GNUNET_MessageHeader *msg;
309 
315 
320  struct GNUNET_TIME_Absolute warn_start;
321 
325  size_t msg_pos;
326 
332  int persist;
333 
340 
345 
349  uint16_t warn_type;
350 };
351 
352 
360 static int
362 {
363  for (struct GNUNET_SERVICE_Client *client = sh->clients_head; NULL != client;
364  client = client->next)
365  {
366  if (client->is_monitor)
367  continue;
368  return GNUNET_YES;
369  }
370  return GNUNET_NO;
371 }
372 
373 
381 static void
383 {
384  struct ServiceListenContext *slc;
385 
386  GNUNET_assert (0 == (sh->suspend_state & sr));
387  sh->suspend_state |= sr;
388  for (slc = sh->slc_head; NULL != slc; slc = slc->next)
389  {
390  if (NULL != slc->listen_task)
391  {
393  slc->listen_task = NULL;
394  }
395  }
396 }
397 
398 
407 static void
408 service_shutdown (void *cls)
409 {
410  struct GNUNET_SERVICE_Handle *sh = cls;
411 
413  {
416  break;
418  /* This task should never be run if we are using
419  the manual shutdown. */
420  GNUNET_assert (0);
421  break;
423  if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN))
427  break;
428  }
429 }
430 
431 
439 static int
441  const struct in_addr *add)
442 {
443  unsigned int i;
444 
445  if (NULL == list)
446  return GNUNET_NO;
447  i = 0;
448  while ((0 != list[i].network.s_addr) || (0 != list[i].netmask.s_addr))
449  {
450  if ((add->s_addr & list[i].netmask.s_addr) ==
451  (list[i].network.s_addr & list[i].netmask.s_addr))
452  return GNUNET_YES;
453  i++;
454  }
455  return GNUNET_NO;
456 }
457 
458 
466 static int
468  const struct in6_addr *ip)
469 {
470  unsigned int i;
471 
472  if (NULL == list)
473  return GNUNET_NO;
474  i = 0;
475 NEXT:
476  while (0 != GNUNET_is_zero (&list[i].network))
477  {
478  for (unsigned int j = 0; j < sizeof(struct in6_addr) / sizeof(int); j++)
479  if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
480  (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
481  {
482  i++;
483  goto NEXT;
484  }
485  return GNUNET_YES;
486  }
487  return GNUNET_NO;
488 }
489 
490 
497 static void
498 do_send (void *cls)
499 {
500  struct GNUNET_SERVICE_Client *client = cls;
501  ssize_t ret;
502  size_t left;
503  const char *buf;
504 
506  "service: sending message with type %u\n",
507  ntohs (client->msg->type));
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,
512  &buf[client->msg_pos],
513  left);
514  GNUNET_assert (ret <= (ssize_t) left);
515  if (0 == ret)
516  {
517  LOG (GNUNET_ERROR_TYPE_DEBUG, "no data send");
519  return;
520  }
521  if (-1 == ret)
522  {
523  if ((EAGAIN == errno) || (EINTR == errno))
524  {
525  /* ignore */
526  ret = 0;
527  }
528  else
529  {
530  if (EPIPE != errno)
533  "socket send returned with error code %i",
534  errno);
536  return;
537  }
538  }
539  if (0 == client->msg_pos)
540  {
542  }
543  client->msg_pos += ret;
544  if (left > (size_t) ret)
545  {
546  GNUNET_assert (NULL == client->drop_task);
547  client->send_task =
549  client->sock,
550  &do_send,
551  client);
552  return;
553  }
555 }
556 
557 
566 static void
568  const struct GNUNET_MessageHeader *msg,
569  void *impl_state)
570 {
571  struct GNUNET_SERVICE_Client *client = impl_state;
572 
573  (void) mq;
574  if (NULL != client->drop_task)
575  return; /* we're going down right now, do not try to send */
576  GNUNET_assert (NULL == client->send_task);
578  "Sending message of type %u and size %u to client\n",
579  ntohs (msg->type),
580  ntohs (msg->size));
581  client->msg = msg;
582  client->msg_pos = 0;
584  client);
585 }
586 
587 
594 static void
595 service_mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
596 {
597  struct GNUNET_SERVICE_Client *client = impl_state;
598 
599  (void) mq;
600  GNUNET_assert (0 == client->msg_pos);
601  client->msg = NULL;
603  client->send_task = NULL;
604 }
605 
606 
616 static void
618 {
619  struct GNUNET_SERVICE_Client *client = cls;
620  struct GNUNET_SERVICE_Handle *sh = client->sh;
621 
622  if ((GNUNET_MQ_ERROR_NO_MATCH == error) && (GNUNET_NO == sh->require_found))
623  {
625  "No handler for message of type %u found\n",
626  (unsigned int) client->warn_type);
628  return; /* ignore error */
629  }
631 }
632 
633 
639 static void
641 {
642  struct GNUNET_SERVICE_Client *client = cls;
643 
644  GNUNET_break (
645  0 !=
646  client->warn_type); /* type should never be 0 here, as we don't use 0 */
649  client);
650  LOG (
652  _ (
653  "Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"),
654  (unsigned int) client->warn_type,
656  client->warn_start),
657  GNUNET_YES));
658 }
659 
660 
672 static int
673 service_client_mst_cb (void *cls, const struct GNUNET_MessageHeader *message)
674 {
675  struct GNUNET_SERVICE_Client *client = cls;
676 
678  "Received message of type %u and size %u from client\n",
679  ntohs (message->type),
680  ntohs (message->size));
682  client->needs_continue = GNUNET_YES;
683  client->warn_type = ntohs (message->type);
685  GNUNET_assert (NULL == client->warn_task);
688  client);
689  GNUNET_MQ_inject_message (client->mq, message);
690  if (NULL != client->drop_task)
691  return GNUNET_SYSERR;
692  return GNUNET_OK;
693 }
694 
695 
702 static void
704 {
705  struct GNUNET_SERVICE_Client *client = cls;
706  int ret;
707 
708  client->recv_task = NULL;
709  ret = GNUNET_MST_read (client->mst, client->sock, GNUNET_NO, GNUNET_YES);
710  if (GNUNET_SYSERR == ret)
711  {
712  /* client closed connection (or IO error) */
713  if (NULL == client->drop_task)
714  {
717  }
718  return;
719  }
720  if (GNUNET_NO == ret)
721  return; /* more messages in buffer, wait for application
722  to be done processing */
723  GNUNET_assert (GNUNET_OK == ret);
724  if (GNUNET_YES == client->needs_continue)
725  return;
726  if (NULL != client->recv_task)
727  return;
728  /* MST needs more data, re-schedule read job */
729  client->recv_task =
731  client->sock,
733  client);
734 }
735 
736 
744 static void
746  struct GNUNET_NETWORK_Handle *csock)
747 {
748  struct GNUNET_SERVICE_Client *client;
749 
750  client = GNUNET_new (struct GNUNET_SERVICE_Client);
752  client->sh = sh;
753  client->sock = csock;
755  NULL,
757  client,
758  sh->handlers,
760  client);
761  client->mst = GNUNET_MST_create (&service_client_mst_cb, client);
762  if (NULL != sh->connect_cb)
763  client->user_context = sh->connect_cb (sh->cb_cls, client, client->mq);
765  client->recv_task =
767  client->sock,
769  client);
770 }
771 
772 
779 static void
780 accept_client (void *cls)
781 {
782  struct ServiceListenContext *slc = cls;
783  struct GNUNET_SERVICE_Handle *sh = slc->sh;
784 
785  slc->listen_task = NULL;
786  while (1)
787  {
788  struct GNUNET_NETWORK_Handle *sock;
789  const struct sockaddr_in *v4;
790  const struct sockaddr_in6 *v6;
791  struct sockaddr_storage sa;
792  socklen_t addrlen;
793  int ok;
794 
795  addrlen = sizeof(sa);
797  (struct sockaddr *) &sa,
798  &addrlen);
799  if (NULL == sock)
800  {
801  if (EMFILE == errno)
803  else if (EAGAIN != errno)
805  break;
806  }
807  switch (sa.ss_family)
808  {
809  case AF_INET:
810  GNUNET_assert (addrlen == sizeof(struct sockaddr_in));
811  v4 = (const struct sockaddr_in *) &sa;
812  ok = (((NULL == sh->v4_allowed) ||
813  (check_ipv4_listed (sh->v4_allowed, &v4->sin_addr))) &&
814  ((NULL == sh->v4_denied) ||
815  (! check_ipv4_listed (sh->v4_denied, &v4->sin_addr))));
816  break;
817 
818  case AF_INET6:
819  GNUNET_assert (addrlen == sizeof(struct sockaddr_in6));
820  v6 = (const struct sockaddr_in6 *) &sa;
821  ok = (((NULL == sh->v6_allowed) ||
822  (check_ipv6_listed (sh->v6_allowed, &v6->sin6_addr))) &&
823  ((NULL == sh->v6_denied) ||
824  (! check_ipv6_listed (sh->v6_denied, &v6->sin6_addr))));
825  break;
826 
827  case AF_UNIX:
828  ok = GNUNET_OK; /* controlled using file-system ACL now */
829  break;
830 
831  default:
833  _ ("Unknown address family %d\n"),
834  sa.ss_family);
835  return;
836  }
837  if (! ok)
838  {
840  "Service rejected incoming connection from %s due to policy.\n",
841  GNUNET_a2s ((const struct sockaddr *) &sa, addrlen));
843  continue;
844  }
846  "Service accepted incoming connection from %s.\n",
847  GNUNET_a2s ((const struct sockaddr *) &sa, addrlen));
848  start_client (slc->sh, sock);
849  }
850  if (0 != sh->suspend_state)
851  return;
852  slc->listen_task =
854  slc->listen_socket,
855  &accept_client,
856  slc);
857 }
858 
859 
867 static void
869 {
870  struct ServiceListenContext *slc;
871 
872  GNUNET_assert ((SUSPEND_STATE_NONE == sr) || (0 != (sh->suspend_state & sr)));
873  sh->suspend_state -= sr;
875  return;
876  for (slc = sh->slc_head; NULL != slc; slc = slc->next)
877  {
878  GNUNET_assert (NULL == slc->listen_task);
879  slc->listen_task =
881  slc->listen_socket,
882  &accept_client,
883  slc);
884  }
885 }
886 
887 
895 static void
896 service_main (void *cls)
897 {
898  struct GNUNET_SERVICE_Handle *sh = cls;
899 
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 
1007 static void
1008 add_unixpath (struct sockaddr **saddrs,
1009  socklen_t *saddrlens,
1010  const char *unixpath)
1011 {
1012 #ifdef AF_UNIX
1013  struct sockaddr_un *un;
1014 
1015  un = GNUNET_new (struct sockaddr_un);
1016  un->sun_family = AF_UNIX;
1017  GNUNET_strlcpy (un->sun_path, unixpath, sizeof(un->sun_path));
1018 #if HAVE_SOCKADDR_UN_SUN_LEN
1019  un->sun_len = (u_char) sizeof(struct sockaddr_un);
1020 #endif
1021  *saddrs = (struct sockaddr *) un;
1022  *saddrlens = sizeof(struct sockaddr_un);
1023 #else
1024  /* this function should never be called
1025  * unless AF_UNIX is defined! */
1026  GNUNET_assert (0);
1027 #endif
1028 }
1029 
1030 
1051 static int
1053  const struct GNUNET_CONFIGURATION_Handle *cfg,
1054  struct sockaddr ***addrs,
1055  socklen_t **addr_lens)
1056 {
1057  int disablev6;
1058  struct GNUNET_NETWORK_Handle *desc;
1059  unsigned long long port;
1060  char *unixpath;
1061  struct addrinfo hints;
1062  struct addrinfo *res;
1063  struct addrinfo *pos;
1064  struct addrinfo *next;
1065  unsigned int i;
1066  int resi;
1067  int ret;
1068  struct sockaddr **saddrs;
1069  socklen_t *saddrlens;
1070  char *hostname;
1071 
1072  *addrs = NULL;
1073  *addr_lens = NULL;
1074  desc = NULL;
1075  disablev6 = GNUNET_NO;
1076  if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
1077  (GNUNET_YES ==
1078  GNUNET_CONFIGURATION_get_value_yesno (cfg, service_name, "DISABLEV6")))
1079  disablev6 = GNUNET_YES;
1080 
1081  port = 0;
1082  if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT"))
1083  {
1085  service_name,
1086  "PORT",
1087  &port))
1088  {
1090  _ ("Require valid port number for service `%s' in configuration!\n"),
1091  service_name);
1092  }
1093  if (port > 65535)
1094  {
1096  _ ("Require valid port number for service `%s' in configuration!\n"),
1097  service_name);
1098  return GNUNET_SYSERR;
1099  }
1100  }
1101 
1102  if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO"))
1103  {
1106  service_name,
1107  "BINDTO",
1108  &hostname));
1109  }
1110  else
1111  hostname = NULL;
1112 
1113  unixpath = NULL;
1114 #ifdef AF_UNIX
1115  if ((GNUNET_YES ==
1116  GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) &&
1118  service_name,
1119  "UNIXPATH",
1120  &unixpath)) &&
1121  (0 < strlen (unixpath)))
1122  {
1123  /* probe UNIX support */
1124  struct sockaddr_un s_un;
1125 
1126  if (strlen (unixpath) >= sizeof(s_un.sun_path))
1127  {
1129  _ ("UNIXPATH `%s' too long, maximum length is %llu\n"),
1130  unixpath,
1131  (unsigned long long) sizeof(s_un.sun_path));
1132  unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
1133  LOG (GNUNET_ERROR_TYPE_INFO, _ ("Using `%s' instead\n"), unixpath);
1134  }
1137  }
1138  if (NULL != unixpath)
1139  {
1140  desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
1141  if (NULL == desc)
1142  {
1143  if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
1144  (EACCES == errno))
1145  {
1147  GNUNET_free_non_null (hostname);
1148  GNUNET_free (unixpath);
1149  return GNUNET_SYSERR;
1150  }
1152  _ (
1153  "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
1154  service_name,
1155  strerror (errno));
1156  GNUNET_free (unixpath);
1157  unixpath = NULL;
1158  }
1159  else
1160  {
1162  desc = NULL;
1163  }
1164  }
1165 #endif
1166 
1167  if ((0 == port) && (NULL == unixpath))
1168  {
1170  _ (
1171  "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
1172  service_name);
1173  GNUNET_free_non_null (hostname);
1174  return GNUNET_SYSERR;
1175  }
1176  if (0 == port)
1177  {
1178  saddrs = GNUNET_new_array (2, struct sockaddr *);
1179  saddrlens = GNUNET_new_array (2, socklen_t);
1180  add_unixpath (saddrs, saddrlens, unixpath);
1181  GNUNET_free_non_null (unixpath);
1182  GNUNET_free_non_null (hostname);
1183  *addrs = saddrs;
1184  *addr_lens = saddrlens;
1185  return 1;
1186  }
1187 
1188  if (NULL != hostname)
1189  {
1191  "Resolving `%s' since that is where `%s' will bind to.\n",
1192  hostname,
1193  service_name);
1194  memset (&hints, 0, sizeof(struct addrinfo));
1195  if (disablev6)
1196  hints.ai_family = AF_INET;
1197  hints.ai_protocol = IPPROTO_TCP;
1198  if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
1199  (NULL == res))
1200  {
1202  _ ("Failed to resolve `%s': %s\n"),
1203  hostname,
1204  gai_strerror (ret));
1205  GNUNET_free (hostname);
1206  GNUNET_free_non_null (unixpath);
1207  return GNUNET_SYSERR;
1208  }
1209  next = res;
1210  i = 0;
1211  while (NULL != (pos = next))
1212  {
1213  next = pos->ai_next;
1214  if ((disablev6) && (pos->ai_family == AF_INET6))
1215  continue;
1216  i++;
1217  }
1218  if (0 == i)
1219  {
1221  _ ("Failed to find %saddress for `%s'.\n"),
1222  disablev6 ? "IPv4 " : "",
1223  hostname);
1224  freeaddrinfo (res);
1225  GNUNET_free (hostname);
1226  GNUNET_free_non_null (unixpath);
1227  return GNUNET_SYSERR;
1228  }
1229  resi = i;
1230  if (NULL != unixpath)
1231  resi++;
1232  saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
1233  saddrlens = GNUNET_new_array (resi + 1, socklen_t);
1234  i = 0;
1235  if (NULL != unixpath)
1236  {
1237  add_unixpath (saddrs, saddrlens, unixpath);
1238  i++;
1239  }
1240  next = res;
1241  while (NULL != (pos = next))
1242  {
1243  next = pos->ai_next;
1244  if ((disablev6) && (AF_INET6 == pos->ai_family))
1245  continue;
1246  if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
1247  continue; /* not TCP */
1248  if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
1249  continue; /* huh? */
1251  "Service `%s' will bind to `%s'\n",
1252  service_name,
1253  GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
1254  if (AF_INET == pos->ai_family)
1255  {
1256  GNUNET_assert (sizeof(struct sockaddr_in) == pos->ai_addrlen);
1257  saddrlens[i] = pos->ai_addrlen;
1258  saddrs[i] = GNUNET_malloc (saddrlens[i]);
1259  GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
1260  ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1261  }
1262  else
1263  {
1264  GNUNET_assert (AF_INET6 == pos->ai_family);
1265  GNUNET_assert (sizeof(struct sockaddr_in6) == pos->ai_addrlen);
1266  saddrlens[i] = pos->ai_addrlen;
1267  saddrs[i] = GNUNET_malloc (saddrlens[i]);
1268  GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
1269  ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
1270  }
1271  i++;
1272  }
1273  GNUNET_free (hostname);
1274  freeaddrinfo (res);
1275  resi = i;
1276  }
1277  else
1278  {
1279  /* will bind against everything, just set port */
1280  if (disablev6)
1281  {
1282  /* V4-only */
1283  resi = 1;
1284  if (NULL != unixpath)
1285  resi++;
1286  i = 0;
1287  saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
1288  saddrlens = GNUNET_new_array (resi + 1, socklen_t);
1289  if (NULL != unixpath)
1290  {
1291  add_unixpath (saddrs, saddrlens, unixpath);
1292  i++;
1293  }
1294  saddrlens[i] = sizeof(struct sockaddr_in);
1295  saddrs[i] = GNUNET_malloc (saddrlens[i]);
1296 #if HAVE_SOCKADDR_IN_SIN_LEN
1297  ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
1298 #endif
1299  ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
1300  ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1301  }
1302  else
1303  {
1304  /* dual stack */
1305  resi = 2;
1306  if (NULL != unixpath)
1307  resi++;
1308  saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
1309  saddrlens = GNUNET_new_array (resi + 1, socklen_t);
1310  i = 0;
1311  if (NULL != unixpath)
1312  {
1313  add_unixpath (saddrs, saddrlens, unixpath);
1314  i++;
1315  }
1316  saddrlens[i] = sizeof(struct sockaddr_in6);
1317  saddrs[i] = GNUNET_malloc (saddrlens[i]);
1318 #if HAVE_SOCKADDR_IN_SIN_LEN
1319  ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
1320 #endif
1321  ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
1322  ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
1323  i++;
1324  saddrlens[i] = sizeof(struct sockaddr_in);
1325  saddrs[i] = GNUNET_malloc (saddrlens[i]);
1326 #if HAVE_SOCKADDR_IN_SIN_LEN
1327  ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
1328 #endif
1329  ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
1330  ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1331  }
1332  }
1333  GNUNET_free_non_null (unixpath);
1334  *addrs = saddrs;
1335  *addr_lens = saddrlens;
1336  return resi;
1337 }
1338 
1339 
1347 static struct GNUNET_NETWORK_Handle *
1348 open_listen_socket (const struct sockaddr *server_addr,
1349  socklen_t socklen)
1350 {
1351  struct GNUNET_NETWORK_Handle *sock;
1352  uint16_t port;
1353  int eno;
1354 
1355  switch (server_addr->sa_family)
1356  {
1357  case AF_INET:
1358  port = ntohs (((const struct sockaddr_in *) server_addr)->sin_port);
1359  break;
1360  case AF_INET6:
1361  port = ntohs (((const struct sockaddr_in6 *) server_addr)->sin6_port);
1362  break;
1363  case AF_UNIX:
1364  port = 0;
1365  break;
1366  default:
1367  GNUNET_break (0);
1368  port = 0;
1369  break;
1370  }
1371  sock = GNUNET_NETWORK_socket_create (server_addr->sa_family,
1372  SOCK_STREAM,
1373  0);
1374  if (NULL == sock)
1375  {
1377  "socket");
1378  errno = 0;
1379  return NULL;
1380  }
1381  /* bind the socket */
1382  if (GNUNET_OK !=
1384  server_addr,
1385  socklen))
1386  {
1387  eno = errno;
1388  if (EADDRINUSE != errno)
1389  {
1390  /* we don't log 'EADDRINUSE' here since an IPv4 bind may
1391  * fail if we already took the port on IPv6; if both IPv4 and
1392  * IPv6 binds fail, then our caller will log using the
1393  * errno preserved in 'eno' */
1394  if (0 != port)
1396  _ ("`%s' failed for port %d (%s).\n"),
1397  "bind",
1398  port,
1399  (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1400  else
1402  eno = 0;
1403  }
1404  else
1405  {
1406  if (0 != port)
1408  _ ("`%s' failed for port %d (%s): address already in use\n"),
1409  "bind",
1410  port,
1411  (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1412  else if (AF_UNIX == server_addr->sa_family)
1413  {
1415  _ ("`%s' failed for `%s': address already in use\n"),
1416  "bind",
1417  GNUNET_a2s (server_addr, socklen));
1418  }
1419  }
1421  errno = eno;
1422  return NULL;
1423  }
1424  if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5))
1425  {
1428  errno = 0;
1429  return NULL;
1430  }
1431  if (0 != port)
1433  "Server starts to listen on port %u.\n",
1434  port);
1435  return sock;
1436 }
1437 
1438 
1455 static int
1457 {
1458  int tolerant;
1459  struct GNUNET_NETWORK_Handle **csocks = NULL;
1460  struct GNUNET_NETWORK_Handle **lsocks;
1461  const char *nfds;
1462  unsigned int cnt;
1463  int flags;
1464  char dummy[2];
1465 
1467  sh->service_name,
1468  "TOLERANT"))
1469  {
1470  if (GNUNET_SYSERR ==
1471  (tolerant = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
1472  sh->service_name,
1473  "TOLERANT")))
1474  {
1476  _ ("Specified value for `%s' of service `%s' is invalid\n"),
1477  "TOLERANT",
1478  sh->service_name);
1479  return GNUNET_SYSERR;
1480  }
1481  }
1482  else
1483  tolerant = GNUNET_NO;
1484 
1485  lsocks = NULL;
1486  errno = 0;
1487  if ((NULL != (nfds = getenv ("LISTEN_FDS"))) &&
1488  (1 == sscanf (nfds, "%u%1s", &cnt, dummy)) && (cnt > 0) &&
1489  (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE))
1490  {
1491  lsocks = GNUNET_new_array (cnt + 1, struct GNUNET_NETWORK_Handle *);
1492  while (0 < cnt--)
1493  {
1494  flags = fcntl (3 + cnt, F_GETFD);
1495  if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) ||
1496  (NULL == (lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt))))
1497  {
1499  _ (
1500  "Could not access pre-bound socket %u, will try to bind myself\n"),
1501  (unsigned int) 3 + cnt);
1502  cnt++;
1503  while (NULL != lsocks[cnt])
1505  GNUNET_NETWORK_socket_close (lsocks[cnt++]));
1506  GNUNET_free (lsocks);
1507  lsocks = NULL;
1508  break;
1509  }
1510  }
1511  unsetenv ("LISTEN_FDS");
1512  }
1513  if ( (0 != (GNUNET_SERVICE_OPTION_CLOSE_LSOCKS & sh->options)) &&
1514  (NULL != lsocks) )
1515  {
1516  csocks = lsocks;
1517  lsocks = NULL;
1518  }
1519 
1520  if (NULL != lsocks)
1521  {
1522  /* listen only on inherited sockets if we have any */
1523  for (struct GNUNET_NETWORK_Handle **ls = lsocks; NULL != *ls; ls++)
1524  {
1525  struct ServiceListenContext *slc;
1526 
1527  slc = GNUNET_new (struct ServiceListenContext);
1528  slc->sh = sh;
1529  slc->listen_socket = *ls;
1531  }
1532  GNUNET_free (lsocks);
1533  }
1534  else
1535  {
1536  struct sockaddr **addrs;
1537  socklen_t *addrlens;
1538  int num;
1539 
1540  num = get_server_addresses (sh->service_name, sh->cfg, &addrs, &addrlens);
1541  if (GNUNET_SYSERR == num)
1542  return GNUNET_SYSERR;
1543 
1544  for (int i = 0; i < num; i++)
1545  {
1546  struct ServiceListenContext *slc;
1547 
1548  slc = GNUNET_new (struct ServiceListenContext);
1549  slc->sh = sh;
1550  slc->listen_socket = open_listen_socket (addrs[i], addrlens[i]);
1551  GNUNET_free (addrs[i]);
1552  if (NULL == slc->listen_socket)
1553  {
1555  GNUNET_free (slc);
1556  continue;
1557  }
1559  }
1560  GNUNET_free_non_null (addrlens);
1561  GNUNET_free_non_null (addrs);
1562  if ((0 != num) && (NULL == sh->slc_head))
1563  {
1564  /* All attempts to bind failed, hard failure */
1565  GNUNET_log (
1567  _ (
1568  "Could not bind to any of the ports I was supposed to, refusing to run!\n"));
1569  GNUNET_free_non_null (csocks);
1570  return GNUNET_SYSERR;
1571  }
1572  }
1573  if (NULL != csocks)
1574  {
1575  /* close inherited sockets to signal parent that we are ready */
1576  for (struct GNUNET_NETWORK_Handle **ls = csocks; NULL != *ls; ls++)
1578  GNUNET_free (csocks);
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 
1911  GNUNET_SERVICE_suspend (srv);
1912  while (NULL != (client = srv->clients_head))
1913  GNUNET_SERVICE_client_drop (client);
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;
1989  const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get ();
1990  struct GNUNET_GETOPT_CommandLineOption service_options[] = {
1991  GNUNET_GETOPT_option_cfgfile (&opt_cfg_filename),
1993  "daemonize",
1994  gettext_noop (
1995  "do daemonize (detach from terminal)"),
1996  &do_daemonize),
1999  GNUNET_GETOPT_option_logfile (&logfile),
2002  };
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  }
2042  textdomain (pd->gettext_domain);
2043  }
2044 #endif
2045  ret = GNUNET_GETOPT_run (service_name,
2046  service_options,
2047  argc,
2048  argv);
2049  if (GNUNET_SYSERR == ret)
2050  goto shutdown;
2051  if (GNUNET_NO == ret)
2052  {
2053  err = 0;
2054  goto shutdown;
2055  }
2056  if (GNUNET_OK != GNUNET_log_setup (service_name,
2057  loglev,
2058  logfile))
2059  {
2060  GNUNET_break (0);
2061  goto shutdown;
2062  }
2063  if (NULL != opt_cfg_filename)
2064  {
2065  if ((GNUNET_YES != GNUNET_DISK_file_test (opt_cfg_filename)) ||
2066  (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_filename)))
2067  {
2069  _ ("Malformed configuration file `%s', exit ...\n"),
2070  opt_cfg_filename);
2071  goto shutdown;
2072  }
2073  }
2074  else
2075  {
2076  if (GNUNET_YES == GNUNET_DISK_file_test (cfg_filename))
2077  {
2078  if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cfg_filename))
2079  {
2081  _ ("Malformed configuration file `%s', exit ...\n"),
2082  cfg_filename);
2083  goto shutdown;
2084  }
2085  }
2086  else
2087  {
2088  if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL))
2089  {
2091  _ ("Malformed configuration, exit ...\n"));
2092  goto shutdown;
2093  }
2094  }
2095  }
2096  if (GNUNET_OK != setup_service (&sh))
2097  goto shutdown;
2098  if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sh)))
2099  {
2100  GNUNET_break (0);
2101  goto shutdown;
2102  }
2103  if (GNUNET_OK != set_user_id (&sh))
2104  goto shutdown;
2106  "Service `%s' runs with configuration from `%s'\n",
2107  service_name,
2108  (NULL != opt_cfg_filename) ? opt_cfg_filename : cfg_filename);
2110  "TESTING",
2111  "SKEW_OFFSET",
2112  &skew_offset)) &&
2114  "TESTING",
2115  "SKEW_VARIANCE",
2116  &skew_variance)))
2117  {
2118  clock_offset = skew_offset - skew_variance;
2119  GNUNET_TIME_set_offset (clock_offset);
2120  LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset);
2121  }
2123 
2124  /* actually run service */
2125  err = 0;
2127  /* shutdown */
2128  if (1 == do_daemonize)
2129  pid_file_delete (&sh);
2130 
2131 shutdown:
2132  if (-1 != sh.ready_confirm_fd)
2133  {
2134  if (1 != write (sh.ready_confirm_fd, err ? "I" : "S", 1))
2136  GNUNET_break (0 == close (sh.ready_confirm_fd));
2137  }
2138 #if HAVE_MALLINFO
2139  {
2140  char *counter;
2141 
2143  service_name,
2144  "GAUGER_HEAP")) &&
2146  service_name,
2147  "GAUGER_HEAP",
2148  &counter)))
2149  {
2150  struct mallinfo mi;
2151 
2152  mi = mallinfo ();
2153  GAUGER (service_name, counter, mi.usmblks, "blocks");
2154  GNUNET_free (counter);
2155  }
2156  }
2157 #endif
2158  teardown_service (&sh);
2162  GNUNET_free_non_null (logfile);
2163  GNUNET_free_non_null (loglev);
2164  GNUNET_free (cfg_filename);
2165  GNUNET_free_non_null (opt_cfg_filename);
2166 
2167  return err ? GNUNET_SYSERR : sh.ret;
2168 }
2169 
2170 
2177 void
2179 {
2181 }
2182 
2183 
2189 void
2191 {
2193 }
2194 
2195 
2202 static void
2204 {
2205  struct GNUNET_SERVICE_Client *c = cls;
2206  int ret;
2207 
2208  c->recv_task = NULL;
2209  /* first, check if there is still something in the buffer */
2210  ret = GNUNET_MST_next (c->mst, GNUNET_YES);
2211  if (GNUNET_SYSERR == ret)
2212  {
2213  if (NULL == c->drop_task)
2215  return;
2216  }
2217  if (GNUNET_NO == ret)
2218  return; /* done processing, wait for more later */
2219  GNUNET_assert (GNUNET_OK == ret);
2220  if (GNUNET_YES == c->needs_continue)
2221  return; /* #GNUNET_MST_next() did give a message to the client */
2222  /* need to receive more data from the network first */
2223  if (NULL != c->recv_task)
2224  return;
2226  c->sock,
2228  c);
2229 }
2230 
2231 
2238 void
2240 {
2241  GNUNET_assert (NULL == c->drop_task);
2243  GNUNET_assert (NULL == c->recv_task);
2245  if (NULL != c->warn_task)
2246  {
2248  c->warn_task = NULL;
2249  }
2251 }
2252 
2253 
2262 void
2264 {
2265  GNUNET_break (NULL != c->warn_task);
2266  if (NULL != c->warn_task)
2267  {
2269  c->warn_task = NULL;
2270  }
2271 }
2272 
2273 
2279 static void
2281 {
2282  struct GNUNET_SERVICE_Client *c = cls;
2283  struct GNUNET_SERVICE_Handle *sh = c->sh;
2284 
2285  c->drop_task = NULL;
2286  GNUNET_assert (NULL == c->send_task);
2287  GNUNET_assert (NULL == c->recv_task);
2288  GNUNET_assert (NULL == c->warn_task);
2289  GNUNET_MST_destroy (c->mst);
2290  GNUNET_MQ_destroy (c->mq);
2291  if (GNUNET_NO == c->persist)
2292  {
2294  if ((0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) &&
2295  (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)))
2297  }
2298  else
2299  {
2301  }
2302  GNUNET_free (c);
2303  if ((0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) &&
2306 }
2307 
2308 
2319 void
2321 {
2322  struct GNUNET_SERVICE_Handle *sh = c->sh;
2323 
2325  "Client dropped: %p (MQ: %p)\n",
2326  c,
2327  c->mq);
2328 #if EXECINFO
2329  {
2330  void *backtrace_array[MAX_TRACE_DEPTH];
2331  int num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH);
2332  char **backtrace_strings =
2333  backtrace_symbols (backtrace_array, t->num_backtrace_strings);
2334  for (unsigned int i = 0; i < num_backtrace_strings; i++)
2336  "client drop trace %u: %s\n",
2337  i,
2338  backtrace_strings[i]);
2339  }
2340 #endif
2341  if (NULL != c->drop_task)
2342  {
2343  /* asked to drop twice! */
2344  GNUNET_assert (0);
2345  return;
2346  }
2348  sh->clients_tail,
2349  c);
2350  if (NULL != sh->disconnect_cb)
2351  sh->disconnect_cb (sh->cb_cls,
2352  c,
2353  c->user_context);
2354  if (NULL != c->warn_task)
2355  {
2357  c->warn_task = NULL;
2358  }
2359  if (NULL != c->recv_task)
2360  {
2362  c->recv_task = NULL;
2363  }
2364  if (NULL != c->send_task)
2365  {
2367  c->send_task = NULL;
2368  }
2370 }
2371 
2372 
2378 void
2380 {
2381  struct GNUNET_SERVICE_Client *client;
2382 
2383  if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN))
2385  while (NULL != (client = sh->clients_head))
2386  GNUNET_SERVICE_client_drop (client);
2387 }
2388 
2389 
2402 void
2404 {
2405  c->is_monitor = GNUNET_YES;
2406  if (((0 != (SUSPEND_STATE_SHUTDOWN & c->sh->suspend_state)) &&
2409 }
2410 
2411 
2419 void
2421 {
2422  c->persist = GNUNET_YES;
2423 }
2424 
2425 
2432 struct GNUNET_MQ_Handle *
2434 {
2435  return c->mq;
2436 }
2437 
2438 
2439 /* end of service.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:595
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:708
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:544
struct GNUNET_STRINGS_IPv4NetworkPolicy * GNUNET_STRINGS_parse_ipv4_policy(const char *routeListX)
Parse an IPv4 network policy.
Definition: strings.c:1537
struct ServiceListenContext * slc_head
DLL of listen sockets used to accept new connections.
Definition: service.c:151
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:2203
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:1052
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:206
struct ServiceListenContext * prev
Kept in a DLL.
Definition: service.c:62
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
enum SuspendReason suspend_state
Are we suspended, and if so, why?
Definition: service.c:220
char * gettext_domain
Gettext domain for localisation, e.g.
struct GNUNET_MQ_MessageHandler * handlers
Message handlers to use for all clients.
Definition: service.c:171
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.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
struct GNUNET_SERVICE_Client * clients_head
Our clients, kept in a DLL.
Definition: service.c:161
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:339
struct GNUNET_SERVICE_Client * clients_tail
Our clients, kept in a DLL.
Definition: service.c:166
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:300
GNUNET_SERVICE_InitCallback service_init_cb
Main service-specific task to run.
Definition: service.c:131
#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:816
struct GNUNET_SCHEDULER_Task * send_task
Task that transmit data to the client.
Definition: service.c:303
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:2190
int match_gid
Do we require a matching GID for UNIX domain socket connections? Ignored if match_uid is GNUNET_YES...
Definition: service.c:215
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
Handle to a service.
Definition: service.c:116
Bitmask over the shutdown options.
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:440
struct ServiceListenContext * next
Kept in a DLL.
Definition: service.c:57
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:2433
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:1333
static int setup_service(struct GNUNET_SERVICE_Handle *sh)
Setup service handle.
Definition: service.c:1456
#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:1729
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:780
static void do_suspend(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
Suspend accepting connections from the listen socket temporarily.
Definition: service.c:382
#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:1227
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:243
Both reasons, APP and EMFILE apply.
Definition: service.c:104
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:485
struct GNUNET_SERVICE_Client * prev
Kept in a DLL.
Definition: service.c:260
struct GNUNET_NETWORK_Handle * listen_socket
Socket we are listening on.
Definition: service.c:72
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:394
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:1590
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.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
void GNUNET_SCHEDULER_run(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Initialize and run scheduler.
Definition: scheduler.c:722
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:684
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 bindtextdomain(Domainname, Dirname)
Definition: gettext.h:57
enum GNUNET_SERVICE_Options options
Our options.
Definition: service.c:225
#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:896
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:187
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
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct GNUNET_MQ_Handle * mq
Message queue for the client.
Definition: service.c:275
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:89
#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:673
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:280
int GNUNET_CONFIGURATION_load(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Load configuration.
#define _(String)
GNU gettext support macro.
Definition: platform.h:180
static void do_send(void *cls)
Task run when we are ready to transmit data to the client.
Definition: service.c:498
Handle to a client that is connected to a service.
Definition: service.c:250
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:622
#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:617
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:430
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:592
int ready_confirm_fd
If we are daemonizing, this FD is set to the pipe to the parent.
Definition: service.c:232
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:314
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:528
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:320
static void finish_client_drop(void *cls)
Asynchronously finish dropping the client.
Definition: service.c:2280
#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:1271
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:561
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:255
size_t msg_pos
Current position in msg at which we are transmitting.
Definition: service.c:325
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:67
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:411
#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:286
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:1298
#define DIR_SEPARATOR_STR
Definition: platform.h:167
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:467
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:701
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:156
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:349
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:332
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:85
void * task_cls
Closure for task.
Definition: service.c:176
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:136
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:2403
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:202
static void service_shutdown(void *cls)
Shutdown task triggered when a service should be terminated.
Definition: service.c:408
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:1257
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:182
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2320
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:1348
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.
struct GNUNET_SCHEDULER_Task * listen_task
Task scheduled to do the listening.
Definition: service.c:77
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:892
Instead of listening on lsocks passed by the parent, close them after opening our own listen socket(s...
#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:868
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:85
static void warn_no_client_continue(void *cls)
Task run to warn about missing calls to GNUNET_SERVICE_client_continue().
Definition: service.c:640
SuspendReason
Reasons why we might be suspended.
Definition: service.c:84
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_allowed
IPv6 addresses that are allowed to connect (if not set, all are allowed).
Definition: service.c:199
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:84
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:745
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:567
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:375
static void service_client_recv(void *cls)
A client sent us data.
Definition: service.c:703
const struct GNUNET_MessageHeader * msg
Pointer to the message to be transmitted by send_task.
Definition: service.c:308
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:265
Entry in list of pending tasks.
Definition: scheduler.c:134
int needs_continue
Are we waiting for the application to call GNUNET_SERVICE_client_continue()?
Definition: service.c:344
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:345
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:237
const char * service_name
Name of our service.
Definition: service.c:126
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:52
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:158
Suspension because service was permanently shutdown.
Definition: service.c:109
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_allowed
IPv4 addresses that are allowed to connect (if not set, all are allowed).
Definition: service.c:193
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:833
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:1519
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:355
OS ran out of file descriptors.
Definition: service.c:99
struct GNUNET_NETWORK_Handle * sock
Socket of this client.
Definition: service.c:270
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:2178
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: service.c:121
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_box_native(int fd)
Box a native socket (and check that it is a socket).
Definition: network.c:636
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:2263
GNUNET_SERVICE_DisconnectHandler disconnect_cb
Function to call when clients disconnect / are disconnected.
Definition: service.c:141
Application requested it.
Definition: service.c:94
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 void add_unixpath(struct sockaddr **saddrs, socklen_t *saddrlens, const char *unixpath)
Add the given UNIX domain path as an address to the list (as the first entry).
Definition: service.c:1008
#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:495
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:220
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2239
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:560
static int list
Set if we should print a list of currently running services.
Definition: gnunet-arm.c:69
struct GNUNET_SCHEDULER_Task * recv_task
Task that receives data from the client to pass it to the handlers.
Definition: service.c:298
void GNUNET_RESOLVER_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create the connection to the resolver service.
Definition: resolver_api.c:257
#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:292
int GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:85
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:361
void * cb_cls
Closure for service_init_cb, connect_cb, disconnect_cb.
Definition: service.c:146
void GNUNET_SERVICE_client_persist(struct GNUNET_SERVICE_Client *c)
Set the persist option on this client.
Definition: service.c:2420
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh)
Explicitly stops the service.
Definition: service.c:2379
#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:912
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:974
void GNUNET_SPEEDUP_stop_()
Stop tasks that modify clock behavior.
Definition: speedup.c:105