GNUnet  0.10.x
Data Structures | Macros | Enumerations | Functions
service.c File Reference

functions related to starting services More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_protocols.h"
#include "gnunet_constants.h"
#include "gnunet_resolver_service.h"
#include "speedup.h"
Include dependency graph for service.c:

Go to the source code of this file.

Data Structures

struct  ServiceListenContext
 Information the service tracks per listen operation. More...
 
struct  GNUNET_SERVICE_Handle
 Handle to a service. More...
 
struct  GNUNET_SERVICE_Client
 Handle to a client that is connected to a service. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "util-service", __VA_ARGS__)
 
#define LOG_STRERROR(kind, syscall)   GNUNET_log_from_strerror (kind, "util-service", syscall)
 
#define LOG_STRERROR_FILE(kind, syscall, filename)   GNUNET_log_from_strerror_file (kind, "util-service", syscall, filename)
 

Enumerations

enum  SuspendReason {
  SUSPEND_STATE_NONE = 0, SUSPEND_STATE_APP = 1, SUSPEND_STATE_EMFILE = 2, SUSPEND_STATE_APP_AND_EMFILE = 3,
  SUSPEND_STATE_SHUTDOWN = 4
}
 Reasons why we might be suspended. More...
 

Functions

static int have_non_monitor_clients (struct GNUNET_SERVICE_Handle *sh)
 Check if any of the clients we have left are unrelated to monitoring. More...
 
static void do_suspend (struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
 Suspend accepting connections from the listen socket temporarily. More...
 
static void service_shutdown (void *cls)
 Shutdown task triggered when a service should be terminated. More...
 
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 void do_send (void *cls)
 Task run when we are ready to transmit data to the client. More...
 
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. More...
 
static void service_mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
 Implementation function that cancels the currently sent message. More...
 
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 creation of the message queue. More...
 
static void warn_no_client_continue (void *cls)
 Task run to warn about missing calls to GNUNET_SERVICE_client_continue(). More...
 
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 a client. More...
 
static void service_client_recv (void *cls)
 A client sent us data. More...
 
static void start_client (struct GNUNET_SERVICE_Handle *sh, struct GNUNET_NETWORK_Handle *csock)
 We have successfully accepted a connection from a client. More...
 
static void accept_client (void *cls)
 We have a client. More...
 
static void do_resume (struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
 Resume accepting connections from the listen socket. More...
 
static void service_main (void *cls)
 First task run by any service. More...
 
static int process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, struct GNUNET_SERVICE_Handle *sh, const char *option)
 Parse an IPv4 access control list. More...
 
static int process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, struct GNUNET_SERVICE_Handle *sh, 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...
 
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. More...
 
static struct GNUNET_NETWORK_Handleopen_listen_socket (const struct sockaddr *server_addr, socklen_t socklen)
 Create and initialize a listen socket for the server. More...
 
static int setup_service (struct GNUNET_SERVICE_Handle *sh)
 Setup service handle. More...
 
static char * get_user_name (struct GNUNET_SERVICE_Handle *sh)
 Get the name of the user that'll be used to provide the service. More...
 
static int set_user_id (struct GNUNET_SERVICE_Handle *sh)
 Set user ID. More...
 
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. More...
 
static void pid_file_delete (struct GNUNET_SERVICE_Handle *sh)
 Delete the PID file that was created by our parent. More...
 
static int detach_terminal (struct GNUNET_SERVICE_Handle *sh)
 Detach from terminal. More...
 
static void teardown_service (struct GNUNET_SERVICE_Handle *sh)
 Tear down the service, closing the listen sockets and freeing the ACLs. More...
 
static void return_agpl (void *cls, const struct GNUNET_MessageHeader *msg)
 Function to return link to AGPL source upon request. More...
 
struct GNUNET_SERVICE_HandleGNUNET_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. More...
 
void GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Handle *srv)
 Stops a service that was started with GNUNET_SERVICE_start(). More...
 
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. More...
 
void GNUNET_SERVICE_suspend (struct GNUNET_SERVICE_Handle *sh)
 Suspend accepting connections from the listen socket temporarily. More...
 
void GNUNET_SERVICE_resume (struct GNUNET_SERVICE_Handle *sh)
 Resume accepting connections from the listen socket. More...
 
static void resume_client_receive (void *cls)
 Task run to resume receiving data from the client after the client called GNUNET_SERVICE_client_continue(). More...
 
void GNUNET_SERVICE_client_continue (struct GNUNET_SERVICE_Client *c)
 Continue receiving further messages from the given client. More...
 
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. More...
 
static void finish_client_drop (void *cls)
 Asynchronously finish dropping the client. More...
 
void GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client *c)
 Ask the server to disconnect from the given client. More...
 
void GNUNET_SERVICE_shutdown (struct GNUNET_SERVICE_Handle *sh)
 Explicitly stops the service. More...
 
void GNUNET_SERVICE_client_mark_monitor (struct GNUNET_SERVICE_Client *c)
 Set the 'monitor' flag on this client. More...
 
void GNUNET_SERVICE_client_persist (struct GNUNET_SERVICE_Client *c)
 Set the persist option on this client. More...
 
struct GNUNET_MQ_HandleGNUNET_SERVICE_client_get_mq (struct GNUNET_SERVICE_Client *c)
 Obtain the message queue of c. More...
 

Detailed Description

functions related to starting services

Author
Christian Grothoff

Definition in file service.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "util-service", __VA_ARGS__)

◆ LOG_STRERROR

#define LOG_STRERROR (   kind,
  syscall 
)    GNUNET_log_from_strerror (kind, "util-service", syscall)

◆ LOG_STRERROR_FILE

#define LOG_STRERROR_FILE (   kind,
  syscall,
  filename 
)    GNUNET_log_from_strerror_file (kind, "util-service", syscall, filename)

Definition at line 44 of file service.c.

Referenced by pid_file_delete().

Enumeration Type Documentation

◆ SuspendReason

Reasons why we might be suspended.

Enumerator
SUSPEND_STATE_NONE 

We are running normally.

SUSPEND_STATE_APP 

Application requested it.

SUSPEND_STATE_EMFILE 

OS ran out of file descriptors.

SUSPEND_STATE_APP_AND_EMFILE 

Both reasons, APP and EMFILE apply.

SUSPEND_STATE_SHUTDOWN 

Suspension because service was permanently shutdown.

Definition at line 84 of file service.c.

85 {
90 
95 
100 
105 
110 };
Both reasons, APP and EMFILE apply.
Definition: service.c:104
We are running normally.
Definition: service.c:89
Suspension because service was permanently shutdown.
Definition: service.c:109
OS ran out of file descriptors.
Definition: service.c:99
Application requested it.
Definition: service.c:94

Function Documentation

◆ have_non_monitor_clients()

static int have_non_monitor_clients ( struct GNUNET_SERVICE_Handle sh)
static

Check if any of the clients we have left are unrelated to monitoring.

Parameters
shservice to check clients for
Returns
GNUNET_YES if we have non-monitoring clients left

Definition at line 361 of file service.c.

References GNUNET_SERVICE_Handle::clients_head, GNUNET_NO, GNUNET_YES, and GNUNET_SERVICE_Client::next.

Referenced by finish_client_drop(), GNUNET_SERVICE_client_mark_monitor(), and service_shutdown().

362 {
363  for (struct GNUNET_SERVICE_Client *client = sh->clients_head;
364  NULL != client;
365  client = client->next)
366  {
367  if (client->is_monitor)
368  continue;
369  return GNUNET_YES;
370  }
371  return GNUNET_NO;
372 }
struct GNUNET_SERVICE_Client * clients_head
Our clients, kept in a DLL.
Definition: service.c:161
#define GNUNET_NO
Definition: gnunet_common.h:81
Handle to a client that is connected to a service.
Definition: service.c:249
struct GNUNET_SERVICE_Client * next
Kept in a DLL.
Definition: service.c:255
#define GNUNET_YES
Definition: gnunet_common.h:80
Here is the caller graph for this function:

◆ do_suspend()

static void do_suspend ( struct GNUNET_SERVICE_Handle sh,
enum SuspendReason  sr 
)
static

Suspend accepting connections from the listen socket temporarily.

Resume activity using do_resume.

Parameters
shservice to stop accepting connections.
srreason for suspending accepting connections

Definition at line 383 of file service.c.

References GNUNET_assert, GNUNET_SCHEDULER_cancel(), ServiceListenContext::listen_task, ServiceListenContext::next, GNUNET_SERVICE_Handle::slc_head, and GNUNET_SERVICE_Handle::suspend_state.

Referenced by accept_client(), GNUNET_SERVICE_shutdown(), GNUNET_SERVICE_suspend(), and service_shutdown().

385 {
386  struct ServiceListenContext *slc;
387 
388  GNUNET_assert (0 == (sh->suspend_state & sr));
389  sh->suspend_state |= sr;
390  for (slc = sh->slc_head; NULL != slc; slc = slc->next)
391  {
392  if (NULL != slc->listen_task)
393  {
395  slc->listen_task = NULL;
396  }
397  }
398 }
struct ServiceListenContext * slc_head
DLL of listen sockets used to accept new connections.
Definition: service.c:151
enum SuspendReason suspend_state
Are we suspended, and if so, why?
Definition: service.c:219
struct ServiceListenContext * next
Kept in a DLL.
Definition: service.c:56
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Information the service tracks per listen operation.
Definition: service.c:50
struct GNUNET_SCHEDULER_Task * listen_task
Task scheduled to do the listening.
Definition: service.c:76
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
Here is the call graph for this function:
Here is the caller graph for this function:

◆ service_shutdown()

static void service_shutdown ( void *  cls)
static

Shutdown task triggered when a service should be terminated.

This considers active clients and the service options to see how this specific service is to be terminated, and depending on this proceeds with the shutdown logic.

Parameters
clsour struct GNUNET_SERVICE_Handle

Definition at line 410 of file service.c.

References do_suspend(), GNUNET_assert, GNUNET_NO, GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN, GNUNET_SERVICE_OPTION_NONE, GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN, GNUNET_SERVICE_shutdown(), have_non_monitor_clients(), GNUNET_SERVICE_Handle::options, ServiceListenContext::sh, GNUNET_SERVICE_Handle::suspend_state, and SUSPEND_STATE_SHUTDOWN.

Referenced by service_main().

411 {
412  struct GNUNET_SERVICE_Handle *sh = cls;
413 
414  switch (sh->options)
415  {
418  break;
420  /* This task should never be run if we are using
421  the manual shutdown. */
422  GNUNET_assert (0);
423  break;
425  if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN))
426  do_suspend (sh,
430  break;
431  }
432 }
enum SuspendReason suspend_state
Are we suspended, and if so, why?
Definition: service.c:219
Handle to a service.
Definition: service.c:116
Do not trigger server shutdown on signal at all; instead, allow for the user to terminate the server ...
static void do_suspend(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
Suspend accepting connections from the listen socket temporarily.
Definition: service.c:383
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:81
enum GNUNET_SERVICE_Options options
Our options.
Definition: service.c:224
Trigger a SOFT server shutdown on signals, allowing active non-monitor clients to complete their tran...
static struct SolverHandle * sh
Suspension because service was permanently shutdown.
Definition: service.c:109
static int have_non_monitor_clients(struct GNUNET_SERVICE_Handle *sh)
Check if any of the clients we have left are unrelated to monitoring.
Definition: service.c:361
void GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh)
Explicitly stops the service.
Definition: service.c:2679
Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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 443 of file service.c.

