GNUnet  0.17.5
Data Structures | Macros | Functions
client.c File Reference

code for access to services More...

#include "platform.h"
#include "gnunet_protocols.h"
#include "gnunet_util_lib.h"
#include "gnunet_resolver_service.h"
#include "gnunet_socks.h"
Include dependency graph for client.c:

Go to the source code of this file.

Data Structures

struct  AddressProbe
 During connect, we try multiple possible IP addresses to find out which one might work. More...
 
struct  ClientState
 State we keep per client. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "util-client", __VA_ARGS__)
 
#define CONNECT_RETRY_TIMEOUT
 Timeout we use on TCP connect before trying another result from the DNS resolver. More...
 

Functions

static void start_connect (void *cls)
 Try to connect to the service. More...
 
static void connect_fail_continuation (struct ClientState *cstate)
 We've failed for good to establish a connection (timeout or no more addresses to try). More...
 
static void transmit_ready (void *cls)
 We are ready to send a message to the service. More...
 
static int recv_message (void *cls, const struct GNUNET_MessageHeader *msg)
 We have received a full message, pass to the MQ dispatcher. More...
 
static void cancel_aps (struct ClientState *cstate)
 Cancel all remaining connect attempts. More...
 
static void connection_client_destroy_impl (struct GNUNET_MQ_Handle *mq, void *impl_state)
 Implement the destruction of a message queue. More...
 
static void receive_ready (void *cls)
 This function is called once we have data ready to read. More...
 
static void connect_success_continuation (struct ClientState *cstate)
 We've succeeded in establishing a connection. More...
 
static struct GNUNET_NETWORK_Handletry_unixpath (const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg)
 Try connecting to the server using UNIX domain sockets. More...
 
static void connect_probe_continuation (void *cls)
 Scheduler let us know that we're either ready to write on the socket OR connect timed out. More...
 
static void try_connect_using_address (void *cls, const struct sockaddr *addr, socklen_t addrlen)
 Try to establish a connection given the specified address. More...
 
static int test_service_configuration (const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg)
 Test whether the configuration has proper values for connection (UNIXPATH || (PORT && HOSTNAME)). More...
 
