GNUnet  0.16.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_MALLINFO2
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 
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 
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 
412  switch (sh->options & GNUNET_SERVICE_OPTION_SHUTDOWN_BITMASK)
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 (GNUNET_NO == 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;
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
674  const struct GNUNET_MessageHeader *message)
675 {
676  struct GNUNET_SERVICE_Client *client = cls;
677 
679  "Received message of type %u and size %u from client\n",
680  ntohs (message->type),
681  ntohs (message->size));
683  client->needs_continue = GNUNET_YES;
684  client->warn_type = ntohs (message->type);
686  GNUNET_assert (NULL == client->warn_task);
689  client);
690  GNUNET_MQ_inject_message (client->mq, message);
691  if (NULL != client->drop_task)
692  return GNUNET_SYSERR;
693  return GNUNET_OK;
694 }
695 
696 
703 static void
705 {
706  struct GNUNET_SERVICE_Client *client = cls;
708 
709  client->recv_task = NULL;
710  ret = GNUNET_MST_read (client->mst,
711  client->sock,
712  GNUNET_NO,
713  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 */
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);
755  GNUNET_CONTAINER_DLL_insert (sh->clients_head, sh->clients_tail, 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;
878  if (SUSPEND_STATE_NONE != sh->suspend_state)
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 ==
1083  disablev6 = GNUNET_YES;
1084 
1085  port = 0;
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 
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 ==
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  {
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);
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 (unixpath);
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));
1210  GNUNET_free (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);
1230  GNUNET_free (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  }
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 (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;
1534  GNUNET_CONTAINER_DLL_insert (sh->slc_head, sh->slc_tail, slc);
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  }
1562  GNUNET_CONTAINER_DLL_insert (sh->slc_head, sh->slc_tail, slc);
1563  }
1564  GNUNET_free (addrlens);
1565  GNUNET_free (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 (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;
1585  sh->match_uid = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
1586  sh->service_name,
1587  "UNIX_MATCH_UID");
1588  sh->match_gid = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
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 
1800  GNUNET_free (sh->v4_denied);
1801  GNUNET_free (sh->v6_denied);
1802  GNUNET_free (sh->v4_allowed);
1803  GNUNET_free (sh->v6_allowed);
1804  while (NULL != (slc = sh->slc_head))
1805  {
1806  GNUNET_CONTAINER_DLL_remove (sh->slc_head, sh->slc_tail, slc);
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  const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get ();
1831 
1832  (void) msg;
1833  slen = strlen (pd->agpl_url) + 1;
1835  memcpy (&res[1], GNUNET_AGPL_URL, slen);
1836  mq = GNUNET_SERVICE_client_get_mq (client);
1837  GNUNET_MQ_send (mq, env);
1839 }
1840 
1841 
1878 struct GNUNET_SERVICE_Handle *
1880  const struct GNUNET_CONFIGURATION_Handle *cfg,
1883  void *cls,
1884  const struct GNUNET_MQ_MessageHandler *handlers)
1885 {
1886  struct GNUNET_SERVICE_Handle *sh;
1887 
1888  sh = GNUNET_new (struct GNUNET_SERVICE_Handle);
1889  sh->service_name = service_name;
1890  sh->cfg = cfg;
1891  sh->connect_cb = connect_cb;
1892  sh->disconnect_cb = disconnect_cb;
1893  sh->cb_cls = cls;
1894  sh->handlers = GNUNET_MQ_copy_handlers2 (handlers, &return_agpl, NULL);
1895  if (GNUNET_OK != setup_service (sh))
1896  {
1897  GNUNET_free (sh->handlers);
1898  GNUNET_free (sh);
1899  return NULL;
1900  }
1902  return sh;
1903 }
1904 
1905 
1911 void
1913 {
1914  struct GNUNET_SERVICE_Client *client;
1915 
1916  GNUNET_SERVICE_suspend (srv);
1917  while (NULL != (client = srv->clients_head))
1918  GNUNET_SERVICE_client_drop (client);
1919  teardown_service (srv);
1920  GNUNET_free (srv->handlers);
1921  GNUNET_free (srv);
1922 }
1923 
1924 
1966 int
1968  char *const *argv,
1969  const char *service_name,
1971  GNUNET_SERVICE_InitCallback service_init_cb,
1974  void *cls,
1975  const struct GNUNET_MQ_MessageHandler *handlers)
1976 {
1977  struct GNUNET_SERVICE_Handle sh;
1978 
1979 #if ENABLE_NLS
1980  char *path;
1981 #endif
1982  char *cfg_filename;
1983  char *opt_cfg_filename;
1984  char *loglev;
1985  const char *xdg;
1986  char *logfile;
1987  int do_daemonize;
1988  unsigned long long skew_offset;
1989  unsigned long long skew_variance;
1990  long long clock_offset;
1992  int ret;
1993  int err;
1994  const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get ();
1995  struct GNUNET_GETOPT_CommandLineOption service_options[] = {
1996  GNUNET_GETOPT_option_cfgfile (&opt_cfg_filename),
1998  "daemonize",
1999  gettext_noop (
2000  "do daemonize (detach from terminal)"),
2001  &do_daemonize),
2004  GNUNET_GETOPT_option_logfile (&logfile),
2007  };
2008 
2009  err = 1;
2010  memset (&sh, 0, sizeof(sh));
2011  xdg = getenv ("XDG_CONFIG_HOME");
2012  if (NULL != xdg)
2014  "%s%s%s",
2015  xdg,
2017  pd->config_file);
2018  else
2020  sh.ready_confirm_fd = -1;
2021  sh.options = options;
2022  sh.cfg = cfg = GNUNET_CONFIGURATION_create ();
2023  sh.service_init_cb = service_init_cb;
2024  sh.connect_cb = connect_cb;
2025  sh.disconnect_cb = disconnect_cb;
2026  sh.cb_cls = cls;
2027  sh.handlers = (NULL == pd->agpl_url)
2030  sh.service_name = service_name;
2031  sh.ret = 0;
2032  /* setup subsystems */
2033  loglev = NULL;
2034  logfile = NULL;
2035  opt_cfg_filename = NULL;
2036  do_daemonize = 0;
2037 #if ENABLE_NLS
2038  if (NULL != pd->gettext_domain)
2039  {
2040  setlocale (LC_ALL, "");
2041  path = (NULL == pd->gettext_path) ?
2044  if (NULL != path)
2045  {
2046  bindtextdomain (pd->gettext_domain, path);
2047  GNUNET_free (path);
2048  }
2049  textdomain (pd->gettext_domain);
2050  }
2051 #endif
2053  service_options,
2054  argc,
2055  argv);
2056  if (GNUNET_SYSERR == ret)
2057  goto shutdown;
2058  if (GNUNET_NO == ret)
2059  {
2060  err = 0;
2061  goto shutdown;
2062  }
2064  loglev,
2065  logfile))
2066  {
2067  GNUNET_break (0);
2068  goto shutdown;
2069  }
2070  if (NULL != opt_cfg_filename)
2071  {
2072  if ((GNUNET_YES != GNUNET_DISK_file_test (opt_cfg_filename)) ||
2073  (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_filename)))
2074  {
2076  _ ("Malformed configuration file `%s', exit ...\n"),
2077  opt_cfg_filename);
2078  goto shutdown;
2079  }
2080  }
2081  else
2082  {
2084  {
2086  {
2088  _ ("Malformed configuration file `%s', exit ...\n"),
2089  cfg_filename);
2090  goto shutdown;
2091  }
2092  }
2093  else
2094  {
2096  {
2098  _ ("Malformed configuration, exit ...\n"));
2099  goto shutdown;
2100  }
2101  }
2102  }
2103  if (GNUNET_OK != setup_service (&sh))
2104  goto shutdown;
2105  if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sh)))
2106  {
2107  GNUNET_break (0);
2108  goto shutdown;
2109  }
2110  if (GNUNET_OK != set_user_id (&sh))
2111  goto shutdown;
2113  "Service `%s' runs with configuration from `%s'\n",
2114  service_name,
2115  (NULL != opt_cfg_filename) ? opt_cfg_filename : cfg_filename);
2117  "TESTING",
2118  "SKEW_OFFSET",
2119  &skew_offset)) &&
2121  "TESTING",
2122  "SKEW_VARIANCE",
2123  &skew_variance)))
2124  {
2125  clock_offset = skew_offset - skew_variance;
2126  GNUNET_TIME_set_offset (clock_offset);
2128  "Skewing clock by %lld ms\n",
2129  (long long) clock_offset);
2130  }
2132 
2133  /* actually run service */
2134  err = 0;
2136  /* shutdown */
2137  if (1 == do_daemonize)
2138  pid_file_delete (&sh);
2139 
2140 shutdown:
2141  if (-1 != sh.ready_confirm_fd)
2142  {
2143  if (1 != write (sh.ready_confirm_fd, err ? "I" : "S", 1))
2145  GNUNET_break (0 == close (sh.ready_confirm_fd));
2146  }
2147 #if HAVE_MALLINFO2
2148  {
2149  char *counter;
2150 
2152  service_name,
2153  "GAUGER_HEAP")) &&
2155  service_name,
2156  "GAUGER_HEAP",
2157  &counter)))
2158  {
2159  struct mallinfo2 mi;
2160 
2161  mi = mallinfo2 ();
2162  GAUGER (service_name, counter, mi.usmblks, "blocks");
2163  GNUNET_free (counter);
2164  }
2165  }
2166 #endif
2167  teardown_service (&sh);
2168  GNUNET_free (sh.handlers);
2171  GNUNET_free (logfile);
2172  GNUNET_free (loglev);
2174  GNUNET_free (opt_cfg_filename);
2175 
2176  return err ? GNUNET_SYSERR : sh.ret;
2177 }
2178 
2179 
2186 void
2188 {
2190 }
2191 
2192 
2198 void
2200 {
2202 }
2203 
2204 
2211 static void
2213 {
2214  struct GNUNET_SERVICE_Client *c = cls;
2215  int ret;
2216 
2217  c->recv_task = NULL;
2218  /* first, check if there is still something in the buffer */
2220  if (GNUNET_SYSERR == ret)
2221  {
2222  if (NULL == c->drop_task)
2224  return;
2225  }
2226  if (GNUNET_NO == ret)
2227  return; /* done processing, wait for more later */
2229  if (GNUNET_YES == c->needs_continue)
2230  return; /* #GNUNET_MST_next() did give a message to the client */
2231  /* need to receive more data from the network first */
2232  if (NULL != c->recv_task)
2233  return;
2235  c->sock,
2237  c);
2238 }
2239 
2240 
2247 void
2249 {
2250  GNUNET_assert (NULL == c->drop_task);
2252  GNUNET_assert (NULL == c->recv_task);
2254  if (NULL != c->warn_task)
2255  {
2257  c->warn_task = NULL;
2258  }
2260 }
2261 
2262 
2271 void
2273 {
2274  GNUNET_break (NULL != c->warn_task);
2275  if (NULL != c->warn_task)
2276  {
2278  c->warn_task = NULL;
2279  }
2280 }
2281 
2282 
2288 static void
2290 {
2291  struct GNUNET_SERVICE_Client *c = cls;
2292  struct GNUNET_SERVICE_Handle *sh = c->sh;
2293 
2294  c->drop_task = NULL;
2295  GNUNET_assert (NULL == c->send_task);
2296  GNUNET_assert (NULL == c->recv_task);
2297  GNUNET_assert (NULL == c->warn_task);
2298  GNUNET_MST_destroy (c->mst);
2299  GNUNET_MQ_destroy (c->mq);
2300  if (GNUNET_NO == c->persist)
2301  {
2303  if ((0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) &&
2304  (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)))
2306  }
2307  else
2308  {
2310  }
2311  GNUNET_free (c);
2312  if ((0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) &&
2315 }
2316 
2317 
2328 void
2330 {
2331  struct GNUNET_SERVICE_Handle *sh = c->sh;
2332 
2334  "Client dropped: %p (MQ: %p)\n",
2335  c,
2336  c->mq);
2337 #if EXECINFO
2338  {
2339  void *backtrace_array[MAX_TRACE_DEPTH];
2340  int num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH);
2341  char **backtrace_strings =
2342  backtrace_symbols (backtrace_array, t->num_backtrace_strings);
2343  for (unsigned int i = 0; i < num_backtrace_strings; i++)
2345  "client drop trace %u: %s\n",
2346  i,
2347  backtrace_strings[i]);
2348  }
2349 #endif
2350  if (NULL != c->drop_task)
2351  {
2352  /* asked to drop twice! */
2353  GNUNET_assert (0);
2354  return;
2355  }
2356  GNUNET_CONTAINER_DLL_remove (sh->clients_head,
2357  sh->clients_tail,
2358  c);
2359  if (NULL != sh->disconnect_cb)
2360  sh->disconnect_cb (sh->cb_cls,
2361  c,
2362  c->user_context);
2363  if (NULL != c->warn_task)
2364  {
2366  c->warn_task = NULL;
2367  }
2368  if (NULL != c->recv_task)
2369  {
2371  c->recv_task = NULL;
2372  }
2373  if (NULL != c->send_task)
2374  {
2376  c->send_task = NULL;
2377  }
2379 }
2380 
2381 
2387 void
2389 {
2390  struct GNUNET_SERVICE_Client *client;
2391 
2392  if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN))
2394  while (NULL != (client = sh->clients_head))
2395  GNUNET_SERVICE_client_drop (client);
2396 }
2397 
2398 
2411 void
2413 {
2414  c->is_monitor = GNUNET_YES;
2415  if (((0 != (SUSPEND_STATE_SHUTDOWN & c->sh->suspend_state)) &&
2418 }
2419 
2420 
2428 void
2430 {
2431  c->persist = GNUNET_YES;
2432 }
2433 
2434 
2441 struct GNUNET_MQ_Handle *
2443 {
2444  return c->mq;
2445 }
2446 
2447 
2448 /* end of service.c */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define GAUGER(category, counter, value, unit)
Definition: gauger.h:18
char * getenv()
#define gettext_noop(String)
Definition: gettext.h:69
#define textdomain(Domainname)
Definition: gettext.h:56
#define bindtextdomain(Domainname, Dirname)
Definition: gettext.h:57
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static int list
Set if we should print a list of currently running services.
Definition: gnunet-arm.c:69
static int res
static struct SolverHandle * sh
static char * cfg_filename
Name of the configuration file.
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
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
static int ok
Return value from 'main' (0 == success)
static void disconnect_cb(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called by cadet when a client disconnects.
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.
static char * hostname
Our hostname; we give this to all the peers we start.
static char buf[2048]
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static char * service_name
Option -s: service name (hash to get service descriptor)
Definition: gnunet-vpn.c:51
static struct GNUNET_SCHEDULER_Task * t
Main task.
#define GNUNET_is_zero(a)
Check that memory in a is all zeros.
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
Definition: gnunet_common.h:92
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
#define GNUNET_AGPL_URL
NOTE: You MUST adjust this URL to point to the location of a publicly accessible repository (or TGZ) ...
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_create(void)
Create a new configuration object.
void GNUNET_CONFIGURATION_destroy(struct GNUNET_CONFIGURATION_Handle *cfg)
Destroy configuration object.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_load(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Load configuration.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_have_value(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Test if we have a value for a particular option.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory).
Definition: disk.c:482
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:582
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_cfgfile(char **fn)
Allow user to specify configuration file name (-c option)
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_logfile(char **logfn)
Allow user to specify log file name (-l option)
int GNUNET_GETOPT_run(const char *binaryOptions, const struct GNUNET_GETOPT_CommandLineOption *allOptions, unsigned int argc, char *const *argv)
Parse the command line.
Definition: getopt.c:883
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_help(const char *about)
Defining the option to print the command line help text (-h option).
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_loglevel(char **level)
Define the '-L' log level option.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_flag(char shortName, const char *name, const char *description, int *val)
Allow user to specify a flag (which internally means setting an integer to 1/GNUNET_YES/GNUNET_OK.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_version(const char *version)
Define the option to print the version of the application (-v option)
int GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages).
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_Error
Error codes for the queue.
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:267
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:302
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:467
#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
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:423
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:186
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:446
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:491
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:977
struct GNUNET_MQ_MessageHandler * GNUNET_MQ_copy_handlers(const struct GNUNET_MQ_MessageHandler *handlers)
Copy an array of handlers.
Definition: mq.c:959
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:685
@ GNUNET_MQ_ERROR_NO_MATCH
We received a message for which we have no matching handler.
@ GNUNET_MQ_ERROR_WRITE
FIXME: document!
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_accept(const struct GNUNET_NETWORK_Handle *desc, struct sockaddr *address, socklen_t *address_len)
Accept a new connection on a socket.
Definition: network.c:392
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:855
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:570
char * GNUNET_NETWORK_shorten_unixpath(char *unixpath)
Given a unixpath that is too long (larger than UNIX_PATH_MAX), shorten it to an acceptable length whi...
Definition: network.c:143
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:760
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:79
enum GNUNET_GenericReturnValue 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:439
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_listen(const struct GNUNET_NETWORK_Handle *desc, int backlog)
Listen on a socket.
Definition: network.c:656
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:584
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_get(void)
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,...
@ GNUNET_OS_IPK_LOCALEDIR
Return the directory where translations are installed (share/locale/)
#define GNUNET_MESSAGE_TYPE_RESPONSE_AGPL
Source code link.
void GNUNET_RESOLVER_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create the connection to the resolver service.
Definition: resolver_api.c:257
void GNUNET_SCHEDULER_run(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Initialize and run scheduler.
Definition: scheduler.c:705
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:1281
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:1573
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:1502
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1316
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957
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:1254
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:401
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:352
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:418
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:85
void GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh)
Suspend accepting connections from the listen socket temporarily.
Definition: service.c:2187
void GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv)
Stops a service that was started with GNUNET_SERVICE_start().
Definition: service.c:1912
void GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh)
Explicitly stops the service.
Definition: service.c:2388
GNUNET_SERVICE_Options
Options for the service (bitmask).
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the 'monitor' flag on this client.
Definition: service.c:2412
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.
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.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2329
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2442
void GNUNET_SERVICE_client_persist(struct GNUNET_SERVICE_Client *c)
Set the persist option on this client.
Definition: service.c:2429
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:2272
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:1879
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.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2248
void GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh)
Resume accepting connections from the listen socket.
Definition: service.c:2199
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:1967
@ GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN
Do not trigger server shutdown on signal at all; instead, allow for the user to terminate the server ...
@ GNUNET_SERVICE_OPTION_SHUTDOWN_BITMASK
Bitmask over the shutdown options.
@ GNUNET_SERVICE_OPTION_CLOSE_LSOCKS
Instead of listening on lsocks passed by the parent, close them after opening our own listen socket(s...
@ GNUNET_SERVICE_OPTION_NONE
Use defaults.
@ GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN
Trigger a SOFT server shutdown on signals, allowing active non-monitor clients to complete their tran...
struct GNUNET_STRINGS_IPv6NetworkPolicy * GNUNET_STRINGS_parse_ipv6_policy(const char *routeListX)
Parse an IPv6 network policy.
Definition: strings.c:1472
struct GNUNET_STRINGS_IPv4NetworkPolicy * GNUNET_STRINGS_parse_ipv4_policy(const char *routeListX)
Parse an IPv4 network policy.
Definition: strings.c:1291
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:139
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
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:435
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:110
#define GNUNET_TIME_UNIT_MINUTES
One minute.
void GNUNET_TIME_set_offset(long long offset)
Set the timestamp offset for this instance.
Definition: time.c:48
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:570
#define DIR_SEPARATOR_STR
Definition: platform.h:165
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
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 detach_terminal(struct GNUNET_SERVICE_Handle *sh)
Detach from terminal.
Definition: service.c:1716
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 void return_agpl(void *cls, const struct GNUNET_MessageHeader *msg)
Function to return link to AGPL source upon request.
Definition: service.c:1823
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
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
static void service_client_recv(void *cls)
A client sent us data.
Definition: service.c:704
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 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
static void service_shutdown(void *cls)
Shutdown task triggered when a service should be terminated.
Definition: service.c:408
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:2212
static int set_user_id(struct GNUNET_SERVICE_Handle *sh)
Set user ID.
Definition: service.c:1627
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
#define LOG_STRERROR_FILE(kind, syscall, filename)
Definition: service.c:45
static char * get_user_name(struct GNUNET_SERVICE_Handle *sh)
Get the name of the user that'll be used to provide the service.
Definition: service.c:1607
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 do_send(void *cls)
Task run when we are ready to transmit data to the client.
Definition: service.c:498
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
static void finish_client_drop(void *cls)
Asynchronously finish dropping the client.
Definition: service.c:2289
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:1697
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
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
static void do_suspend(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
Suspend accepting connections from the listen socket temporarily.
Definition: service.c:382
static void warn_no_client_continue(void *cls)
Task run to warn about missing calls to GNUNET_SERVICE_client_continue().
Definition: service.c:640
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
static int setup_service(struct GNUNET_SERVICE_Handle *sh)
Setup service handle.
Definition: service.c:1460
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
static void service_main(void *cls)
First task run by any service.
Definition: service.c:900
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
#define LOG(kind,...)
Definition: service.c:40
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
#define LOG_STRERROR(kind, syscall)
Definition: service.c:42
static void accept_client(void *cls)
We have a client.
Definition: service.c:784
SuspendReason
Reasons why we might be suspended.
Definition: service.c:85
@ SUSPEND_STATE_SHUTDOWN
Suspension because service was permanently shutdown.
Definition: service.c:109
@ SUSPEND_STATE_APP
Application requested it.
Definition: service.c:94
@ SUSPEND_STATE_NONE
We are running normally.
Definition: service.c:89
@ SUSPEND_STATE_APP_AND_EMFILE
Both reasons, APP and EMFILE apply.
Definition: service.c:104
@ SUSPEND_STATE_EMFILE
OS ran out of file descriptors.
Definition: service.c:99
void GNUNET_SPEEDUP_stop_()
Stop tasks that modify clock behavior.
Definition: speedup.c:105
Definition of a command line option.
Handle to a message queue.
Definition: mq.c:86
Message handler for a specific message type.
Header for all communications.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
Handle to a message stream tokenizer.
Definition: mst.c:44
handle to a socket
Definition: network.c:53
Project-specific data used to help the OS subsystem find installation paths.
char * gettext_path
Gettext directory, e.g.
const char * user_config_file
Configuration file name to use (if $XDG_CONFIG_HOME is not set).
const char * config_file
Configuration file name (in $XDG_CONFIG_HOME) to use.
char * gettext_domain
Gettext domain for localisation, e.g.
const char * version
String identifying the current project version.
char * agpl_url
URL pointing to the source code of the application.
Entry in list of pending tasks.
Definition: scheduler.c:135
Handle to a client that is connected to a service.
Definition: service.c:251
int needs_continue
Are we waiting for the application to call GNUNET_SERVICE_client_continue()?
Definition: service.c:344
size_t msg_pos
Current position in msg at which we are transmitting.
Definition: service.c:325
int is_monitor
Is this client a 'monitor' client that should not be counted when deciding on destroying the server d...
Definition: service.c:339
struct GNUNET_SCHEDULER_Task * send_task
Task that transmit data to the client.
Definition: service.c:303
struct GNUNET_SCHEDULER_Task * drop_task
Task run to finish dropping the client after the stack has properly unwound.
Definition: service.c:292
struct GNUNET_TIME_Absolute warn_start
Time when we last gave a message from this client to the application.
Definition: service.c:320
struct GNUNET_NETWORK_Handle * sock
Socket of this client.
Definition: service.c:270
uint16_t warn_type
Type of last message processed (for warn_no_receive_done).
Definition: service.c:349
const struct GNUNET_MessageHeader * msg
Pointer to the message to be transmitted by send_task.
Definition: service.c:308
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_SCHEDULER_Task * warn_task
Task that warns about missing calls to GNUNET_SERVICE_client_continue().
Definition: service.c:286
struct GNUNET_SCHEDULER_Task * recv_task
Task that receives data from the client to pass it to the handlers.
Definition: service.c:298
struct GNUNET_SERVICE_Handle * sh
Service that this client belongs to.
Definition: service.c:265
struct GNUNET_SERVICE_Client * next
Kept in a DLL.
Definition: service.c:255
void * user_context
User context value, value returned from the connect callback.
Definition: service.c:314
struct GNUNET_SERVICE_Client * prev
Kept in a DLL.
Definition: service.c:260
struct GNUNET_MQ_Handle * mq
Message queue for the client.
Definition: service.c:275
struct GNUNET_MessageStreamTokenizer * mst
Tokenizer we use for processing incoming data.
Definition: service.c:280
Handle to a service.
Definition: service.c:117
void * task_cls
Closure for task.
Definition: service.c:176
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_denied
IPv6 addresses that are not allowed to connect.
Definition: service.c:187
GNUNET_SERVICE_ConnectHandler connect_cb
Function to call when clients connect.
Definition: service.c:136
GNUNET_SERVICE_InitCallback service_init_cb
Main service-specific task to run.
Definition: service.c:131
int ready_confirm_fd
If we are daemonizing, this FD is set to the pipe to the parent.
Definition: service.c:232
int ret
Overall success/failure of the service start.
Definition: service.c:237
struct GNUNET_SERVICE_Client * clients_tail
Our clients, kept in a DLL.
Definition: service.c:166
struct GNUNET_MQ_MessageHandler * handlers
Message handlers to use for all clients.
Definition: service.c:171
void * cb_cls
Closure for service_init_cb, connect_cb, disconnect_cb.
Definition: service.c:146
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_denied
IPv4 addresses that are not allowed to connect.
Definition: service.c:182
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_allowed
IPv6 addresses that are allowed to connect (if not set, all are allowed).
Definition: service.c:199
const char * service_name
Name of our service.
Definition: service.c:126
struct GNUNET_SERVICE_Client * clients_head
Our clients, kept in a DLL.
Definition: service.c:161
GNUNET_SERVICE_DisconnectHandler disconnect_cb
Function to call when clients disconnect / are disconnected.
Definition: service.c:141
enum GNUNET_SERVICE_Options options
Our options.
Definition: service.c:225
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
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 ServiceListenContext * slc_head
DLL of listen sockets used to accept new connections.
Definition: service.c:151
int require_found
If GNUNET_YES, consider unknown message types an error where the client is disconnected.
Definition: service.c:243
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: service.c:121
enum SuspendReason suspend_state
Are we suspended, and if so, why?
Definition: service.c:220
struct ServiceListenContext * slc_tail
DLL of listen sockets used to accept new connections.
Definition: service.c:156
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_allowed
IPv4 addresses that are allowed to connect (if not set, all are allowed).
Definition: service.c:193
IPV4 network in CIDR notation.
network in CIDR notation for IPV6.
Time for absolute times used by GNUnet, in microseconds.
Information the service tracks per listen operation.
Definition: service.c:53
struct ServiceListenContext * next
Kept in a DLL.
Definition: service.c:57
struct ServiceListenContext * prev
Kept in a DLL.
Definition: service.c:62
struct GNUNET_SCHEDULER_Task * listen_task
Task scheduled to do the listening.
Definition: service.c:77
struct GNUNET_NETWORK_Handle * listen_socket
Socket we are listening on.
Definition: service.c:72
struct GNUNET_SERVICE_Handle * sh
Service this listen context belongs to.
Definition: service.c:67