GNUnet  0.20.0
tcp_service_legacy.c File Reference
#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_protocols.h"
#include "gnunet_constants.h"
#include "gnunet_resolver_service.h"
Include dependency graph for tcp_service_legacy.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  LEGACY_SERVICE_Context
 Context for "service_task". More...
 

Macros

#define HANDLE_ERROR
 

Functions

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. More...
 
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. More...
 
static size_t write_test (void *cls, size_t size, void *buf)
 Send a 'TEST' message back to the client. More...
 
static void handle_test (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message)
 Handler for TEST message. More...
 
static int check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc, const struct sockaddr *addr, socklen_t addrlen)
 Check if access to the service is allowed from the given address. More...
 
static char * get_pid_file_name (struct LEGACY_SERVICE_Context *sctx)
 Get the name of the file where we will write the PID of the service. More...
 
static int process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, struct LEGACY_SERVICE_Context *sctx, const char *option)
 Parse an IPv4 access control list. More...
 
static int process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, struct LEGACY_SERVICE_Context *sctx, const char *option)
 Parse an IPv6 access control list. More...
 
static void add_unixpath (struct sockaddr **saddrs, socklen_t *saddrlens, const char *unixpath, int abstract)
 Add the given UNIX domain path as an address to the list (as the first entry). More...
 
int LEGACY_SERVICE_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. More...
 
static int setup_service (struct LEGACY_SERVICE_Context *sctx)
 Setup addr, addrlen, idle_timeout based on configuration! More...
 
static char * get_user_name (struct LEGACY_SERVICE_Context *sctx)
 Get the name of the user that'll be used to provide the service. More...
 
static int write_pid_file (struct LEGACY_SERVICE_Context *sctx, pid_t pid)
 Write PID file. More...
 
static void shutdown_task (void *cls)
 Task run during shutdown. More...
 
static void service_task (void *cls)
 Initial task for the service. More...
 
static int detach_terminal (struct LEGACY_SERVICE_Context *sctx)
 Detach from terminal. More...
 
static int set_user_id (struct LEGACY_SERVICE_Context *sctx)
 Set user ID. More...
 
static void pid_file_delete (struct LEGACY_SERVICE_Context *sctx)
 Delete the PID file that was created by our parent. More...
 
int LEGACY_SERVICE_run (int argc, char *const *argv, const char *service_name, enum LEGACY_SERVICE_Options options, LEGACY_SERVICE_Main task, void *task_cls)
 Run a standard GNUnet service startup sequence (initialize loggers and configuration, parse options). More...
 
struct LEGACY_SERVICE_ContextLEGACY_SERVICE_start (const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg, enum LEGACY_SERVICE_Options options)
 Run a service startup sequence within an existing initialized system. More...
 
struct GNUNET_SERVER_HandleLEGACY_SERVICE_get_server (struct LEGACY_SERVICE_Context *ctx)
 Obtain the server used by a service. More...
 
struct GNUNET_NETWORK_Handle *const * LEGACY_SERVICE_get_listen_sockets (struct LEGACY_SERVICE_Context *ctx)
 Get the NULL-terminated array of listen sockets for this service. More...
 
void LEGACY_SERVICE_stop (struct LEGACY_SERVICE_Context *sctx)
 Stop a service that was started with "LEGACY_SERVICE_start". More...
 

Variables

static const struct GNUNET_SERVER_MessageHandler defhandlers []
 Default handlers for all services. More...
 

Macro Definition Documentation

◆ HANDLE_ERROR

#define HANDLE_ERROR
Value:
do \
{ \
GNUNET_break (0); \
goto shutdown; \
} while (0)

Function Documentation

◆ check_ipv4_listed()

static int check_ipv4_listed ( const struct GNUNET_STRINGS_IPv4NetworkPolicy list,
const struct in_addr *  add 
)
static

Check if the given IP address is in the list of IP addresses.

Parameters
lista list of networks
addthe IP to check (in network byte order)
Returns
GNUNET_NO if the IP is not in the list, GNUNET_YES if it it is

Definition at line 48 of file tcp_service_legacy.c.

50 {
51  unsigned int i;
52 
53  if (NULL == list)
54  return GNUNET_NO;
55  i = 0;
56  while ((list[i].network.s_addr != 0) || (list[i].netmask.s_addr != 0))
57  {
58  if ((add->s_addr & list[i].netmask.s_addr) ==
59  (list[i].network.s_addr & list[i].netmask.s_addr))
60  return GNUNET_YES;
61  i++;
62  }
63  return GNUNET_NO;
64 }
static int list
Set if we should print a list of currently running services.
Definition: gnunet-arm.c:69
static int add
Desired action is to add a record.
@ GNUNET_YES
@ GNUNET_NO

References add, GNUNET_NO, GNUNET_YES, and list.

Referenced by check_access().

Here is the caller graph for this function:

◆ check_ipv6_listed()

static int check_ipv6_listed ( const struct GNUNET_STRINGS_IPv6NetworkPolicy list,
const struct in6_addr *  ip 
)
static

Check if the given IP address is in the list of IP addresses.

Parameters
lista list of networks
ipthe IP to check (in network byte order)
Returns
GNUNET_NO if the IP is not in the list, GNUNET_YES if it it is

Definition at line 75 of file tcp_service_legacy.c.

77 {
78  unsigned int i;
79  unsigned int j;
80  struct in6_addr zero;
81 
82  if (NULL == list)
83  return GNUNET_NO;
84  memset (&zero, 0, sizeof(struct in6_addr));
85  i = 0;
86 NEXT:
87  while (0 != memcmp (&zero, &list[i].network, sizeof(struct in6_addr)))
88  {
89  for (j = 0; j < sizeof(struct in6_addr) / sizeof(int); j++)
90  if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
91  (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
92  {
93  i++;
94  goto NEXT;
95  }
96  return GNUNET_YES;
97  }
98  return GNUNET_NO;
99 }
static const struct GNUNET_IDENTITY_PrivateKey zero
Public key of all zeros.

References GNUNET_NO, GNUNET_YES, consensus-simulation::int, list, and zero.

Referenced by check_access().

Here is the caller graph for this function:

◆ write_test()

static size_t write_test ( void *  cls,
size_t  size,
void *  buf 
)
static

Send a 'TEST' message back to the client.

Parameters
clsthe 'struct GNUNET_SERVER_Client' to send TEST to
sizenumber of bytes available in 'buf'
bufwhere to copy the message
Returns
number of bytes written to 'buf'

Definition at line 241 of file tcp_service_legacy.c.

242 {
243  struct GNUNET_SERVER_Client *client = cls;
244  struct GNUNET_MessageHeader *msg;
245 
246  if (size < sizeof(struct GNUNET_MessageHeader))
247  {
249  return 0; /* client disconnected */
250  }
251  msg = (struct GNUNET_MessageHeader *) buf;
252  msg->type = htons (GNUNET_MESSAGE_TYPE_TEST);
253  msg->size = htons (sizeof(struct GNUNET_MessageHeader));
255  return sizeof(struct GNUNET_MessageHeader);
256 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static char buf[2048]
@ GNUNET_OK
@ GNUNET_SYSERR
#define GNUNET_MESSAGE_TYPE_TEST
Test if service is online.
static unsigned int size
Size of the "table".
Definition: peer.c:68
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 for a client of the server
void GNUNET_SERVER_receive_done(struct GNUNET_SERVER_Client *client, int success)
Resume receiving from this client, we are done processing the current request.

References buf, GNUNET_MESSAGE_TYPE_TEST, GNUNET_OK, GNUNET_SERVER_receive_done(), GNUNET_SYSERR, msg, GNUNET_MessageHeader::size, size, and GNUNET_MessageHeader::type.

Here is the call graph for this function:

◆ handle_test()

static void handle_test ( void *  cls,
struct GNUNET_SERVER_Client client,
const struct GNUNET_MessageHeader message 
)
static

Handler for TEST message.

Parameters
clsclosure (refers to service)
clientidentification of the client
messagethe actual message

Definition at line 267 of file tcp_service_legacy.c.

270 {
271  /* simply bounce message back to acknowledge */
272  if (NULL ==
274  sizeof(struct GNUNET_MessageHeader),
276  &write_test,
277  client))
279 }
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_SERVER_TransmitHandle * GNUNET_SERVER_notify_transmit_ready(struct GNUNET_SERVER_Client *client, size_t size, struct GNUNET_TIME_Relative timeout, GNUNET_CONNECTION_TransmitReadyNotify callback, void *callback_cls)
Notify us when the server has enough space to transmit a message of the given size to the given clien...
static size_t write_test(void *cls, size_t size, void *buf)
Send a 'TEST' message back to the client.

◆ check_access()

static int check_access ( void *  cls,
const struct GNUNET_CONNECTION_Credentials uc,
const struct sockaddr *  addr,
socklen_t  addrlen 
)
static

Check if access to the service is allowed from the given address.

Parameters
clsclosure
uccredentials, if available, otherwise NULL
addraddress
addrlenlength of address
Returns
GNUNET_YES to allow, GNUNET_NO to deny, GNUNET_SYSERR for unknown address family (will be denied).

Definition at line 309 of file tcp_service_legacy.c.

313 {
314  struct LEGACY_SERVICE_Context *sctx = cls;
315  const struct sockaddr_in *i4;
316  const struct sockaddr_in6 *i6;
317  int ret;
318 
319  switch (addr->sa_family)
320  {
321  case AF_INET:
322  GNUNET_assert (addrlen == sizeof(struct sockaddr_in));
323  i4 = (const struct sockaddr_in *) addr;
324  ret = ((NULL == sctx->v4_allowed) ||
325  (check_ipv4_listed (sctx->v4_allowed, &i4->sin_addr))) &&
326  ((NULL == sctx->v4_denied) ||
327  (! check_ipv4_listed (sctx->v4_denied, &i4->sin_addr)));
328  break;
329 
330  case AF_INET6:
331  GNUNET_assert (addrlen == sizeof(struct sockaddr_in6));
332  i6 = (const struct sockaddr_in6 *) addr;
333  ret = ((NULL == sctx->v6_allowed) ||
334  (check_ipv6_listed (sctx->v6_allowed, &i6->sin6_addr))) &&
335  ((NULL == sctx->v6_denied) ||
336  (! check_ipv6_listed (sctx->v6_denied, &i6->sin6_addr)));
337  break;
338 
339  case AF_UNIX:
340  ret = GNUNET_OK; /* controlled using file-system ACL now */
341  break;
342 
343  default:
345  _ ("Unknown address family %d\n"),
346  addr->sa_family);
347  return GNUNET_SYSERR;
348  }
349  if (GNUNET_OK != ret)
350  {
352  _ ("Access from `%s' denied to service `%s'\n"),
353  GNUNET_a2s (addr, addrlen),
354  sctx->service_name);
355  }
356  return ret;
357 }
#define LOG(kind,...)
Definition: abd_api.c:38
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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).
@ GNUNET_ERROR_TYPE_WARNING
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
Context for "service_task".
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_allowed
IPv4 addresses that are allowed to connect (if not set, all are allowed).
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_denied
IPv4 addresses that are not allowed to connect.
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_denied
IPv6 addresses that are not allowed to connect.
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_allowed
IPv6 addresses that are allowed to connect (if not set, all are allowed).
const char * service_name
Name of our service.
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.
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.