static void connection_client_send_impl (struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
 Implements the transmission functionality of a message queue. More...
 
static void connection_client_cancel_impl (struct GNUNET_MQ_Handle *mq, void *impl_state)
 Cancel the currently sent message. More...
 
int GNUNET_CLIENT_test (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name)
 Test if the port or UNIXPATH of the given service_name is in use and thus (most likely) the respective service is up. More...
 
struct GNUNET_MQ_HandleGNUNET_CLIENT_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
 Create a message queue to connect to a GNUnet service. More...
 

Detailed Description

code for access to services

Author
Christian Grothoff

Generic TCP code for reliable, record-oriented TCP connections between clients and service providers.

Definition in file client.c.

Macro Definition Documentation

◆ LOG

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

Definition at line 36 of file client.c.

◆ CONNECT_RETRY_TIMEOUT

#define CONNECT_RETRY_TIMEOUT
Value:
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:483

Timeout we use on TCP connect before trying another result from the DNS resolver.

Actual value used is this value divided by the number of address families. Default is 5s.

Definition at line 44 of file client.c.

Function Documentation

◆ start_connect()

static void start_connect ( void *  cls)
static

Try to connect to the service.

Parameters
clsthe struct ClientState to try to connect to the service

Definition at line 785 of file client.c.

786 {
787  struct ClientState *cstate = cls;
788 
789  cstate->retry_task = NULL;
790 #if 0
791  /* Never use a local source if a proxy is configured */
792  if (GNUNET_YES ==
794  cstate->cfg))
795  {
796  socks_connect (cstate);
797  return;
798  }
799 #endif
800 
801  if ((0 == (cstate->attempts++ % 2)) ||
802  (0 == cstate->port) ||
803  (NULL == cstate->hostname))
804  {
805  /* on even rounds, try UNIX first, or always
806  if we do not have a DNS name and TCP port. */
807  cstate->sock = try_unixpath (cstate->service_name,
808  cstate->cfg);
809  if (NULL != cstate->sock)
810  {
812  return;
813  }
814  }
815  if ((NULL == cstate->hostname) ||
816  (0 == cstate->port))
817  {
818  /* All options failed. Boo! */
819  connect_fail_continuation (cstate);
820  return;
821  }
822  cstate->dns_active
823  = GNUNET_RESOLVER_ip_get (cstate->hostname,
824  AF_UNSPEC,
827  cstate);
828 }
static void try_connect_using_address(void *cls, const struct sockaddr *addr, socklen_t addrlen)
Try to establish a connection given the specified address.
Definition: client.c:636
static void connect_success_continuation(struct ClientState *cstate)
We've succeeded in establishing a connection.
Definition: client.c:481
static struct GNUNET_NETWORK_Handle * try_unixpath(const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg)
Try connecting to the server using UNIX domain sockets.
Definition: client.c:509
static void connect_fail_continuation(struct ClientState *cstate)
We've failed for good to establish a connection (timeout or no more addresses to try).
Definition: client.c:220
#define CONNECT_RETRY_TIMEOUT
Timeout we use on TCP connect before trying another result from the DNS resolver.
Definition: client.c:44
@ GNUNET_YES
struct GNUNET_RESOLVER_RequestHandle * GNUNET_RESOLVER_ip_get(const char *hostname, int af, struct GNUNET_TIME_Relative timeout, GNUNET_RESOLVER_AddressCallback callback, void *callback_cls)
Convert a string to one or more IP addresses.
Definition: resolver_api.c:939
int GNUNET_SOCKS_check_service(const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg)
Check if a SOCKS proxy is required by a service.
Definition: socks.c:593
State we keep per client.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: client.c:115
unsigned int attempts
How often have we tried to connect?
Definition: client.c:193
struct GNUNET_SCHEDULER_Task * retry_task
Task for trying to connect to the service.
Definition: client.c:147
char * hostname
Hostname, if any.
Definition: client.c:137
struct GNUNET_RESOLVER_RequestHandle * dns_active
Handle to a pending DNS lookup request, NULL if DNS is finished.
Definition: client.c:110
unsigned long long port
TCP port (0 for disabled).
Definition: client.c:183
struct GNUNET_NETWORK_Handle * sock
The connection handle, NULL if not live.
Definition: client.c:105
char * service_name
Name of the service we interact with.
Definition: client.c:132

References ClientState::attempts, ClientState::cfg, connect_fail_continuation(), CONNECT_RETRY_TIMEOUT, connect_success_continuation(), ClientState::dns_active, GNUNET_RESOLVER_ip_get(), GNUNET_SOCKS_check_service(), GNUNET_YES, ClientState::hostname, ClientState::port, ClientState::retry_task, ClientState::service_name, ClientState::sock, try_connect_using_address(), and try_unixpath().

Referenced by connect_fail_continuation(), and GNUNET_CLIENT_connect().

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

◆ connect_fail_continuation()

static void connect_fail_continuation ( struct ClientState cstate)
static

We've failed for good to establish a connection (timeout or no more addresses to try).

Parameters
cstatethe connection we tried to establish

Definition at line 220 of file client.c.

221 {
222  GNUNET_break (NULL == cstate->ap_head);
223  GNUNET_break (NULL == cstate->ap_tail);
224  GNUNET_break (NULL == cstate->dns_active);
225  GNUNET_break (NULL == cstate->sock);
226  GNUNET_assert (NULL == cstate->send_task);
227  GNUNET_assert (NULL == cstate->recv_task);
228  // GNUNET_assert (NULL == cstate->proxy_handshake);
229 
230  cstate->back_off = GNUNET_TIME_STD_BACKOFF (cstate->back_off);
232  "Failed to establish connection to `%s', no further addresses to try, will try again in %s.\n",
233  cstate->service_name,
235  GNUNET_YES));
236  cstate->retry_task
238  &start_connect,
239  cstate);
240 }
static void start_connect(void *cls)
Try to connect to the service.
Definition: client.c:785
#define LOG(kind,...)
Definition: client.c:36
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_DEBUG
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1254
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:570
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
struct GNUNET_TIME_Relative back_off
Current value for our incremental back-off (for connect re-tries).
Definition: client.c:178
struct GNUNET_SCHEDULER_Task * send_task
Task for sending messages to the service.
Definition: client.c:152
struct GNUNET_SCHEDULER_Task * recv_task
Task for sending messages to the service.
Definition: client.c:157
struct AddressProbe * ap_tail
Linked list of sockets we are currently trying out (during connect).
Definition: client.c:127
struct AddressProbe * ap_head
Linked list of sockets we are currently trying out (during connect).
Definition: client.c:121