References GNUNET_NO, GNUNET_YES, GNUNET_STRINGS_IPv4NetworkPolicy::netmask, and GNUNET_STRINGS_IPv4NetworkPolicy::network.

Referenced by accept_client().

445 {
446  unsigned int i;
447 
448  if (NULL == list)
449  return GNUNET_NO;
450  i = 0;
451  while ( (0 != list[i].network.s_addr) ||
452  (0 != list[i].netmask.s_addr) )
453  {
454  if ((add->s_addr & list[i].netmask.s_addr) ==
455  (list[i].network.s_addr & list[i].netmask.s_addr))
456  return GNUNET_YES;
457  i++;
458  }
459  return GNUNET_NO;
460 }
struct in_addr netmask
IPv4 netmask.
#define GNUNET_NO
Definition: gnunet_common.h:81
struct in_addr network
IPv4 address.
static int add
Desired action is to add a record.
#define GNUNET_YES
Definition: gnunet_common.h:80
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 471 of file service.c.

References GNUNET_is_zero, GNUNET_NO, and GNUNET_YES.

Referenced by accept_client().

473 {
474  unsigned int i;
475  unsigned int j;
476 
477  if (NULL == list)
478  return GNUNET_NO;
479  i = 0;
480 NEXT:
481  while (0 != GNUNET_is_zero (&list[i].network))
482  {
483  for (j = 0; j < sizeof (struct in6_addr) / sizeof (int); j++)
484  if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
485  (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
486  {
487  i++;
488  goto NEXT;
489  }
490  return GNUNET_YES;
491  }
492  return GNUNET_NO;
493 }
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_is_zero(a)
Check that memory in a is all zeros.
#define GNUNET_YES
Definition: gnunet_common.h:80
Here is the caller graph for this function:

◆ do_send()

static void do_send ( void *  cls)
static

Task run when we are ready to transmit data to the client.

Parameters
clsthe struct GNUNET_SERVICE_Client * to send to

Definition at line 503 of file service.c.

References buf, GNUNET_SERVICE_Client::drop_task, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_log_strerror, GNUNET_MQ_ERROR_WRITE, GNUNET_MQ_impl_send_continue(), GNUNET_MQ_impl_send_in_flight(), GNUNET_MQ_inject_error(), GNUNET_NETWORK_socket_send(), GNUNET_SCHEDULER_add_write_net(), GNUNET_TIME_UNIT_FOREVER_REL, LOG, GNUNET_SERVICE_Client::mq, GNUNET_SERVICE_Client::msg, GNUNET_SERVICE_Client::msg_pos, ret, GNUNET_SERVICE_Client::send_task, GNUNET_MessageHeader::size, GNUNET_SERVICE_Client::sock, and GNUNET_MessageHeader::type.

Referenced by service_mq_send().

504 {
505  struct GNUNET_SERVICE_Client *client = cls;
506  ssize_t ret;
507  size_t left;
508  const char *buf;
509 
511  "service: sending message with type %u\n",
512  ntohs(client->msg->type));
513 
514 
515  client->send_task = NULL;
516  buf = (const char *) client->msg;
517  left = ntohs (client->msg->size) - client->msg_pos;
518  ret = GNUNET_NETWORK_socket_send (client->sock,
519  &buf[client->msg_pos],
520  left);
521  GNUNET_assert (ret <= (ssize_t) left);
522  if (0 == ret)
523  {
525  "no data send");
526  GNUNET_MQ_inject_error (client->mq,
528  return;
529  }
530  if (-1 == ret)
531  {
532  if ( (EAGAIN == errno) ||
533  (EINTR == errno) )
534  {
535  /* ignore */
536  ret = 0;
537  }
538  else
539  {
540  if (EPIPE != errno)
542  "send");
544  "socket send returned with error code %i",
545  errno);
546  GNUNET_MQ_inject_error (client->mq,
548  return;
549  }
550  }
551  if (0 == client->msg_pos)
552  {
554  }
555  client->msg_pos += ret;
556  if (left > (size_t) ret)
557  {
558  GNUNET_assert (NULL == client->drop_task);
559  client->send_task
561  client->sock,
562  &do_send,
563  client);
564  return;
565  }
567 }
void GNUNET_MQ_inject_error(struct GNUNET_MQ_Handle *mq, enum GNUNET_MQ_Error error)
Call the error handler of a message queue with the given error code.
Definition: mq.c:300
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:927
struct GNUNET_SCHEDULER_Task * send_task
Task that transmit data to the client.
Definition: service.c:303
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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:1548
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
static int ret
Final status code.
Definition: gnunet-arm.c:89
struct GNUNET_MQ_Handle * mq
Message queue for the client.
Definition: service.c:275
static void do_send(void *cls)
Task run when we are ready to transmit data to the client.
Definition: service.c:503
Handle to a client that is connected to a service.
Definition: service.c:249
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
void GNUNET_MQ_impl_send_in_flight(struct GNUNET_MQ_Handle *mq)
Call the send notification for the current message, but do not try to send the next message until #gn...
Definition: mq.c:519
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
size_t msg_pos
Current position in msg at which we are transmitting.
Definition: service.c:325
FIXME: document!
static char buf[2048]
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
#define LOG(kind,...)
Definition: service.c:40
const struct GNUNET_MessageHeader * msg
Pointer to the message to be transmitted by send_task.
Definition: service.c:308
struct GNUNET_NETWORK_Handle * sock
Socket of this client.
Definition: service.c:270
void GNUNET_MQ_impl_send_continue(struct GNUNET_MQ_Handle *mq)
Call the send implementation for the next queued message, if any.
Definition: mq.c:486
struct GNUNET_SCHEDULER_Task * drop_task
Task run to finish dropping the client after the stack has properly unwound.
Definition: service.c:292
Here is the call graph for this function:
Here is the caller graph for this function:

◆ service_mq_send()

static void service_mq_send ( struct GNUNET_MQ_Handle mq,
const struct GNUNET_MessageHeader msg,
void *  impl_state 
)
static

Signature of functions implementing the sending functionality of a message queue.

Parameters
mqthe message queue
msgthe message to send
impl_stateour struct GNUNET_SERVICE_Client *

Definition at line 579 of file service.c.

References do_send(), GNUNET_SERVICE_Client::drop_task, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_SCHEDULER_add_write_net(), GNUNET_TIME_UNIT_FOREVER_REL, LOG, msg, GNUNET_SERVICE_Client::msg, GNUNET_SERVICE_Client::msg_pos, GNUNET_SERVICE_Client::send_task, GNUNET_MessageHeader::size, GNUNET_SERVICE_Client::sock, and GNUNET_MessageHeader::type.

Referenced by start_client().

582 {
583  struct GNUNET_SERVICE_Client *client = impl_state;
584 
585  (void) mq;
586  if (NULL != client->drop_task)
587  return; /* we're going down right now, do not try to send */
588  GNUNET_assert (NULL == client->send_task);
590  "Sending message of type %u and size %u to client\n",
591  ntohs (msg->type),
592  ntohs (msg->size));
593  client->msg = msg;
594  client->msg_pos = 0;
595  client->send_task
597  client->sock,
598  &do_send,
599  client);
600 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_SCHEDULER_Task * send_task
Task that transmit data to the client.
Definition: service.c:303
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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:1548
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
static void do_send(void *cls)
Task run when we are ready to transmit data to the client.
Definition: service.c:503
Handle to a client that is connected to a service.
Definition: service.c:249
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
size_t msg_pos
Current position in msg at which we are transmitting.
Definition: service.c:325
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
#define LOG(kind,...)
Definition: service.c:40
const struct GNUNET_MessageHeader * msg
Pointer to the message to be transmitted by send_task.
Definition: service.c:308
struct GNUNET_NETWORK_Handle * sock
Socket of this client.
Definition: service.c:270
struct GNUNET_SCHEDULER_Task * drop_task
Task run to finish dropping the client after the stack has properly unwound.
Definition: service.c:292
Here is the call graph for this function:
Here is the caller graph for this function:

◆ service_mq_cancel()

static void service_mq_cancel ( struct GNUNET_MQ_Handle mq,
void *  impl_state 
)
static

Implementation function that cancels the currently sent message.

Parameters
mqmessage queue
impl_statestate specific to the implementation

Definition at line 610 of file service.c.

References GNUNET_assert, GNUNET_SCHEDULER_cancel(), GNUNET_SERVICE_Client::msg, GNUNET_SERVICE_Client::msg_pos, and GNUNET_SERVICE_Client::send_task.

Referenced by start_client().

612 {
613  struct GNUNET_SERVICE_Client *client = impl_state;
614 
615  (void) mq;
616  GNUNET_assert (0 == client->msg_pos);
617  client->msg = NULL;
619  client->send_task = NULL;
620 }
struct GNUNET_SCHEDULER_Task * send_task
Task that transmit data to the client.
Definition: service.c:303
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Handle to a client that is connected to a service.
Definition: service.c:249
size_t msg_pos
Current position in msg at which we are transmitting.
Definition: service.c:325
const struct GNUNET_MessageHeader * msg
Pointer to the message to be transmitted by send_task.
Definition: service.c:308
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
Here is the call graph for this function:
Here is the caller graph for this function:

◆ service_mq_error_handler()

static void service_mq_error_handler ( void *  cls,
enum GNUNET_MQ_Error  error 
)
static

Generic error handler, called with the appropriate error code and the same closure specified at the creation of the message queue.

Not every message queue implementation supports an error handler.

Parameters
clsclosure with our struct GNUNET_SERVICE_Client
errorerror code

Definition at line 633 of file service.c.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MQ_ERROR_NO_MATCH, GNUNET_NO, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_SERVICE_Handle::require_found, ServiceListenContext::sh, GNUNET_SERVICE_Client::sh, and GNUNET_SERVICE_Client::warn_type.

Referenced by start_client().

635 {
636  struct GNUNET_SERVICE_Client *client = cls;
637  struct GNUNET_SERVICE_Handle *sh = client->sh;
638 
639  if ( (GNUNET_MQ_ERROR_NO_MATCH == error) &&
640  (GNUNET_NO == sh->require_found) )
641  {
643  "No handler for message of type %u found\n",
644  (unsigned int) client->warn_type);
646  return; /* ignore error */
647  }
649 }
Handle to a service.
Definition: service.c:116
We received a message for which we have no matching handler.
int require_found
If GNUNET_YES, consider unknown message types an error where the client is disconnected.
Definition: service.c:242
#define GNUNET_NO
Definition: gnunet_common.h:81
Handle to a client that is connected to a service.
Definition: service.c:249
static struct SolverHandle * sh
uint16_t warn_type
Type of last message processed (for warn_no_receive_done).
Definition: service.c:349
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2618
#define GNUNET_log(kind,...)
struct GNUNET_SERVICE_Handle * sh
Service that this client belongs to.
Definition: service.c:265
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2533
Here is the call graph for this function:
Here is the caller graph for this function:

◆ warn_no_client_continue()

static void warn_no_client_continue ( void *  cls)
static

Task run to warn about missing calls to GNUNET_SERVICE_client_continue().

Parameters
clsour struct GNUNET_SERVICE_Client * to process more requests from

Definition at line 658 of file service.c.

References _, GNUNET_break, GNUNET_ERROR_TYPE_WARNING, GNUNET_SCHEDULER_add_delayed(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_absolute_get_duration(), GNUNET_TIME_UNIT_MINUTES, GNUNET_YES, LOG, GNUNET_SERVICE_Client::warn_start, GNUNET_SERVICE_Client::warn_task, and GNUNET_SERVICE_Client::warn_type.

Referenced by service_client_mst_cb().

659 {
660  struct GNUNET_SERVICE_Client *client = cls;
661 
662  GNUNET_break (0 != client->warn_type); /* type should never be 0 here, as we don't use 0 */
663  client->warn_task
666  client);
668  _("Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"),
669  (unsigned int) client->warn_type,
671  GNUNET_YES));
672 }
#define GNUNET_TIME_UNIT_MINUTES
One minute.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
Handle to a client that is connected to a service.
Definition: service.c:249
struct GNUNET_TIME_Absolute warn_start
Time when we last gave a message from this client to the application.
Definition: service.c:320
struct GNUNET_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:1246
struct GNUNET_SCHEDULER_Task * warn_task
Task that warns about missing calls to GNUNET_SERVICE_client_continue().
Definition: service.c:286
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:727
uint16_t warn_type
Type of last message processed (for warn_no_receive_done).
Definition: service.c:349
static void warn_no_client_continue(void *cls)
Task run to warn about missing calls to GNUNET_SERVICE_client_continue().
Definition: service.c:658
#define LOG(kind,...)
Definition: service.c:40
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:373
#define GNUNET_YES
Definition: gnunet_common.h:80
Here is the call graph for this function:
Here is the caller graph for this function:

◆ service_client_mst_cb()

static int service_client_mst_cb ( void *  cls,
const struct GNUNET_MessageHeader message 
)
static

Functions with this signature are called whenever a complete message is received by the tokenizer for a client.

Do not call GNUNET_MST_destroy() from within the scope of this callback.

Parameters
clsclosure with the struct GNUNET_SERVICE_Client *
messagethe actual message
Returns
GNUNET_OK on success, GNUNET_SYSERR if the client was dropped

Definition at line 687 of file service.c.

References GNUNET_SERVICE_Client::drop_task, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_MQ_inject_message(), GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_delayed(), GNUNET_SYSERR, GNUNET_TIME_absolute_get(), GNUNET_TIME_UNIT_MINUTES, GNUNET_YES, LOG, GNUNET_SERVICE_Client::mq, GNUNET_SERVICE_Client::needs_continue, GNUNET_MessageHeader::size, GNUNET_MessageHeader::type, warn_no_client_continue(), GNUNET_SERVICE_Client::warn_start, GNUNET_SERVICE_Client::warn_task, and GNUNET_SERVICE_Client::warn_type.

Referenced by start_client().

689 {
690  struct GNUNET_SERVICE_Client *client = cls;
691 
693  "Received message of type %u and size %u from client\n",
694  ntohs (message->type),
695  ntohs (message->size));
697  client->needs_continue = GNUNET_YES;
698  client->warn_type = ntohs (message->type);
700  GNUNET_assert (NULL == client->warn_task);
701  client->warn_task
704  client);
705  GNUNET_MQ_inject_message (client->mq,
706  message);
707  if (NULL != client->drop_task)
708  return GNUNET_SYSERR;
709  return GNUNET_OK;
710 }
#define GNUNET_TIME_UNIT_MINUTES
One minute.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
struct GNUNET_MQ_Handle * mq
Message queue for the client.
Definition: service.c:275
Handle to a client that is connected to a service.
Definition: service.c:249
struct GNUNET_TIME_Absolute warn_start
Time when we last gave a message from this client to the application.
Definition: service.c:320
struct GNUNET_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:1246
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
struct GNUNET_SCHEDULER_Task * warn_task
Task that warns about missing calls to GNUNET_SERVICE_client_continue().
Definition: service.c:286
uint16_t warn_type
Type of last message processed (for warn_no_receive_done).
Definition: service.c:349
void GNUNET_MQ_inject_message(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *mh)
Call the message message handler that was registered for the type of the given message in the given m...
Definition: mq.c:202
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static void warn_no_client_continue(void *cls)
Task run to warn about missing calls to GNUNET_SERVICE_client_continue().
Definition: service.c:658
#define LOG(kind,...)
Definition: service.c:40
int needs_continue
Are we waiting for the application to call GNUNET_SERVICE_client_continue()?
Definition: service.c:344
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_SCHEDULER_Task * drop_task
Task run to finish dropping the client after the stack has properly unwound.
Definition: service.c:292
Here is the call graph for this function:
Here is the caller graph for this function:

◆ service_client_recv()

static void service_client_recv ( void *  cls)
static

A client sent us data.

Receive and process it. If we are done, reschedule this task.

Parameters
clsthe struct GNUNET_SERVICE_Client that sent us data.

Definition at line 720 of file service.c.

References GNUNET_SERVICE_Client::drop_task, GNUNET_assert, GNUNET_MST_read(), GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_read_net(), GNUNET_SERVICE_client_drop(), GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, GNUNET_SERVICE_Client::mst, GNUNET_SERVICE_Client::needs_continue, GNUNET_SERVICE_Client::recv_task, ret, and GNUNET_SERVICE_Client::sock.

Referenced by resume_client_receive(), and start_client().

721 {
722  struct GNUNET_SERVICE_Client *client = cls;
723  int ret;
724 
725  client->recv_task = NULL;
726  ret = GNUNET_MST_read (client->mst,
727  client->sock,
728  GNUNET_NO,
729  GNUNET_YES);
730  if (GNUNET_SYSERR == ret)
731  {
732  /* client closed connection (or IO error) */
733  if (NULL == client->drop_task)
734  {
737  }
738  return;
739  }
740  if (GNUNET_NO == ret)
741  return; /* more messages in buffer, wait for application
742  to be done processing */
743  GNUNET_assert (GNUNET_OK == ret);
744  if (GNUNET_YES == client->needs_continue)
745  return;
746  if (NULL != client->recv_task)
747  return;
748  /* MST needs more data, re-schedule read job */
749  client->recv_task
751  client->sock,
753  client);
754 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
static int ret
Final status code.
Definition: gnunet-arm.c:89
struct GNUNET_MessageStreamTokenizer * mst
Tokenizer we use for processing incoming data.
Definition: service.c:280
Handle to a client that is connected to a service.
Definition: service.c:249
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2618
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static void service_client_recv(void *cls)
A client sent us data.
Definition: service.c:720
int needs_continue
Are we waiting for the application to call GNUNET_SERVICE_client_continue()?
Definition: service.c:344
int GNUNET_MST_read(struct GNUNET_MessageStreamTokenizer *mst, struct GNUNET_NETWORK_Handle *sock, int purge, int one_shot)
Add incoming data to the receive buffer and call the callback for all complete messages.
Definition: mst.c:347
#define GNUNET_YES
Definition: gnunet_common.h:80
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:1478
struct GNUNET_NETWORK_Handle * sock
Socket of this client.
Definition: service.c:270
struct GNUNET_SCHEDULER_Task * recv_task
Task that receives data from the client to pass it to the handlers.
Definition: service.c:298
struct GNUNET_SCHEDULER_Task * drop_task
Task run to finish dropping the client after the stack has properly unwound.
Definition: service.c:292
Here is the call graph for this function:
Here is the caller graph for this function:

◆ start_client()

static void start_client ( struct GNUNET_SERVICE_Handle sh,
struct GNUNET_NETWORK_Handle csock 
)
static

We have successfully accepted a connection from a client.

Now setup the client (with the scheduler) and tell the application.

Parameters
shservice that accepted the client
socksocket associated with the client

Definition at line 765 of file service.c.

References GNUNET_SERVICE_Handle::cb_cls, GNUNET_SERVICE_Handle::clients_head, GNUNET_SERVICE_Handle::clients_tail, GNUNET_SERVICE_Handle::connect_cb, GNUNET_CONTAINER_DLL_insert, GNUNET_MQ_queue_for_callbacks(), GNUNET_MQ_set_handlers_closure(), GNUNET_MST_create(), GNUNET_new, GNUNET_SCHEDULER_add_read_net(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_SERVICE_Handle::handlers, GNUNET_SERVICE_Client::mq, GNUNET_SERVICE_Client::mst, GNUNET_SERVICE_Client::recv_task, service_client_mst_cb(), service_client_recv(), service_mq_cancel(), service_mq_error_handler(), service_mq_send(), ServiceListenContext::sh, GNUNET_SERVICE_Client::sh, GNUNET_SERVICE_Client::sock, and GNUNET_SERVICE_Client::user_context.

Referenced by accept_client().

767 {
768  struct GNUNET_SERVICE_Client *client;
769 
770  client = GNUNET_new (struct GNUNET_SERVICE_Client);
772  sh->clients_tail,
773  client);
774  client->sh = sh;
775  client->sock = csock;
777  NULL,
779  client,
780  sh->handlers,
782  client);
784  client);
785  if (NULL != sh->connect_cb)
786  client->user_context = sh->connect_cb (sh->cb_cls,
787  client,
788  client->mq);
790  client->user_context);
791  client->recv_task
793  client->sock,
795  client);
796 }
static void service_mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implementation function that cancels the currently sent message.
Definition: service.c:610
struct GNUNET_MQ_MessageHandler * handlers
Message handlers to use for all clients.
Definition: service.c:171
struct GNUNET_SERVICE_Client * clients_head
Our clients, kept in a DLL.
Definition: service.c:161
struct GNUNET_SERVICE_Client * clients_tail
Our clients, kept in a DLL.
Definition: service.c:166
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_MQ_Handle * mq
Message queue for the client.
Definition: service.c:275
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:687
struct GNUNET_MessageStreamTokenizer * mst
Tokenizer we use for processing incoming data.
Definition: service.c:280
Handle to a client that is connected to a service.
Definition: service.c:249
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:633
void GNUNET_MQ_set_handlers_closure(struct GNUNET_MQ_Handle *mq, void *handlers_cls)
Change the closure argument in all of the handlers of the mq.
Definition: mq.c:583
void * user_context
User context value, value returned from the connect callback.
Definition: service.c:314
struct GNUNET_MQ_Handle * GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send, GNUNET_MQ_DestroyImpl destroy, GNUNET_MQ_CancelImpl cancel, void *impl_state, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *cls)
Create a message queue for the specified handlers.
Definition: mq.c:552
static struct SolverHandle * sh
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:87
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
GNUNET_SERVICE_ConnectHandler connect_cb
Function to call when clients connect.
Definition: service.c:136
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:579
static void service_client_recv(void *cls)
A client sent us data.
Definition: service.c:720
struct GNUNET_SERVICE_Handle * sh
Service that this client belongs to.
Definition: service.c:265
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:1478
struct GNUNET_NETWORK_Handle * sock
Socket of this client.
Definition: service.c:270
struct GNUNET_SCHEDULER_Task * recv_task
Task that receives data from the client to pass it to the handlers.
Definition: service.c:298
void * cb_cls
Closure for service_init_cb, connect_cb, disconnect_cb.
Definition: service.c:146
Here is the call graph for this function:
Here is the caller graph for this function:

◆ accept_client()

static void accept_client ( void *  cls)
static

We have a client.

Accept the incoming socket(s) (and reschedule the listen task).

Parameters
clsthe struct ServiceListenContext of the ready listen socket

Definition at line 806 of file service.c.

References _, check_ipv4_listed(), check_ipv6_listed(), do_suspend(), GNUNET_a2s(), GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_log_strerror, GNUNET_NETWORK_socket_accept(), GNUNET_NETWORK_socket_close(), GNUNET_OK, GNUNET_SCHEDULER_add_read_net(), GNUNET_TIME_UNIT_FOREVER_REL, ServiceListenContext::listen_socket, ServiceListenContext::listen_task, LOG, ok, ServiceListenContext::sh, start_client(), GNUNET_SERVICE_Handle::suspend_state, SUSPEND_STATE_EMFILE, GNUNET_SERVICE_Handle::v4_allowed, GNUNET_SERVICE_Handle::v4_denied, GNUNET_SERVICE_Handle::v6_allowed, and GNUNET_SERVICE_Handle::v6_denied.

Referenced by do_resume().

807 {
808  struct ServiceListenContext *slc = cls;
809  struct GNUNET_SERVICE_Handle *sh = slc->sh;
810 
811  slc->listen_task = NULL;
812  while (1)
813  {
814  struct GNUNET_NETWORK_Handle *sock;
815  const struct sockaddr_in *v4;
816  const struct sockaddr_in6 *v6;
817  struct sockaddr_storage sa;
818  socklen_t addrlen;
819  int ok;
820 
821  addrlen = sizeof (sa);
823  (struct sockaddr *) &sa,
824  &addrlen);
825  if (NULL == sock)
826  {
827  if (EMFILE == errno)
828  do_suspend (sh,
830  else if (EAGAIN != errno)
832  "accept");
833  break;
834  }
835  switch (sa.ss_family)
836  {
837  case AF_INET:
838  GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
839  v4 = (const struct sockaddr_in *) &sa;
840  ok = ( ( (NULL == sh->v4_allowed) ||
842  &v4->sin_addr))) &&
843  ( (NULL == sh->v4_denied) ||
845  &v4->sin_addr)) ) );
846  break;
847  case AF_INET6:
848  GNUNET_assert (addrlen == sizeof (struct sockaddr_in6));
849  v6 = (const struct sockaddr_in6 *) &sa;
850  ok = ( ( (NULL == sh->v6_allowed) ||
852  &v6->sin6_addr))) &&
853  ( (NULL == sh->v6_denied) ||
855  &v6->sin6_addr)) ) );
856  break;
857 #ifndef WINDOWS
858  case AF_UNIX:
859  ok = GNUNET_OK; /* controlled using file-system ACL now */
860  break;
861 #endif
862  default:
864  _("Unknown address family %d\n"),
865  sa.ss_family);
866  return;
867  }
868  if (! ok)
869  {
871  "Service rejected incoming connection from %s due to policy.\n",
872  GNUNET_a2s ((const struct sockaddr *) &sa,
873  addrlen));
876  continue;
877  }
879  "Service accepted incoming connection from %s.\n",
880  GNUNET_a2s ((const struct sockaddr *) &sa,
881  addrlen));
882  start_client (slc->sh,
883  sock);
884  }
885  if (0 != sh->suspend_state)
886  return;
887  slc->listen_task
889  slc->listen_socket,
890  &accept_client,
891  slc);
892 }
enum SuspendReason suspend_state
Are we suspended, and if so, why?
Definition: service.c:219
Handle to a service.
Definition: service.c:116
static int check_ipv4_listed(const struct GNUNET_STRINGS_IPv4NetworkPolicy *list, const struct in_addr *add)
Check if the given IP address is in the list of IP addresses.
Definition: service.c:443
static void accept_client(void *cls)
We have a client.
Definition: service.c:806
static void do_suspend(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
Suspend accepting connections from the listen socket temporarily.
Definition: service.c:383
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_NETWORK_Handle * listen_socket
Socket we are listening on.
Definition: service.c:71
static int ok
Return value from &#39;main&#39; (0 == success)
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_denied
IPv6 addresses that are not allowed to connect.
Definition: service.c:186
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
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:468
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
struct GNUNET_SERVICE_Handle * sh
Service this listen context belongs to.
Definition: service.c:66
static struct SolverHandle * sh
static int check_ipv6_listed(const struct GNUNET_STRINGS_IPv6NetworkPolicy *list, const struct in6_addr *ip)
Check if the given IP address is in the list of IP addresses.
Definition: service.c:471
Information the service tracks per listen operation.
Definition: service.c:50
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
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)...
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_denied
IPv4 addresses that are not allowed to connect.
Definition: service.c:181
struct GNUNET_SCHEDULER_Task * listen_task
Task scheduled to do the listening.
Definition: service.c:76
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_allowed
IPv6 addresses that are allowed to connect (if not set, all are allowed).
Definition: service.c:198
#define LOG(kind,...)
Definition: service.c:40
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:765
handle to a socket
Definition: network.c:46
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_allowed
IPv4 addresses that are allowed to connect (if not set, all are allowed).
Definition: service.c:192
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:1478
OS ran out of file descriptors.
Definition: service.c:99
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:604
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_resume()

static void do_resume ( struct GNUNET_SERVICE_Handle sh,
enum SuspendReason  sr 
)
static

Resume accepting connections from the listen socket.

Parameters
shservice to resume accepting connections.
srreason that is no longer causing the suspension, or SUSPEND_STATE_NONE on first startup

Definition at line 903 of file service.c.

References accept_client(), GNUNET_assert, GNUNET_SCHEDULER_add_read_net(), GNUNET_TIME_UNIT_FOREVER_REL, ServiceListenContext::listen_socket, ServiceListenContext::listen_task, ServiceListenContext::next, GNUNET_SERVICE_Handle::slc_head, GNUNET_SERVICE_Handle::suspend_state, and SUSPEND_STATE_NONE.

Referenced by finish_client_drop(), GNUNET_SERVICE_resume(), GNUNET_SERVICE_start(), and service_main().

905 {
906  struct ServiceListenContext *slc;
907 
908  GNUNET_assert ( (SUSPEND_STATE_NONE == sr) ||
909  (0 != (sh->suspend_state & sr)) );
910  sh->suspend_state -= sr;
912  return;
913  for (slc = sh->slc_head; NULL != slc; slc = slc->next)
914  {
915  GNUNET_assert (NULL == slc->listen_task);
916  slc->listen_task
918  slc->listen_socket,
919  &accept_client,
920  slc);
921  }
922 }
struct ServiceListenContext * slc_head
DLL of listen sockets used to accept new connections.
Definition: service.c:151
enum SuspendReason suspend_state
Are we suspended, and if so, why?
Definition: service.c:219
struct ServiceListenContext * next
Kept in a DLL.
Definition: service.c:56
static void accept_client(void *cls)
We have a client.
Definition: service.c:806
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_NETWORK_Handle * listen_socket
Socket we are listening on.
Definition: service.c:71
We are running normally.
Definition: service.c:89
Information the service tracks per listen operation.
Definition: service.c:50
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_SCHEDULER_Task * listen_task
Task scheduled to do the listening.
Definition: service.c:76
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:1478
Here is the call graph for this function:
Here is the caller graph for this function:

◆ service_main()

static void service_main ( void *  cls)
static

First task run by any service.

Initializes our shutdown task, starts the listening operation on our listen sockets and launches the custom logic of the application service.

Parameters
clsour struct GNUNET_SERVICE_Handle

Definition at line 933 of file service.c.

References GNUNET_SERVICE_Handle::cb_cls, GNUNET_SERVICE_Handle::cfg, CLOSE, do_resume(), GNUNET_break, GNUNET_SCHEDULER_add_shutdown(), GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN, GNUNET_SERVICE_Handle::options, GNUNET_SERVICE_Handle::ready_confirm_fd, GNUNET_SERVICE_Handle::service_init_cb, service_shutdown(), ServiceListenContext::sh, SUSPEND_STATE_NONE, and WRITE.

Referenced by GNUNET_SERVICE_run_().

934 {
935  struct GNUNET_SERVICE_Handle *sh = cls;
936 
939  sh);
940  do_resume (sh,
942 
943  if (-1 != sh->ready_confirm_fd)
944  {
945  GNUNET_break (1 == WRITE (sh->ready_confirm_fd, ".", 1));
946  GNUNET_break (0 == CLOSE (sh->ready_confirm_fd));
947  sh->ready_confirm_fd = -1;
948  }
949 
950  if (NULL != sh->service_init_cb)
951  sh->service_init_cb (sh->cb_cls,
952  sh->cfg,
953  sh);
954 }
GNUNET_SERVICE_InitCallback service_init_cb
Main service-specific task to run.
Definition: service.c:131
Handle to a service.
Definition: service.c:116
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1293
Do not trigger server shutdown on signal at all; instead, allow for the user to terminate the server ...
enum GNUNET_SERVICE_Options options
Our options.
Definition: service.c:224
We are running normally.
Definition: service.c:89
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
int ready_confirm_fd
If we are daemonizing, this FD is set to the pipe to the parent.
Definition: service.c:231
static struct SolverHandle * sh
#define CLOSE(f)
Definition: plibc.h:653
static void service_shutdown(void *cls)
Shutdown task triggered when a service should be terminated.
Definition: service.c:410
#define WRITE(f, b, n)
Definition: plibc.h:667
static void do_resume(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
Resume accepting connections from the listen socket.
Definition: service.c:903
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: service.c:121
void * cb_cls
Closure for service_init_cb, connect_cb, disconnect_cb.
Definition: service.c:146
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 GNUNET_SERVICE_Handle sh,
const char *  option 
)
static

Parse an IPv4 access control list.

Parameters
retlocation where to write the ACL (set)
shservice 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 967 of file service.c.

References _, GNUNET_SERVICE_Handle::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, and GNUNET_SERVICE_Handle::service_name.

Referenced by setup_service().

