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  unsigned int j;
472 
473  if (NULL == list)
474  return GNUNET_NO;
475  i = 0;
476 NEXT:
477  while (0 != GNUNET_is_zero (&list[i].network))
478  {
479  for (j = 0; j < sizeof(struct in6_addr) / sizeof(int); j++)
480  if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
481  (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
482  {
483  i++;
484  goto NEXT;
485  }
486  return GNUNET_YES;
487  }
488  return GNUNET_NO;
489 }
490 
491 
498 static void
499 do_send (void *cls)
500 {
501  struct GNUNET_SERVICE_Client *client = cls;
502  ssize_t ret;
503  size_t left;
504  const char *buf;
505 
507  "service: sending message with type %u\n",
508  ntohs (client->msg->type));
509 
510 
511  client->send_task = NULL;
512  buf = (const char *) client->msg;
513  left = ntohs (client->msg->size) - client->msg_pos;
514  ret = GNUNET_NETWORK_socket_send (client->sock, &buf[client->msg_pos], left);
515  GNUNET_assert (ret <= (ssize_t) left);
516  if (0 == ret)
517  {
518  LOG (GNUNET_ERROR_TYPE_DEBUG, "no data send");
520  return;
521  }
522  if (-1 == ret)
523  {
524  if ((EAGAIN == errno) || (EINTR == errno))
525  {
526  /* ignore */
527  ret = 0;
528  }
529  else
530  {
531  if (EPIPE != errno)
534  "socket send returned with error code %i",
535  errno);
537  return;
538  }
539  }
540  if (0 == client->msg_pos)
541  {
543  }
544  client->msg_pos += ret;
545  if (left > (size_t) ret)
546  {
547  GNUNET_assert (NULL == client->drop_task);
548  client->send_task =
550  client->sock,
551  &do_send,
552  client);
553  return;
554  }
556 }
557 
558 
567 static void
569  const struct GNUNET_MessageHeader *msg,
570  void *impl_state)
571 {
572  struct GNUNET_SERVICE_Client *client = impl_state;
573 
574  (void) mq;
575  if (NULL != client->drop_task)
576  return; /* we're going down right now, do not try to send */
577  GNUNET_assert (NULL == client->send_task);
579  "Sending message of type %u and size %u to client\n",
580  ntohs (msg->type),
581  ntohs (msg->size));
582  client->msg = msg;
583  client->msg_pos = 0;
584  client->send_task =
586  client->sock,
587  &do_send,
588  client);
589 }
590 
591 
598 static void
599 service_mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
600 {
601  struct GNUNET_SERVICE_Client *client = impl_state;
602 
603  (void) mq;
604  GNUNET_assert (0 == client->msg_pos);
605  client->msg = NULL;
607  client->send_task = NULL;
608 }
609 
610 
620 static void
622 {
623  struct GNUNET_SERVICE_Client *client = cls;
624  struct GNUNET_SERVICE_Handle *sh = client->sh;
625 
626  if ((GNUNET_MQ_ERROR_NO_MATCH == error) && (GNUNET_NO == sh->require_found))
627  {
629  "No handler for message of type %u found\n",
630  (unsigned int) client->warn_type);
632  return; /* ignore error */
633  }
635 }
636 
637 
643 static void
645 {
646  struct GNUNET_SERVICE_Client *client = cls;
647 
648  GNUNET_break (
649  0 !=
650  client->warn_type); /* type should never be 0 here, as we don't use 0 */
653  client);
654  LOG (
656  _ (
657  "Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"),
658  (unsigned int) client->warn_type,
660  client->warn_start),
661  GNUNET_YES));
662 }
663 
664 
676 static int
677 service_client_mst_cb (void *cls, const struct GNUNET_MessageHeader *message)
678 {
679  struct GNUNET_SERVICE_Client *client = cls;
680 
682  "Received message of type %u and size %u from client\n",
683  ntohs (message->type),
684  ntohs (message->size));
686  client->needs_continue = GNUNET_YES;
687  client->warn_type = ntohs (message->type);
689  GNUNET_assert (NULL == client->warn_task);
692  client);
693  GNUNET_MQ_inject_message (client->mq, message);
694  if (NULL != client->drop_task)
695  return GNUNET_SYSERR;
696  return GNUNET_OK;
697 }
698 
699 
706 static void
708 {
709  struct GNUNET_SERVICE_Client *client = cls;
710  int ret;
711 
712  client->recv_task = NULL;
713  ret = GNUNET_MST_read (client->mst, client->sock, GNUNET_NO, GNUNET_YES);
714  if (GNUNET_SYSERR == ret)
715  {
716  /* client closed connection (or IO error) */
717  if (NULL == client->drop_task)
718  {
721  }
722  return;
723  }
724  if (GNUNET_NO == ret)
725  return; /* more messages in buffer, wait for application
726  to be done processing */
727  GNUNET_assert (GNUNET_OK == ret);
728  if (GNUNET_YES == client->needs_continue)
729  return;
730  if (NULL != client->recv_task)
731  return;
732  /* MST needs more data, re-schedule read job */
733  client->recv_task =
735  client->sock,
737  client);
738 }
739 
740 
748 static void
750  struct GNUNET_NETWORK_Handle *csock)
751 {
752  struct GNUNET_SERVICE_Client *client;
753 
754  client = GNUNET_new (struct GNUNET_SERVICE_Client);
756  client->sh = sh;
757  client->sock = csock;
759  NULL,
761  client,
762  sh->handlers,
764  client);
765  client->mst = GNUNET_MST_create (&service_client_mst_cb, client);
766  if (NULL != sh->connect_cb)
767  client->user_context = sh->connect_cb (sh->cb_cls, client, client->mq);
769  client->recv_task =
771  client->sock,
773  client);
774 }
775 
776 
783 static void
784 accept_client (void *cls)
785 {
786  struct ServiceListenContext *slc = cls;
787  struct GNUNET_SERVICE_Handle *sh = slc->sh;
788 
789  slc->listen_task = NULL;
790  while (1)
791  {
792  struct GNUNET_NETWORK_Handle *sock;
793  const struct sockaddr_in *v4;
794  const struct sockaddr_in6 *v6;
795  struct sockaddr_storage sa;
796  socklen_t addrlen;
797  int ok;
798 
799  addrlen = sizeof(sa);
801  (struct sockaddr *) &sa,
802  &addrlen);
803  if (NULL == sock)
804  {
805  if (EMFILE == errno)
807  else if (EAGAIN != errno)
809  break;
810  }
811  switch (sa.ss_family)
812  {
813  case AF_INET:
814  GNUNET_assert (addrlen == sizeof(struct sockaddr_in));
815  v4 = (const struct sockaddr_in *) &sa;
816  ok = (((NULL == sh->v4_allowed) ||
817  (check_ipv4_listed (sh->v4_allowed, &v4->sin_addr))) &&
818  ((NULL == sh->v4_denied) ||
819  (! check_ipv4_listed (sh->v4_denied, &v4->sin_addr))));
820  break;
821 
822  case AF_INET6:
823  GNUNET_assert (addrlen == sizeof(struct sockaddr_in6));
824  v6 = (const struct sockaddr_in6 *) &sa;
825  ok = (((NULL == sh->v6_allowed) ||
826  (check_ipv6_listed (sh->v6_allowed, &v6->sin6_addr))) &&
827  ((NULL == sh->v6_denied) ||
828  (! check_ipv6_listed (sh->v6_denied, &v6->sin6_addr))));
829  break;
830 
831  case AF_UNIX:
832  ok = GNUNET_OK; /* controlled using file-system ACL now */
833  break;
834 
835  default:
837  _ ("Unknown address family %d\n"),
838  sa.ss_family);
839  return;
840  }
841  if (! ok)
842  {
844  "Service rejected incoming connection from %s due to policy.\n",
845  GNUNET_a2s ((const struct sockaddr *) &sa, addrlen));
847  continue;
848  }
850  "Service accepted incoming connection from %s.\n",
851  GNUNET_a2s ((const struct sockaddr *) &sa, addrlen));
852  start_client (slc->sh, sock);
853  }
854  if (0 != sh->suspend_state)
855  return;
856  slc->listen_task =
858  slc->listen_socket,
859  &accept_client,
860  slc);
861 }
862 
863 
871 static void
873 {
874  struct ServiceListenContext *slc;
875 
876  GNUNET_assert ((SUSPEND_STATE_NONE == sr) || (0 != (sh->suspend_state & sr)));
877  sh->suspend_state -= sr;
879  return;
880  for (slc = sh->slc_head; NULL != slc; slc = slc->next)
881  {
882  GNUNET_assert (NULL == slc->listen_task);
883  slc->listen_task =
885  slc->listen_socket,
886  &accept_client,
887  slc);
888  }
889 }
890 
891 
899 static void
900 service_main (void *cls)
901 {
902  struct GNUNET_SERVICE_Handle *sh = cls;
903 
908 
909  if (-1 != sh->ready_confirm_fd)
910  {
911  GNUNET_break (1 == write (sh->ready_confirm_fd, ".", 1));
912  GNUNET_break (0 == close (sh->ready_confirm_fd));
913  sh->ready_confirm_fd = -1;
914  }
915 
916  if (NULL != sh->service_init_cb)
917  sh->service_init_cb (sh->cb_cls, sh->cfg, sh);
918 }
919 
920 
930 static int
932  struct GNUNET_SERVICE_Handle *sh,
933  const char *option)
934 {
935  char *opt;
936 
937  if (! GNUNET_CONFIGURATION_have_value (sh->cfg, sh->service_name, option))
938  {
939  *ret = NULL;
940  return GNUNET_OK;
941  }
944  sh->service_name,
945  option,
946  &opt));
947  if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy (opt)))
948  {
950  _ ("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
951  opt,
952  sh->service_name,
953  option);
954  GNUNET_free (opt);
955  return GNUNET_SYSERR;
956  }
957  GNUNET_free (opt);
958  return GNUNET_OK;
959 }
960 
961 
971 static int
973  struct GNUNET_SERVICE_Handle *sh,
974  const char *option)
975 {
976  char *opt;
977 
978  if (! GNUNET_CONFIGURATION_have_value (sh->cfg, sh->service_name, option))
979  {
980  *ret = NULL;
981  return GNUNET_OK;
982  }
985  sh->service_name,
986  option,
987  &opt));
988  if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy (opt)))
989  {
991  _ ("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
992  opt,
993  sh->service_name,
994  option);
995  GNUNET_free (opt);
996  return GNUNET_SYSERR;
997  }
998  GNUNET_free (opt);
999  return GNUNET_OK;
1000 }
1001 
1002 
1011 static void
1012 add_unixpath (struct sockaddr **saddrs,
1013  socklen_t *saddrlens,
1014  const char *unixpath)
1015 {
1016 #ifdef AF_UNIX
1017  struct sockaddr_un *un;
1018 
1019  un = GNUNET_new (struct sockaddr_un);
1020  un->sun_family = AF_UNIX;
1021  GNUNET_strlcpy (un->sun_path, unixpath, sizeof(un->sun_path));
1022 #if HAVE_SOCKADDR_UN_SUN_LEN
1023  un->sun_len = (u_char) sizeof(struct sockaddr_un);
1024 #endif
1025  *saddrs = (struct sockaddr *) un;
1026  *saddrlens = sizeof(struct sockaddr_un);
1027 #else
1028  /* this function should never be called
1029  * unless AF_UNIX is defined! */
1030  GNUNET_assert (0);
1031 #endif
1032 }
1033 
1034 
1055 static int
1057  const struct GNUNET_CONFIGURATION_Handle *cfg,
1058  struct sockaddr ***addrs,
1059  socklen_t **addr_lens)
1060 {
1061  int disablev6;
1062  struct GNUNET_NETWORK_Handle *desc;
1063  unsigned long long port;
1064  char *unixpath;
1065  struct addrinfo hints;
1066  struct addrinfo *res;
1067  struct addrinfo *pos;
1068  struct addrinfo *next;
1069  unsigned int i;
1070  int resi;
1071  int ret;
1072  struct sockaddr **saddrs;
1073  socklen_t *saddrlens;
1074  char *hostname;
1075 
1076  *addrs = NULL;
1077  *addr_lens = NULL;
1078  desc = NULL;
1079  disablev6 = GNUNET_NO;
1080  if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
1081  (GNUNET_YES ==
1082  GNUNET_CONFIGURATION_get_value_yesno (cfg, service_name, "DISABLEV6")))
1083  disablev6 = GNUNET_YES;
1084 
1085  port = 0;
1086  if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT"))
1087  {
1089  service_name,
1090  "PORT",
1091  &port))
1092  {
1094  _ ("Require valid port number for service `%s' in configuration!\n"),
1095  service_name);
1096  }
1097  if (port > 65535)
1098  {
1100  _ ("Require valid port number for service `%s' in configuration!\n"),
1101  service_name);
1102  return GNUNET_SYSERR;
1103  }
1104  }
1105 
1106  if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO"))
1107  {
1110  service_name,
1111  "BINDTO",
1112  &hostname));
1113  }
1114  else
1115  hostname = NULL;
1116 
1117  unixpath = NULL;
1118 #ifdef AF_UNIX
1119  if ((GNUNET_YES ==
1120  GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) &&
1122  service_name,
1123  "UNIXPATH",
1124  &unixpath)) &&
1125  (0 < strlen (unixpath)))
1126  {
1127  /* probe UNIX support */
1128  struct sockaddr_un s_un;
1129 
1130  if (strlen (unixpath) >= sizeof(s_un.sun_path))
1131  {
1133  _ ("UNIXPATH `%s' too long, maximum length is %llu\n"),
1134  unixpath,
1135  (unsigned long long) sizeof(s_un.sun_path));
1136  unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
1137  LOG (GNUNET_ERROR_TYPE_INFO, _ ("Using `%s' instead\n"), unixpath);
1138  }
1141  }
1142  if (NULL != unixpath)
1143  {
1144  desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
1145  if (NULL == desc)
1146  {
1147  if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
1148  (EACCES == errno))
1149  {
1151  GNUNET_free_non_null (hostname);
1152  GNUNET_free (unixpath);
1153  return GNUNET_SYSERR;
1154  }
1156  _ (
1157  "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
1158  service_name,
1159  strerror (errno));
1160  GNUNET_free (unixpath);
1161  unixpath = NULL;
1162  }
1163  else
1164  {
1166  desc = NULL;
1167  }
1168  }
1169 #endif
1170 
1171  if ((0 == port) && (NULL == unixpath))
1172  {
1174  _ (
1175  "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
1176  service_name);
1177  GNUNET_free_non_null (hostname);
1178  return GNUNET_SYSERR;
1179  }
1180  if (0 == port)
1181  {
1182  saddrs = GNUNET_new_array (2, struct sockaddr *);
1183  saddrlens = GNUNET_new_array (2, socklen_t);
1184  add_unixpath (saddrs, saddrlens, unixpath);
1185  GNUNET_free_non_null (unixpath);
1186  GNUNET_free_non_null (hostname);
1187  *addrs = saddrs;
1188  *addr_lens = saddrlens;
1189  return 1;
1190  }
1191 
1192  if (NULL != hostname)
1193  {
1195  "Resolving `%s' since that is where `%s' will bind to.\n",
1196  hostname,
1197  service_name);
1198  memset (&hints, 0, sizeof(struct addrinfo));
1199  if (disablev6)
1200  hints.ai_family = AF_INET;
1201  hints.ai_protocol = IPPROTO_TCP;
1202  if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
1203  (NULL == res))
1204  {
1206  _ ("Failed to resolve `%s': %s\n"),
1207  hostname,
1208  gai_strerror (ret));
1209  GNUNET_free (hostname);
1210  GNUNET_free_non_null (unixpath);
1211  return GNUNET_SYSERR;
1212  }
1213  next = res;
1214  i = 0;
1215  while (NULL != (pos = next))
1216  {
1217  next = pos->ai_next;
1218  if ((disablev6) && (pos->ai_family == AF_INET6))
1219  continue;
1220  i++;
1221  }
1222  if (0 == i)
1223  {
1225  _ ("Failed to find %saddress for `%s'.\n"),
1226  disablev6 ? "IPv4 " : "",
1227  hostname);
1228  freeaddrinfo (res);
1229  GNUNET_free (hostname);
1230  GNUNET_free_non_null (unixpath);
1231  return GNUNET_SYSERR;
1232  }
1233  resi = i;
1234  if (NULL != unixpath)
1235  resi++;
1236  saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
1237  saddrlens = GNUNET_new_array (resi + 1, socklen_t);
1238  i = 0;
1239  if (NULL != unixpath)
1240  {
1241  add_unixpath (saddrs, saddrlens, unixpath);
1242  i++;
1243  }
1244  next = res;
1245  while (NULL != (pos = next))
1246  {
1247  next = pos->ai_next;
1248  if ((disablev6) && (AF_INET6 == pos->ai_family))
1249  continue;
1250  if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
1251  continue; /* not TCP */
1252  if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
1253  continue; /* huh? */
1255  "Service `%s' will bind to `%s'\n",
1256  service_name,
1257  GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
1258  if (AF_INET == pos->ai_family)
1259  {
1260  GNUNET_assert (sizeof(struct sockaddr_in) == pos->ai_addrlen);
1261  saddrlens[i] = pos->ai_addrlen;
1262  saddrs[i] = GNUNET_malloc (saddrlens[i]);
1263  GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
1264  ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1265  }
1266  else
1267  {
1268  GNUNET_assert (AF_INET6 == pos->ai_family);
1269  GNUNET_assert (sizeof(struct sockaddr_in6) == pos->ai_addrlen);
1270  saddrlens[i] = pos->ai_addrlen;
1271  saddrs[i] = GNUNET_malloc (saddrlens[i]);
1272  GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
1273  ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
1274  }
1275  i++;
1276  }
1277  GNUNET_free (hostname);
1278  freeaddrinfo (res);
1279  resi = i;
1280  }
1281  else
1282  {
1283  /* will bind against everything, just set port */
1284  if (disablev6)
1285  {
1286  /* V4-only */
1287  resi = 1;
1288  if (NULL != unixpath)
1289  resi++;
1290  i = 0;
1291  saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
1292  saddrlens = GNUNET_new_array (resi + 1, socklen_t);
1293  if (NULL != unixpath)
1294  {
1295  add_unixpath (saddrs, saddrlens, unixpath);
1296  i++;
1297  }
1298  saddrlens[i] = sizeof(struct sockaddr_in);
1299  saddrs[i] = GNUNET_malloc (saddrlens[i]);
1300 #if HAVE_SOCKADDR_IN_SIN_LEN
1301  ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
1302 #endif
1303  ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
1304  ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1305  }
1306  else
1307  {
1308  /* dual stack */
1309  resi = 2;
1310  if (NULL != unixpath)
1311  resi++;
1312  saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
1313  saddrlens = GNUNET_new_array (resi + 1, socklen_t);
1314  i = 0;
1315  if (NULL != unixpath)
1316  {
1317  add_unixpath (saddrs, saddrlens, unixpath);
1318  i++;
1319  }
1320  saddrlens[i] = sizeof(struct sockaddr_in6);
1321  saddrs[i] = GNUNET_malloc (saddrlens[i]);
1322 #if HAVE_SOCKADDR_IN_SIN_LEN
1323  ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
1324 #endif
1325  ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
1326  ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
1327  i++;
1328  saddrlens[i] = sizeof(struct sockaddr_in);
1329  saddrs[i] = GNUNET_malloc (saddrlens[i]);
1330 #if HAVE_SOCKADDR_IN_SIN_LEN
1331  ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
1332 #endif
1333  ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
1334  ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1335  }
1336  }
1337  GNUNET_free_non_null (unixpath);
1338  *addrs = saddrs;
1339  *addr_lens = saddrlens;
1340  return resi;
1341 }
1342 
1343 
1351 static struct GNUNET_NETWORK_Handle *
1352 open_listen_socket (const struct sockaddr *server_addr,
1353  socklen_t socklen)
1354 {
1355  struct GNUNET_NETWORK_Handle *sock;
1356  uint16_t port;
1357  int eno;
1358 
1359  switch (server_addr->sa_family)
1360  {
1361  case AF_INET:
1362  port = ntohs (((const struct sockaddr_in *) server_addr)->sin_port);
1363  break;
1364  case AF_INET6:
1365  port = ntohs (((const struct sockaddr_in6 *) server_addr)->sin6_port);
1366  break;
1367  case AF_UNIX:
1368  port = 0;
1369  break;
1370  default:
1371  GNUNET_break (0);
1372  port = 0;
1373  break;
1374  }
1375  sock = GNUNET_NETWORK_socket_create (server_addr->sa_family,
1376  SOCK_STREAM,
1377  0);
1378  if (NULL == sock)
1379  {
1381  "socket");
1382  errno = 0;
1383  return NULL;
1384  }
1385  /* bind the socket */
1386  if (GNUNET_OK !=
1388  server_addr,
1389  socklen))
1390  {
1391  eno = errno;
1392  if (EADDRINUSE != errno)
1393  {
1394  /* we don't log 'EADDRINUSE' here since an IPv4 bind may
1395  * fail if we already took the port on IPv6; if both IPv4 and
1396  * IPv6 binds fail, then our caller will log using the
1397  * errno preserved in 'eno' */
1398  if (0 != port)
1400  _ ("`%s' failed for port %d (%s).\n"),
1401  "bind",
1402  port,
1403  (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1404  else
1406  eno = 0;
1407  }
1408  else
1409  {
1410  if (0 != port)
1412  _ ("`%s' failed for port %d (%s): address already in use\n"),
1413  "bind",
1414  port,
1415  (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1416  else if (AF_UNIX == server_addr->sa_family)
1417  {
1419  _ ("`%s' failed for `%s': address already in use\n"),
1420  "bind",
1421  GNUNET_a2s (server_addr, socklen));
1422  }
1423  }
1425  errno = eno;
1426  return NULL;
1427  }
1428  if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5))
1429  {
1432  errno = 0;
1433  return NULL;
1434  }
1435  if (0 != port)
1437  "Server starts to listen on port %u.\n",
1438  port);
1439  return sock;
1440 }
1441 
1442 
1459 static int
1461 {
1462  int tolerant;
1463  struct GNUNET_NETWORK_Handle **csocks = NULL;
1464  struct GNUNET_NETWORK_Handle **lsocks;
1465  const char *nfds;
1466  unsigned int cnt;
1467  int flags;
1468  char dummy[2];
1469 
1471  sh->service_name,
1472  "TOLERANT"))
1473  {
1474  if (GNUNET_SYSERR ==
1475  (tolerant = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
1476  sh->service_name,
1477  "TOLERANT")))
1478  {
1480  _ ("Specified value for `%s' of service `%s' is invalid\n"),
1481  "TOLERANT",
1482  sh->service_name);
1483  return GNUNET_SYSERR;
1484  }
1485  }
1486  else
1487  tolerant = GNUNET_NO;
1488 
1489  lsocks = NULL;
1490  errno = 0;
1491  if ((NULL != (nfds = getenv ("LISTEN_FDS"))) &&
1492  (1 == sscanf (nfds, "%u%1s", &cnt, dummy)) && (cnt > 0) &&
1493  (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE))
1494  {
1495  lsocks = GNUNET_new_array (cnt + 1, struct GNUNET_NETWORK_Handle *);
1496  while (0 < cnt--)
1497  {
1498  flags = fcntl (3 + cnt, F_GETFD);
1499  if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) ||
1500  (NULL == (lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt))))
1501  {
1503  _ (
1504  "Could not access pre-bound socket %u, will try to bind myself\n"),
1505  (unsigned int) 3 + cnt);
1506  cnt++;
1507  while (NULL != lsocks[cnt])
1509  GNUNET_NETWORK_socket_close (lsocks[cnt++]));
1510  GNUNET_free (lsocks);
1511  lsocks = NULL;
1512  break;
1513  }
1514  }
1515  unsetenv ("LISTEN_FDS");
1516  }
1517  if ( (0 != (GNUNET_SERVICE_OPTION_CLOSE_LSOCKS & sh->options)) &&
1518  (NULL != lsocks) )
1519  {
1520  csocks = lsocks;
1521  lsocks = NULL;
1522  }
1523 
1524  if (NULL != lsocks)
1525  {
1526  /* listen only on inherited sockets if we have any */
1527  for (struct GNUNET_NETWORK_Handle **ls = lsocks; NULL != *ls; ls++)
1528  {
1529  struct ServiceListenContext *slc;
1530 
1531  slc = GNUNET_new (struct ServiceListenContext);
1532  slc->sh = sh;
1533  slc->listen_socket = *ls;
1535  }
1536  GNUNET_free (lsocks);
1537  }
1538  else
1539  {
1540  struct sockaddr **addrs;
1541  socklen_t *addrlens;
1542  int num;
1543 
1544  num = get_server_addresses (sh->service_name, sh->cfg, &addrs, &addrlens);
1545  if (GNUNET_SYSERR == num)
1546  return GNUNET_SYSERR;
1547 
1548  for (int i = 0; i < num; i++)
1549  {
1550  struct ServiceListenContext *slc;
1551 
1552  slc = GNUNET_new (struct ServiceListenContext);
1553  slc->sh = sh;
1554  slc->listen_socket = open_listen_socket (addrs[i], addrlens[i]);
1555  GNUNET_free (addrs[i]);
1556  if (NULL == slc->listen_socket)
1557  {
1559  GNUNET_free (slc);
1560  continue;
1561  }
1563  }
1564  GNUNET_free_non_null (addrlens);
1565  GNUNET_free_non_null (addrs);
1566  if ((0 != num) && (NULL == sh->slc_head))
1567  {
1568  /* All attempts to bind failed, hard failure */
1569  GNUNET_log (
1571  _ (
1572  "Could not bind to any of the ports I was supposed to, refusing to run!\n"));
1573  GNUNET_free_non_null (csocks);
1574  return GNUNET_SYSERR;
1575  }
1576  }
1577  if (NULL != csocks)
1578  {
1579  /* close inherited sockets to signal parent that we are ready */
1580  for (struct GNUNET_NETWORK_Handle **ls = csocks; NULL != *ls; ls++)
1582  GNUNET_free (csocks);
1583  }
1584  sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
1586  sh->service_name,
1587  "UNIX_MATCH_UID");
1589  sh->service_name,
1590  "UNIX_MATCH_GID");
1591  process_acl4 (&sh->v4_denied, sh, "REJECT_FROM");
1592  process_acl4 (&sh->v4_allowed, sh, "ACCEPT_FROM");
1593  process_acl6 (&sh->v6_denied, sh, "REJECT_FROM6");
1594  process_acl6 (&sh->v6_allowed, sh, "ACCEPT_FROM6");
1595  return GNUNET_OK;
1596 }
1597 
1598 
1606 static char *
1608 {
1609  char *un;
1610 
1612  sh->service_name,
1613  "USERNAME",
1614  &un))
1615  return NULL;
1616  return un;
1617 }
1618 
1619 
1626 static int
1628 {
1629  char *user;
1630 
1631  if (NULL == (user = get_user_name (sh)))
1632  return GNUNET_OK; /* keep */
1633 
1634  struct passwd *pws;
1635 
1636  errno = 0;
1637  pws = getpwnam (user);
1638  if (NULL == pws)
1639  {
1641  _ ("Cannot obtain information about user `%s': %s\n"),
1642  user,
1643  errno == 0 ? _ ("No such user") : strerror (errno));
1644  GNUNET_free (user);
1645  return GNUNET_SYSERR;
1646  }
1647  if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) ||
1648 #if HAVE_INITGROUPS
1649  (0 != initgroups (user, pws->pw_gid)) ||
1650 #endif
1651  (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid)))
1652  {
1653  if ((0 != setregid (pws->pw_gid, pws->pw_gid)) ||
1654  (0 != setreuid (pws->pw_uid, pws->pw_uid)))
1655  {
1657  _ ("Cannot change user/group to `%s': %s\n"),
1658  user,
1659  strerror (errno));
1660  GNUNET_free (user);
1661  return GNUNET_SYSERR;
1662  }
1663  }
1664 
1665  GNUNET_free (user);
1666  return GNUNET_OK;
1667 }
1668 
1669 
1677 static char *
1679 {
1680  char *pif;
1681 
1683  sh->service_name,
1684  "PIDFILE",
1685  &pif))
1686  return NULL;
1687  return pif;
1688 }
1689 
1690 
1696 static void
1698 {
1699  char *pif = get_pid_file_name (sh);
1700 
1701  if (NULL == pif)
1702  return; /* no PID file */
1703  if (0 != unlink (pif))
1705  GNUNET_free (pif);
1706 }
1707 
1708 
1715 static int
1717 {
1718  pid_t pid;
1719  int nullfd;
1720  int filedes[2];
1721 
1722  if (0 != pipe (filedes))
1723  {
1725  return GNUNET_SYSERR;
1726  }
1727  pid = fork ();
1728  if (pid < 0)
1729  {
1731  return GNUNET_SYSERR;
1732  }
1733  if (0 != pid)
1734  {
1735  /* Parent */
1736  char c;
1737 
1738  GNUNET_break (0 == close (filedes[1]));
1739  c = 'X';
1740  if (1 != read (filedes[0], &c, sizeof(char)))
1742  fflush (stdout);
1743  switch (c)
1744  {
1745  case '.':
1746  exit (0);
1747 
1748  case 'I':
1750  _ ("Service process failed to initialize\n"));
1751  break;
1752 
1753  case 'S':
1755  _ ("Service process could not initialize server function\n"));
1756  break;
1757 
1758  case 'X':
1760  _ ("Service process failed to report status\n"));
1761  break;
1762  }
1763  exit (1); /* child reported error */
1764  }
1765  GNUNET_break (0 == close (0));
1766  GNUNET_break (0 == close (1));
1767  GNUNET_break (0 == close (filedes[0]));
1768  nullfd = open ("/dev/null", O_RDWR | O_APPEND);
1769  if (nullfd < 0)
1770  return GNUNET_SYSERR;
1771  /* set stdin/stdout to /dev/null */
1772  if ((dup2 (nullfd, 0) < 0) || (dup2 (nullfd, 1) < 0))
1773  {
1775  (void) close (nullfd);
1776  return GNUNET_SYSERR;
1777  }
1778  (void) close (nullfd);
1779  /* Detach from controlling terminal */
1780  pid = setsid ();
1781  if (-1 == pid)
1783  sh->ready_confirm_fd = filedes[1];
1784 
1785  return GNUNET_OK;
1786 }
1787 
1788 
1795 static void
1797 {
1798  struct ServiceListenContext *slc;
1799 
1804  while (NULL != (slc = sh->slc_head))
1805  {
1807  if (NULL != slc->listen_task)
1811  GNUNET_free (slc);
1812  }
1813 }
1814 
1815 
1822 static void
1823 return_agpl (void *cls, const struct GNUNET_MessageHeader *msg)
1824 {
1825  struct GNUNET_SERVICE_Client *client = cls;
1826  struct GNUNET_MQ_Handle *mq;
1827  struct GNUNET_MQ_Envelope *env;
1828  struct GNUNET_MessageHeader *res;
1829  size_t slen;
1830 
1831  (void) msg;
1832  slen = strlen (GNUNET_AGPL_URL) + 1;
1834  memcpy (&res[1], GNUNET_AGPL_URL, slen);
1835  mq = GNUNET_SERVICE_client_get_mq (client);
1836  GNUNET_MQ_send (mq, env);
1838 }
1839 
1840 
1877 struct GNUNET_SERVICE_Handle *
1879  const struct GNUNET_CONFIGURATION_Handle *cfg,
1882  void *cls,
1883  const struct GNUNET_MQ_MessageHandler *handlers)
1884 {
1885  struct GNUNET_SERVICE_Handle *sh;
1886 
1887  sh = GNUNET_new (struct GNUNET_SERVICE_Handle);
1888  sh->service_name = service_name;
1889  sh->cfg = cfg;
1890  sh->connect_cb = connect_cb;
1892  sh->cb_cls = cls;
1893  sh->handlers = GNUNET_MQ_copy_handlers2 (handlers, &return_agpl, NULL);
1894  if (GNUNET_OK != setup_service (sh))
1895  {
1897  GNUNET_free (sh);
1898  return NULL;
1899  }
1901  return sh;
1902 }
1903 
1904 
1910 void
1912 {
1913  struct GNUNET_SERVICE_Client *client;
1914 
1915  GNUNET_SERVICE_suspend (srv);
1916  while (NULL != (client = srv->clients_head))
1917  GNUNET_SERVICE_client_drop (client);
1918  teardown_service (srv);
1920  GNUNET_free (srv);
1921 }
1922 
1923 
1965 int
1967  char *const *argv,
1968  const char *service_name,
1970  GNUNET_SERVICE_InitCallback service_init_cb,
1973  void *cls,
1974  const struct GNUNET_MQ_MessageHandler *handlers)
1975 {
1976  struct GNUNET_SERVICE_Handle sh;
1977 
1978 #if ENABLE_NLS
1979  char *path;
1980 #endif
1981  char *cfg_filename;
1982  char *opt_cfg_filename;
1983  char *loglev;
1984  const char *xdg;
1985  char *logfile;
1986  int do_daemonize;
1987  unsigned long long skew_offset;
1988  unsigned long long skew_variance;
1989  long long clock_offset;
1991  int ret;
1992  int err;
1993  const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get ();
1994  struct GNUNET_GETOPT_CommandLineOption service_options[] = {
1995  GNUNET_GETOPT_option_cfgfile (&opt_cfg_filename),
1997  "daemonize",
1998  gettext_noop (
1999  "do daemonize (detach from terminal)"),
2000  &do_daemonize),
2003  GNUNET_GETOPT_option_logfile (&logfile),
2006  };
2007 
2008  err = 1;
2009  memset (&sh, 0, sizeof(sh));
2010  xdg = getenv ("XDG_CONFIG_HOME");
2011  if (NULL != xdg)
2012  GNUNET_asprintf (&cfg_filename,
2013  "%s%s%s",
2014  xdg,
2016  pd->config_file);
2017  else
2018  cfg_filename = GNUNET_strdup (pd->user_config_file);
2019  sh.ready_confirm_fd = -1;
2020  sh.options = options;
2021  sh.cfg = cfg = GNUNET_CONFIGURATION_create ();
2022  sh.service_init_cb = service_init_cb;
2023  sh.connect_cb = connect_cb;
2025  sh.cb_cls = cls;
2026  sh.handlers = GNUNET_MQ_copy_handlers (handlers);
2028  sh.ret = 0;
2029  /* setup subsystems */
2030  loglev = NULL;
2031  logfile = NULL;
2032  opt_cfg_filename = NULL;
2033  do_daemonize = 0;
2034 #if ENABLE_NLS
2035  if (NULL != pd->gettext_domain)
2036  {
2037  setlocale (LC_ALL, "");
2038  path = (NULL == pd->gettext_path) ?
2041  if (NULL != path)
2042  {
2043  bindtextdomain (pd->gettext_domain, path);
2044  GNUNET_free (path);
2045  }
2046  textdomain (pd->gettext_domain);
2047  }
2048 #endif
2049  ret = GNUNET_GETOPT_run (service_name,
2050  service_options,
2051  argc,
2052  argv);
2053  if (GNUNET_SYSERR == ret)
2054  goto shutdown;
2055  if (GNUNET_NO == ret)
2056  {
2057  err = 0;
2058  goto shutdown;
2059  }
2060  if (GNUNET_OK != GNUNET_log_setup (service_name,
2061  loglev,
2062  logfile))
2063  {
2064  GNUNET_break (0);
2065  goto shutdown;
2066  }
2067  if (NULL != opt_cfg_filename)
2068  {
2069  if ((GNUNET_YES != GNUNET_DISK_file_test (opt_cfg_filename)) ||
2070  (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_filename)))
2071  {
2073  _ ("Malformed configuration file `%s', exit ...\n"),
2074  opt_cfg_filename);
2075  goto shutdown;
2076  }
2077  }
2078  else
2079  {
2080  if (GNUNET_YES == GNUNET_DISK_file_test (cfg_filename))
2081  {
2082  if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cfg_filename))
2083  {
2085  _ ("Malformed configuration file `%s', exit ...\n"),
2086  cfg_filename);
2087  goto shutdown;
2088  }
2089  }
2090  else
2091  {
2092  if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL))
2093  {
2095  _ ("Malformed configuration, exit ...\n"));
2096  goto shutdown;
2097  }
2098  }
2099  }
2100  if (GNUNET_OK != setup_service (&sh))
2101  goto shutdown;
2102  if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sh)))
2103  {
2104  GNUNET_break (0);
2105  goto shutdown;
2106  }
2107  if (GNUNET_OK != set_user_id (&sh))
2108  goto shutdown;
2110  "Service `%s' runs with configuration from `%s'\n",
2111  service_name,
2112  (NULL != opt_cfg_filename) ? opt_cfg_filename : cfg_filename);
2114  "TESTING",
2115  "SKEW_OFFSET",
2116  &skew_offset)) &&
2118  "TESTING",
2119  "SKEW_VARIANCE",
2120  &skew_variance)))
2121  {
2122  clock_offset = skew_offset - skew_variance;
2123  GNUNET_TIME_set_offset (clock_offset);
2124  LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset);
2125  }
2127 
2128  /* actually run service */
2129  err = 0;
2131  /* shutdown */
2132  if (1 == do_daemonize)
2133  pid_file_delete (&sh);
2134 
2135 shutdown:
2136  if (-1 != sh.ready_confirm_fd)
2137  {
2138  if (1 != write (sh.ready_confirm_fd, err ? "I" : "S", 1))
2140  GNUNET_break (0 == close (sh.ready_confirm_fd));
2141  }
2142 #if HAVE_MALLINFO
2143  {
2144  char *counter;
2145 
2147  service_name,
2148  "GAUGER_HEAP")) &&
2150  service_name,
2151  "GAUGER_HEAP",
2152  &counter)))
2153  {
2154  struct mallinfo mi;
2155 
2156  mi = mallinfo ();
2157  GAUGER (service_name, counter, mi.usmblks, "blocks");
2158  GNUNET_free (counter);
2159  }
2160  }
2161 #endif
2162  teardown_service (&sh);
2166  GNUNET_free_non_null (logfile);
2167  GNUNET_free_non_null (loglev);
2168  GNUNET_free (cfg_filename);
2169  GNUNET_free_non_null (opt_cfg_filename);
2170 
2171  return err ? GNUNET_SYSERR : sh.ret;
2172 }
2173 
2174 
2181 void
2183 {
2185 }
2186 
2187 
2193 void
2195 {
2197 }
2198 
2199 
2206 static void
2208 {
2209  struct GNUNET_SERVICE_Client *c = cls;
2210  int ret;
2211 
2212  c->recv_task = NULL;
2213  /* first, check if there is still something in the buffer */
2214  ret = GNUNET_MST_next (c->mst, GNUNET_YES);
2215  if (GNUNET_SYSERR == ret)
2216  {
2217  if (NULL == c->drop_task)
2219  return;
2220  }
2221  if (GNUNET_NO == ret)
2222  return; /* done processing, wait for more later */
2223  GNUNET_assert (GNUNET_OK == ret);
2224  if (GNUNET_YES == c->needs_continue)
2225  return; /* #GNUNET_MST_next() did give a message to the client */
2226  /* need to receive more data from the network first */
2227  if (NULL != c->recv_task)
2228  return;
2230  c->sock,
2232  c);
2233 }
2234 
2235 
2242 void
2244 {
2245  GNUNET_assert (NULL == c->drop_task);
2247  GNUNET_assert (NULL == c->recv_task);
2249  if (NULL != c->warn_task)
2250  {
2252  c->warn_task = NULL;
2253  }
2255 }
2256 
2257 
2266 void
2268 {
2269  GNUNET_break (NULL != c->warn_task);
2270  if (NULL != c->warn_task)
2271  {
2273  c->warn_task = NULL;
2274  }
2275 }
2276 
2277 
2283 static void
2285 {
2286  struct GNUNET_SERVICE_Client *c = cls;
2287  struct GNUNET_SERVICE_Handle *sh = c->sh;
2288 
2289  c->drop_task = NULL;
2290  GNUNET_assert (NULL == c->send_task);
2291  GNUNET_assert (NULL == c->recv_task);
2292  GNUNET_assert (NULL == c->warn_task);
2293  GNUNET_MST_destroy (c->mst);
2294  GNUNET_MQ_destroy (c->mq);
2295  if (GNUNET_NO == c->persist)
2296  {
2298  if ((0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) &&
2299  (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)))
2301  }
2302  else
2303  {
2305  }
2306  GNUNET_free (c);
2307  if ((0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) &&
2310 }
2311 
2312 
2323 void
2325 {
2326  struct GNUNET_SERVICE_Handle *sh = c->sh;
2327 
2329  "Client dropped: %p (MQ: %p)\n",
2330  c,
2331  c->mq);
2332 #if EXECINFO
2333  {
2334  void *backtrace_array[MAX_TRACE_DEPTH];
2335  int num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH);
2336  char **backtrace_strings =
2337  backtrace_symbols (backtrace_array, t->num_backtrace_strings);
2338  for (unsigned int i = 0; i < num_backtrace_strings; i++)
2340  "client drop trace %u: %s\n",
2341  i,
2342  backtrace_strings[i]);
2343  }
2344 #endif
2345  if (NULL != c->drop_task)
2346  {
2347  /* asked to drop twice! */
2348  GNUNET_assert (0);
2349  return;
2350  }
2352  sh->clients_tail,
2353  c);
2354  if (NULL != sh->disconnect_cb)
2355  sh->disconnect_cb (sh->cb_cls,
2356  c,
2357  c->user_context);
2358  if (NULL != c->warn_task)
2359  {
2361  c->warn_task = NULL;
2362  }
2363  if (NULL != c->recv_task)
2364  {
2366  c->recv_task = NULL;
2367  }
2368  if (NULL != c->send_task)
2369  {
2371  c->send_task = NULL;
2372  }
2374 }
2375 
2376 
2382 void
2384 {
2385  struct GNUNET_SERVICE_Client *client;
2386 
2387  if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN))
2389  while (NULL != (client = sh->clients_head))
2390  GNUNET_SERVICE_client_drop (client);
2391 }
2392 
2393 
2406 void
2408 {
2409  c->is_monitor = GNUNET_YES;
2410  if (((0 != (SUSPEND_STATE_SHUTDOWN & c->sh->suspend_state)) &&
2413 }
2414 
2415 
2423 void
2425 {
2426  c->persist = GNUNET_YES;
2427 }
2428 
2429 
2436 struct GNUNET_MQ_Handle *
2438 {
2439  return c->mq;
2440 }
2441 
2442 
2443 /* 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:599
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:1823
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:1518
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:2207
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:1056
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:2194
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:2437
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:1300
static int setup_service(struct GNUNET_SERVICE_Handle *sh)
Setup service handle.
Definition: service.c:1460
#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:1710
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:784
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:1214
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:1557
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:717
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:1878
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:225
#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:972
Definition of a command line option.
static void service_main(void *cls)
First task run by any service.
Definition: service.c:900
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:677
static void pid_file_delete(struct GNUNET_SERVICE_Handle *sh)
Delete the PID file that was created by our parent.
Definition: service.c:1697
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:1627
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:181
static void do_send(void *cls)
Task run when we are ready to transmit data to the client.
Definition: service.c:499
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:621
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:583
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:519
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:2284
#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:1253
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:552
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:1280
#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: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:687
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:1678
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:1607
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:1796
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:2407
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:1244
void GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv)
Stops a service that was started with GNUNET_SERVICE_start().
Definition: service.c:1911
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:2324
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:1352
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_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:931
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:872
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:644
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:1966
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
configuration data
Definition: configuration.c:85
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:749
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:568
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:707
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:824
#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:1486
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:353
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:2182
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:2267
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:1012
#define LOG_STRERROR(kind, syscall)
Definition: service.c:42
static int detach_terminal(struct GNUNET_SERVICE_Handle *sh)
Detach from terminal.
Definition: service.c:1716
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:486
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:2243
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:2424
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh)
Explicitly stops the service.
Definition: service.c:2383
#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:966
void GNUNET_SPEEDUP_stop_()
Stop tasks that modify clock behavior.
Definition: speedup.c:105