References ClientState::ap_head, ClientState::ap_tail, ClientState::back_off, ClientState::dns_active, GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_SCHEDULER_add_delayed(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_STD_BACKOFF, GNUNET_YES, LOG, ClientState::recv_task, ClientState::retry_task, ClientState::send_task, ClientState::service_name, ClientState::sock, and start_connect().

Referenced by connect_probe_continuation(), start_connect(), and try_connect_using_address().

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

◆ transmit_ready()

static void transmit_ready ( void *  cls)
static

We are ready to send a message to the service.

Parameters
clsthe struct ClientState with the msg to transmit

Definition at line 249 of file client.c.

250 {
251  struct ClientState *cstate = cls;
252  ssize_t ret;
253  size_t len;
254  const char *pos;
255  int notify_in_flight;
256 
257  cstate->send_task = NULL;
258  if (GNUNET_YES == cstate->in_destroy)
259  return;
260  pos = (const char *) cstate->msg;
261  len = ntohs (cstate->msg->size);
262  GNUNET_assert (cstate->msg_off < len);
264  "message of type %u and size %u trying to send with socket %p (MQ: %p\n",
265  ntohs (cstate->msg->type),
266  ntohs (cstate->msg->size),
267  cstate->sock,
268  cstate->mq);
269 
270  RETRY:
272  &pos[cstate->msg_off],
273  len - cstate->msg_off);
274  if ( (-1 == ret) &&
275  ( (EAGAIN == errno) ||
276  (EINTR == errno) ) )
277  {
278  /* ignore */
279  ret = 0;
280  }
281  if (-1 == ret)
282  {
284  "Error during sending message of type %u: %s\n",
285  ntohs (cstate->msg->type),
286  strerror (errno));
287  if (EINTR == errno)
288  {
290  "Retrying message of type %u\n",
291  ntohs (cstate->msg->type));
292  goto RETRY;
293  }
294  GNUNET_MQ_inject_error (cstate->mq,
296  return;
297  }
298  notify_in_flight = (0 == cstate->msg_off);
299  cstate->msg_off += ret;
300  if (cstate->msg_off < len)
301  {
303  "rescheduling message of type %u\n",
304  ntohs (cstate->msg->type));
305  cstate->send_task
307  cstate->sock,
309  cstate);
310  if (notify_in_flight)
312  return;
313  }
315  "sending message of type %u and size %u successful\n",
316  ntohs (cstate->msg->type),
317  ntohs (cstate->msg->size));
318  cstate->msg = NULL;
320 }
static void transmit_ready(void *cls)
We are ready to send a message to the service.
Definition: client.c:249
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
@ GNUNET_ERROR_TYPE_WARNING
void GNUNET_MQ_inject_error(struct GNUNET_MQ_Handle *mq, enum GNUNET_MQ_Error error)
Call the error handler of a message queue with the given error code.
Definition: mq.c:267
void GNUNET_MQ_impl_send_continue(struct GNUNET_MQ_Handle *mq)
Call the send implementation for the next queued message, if any.
Definition: mq.c:423
void GNUNET_MQ_impl_send_in_flight(struct GNUNET_MQ_Handle *mq)
Call the send notification for the current message, but do not try to send the next message until #gn...
Definition: mq.c:446
@ GNUNET_MQ_ERROR_WRITE
FIXME: document!
ssize_t GNUNET_NETWORK_socket_send(const struct GNUNET_NETWORK_Handle *desc, const void *buffer, size_t length)
Send data (always non-blocking).
Definition: network.c:760
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_write_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *wfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1573
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
#define RETRY
Return code we give on 'send' if we failed to send right now but it makes sense to retry later.
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
int in_destroy
Are we supposed to die? GNUNET_SYSERR if destruction must be deferred, GNUNET_NO by default,...
Definition: client.c:200
const struct GNUNET_MessageHeader * msg
Next message to transmit to the service.
Definition: client.c:142
size_t msg_off
Offset in the message where we are for transmission.
Definition: client.c:188
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.

References GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, 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, GNUNET_YES, ClientState::in_destroy, len, LOG, ClientState::mq, ClientState::msg, ClientState::msg_off, ret, RETRY, ClientState::send_task, GNUNET_MessageHeader::size, ClientState::sock, and GNUNET_MessageHeader::type.

Referenced by connect_success_continuation(), and connection_client_send_impl().

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

◆ recv_message()

static int recv_message ( void *  cls,
const struct GNUNET_MessageHeader msg 
)
static

We have received a full message, pass to the MQ dispatcher.

Called by the tokenizer via receive_ready().

Parameters
clsthe struct ClientState
msgmessage we received.
Returns
GNUNET_OK on success, GNUNET_NO to stop further processing due to disconnect (no error) GNUNET_SYSERR to stop further processing due to error

Definition at line 334 of file client.c.

336 {
337  struct ClientState *cstate = cls;
338 
339  if (GNUNET_YES == cstate->in_destroy)
340  return GNUNET_NO;
342  "Received message of type %u and size %u from %s\n",
343  ntohs (msg->type),
344  ntohs (msg->size),
345  cstate->service_name);
346  GNUNET_MQ_inject_message (cstate->mq,
347  msg);
348  if (GNUNET_YES == cstate->in_destroy)
349  return GNUNET_NO;
350  return GNUNET_OK;
351 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
@ GNUNET_OK
Definition: gnunet_common.h:99
@ GNUNET_NO
Definition: gnunet_common.h:98
void GNUNET_MQ_inject_message(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *mh)
Call the message message handler that was registered for the type of the given message in the given m...
Definition: mq.c:186

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_MQ_inject_message(), GNUNET_NO, GNUNET_OK, GNUNET_YES, ClientState::in_destroy, LOG, ClientState::mq, msg, ClientState::service_name, GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

Referenced by GNUNET_CLIENT_connect(), and reconnect().

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

◆ cancel_aps()

static void cancel_aps ( struct ClientState cstate)
static

Cancel all remaining connect attempts.

Parameters
cstatehandle of the client state to process

Definition at line 360 of file client.c.

361 {
362  struct AddressProbe *pos;
363 
364  while (NULL != (pos = cstate->ap_head))
365  {
370  cstate->ap_tail,
371  pos);
372  GNUNET_free (pos);
373  }
374 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_free(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957
During connect, we try multiple possible IP addresses to find out which one might work.
struct GNUNET_SCHEDULER_Task * task
Task waiting for the connection to finish connecting.
struct GNUNET_NETWORK_Handle * sock
Underlying OS's socket.
struct ClientState * cstate
Connection for which we are probing.
Definition: client.c:83

References ClientState::ap_head, ClientState::ap_tail, AddressProbe::cstate, GNUNET_break, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_NETWORK_socket_close(), GNUNET_OK, GNUNET_SCHEDULER_cancel(), AddressProbe::sock, and AddressProbe::task.

Referenced by connect_probe_continuation(), and connection_client_destroy_impl().

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

◆ connection_client_destroy_impl()

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

Implement the destruction of a message queue.

Implementations must not free mq, but should take care of impl_state.

Parameters
mqthe message queue to destroy
impl_stateour struct ClientState

Definition at line 385 of file client.c.

387 {
388  struct ClientState *cstate = impl_state;
389 
390  (void) mq;
391  if (NULL != cstate->dns_active)
392  {
394  cstate->dns_active = NULL;
395  }
396  if (NULL != cstate->send_task)
397  {
399  cstate->send_task = NULL;
400  }
401  if (NULL != cstate->retry_task)
402  {
404  cstate->retry_task = NULL;
405  }
406  if (GNUNET_SYSERR == cstate->in_destroy)
407  {
408  /* defer destruction */
409  cstate->in_destroy = GNUNET_YES;
410  cstate->mq = NULL;
411  return;
412  }
413  if (NULL != cstate->recv_task)
414  {
416  cstate->recv_task = NULL;
417  }
418  if (NULL != cstate->sock)
419  {
421  "destroying socket: %p\n",
422  cstate->sock);
424  }
425  cancel_aps (cstate);
426  GNUNET_free (cstate->service_name);
427  GNUNET_free (cstate->hostname);
428  GNUNET_MST_destroy (cstate->mst);
429  GNUNET_free (cstate);
430 }
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
static void cancel_aps(struct ClientState *cstate)
Cancel all remaining connect attempts.
Definition: client.c:360
@ GNUNET_SYSERR
Definition: gnunet_common.h:97
void GNUNET_RESOLVER_request_cancel(struct GNUNET_RESOLVER_RequestHandle *rh)
Cancel a request that is still pending with the resolver.
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:418
struct GNUNET_MessageStreamTokenizer * mst
Tokenizer for inbound messages.
Definition: client.c:162