970 {
971  char *opt;
972 
974  sh->service_name,
975  option))
976  {
977  *ret = NULL;
978  return GNUNET_OK;
979  }
982  sh->service_name,
983  option,
984  &opt));
985  if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy (opt)))
986  {
988  _("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
989  opt,
990  sh->service_name,
991  option);
992  GNUNET_free (opt);
993  return GNUNET_SYSERR;
994  }
995  GNUNET_free (opt);
996  return GNUNET_OK;
997 }
struct GNUNET_STRINGS_IPv4NetworkPolicy * GNUNET_STRINGS_parse_ipv4_policy(const char *routeListX)
Parse an IPv4 network policy.
Definition: strings.c:1654
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
int GNUNET_CONFIGURATION_have_value(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Test if we have a value for a particular option.
static char * option
Name of the option.
Definition: gnunet-config.c:38
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
#define LOG(kind,...)
Definition: service.c:40
const char * service_name
Name of our service.
Definition: service.c:126
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: service.c:121
#define GNUNET_free(ptr)
Wrapper around free.
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 GNUNET_SERVICE_Handle sh,
const char *  option 
)
static

Parse an IPv6 access control list.

Parameters
retlocation where to write the ACL (set)
shservice 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 1010 of file service.c.

References _, GNUNET_SERVICE_Handle::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, and GNUNET_SERVICE_Handle::service_name.

Referenced by setup_service().

1013 {
1014  char *opt;
1015 
1017  sh->service_name,
1018  option))
1019  {
1020  *ret = NULL;
1021  return GNUNET_OK;
1022  }
1025  sh->service_name,
1026  option,
1027  &opt));
1028  if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy (opt)))
1029  {
1031  _("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
1032  opt,
1033  sh->service_name,
1034  option);
1035  GNUNET_free (opt);
1036  return GNUNET_SYSERR;
1037  }
1038  GNUNET_free (opt);
1039  return GNUNET_OK;
1040 }
struct GNUNET_STRINGS_IPv6NetworkPolicy * GNUNET_STRINGS_parse_ipv6_policy(const char *routeListX)
Parse an IPv6 network policy.
Definition: strings.c:1854
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
int GNUNET_CONFIGURATION_have_value(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Test if we have a value for a particular option.
static char * option
Name of the option.
Definition: gnunet-config.c:38
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
#define LOG(kind,...)
Definition: service.c:40
const char * service_name
Name of our service.
Definition: service.c:126
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: service.c:121
#define GNUNET_free(ptr)
Wrapper around free.
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 1054 of file service.c.

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

Referenced by get_server_addresses().

1058 {
1059 #ifdef AF_UNIX
1060  struct sockaddr_un *un;
1061 
1062  un = GNUNET_new (struct sockaddr_un);
1063  un->sun_family = AF_UNIX;
1064  GNUNET_strlcpy (un->sun_path,
1065  unixpath,
1066  sizeof (un->sun_path));
1067 #ifdef LINUX
1068  if (GNUNET_YES == abstract)
1069  un->sun_path[0] = '\0';
1070 #endif
1071 #if HAVE_SOCKADDR_UN_SUN_LEN
1072  un->sun_len = (u_char) sizeof (struct sockaddr_un);
1073 #endif
1074  *saddrs = (struct sockaddr *) un;
1075  *saddrlens = sizeof (struct sockaddr_un);
1076 #else
1077  /* this function should never be called
1078  * unless AF_UNIX is defined! */
1079  GNUNET_assert (0);
1080 #endif
1081 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_YES
Definition: gnunet_common.h:80
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_server_addresses()

static int get_server_addresses ( const char *  service_name,
const struct GNUNET_CONFIGURATION_Handle cfg,
struct sockaddr ***  addrs,
socklen_t **  addr_lens 
)
static

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 1105 of file service.c.

References _, add_unixpath(), getenv(), 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_free_non_null, GNUNET_log_strerror_file, GNUNET_malloc, GNUNET_memcpy, GNUNET_NETWORK_shorten_unixpath(), GNUNET_NETWORK_socket_box_native(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_create(), GNUNET_NETWORK_test_pf(), GNUNET_new_array, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, hostname, LOG, LOG_STRERROR, ServiceListenContext::next, pi, port, res, ret, ServiceListenContext::sh, size, SOCKET, and STRERROR.

Referenced by setup_service().

1109 {
1110  int disablev6;
1111  struct GNUNET_NETWORK_Handle *desc;
1112  unsigned long long port;
1113  char *unixpath;
1114  struct addrinfo hints;
1115  struct addrinfo *res;
1116  struct addrinfo *pos;
1117  struct addrinfo *next;
1118  unsigned int i;
1119  int resi;
1120  int ret;
1121  int abstract;
1122  struct sockaddr **saddrs;
1123  socklen_t *saddrlens;
1124  char *hostname;
1125 
1126  *addrs = NULL;
1127  *addr_lens = NULL;
1128  desc = NULL;
1129  disablev6 = GNUNET_NO;
1130  if ( (GNUNET_NO ==
1131  GNUNET_NETWORK_test_pf (PF_INET6)) ||
1132  (GNUNET_YES ==
1134  service_name,
1135  "DISABLEV6") ) )
1136  disablev6 = GNUNET_YES;
1137 
1138  port = 0;
1140  service_name,
1141  "PORT"))
1142  {
1143  if (GNUNET_OK !=
1145  service_name,
1146  "PORT",
1147  &port))
1148  {
1150  _("Require valid port number for service `%s' in configuration!\n"),
1151  service_name);
1152  }
1153  if (port > 65535)
1154  {
1156  _("Require valid port number for service `%s' in configuration!\n"),
1157  service_name);
1158  return GNUNET_SYSERR;
1159  }
1160  }
1161 
1163  service_name,
1164  "BINDTO"))
1165  {
1168  service_name,
1169  "BINDTO",
1170  &hostname));
1171  }
1172  else
1173  hostname = NULL;
1174 
1175  unixpath = NULL;
1176  abstract = GNUNET_NO;
1177 #ifdef AF_UNIX
1178  if ((GNUNET_YES ==
1180  service_name,
1181  "UNIXPATH")) &&
1182  (GNUNET_OK ==
1184  service_name,
1185  "UNIXPATH",
1186  &unixpath)) &&
1187  (0 < strlen (unixpath)))
1188  {
1189  /* probe UNIX support */
1190  struct sockaddr_un s_un;
1191 
1192  if (strlen (unixpath) >= sizeof (s_un.sun_path))
1193  {
1195  _("UNIXPATH `%s' too long, maximum length is %llu\n"),
1196  unixpath,
1197  (unsigned long long) sizeof (s_un.sun_path));
1198  unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
1200  _("Using `%s' instead\n"),
1201  unixpath);
1202  }
1203 #ifdef LINUX
1204  abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1205  "TESTING",
1206  "USE_ABSTRACT_SOCKETS");
1207  if (GNUNET_SYSERR == abstract)
1208  abstract = GNUNET_NO;
1209 #endif
1210  if ( (GNUNET_YES != abstract) &&
1211  (GNUNET_OK !=
1214  "mkdir",
1215  unixpath);
1216  }
1217  if (NULL != unixpath)
1218  {
1219  desc = GNUNET_NETWORK_socket_create (AF_UNIX,
1220  SOCK_STREAM,
1221  0);
1222  if (NULL == desc)
1223  {
1224  if ((ENOBUFS == errno) ||
1225  (ENOMEM == errno) ||
1226  (ENFILE == errno) ||
1227  (EACCES == errno))
1228  {
1230  "socket");
1231  GNUNET_free_non_null (hostname);
1232  GNUNET_free (unixpath);
1233  return GNUNET_SYSERR;
1234  }
1236  _("Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
1237  service_name,
1238  STRERROR (errno));
1239  GNUNET_free (unixpath);
1240  unixpath = NULL;
1241  }
1242  else
1243  {
1246  desc = NULL;
1247  }
1248  }
1249 #endif
1250 
1251  if ((0 == port) && (NULL == unixpath))
1252  {
1254  _("Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
1255  service_name);
1256  GNUNET_free_non_null (hostname);
1257  return GNUNET_SYSERR;
1258  }
1259  if (0 == port)
1260  {
1261  saddrs = GNUNET_new_array (2,
1262  struct sockaddr *);
1263  saddrlens = GNUNET_new_array (2,
1264  socklen_t);
1265  add_unixpath (saddrs,
1266  saddrlens,
1267  unixpath,
1268  abstract);
1269  GNUNET_free_non_null (unixpath);
1270  GNUNET_free_non_null (hostname);
1271  *addrs = saddrs;
1272  *addr_lens = saddrlens;
1273  return 1;
1274  }
1275 
1276  if (NULL != hostname)
1277  {
1279  "Resolving `%s' since that is where `%s' will bind to.\n",
1280  hostname,
1281  service_name);
1282  memset (&hints,
1283  0,
1284  sizeof (struct addrinfo));
1285  if (disablev6)
1286  hints.ai_family = AF_INET;
1287  hints.ai_protocol = IPPROTO_TCP;
1288  if ((0 != (ret = getaddrinfo (hostname,
1289  NULL,
1290  &hints,
1291  &res))) ||
1292  (NULL == res))
1293  {
1295  _("Failed to resolve `%s': %s\n"),
1296  hostname,
1297  gai_strerror (ret));
1298  GNUNET_free (hostname);
1299  GNUNET_free_non_null (unixpath);
1300  return GNUNET_SYSERR;
1301  }
1302  next = res;
1303  i = 0;
1304  while (NULL != (pos = next))
1305  {
1306  next = pos->ai_next;
1307  if ( (disablev6) &&
1308  (pos->ai_family == AF_INET6) )
1309  continue;
1310  i++;
1311  }
1312  if (0 == i)
1313  {
1315  _("Failed to find %saddress for `%s'.\n"),
1316  disablev6 ? "IPv4 " : "",
1317  hostname);
1318  freeaddrinfo (res);
1319  GNUNET_free (hostname);
1320  GNUNET_free_non_null (unixpath);
1321  return GNUNET_SYSERR;
1322  }
1323  resi = i;
1324  if (NULL != unixpath)
1325  resi++;
1326  saddrs = GNUNET_new_array (resi + 1,
1327  struct sockaddr *);
1328  saddrlens = GNUNET_new_array (resi + 1,
1329  socklen_t);
1330  i = 0;
1331  if (NULL != unixpath)
1332  {
1333  add_unixpath (saddrs,
1334  saddrlens,
1335  unixpath,
1336  abstract);
1337  i++;
1338  }
1339  next = res;
1340  while (NULL != (pos = next))
1341  {
1342  next = pos->ai_next;
1343  if ( (disablev6) &&
1344  (AF_INET6 == pos->ai_family) )
1345  continue;
1346  if ( (IPPROTO_TCP != pos->ai_protocol) &&
1347  (0 != pos->ai_protocol) )
1348  continue; /* not TCP */
1349  if ( (SOCK_STREAM != pos->ai_socktype) &&
1350  (0 != pos->ai_socktype) )
1351  continue; /* huh? */
1353  "Service `%s' will bind to `%s'\n",
1354  service_name,
1355  GNUNET_a2s (pos->ai_addr,
1356  pos->ai_addrlen));
1357  if (AF_INET == pos->ai_family)
1358  {
1359  GNUNET_assert (sizeof (struct sockaddr_in) == pos->ai_addrlen);
1360  saddrlens[i] = pos->ai_addrlen;
1361  saddrs[i] = GNUNET_malloc (saddrlens[i]);
1362  GNUNET_memcpy (saddrs[i],
1363  pos->ai_addr,
1364  saddrlens[i]);
1365  ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1366  }
1367  else
1368  {
1369  GNUNET_assert (AF_INET6 == pos->ai_family);
1370  GNUNET_assert (sizeof (struct sockaddr_in6) == pos->ai_addrlen);
1371  saddrlens[i] = pos->ai_addrlen;
1372  saddrs[i] = GNUNET_malloc (saddrlens[i]);
1373  GNUNET_memcpy (saddrs[i],
1374  pos->ai_addr,
1375  saddrlens[i]);
1376  ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
1377  }
1378  i++;
1379  }
1380  GNUNET_free (hostname);
1381  freeaddrinfo (res);
1382  resi = i;
1383  }
1384  else
1385  {
1386  /* will bind against everything, just set port */
1387  if (disablev6)
1388  {
1389  /* V4-only */
1390  resi = 1;
1391  if (NULL != unixpath)
1392  resi++;
1393  i = 0;
1394  saddrs = GNUNET_new_array (resi + 1,
1395  struct sockaddr *);
1396  saddrlens = GNUNET_new_array (resi + 1,
1397  socklen_t);
1398  if (NULL != unixpath)
1399  {
1400  add_unixpath (saddrs,
1401  saddrlens,
1402  unixpath,
1403  abstract);
1404  i++;
1405  }
1406  saddrlens[i] = sizeof (struct sockaddr_in);
1407  saddrs[i] = GNUNET_malloc (saddrlens[i]);
1408 #if HAVE_SOCKADDR_IN_SIN_LEN
1409  ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
1410 #endif
1411  ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
1412  ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1413  }
1414  else
1415  {
1416  /* dual stack */
1417  resi = 2;
1418  if (NULL != unixpath)
1419  resi++;
1420  saddrs = GNUNET_new_array (resi + 1,
1421  struct sockaddr *);
1422  saddrlens = GNUNET_new_array (resi + 1,
1423  socklen_t);
1424  i = 0;
1425  if (NULL != unixpath)
1426  {
1427  add_unixpath (saddrs,
1428  saddrlens,
1429  unixpath,
1430  abstract);
1431  i++;
1432  }
1433  saddrlens[i] = sizeof (struct sockaddr_in6);
1434  saddrs[i] = GNUNET_malloc (saddrlens[i]);
1435 #if HAVE_SOCKADDR_IN_SIN_LEN
1436  ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
1437 #endif
1438  ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
1439  ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
1440  i++;
1441  saddrlens[i] = sizeof (struct sockaddr_in);
1442  saddrs[i] = GNUNET_malloc (saddrlens[i]);
1443 #if HAVE_SOCKADDR_IN_SIN_LEN
1444  ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
1445 #endif
1446  ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
1447  ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1448  }
1449  }
1450  GNUNET_free_non_null (unixpath);
1451  *addrs = saddrs;
1452  *addr_lens = saddrlens;
1453  return resi;
1454 }
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).
Definition: service.c:1054
int GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define STRERROR(i)
Definition: plibc.h:676
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:833
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
static int ret
Final status code.
Definition: gnunet-arm.c:89
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
#define GNUNET_memcpy(dst, src, n)
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
int GNUNET_CONFIGURATION_have_value(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Test if we have a value for a particular option.
static char * service_name
Option -s: service name (hash to get service descriptor)
Definition: gnunet-vpn.c:51
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
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)...
static int res
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static char * hostname
Our hostname; we give this to all the peers we start.
#define LOG(kind,...)
Definition: service.c:40
static uint16_t port
Port number.
Definition: gnunet-bcd.c:79
int GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
handle to a socket
Definition: network.c:46
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:157
#define GNUNET_YES
Definition: gnunet_common.h:80
int GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
#define LOG_STRERROR(kind, syscall)
Definition: service.c:42
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:604
#define GNUNET_malloc(size)
Wrapper around malloc.
int GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:84
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:1037
Here is the call graph for this function:
Here is the caller graph for this function:

◆ open_listen_socket()

static struct GNUNET_NETWORK_Handle* open_listen_socket ( const struct sockaddr *  server_addr,
socklen_t  socklen 
)
static

Create and initialize a listen socket for the server.

Parameters
server_addraddress to listen on
socklenlength of server_addr
Returns
NULL on error, otherwise the listen socket

Definition at line 1575 of file service.c.

References _, GNUNET_a2s(), GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_NETWORK_socket_bind(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_create(), GNUNET_NETWORK_socket_listen(), GNUNET_OK, LOG, LOG_STRERROR, and port.

Referenced by setup_service().

1577 {
1578  struct GNUNET_NETWORK_Handle *sock;
1579  uint16_t port;
1580  int eno;
1581 
1582  switch (server_addr->sa_family)
1583  {
1584  case AF_INET:
1585  port = ntohs (((const struct sockaddr_in *) server_addr)->sin_port);
1586  break;
1587  case AF_INET6:
1588  port = ntohs (((const struct sockaddr_in6 *) server_addr)->sin6_port);
1589  break;
1590  case AF_UNIX:
1591  port = 0;
1592  break;
1593  default:
1594  GNUNET_break (0);
1595  port = 0;
1596  break;
1597  }
1598  sock = GNUNET_NETWORK_socket_create (server_addr->sa_family,
1599  SOCK_STREAM,
1600  0);
1601  if (NULL == sock)
1602  {
1604  "socket");
1605  errno = 0;
1606  return NULL;
1607  }
1608  /* bind the socket */
1610  server_addr,
1611  socklen))
1612  {
1613  eno = errno;
1614  if (EADDRINUSE != errno)
1615  {
1616  /* we don't log 'EADDRINUSE' here since an IPv4 bind may
1617  * fail if we already took the port on IPv6; if both IPv4 and
1618  * IPv6 binds fail, then our caller will log using the
1619  * errno preserved in 'eno' */
1621  "bind");
1622  if (0 != port)
1624  _("`%s' failed for port %d (%s).\n"),
1625  "bind",
1626  port,
1627  (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1628  eno = 0;
1629  }
1630  else
1631  {
1632  if (0 != port)
1634  _("`%s' failed for port %d (%s): address already in use\n"),
1635  "bind", port,
1636  (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1637  else if (AF_UNIX == server_addr->sa_family)
1638  {
1640  _("`%s' failed for `%s': address already in use\n"),
1641  "bind",
1642  GNUNET_a2s (server_addr, socklen));
1643  }
1644  }
1647  errno = eno;
1648  return NULL;
1649  }
1651  5))
1652  {
1654  "listen");
1657  errno = 0;
1658  return NULL;
1659  }
1660  if (0 != port)
1662  "Server starts to listen on port %u.\n",
1663  port);
1664  return sock;
1665 }
int GNUNET_NETWORK_socket_listen(const struct GNUNET_NETWORK_Handle *desc, int backlog)
Listen on a socket.
Definition: network.c:796
int GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition: network.c:522
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
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 LOG(kind,...)
Definition: service.c:40
static uint16_t port
Port number.
Definition: gnunet-bcd.c:79
handle to a socket
Definition: network.c:46
#define LOG_STRERROR(kind, syscall)
Definition: service.c:42
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:604
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:1037
Here is the call graph for this function:
Here is the caller graph for this function:

◆ setup_service()

static int setup_service ( struct GNUNET_SERVICE_Handle sh)
static

Setup service handle.

Configuration may specify:

  • PORT (where to bind to for TCP)
  • UNIXPATH (where to bind to for UNIX domain sockets)
  • 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
shservice context to initialize
Returns
GNUNET_OK if configuration succeeded

Definition at line 1685 of file service.c.

References _, GNUNET_SERVICE_Handle::cfg, dummy, FD_SETSIZE, get_server_addresses(), getenv(), GNUNET_break, GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_CONFIGURATION_have_value(), GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_free_non_null, GNUNET_log, GNUNET_log_strerror, GNUNET_NETWORK_socket_box_native(), GNUNET_NETWORK_socket_close(), GNUNET_new, GNUNET_new_array, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, ServiceListenContext::listen_socket, LOG, ls, GNUNET_SERVICE_Handle::match_gid, GNUNET_SERVICE_Handle::match_uid, open_listen_socket(), process_acl4(), process_acl6(), GNUNET_SERVICE_Handle::require_found, GNUNET_SERVICE_Handle::service_name, ServiceListenContext::sh, GNUNET_SERVICE_Handle::slc_head, GNUNET_SERVICE_Handle::slc_tail, SSCANF, GNUNET_SERVICE_Handle::v4_allowed, GNUNET_SERVICE_Handle::v4_denied, GNUNET_SERVICE_Handle::v6_allowed, and GNUNET_SERVICE_Handle::v6_denied.

Referenced by GNUNET_SERVICE_run_(), and GNUNET_SERVICE_start().