References _, check_ipv4_listed(), check_ipv6_listed(), GNUNET_a2s(), GNUNET_assert, GNUNET_ERROR_TYPE_WARNING, GNUNET_OK, GNUNET_SYSERR, LOG, ret, LEGACY_SERVICE_Context::service_name, LEGACY_SERVICE_Context::v4_allowed, LEGACY_SERVICE_Context::v4_denied, LEGACY_SERVICE_Context::v6_allowed, and LEGACY_SERVICE_Context::v6_denied.

Referenced by LEGACY_SERVICE_start(), and service_task().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_pid_file_name()

static char* get_pid_file_name ( struct LEGACY_SERVICE_Context sctx)
static

Get the name of the file where we will write the PID of the service.

Parameters
sctxservice context
Returns
name of the file for the process ID

Definition at line 368 of file tcp_service_legacy.c.

369 {
370  char *pif;
371 
373  sctx->service_name,
374  "PIDFILE",
375  &pif))
376  return NULL;
377  return pif;
378 }
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.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.

References LEGACY_SERVICE_Context::cfg, GNUNET_CONFIGURATION_get_value_filename(), GNUNET_OK, and LEGACY_SERVICE_Context::service_name.

Referenced by pid_file_delete(), and write_pid_file().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_acl4()

static int process_acl4 ( struct GNUNET_STRINGS_IPv4NetworkPolicy **  ret,
struct LEGACY_SERVICE_Context sctx,
const char *  option 
)
static

Parse an IPv4 access control list.

Parameters
retlocation where to write the ACL (set)
sctxservice context to use to get the configuration
optionname of the ACL option to parse
Returns
GNUNET_SYSERR on parse error, GNUNET_OK on success (including no ACL configured)

Definition at line 391 of file tcp_service_legacy.c.

394 {
395  char *opt;
396 
397  if (! GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, option))
398  {
399  *ret = NULL;
400  return GNUNET_OK;
401  }
404  sctx->service_name,
405  option,
406  &opt));
407  if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy (opt)))
408  {
410  _ ("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
411  opt,
412  sctx->service_name,
413  option);
414  GNUNET_free (opt);
415  return GNUNET_SYSERR;
416  }
417  GNUNET_free (opt);
418  return GNUNET_OK;
419 }
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_have_value(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Test if we have a value for a particular option.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_STRINGS_IPv4NetworkPolicy * GNUNET_STRINGS_parse_ipv4_policy(const char *routeListX)
Parse an IPv4 network policy.
Definition: strings.c:1290

References _, LEGACY_SERVICE_Context::cfg, GNUNET_break, GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_have_value(), GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_OK, GNUNET_STRINGS_parse_ipv4_policy(), GNUNET_SYSERR, LOG, ret, and LEGACY_SERVICE_Context::service_name.

Referenced by setup_service().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_acl6()

static int process_acl6 ( struct GNUNET_STRINGS_IPv6NetworkPolicy **  ret,
struct LEGACY_SERVICE_Context sctx,
const char *  option 
)
static

Parse an IPv6 access control list.

Parameters
retlocation where to write the ACL (set)
sctxservice context to use to get the configuration
optionname of the ACL option to parse
Returns
GNUNET_SYSERR on parse error, GNUNET_OK on success (including no ACL configured)

Definition at line 432 of file tcp_service_legacy.c.

435 {
436  char *opt;
437 
438  if (! GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, option))
439  {
440  *ret = NULL;
441  return GNUNET_OK;
442  }
445  sctx->service_name,
446  option,
447  &opt));
448  if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy (opt)))
449  {
451  _ ("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
452  opt,
453  sctx->service_name,
454  option);
455  GNUNET_free (opt);
456  return GNUNET_SYSERR;
457  }
458  GNUNET_free (opt);
459  return GNUNET_OK;
460 }
struct GNUNET_STRINGS_IPv6NetworkPolicy * GNUNET_STRINGS_parse_ipv6_policy(const char *routeListX)
Parse an IPv6 network policy.
Definition: strings.c:1471

References _, LEGACY_SERVICE_Context::cfg, GNUNET_break, GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_have_value(), GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_OK, GNUNET_STRINGS_parse_ipv6_policy(), GNUNET_SYSERR, LOG, ret, and LEGACY_SERVICE_Context::service_name.

Referenced by setup_service().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_unixpath()

static void add_unixpath ( struct sockaddr **  saddrs,
socklen_t *  saddrlens,
const char *  unixpath,
int  abstract 
)
static

Add the given UNIX domain path as an address to the list (as the first entry).

Parameters
saddrsarray to update
saddrlenswhere to store the address length
unixpathpath to add
abstractGNUNET_YES to add an abstract UNIX domain socket. This parameter is ignore on systems other than LINUX

Definition at line 474 of file tcp_service_legacy.c.

478 {
479 #ifdef AF_UNIX
480  struct sockaddr_un *un;
481 
482  un = GNUNET_new (struct sockaddr_un);
483  un->sun_family = AF_UNIX;
484  GNUNET_strlcpy (un->sun_path, unixpath, sizeof(un->sun_path));
485 #ifdef __linux__
486  if (GNUNET_YES == abstract)
487  un->sun_path[0] = '\0';
488 #endif
489 #if HAVE_SOCKADDR_UN_SUN_LEN
490  un->sun_len = (u_char) sizeof(struct sockaddr_un);
491 #endif
492  *saddrs = (struct sockaddr *) un;
493  *saddrlens = sizeof(struct sockaddr_un);
494 #else
495  /* this function should never be called
496  * unless AF_UNIX is defined! */
497  GNUNET_assert (0);
498 #endif
499 }
#define GNUNET_new(type)
Allocate a struct or union of the given type.
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:138

