GNUnet 0.22.0
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#endif
37
38
39#define LOG(kind, ...) GNUNET_log_from (kind, "util-service", __VA_ARGS__)
40
41#define LOG_STRERROR(kind, syscall) \
42 GNUNET_log_from_strerror (kind, "util-service", syscall)
43
44#define LOG_STRERROR_FILE(kind, syscall, filename) \
45 GNUNET_log_from_strerror_file (kind, "util-service", syscall, filename)
46
47
52{
57
62
67
72
77};
78
79
84{
89
94
99
104
110
111
116{
121
125 const char *service_name;
126
131
136
141
145 void *cb_cls;
146
151
156
161
166
171
175 void *task_cls;
176
177
182
187
193
199
206
215
220
225
232
238};
239
240
245{
250
255
260
265
270
275
281
287
293
298
303
309
315
319 size_t msg_pos;
320
327
334
339
343 uint16_t warn_type;
344};
345
346
356{
357 for (struct GNUNET_SERVICE_Client *client = sh->clients_head;
358 NULL != client;
359 client = client->next)
360 {
361 if (NULL != client->drop_task)
362 continue;
363 if (client->is_monitor)
364 continue;
365 return true;
366 }
367 return false;
368}
369
370
378static void
380 enum SuspendReason sr)
381{
382 GNUNET_assert (0 == (sh->suspend_state & sr));
383 sh->suspend_state |= sr;
384 for (struct ServiceListenContext *slc = sh->slc_head;
385 NULL != slc;
386 slc = slc->next)
387 {
388 if (NULL != slc->listen_task)
389 {
390 GNUNET_SCHEDULER_cancel (slc->listen_task);
391 slc->listen_task = NULL;
392 }
393 }
394}
395
396
405static void
407{
408 struct GNUNET_SERVICE_Handle *sh = cls;
409
411 {
414 break;
416 /* This task should never be run if we are using
417 the manual shutdown. */
418 GNUNET_assert (0);
419 break;
421 if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN))
425 break;
426 }
427}
428
429
437static bool
439 const struct in_addr *add)
440{
441 for (unsigned int i = 0;
442 0 != list[i].network.s_addr;
443 i++)
444 {
445 if ( (add->s_addr & list[i].netmask.s_addr) ==
446 (list[i].network.s_addr & list[i].netmask.s_addr) )
447 return true;
448 }
449 return false;
450}
451
452
460static bool
462 const struct in6_addr *ip)
463{
464 for (unsigned int i = 0;
465 ! GNUNET_is_zero (&list[i].network);
466 i++)
467 {
468 bool match = true;
469
470 for (unsigned int j = 0; j < sizeof(struct in6_addr) / sizeof(int); j++)
471 if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
472 (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
473 {
474 match = false;
475 break;
476 }
477 if (match)
478 return true;
479 }
480 return false;
481}
482
483
490static void
491do_send (void *cls)
492{
493 struct GNUNET_SERVICE_Client *client = cls;
494 ssize_t ret;
495 size_t left;
496 const char *buf;
497
499 "service: sending message with type %u\n",
500 ntohs (client->msg->type));
501 client->send_task = NULL;
502 buf = (const char *) client->msg;
503 left = ntohs (client->msg->size) - client->msg_pos;
505 &buf[client->msg_pos],
506 left);
507 GNUNET_assert (ret <= (ssize_t) left);
508 if (0 == ret)
509 {
510 LOG (GNUNET_ERROR_TYPE_DEBUG, "no data send");
512 return;
513 }
514 if (-1 == ret)
515 {
516 if ((EAGAIN == errno) || (EINTR == errno))
517 {
518 /* ignore */
519 ret = 0;
520 }
521 else
522 {
523 if (EPIPE != errno)
526 "socket send returned with error code %i",
527 errno);
529 return;
530 }
531 }
532 if (0 == client->msg_pos)
533 {
535 }
536 client->msg_pos += ret;
537 if (left > (size_t) ret)
538 {
539 GNUNET_assert (NULL == client->drop_task);
540 client->send_task =
542 client->sock,
543 &do_send,
544 client);
545 return;
546 }
548}
549
550
559static void
561 const struct GNUNET_MessageHeader *msg,
562 void *impl_state)
563{
564 struct GNUNET_SERVICE_Client *client = impl_state;
565
566 (void) mq;
567 if (NULL != client->drop_task)
568 return; /* we're going down right now, do not try to send */
569 GNUNET_assert (NULL == client->send_task);
571 "Sending message of type %u and size %u to client\n",
572 ntohs (msg->type),
573 ntohs (msg->size));
574 client->msg = msg;
575 client->msg_pos = 0;
577 client);
578}
579
580
587static void
589 void *impl_state)
590{
591 struct GNUNET_SERVICE_Client *client = impl_state;
592
593 (void) mq;
594 GNUNET_assert (0 == client->msg_pos);
595 client->msg = NULL;
597 client->send_task = NULL;
598}
599
600
610static void
612 enum GNUNET_MQ_Error error)
613{
614 struct GNUNET_SERVICE_Client *client = cls;
615 struct GNUNET_SERVICE_Handle *sh = client->sh;
616
617 if ( (GNUNET_MQ_ERROR_NO_MATCH == error) &&
618 (! sh->require_found) )
619 {
621 "No handler for message of type %u found\n",
622 (unsigned int) client->warn_type);
624 return; /* ignore error */
625 }
627}
628
629
635static void
637{
638 struct GNUNET_SERVICE_Client *client = cls;
639
641 0 !=
642 client->warn_type); /* type should never be 0 here, as we don't use 0 */
645 client);
646 LOG (
648 _ (
649 "Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"),
650 (unsigned int) client->warn_type,
652 client->warn_start),
653 GNUNET_YES));
654}
655
656
668static int
670 const struct GNUNET_MessageHeader *message)
671{
672 struct GNUNET_SERVICE_Client *client = cls;
673
675 "Received message of type %u and size %u from client\n",
676 ntohs (message->type),
677 ntohs (message->size));
678 GNUNET_assert (! client->needs_continue);
679 client->needs_continue = true;
680 client->warn_type = ntohs (message->type);
682 GNUNET_assert (NULL == client->warn_task);
685 client);
686 GNUNET_MQ_inject_message (client->mq, message);
687 if (NULL != client->drop_task)
688 return GNUNET_SYSERR;
689 return GNUNET_OK;
690}
691
692
699static void
701{
702 struct GNUNET_SERVICE_Client *client = cls;
704
705 client->recv_task = NULL;
706 ret = GNUNET_MST_read (client->mst,
707 client->sock,
708 GNUNET_NO,
709 GNUNET_YES);
710 if (GNUNET_SYSERR == ret)
711 {
712 /* client closed connection (or IO error) */
713 if (NULL == client->drop_task)
714 {
715 GNUNET_assert (! client->needs_continue);
717 }
718 return;
719 }
720 if (GNUNET_NO == ret)
721 return; /* more messages in buffer, wait for application
722 to be done processing */
724 if (client->needs_continue)
725 return;
726 if (NULL != client->recv_task)
727 return;
728 /* MST needs more data, re-schedule read job */
729 client->recv_task =
731 client->sock,
733 client);
734}
735
736
744static void
746 struct GNUNET_NETWORK_Handle *csock)
747{
748 struct GNUNET_SERVICE_Client *client;
749
750 client = GNUNET_new (struct GNUNET_SERVICE_Client);
751 GNUNET_CONTAINER_DLL_insert (sh->clients_head,
752 sh->clients_tail,
753 client);
754 client->sh = sh;
755 client->sock = csock;
757 NULL,
759 client,
760 sh->handlers,
762 client);
763 client->mst = GNUNET_MST_create (&service_client_mst_cb, client);
764 if (NULL != sh->connect_cb)
765 client->user_context = sh->connect_cb (sh->cb_cls, client, client->mq);
767 client->recv_task =
769 client->sock,
771 client);
772}
773
774
781static void
782accept_client (void *cls)
783{
784 struct ServiceListenContext *slc = cls;
785 struct GNUNET_SERVICE_Handle *sh = slc->sh;
786
787 slc->listen_task = NULL;
788 while (1)
789 {
790 struct GNUNET_NETWORK_Handle *sock;
791 const struct sockaddr_in *v4;
792 const struct sockaddr_in6 *v6;
793 struct sockaddr_storage sa;
794 socklen_t addrlen;
795 int ok;
796
797 addrlen = sizeof(sa);
799 (struct sockaddr *) &sa,
800 &addrlen);
801 if (NULL == sock)
802 {
803 if (EMFILE == errno)
805 else if (EAGAIN != errno)
807 "accept");
808 break;
809 }
810 switch (sa.ss_family)
811 {
812 case AF_INET:
813 GNUNET_assert (addrlen == sizeof(struct sockaddr_in));
814 v4 = (const struct sockaddr_in *) &sa;
815 ok = (((NULL == sh->v4_allowed) ||
816 (check_ipv4_listed (sh->v4_allowed,
817 &v4->sin_addr))) &&
818 ((NULL == sh->v4_denied) ||
819 (! check_ipv4_listed (sh->v4_denied,
820 &v4->sin_addr))));
821 break;
822
823 case AF_INET6:
824 GNUNET_assert (addrlen == sizeof(struct sockaddr_in6));
825 v6 = (const struct sockaddr_in6 *) &sa;
826 ok = (((NULL == sh->v6_allowed) ||
827 (check_ipv6_listed (sh->v6_allowed,
828 &v6->sin6_addr))) &&
829 ((NULL == sh->v6_denied) ||
830 (! check_ipv6_listed (sh->v6_denied,
831 &v6->sin6_addr))));
832 break;
833
834 case AF_UNIX:
835 ok = GNUNET_OK; /* controlled using file-system ACL now */
836 break;
837
838 default:
840 _ ("Unknown address family %d\n"),
841 sa.ss_family);
842 return;
843 }
844 if (! ok)
845 {
847 "Service rejected incoming connection from %s due to policy.\n",
848 GNUNET_a2s ((const struct sockaddr *) &sa, addrlen));
850 continue;
851 }
853 "Service accepted incoming connection from %s.\n",
854 GNUNET_a2s ((const struct sockaddr *) &sa, addrlen));
855 start_client (slc->sh,
856 sock);
857 }
858 if (0 != sh->suspend_state)
859 return;
860 slc->listen_task =
862 slc->listen_socket,
864 slc);
865}
866
867
875static void
877 enum SuspendReason sr)
878{
879 GNUNET_assert ((SUSPEND_STATE_NONE == sr) || (0 != (sh->suspend_state & sr)));
880 sh->suspend_state -= sr;
881 if (SUSPEND_STATE_NONE != sh->suspend_state)
882 return;
883 for (struct ServiceListenContext *slc = sh->slc_head;
884 NULL != slc;
885 slc = slc->next)
886 {
887 GNUNET_assert (NULL == slc->listen_task);
888 slc->listen_task =
890 slc->listen_socket,
892 slc);
893 }
894}
895
896
904static void
905service_main (void *cls)
906{
907 struct GNUNET_SERVICE_Handle *sh = cls;
908
913
914 if (-1 != sh->ready_confirm_fd)
915 {
916 GNUNET_break (1 == write (sh->ready_confirm_fd, ".", 1));
917 GNUNET_break (0 == close (sh->ready_confirm_fd));
918 sh->ready_confirm_fd = -1;
919 }
920
921 if (NULL != sh->service_init_cb)
922 sh->service_init_cb (sh->cb_cls, sh->cfg, sh);
923}
924
925
938 const char *option)
939{
940 char *opt;
941
942 if (! GNUNET_CONFIGURATION_have_value (sh->cfg, sh->service_name, option))
943 {
944 *ret = NULL;
945 return GNUNET_OK;
946 }
949 sh->service_name,
950 option,
951 &opt));
952 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy (opt)))
953 {
955 _ ("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
956 opt,
957 sh->service_name,
958 option);
959 GNUNET_free (opt);
960 return GNUNET_SYSERR;
961 }
962 GNUNET_free (opt);
963 return GNUNET_OK;
964}
965
966
979 const char *option)
980{
981 char *opt;
982
983 if (! GNUNET_CONFIGURATION_have_value (sh->cfg, sh->service_name, option))
984 {
985 *ret = NULL;
986 return GNUNET_OK;
987 }
990 sh->service_name,
991 option,
992 &opt));
993 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy (opt)))
994 {
996 _ ("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
997 opt,
998 sh->service_name,
999 option);
1000 GNUNET_free (opt);
1001 return GNUNET_SYSERR;
1002 }
1003 GNUNET_free (opt);
1004 return GNUNET_OK;
1005}
1006
1007
1016static void
1017add_unixpath (struct sockaddr **saddrs,
1018 socklen_t *saddrlens,
1019 const char *unixpath)
1020{
1021#ifdef AF_UNIX
1022 struct sockaddr_un *un;
1023
1024 un = GNUNET_new (struct sockaddr_un);
1025 un->sun_family = AF_UNIX;
1026 GNUNET_strlcpy (un->sun_path, unixpath, sizeof(un->sun_path));
1027#if HAVE_SOCKADDR_UN_SUN_LEN
1028 un->sun_len = (u_char) sizeof(struct sockaddr_un);
1029#endif
1030 *saddrs = (struct sockaddr *) un;
1031 *saddrlens = sizeof(struct sockaddr_un);
1032#else
1033 /* this function should never be called
1034 * unless AF_UNIX is defined! */
1035 GNUNET_assert (0);
1036#endif
1037}
1038
1039
1060static int
1062 const struct GNUNET_CONFIGURATION_Handle *cfg,
1063 struct sockaddr ***addrs,
1064 socklen_t **addr_lens)
1065{
1066 bool disablev6;
1067 struct GNUNET_NETWORK_Handle *desc;
1068 unsigned long long port;
1069 char *unixpath;
1070 struct addrinfo hints;
1071 struct addrinfo *res;
1072 struct addrinfo *pos;
1073 struct addrinfo *next;
1074 unsigned int i;
1075 int resi;
1076 int ret;
1077 struct sockaddr **saddrs;
1078 socklen_t *saddrlens;
1079 char *hostname;
1080
1081 *addrs = NULL;
1082 *addr_lens = NULL;
1083 desc = NULL;
1084 disablev6 = false;
1085 if ((GNUNET_NO ==
1086 GNUNET_NETWORK_test_pf (PF_INET6)) ||
1087 (GNUNET_YES ==
1090 "DISABLEV6")))
1091 disablev6 = true;
1092
1093 port = 0;
1094 if (GNUNET_SYSERR ==
1097 "PORT",
1098 &port))
1099 {
1101 _ ("Require valid port number for service `%s' in configuration!\n"),
1102 service_name);
1103 }
1104 if (port > 65535)
1105 {
1107 _ ("Require valid port number for service `%s' in configuration!\n"),
1108 service_name);
1109 return GNUNET_SYSERR;
1110 }
1111
1112 hostname = NULL;
1116 "BINDTO",
1117 &hostname));
1118
1119 unixpath = NULL;
1120#ifdef AF_UNIX
1121 if ( (GNUNET_OK ==
1124 "UNIXPATH",
1125 &unixpath)) &&
1126 (0 < strlen (unixpath)) )
1127 {
1128 /* probe UNIX support */
1129 struct sockaddr_un s_un;
1130
1131 if (strlen (unixpath) >= sizeof(s_un.sun_path))
1132 {
1134 "UNIXPATH `%s' too long, maximum length is %llu\n",
1135 unixpath,
1136 (unsigned long long) sizeof(s_un.sun_path));
1137 unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
1139 _ ("Using `%s' instead\n"),
1140 unixpath);
1141 }
1142 if (GNUNET_OK !=
1145 "mkdir",
1146 unixpath);
1147 }
1148 if (NULL != unixpath)
1149 {
1150 desc = GNUNET_NETWORK_socket_create (AF_UNIX,
1151 SOCK_STREAM,
1152 0);
1153 if (NULL == desc)
1154 {
1155 if ((ENOBUFS == errno) ||
1156 (ENOMEM == errno) ||
1157 (ENFILE == errno) ||
1158 (EACCES == errno))
1159 {
1161 "socket");
1162 GNUNET_free (hostname);
1163 GNUNET_free (unixpath);
1164 return GNUNET_SYSERR;
1165 }
1167 "Failed to create UNIX domain socket for service %s: %s\n",
1169 strerror (errno));
1170 GNUNET_free (unixpath);
1171 unixpath = NULL;
1172 }
1173 else
1174 {
1177 desc = NULL;
1178 }
1179 }
1180#endif
1181
1182 if ( (0 == port) &&
1183 (NULL == unixpath) )
1184 {
1186 "Have neither PORT nor UNIXPATH for service `%s', but one is required\n",
1187 service_name);
1188 GNUNET_free (hostname);
1189 return GNUNET_SYSERR;
1190 }
1191 if (0 == port)
1192 {
1193 saddrs = GNUNET_new_array (2, struct sockaddr *);
1194 saddrlens = GNUNET_new_array (2, socklen_t);
1195 add_unixpath (saddrs, saddrlens, unixpath);
1196 GNUNET_free (unixpath);
1197 GNUNET_free (hostname);
1198 *addrs = saddrs;
1199 *addr_lens = saddrlens;
1200 return 1;
1201 }
1202
1203 if (NULL != hostname)
1204 {
1206 "Resolving `%s' since that is where `%s' will bind to.\n",
1207 hostname,
1208 service_name);
1209 memset (&hints, 0, sizeof(struct addrinfo));
1210 if (disablev6)
1211 hints.ai_family = AF_INET;
1212 hints.ai_protocol = IPPROTO_TCP;
1213 if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
1214 (NULL == res))
1215 {
1217 _ ("Failed to resolve `%s': %s\n"),
1218 hostname,
1219 gai_strerror (ret));
1220 GNUNET_free (hostname);
1221 GNUNET_free (unixpath);
1222 return GNUNET_SYSERR;
1223 }
1224 next = res;
1225 i = 0;
1226 while (NULL != (pos = next))
1227 {
1228 next = pos->ai_next;
1229 if ((disablev6) && (pos->ai_family == AF_INET6))
1230 continue;
1231 i++;
1232 }
1233 if (0 == i)
1234 {
1236 _ ("Failed to find %saddress for `%s'.\n"),
1237 disablev6 ? "IPv4 " : "",
1238 hostname);
1239 freeaddrinfo (res);
1240 GNUNET_free (hostname);
1241 GNUNET_free (unixpath);
1242 return GNUNET_SYSERR;
1243 }
1244 resi = i;
1245 if (NULL != unixpath)
1246 resi++;
1247 saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
1248 saddrlens = GNUNET_new_array (resi + 1, socklen_t);
1249 i = 0;
1250 if (NULL != unixpath)
1251 {
1252 add_unixpath (saddrs, saddrlens, unixpath);
1253 i++;
1254 }
1255 next = res;
1256 while (NULL != (pos = next))
1257 {
1258 next = pos->ai_next;
1259 if ((disablev6) && (AF_INET6 == pos->ai_family))
1260 continue;
1261 if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
1262 continue; /* not TCP */
1263 if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
1264 continue; /* huh? */
1266 "Service `%s' will bind to `%s'\n",
1268 GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
1269 if (AF_INET == pos->ai_family)
1270 {
1271 GNUNET_assert (sizeof(struct sockaddr_in) == pos->ai_addrlen);
1272 saddrlens[i] = pos->ai_addrlen;
1273 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1274 GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
1275 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1276 }
1277 else
1278 {
1279 GNUNET_assert (AF_INET6 == pos->ai_family);
1280 GNUNET_assert (sizeof(struct sockaddr_in6) == pos->ai_addrlen);
1281 saddrlens[i] = pos->ai_addrlen;
1282 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1283 GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
1284 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
1285 }
1286 i++;
1287 }
1288 GNUNET_free (hostname);
1289 freeaddrinfo (res);
1290 resi = i;
1291 }
1292 else
1293 {
1294 /* will bind against everything, just set port */
1295 if (disablev6)
1296 {
1297 /* V4-only */
1298 resi = 1;
1299 if (NULL != unixpath)
1300 resi++;
1301 i = 0;
1302 saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
1303 saddrlens = GNUNET_new_array (resi + 1, socklen_t);
1304 if (NULL != unixpath)
1305 {
1306 add_unixpath (saddrs, saddrlens, unixpath);
1307 i++;
1308 }
1309 saddrlens[i] = sizeof(struct sockaddr_in);
1310 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1311#if HAVE_SOCKADDR_IN_SIN_LEN
1312 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
1313#endif
1314 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
1315 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1316 }
1317 else
1318 {
1319 /* dual stack */
1320 resi = 2;
1321 if (NULL != unixpath)
1322 resi++;
1323 saddrs = GNUNET_new_array (resi + 1, struct sockaddr *);
1324 saddrlens = GNUNET_new_array (resi + 1, socklen_t);
1325 i = 0;
1326 if (NULL != unixpath)
1327 {
1328 add_unixpath (saddrs, saddrlens, unixpath);
1329 i++;
1330 }
1331 saddrlens[i] = sizeof(struct sockaddr_in6);
1332 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1333#if HAVE_SOCKADDR_IN_SIN_LEN
1334 ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
1335#endif
1336 ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
1337 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
1338 i++;
1339 saddrlens[i] = sizeof(struct sockaddr_in);
1340 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1341#if HAVE_SOCKADDR_IN_SIN_LEN
1342 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
1343#endif
1344 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
1345 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1346 }
1347 }
1348 GNUNET_free (unixpath);
1349 *addrs = saddrs;
1350 *addr_lens = saddrlens;
1351 return resi;
1352}
1353
1354
1362static struct GNUNET_NETWORK_Handle *
1363open_listen_socket (const struct sockaddr *server_addr,
1364 socklen_t socklen)
1365{
1366 struct GNUNET_NETWORK_Handle *sock;
1367 uint16_t port;
1368 int eno;
1369
1370 switch (server_addr->sa_family)
1371 {
1372 case AF_INET:
1373 port = ntohs (((const struct sockaddr_in *) server_addr)->sin_port);
1374 break;
1375 case AF_INET6:
1376 port = ntohs (((const struct sockaddr_in6 *) server_addr)->sin6_port);
1377 break;
1378 case AF_UNIX:
1379 port = 0;
1380 break;
1381 default:
1382 GNUNET_break (0);
1383 port = 0;
1384 break;
1385 }
1386 sock = GNUNET_NETWORK_socket_create (server_addr->sa_family,
1387 SOCK_STREAM,
1388 0);
1389 if (NULL == sock)
1390 {
1392 "socket");
1393 errno = 0;
1394 return NULL;
1395 }
1396 /* bind the socket */
1397 if (GNUNET_OK !=
1399 server_addr,
1400 socklen))
1401 {
1402 eno = errno;
1403 if (EADDRINUSE != errno)
1404 {
1405 /* we don't log 'EADDRINUSE' here since an IPv4 bind may
1406 * fail if we already took the port on IPv6; if both IPv4 and
1407 * IPv6 binds fail, then our caller will log using the
1408 * errno preserved in 'eno' */
1409 if (0 != port)
1411 _ ("`%s' failed for port %d (%s).\n"),
1412 "bind",
1413 port,
1414 (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1415 else
1417 eno = 0;
1418 }
1419 else
1420 {
1421 if (0 != port)
1423 _ ("`%s' failed for port %d (%s): address already in use\n"),
1424 "bind",
1425 port,
1426 (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1427 else if (AF_UNIX == server_addr->sa_family)
1428 {
1430 _ ("`%s' failed for `%s': address already in use\n"),
1431 "bind",
1432 GNUNET_a2s (server_addr, socklen));
1433 }
1434 }
1436 errno = eno;
1437 return NULL;
1438 }
1439 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5))
1440 {
1443 errno = 0;
1444 return NULL;
1445 }
1446 if (0 != port)
1448 "Server starts to listen on port %u.\n",
1449 port);
1450 return sock;
1451}
1452
1453
1470static enum GNUNET_GenericReturnValue
1472{
1473 int tolerant;
1474 struct GNUNET_NETWORK_Handle **csocks = NULL;
1475 struct GNUNET_NETWORK_Handle **lsocks;
1476 const char *nfds;
1477 unsigned int cnt;
1478 int flags;
1479 char dummy[2];
1480
1482 sh->service_name,
1483 "TOLERANT"))
1484 {
1485 if (GNUNET_SYSERR ==
1487 sh->service_name,
1488 "TOLERANT")))
1489 {
1491 _ ("Specified value for `%s' of service `%s' is invalid\n"),
1492 "TOLERANT",
1493 sh->service_name);
1494 return GNUNET_SYSERR;
1495 }
1496 }
1497 else
1498 tolerant = GNUNET_NO;
1499
1500 lsocks = NULL;
1501 errno = 0;
1502 if ( (NULL != (nfds = getenv ("LISTEN_FDS"))) &&
1503 (1 == sscanf (nfds, "%u%1s", &cnt, dummy)) && (cnt > 0) &&
1504 (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE))
1505 {
1506 lsocks = GNUNET_new_array (cnt + 1, struct GNUNET_NETWORK_Handle *);
1507 while (0 < cnt--)
1508 {
1509 flags = fcntl (3 + cnt, F_GETFD);
1510 if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) ||
1511 (NULL == (lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt))))
1512 {
1514 _ (
1515 "Could not access pre-bound socket %u, will try to bind myself\n"),
1516 (unsigned int) 3 + cnt);
1517 cnt++;
1518 while (NULL != lsocks[cnt])
1520 GNUNET_NETWORK_socket_close (lsocks[cnt++]));
1521 GNUNET_free (lsocks);
1522 lsocks = NULL;
1523 break;
1524 }
1525 }
1526 unsetenv ("LISTEN_FDS");
1527 }
1528 if ( (0 != (GNUNET_SERVICE_OPTION_CLOSE_LSOCKS & sh->options)) &&
1529 (NULL != lsocks) )
1530 {
1531 csocks = lsocks;
1532 lsocks = NULL;
1533 }
1534
1535 if (NULL != lsocks)
1536 {
1537 /* listen only on inherited sockets if we have any */
1538 for (struct GNUNET_NETWORK_Handle **ls = lsocks; NULL != *ls; ls++)
1539 {
1540 struct ServiceListenContext *slc;
1541
1542 slc = GNUNET_new (struct ServiceListenContext);
1543 slc->sh = sh;
1544 slc->listen_socket = *ls;
1546 sh->slc_tail,
1547 slc);
1548 }
1549 GNUNET_free (lsocks);
1550 }
1551 else
1552 {
1553 struct sockaddr **addrs;
1554 socklen_t *addrlens;
1555 int num;
1556
1557 num = get_server_addresses (sh->service_name, sh->cfg, &addrs, &addrlens);
1558 if (GNUNET_SYSERR == num)
1559 {
1560 GNUNET_free (csocks);
1561 return GNUNET_SYSERR;
1562 }
1563
1564 for (int i = 0; i < num; i++)
1565 {
1566 struct ServiceListenContext *slc;
1567
1568 slc = GNUNET_new (struct ServiceListenContext);
1569 slc->sh = sh;
1570 slc->listen_socket = open_listen_socket (addrs[i],
1571 addrlens[i]);
1572 GNUNET_free (addrs[i]);
1573 if (NULL == slc->listen_socket)
1574 {
1576 GNUNET_free (slc);
1577 continue;
1578 }
1580 sh->slc_tail,
1581 slc);
1582 }
1583 GNUNET_free (addrlens);
1584 GNUNET_free (addrs);
1585 if ((0 != num) && (NULL == sh->slc_head))
1586 {
1587 /* All attempts to bind failed, hard failure */
1588 GNUNET_log (
1590 _ (
1591 "Could not bind to any of the ports I was supposed to, refusing to run!\n"));
1592 GNUNET_free (csocks);
1593 return GNUNET_SYSERR;
1594 }
1595 }
1596 if (NULL != csocks)
1597 {
1598 /* close inherited sockets to signal parent that we are ready */
1599 for (struct GNUNET_NETWORK_Handle **ls = csocks; NULL != *ls; ls++)
1601 GNUNET_free (csocks);
1602 }
1603 sh->require_found = (GNUNET_NO == tolerant);
1605 sh->service_name,
1606 "UNIX_MATCH_UID");
1608 sh->service_name,
1609 "UNIX_MATCH_GID");
1610 process_acl4 (&sh->v4_denied, sh, "REJECT_FROM");
1611 process_acl4 (&sh->v4_allowed, sh, "ACCEPT_FROM");
1612 process_acl6 (&sh->v6_denied, sh, "REJECT_FROM6");
1613 process_acl6 (&sh->v6_allowed, sh, "ACCEPT_FROM6");
1614 return GNUNET_OK;
1615}
1616
1617
1625static char *
1627{
1628 char *un;
1629
1630 if (GNUNET_OK !=
1632 sh->service_name,
1633 "USERNAME",
1634 &un))
1635 return NULL;
1636 return un;
1637}
1638
1639
1646static enum GNUNET_GenericReturnValue
1648{
1649 char *user;
1650 struct passwd *pws;
1651
1652 if (NULL == (user = get_user_name (sh)))
1653 return GNUNET_OK; /* keep */
1654 errno = 0;
1655 pws = getpwnam (user);
1656 if (NULL == pws)
1657 {
1659 _ ("Cannot obtain information about user `%s': %s\n"),
1660 user,
1661 errno == 0 ? _ ("No such user") : strerror (errno));
1662 GNUNET_free (user);
1663 return GNUNET_SYSERR;
1664 }
1665 if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) ||
1666#if HAVE_INITGROUPS
1667 (0 != initgroups (user, pws->pw_gid)) ||
1668#endif
1669 (0 != setuid (pws->pw_uid)) ||
1670 (0 != seteuid (pws->pw_uid)))
1671 {
1672 if ((0 != setregid (pws->pw_gid, pws->pw_gid)) ||
1673 (0 != setreuid (pws->pw_uid, pws->pw_uid)))
1674 {
1676 _ ("Cannot change user/group to `%s': %s\n"),
1677 user,
1678 strerror (errno));
1679 GNUNET_free (user);
1680 return GNUNET_SYSERR;
1681 }
1682 }
1683
1684 GNUNET_free (user);
1685 return GNUNET_OK;
1686}
1687
1688
1696static char *
1698{
1699 char *pif;
1700
1701 if (GNUNET_OK !=
1703 sh->service_name,
1704 "PIDFILE",
1705 &pif))
1706 return NULL;
1707 return pif;
1708}
1709
1710
1716static void
1718{
1719 char *pif = get_pid_file_name (sh);
1720
1721 if (NULL == pif)
1722 return; /* no PID file */
1723 if (0 != unlink (pif))
1725 "unlink",
1726 pif);
1727 GNUNET_free (pif);
1728}
1729
1730
1737static enum GNUNET_GenericReturnValue
1739{
1740 pid_t pid;
1741 int nullfd;
1742 int filedes[2];
1743
1744 if (0 != pipe (filedes))
1745 {
1747 "pipe");
1748 return GNUNET_SYSERR;
1749 }
1750 pid = fork ();
1751 if (pid < 0)
1752 {
1754 "fork");
1755 return GNUNET_SYSERR;
1756 }
1757 if (0 != pid)
1758 {
1759 /* Parent */
1760 char c;
1761
1762 GNUNET_break (0 == close (filedes[1]));
1763 c = 'X';
1764 if (1 != read (filedes[0], &c, sizeof(char)))
1766 "read");
1767 fflush (stdout);
1768 switch (c)
1769 {
1770 case '.':
1771 exit (0);
1772
1773 case 'I':
1775 _ ("Service process failed to initialize\n"));
1776 break;
1777
1778 case 'S':
1780 _ ("Service process could not initialize server function\n"));
1781 break;
1782
1783 case 'X':
1785 _ ("Service process failed to report status\n"));
1786 break;
1787 }
1788 exit (1); /* child reported error */
1789 }
1790 GNUNET_break (0 == close (0));
1791 GNUNET_break (0 == close (1));
1792 GNUNET_break (0 == close (filedes[0]));
1793 nullfd = open ("/dev/null", O_RDWR | O_APPEND);
1794 if (nullfd < 0)
1795 return GNUNET_SYSERR;
1796 /* set stdin/stdout to /dev/null */
1797 if ((dup2 (nullfd, 0) < 0) || (dup2 (nullfd, 1) < 0))
1798 {
1800 (void) close (nullfd);
1801 return GNUNET_SYSERR;
1802 }
1803 (void) close (nullfd);
1804 /* Detach from controlling terminal */
1805 pid = setsid ();
1806 if (-1 == pid)
1808 "setsid");
1809 sh->ready_confirm_fd = filedes[1];
1810
1811 return GNUNET_OK;
1812}
1813
1814
1821static void
1823{
1824 struct ServiceListenContext *slc;
1825
1826 GNUNET_free (sh->v4_denied);
1827 GNUNET_free (sh->v6_denied);
1828 GNUNET_free (sh->v4_allowed);
1829 GNUNET_free (sh->v6_allowed);
1830 while (NULL != (slc = sh->slc_head))
1831 {
1833 sh->slc_tail,
1834 slc);
1835 if (NULL != slc->listen_task)
1839 GNUNET_free (slc);
1840 }
1841}
1842
1843
1850static void
1851return_agpl (void *cls,
1852 const struct GNUNET_MessageHeader *msg)
1853{
1854 struct GNUNET_SERVICE_Client *client = cls;
1855 struct GNUNET_MQ_Handle *mq;
1856 struct GNUNET_MQ_Envelope *env;
1857 struct GNUNET_MessageHeader *res;
1858 size_t slen;
1860
1861 (void) msg;
1862 slen = strlen (pd->agpl_url) + 1;
1865 memcpy (&res[1],
1867 slen);
1871}
1872
1873
1874struct GNUNET_SERVICE_Handle *
1876 const struct GNUNET_CONFIGURATION_Handle *cfg,
1879 void *cls,
1880 const struct GNUNET_MQ_MessageHandler *handlers)
1881{
1882 struct GNUNET_SERVICE_Handle *sh;
1883
1885 sh->service_name = service_name;
1886 sh->cfg = cfg;
1887 sh->connect_cb = connect_cb;
1888 sh->disconnect_cb = disconnect_cb;
1889 sh->cb_cls = cls;
1891 &return_agpl,
1892 NULL);
1893 if (GNUNET_OK != setup_service (sh))
1894 {
1895 GNUNET_free (sh->handlers);
1896 GNUNET_free (sh);
1897 return NULL;
1898 }
1899 do_resume (sh,
1901 return sh;
1902}
1903
1904
1910static void
1912{
1913 struct GNUNET_SERVICE_Client *c = cls;
1914 struct GNUNET_SERVICE_Handle *sh = c->sh;
1915
1916 c->drop_task = NULL;
1917 GNUNET_CONTAINER_DLL_remove (sh->clients_head,
1918 sh->clients_tail,
1919 c);
1920 GNUNET_assert (NULL == c->send_task);
1921 GNUNET_assert (NULL == c->recv_task);
1922 GNUNET_assert (NULL == c->warn_task);
1924 GNUNET_MQ_destroy (c->mq);
1925 if (! c->persist)
1926 {
1929 if ((0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) &&
1930 (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)))
1931 do_resume (sh,
1933 }
1934 else
1935 {
1937 }
1938 GNUNET_free (c);
1939 if ((0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) &&
1942}
1943
1944
1945void
1947{
1948 struct GNUNET_SERVICE_Client *client;
1949
1951 while (NULL != (client = srv->clients_head))
1952 {
1953 if (NULL == client->drop_task)
1956 finish_client_drop (client);
1957 }
1958 teardown_service (srv);
1959 GNUNET_free (srv->handlers);
1960 GNUNET_free (srv);
1961}
1962
1963
1964int
1966 char *const *argv,
1967 const char *service_name,
1969 GNUNET_SERVICE_InitCallback service_init_cb,
1972 void *cls,
1973 const struct GNUNET_MQ_MessageHandler *handlers)
1974{
1976
1977#if ENABLE_NLS
1978 char *path;
1979#endif
1980 char *cfg_filename;
1981 char *opt_cfg_filename;
1982 char *loglev;
1983 const char *xdg;
1984 char *logfile;
1985 int do_daemonize;
1986 unsigned long long skew_offset;
1987 unsigned long long skew_variance;
1988 long long clock_offset;
1990 int ret;
1991 int err;
1993 struct GNUNET_GETOPT_CommandLineOption service_options[] = {
1994 GNUNET_GETOPT_option_cfgfile (&opt_cfg_filename),
1996 "daemonize",
1997 gettext_noop (
1998 "do daemonize (detach from terminal)"),
1999 &do_daemonize),
2005 };
2006
2007 err = 1;
2008 memset (&sh, 0, sizeof(sh));
2009 xdg = getenv ("XDG_CONFIG_HOME");
2010 if (NULL != xdg)
2012 "%s%s%s",
2013 xdg,
2015 pd->config_file);
2016 else
2018 sh.ready_confirm_fd = -1;
2019 sh.options = options;
2021 sh.service_init_cb = service_init_cb;
2022 sh.connect_cb = connect_cb;
2023 sh.disconnect_cb = disconnect_cb;
2024 sh.cb_cls = cls;
2025 sh.handlers = (NULL == pd->agpl_url)
2028 sh.service_name = service_name;
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 }
2047 }
2048#endif
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 }
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 ==
2082 {
2083 if (GNUNET_SYSERR ==
2085 cfg_filename))
2086 {
2088 _ ("Malformed configuration file `%s', exit ...\n"),
2089 cfg_filename);
2090 goto shutdown;
2091 }
2092 }
2093 else
2094 {
2095 if (GNUNET_SYSERR ==
2097 NULL))
2098 {
2100 _ ("Malformed configuration, exit ...\n"));
2101 goto shutdown;
2102 }
2103 }
2104 }
2105 if (GNUNET_OK != setup_service (&sh))
2106 goto shutdown;
2107 if ( (1 == do_daemonize) &&
2108 (GNUNET_OK != detach_terminal (&sh)) )
2109 {
2110 GNUNET_break (0);
2111 goto shutdown;
2112 }
2113 if (GNUNET_OK != set_user_id (&sh))
2114 goto shutdown;
2116 "Service `%s' runs with configuration from `%s'\n",
2118 (NULL != opt_cfg_filename) ? opt_cfg_filename : cfg_filename);
2119 if ( (GNUNET_OK ==
2121 "TESTING",
2122 "SKEW_OFFSET",
2123 &skew_offset)) &&
2124 (GNUNET_OK ==
2126 "TESTING",
2127 "SKEW_VARIANCE",
2128 &skew_variance)) )
2129 {
2130 clock_offset = skew_offset - skew_variance;
2131 GNUNET_TIME_set_offset (clock_offset);
2133 "Skewing clock by %lld ms\n",
2134 (long long) clock_offset);
2135 }
2137
2138 /* actually run service */
2139 err = 0;
2141 /* shutdown */
2142 if (1 == do_daemonize)
2144
2145shutdown:
2146 if (-1 != sh.ready_confirm_fd)
2147 {
2148 if (1 != write (sh.ready_confirm_fd, err ? "I" : "S", 1))
2150 GNUNET_break (0 == close (sh.ready_confirm_fd));
2151 }
2153 GNUNET_free (sh.handlers);
2156 GNUNET_free (logfile);
2157 GNUNET_free (loglev);
2159 GNUNET_free (opt_cfg_filename);
2160
2161 return err ? GNUNET_SYSERR : 0;
2162}
2163
2164
2170{
2171 /* DLL */
2173
2174 /* DLL */
2176
2177 /* Handle to the service to launch */
2179};
2180
2181/* The service list */
2183
2184/* The service list */
2186
2187
2188int
2191 GNUNET_SERVICE_InitCallback service_init_cb,
2194 void *cls,
2195 const struct GNUNET_MQ_MessageHandler *handlers)
2196{
2197 struct ServiceHandleList *hle;
2200
2201 sh->ready_confirm_fd = -1;
2202 sh->options = options;
2203 sh->service_init_cb = service_init_cb;
2204 sh->connect_cb = connect_cb;
2205 sh->disconnect_cb = disconnect_cb;
2206 sh->cb_cls = cls;
2207 sh->handlers = (NULL == pd->agpl_url)
2210 sh->service_name = service_name;
2211 hle = GNUNET_new (struct ServiceHandleList);
2212 hle->sh = sh;
2214 hll_tail,
2215 hle);
2216 return 0;
2217}
2218
2219
2220static void
2222{
2223 while (NULL != hll_head)
2224 {
2225 struct ServiceHandleList *shl = hll_head;
2226 struct GNUNET_SERVICE_Handle *sh = shl->sh;
2227
2229 hll_tail,
2230 shl);
2231 GNUNET_free (shl);
2232 if (-1 != sh->ready_confirm_fd)
2233 {
2234 if (1 != write (sh->ready_confirm_fd, "S", 1))
2236 "write");
2237 GNUNET_break (0 ==
2238 close (sh->ready_confirm_fd));
2239 }
2241 GNUNET_free (sh->handlers);
2242 GNUNET_free (sh);
2243 }
2244}
2245
2246
2247static void
2249{
2250 struct GNUNET_CONFIGURATION_Handle *cfg = cls;
2251
2252 for (struct ServiceHandleList *shl = hll_head;
2253 NULL != shl;
2254 shl = shl->next)
2255 {
2256 shl->sh->cfg = cfg;
2257 if (GNUNET_OK != setup_service (shl->sh))
2258 continue;
2259 if (GNUNET_OK != set_user_id (shl->sh))
2260 continue;
2262 shl->sh);
2263 }
2265 NULL);
2266}
2267
2268
2269void
2271 char *const *argv,
2273 enum GNUNET_GenericReturnValue with_scheduler)
2274{
2276 "Entering GNUNET_SERVICE_main\n");
2277 if (GNUNET_YES == with_scheduler)
2278 {
2280 argv,
2281 cfg))
2282 return;
2284 cfg);
2285 }
2286 else
2288
2290
2291}
2292
2293
2294void
2296{
2297 do_suspend (sh,
2299}
2300
2301
2302void
2304{
2305 do_resume (sh,
2307}
2308
2309
2316static void
2318{
2319 struct GNUNET_SERVICE_Client *c = cls;
2320 int ret;
2321
2322 c->recv_task = NULL;
2323 /* first, check if there is still something in the buffer */
2324 ret = GNUNET_MST_next (c->mst,
2325 GNUNET_YES);
2326 if (GNUNET_SYSERR == ret)
2327 {
2328 if (NULL == c->drop_task)
2330 return;
2331 }
2332 if (GNUNET_NO == ret)
2333 return; /* done processing, wait for more later */
2335 if (c->needs_continue)
2336 return; /* #GNUNET_MST_next() did give a message to the client */
2337 /* need to receive more data from the network first */
2338 if (NULL != c->recv_task)
2339 return;
2341 c->sock,
2343 c);
2344}
2345
2346
2347void
2349{
2350 GNUNET_assert (NULL == c->drop_task);
2352 GNUNET_assert (NULL == c->recv_task);
2353 c->needs_continue = false;
2354 if (NULL != c->warn_task)
2355 {
2357 c->warn_task = NULL;
2358 }
2360 c);
2361}
2362
2363
2364void
2366{
2367 GNUNET_break (NULL != c->warn_task);
2368 if (NULL != c->warn_task)
2369 {
2371 c->warn_task = NULL;
2372 }
2373}
2374
2375
2376void
2378{
2379 struct GNUNET_SERVICE_Handle *sh = c->sh;
2380
2382 "Client dropped: %p (MQ: %p)\n",
2383 c,
2384 c->mq);
2385#if EXECINFO
2386 {
2387 void *backtrace_array[MAX_TRACE_DEPTH];
2388 int num_backtrace_strings = backtrace (backtrace_array,
2389 MAX_TRACE_DEPTH);
2390 char **backtrace_strings =
2391 backtrace_symbols (backtrace_array,
2392 t->num_backtrace_strings);
2393 for (unsigned int i = 0; i < num_backtrace_strings; i++)
2395 "client drop trace %u: %s\n",
2396 i,
2397 backtrace_strings[i]);
2398 }
2399#endif
2400 GNUNET_assert (NULL == c->drop_task);
2401 if (NULL != sh->disconnect_cb)
2402 sh->disconnect_cb (sh->cb_cls,
2403 c,
2404 c->user_context);
2405 if (NULL != c->warn_task)
2406 {
2408 c->warn_task = NULL;
2409 }
2410 if (NULL != c->recv_task)
2411 {
2413 c->recv_task = NULL;
2414 }
2415 if (NULL != c->send_task)
2416 {
2418 c->send_task = NULL;
2419 }
2421 c);
2422}
2423
2424
2425void
2427{
2428 if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN))
2429 do_suspend (sh,
2431 for (struct GNUNET_SERVICE_Client *client = sh->clients_head;
2432 NULL != client;
2433 client = client->next)
2434 {
2435 if (NULL == client->drop_task)
2437 }
2438}
2439
2440
2441void
2443{
2444 c->is_monitor = true;
2445 if (((0 != (SUSPEND_STATE_SHUTDOWN & c->sh->suspend_state)) &&
2446 (! have_non_monitor_clients (c->sh))))
2448}
2449
2450
2451void
2453{
2454 c->persist = true;
2455}
2456
2457
2458struct GNUNET_MQ_Handle *
2460{
2461 return c->mq;
2462}
2463
2464
2465/* 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_MessageHandlers handlers[]
Definition: 003.c:1
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
char * getenv()
#define gettext_noop(String)
Definition: gettext.h:74
#define textdomain(Domainname)
Definition: gettext.h:61
#define bindtextdomain(Domainname, Dirname)
Definition: gettext.h:62
static int list
Set if we should print a list of currently running services.
Definition: gnunet-arm.c:68
static int ret
Final status code.
Definition: gnunet-arm.c:93
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:108
static char * cfg_filename
Name of the configuration file.
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
static struct GNUNET_IDENTITY_Handle * sh
Handle to IDENTITY service.
static char * res
Currently read line or NULL on EOF.
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 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 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:50
static struct GNUNET_SCHEDULER_Task * t
Main task.
Constants for network protocols.
Functions related to doing DNS lookups.
#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.
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.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_create(void)
Create a new configuration object.
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:483
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:583
#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:884
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)
#define GNUNET_is_zero(a)
Check that memory in a is all zeros.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#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.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#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.
enum GNUNET_GenericReturnValue GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
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(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
#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:269
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:482
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:305
#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:63
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:992
struct GNUNET_MQ_MessageHandler * GNUNET_MQ_copy_handlers(const struct GNUNET_MQ_MessageHandler *handlers)
Copy an array of handlers.
Definition: mq.c:974
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:437
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:187
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:461
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:506
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:700
@ GNUNET_MQ_ERROR_NO_MATCH
We received a message for which we have no matching handler.
@ GNUNET_MQ_ERROR_WRITE
FIXME: document!
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
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
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
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:580
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:833
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:566
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:738
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:652
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,...
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_get(void)
@ GNUNET_OS_IPK_LOCALEDIR
Return the directory where translations are installed (share/locale/)
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_conf_and_options(int argc, char *const *argv, struct GNUNET_CONFIGURATION_Handle *cfg)
Create configuration handle from options and configuration file.
Definition: program.c:420
#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:258
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:1510
void GNUNET_SCHEDULER_run(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Initialize and run scheduler.
Definition: scheduler.c:724
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:1581
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:1338
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:979
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:1303
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:1276
enum GNUNET_GenericReturnValue 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:387
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:86
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:404
enum GNUNET_GenericReturnValue 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:338
void GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh)
Suspend accepting connections from the listen socket temporarily.
Definition: service.c:2295
void GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv)
Stops a service that was started with GNUNET_SERVICE_start().
Definition: service.c:1946
void GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh)
Explicitly stops the service.
Definition: service.c:2426
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:2442
void GNUNET_SERVICE_main(int argc, char *const *argv, struct GNUNET_CONFIGURATION_Handle *cfg, enum GNUNET_GenericReturnValue with_scheduler)
Run the mainloop in a monolithic libgnunet.
Definition: service.c:2270
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:1875
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_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2377
void GNUNET_SERVICE_client_persist(struct GNUNET_SERVICE_Client *c)
Set the persist option on this client.
Definition: service.c:2452
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:2365
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_ConnectHandler)(void *cls, struct GNUNET_SERVICE_Client *c, struct GNUNET_MQ_Handle *mq)
Callback to be called when a client connects to the service.
int GNUNET_SERVICE_register_(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)
Registers the GNUnet service to be scheduled as part of a monilithic libgnunet.
Definition: service.c:2189
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2459
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2348
void GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh)
Resume accepting connections from the listen socket.
Definition: service.c:2303
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:1965
@ 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:1473
struct GNUNET_STRINGS_IPv4NetworkPolicy * GNUNET_STRINGS_parse_ipv4_policy(const char *routeListX)
Parse an IPv4 network policy.
Definition: strings.c:1298
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:138
#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:438
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
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
#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:49
#define DIR_SEPARATOR_STR
Definition: platform.h:166
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
static void do_registered_services_shutdown(void *cls)
Definition: service.c:2221
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:1697
static void do_resume(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
Resume accepting connections from the listen socket.
Definition: service.c:876
static bool 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:461
static void return_agpl(void *cls, const struct GNUNET_MessageHeader *msg)
Function to return link to AGPL source upon request.
Definition: service.c:1851
static void teardown_service(struct GNUNET_SERVICE_Handle *sh)
Tear down the service, closing the listen sockets and freeing the ACLs.
Definition: service.c:1822
static void service_client_recv(void *cls)
A client sent us data.
Definition: service.c:700
static void service_mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implementation function that cancels the currently sent message.
Definition: service.c:588
static void service_shutdown(void *cls)
Shutdown task triggered when a service should be terminated.
Definition: service.c:406
static enum GNUNET_GenericReturnValue setup_service(struct GNUNET_SERVICE_Handle *sh)
Setup service handle.
Definition: service.c:1471
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:2317
static enum GNUNET_GenericReturnValue detach_terminal(struct GNUNET_SERVICE_Handle *sh)
Detach from terminal.
Definition: service.c:1738
static void launch_registered_services(void *cls)
Definition: service.c:2248
static struct ServiceHandleList * hll_head
Definition: service.c:2182
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:560
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:1626
#define LOG_STRERROR_FILE(kind, syscall, filename)
Definition: service.c:44
static void start_client(struct GNUNET_SERVICE_Handle *sh, struct GNUNET_NETWORK_Handle *csock)
We have successfully accepted a connection from a client.
Definition: service.c:745
static void do_send(void *cls)
Task run when we are ready to transmit data to the client.
Definition: service.c:491
static enum GNUNET_GenericReturnValue process_acl4(struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, struct GNUNET_SERVICE_Handle *sh, const char *option)
Parse an IPv4 access control list.
Definition: service.c:936
static void finish_client_drop(void *cls)
Asynchronously finish dropping the client.
Definition: service.c:1911
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:669
static bool 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:438
static void pid_file_delete(struct GNUNET_SERVICE_Handle *sh)
Delete the PID file that was created by our parent.
Definition: service.c:1717
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:1061
static void do_suspend(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
Suspend accepting connections from the listen socket temporarily.
Definition: service.c:379
static void warn_no_client_continue(void *cls)
Task run to warn about missing calls to GNUNET_SERVICE_client_continue().
Definition: service.c:636
static enum GNUNET_GenericReturnValue set_user_id(struct GNUNET_SERVICE_Handle *sh)
Set user ID.
Definition: service.c:1647
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:611
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:1017
static void service_main(void *cls)
First task run by any service.
Definition: service.c:905
static enum GNUNET_GenericReturnValue process_acl6(struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, struct GNUNET_SERVICE_Handle *sh, const char *option)
Parse an IPv6 access control list.
Definition: service.c:977
static enum GNUNET_GenericReturnValue 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:355
#define LOG(kind,...)
Definition: service.c:39
#define LOG_STRERROR(kind, syscall)
Definition: service.c:41
static void accept_client(void *cls)
We have a client.
Definition: service.c:782
SuspendReason
Reasons why we might be suspended.
Definition: service.c:84
@ SUSPEND_STATE_SHUTDOWN
Suspension because service was permanently shutdown.
Definition: service.c:108
@ SUSPEND_STATE_APP
Application requested it.
Definition: service.c:93
@ SUSPEND_STATE_NONE
We are running normally.
Definition: service.c:88
@ SUSPEND_STATE_APP_AND_EMFILE
Both reasons, APP and EMFILE apply.
Definition: service.c:103
@ SUSPEND_STATE_EMFILE
OS ran out of file descriptors.
Definition: service.c:98
static struct ServiceHandleList * hll_tail
Definition: service.c:2185
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:1363
void GNUNET_SPEEDUP_stop_()
Stop tasks that modify clock behavior.
Definition: speedup.c:100
Definition of a command line option.
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
Definition: identity_api.c:101
void * cb_cls
Closure for cb.
Definition: identity_api.c:122
Handle to a message queue.
Definition: mq.c:87
Message handler for a specific message type.
Header for all communications.
Handle to a message stream tokenizer.
Definition: mst.c:45
handle to a socket
Definition: network.c:53
Project-specific data used to help the OS subsystem find installation paths.
const char * gettext_path
Gettext directory, e.g.
const char * gettext_domain
Gettext domain for localisation, e.g.
const char * agpl_url
URL pointing to the source code of the application.
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.
const char * version
String identifying the current project version.
Entry in list of pending tasks.
Definition: scheduler.c:135
Handle to a client that is connected to a service.
Definition: service.c:245
bool persist
Persist the file handle for this client no matter what happens, force the OS to close once the proces...
Definition: service.c:326
size_t msg_pos
Current position in msg at which we are transmitting.
Definition: service.c:319
struct GNUNET_SCHEDULER_Task * send_task
Task that transmit data to the client.
Definition: service.c:297
struct GNUNET_SCHEDULER_Task * drop_task
Task run to finish dropping the client after the stack has properly unwound.
Definition: service.c:286
struct GNUNET_TIME_Absolute warn_start
Time when we last gave a message from this client to the application.
Definition: service.c:314
struct GNUNET_NETWORK_Handle * sock
Socket of this client.
Definition: service.c:264
uint16_t warn_type
Type of last message processed (for warn_no_receive_done).
Definition: service.c:343
const struct GNUNET_MessageHeader * msg
Pointer to the message to be transmitted by send_task.
Definition: service.c:302
struct GNUNET_SCHEDULER_Task * warn_task
Task that warns about missing calls to GNUNET_SERVICE_client_continue().
Definition: service.c:280
struct GNUNET_SCHEDULER_Task * recv_task
Task that receives data from the client to pass it to the handlers.
Definition: service.c:292
struct GNUNET_SERVICE_Handle * sh
Service that this client belongs to.
Definition: service.c:259
struct GNUNET_SERVICE_Client * next
Kept in a DLL.
Definition: service.c:249
void * user_context
User context value, value returned from the connect callback.
Definition: service.c:308
bool needs_continue
Are we waiting for the application to call GNUNET_SERVICE_client_continue()?
Definition: service.c:338
bool is_monitor
Is this client a 'monitor' client that should not be counted when deciding on destroying the server d...
Definition: service.c:333
struct GNUNET_SERVICE_Client * prev
Kept in a DLL.
Definition: service.c:254
struct GNUNET_MQ_Handle * mq
Message queue for the client.
Definition: service.c:269
struct GNUNET_MessageStreamTokenizer * mst
Tokenizer we use for processing incoming data.
Definition: service.c:274
Handle to a service.
Definition: service.c:116
void * task_cls
Closure for task.
Definition: service.c:175
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_denied
IPv6 addresses that are not allowed to connect.
Definition: service.c:186
GNUNET_SERVICE_ConnectHandler connect_cb
Function to call when clients connect.
Definition: service.c:135
GNUNET_SERVICE_InitCallback service_init_cb
Main service-specific task to run.
Definition: service.c:130
int ready_confirm_fd
If we are daemonizing, this FD is set to the pipe to the parent.
Definition: service.c:231
struct GNUNET_SERVICE_Client * clients_tail
Our clients, kept in a DLL.
Definition: service.c:165
struct GNUNET_MQ_MessageHandler * handlers
Message handlers to use for all clients.
Definition: service.c:170
void * cb_cls
Closure for service_init_cb, connect_cb, disconnect_cb.
Definition: service.c:145
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_denied
IPv4 addresses that are not allowed to connect.
Definition: service.c:181
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_allowed
IPv6 addresses that are allowed to connect (if not set, all are allowed).
Definition: service.c:198
const char * service_name
Name of our service.
Definition: service.c:125
struct GNUNET_SERVICE_Client * clients_head
Our clients, kept in a DLL.
Definition: service.c:160
bool require_found
If true, consider unknown message types an error where the client is disconnected.
Definition: service.c:237
GNUNET_SERVICE_DisconnectHandler disconnect_cb
Function to call when clients disconnect / are disconnected.
Definition: service.c:140
enum GNUNET_SERVICE_Options options
Our options.
Definition: service.c:224
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:205
int match_gid
Do we require a matching GID for UNIX domain socket connections? Ignored if match_uid is GNUNET_YES.
Definition: service.c:214
struct ServiceListenContext * slc_head
DLL of listen sockets used to accept new connections.
Definition: service.c:150
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: service.c:120
enum SuspendReason suspend_state
Are we suspended, and if so, why?
Definition: service.c:219
struct ServiceListenContext * slc_tail
DLL of listen sockets used to accept new connections.
Definition: service.c:155
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_allowed
IPv4 addresses that are allowed to connect (if not set, all are allowed).
Definition: service.c:192
IPV4 network in CIDR notation.
network in CIDR notation for IPV6.
Time for absolute times used by GNUnet, in microseconds.
A list of service to be launched when GNUNET_SERVICE_main() is called.
Definition: service.c:2170
struct GNUNET_SERVICE_Handle * sh
Definition: service.c:2178
struct ServiceHandleList * next
Definition: service.c:2175
struct ServiceHandleList * prev
Definition: service.c:2172
Information the service tracks per listen operation.
Definition: service.c:52
struct ServiceListenContext * next
Kept in a DLL.
Definition: service.c:56
struct ServiceListenContext * prev
Kept in a DLL.
Definition: service.c:61
struct GNUNET_SCHEDULER_Task * listen_task
Task scheduled to do the listening.
Definition: service.c:76
struct GNUNET_NETWORK_Handle * listen_socket
Socket we are listening on.
Definition: service.c:71
struct GNUNET_SERVICE_Handle * sh
Service this listen context belongs to.
Definition: service.c:66