References cancel_aps(), ClientState::dns_active, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_MST_destroy(), GNUNET_NETWORK_socket_close(), GNUNET_RESOLVER_request_cancel(), GNUNET_SCHEDULER_cancel(), GNUNET_SYSERR, GNUNET_YES, ClientState::hostname, ClientState::in_destroy, LOG, mq, ClientState::mq, ClientState::mst, ClientState::recv_task, ClientState::retry_task, ClientState::send_task, ClientState::service_name, and ClientState::sock.

Referenced by GNUNET_CLIENT_connect(), and receive_ready().

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

◆ receive_ready()

static void receive_ready ( void *  cls)
static

This function is called once we have data ready to read.

Parameters
clsstruct ClientState with connection to read from

Definition at line 439 of file client.c.

440 {
441  struct ClientState *cstate = cls;
442  int ret;
443 
444  cstate->recv_task = NULL;
445  cstate->in_destroy = GNUNET_SYSERR;
446  ret = GNUNET_MST_read (cstate->mst,
447  cstate->sock,
448  GNUNET_NO,
449  GNUNET_NO);
450  if (GNUNET_SYSERR == ret)
451  {
452  if (NULL != cstate->mq)
453  GNUNET_MQ_inject_error (cstate->mq,
455  if (GNUNET_YES == cstate->in_destroy)
457  cstate);
458  return;
459  }
460  if (GNUNET_YES == cstate->in_destroy)
461  {
463  cstate);
464  return;
465  }
466  cstate->in_destroy = GNUNET_NO;
467  cstate->recv_task
469  cstate->sock,
470  &receive_ready,
471  cstate);
472 }
static void receive_ready(void *cls)
This function is called once we have data ready to read.
Definition: client.c:439
static void connection_client_destroy_impl(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implement the destruction of a message queue.
Definition: client.c:385
@ GNUNET_MQ_ERROR_READ
Failed to read message from the network.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1502
int GNUNET_MST_read(struct GNUNET_MessageStreamTokenizer *mst, struct GNUNET_NETWORK_Handle *sock, int purge, int one_shot)
Add incoming data to the receive buffer and call the callback for all complete messages.
Definition: mst.c:352

References connection_client_destroy_impl(), GNUNET_MQ_ERROR_READ, GNUNET_MQ_inject_error(), GNUNET_MST_read(), GNUNET_NO, GNUNET_SCHEDULER_add_read_net(), GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, ClientState::in_destroy, ClientState::mq, ClientState::mst, ClientState::recv_task, ret, and ClientState::sock.

Referenced by connect_success_continuation().

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

◆ connect_success_continuation()

static void connect_success_continuation ( struct ClientState cstate)
static

We've succeeded in establishing a connection.

Parameters
cstatethe connection we tried to establish

Definition at line 481 of file client.c.

482 {
483  GNUNET_assert (NULL == cstate->recv_task);
484  cstate->recv_task
486  cstate->sock,
487  &receive_ready,
488  cstate);
489  if (NULL != cstate->msg)
490  {
491  GNUNET_assert (NULL == cstate->send_task);
492  cstate->send_task
494  cstate->sock,
496  cstate);
497  }
498 }

References GNUNET_assert, GNUNET_SCHEDULER_add_read_net(), GNUNET_SCHEDULER_add_write_net(), GNUNET_TIME_UNIT_FOREVER_REL, ClientState::msg, receive_ready(), ClientState::recv_task, ClientState::send_task, ClientState::sock, and transmit_ready().

Referenced by connect_probe_continuation(), and start_connect().

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

◆ try_unixpath()

static struct GNUNET_NETWORK_Handle* try_unixpath ( const char *  service_name,
const struct GNUNET_CONFIGURATION_Handle cfg 
)
static

Try connecting to the server using UNIX domain sockets.

Parameters
service_namename of service to connect to
cfgconfiguration to use
Returns
NULL on error, socket connected to UNIX otherwise

Definition at line 509 of file client.c.

511 {
512 #if AF_UNIX
513  struct GNUNET_NETWORK_Handle *sock;
514  char *unixpath;
515  struct sockaddr_un s_un;
516 
517  unixpath = NULL;
518  if ((GNUNET_OK ==
520  service_name,
521  "UNIXPATH",
522  &unixpath)) &&
523  (0 < strlen (unixpath)))
524  {
525  /* We have a non-NULL unixpath, need to validate it */
526  if (strlen (unixpath) >= sizeof(s_un.sun_path))
527  {
529  _ ("UNIXPATH `%s' too long, maximum length is %llu\n"),
530  unixpath,
531  (unsigned long long) sizeof(s_un.sun_path));
532  unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
534  _ ("Using `%s' instead\n"),
535  unixpath);
536  if (NULL == unixpath)
537  return NULL;
538  }
539  memset (&s_un,
540  0,
541  sizeof(s_un));
542  s_un.sun_family = AF_UNIX;
543  GNUNET_strlcpy (s_un.sun_path,
544  unixpath,
545  sizeof(s_un.sun_path));
546 #if HAVE_SOCKADDR_UN_SUN_LEN
547  s_un.sun_len = (u_char) sizeof(struct sockaddr_un);
548 #endif
549  sock = GNUNET_NETWORK_socket_create (AF_UNIX,
550  SOCK_STREAM,
551  0);
552  if ((NULL != sock) &&
553  ((GNUNET_OK ==
555  (struct sockaddr *) &s_un,
556  sizeof(s_un))) ||
557  (EINPROGRESS == errno)))
558  {
560  "Successfully connected to unixpath `%s'!\n",
561  unixpath);
562  GNUNET_free (unixpath);
563  return sock;
564  }
565  if (NULL != sock)
567  }
568  GNUNET_free (unixpath);
569 #endif
570  return NULL;
571 }
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static char * service_name
Option -s: service name (hash to get service descriptor)
Definition: gnunet-vpn.c:51
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
@ GNUNET_ERROR_TYPE_INFO
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_connect(const struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Connect a socket to some remote address.
Definition: network.c:606
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:855
char * GNUNET_NETWORK_shorten_unixpath(char *unixpath)
Given a unixpath that is too long (larger than UNIX_PATH_MAX), shorten it to an acceptable length whi...
Definition: network.c:143
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:139
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
handle to a socket
Definition: network.c:53

References _, cfg, GNUNET_CONFIGURATION_get_value_filename(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_NETWORK_shorten_unixpath(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_connect(), GNUNET_NETWORK_socket_create(), GNUNET_OK, GNUNET_strlcpy(), LOG, and service_name.

Referenced by start_connect().

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

◆ connect_probe_continuation()

static void connect_probe_continuation ( void *  cls)
static

Scheduler let us know that we're either ready to write on the socket OR connect timed out.

Do the right thing.

Parameters
clsthe struct AddressProbe * with the address that we are probing

Definition at line 581 of file client.c.

582 {
583  struct AddressProbe *ap = cls;
584  struct ClientState *cstate = ap->cstate;
585  const struct GNUNET_SCHEDULER_TaskContext *tc;
586  int error;
587  socklen_t len;
588 
589  ap->task = NULL;
590  GNUNET_assert (NULL != ap->sock);
592  cstate->ap_tail,
593  ap);
594  len = sizeof(error);
595  error = 0;
598  (GNUNET_OK !=
600  SOL_SOCKET,
601  SO_ERROR,
602  &error,
603  &len)) ||
604  (0 != error))
605  {
608  GNUNET_free (ap);
609  if ((NULL == cstate->ap_head) &&
610  // (NULL == cstate->proxy_handshake) &&
611  (NULL == cstate->dns_active))
612  connect_fail_continuation (cstate);
613  return;
614  }
616  "Connection to `%s' succeeded!\n",
617  cstate->service_name);
618  /* trigger jobs that waited for the connection */
619  GNUNET_assert (NULL == cstate->sock);
620  cstate->sock = ap->sock;
621  GNUNET_free (ap);
622  cancel_aps (cstate);
624 }
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_getsockopt(const struct GNUNET_NETWORK_Handle *desc, int level, int optname, void *optval, socklen_t *optlen)
Get socket options.
Definition: network.c:631
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition: scheduler.c:737
@ GNUNET_SCHEDULER_REASON_WRITE_READY
The writing socket is ready.
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:423
Context information passed to each scheduler task.
enum GNUNET_SCHEDULER_Reason reason
Reason why the task is run now.