References GNUNET_assert, GNUNET_new, GNUNET_strlcpy(), and GNUNET_YES.

Referenced by LEGACY_SERVICE_get_server_addresses().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LEGACY_SERVICE_get_server_addresses()

int LEGACY_SERVICE_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.

Parameters
service_namename of the service
cfgconfiguration (which specifies the addresses)
addrsset (call by reference) to an array of pointers to the addresses the server should bind to and listen on; the array will be NULL-terminated (on success)
addr_lensset (call by reference) to an array of the lengths of the respective struct sockaddr struct in the addrs array (on success)
Returns
number of addresses found on success, GNUNET_SYSERR if the configuration did not specify reasonable finding information or if it specified a hostname that could not be resolved; GNUNET_NO if the number of addresses configured is zero (in this case, *addrs and *addr_lens will be set to NULL).

Definition at line 523 of file tcp_service_legacy.c.

528 {
529  int disablev6;
530  struct GNUNET_NETWORK_Handle *desc;
531  unsigned long long port;
532  char *unixpath;
533  struct addrinfo hints;
534  struct addrinfo *res;
535  struct addrinfo *pos;
536  struct addrinfo *next;
537  unsigned int i;
538  int resi;
539  int ret;
540  int abstract;
541  struct sockaddr **saddrs;
542  socklen_t *saddrlens;
543  char *hostname;
544 
545  *addrs = NULL;
546  *addr_lens = NULL;
547  desc = NULL;
549  {
550  if (GNUNET_SYSERR ==
552  service_name,
553  "DISABLEV6")))
554  return GNUNET_SYSERR;
555  }
556  else
557  disablev6 = GNUNET_NO;
558 
559  if (! disablev6)
560  {
561  /* probe IPv6 support */
562  desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
563  if (NULL == desc)
564  {
565  if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
566  (EACCES == errno))
567  {
569  return GNUNET_SYSERR;
570  }
572  _ (
573  "Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
574  service_name,
575  strerror (errno));
576  disablev6 = GNUNET_YES;
577  }
578  else
579  {
581  desc = NULL;
582  }
583  }
584 
585  port = 0;
587  {
589  service_name,
590  "PORT",
591  &port))
592  {
594  _ ("Require valid port number for service `%s' in configuration!\n"),
595  service_name);
596  }
597  if (port > 65535)
598  {
600  _ ("Require valid port number for service `%s' in configuration!\n"),
601  service_name);
602  return GNUNET_SYSERR;
603  }
604  }
605 
607  {
610  service_name,
611  "BINDTO",
612  &hostname));
613  }
614  else
615  hostname = NULL;
616 
617  unixpath = NULL;
618  abstract = GNUNET_NO;
619 #ifdef AF_UNIX
620  if ((GNUNET_YES ==
623  service_name,
624  "UNIXPATH",
625  &unixpath)) &&
626  (0 < strlen (unixpath)))
627  {
628  /* probe UNIX support */
629  struct sockaddr_un s_un;
630 
631  if (strlen (unixpath) >= sizeof(s_un.sun_path))
632  {
634  _ ("UNIXPATH `%s' too long, maximum length is %llu\n"),
635  unixpath,
636  (unsigned long long) sizeof(s_un.sun_path));
637  unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
638  LOG (GNUNET_ERROR_TYPE_INFO, _ ("Using `%s' instead\n"), unixpath);
639  }
640 #ifdef __linux__
642  "TESTING",
643  "USE_ABSTRACT_SOCKETS");
644  if (GNUNET_SYSERR == abstract)
645  abstract = GNUNET_NO;
646 #endif
647  if ((GNUNET_YES != abstract) &&
650  }
651  if (NULL != unixpath)
652  {
653  desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
654  if (NULL == desc)
655  {
656  if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
657  (EACCES == errno))
658  {
661  GNUNET_free (unixpath);
662  return GNUNET_SYSERR;
663  }
665  _ (
666  "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
667  service_name,
668  strerror (errno));
669  GNUNET_free (unixpath);
670  unixpath = NULL;
671  }
672  else
673  {
675  desc = NULL;
676  }
677  }
678 #endif
679 
680  if ((0 == port) && (NULL == unixpath))
681  {
683  _ (
684  "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
685  service_name);
687  return GNUNET_SYSERR;
688  }
689  if (0 == port)
690  {
691  saddrs = GNUNET_malloc (2 * sizeof(struct sockaddr *));
692  saddrlens = GNUNET_malloc (2 * sizeof(socklen_t));
693  add_unixpath (saddrs, saddrlens, unixpath, abstract);
694  GNUNET_free (unixpath);
696  *addrs = saddrs;
697  *addr_lens = saddrlens;
698  return 1;
699  }
700 
701  if (NULL != hostname)
702  {
704  "Resolving `%s' since that is where `%s' will bind to.\n",
705  hostname,
706  service_name);
707  memset (&hints, 0, sizeof(struct addrinfo));
708  if (disablev6)
709  hints.ai_family = AF_INET;
710  hints.ai_protocol = IPPROTO_TCP;
711  if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
712  (NULL == res))
713  {
715  _ ("Failed to resolve `%s': %s\n"),
716  hostname,
717  gai_strerror (ret));
719  GNUNET_free (unixpath);
720  return GNUNET_SYSERR;
721  }
722  next = res;
723  i = 0;
724  while (NULL != (pos = next))
725  {
726  next = pos->ai_next;
727  if ((disablev6) && (pos->ai_family == AF_INET6))
728  continue;
729  i++;
730  }
731  if (0 == i)
732  {
734  _ ("Failed to find %saddress for `%s'.\n"),
735  disablev6 ? "IPv4 " : "",
736  hostname);
737  freeaddrinfo (res);
739  GNUNET_free (unixpath);
740  return GNUNET_SYSERR;
741  }
742  resi = i;
743  if (NULL != unixpath)
744  resi++;
745  saddrs = GNUNET_malloc ((resi + 1) * sizeof(struct sockaddr *));
746  saddrlens = GNUNET_malloc ((resi + 1) * sizeof(socklen_t));
747  i = 0;
748  if (NULL != unixpath)
749  {
750  add_unixpath (saddrs, saddrlens, unixpath, abstract);
751  i++;
752  }
753  next = res;
754  while (NULL != (pos = next))
755  {
756  next = pos->ai_next;
757  if ((disablev6) && (AF_INET6 == pos->ai_family))
758  continue;
759  if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
760  continue; /* not TCP */
761  if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
762  continue; /* huh? */
764  "Service `%s' will bind to `%s'\n",
765  service_name,
766  GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
767  if (AF_INET == pos->ai_family)
768  {
769  GNUNET_assert (sizeof(struct sockaddr_in) == pos->ai_addrlen);
770  saddrlens[i] = pos->ai_addrlen;
771  saddrs[i] = GNUNET_malloc (saddrlens[i]);
772  GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
773  ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
774  }
775  else
776  {
777  GNUNET_assert (AF_INET6 == pos->ai_family);
778  GNUNET_assert (sizeof(struct sockaddr_in6) == pos->ai_addrlen);
779  saddrlens[i] = pos->ai_addrlen;
780  saddrs[i] = GNUNET_malloc (saddrlens[i]);
781  GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
782  ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
783  }
784  i++;
785  }
787  freeaddrinfo (res);
788  resi = i;
789  }
790  else
791  {
792  /* will bind against everything, just set port */
793  if (disablev6)
794  {
795  /* V4-only */
796  resi = 1;
797  if (NULL != unixpath)
798  resi++;
799  i = 0;
800  saddrs = GNUNET_malloc ((resi + 1) * sizeof(struct sockaddr *));
801  saddrlens = GNUNET_malloc ((resi + 1) * sizeof(socklen_t));
802  if (NULL != unixpath)
803  {
804  add_unixpath (saddrs, saddrlens, unixpath, abstract);
805  i++;
806  }
807  saddrlens[i] = sizeof(struct sockaddr_in);
808  saddrs[i] = GNUNET_malloc (saddrlens[i]);
809 #if HAVE_SOCKADDR_IN_SIN_LEN
810  ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
811 #endif
812  ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
813  ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
814  }
815  else
816  {
817  /* dual stack */
818  resi = 2;
819  if (NULL != unixpath)
820  resi++;
821  saddrs = GNUNET_malloc ((resi + 1) * sizeof(struct sockaddr *));
822  saddrlens = GNUNET_malloc ((resi + 1) * sizeof(socklen_t));
823  i = 0;
824  if (NULL != unixpath)
825  {
826  add_unixpath (saddrs, saddrlens, unixpath, abstract);
827  i++;
828  }
829  saddrlens[i] = sizeof(struct sockaddr_in6);
830  saddrs[i] = GNUNET_malloc (saddrlens[i]);
831 #if HAVE_SOCKADDR_IN_SIN_LEN
832  ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
833 #endif
834  ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
835  ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
836  i++;
837  saddrlens[i] = sizeof(struct sockaddr_in);
838  saddrs[i] = GNUNET_malloc (saddrlens[i]);
839 #if HAVE_SOCKADDR_IN_SIN_LEN
840  ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
841 #endif
842  ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
843  ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
844  }
845  }
846  GNUNET_free (unixpath);
847  *addrs = saddrs;
848  *addr_lens = saddrlens;
849  return resi;
850 }
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static int res
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
#define LOG_STRERROR(kind, syscall)
static char * hostname
Our hostname; we give this to all the peers we start.
static char * service_name
Option -s: service name (hash to get service descriptor)
Definition: gnunet-vpn.c:50
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.
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_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:582
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#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_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_malloc(size)
Wrapper around malloc.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:509
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:833
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:144
handle to a socket
Definition: network.c:54
static void add_unixpath(struct sockaddr **saddrs, socklen_t *saddrlens, const char *unixpath, int abstract)
Add the given UNIX domain path as an address to the list (as the first entry).

