GNUnet  0.10.x
client.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2001-2016 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19 */
20 
29 #include "platform.h"
30 #include "gnunet_protocols.h"
31 #include "gnunet_util_lib.h"
33 #include "gnunet_socks.h"
34 
35 
36 #define LOG(kind,...) GNUNET_log_from (kind, "util-client",__VA_ARGS__)
37 
44 #define CONNECT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
45 
46 
47 
51 struct ClientState;
52 
53 
58 struct AddressProbe
59 {
60 
64  struct AddressProbe *next;
65 
69  struct AddressProbe *prev;
70 
74  const struct sockaddr *addr;
75 
80 
85 
89  socklen_t addrlen;
90 
95 };
96 
97 
101 struct ClientState
102 {
103 
108 
113 
118 
124 
130 
135 
139  char *hostname;
140 
144  const struct GNUNET_MessageHeader *msg;
145 
150 
155 
160 
165 
169  struct GNUNET_MQ_Handle *mq;
170 
174  struct GNUNET_TIME_Absolute receive_timeout;
175 
180  struct GNUNET_TIME_Relative back_off;
181 
185  unsigned long long port;
186 
190  size_t msg_off;
191 
195  unsigned int attempts;
196 
203 
204 };
205 
206 
212 static void
213 start_connect (void *cls);
214 
215 
222 static void
224 {
225  GNUNET_break (NULL == cstate->ap_head);
226  GNUNET_break (NULL == cstate->ap_tail);
227  GNUNET_break (NULL == cstate->dns_active);
228  GNUNET_break (NULL == cstate->sock);
229  GNUNET_assert (NULL == cstate->send_task);
230  GNUNET_assert (NULL == cstate->recv_task);
231  // GNUNET_assert (NULL == cstate->proxy_handshake);
232 
233  cstate->back_off = GNUNET_TIME_STD_BACKOFF (cstate->back_off);
235  "Failed to establish connection to `%s', no further addresses to try, will try again in %s.\n",
236  cstate->service_name,
238  GNUNET_YES));
239  cstate->retry_task
241  &start_connect,
242  cstate);
243 }
244 
245 
251 static void
252 transmit_ready (void *cls)
253 {
254  struct ClientState *cstate = cls;
255  ssize_t ret;
256  size_t len;
257  const char *pos;
258  int notify_in_flight;
259 
260  cstate->send_task = NULL;
261  if (GNUNET_YES == cstate->in_destroy)
262  return;
263  pos = (const char *) cstate->msg;
264  len = ntohs (cstate->msg->size);
265  GNUNET_assert (cstate->msg_off < len);
267  "message of type %u trying to send with socket %p (MQ: %p\n",
268  ntohs(cstate->msg->type),
269  cstate->sock,
270  cstate->mq);
271 
272  RETRY:
273  ret = GNUNET_NETWORK_socket_send (cstate->sock,
274  &pos[cstate->msg_off],
275  len - cstate->msg_off);
276  if (-1 == ret)
277  {
279  "Error during sending message of type %u\n",
280  ntohs(cstate->msg->type));
281  if (EINTR == errno){
283  "Retrying message of type %u\n",
284  ntohs(cstate->msg->type));
285  goto RETRY;
286  }
287  GNUNET_MQ_inject_error (cstate->mq,
289  return;
290  }
291  notify_in_flight = (0 == cstate->msg_off);
292  cstate->msg_off += ret;
293  if (cstate->msg_off < len)
294  {
296  "rescheduling message of type %u\n",
297  ntohs(cstate->msg->type));
298  cstate->send_task
300  cstate->sock,
302  cstate);
303  if (notify_in_flight)
305  return;
306  }
308  "sending message of type %u successful\n",
309  ntohs(cstate->msg->type));
310  cstate->msg = NULL;
312 }
313 
314 
325 static int
326 recv_message (void *cls,
327  const struct GNUNET_MessageHeader *msg)
328 {
329  struct ClientState *cstate = cls;
330 
331  if (GNUNET_YES == cstate->in_destroy)
332  return GNUNET_NO;
334  "Received message of type %u and size %u from %s\n",
335  ntohs (msg->type),
336  ntohs (msg->size),
337  cstate->service_name);
338  GNUNET_MQ_inject_message (cstate->mq,
339  msg);
340  if (GNUNET_YES == cstate->in_destroy)
341  return GNUNET_NO;
342  return GNUNET_OK;
343 }
344 
345 
351 static void
353 {
354  struct AddressProbe *pos;
355 
356  while (NULL != (pos = cstate->ap_head))
357  {
362  cstate->ap_tail,
363  pos);
364  GNUNET_free (pos);
365  }
366 }
367 
368 
376 static void
378  void *impl_state)
379 {
380  struct ClientState *cstate = impl_state;
381 
382  (void) mq;
383  if (NULL != cstate->dns_active)
384  {
386  cstate->dns_active = NULL;
387  }
388  if (NULL != cstate->send_task)
389  {
391  cstate->send_task = NULL;
392  }
393  if (NULL != cstate->retry_task)
394  {
396  cstate->retry_task = NULL;
397  }
398  if (GNUNET_SYSERR == cstate->in_destroy)
399  {
400  /* defer destruction */
401  cstate->in_destroy = GNUNET_YES;
402  cstate->mq = NULL;
403  return;
404  }
405  if (NULL != cstate->recv_task)
406  {
408  cstate->recv_task = NULL;
409  }
410  if (NULL != cstate->sock)
411  {
413  "destroying socket: %p\n",
414  cstate->sock);
416  }
417  cancel_aps (cstate);
418  GNUNET_free (cstate->service_name);
419  GNUNET_free_non_null (cstate->hostname);
420  GNUNET_MST_destroy (cstate->mst);
421  GNUNET_free (cstate);
422 }
423 
424 
430 static void
431 receive_ready (void *cls)
432 {
433  struct ClientState *cstate = cls;
434  int ret;
435 
436  cstate->recv_task = NULL;
437  cstate->in_destroy = GNUNET_SYSERR;
438  ret = GNUNET_MST_read (cstate->mst,
439  cstate->sock,
440  GNUNET_NO,
441  GNUNET_NO);
442  if (GNUNET_SYSERR == ret)
443  {
444  if (NULL != cstate->mq)
445  GNUNET_MQ_inject_error (cstate->mq,
447  if (GNUNET_YES == cstate->in_destroy)
449  cstate);
450  return;
451  }
452  if (GNUNET_YES == cstate->in_destroy)
453  {
455  cstate);
456  return;
457  }
458  cstate->in_destroy = GNUNET_NO;
459  cstate->recv_task
461  cstate->sock,
462  &receive_ready,
463  cstate);
464 }
465 
466 
472 static void
474 {
475  GNUNET_assert (NULL == cstate->recv_task);
476  cstate->recv_task
478  cstate->sock,
479  &receive_ready,
480  cstate);
481  if (NULL != cstate->msg)
482  {
483  GNUNET_assert (NULL == cstate->send_task);
484  cstate->send_task
486  cstate->sock,
488  cstate);
489  }
490 }
491 
492 
500 static struct GNUNET_NETWORK_Handle *
502  const struct GNUNET_CONFIGURATION_Handle *cfg)
503 {
504 #if AF_UNIX
505  struct GNUNET_NETWORK_Handle *sock;
506  char *unixpath;
507  struct sockaddr_un s_un;
508 
509  unixpath = NULL;
510  if ((GNUNET_OK ==
512  service_name,
513  "UNIXPATH",
514  &unixpath)) &&
515  (0 < strlen (unixpath)))
516  {
517  /* We have a non-NULL unixpath, need to validate it */
518  if (strlen (unixpath) >= sizeof (s_un.sun_path))
519  {
521  _("UNIXPATH `%s' too long, maximum length is %llu\n"),
522  unixpath,
523  (unsigned long long) sizeof (s_un.sun_path));
524  unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
526  _("Using `%s' instead\n"),
527  unixpath);
528  if (NULL == unixpath)
529  return NULL;
530  }
531  memset (&s_un,
532  0,
533  sizeof (s_un));
534  s_un.sun_family = AF_UNIX;
535  GNUNET_strlcpy (s_un.sun_path,
536  unixpath,
537  sizeof (s_un.sun_path));
538 #ifdef LINUX
539  {
540  int abstract;
541 
542  abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
543  "TESTING",
544  "USE_ABSTRACT_SOCKETS");
545  if (GNUNET_YES == abstract)
546  s_un.sun_path[0] = '\0';
547  }
548 #endif
549 #if HAVE_SOCKADDR_UN_SUN_LEN
550  s_un.sun_len = (u_char) sizeof (struct sockaddr_un);
551 #endif
552  sock = GNUNET_NETWORK_socket_create (AF_UNIX,
553  SOCK_STREAM,
554  0);
555  if ( (NULL != sock) &&
556  ( (GNUNET_OK ==
558  (struct sockaddr *) &s_un,
559  sizeof (s_un))) ||
560  (EINPROGRESS == errno) ) )
561  {
563  "Successfully connected to unixpath `%s'!\n",
564  unixpath);
565  GNUNET_free (unixpath);
566  return sock;
567  }
568  if (NULL != sock)
570  }
571  GNUNET_free_non_null (unixpath);
572 #endif
573  return NULL;
574 }
575 
576 
583 static void
585 {
586  struct AddressProbe *ap = cls;
587  struct ClientState *cstate = ap->cstate;
588  const struct GNUNET_SCHEDULER_TaskContext *tc;
589  int error;
590  socklen_t len;
591 
592  ap->task = NULL;
593  GNUNET_assert (NULL != ap->sock);
595  cstate->ap_tail,
596  ap);
597  len = sizeof (error);
598  error = 0;
600  if ( (0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ||
601  (GNUNET_OK !=
603  SOL_SOCKET,
604  SO_ERROR,
605  &error,
606  &len)) ||
607  (0 != error) )
608  {
611  GNUNET_free (ap);
612  if ( (NULL == cstate->ap_head) &&
613  // (NULL == cstate->proxy_handshake) &&
614  (NULL == cstate->dns_active) )
615  connect_fail_continuation (cstate);
616  return;
617  }
619  "Connection to `%s' succeeded!\n",
620  cstate->service_name);
621  /* trigger jobs that waited for the connection */
622  GNUNET_assert (NULL == cstate->sock);
623  cstate->sock = ap->sock;
624  GNUNET_free (ap);
625  cancel_aps (cstate);
627 }
628 
629 
638 static void
640  const struct sockaddr *addr,
641  socklen_t addrlen)
642 {
643  struct ClientState *cstate = cls;
644  struct AddressProbe *ap;
645 
646  if (NULL == addr)
647  {
648  cstate->dns_active = NULL;
649  if ( (NULL == cstate->ap_head) &&
650  // (NULL == cstate->proxy_handshake) &&
651  (NULL == cstate->sock) )
652  connect_fail_continuation (cstate);
653  return;
654  }
655  if (NULL != cstate->sock)
656  return; /* already connected */
657  /* try to connect */
659  "Trying to connect using address `%s:%u'\n",
660  GNUNET_a2s (addr,
661  addrlen),
662  cstate->port);
663  ap = GNUNET_malloc (sizeof (struct AddressProbe) + addrlen);
664  ap->addr = (const struct sockaddr *) &ap[1];
665  GNUNET_memcpy (&ap[1],
666  addr,
667  addrlen);
668  ap->addrlen = addrlen;
669  ap->cstate = cstate;
670 
671  switch (ap->addr->sa_family)
672  {
673  case AF_INET:
674  ((struct sockaddr_in *) ap->addr)->sin_port = htons (cstate->port);
675  break;
676  case AF_INET6:
677  ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (cstate->port);
678  break;
679  default:
680  GNUNET_break (0);
681  GNUNET_free (ap);
682  return; /* not supported by us */
683  }
684  ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family,
685  SOCK_STREAM,
686  0);
687  if (NULL == ap->sock)
688  {
689  GNUNET_free (ap);
690  return; /* not supported by OS */
691  }
692  if ( (GNUNET_OK !=
694  ap->addr,
695  ap->addrlen)) &&
696  (EINPROGRESS != errno) )
697  {
698  /* maybe refused / unsupported address, try next */
700  "connect");
703  GNUNET_free (ap);
704  return;
705  }
707  cstate->ap_tail,
708  ap);
710  ap->sock,
712  ap);
713 }
714 
715 
724 static int
726  const struct GNUNET_CONFIGURATION_Handle *cfg)
727 {
728  int ret = GNUNET_SYSERR;
729  char *hostname = NULL;
730  unsigned long long port;
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  return GNUNET_SYSERR; /* UNIXPATH specified but invalid! */
751  }
752  GNUNET_free_non_null (unixpath);
753 #endif
754 
755  if ( (GNUNET_YES ==
757  service_name,
758  "PORT")) &&
759  (GNUNET_OK ==
761  service_name,
762  "PORT",
763  &port)) &&
764  (port <= 65535) &&
765  (0 != port) &&
766  (GNUNET_OK ==
768  service_name,
769  "HOSTNAME",
770  &hostname)) &&
771  (0 != strlen (hostname)) )
772  ret = GNUNET_OK;
773  GNUNET_free_non_null (hostname);
774  return ret;
775 }
776 
777 
783 static void
784 start_connect (void *cls)
785 {
786  struct ClientState *cstate = cls;
787 
788  cstate->retry_task = NULL;
789 #if 0
790  /* Never use a local source if a proxy is configured */
791  if (GNUNET_YES ==
793  cstate->cfg))
794  {
795  socks_connect (cstate);
796  return;
797  }
798 #endif
799 
800  if ( (0 == (cstate->attempts++ % 2)) ||
801  (0 == cstate->port) ||
802  (NULL == cstate->hostname) )
803  {
804  /* on even rounds, try UNIX first, or always
805  if we do not have a DNS name and TCP port. */
806  cstate->sock = try_unixpath (cstate->service_name,
807  cstate->cfg);
808  if (NULL != cstate->sock)
809  {
811  return;
812  }
813  }
814  if ( (NULL == cstate->hostname) ||
815  (0 == cstate->port) )
816  {
817  /* All options failed. Boo! */
818  connect_fail_continuation (cstate);
819  return;
820  }
821  cstate->dns_active
822  = GNUNET_RESOLVER_ip_get (cstate->hostname,
823  AF_UNSPEC,
826  cstate);
827 }
828 
829 
837 static void
839  const struct GNUNET_MessageHeader *msg,
840  void *impl_state)
841 {
842  struct ClientState *cstate = impl_state;
843 
844  (void) mq;
845  /* only one message at a time allowed */
846  GNUNET_assert (NULL == cstate->msg);
847  GNUNET_assert (NULL == cstate->send_task);
848  cstate->msg = msg;
849  cstate->msg_off = 0;
850  if (NULL == cstate->sock)
851  {
853  "message of type %u waiting for socket\n",
854  ntohs(msg->type));
855  return; /* still waiting for connection */
856  }
857  cstate->send_task
859  cstate->sock,
861  cstate);
862 }
863 
864 
871 static void
873  void *impl_state)
874 {
875  struct ClientState *cstate = impl_state;
876 
877  (void) mq;
878  GNUNET_assert (NULL != cstate->msg);
879  GNUNET_assert (0 == cstate->msg_off);
880  cstate->msg = NULL;
881  if (NULL != cstate->send_task)
882  {
884  cstate->send_task = NULL;
885  }
886 }
887 
888 
900 struct GNUNET_MQ_Handle *
902  const char *service_name,
903  const struct GNUNET_MQ_MessageHandler *handlers,
905  void *error_handler_cls)
906 {
907  struct ClientState *cstate;
908 
909  if (GNUNET_OK !=
910  test_service_configuration (service_name,
911  cfg))
912  return NULL;
913  cstate = GNUNET_new (struct ClientState);
914  cstate->service_name = GNUNET_strdup (service_name);
915  cstate->cfg = cfg;
917  cstate);
918  cstate->mst = GNUNET_MST_create (&recv_message,
919  cstate);
920  if (GNUNET_YES ==
922  service_name,
923  "PORT"))
924  {
925  if (! ( (GNUNET_OK !=
927  service_name,
928  "PORT",
929  &cstate->port)) ||
930  (cstate->port > 65535) ||
931  (GNUNET_OK !=
933  service_name,
934  "HOSTNAME",
935  &cstate->hostname)) ) &&
936  (0 == strlen (cstate->hostname)) )
937  {
938  GNUNET_free (cstate->hostname);
939  cstate->hostname = NULL;
941  _("Need a non-empty hostname for service `%s'.\n"),
942  service_name);
943  }
944  }
948  cstate,
949  handlers,
950  error_handler,
951  error_handler_cls);
952  return cstate->mq;
953 }
954 
955 /* end of client.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct GNUNET_RESOLVER_RequestHandle * dns_active
Handle to a pending DNS lookup request, NULL if DNS is finished.
Definition: client.c:112
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition: scheduler.c:746
static void error_handler(void *cls, enum GNUNET_MQ_Error error)
We encountered an error handling the MQ to the ATS service.
const struct sockaddr * addr
The address; do not free (allocated at the end of this struct).
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
State we keep per client.
void GNUNET_RESOLVER_request_cancel(struct GNUNET_RESOLVER_RequestHandle *rh)
Cancel a request that is still pending with the resolver.
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.
struct AddressProbe * prev
This is a doubly-linked list.
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
#define RETRY
Return code we give on &#39;send&#39; if we failed to send right now but it makes sense to retry later...
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
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_MQ_Handle * GNUNET_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.
Definition: client.c:901
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
Context information passed to each scheduler task.
void(* GNUNET_MQ_ErrorHandler)(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
#define LOG(kind,...)
Definition: client.c:36
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:417
int 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:763
static void cancel_aps(struct ClientState *cstate)
Cancel all remaining connect attempts.
Definition: client.c:352
static void connection_client_cancel_impl(struct GNUNET_MQ_Handle *mq, void *impl_state)
Cancel the currently sent message.
Definition: client.c:872
static void connection_client_destroy_impl(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implement the destruction of a message queue.
Definition: client.c:377
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
int in_destroy
Are we supposed to die? GNUNET_SYSERR if destruction must be deferred, GNUNET_NO by default...
Definition: client.c:202
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: client.c:117
#define GNUNET_NO
Definition: gnunet_common.h:81
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:927
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
static void transmit_ready(void *cls)
We are ready to send a message to the service.
Definition: client.c:252
#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.
struct GNUNET_SCHEDULER_Task * task
Task waiting for the connection to finish connecting.
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.
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
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
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:501
enum GNUNET_SCHEDULER_Reason reason
Reason why the task is run now.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
char * service_name
Name of the service we interact with.
Definition: client.c:134
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
#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
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
int 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:731
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
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
#define GNUNET_memcpy(dst, src, n)
struct GNUNET_SCHEDULER_Task * recv_task
Task for sending messages to the service.
Definition: client.c:159
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:413
struct GNUNET_SCHEDULER_Task * send_task
Task for sending messages to the service.
Definition: client.c:154
static int recv_message(void *cls, const struct GNUNET_MessageHeader *msg)
We have received a full message, pass to the MQ dispatcher.
Definition: client.c:326
static void connect_success_continuation(struct ClientState *cstate)
We&#39;ve succeeded in establishing a connection.
Definition: client.c:473
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:1273
FIXME: document!
struct AddressProbe * ap_tail
Linked list of sockets we are currently trying out (during connect).
Definition: client.c:129
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 void start_connect(void *cls)
Try to connect to the service.
Definition: client.c:784
Handle to a message stream tokenizer.
Definition: mst.c:43
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
static char * service_name
Option -s: service name (hash to get service descriptor)
Definition: gnunet-vpn.c:51
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:87
Failed to read message from the network.
#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)...
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
static void connect_fail_continuation(struct ClientState *cstate)
We&#39;ve failed for good to establish a connection (timeout or no more addresses to try).
Definition: client.c:223
const struct GNUNET_MessageHeader * msg
Next message to transmit to the service.
Definition: client.c:144
socklen_t addrlen
Lenth of addr.
Message handler for a specific message type.
unsigned int attempts
How often have we tried to connect?
Definition: client.c:195
struct GNUNET_NETWORK_Handle * sock
Underlying OS&#39;s socket.
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.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
The writing socket is ready.
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:639
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
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:575
Handle to a request given to the resolver.
Definition: resolver_api.c:100
void * error_handler_cls
Closure for the error handler.
Definition: mq.c:121
#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_MessageStreamTokenizer * mst
Tokenizer for inbound messages.
Definition: client.c:164
Handle to a message queue.
Definition: mq.c:85
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))...
Definition: client.c:725
size_t msg_off
Offset in the message where we are for transmission.
Definition: client.c:190
struct AddressProbe * next
This is a linked list.
struct AddressProbe * ap_head
Linked list of sockets we are currently trying out (during connect).
Definition: client.c:123
static void connect_probe_continuation(void *cls)
Scheduler let us know that we&#39;re either ready to write on the socket OR connect timed out...
Definition: client.c:584
unsigned long long port
TCP port (0 for disabled).
Definition: client.c:185
static char * hostname
Our hostname; we give this to all the peers we start.
static uint16_t port
Port number.
Definition: gnunet-bcd.c:79
char * hostname
Hostname, if any.
Definition: client.c:139
configuration data
Definition: configuration.c:85
#define CONNECT_RETRY_TIMEOUT
Timeout we use on TCP connect before trying another result from the DNS resolver. ...
Definition: client.c:44
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
Entry in list of pending tasks.
Definition: scheduler.c:134
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
struct GNUNET_TIME_Relative back_off
Current value for our incremental back-off (for connect re-tries).
Definition: client.c:180
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
struct GNUNET_NETWORK_Handle * sock
The connection handle, NULL if not live.
Definition: client.c:107
struct GNUNET_SCHEDULER_Task * retry_task
Task for trying to connect to the service.
Definition: client.c:149
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
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
#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
static void receive_ready(void *cls)
This function is called once we have data ready to read.
Definition: client.c:431
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.
Definition: client.c:838
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".
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
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:604
#define GNUNET_malloc(size)
Wrapper around malloc.
During connect, we try multiple possible IP addresses to find out which one might work...
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:1037
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
struct ClientState * cstate
Connection for which we are probing.
Definition: client.c:84