References ClientState::ap_head, ClientState::ap_tail, cancel_aps(), connect_fail_continuation(), connect_success_continuation(), AddressProbe::cstate, ClientState::dns_active, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_getsockopt(), GNUNET_OK, GNUNET_SCHEDULER_get_task_context(), GNUNET_SCHEDULER_REASON_WRITE_READY, len, LOG, GNUNET_SCHEDULER_TaskContext::reason, ClientState::service_name, AddressProbe::sock, ClientState::sock, AddressProbe::task, and tc.

Referenced by try_connect_using_address().

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

◆ try_connect_using_address()

static void try_connect_using_address ( void *  cls,
const struct sockaddr *  addr,
socklen_t  addrlen 
)
static

Try to establish a connection given the specified address.

This function is called by the resolver once we have a DNS reply.

Parameters
clsour struct ClientState *
addraddress to try, NULL for "last call"
addrlenlength of addr

Definition at line 636 of file client.c.

639 {
640  struct ClientState *cstate = cls;
641  struct AddressProbe *ap;
642 
643  if (NULL == addr)
644  {
645  cstate->dns_active = NULL;
646  if ((NULL == cstate->ap_head) &&
647  // (NULL == cstate->proxy_handshake) &&
648  (NULL == cstate->sock))
650  return;
651  }
652  if (NULL != cstate->sock)
653  return; /* already connected */
654  /* try to connect */
656  "Trying to connect using address `%s:%u'\n",
657  GNUNET_a2s (addr,
658  addrlen),
659  (unsigned int) cstate->port);
660  ap = GNUNET_malloc (sizeof(struct AddressProbe) + addrlen);
661  ap->addr = (const struct sockaddr *) &ap[1];
662  GNUNET_memcpy (&ap[1],
663  addr,
664  addrlen);
665  ap->addrlen = addrlen;
666  ap->cstate = cstate;
667 
668  switch (ap->addr->sa_family)
669  {
670  case AF_INET:
671  ((struct sockaddr_in *) ap->addr)->sin_port = htons (cstate->port);
672  break;
673 
674  case AF_INET6:
675  ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (cstate->port);
676  break;
677 
678  default:
679  GNUNET_break (0);
680  GNUNET_free (ap);
681  return; /* not supported by us */
682  }
683  ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family,
684  SOCK_STREAM,
685  0);
686  if (NULL == ap->sock)
687  {
688  GNUNET_free (ap);
689  return; /* not supported by OS */
690  }
691  if ((GNUNET_OK !=
693  ap->addr,
694  ap->addrlen)) &&
695  (EINPROGRESS != errno))
696  {
697  /* maybe refused / unsupported address, try next */
699  "connect");
702  GNUNET_free (ap);
703  return;
704  }
706  cstate->ap_tail,
707  ap);
709  ap->sock,
711  ap);
712 }
static void connect_probe_continuation(void *cls)
Scheduler let us know that we're either ready to write on the socket OR connect timed out.
Definition: client.c:581
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages).
#define GNUNET_malloc(size)
Wrapper around malloc.
socklen_t addrlen
Length of addr.
const struct sockaddr * addr
The address; do not free (allocated at the end of this struct).

References AddressProbe::addr, AddressProbe::addrlen, ClientState::ap_head, ClientState::ap_tail, connect_fail_continuation(), connect_probe_continuation(), CONNECT_RETRY_TIMEOUT, AddressProbe::cstate, ClientState::dns_active, GNUNET_a2s(), GNUNET_break, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_log_strerror, GNUNET_malloc, GNUNET_memcpy, GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_connect(), GNUNET_NETWORK_socket_create(), GNUNET_OK, GNUNET_SCHEDULER_add_write_net(), LOG, ClientState::port, AddressProbe::sock, ClientState::sock, and AddressProbe::task.

Referenced by start_connect().

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

◆ test_service_configuration()

static int test_service_configuration ( const char *  service_name,
const struct GNUNET_CONFIGURATION_Handle cfg 
)
static

Test whether the configuration has proper values for connection (UNIXPATH || (PORT && HOSTNAME)).

Parameters
service_namename of service to connect to
cfgconfiguration to use
Returns
GNUNET_OK if the configuration is valid, GNUNET_SYSERR if not

Definition at line 724 of file client.c.

726 {
727  int ret = GNUNET_SYSERR;
728  char *hostname = NULL;
729  unsigned long long port;
730 
731 #if AF_UNIX
732  char *unixpath = NULL;
733 
734  if ((GNUNET_OK ==
736  service_name,
737  "UNIXPATH",
738  &unixpath)) &&
739  (0 < strlen (unixpath)))
740  ret = GNUNET_OK;
741  else if ((GNUNET_OK ==
743  service_name,
744  "UNIXPATH")))
745  {
747  service_name,
748  "UNIXPATH",
749  _ ("not a valid filename"));
750  GNUNET_free (unixpath);
751  return GNUNET_SYSERR; /* UNIXPATH specified but invalid! */
752  }
753  GNUNET_free (unixpath);
754 #endif
755 
756  if ((GNUNET_YES ==
758  service_name,
759  "PORT")) &&
760  (GNUNET_OK ==
762  service_name,
763  "PORT",
764  &port)) &&
765  (port <= 65535) &&
766  (0 != port) &&
767  (GNUNET_OK ==
769  service_name,
770  "HOSTNAME",
771  &hostname)) &&
772  (0 != strlen (hostname)))
773  ret = GNUNET_OK;
775  return ret;
776 }
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static char * hostname
Our hostname; we give this to all the peers we start.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_have_value(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Test if we have a value for a particular option.
void GNUNET_log_config_invalid(enum GNUNET_ErrorType kind, const char *section, const char *option, const char *required)
Log error message about invalid configuration option value.
@ GNUNET_ERROR_TYPE_ERROR

References _, cfg, GNUNET_CONFIGURATION_get_value_filename(), GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_have_value(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log_config_invalid(), GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, hostname, port, ret, and service_name.

Referenced by GNUNET_CLIENT_connect().

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

◆ connection_client_send_impl()

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

Implements the transmission functionality of a message queue.

Parameters
mqthe message queue
msgthe message to send
impl_stateour struct ClientState

Definition at line 839 of file client.c.

842 {
843  struct ClientState *cstate = impl_state;
844 
845  (void) mq;
846  /* only one message at a time allowed */
847  GNUNET_assert (NULL == cstate->msg);
848  GNUNET_assert (NULL == cstate->send_task);
849  cstate->msg = msg;
850  cstate->msg_off = 0;
851  if (NULL == cstate->sock)
852  {
854  "message of type %u waiting for socket\n",
855  ntohs (msg->type));
856  return; /* still waiting for connection */
857  }
858  cstate->send_task
860  cstate);
861 }
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1281

References GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_SCHEDULER_add_now(), LOG, mq, msg, ClientState::msg, ClientState::msg_off, ClientState::send_task, ClientState::sock, transmit_ready(), and GNUNET_MessageHeader::type.

Referenced by GNUNET_CLIENT_connect().

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

◆ connection_client_cancel_impl()

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

Cancel the currently sent message.

Parameters
mqmessage queue
impl_stateour struct ClientState

Definition at line 871 of file client.c.

873 {
874  struct ClientState *cstate = impl_state;
875 
876  (void) mq;
877  GNUNET_assert (NULL != cstate->msg);
878  GNUNET_assert (0 == cstate->msg_off);
879  cstate->msg = NULL;
880  if (NULL != cstate->send_task)
881  {
883  cstate->send_task = NULL;
884  }
885 }

References GNUNET_assert, GNUNET_SCHEDULER_cancel(), mq, ClientState::msg, ClientState::msg_off, and ClientState::send_task.

Referenced by GNUNET_CLIENT_connect().

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