References _, add_unixpath(), cfg, GNUNET_a2s(), GNUNET_assert, GNUNET_break, GNUNET_CONFIGURATION_get_value_filename(), GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_CONFIGURATION_have_value(), GNUNET_DISK_directory_create_for_file(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log_strerror_file, GNUNET_malloc, GNUNET_memcpy, GNUNET_NETWORK_shorten_unixpath(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_create(), GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, hostname, LOG, LOG_STRERROR, port, res, ret, and service_name.

Referenced by setup_service().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setup_service()

static int setup_service ( struct LEGACY_SERVICE_Context sctx)
static

Setup addr, addrlen, idle_timeout based on configuration!

Configuration may specify:

  • PORT (where to bind to for TCP)
  • UNIXPATH (where to bind to for UNIX domain sockets)
  • TIMEOUT (after how many ms does an inactive service timeout);
  • DISABLEV6 (disable support for IPv6, otherwise we use dual-stack)
  • BINDTO (hostname or IP address to bind to, otherwise we take everything)
  • ACCEPT_FROM (only allow connections from specified IPv4 subnets)
  • ACCEPT_FROM6 (only allow connections from specified IPv6 subnets)
  • REJECT_FROM (disallow allow connections from specified IPv4 subnets)
  • REJECT_FROM6 (disallow allow connections from specified IPv6 subnets)
Parameters
sctxservice context to initialize
Returns
GNUNET_OK if configuration succeeded

Definition at line 872 of file tcp_service_legacy.c.

873 {
874  struct GNUNET_TIME_Relative idleout;
875  int tolerant;
876  const char *nfds;
877  unsigned int cnt;
878  int flags;
879 
881  sctx->service_name,
882  "TIMEOUT"))
883  {
885  sctx->service_name,
886  "TIMEOUT",
887  &idleout))
888  {
890  _ ("Specified value for `%s' of service `%s' is invalid\n"),
891  "TIMEOUT",
892  sctx->service_name);
893  return GNUNET_SYSERR;
894  }
895  sctx->timeout = idleout;
896  }
897  else
899 
901  sctx->service_name,
902  "TOLERANT"))
903  {
904  if (GNUNET_SYSERR ==
905  (tolerant = GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg,
906  sctx->service_name,
907  "TOLERANT")))
908  {
910  _ ("Specified value for `%s' of service `%s' is invalid\n"),
911  "TOLERANT",
912  sctx->service_name);
913  return GNUNET_SYSERR;
914  }
915  }
916  else
917  tolerant = GNUNET_NO;
918 
919  errno = 0;
920  if ((NULL != (nfds = getenv ("LISTEN_FDS"))) &&
921  (1 == sscanf (nfds, "%u", &cnt)) && (cnt > 0) && (cnt < FD_SETSIZE) &&
922  (cnt + 4 < FD_SETSIZE))
923  {
924  sctx->lsocks =
925  GNUNET_malloc (sizeof(struct GNUNET_NETWORK_Handle *) * (cnt + 1));
926  while (0 < cnt--)
927  {
928  flags = fcntl (3 + cnt, F_GETFD);
929  if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) ||
930  (NULL ==
931  (sctx->lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt))))
932  {
934  _ (
935  "Could not access pre-bound socket %u, will try to bind myself\n"),
936  (unsigned int) 3 + cnt);
937  cnt++;
938  while (sctx->lsocks[cnt] != NULL)
939  GNUNET_break (0 == GNUNET_NETWORK_socket_close (sctx->lsocks[cnt++]));
940  GNUNET_free (sctx->lsocks);
941  sctx->lsocks = NULL;
942  break;
943  }
944  }
945  unsetenv ("LISTEN_FDS");
946  }
947 
948  if ((NULL == sctx->lsocks) &&
950  sctx->cfg,
951  &sctx->addrs,
952  &sctx->addrlens)))
953  return GNUNET_SYSERR;
954  sctx->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
956  sctx->service_name,
957  "UNIX_MATCH_UID");
959  sctx->service_name,
960  "UNIX_MATCH_GID");
961  process_acl4 (&sctx->v4_denied, sctx, "REJECT_FROM");
962  process_acl4 (&sctx->v4_allowed, sctx, "ACCEPT_FROM");
963  process_acl6 (&sctx->v6_denied, sctx, "REJECT_FROM6");
964  process_acl6 (&sctx->v6_allowed, sctx, "ACCEPT_FROM6");
965 
966  return GNUNET_OK;
967 }
char * getenv()
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
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
Time for relative time used by GNUnet, in microseconds.
struct sockaddr ** addrs
NULL-terminated array of addresses to bind to, NULL if we got pre-bound listen sockets.
struct GNUNET_TIME_Relative timeout
Idle timeout for server.
int require_found
Do we close connections if we receive messages for which we have no handler?
int match_uid
Do we require a matching UID for UNIX domain socket connections? GNUNET_NO means that the UID does no...
int match_gid
Do we require a matching GID for UNIX domain socket connections? Ignored if match_uid is GNUNET_YES.
struct GNUNET_NETWORK_Handle ** lsocks
NULL-terminated array of listen sockets we should take over.
socklen_t * addrlens
Array of the lengths of the entries in addrs.
static int process_acl4(struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, struct LEGACY_SERVICE_Context *sctx, const char *option)
Parse an IPv4 access control list.
static int process_acl6(struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, struct LEGACY_SERVICE_Context *sctx, const char *option)
Parse an IPv6 access control list.
int LEGACY_SERVICE_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.

References _, LEGACY_SERVICE_Context::addrlens, LEGACY_SERVICE_Context::addrs, LEGACY_SERVICE_Context::cfg, getenv(), GNUNET_break, GNUNET_CONFIGURATION_get_value_time(), GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_CONFIGURATION_have_value(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_malloc, GNUNET_NETWORK_socket_box_native(), GNUNET_NETWORK_socket_close(), GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, LEGACY_SERVICE_get_server_addresses(), LOG, LEGACY_SERVICE_Context::lsocks, LEGACY_SERVICE_Context::match_gid, LEGACY_SERVICE_Context::match_uid, process_acl4(), process_acl6(), LEGACY_SERVICE_Context::require_found, LEGACY_SERVICE_Context::service_name, LEGACY_SERVICE_Context::timeout, LEGACY_SERVICE_Context::v4_allowed, LEGACY_SERVICE_Context::v4_denied, LEGACY_SERVICE_Context::v6_allowed, and LEGACY_SERVICE_Context::v6_denied.

Referenced by LEGACY_SERVICE_run(), and LEGACY_SERVICE_start().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_user_name()

static char* get_user_name ( struct LEGACY_SERVICE_Context sctx)
static

Get the name of the user that'll be used to provide the service.

Parameters
sctxservice context
Returns
value of the 'USERNAME' option

Definition at line 978 of file tcp_service_legacy.c.

979 {
980  char *un;
981 
983  sctx->service_name,
984  "USERNAME",
985  &un))
986  return NULL;
987  return un;
988 }

References LEGACY_SERVICE_Context::cfg, GNUNET_CONFIGURATION_get_value_filename(), GNUNET_OK, and LEGACY_SERVICE_Context::service_name.

Referenced by set_user_id(), and write_pid_file().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ write_pid_file()

static int write_pid_file ( struct LEGACY_SERVICE_Context sctx,
pid_t  pid 
)
static

Write PID file.

Parameters
sctxservice context
pidPID to write (should be equal to 'getpid()'
Returns
GNUNET_OK on success (including no work to be done)

Definition at line 999 of file tcp_service_legacy.c.

1000 {
1001  FILE *pidfd;
1002  char *pif;
1003  char *user;
1004  char *rdir;
1005  int len;
1006 
1007  if (NULL == (pif = get_pid_file_name (sctx)))
1008  return GNUNET_OK; /* no file desired */
1009  user = get_user_name (sctx);
1010  rdir = GNUNET_strdup (pif);
1011  len = strlen (rdir);
1012  while ((len > 0) && (rdir[len] != DIR_SEPARATOR))
1013  len--;
1014  rdir[len] = '\0';
1015  if (0 != access (rdir, F_OK))
1016  {
1017  /* we get to create a directory -- and claim it
1018  * as ours! */
1019  (void) GNUNET_DISK_directory_create (rdir);
1020  if ((NULL != user) && (0 < strlen (user)))
1021  GNUNET_DISK_file_change_owner (rdir, user);
1022  }
1023  if (0 != access (rdir, W_OK | X_OK))
1024  {
1025  LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", rdir);
1026  GNUNET_free (rdir);
1027  GNUNET_free (user);
1028  GNUNET_free (pif);
1029  return GNUNET_SYSERR;
1030  }
1031  GNUNET_free (rdir);
1032  pidfd = fopen (pif, "w");
1033  if (NULL == pidfd)
1034  {
1036  GNUNET_free (pif);
1037  GNUNET_free (user);
1038  return GNUNET_SYSERR;
1039  }
1040  if (0 > fprintf (pidfd, "%u", pid))
1041  LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fprintf", pif);
1042  GNUNET_break (0 == fclose (pidfd));
1043  if ((NULL != user) && (0 < strlen (user)))
1044  GNUNET_DISK_file_change_owner (pif, user);
1045  GNUNET_free (user);
1046  GNUNET_free (pif);
1047  return GNUNET_OK;
1048 }
#define LOG_STRERROR_FILE(kind, op, fn)
Definition: datacache.c:34
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_change_owner(const char *filename, const char *user)
Change owner of a file.
Definition: disk.c:1213
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:496
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define DIR_SEPARATOR
Definition: platform.h:165
static char * get_user_name(struct LEGACY_SERVICE_Context *sctx)
Get the name of the user that'll be used to provide the service.
static char * get_pid_file_name(struct LEGACY_SERVICE_Context *sctx)
Get the name of the file where we will write the PID of the service.

References DIR_SEPARATOR, get_pid_file_name(), get_user_name(), GNUNET_break, GNUNET_DISK_directory_create(), GNUNET_DISK_file_change_owner(), GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_OK, GNUNET_strdup, GNUNET_SYSERR, len, LOG_STRERROR_FILE, and pid.

Referenced by service_task().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ shutdown_task()

static void shutdown_task ( void *  cls)
static

Task run during shutdown.

Stops the server/service.

Parameters
clsthe struct LEGACY_SERVICE_Context

Definition at line 1057 of file tcp_service_legacy.c.

1058 {
1059  struct LEGACY_SERVICE_Context *service = cls;
1060  struct GNUNET_SERVER_Handle *server = service->server;
1061 
1062  service->shutdown_task = NULL;
1065  else
1066  GNUNET_SERVER_destroy (server);
1067 }
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
void GNUNET_SERVER_destroy(struct GNUNET_SERVER_Handle *server)
Free resources held by this server.
@ LEGACY_SERVICE_OPTION_SOFT_SHUTDOWN
Trigger a SOFT server shutdown on signals, allowing active non-monitor clients to complete their tran...
handle for a server
enum GNUNET_SERVICE_Options options
Our options.
Definition: service.c:226
void GNUNET_SERVER_stop_listening(struct GNUNET_SERVER_Handle *server)
Stop the listen socket and get ready to shutdown the server once only 'monitor' clients are left.

References GNUNET_SERVER_destroy(), GNUNET_SERVER_stop_listening(), LEGACY_SERVICE_OPTION_SOFT_SHUTDOWN, GNUNET_SERVICE_Handle::options, and service.

Referenced by service_task().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ service_task()

static void service_task ( void *  cls)
static

Initial task for the service.

Parameters
clsservice context

Definition at line 1076 of file tcp_service_legacy.c.

1077 {
1078  struct LEGACY_SERVICE_Context *sctx = cls;
1079  unsigned int i;
1080 
1081  GNUNET_RESOLVER_connect (sctx->cfg);
1082  if (NULL != sctx->lsocks)
1084  sctx,
1085  sctx->lsocks,
1086  sctx->timeout,
1087  sctx->require_found);
1088  else
1090  sctx,
1091  sctx->addrs,
1092  sctx->addrlens,
1093  sctx->timeout,
1094  sctx->require_found);
1095  if (NULL == sctx->server)
1096  {
1097  if (NULL != sctx->addrs)
1098  for (i = 0; NULL != sctx->addrs[i]; i++)
1100  _ ("Failed to start `%s' at `%s'\n"),
1101  sctx->service_name,
1102  GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
1103  sctx->ret = GNUNET_SYSERR;
1104  return;
1105  }
1106 
1107  if (NULL != sctx->addrs)
1108  for (i = 0; NULL != sctx->addrs[i]; i++)
1109  if ((AF_UNIX == sctx->addrs[i]->sa_family) &&
1110  ('\0' != ((const struct sockaddr_un *) sctx->addrs[i])->sun_path[0]))
1111  GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)
1112  sctx->addrs[i])
1113  ->sun_path,
1114  sctx->match_uid,
1115  sctx->match_gid);
1116 
1118  {
1119  /* install a task that will kill the server
1120  * process if the scheduler ever gets a shutdown signal */
1122  }
1123  sctx->my_handlers = GNUNET_malloc (sizeof(defhandlers));
1125  i = 0;
1126  while (NULL != sctx->my_handlers[i].callback)
1127  sctx->my_handlers[i++].callback_cls = sctx;
1129  if (-1 != sctx->ready_confirm_fd)
1130  {
1131  GNUNET_break (1 == write (sctx->ready_confirm_fd, ".", 1));
1132  GNUNET_break (0 == close (sctx->ready_confirm_fd));
1133  sctx->ready_confirm_fd = -1;
1134  write_pid_file (sctx, getpid ());
1135  }
1136  if (NULL != sctx->addrs)
1137  {
1138  i = 0;
1139  while (NULL != sctx->addrs[i])
1140  {
1142  _ ("Service `%s' runs at %s\n"),
1143  sctx->service_name,
1144  GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
1145  i++;
1146  }
1147  }
1148  sctx->task (sctx->task_cls, sctx->server, sctx->cfg);
1149 }
void GNUNET_DISK_fix_permissions(const char *fn, int require_uid_match, int require_gid_match)
Update POSIX permissions mask of a file on disk.
Definition: disk.c:320
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_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:1334
@ LEGACY_SERVICE_OPTION_MANUAL_SHUTDOWN
Do not trigger server shutdown on signal at all; instead, allow for the user to terminate the server ...
GNUNET_SERVER_MessageCallback callback
Function to call for messages of "type".
void * callback_cls
Closure argument for callback.
LEGACY_SERVICE_Main task
Main service-specific task to run.
void * task_cls
Closure for task.
int ret
Overall success/failure of the service start.
int ready_confirm_fd
If we are daemonizing, this FD is set to the pipe to the parent.
struct GNUNET_SERVER_Handle * server
Handle for the server.
struct GNUNET_SCHEDULER_Task * shutdown_task
Task ID of the shutdown task.
struct GNUNET_SERVER_MessageHandler * my_handlers
My (default) message handlers.
enum LEGACY_SERVICE_Options options
Our options.
void GNUNET_SERVER_add_handlers(struct GNUNET_SERVER_Handle *server, const struct GNUNET_SERVER_MessageHandler *handlers)
Add additional handlers to an existing server.
struct GNUNET_SERVER_Handle * GNUNET_SERVER_create_with_sockets(GNUNET_CONNECTION_AccessCheck access_cb, void *access_cb_cls, struct GNUNET_NETWORK_Handle **lsocks, struct GNUNET_TIME_Relative idle_timeout, int require_found)
Create a new server.
struct GNUNET_SERVER_Handle * GNUNET_SERVER_create(GNUNET_CONNECTION_AccessCheck access_cb, void *access_cb_cls, struct sockaddr *const *server_addr, const socklen_t *socklen, struct GNUNET_TIME_Relative idle_timeout, int require_found)
Create a new server.
static int write_pid_file(struct LEGACY_SERVICE_Context *sctx, pid_t pid)
Write PID file.
static int check_access(void *cls, const struct GNUNET_CONNECTION_Credentials *uc, const struct sockaddr *addr, socklen_t addrlen)
Check if access to the service is allowed from the given address.
static const struct GNUNET_SERVER_MessageHandler defhandlers[]
Default handlers for all services.
static void shutdown_task(void *cls)
Task run during shutdown.

References _, LEGACY_SERVICE_Context::addrlens, LEGACY_SERVICE_Context::addrs, GNUNET_SERVER_MessageHandler::callback, GNUNET_SERVER_MessageHandler::callback_cls, LEGACY_SERVICE_Context::cfg, check_access(), defhandlers, GNUNET_a2s(), GNUNET_break, GNUNET_DISK_fix_permissions(), GNUNET_ERROR_TYPE_INFO, GNUNET_malloc, GNUNET_memcpy, GNUNET_RESOLVER_connect(), GNUNET_SCHEDULER_add_shutdown(), GNUNET_SERVER_add_handlers(), GNUNET_SERVER_create(), GNUNET_SERVER_create_with_sockets(), GNUNET_SYSERR, LEGACY_SERVICE_OPTION_MANUAL_SHUTDOWN, LOG, LEGACY_SERVICE_Context::lsocks, LEGACY_SERVICE_Context::match_gid, LEGACY_SERVICE_Context::match_uid, LEGACY_SERVICE_Context::my_handlers, LEGACY_SERVICE_Context::options, LEGACY_SERVICE_Context::ready_confirm_fd, LEGACY_SERVICE_Context::require_found, LEGACY_SERVICE_Context::ret, LEGACY_SERVICE_Context::server, LEGACY_SERVICE_Context::service_name, LEGACY_SERVICE_Context::shutdown_task, shutdown_task(), LEGACY_SERVICE_Context::task, LEGACY_SERVICE_Context::task_cls, LEGACY_SERVICE_Context::timeout, and write_pid_file().

Referenced by LEGACY_SERVICE_run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ detach_terminal()

static int detach_terminal ( struct LEGACY_SERVICE_Context sctx)
static

Detach from terminal.

Parameters
sctxservice context
Returns
GNUNET_OK on success, GNUNET_SYSERR on error

Definition at line 1159 of file tcp_service_legacy.c.

1160 {
1161  pid_t pid;
1162  int nullfd;
1163  int filedes[2];
1164 
1165  if (0 != pipe (filedes))
1166  {
1168  return GNUNET_SYSERR;
1169  }
1170  pid = fork ();
1171  if (pid < 0)
1172  {
1174  return GNUNET_SYSERR;
1175  }
1176  if (0 != pid)
1177  {
1178  /* Parent */
1179  char c;
1180 
1181  GNUNET_break (0 == close (filedes[1]));
1182  c = 'X';
1183  if (1 != read (filedes[0], &c, sizeof(char)))
1185  fflush (stdout);
1186  switch (c)
1187  {
1188  case '.':
1189  exit (0);
1190 
1191  case 'I':
1193  _ ("Service process failed to initialize\n"));
1194  break;
1195 
1196  case 'S':
1198  _ ("Service process could not initialize server function\n"));
1199  break;
1200 
1201  case 'X':
1203  _ ("Service process failed to report status\n"));
1204  break;
1205  }
1206  exit (1); /* child reported error */
1207  }
1208  GNUNET_break (0 == close (0));
1209  GNUNET_break (0 == close (1));
1210  GNUNET_break (0 == close (filedes[0]));
1211  nullfd = open ("/dev/null", O_RDWR | O_APPEND);
1212  if (nullfd < 0)
1213  return GNUNET_SYSERR;
1214  /* set stdin/stdout to /dev/null */
1215  if ((dup2 (nullfd, 0) < 0) || (dup2 (nullfd, 1) < 0))
1216  {
1218  (void) close (nullfd);
1219  return GNUNET_SYSERR;
1220  }
1221  (void) close (nullfd);
1222  /* Detach from controlling terminal */
1223  pid = setsid ();
1224  if (-1 == pid)
1226  sctx->ready_confirm_fd = filedes[1];
1227 
1228  return GNUNET_OK;
1229 }

References _, GNUNET_break, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_OK, GNUNET_SYSERR, LOG, LOG_STRERROR, pid, and LEGACY_SERVICE_Context::ready_confirm_fd.

Referenced by LEGACY_SERVICE_run().

Here is the caller graph for this function:

◆ set_user_id()

static int set_user_id ( struct LEGACY_SERVICE_Context sctx)
static

Set user ID.

Parameters
sctxservice context
Returns
GNUNET_OK on success, GNUNET_SYSERR on error

Definition at line 1239 of file tcp_service_legacy.c.

1240 {
1241  char *user;
1242 
1243  if (NULL == (user = get_user_name (sctx)))
1244  return GNUNET_OK; /* keep */
1245 
1246  struct passwd *pws;
1247 
1248  errno = 0;
1249  pws = getpwnam (user);
1250  if (NULL == pws)
1251  {
1253  _ ("Cannot obtain information about user `%s': %s\n"),
1254  user,
1255  errno == 0 ? _ ("No such user") : strerror (errno));
1256  GNUNET_free (user);
1257  return GNUNET_SYSERR;
1258  }
1259  if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) ||
1260 #if HAVE_INITGROUPS
1261  (0 != initgroups (user, pws->pw_gid)) ||
1262 #endif
1263  (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid)))
1264  {
1265  if ((0 != setregid (pws->pw_gid, pws->pw_gid)) ||
1266  (0 != setreuid (pws->pw_uid, pws->pw_uid)))
1267  {
1269  _ ("Cannot change user/group to `%s': %s\n"),
1270  user,
1271  strerror (errno));
1272  GNUNET_free (user);
1273  return GNUNET_SYSERR;
1274  }
1275  }
1276 
1277  GNUNET_free (user);
1278  return GNUNET_OK;
1279 }

References _, get_user_name(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_OK, GNUNET_SYSERR, and LOG.

Referenced by LEGACY_SERVICE_run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pid_file_delete()

static void pid_file_delete ( struct LEGACY_SERVICE_Context sctx)
static

Delete the PID file that was created by our parent.

Parameters
sctxservice context

Definition at line 1288 of file tcp_service_legacy.c.

1289 {
1290  char *pif = get_pid_file_name (sctx);
1291 
1292  if (NULL == pif)
1293  return; /* no PID file */
1294  if (0 != unlink (pif))
1296  GNUNET_free (pif);
1297 }

References get_pid_file_name(), GNUNET_ERROR_TYPE_WARNING, GNUNET_free, and LOG_STRERROR_FILE.

Referenced by LEGACY_SERVICE_run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LEGACY_SERVICE_run()

int LEGACY_SERVICE_run ( int  argc,
char *const *  argv,
const char *  service_name,
enum LEGACY_SERVICE_Options  options,
LEGACY_SERVICE_Main  task,
void *  task_cls 
)

Run a standard GNUnet service startup sequence (initialize loggers and configuration, parse options).

Parameters
argcnumber of command line arguments
argvcommand line arguments
service_nameour service name
optionsservice options
taskmain task of the service
task_clsclosure for task
Returns
GNUNET_SYSERR on error, GNUNET_OK if we shutdown nicely

Definition at line 1314 of file tcp_service_legacy.c.

1320 {
1321 #define HANDLE_ERROR \
1322  do \
1323  { \
1324  GNUNET_break (0); \
1325  goto shutdown; \
1326  } while (0)
1327 
1328  int err;
1329  int ret;
1330  char *cfg_fn;
1331  char *opt_cfg_fn;
1332  char *loglev;
1333  char *logfile;
1334  int do_daemonize;
1335  unsigned int i;
1336  unsigned long long skew_offset;
1337  unsigned long long skew_variance;
1338  long long clock_offset;
1339  struct LEGACY_SERVICE_Context sctx;
1341  const char *xdg;
1342 
1343  struct GNUNET_GETOPT_CommandLineOption service_options[] =
1344  { GNUNET_GETOPT_option_cfgfile (&opt_cfg_fn),
1346  "daemonize",
1347  gettext_noop (
1348  "do daemonize (detach from terminal)"),
1349  &do_daemonize),
1352  GNUNET_GETOPT_option_logfile (&logfile),
1353  GNUNET_GETOPT_option_version (PACKAGE_VERSION " " VCS_VERSION),
1355  err = 1;
1356  do_daemonize = 0;
1357  logfile = NULL;
1358  loglev = NULL;
1359  opt_cfg_fn = NULL;
1360  xdg = getenv ("XDG_CONFIG_HOME");
1361  if (NULL != xdg)
1362  GNUNET_asprintf (&cfg_fn,
1363  "%s%s%s",
1364  xdg,
1367  else
1368  cfg_fn = GNUNET_strdup (GNUNET_OS_project_data_get ()->user_config_file);
1369  memset (&sctx, 0, sizeof(sctx));
1370  sctx.options = options;
1371  sctx.ready_confirm_fd = -1;
1372  sctx.ret = GNUNET_OK;
1373  sctx.timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1374  sctx.task = task;
1375  sctx.task_cls = task_cls;
1376  sctx.service_name = service_name;
1377  sctx.cfg = cfg = GNUNET_CONFIGURATION_create ();
1378 
1379  /* setup subsystems */
1380  ret = GNUNET_GETOPT_run (service_name, service_options, argc, argv);
1381  if (GNUNET_SYSERR == ret)
1382  goto shutdown;
1383  if (GNUNET_NO == ret)
1384  {
1385  err = 0;
1386  goto shutdown;
1387  }
1388  if (GNUNET_OK != GNUNET_log_setup (service_name, loglev, logfile))
1389  HANDLE_ERROR;
1390  if (NULL == opt_cfg_fn)
1391  opt_cfg_fn = GNUNET_strdup (cfg_fn);
1392  if (GNUNET_YES == GNUNET_DISK_file_test (opt_cfg_fn))
1393  {
1394  if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_fn))
1395  {
1397  _ ("Malformed configuration file `%s', exit ...\n"),
1398  opt_cfg_fn);
1399  goto shutdown;
1400  }
1401  }
1402  else
1403  {
1405  {
1407  _ ("Malformed configuration, exit ...\n"));
1408  goto shutdown;
1409  }
1410  if (0 != strcmp (opt_cfg_fn, cfg_fn))
1412  _ ("Could not access configuration file `%s'\n"),
1413  opt_cfg_fn);
1414  }
1415  if (GNUNET_OK != setup_service (&sctx))
1416  goto shutdown;
1417  if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sctx)))
1418  HANDLE_ERROR;
1419  if (GNUNET_OK != set_user_id (&sctx))
1420  goto shutdown;
1422  "Service `%s' runs with configuration from `%s'\n",
1423  service_name,
1424  opt_cfg_fn);
1426  "TESTING",
1427  "SKEW_OFFSET",
1428  &skew_offset)) &&
1430  "TESTING",
1431  "SKEW_VARIANCE",
1432  &skew_variance)))
1433  {
1434  clock_offset = skew_offset - skew_variance;
1435  GNUNET_TIME_set_offset (clock_offset);
1436  LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %lld ms\n", clock_offset);
1437  }
1438  /* actually run service */
1439  err = 0;
1441  /* shutdown */
1442  if ((1 == do_daemonize) && (NULL != sctx.server))
1443  pid_file_delete (&sctx);
1444  GNUNET_free (sctx.my_handlers);
1445 
1446 shutdown:
1447  if (-1 != sctx.ready_confirm_fd)
1448  {
1449  if (1 != write (sctx.ready_confirm_fd, err ? "I" : "S", 1))
1451  GNUNET_break (0 == close (sctx.ready_confirm_fd));
1452  }
1453 #if HAVE_MALLINFO2
1454  {
1455  char *counter;
1456 
1457  if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value (sctx.cfg,
1458  service_name,
1459  "GAUGER_HEAP")) &&
1461  service_name,
1462  "GAUGER_HEAP",
1463  &counter)))
1464  {
1465  struct mallinfo2 mi;
1466 
1467  mi = mallinfo2 ();
1468  GAUGER (service_name, counter, mi.usmblks, "blocks");
1469  GNUNET_free (counter);
1470  }
1471  }
1472 #endif
1474  i = 0;
1475  if (NULL != sctx.addrs)
1476  while (NULL != sctx.addrs[i])
1477  GNUNET_free_nz (sctx.addrs[i++]);
1478  GNUNET_free (sctx.addrs);
1479  GNUNET_free (sctx.addrlens);
1480  GNUNET_free (logfile);
1481  GNUNET_free (loglev);
1482  GNUNET_free (cfg_fn);
1483  GNUNET_free (opt_cfg_fn);
1484  GNUNET_free (sctx.v4_denied);
1485  GNUNET_free (sctx.v6_denied);
1486  GNUNET_free (sctx.v4_allowed);
1487  GNUNET_free (sctx.v6_allowed);
1488 
1489  return err ? GNUNET_SYSERR : sctx.ret;
1490 }
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
#define GAUGER(category, counter, value, unit)
Definition: gauger.h:19
#define gettext_noop(String)
Definition: gettext.h:70
static char * config_file
Set to the name of the config file used.
Definition: gnunet-arm.c:84
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_load(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Load configuration.
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
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_log(kind,...)
int GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_free_nz(ptr)
Wrapper around free.
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_get(void)
void GNUNET_SCHEDULER_run(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Initialize and run scheduler.
Definition: scheduler.c:720
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
Definition of a command line option.
static int detach_terminal(struct LEGACY_SERVICE_Context *sctx)
Detach from terminal.
static int set_user_id(struct LEGACY_SERVICE_Context *sctx)
Set user ID.
static void service_task(void *cls)
Initial task for the service.
static int setup_service(struct LEGACY_SERVICE_Context *sctx)
Setup addr, addrlen, idle_timeout based on configuration!
#define HANDLE_ERROR
static void pid_file_delete(struct LEGACY_SERVICE_Context *sctx)
Delete the PID file that was created by our parent.

References _, LEGACY_SERVICE_Context::addrlens, LEGACY_SERVICE_Context::addrs, cfg, LEGACY_SERVICE_Context::cfg, config_file, detach_terminal(), DIR_SEPARATOR_STR, GAUGER, getenv(), gettext_noop, GNUNET_asprintf(), GNUNET_break, GNUNET_CONFIGURATION_create(), GNUNET_CONFIGURATION_destroy(), GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_have_value(), GNUNET_CONFIGURATION_load(), GNUNET_DISK_file_test(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_free_nz, GNUNET_GETOPT_option_cfgfile(), GNUNET_GETOPT_OPTION_END, GNUNET_GETOPT_option_flag(), GNUNET_GETOPT_option_help(), GNUNET_GETOPT_option_logfile(), GNUNET_GETOPT_option_loglevel(), GNUNET_GETOPT_option_version(), GNUNET_GETOPT_run(), GNUNET_log, GNUNET_log_setup(), GNUNET_NO, GNUNET_OK, GNUNET_OS_project_data_get(), GNUNET_SCHEDULER_run(), GNUNET_strdup, GNUNET_SYSERR, GNUNET_TIME_set_offset(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, HANDLE_ERROR, LOG, LOG_STRERROR, LEGACY_SERVICE_Context::my_handlers, options, LEGACY_SERVICE_Context::options, pid_file_delete(), LEGACY_SERVICE_Context::ready_confirm_fd, ret, LEGACY_SERVICE_Context::ret, LEGACY_SERVICE_Context::server, LEGACY_SERVICE_Context::service_name, service_name, service_task(), set_user_id(), setup_service(), LEGACY_SERVICE_Context::task, LEGACY_SERVICE_Context::task_cls, LEGACY_SERVICE_Context::timeout, LEGACY_SERVICE_Context::v4_allowed, LEGACY_SERVICE_Context::v4_denied, LEGACY_SERVICE_Context::v6_allowed, and LEGACY_SERVICE_Context::v6_denied.

Here is the call graph for this function:

◆ LEGACY_SERVICE_start()

struct LEGACY_SERVICE_Context* LEGACY_SERVICE_start ( const char *  service_name,
const struct GNUNET_CONFIGURATION_Handle cfg,
enum LEGACY_SERVICE_Options  options 
)

Run a service startup sequence within an existing initialized system.

Parameters
service_nameour service name
cfgconfiguration to use
optionsservice options
Returns
NULL on error, service handle

Definition at line 1503 of file tcp_service_legacy.c.

1506 {
1507  int i;
1508  struct LEGACY_SERVICE_Context *sctx;
1509 
1510  sctx = GNUNET_new (struct LEGACY_SERVICE_Context);
1511  sctx->ready_confirm_fd = -1; /* no daemonizing */
1512  sctx->ret = GNUNET_OK;
1514  sctx->service_name = service_name;
1515  sctx->cfg = cfg;
1516  sctx->options = options;
1517 
1518  /* setup subsystems */
1519  if (GNUNET_OK != setup_service (sctx))
1520  {
1521  LEGACY_SERVICE_stop (sctx);
1522  return NULL;
1523  }
1524  if (NULL != sctx->lsocks)
1526  sctx,
1527  sctx->lsocks,
1528  sctx->timeout,
1529  sctx->require_found);
1530  else
1532  sctx,
1533  sctx->addrs,
1534  sctx->addrlens,
1535  sctx->timeout,
1536  sctx->require_found);
1537 
1538  if (NULL == sctx->server)
1539  {
1540  LEGACY_SERVICE_stop (sctx);
1541  return NULL;
1542  }
1543 
1544  if (NULL != sctx->addrs)
1545  for (i = 0; NULL != sctx->addrs[i]; i++)
1546  if ((AF_UNIX == sctx->addrs[i]->sa_family) &&
1547  ('\0' != ((const struct sockaddr_un *) sctx->addrs[i])->sun_path[0]))
1548  GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)
1549  sctx->addrs[i])
1550  ->sun_path,
1551  sctx->match_uid,
1552  sctx->match_gid);
1553 
1554  sctx->my_handlers = GNUNET_malloc (sizeof(defhandlers));
1556  i = 0;
1557  while ((sctx->my_handlers[i].callback != NULL))
1558  sctx->my_handlers[i++].callback_cls = sctx;
1560  return sctx;
1561 }
void LEGACY_SERVICE_stop(struct LEGACY_SERVICE_Context *sctx)
Stop a service that was started with "LEGACY_SERVICE_start".

References LEGACY_SERVICE_Context::addrlens, LEGACY_SERVICE_Context::addrs, GNUNET_SERVER_MessageHandler::callback, GNUNET_SERVER_MessageHandler::callback_cls, cfg, LEGACY_SERVICE_Context::cfg, check_access(), defhandlers, GNUNET_DISK_fix_permissions(), GNUNET_malloc, GNUNET_memcpy, GNUNET_new, GNUNET_OK, GNUNET_SERVER_add_handlers(), GNUNET_SERVER_create(), GNUNET_SERVER_create_with_sockets(), GNUNET_TIME_UNIT_FOREVER_REL, LEGACY_SERVICE_stop(), LEGACY_SERVICE_Context::lsocks, LEGACY_SERVICE_Context::match_gid, LEGACY_SERVICE_Context::match_uid, LEGACY_SERVICE_Context::my_handlers, options, LEGACY_SERVICE_Context::options, LEGACY_SERVICE_Context::ready_confirm_fd, LEGACY_SERVICE_Context::require_found, LEGACY_SERVICE_Context::ret, LEGACY_SERVICE_Context::server, LEGACY_SERVICE_Context::service_name, service_name, setup_service(), and LEGACY_SERVICE_Context::timeout.

Referenced by libgnunet_plugin_transport_tcp_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LEGACY_SERVICE_get_server()

struct GNUNET_SERVER_Handle* LEGACY_SERVICE_get_server ( struct LEGACY_SERVICE_Context ctx)

Obtain the server used by a service.

Note that the server must NOT be destroyed by the caller.

Parameters
ctxthe service context returned from the start function
Returns
handle to the server for this service, NULL if there is none

Definition at line 1572 of file tcp_service_legacy.c.

1573 {
1574  return ctx->server;
1575 }
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.

References ctx.

Referenced by libgnunet_plugin_transport_tcp_init().

Here is the caller graph for this function:

◆ LEGACY_SERVICE_get_listen_sockets()

struct GNUNET_NETWORK_Handle* const* LEGACY_SERVICE_get_listen_sockets ( struct LEGACY_SERVICE_Context ctx)

Get the NULL-terminated array of listen sockets for this service.

Parameters
ctxservice context to query
Returns
NULL if there are no listen sockets, otherwise NULL-terminated array of listen sockets.

Definition at line 1586 of file tcp_service_legacy.c.

1587 {
1588  return ctx->lsocks;
1589 }

References ctx.

Referenced by libgnunet_plugin_transport_tcp_init().

Here is the caller graph for this function:

◆ LEGACY_SERVICE_stop()

void LEGACY_SERVICE_stop ( struct LEGACY_SERVICE_Context sctx)

Stop a service that was started with "LEGACY_SERVICE_start".

Stops a service that was started with GNUNET_SERVICE_start().

Parameters
sctxthe service context returned from the start function

Definition at line 1598 of file tcp_service_legacy.c.

1599 {
1600  unsigned int i;
1601 
1602 #if HAVE_MALLINFO2
1603  {
1604  char *counter;
1605 
1607  sctx->service_name,
1608  "GAUGER_HEAP")) &&
1610  sctx->service_name,
1611  "GAUGER_HEAP",
1612  &counter)))
1613  {
1614  struct mallinfo2 mi;
1615 
1616  mi = mallinfo2 ();
1617  GAUGER (sctx->service_name, counter, mi.usmblks, "blocks");
1618  GNUNET_free (counter);
1619  }
1620  }
1621 #endif
1622  if (NULL != sctx->shutdown_task)
1623  {
1625  sctx->shutdown_task = NULL;
1626  }
1627  if (NULL != sctx->server)
1628  GNUNET_SERVER_destroy (sctx->server);
1629  GNUNET_free (sctx->my_handlers);
1630  if (NULL != sctx->addrs)
1631  {
1632  i = 0;
1633  while (NULL != sctx->addrs[i])
1634  GNUNET_free_nz (sctx->addrs[i++]);
1635  GNUNET_free (sctx->addrs);
1636  }
1637  GNUNET_free (sctx->addrlens);
1638  GNUNET_free (sctx->v4_denied);
1639  GNUNET_free (sctx->v6_denied);
1640  GNUNET_free (sctx->v4_allowed);
1641  GNUNET_free (sctx->v6_allowed);
1642  GNUNET_free (sctx);
1643 }
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975

References LEGACY_SERVICE_Context::addrlens, LEGACY_SERVICE_Context::addrs, LEGACY_SERVICE_Context::cfg, GAUGER, GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_have_value(), GNUNET_free, GNUNET_free_nz, GNUNET_OK, GNUNET_SCHEDULER_cancel(), GNUNET_SERVER_destroy(), GNUNET_YES, LEGACY_SERVICE_Context::my_handlers, LEGACY_SERVICE_Context::server, LEGACY_SERVICE_Context::service_name, LEGACY_SERVICE_Context::shutdown_task, LEGACY_SERVICE_Context::v4_allowed, LEGACY_SERVICE_Context::v4_denied, LEGACY_SERVICE_Context::v6_allowed, and LEGACY_SERVICE_Context::v6_denied.

Referenced by LEGACY_SERVICE_start(), libgnunet_plugin_transport_tcp_done(), and libgnunet_plugin_transport_tcp_init().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ defhandlers

const struct GNUNET_SERVER_MessageHandler defhandlers[]
static
Initial value:
=
NULL,
sizeof(struct GNUNET_MessageHeader) },
{ NULL, NULL, 0, 0 } }
static void handle_test(void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message)
Handler for TEST message.

Default handlers for all services.

Will be copied and the "callback_cls" fields will be replaced with the specific service struct.

Definition at line 267 of file tcp_service_legacy.c.

Referenced by LEGACY_SERVICE_start(), and service_task().