1686 {
1687  int tolerant;
1688  struct GNUNET_NETWORK_Handle **lsocks;
1689 #ifndef MINGW
1690  const char *nfds;
1691  unsigned int cnt;
1692  int flags;
1693  char dummy[2];
1694 #endif
1695 
1697  (sh->cfg,
1698  sh->service_name,
1699  "TOLERANT"))
1700  {
1701  if (GNUNET_SYSERR ==
1702  (tolerant =
1704  sh->service_name,
1705  "TOLERANT")))
1706  {
1708  _("Specified value for `%s' of service `%s' is invalid\n"),
1709  "TOLERANT",
1710  sh->service_name);
1711  return GNUNET_SYSERR;
1712  }
1713  }
1714  else
1715  tolerant = GNUNET_NO;
1716 
1717  lsocks = NULL;
1718 #ifndef MINGW
1719  errno = 0;
1720  if ( (NULL != (nfds = getenv ("LISTEN_FDS"))) &&
1721  (1 == SSCANF (nfds,
1722  "%u%1s",
1723  &cnt,
1724  dummy)) &&
1725  (cnt > 0) &&
1726  (cnt < FD_SETSIZE) &&
1727  (cnt + 4 < FD_SETSIZE) )
1728  {
1729  lsocks = GNUNET_new_array (cnt + 1,
1730  struct GNUNET_NETWORK_Handle *);
1731  while (0 < cnt--)
1732  {
1733  flags = fcntl (3 + cnt,
1734  F_GETFD);
1735  if ( (flags < 0) ||
1736  (0 != (flags & FD_CLOEXEC)) ||
1737  (NULL ==
1738  (lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt))))
1739  {
1741  _("Could not access pre-bound socket %u, will try to bind myself\n"),
1742  (unsigned int) 3 + cnt);
1743  cnt++;
1744  while (NULL != lsocks[cnt])
1746  GNUNET_NETWORK_socket_close (lsocks[cnt++]));
1747  GNUNET_free (lsocks);
1748  lsocks = NULL;
1749  break;
1750  }
1751  }
1752  unsetenv ("LISTEN_FDS");
1753  }
1754 #else
1755  if (NULL != getenv ("GNUNET_OS_READ_LSOCKS"))
1756  {
1757  lsocks = receive_sockets_from_parent (sh);
1758  putenv ("GNUNET_OS_READ_LSOCKS=");
1759  }
1760 #endif
1761 
1762  if (NULL != lsocks)
1763  {
1764  /* listen only on inherited sockets if we have any */
1765  struct GNUNET_NETWORK_Handle **ls;
1766 
1767  for (ls = lsocks; NULL != *ls; ls++)
1768  {
1769  struct ServiceListenContext *slc;
1770 
1771  slc = GNUNET_new (struct ServiceListenContext);
1772  slc->sh = sh;
1773  slc->listen_socket = *ls;
1775  sh->slc_tail,
1776  slc);
1777  }
1778  GNUNET_free (lsocks);
1779  }
1780  else
1781  {
1782  struct sockaddr **addrs;
1783  socklen_t *addrlens;
1784  int num;
1785 
1787  sh->cfg,
1788  &addrs,
1789  &addrlens);
1790  if (GNUNET_SYSERR == num)
1791  return GNUNET_SYSERR;
1792 
1793  for (int i = 0; i < num; i++)
1794  {
1795  struct ServiceListenContext *slc;
1796 
1797  slc = GNUNET_new (struct ServiceListenContext);
1798  slc->sh = sh;
1799  slc->listen_socket = open_listen_socket (addrs[i],
1800  addrlens[i]);
1801  GNUNET_free (addrs[i]);
1802  if (NULL == slc->listen_socket)
1803  {
1805  "bind");
1806  GNUNET_free (slc);
1807  continue;
1808  }
1810  sh->slc_tail,
1811  slc);
1812  }
1813  GNUNET_free_non_null (addrlens);
1814  GNUNET_free_non_null (addrs);
1815  if ( (0 != num) &&
1816  (NULL == sh->slc_head) )
1817  {
1818  /* All attempts to bind failed, hard failure */
1820  _("Could not bind to any of the ports I was supposed to, refusing to run!\n"));
1821  return GNUNET_SYSERR;
1822  }
1823  }
1824 
1825  sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
1826  sh->match_uid
1828  sh->service_name,
1829  "UNIX_MATCH_UID");
1830  sh->match_gid
1832  sh->service_name,
1833  "UNIX_MATCH_GID");
1834  process_acl4 (&sh->v4_denied,
1835  sh,
1836  "REJECT_FROM");
1837  process_acl4 (&sh->v4_allowed,
1838  sh,
1839  "ACCEPT_FROM");
1840  process_acl6 (&sh->v6_denied,
1841  sh,
1842  "REJECT_FROM6");
1843  process_acl6 (&sh->v6_allowed,
1844  sh,
1845  "ACCEPT_FROM6");
1846  return GNUNET_OK;
1847 }
struct ServiceListenContext * slc_head
DLL of listen sockets used to accept new connections.
Definition: service.c:151
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:1105
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
static struct in_addr dummy
Target "dummy" address.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
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
int require_found
If GNUNET_YES, consider unknown message types an error where the client is disconnected.
Definition: service.c:242
struct GNUNET_NETWORK_Handle * listen_socket
Socket we are listening on.
Definition: service.c:71
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static int process_acl6(struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, struct GNUNET_SERVICE_Handle *sh, const char *option)
Parse an IPv6 access control list.
Definition: service.c:1010
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_denied
IPv6 addresses that are not allowed to connect.
Definition: service.c:186
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
#define FD_SETSIZE
Definition: winproc.h:39
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
struct GNUNET_SERVICE_Handle * sh
Service this listen context belongs to.
Definition: service.c:66
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_box_native(SOCKTYPE fd)
Box a native socket (and check that it is a socket).
Definition: network.c:694
int GNUNET_CONFIGURATION_have_value(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Test if we have a value for a particular option.
static struct SolverHandle * sh
struct ServiceListenContext * slc_tail
DLL of listen sockets used to accept new connections.
Definition: service.c:156
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
Information the service tracks per listen operation.
Definition: service.c:50
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_denied
IPv4 addresses that are not allowed to connect.
Definition: service.c:181
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:1575
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
char * getenv()
static int process_acl4(struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, struct GNUNET_SERVICE_Handle *sh, const char *option)
Parse an IPv4 access control list.
Definition: service.c:967
static struct GNUNET_NETWORK_Handle * ls
Listen socket for STUN processing.
Definition: gnunet-nat.c:85
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_allowed
IPv6 addresses that are allowed to connect (if not set, all are allowed).
Definition: service.c:198
#define LOG(kind,...)
Definition: service.c:40
#define SSCANF
Definition: plibc.h:691
#define GNUNET_log(kind,...)
const char * service_name
Name of our service.
Definition: service.c:126
handle to a socket
Definition: network.c:46
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_allowed
IPv4 addresses that are allowed to connect (if not set, all are allowed).
Definition: service.c:192
#define GNUNET_YES
Definition: gnunet_common.h:80
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: service.c:121
int GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:604
#define GNUNET_free(ptr)
Wrapper around free.
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 GNUNET_SERVICE_Handle sh)
static

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

Parameters
shservice context
Returns
value of the 'USERNAME' option

Definition at line 1858 of file service.c.

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

Referenced by set_user_id().

1859 {
1860  char *un;
1861 
1862  if (GNUNET_OK !=
1864  sh->service_name,
1865  "USERNAME",
1866  &un))
1867  return NULL;
1868  return un;
1869 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
const char * service_name
Name of our service.
Definition: service.c:126
int GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: service.c:121
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_user_id()

static int set_user_id ( struct GNUNET_SERVICE_Handle sh)
static

Set user ID.

Parameters
shservice context
Returns
GNUNET_OK on success, GNUNET_SYSERR on error

Definition at line 1879 of file service.c.

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

Referenced by GNUNET_SERVICE_run_().

1880 {
1881  char *user;
1882 
1883  if (NULL == (user = get_user_name (sh)))
1884  return GNUNET_OK; /* keep */
1885 #ifndef MINGW
1886  struct passwd *pws;
1887 
1888  errno = 0;
1889  pws = getpwnam (user);
1890  if (NULL == pws)
1891  {
1893  _("Cannot obtain information about user `%s': %s\n"),
1894  user,
1895  errno == 0 ? _("No such user") : STRERROR (errno));
1896  GNUNET_free (user);
1897  return GNUNET_SYSERR;
1898  }
1899  if ( (0 != setgid (pws->pw_gid)) ||
1900  (0 != setegid (pws->pw_gid)) ||
1901 #if HAVE_INITGROUPS
1902  (0 != initgroups (user,
1903  pws->pw_gid)) ||
1904 #endif
1905  (0 != setuid (pws->pw_uid)) ||
1906  (0 != seteuid (pws->pw_uid)))
1907  {
1908  if ((0 != setregid (pws->pw_gid,
1909  pws->pw_gid)) ||
1910  (0 != setreuid (pws->pw_uid,
1911  pws->pw_uid)))
1912  {
1914  _("Cannot change user/group to `%s': %s\n"),
1915  user,
1916  STRERROR (errno));
1917  GNUNET_free (user);
1918  return GNUNET_SYSERR;
1919  }
1920  }
1921 #endif
1922  GNUNET_free (user);
1923  return GNUNET_OK;
1924 }
#define STRERROR(i)
Definition: plibc.h:676
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
static char * get_user_name(struct GNUNET_SERVICE_Handle *sh)
Get the name of the user that&#39;ll be used to provide the service.
Definition: service.c:1858
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
#define LOG(kind,...)
Definition: service.c:40
#define GNUNET_free(ptr)
Wrapper around free.
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 GNUNET_SERVICE_Handle sh)
static

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

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

Definition at line 1935 of file service.c.

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

Referenced by pid_file_delete().

1936 {
1937  char *pif;
1938 
1939  if (GNUNET_OK !=
1941  sh->service_name,
1942  "PIDFILE",
1943  &pif))
1944  return NULL;
1945  return pif;
1946 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
const char * service_name
Name of our service.
Definition: service.c:126
int GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: service.c:121
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 GNUNET_SERVICE_Handle sh)
static

Delete the PID file that was created by our parent.

Parameters
shservice context

Definition at line 1955 of file service.c.

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

Referenced by GNUNET_SERVICE_run_().

1956 {
1957  char *pif = get_pid_file_name (sh);
1958 
1959  if (NULL == pif)
1960  return; /* no PID file */
1961  if (0 != UNLINK (pif))
1963  "unlink",
1964  pif);
1965  GNUNET_free (pif);
1966 }
#define UNLINK(f)
Definition: plibc.h:666
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:1935
#define LOG_STRERROR_FILE(kind, syscall, filename)
Definition: service.c:44
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ detach_terminal()

static int detach_terminal ( struct GNUNET_SERVICE_Handle sh)
static

Detach from terminal.

Parameters
shservice context
Returns
GNUNET_OK on success, GNUNET_SYSERR on error

Definition at line 1976 of file service.c.

References _, CLOSE, GNUNET_break, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_OK, GNUNET_SYSERR, LOG, LOG_STRERROR, OPEN, pid, PIPE, READ, and GNUNET_SERVICE_Handle::ready_confirm_fd.

Referenced by GNUNET_SERVICE_run_().

1977 {
1978 #ifndef MINGW
1979  pid_t pid;
1980  int nullfd;
1981  int filedes[2];
1982 
1983  if (0 != PIPE (filedes))
1984  {
1986  "pipe");
1987  return GNUNET_SYSERR;
1988  }
1989  pid = fork ();
1990  if (pid < 0)
1991  {
1993  "fork");
1994  return GNUNET_SYSERR;
1995  }
1996  if (0 != pid)
1997  {
1998  /* Parent */
1999  char c;
2000 
2001  GNUNET_break (0 == CLOSE (filedes[1]));
2002  c = 'X';
2003  if (1 != READ (filedes[0],
2004  &c,
2005  sizeof (char)))
2007  "read");
2008  fflush (stdout);
2009  switch (c)
2010  {
2011  case '.':
2012  exit (0);
2013  case 'I':
2015  _("Service process failed to initialize\n"));
2016  break;
2017  case 'S':
2019  _("Service process could not initialize server function\n"));
2020  break;
2021  case 'X':
2023  _("Service process failed to report status\n"));
2024  break;
2025  }
2026  exit (1); /* child reported error */
2027  }
2028  GNUNET_break (0 == CLOSE (0));
2029  GNUNET_break (0 == CLOSE (1));
2030  GNUNET_break (0 == CLOSE (filedes[0]));
2031  nullfd = OPEN ("/dev/null",
2032  O_RDWR | O_APPEND);
2033  if (nullfd < 0)
2034  return GNUNET_SYSERR;
2035  /* set stdin/stdout to /dev/null */
2036  if ( (dup2 (nullfd, 0) < 0) ||
2037  (dup2 (nullfd, 1) < 0) )
2038  {
2040  "dup2");
2041  (void) CLOSE (nullfd);
2042  return GNUNET_SYSERR;
2043  }
2044  (void) CLOSE (nullfd);
2045  /* Detach from controlling terminal */
2046  pid = setsid ();
2047  if (-1 == pid)
2049  "setsid");
2050  sh->ready_confirm_fd = filedes[1];
2051 #else
2052  /* FIXME: we probably need to do something else
2053  * elsewhere in order to fork the process itself... */
2054  FreeConsole ();
2055 #endif
2056  return GNUNET_OK;
2057 }
#define OPEN
Definition: plibc.h:651
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
int ready_confirm_fd
If we are daemonizing, this FD is set to the pipe to the parent.
Definition: service.c:231
#define PIPE(h)
Definition: plibc.h:660
#define CLOSE(f)
Definition: plibc.h:653
#define READ(f, b, n)
Definition: plibc.h:668
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
#define LOG(kind,...)
Definition: service.c:40
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
#define LOG_STRERROR(kind, syscall)
Definition: service.c:42
Here is the caller graph for this function:

◆ teardown_service()

static void teardown_service ( struct GNUNET_SERVICE_Handle sh)
static

Tear down the service, closing the listen sockets and freeing the ACLs.

Parameters
shhandle to the service to tear down.

Definition at line 2067 of file service.c.

References GNUNET_break, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_free_non_null, GNUNET_NETWORK_socket_close(), GNUNET_OK, GNUNET_SCHEDULER_cancel(), ServiceListenContext::listen_socket, ServiceListenContext::listen_task, GNUNET_SERVICE_Handle::slc_head, GNUNET_SERVICE_Handle::slc_tail, GNUNET_SERVICE_Handle::v4_allowed, GNUNET_SERVICE_Handle::v4_denied, GNUNET_SERVICE_Handle::v6_allowed, and GNUNET_SERVICE_Handle::v6_denied.

Referenced by GNUNET_SERVICE_run_(), and GNUNET_SERVICE_stop().

2068 {
2069  struct ServiceListenContext *slc;
2070 
2075  while (NULL != (slc = sh->slc_head))
2076  {
2078  sh->slc_tail,
2079  slc);
2080  if (NULL != slc->listen_task)
2084  GNUNET_free (slc);
2085  }
2086 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct ServiceListenContext * slc_head
DLL of listen sockets used to accept new connections.
Definition: service.c:151
struct GNUNET_NETWORK_Handle * listen_socket
Socket we are listening on.
Definition: service.c:71
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_denied
IPv6 addresses that are not allowed to connect.
Definition: service.c:186
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct ServiceListenContext * slc_tail
DLL of listen sockets used to accept new connections.
Definition: service.c:156
Information the service tracks per listen operation.
Definition: service.c:50
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_denied
IPv4 addresses that are not allowed to connect.
Definition: service.c:181
struct GNUNET_SCHEDULER_Task * listen_task
Task scheduled to do the listening.
Definition: service.c:76
struct GNUNET_STRINGS_IPv6NetworkPolicy * v6_allowed
IPv6 addresses that are allowed to connect (if not set, all are allowed).
Definition: service.c:198
struct GNUNET_STRINGS_IPv4NetworkPolicy * v4_allowed
IPv4 addresses that are allowed to connect (if not set, all are allowed).
Definition: service.c:192
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:604
#define GNUNET_free(ptr)
Wrapper around free.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
Here is the call graph for this function:
Here is the caller graph for this function:

◆ return_agpl()

static void return_agpl ( void *  cls,
const struct GNUNET_MessageHeader msg 
)
static

Function to return link to AGPL source upon request.

Parameters
clsclosure with the identification of the client
msgAGPL request

Definition at line 2096 of file service.c.

References env, GNUNET_AGPL_URL, GNUNET_MESSAGE_TYPE_RESPONSE_AGPL, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_get_mq(), mq, and res.

Referenced by GNUNET_SERVICE_start().

2098 {
2099  struct GNUNET_SERVICE_Client *client = cls;
2100  struct GNUNET_MQ_Handle *mq;
2101  struct GNUNET_MQ_Envelope *env;
2102  struct GNUNET_MessageHeader *res;
2103  size_t slen;
2104 
2105  (void) msg;
2106  slen = strlen (GNUNET_AGPL_URL) + 1;
2107  env = GNUNET_MQ_msg_extra (res,
2109  slen);
2110  memcpy (&res[1],
2112  slen);
2113  mq = GNUNET_SERVICE_client_get_mq (client);
2114  GNUNET_MQ_send (mq,
2115  env);
2117 }
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2734
Handle to a client that is connected to a service.
Definition: service.c:249
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
static int res
#define GNUNET_MESSAGE_TYPE_RESPONSE_AGPL
Source code link.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
Handle to a message queue.
Definition: mq.c:85
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_AGPL_URL
NOTE: You MUST adjust this URL to point to the location of a publicly accessible repository (or TGZ) ...
Header for all communications.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2533
Here is the call graph for this function:
Here is the caller graph for this function:

◆ resume_client_receive()

static void resume_client_receive ( void *  cls)
static

Task run to resume receiving data from the client after the client called GNUNET_SERVICE_client_continue().

Parameters
clsour struct GNUNET_SERVICE_Client

Definition at line 2495 of file service.c.

References GNUNET_SERVICE_Client::drop_task, GNUNET_assert, GNUNET_MST_next(), GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_read_net(), GNUNET_SERVICE_client_drop(), GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, GNUNET_SERVICE_Client::mst, GNUNET_SERVICE_Client::needs_continue, GNUNET_SERVICE_Client::recv_task, ret, service_client_recv(), and GNUNET_SERVICE_Client::sock.

Referenced by GNUNET_SERVICE_client_continue().

2496 {
2497  struct GNUNET_SERVICE_Client *c = cls;
2498  int ret;
2499 
2500  c->recv_task = NULL;
2501  /* first, check if there is still something in the buffer */
2502  ret = GNUNET_MST_next (c->mst,
2503  GNUNET_YES);
2504  if (GNUNET_SYSERR == ret)
2505  {
2506  if (NULL == c->drop_task)
2508  return;
2509  }
2510  if (GNUNET_NO == ret)
2511  return; /* done processing, wait for more later */
2512  GNUNET_assert (GNUNET_OK == ret);
2513  if (GNUNET_YES == c->needs_continue)
2514  return; /* #GNUNET_MST_next() did give a message to the client */
2515  /* need to receive more data from the network first */
2516  if (NULL != c->recv_task)
2517  return;
2518  c->recv_task
2520  c->sock,
2522  c);
2523 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int GNUNET_MST_next(struct GNUNET_MessageStreamTokenizer *mst, int one_shot)
Obtain the next message from the mst, assuming that there are more unprocessed messages in the intern...
Definition: mst.c:396
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
static int ret
Final status code.
Definition: gnunet-arm.c:89
struct GNUNET_MessageStreamTokenizer * mst
Tokenizer we use for processing incoming data.
Definition: service.c:280
Handle to a client that is connected to a service.
Definition: service.c:249
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2618
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static void service_client_recv(void *cls)
A client sent us data.
Definition: service.c:720
int needs_continue
Are we waiting for the application to call GNUNET_SERVICE_client_continue()?
Definition: service.c:344
#define GNUNET_YES
Definition: gnunet_common.h:80
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:1478
struct GNUNET_NETWORK_Handle * sock
Socket of this client.
Definition: service.c:270
struct GNUNET_SCHEDULER_Task * recv_task
Task that receives data from the client to pass it to the handlers.
Definition: service.c:298
struct GNUNET_SCHEDULER_Task * drop_task
Task run to finish dropping the client after the stack has properly unwound.
Definition: service.c:292
Here is the call graph for this function:
Here is the caller graph for this function:

◆ finish_client_drop()

static void finish_client_drop ( void *  cls)
static

Asynchronously finish dropping the client.

Parameters
clsthe struct GNUNET_SERVICE_Client.

Definition at line 2576 of file service.c.

References do_resume(), GNUNET_SERVICE_Client::drop_task, GNUNET_assert, GNUNET_break, GNUNET_free, GNUNET_MQ_destroy(), GNUNET_MST_destroy(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_free_memory_only_(), GNUNET_NO, GNUNET_OK, GNUNET_SERVICE_shutdown(), have_non_monitor_clients(), GNUNET_SERVICE_Client::mq, GNUNET_SERVICE_Client::mst, GNUNET_SERVICE_Client::persist, GNUNET_SERVICE_Client::recv_task, GNUNET_SERVICE_Client::send_task, GNUNET_SERVICE_Client::sh, GNUNET_SERVICE_Client::sock, GNUNET_SERVICE_Handle::suspend_state, SUSPEND_STATE_EMFILE, SUSPEND_STATE_SHUTDOWN, and GNUNET_SERVICE_Client::warn_task.

Referenced by GNUNET_SERVICE_client_drop().

2577 {
2578  struct GNUNET_SERVICE_Client *c = cls;
2579  struct GNUNET_SERVICE_Handle *sh = c->sh;
2580 
2581  c->drop_task = NULL;
2582  GNUNET_assert (NULL == c->send_task);
2583  GNUNET_assert (NULL == c->recv_task);
2584  GNUNET_assert (NULL == c->warn_task);
2585  GNUNET_MST_destroy (c->mst);
2586  GNUNET_MQ_destroy (c->mq);
2587  if (GNUNET_NO == c->persist)
2588  {
2591  if ( (0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) &&
2592  (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) )
2593  do_resume (sh,
2595  }
2596  else
2597  {
2599  }
2600  GNUNET_free (c);
2601  if ( (0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) &&
2604 }
enum SuspendReason suspend_state
Are we suspended, and if so, why?
Definition: service.c:219
struct GNUNET_SCHEDULER_Task * send_task
Task that transmit data to the client.
Definition: service.c:303
Handle to a service.
Definition: service.c:116
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
struct GNUNET_MQ_Handle * mq
Message queue for the client.
Definition: service.c:275
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_MessageStreamTokenizer * mst
Tokenizer we use for processing incoming data.
Definition: service.c:280
Handle to a client that is connected to a service.
Definition: service.c:249
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:680
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:413
struct GNUNET_SCHEDULER_Task * warn_task
Task that warns about missing calls to GNUNET_SERVICE_client_continue().
Definition: service.c:286
static struct SolverHandle * sh
int persist
Persist the file handle for this client no matter what happens, force the OS to close once the proces...
Definition: service.c:332
static void do_resume(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
Resume accepting connections from the listen socket.
Definition: service.c:903
struct GNUNET_SERVICE_Handle * sh
Service that this client belongs to.
Definition: service.c:265
Suspension because service was permanently shutdown.
Definition: service.c:109
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:824
OS ran out of file descriptors.
Definition: service.c:99
struct GNUNET_NETWORK_Handle * sock
Socket of this client.
Definition: service.c:270
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:604
struct GNUNET_SCHEDULER_Task * recv_task
Task that receives data from the client to pass it to the handlers.
Definition: service.c:298
struct GNUNET_SCHEDULER_Task * drop_task
Task run to finish dropping the client after the stack has properly unwound.
Definition: service.c:292
static int have_non_monitor_clients(struct GNUNET_SERVICE_Handle *sh)
Check if any of the clients we have left are unrelated to monitoring.
Definition: service.c:361
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh)
Explicitly stops the service.
Definition: service.c:2679
Here is the call graph for this function:
Here is the caller graph for this function: