GNUnet  0.11.x
client.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2001-2016, 2019 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 ( \
45  GNUNET_TIME_UNIT_SECONDS, 5)
46 
47 
51 struct ClientState;
52 
53 
58 struct AddressProbe
59 {
63  struct AddressProbe *next;
64 
68  struct AddressProbe *prev;
69 
73  const struct sockaddr *addr;
74 
79 
84 
88  socklen_t addrlen;
89 
94 };
95 
96 
100 struct ClientState
101 {
106 
111 
116 
122 
128 
133 
137  char *hostname;
138 
142  const struct GNUNET_MessageHeader *msg;
143 
148 
153 
158 
163 
167  struct GNUNET_MQ_Handle *mq;
168 
172  struct GNUNET_TIME_Absolute receive_timeout;
173 
178  struct GNUNET_TIME_Relative back_off;
179 
183  unsigned long long port;
184 
188  size_t msg_off;
189 
193  unsigned int attempts;
194 
201 };
202 
203 
209 static void
210 start_connect (void *cls);
211 
212 
219 static void
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 }
241 
242 
248 static void
249 transmit_ready (void *cls)
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 trying to send with socket %p (MQ: %p\n",
265  ntohs (cstate->msg->type),
266  cstate->sock,
267  cstate->mq);
268 
269 RETRY:
270  ret = GNUNET_NETWORK_socket_send (cstate->sock,
271  &pos[cstate->msg_off],
272  len - cstate->msg_off);
273  if ( (-1 == ret) &&
274  ( (EAGAIN == errno) ||
275  (EINTR == errno) ) )
276  {
277  /* ignore */
278  ret = 0;
279  }
280  if (-1 == ret)
281  {
283  "Error during sending message of type %u: %s\n",
284  ntohs (cstate->msg->type),
285  strerror (errno));
286  if (EINTR == errno)
287  {
289  "Retrying message of type %u\n",
290  ntohs (cstate->msg->type));
291  goto RETRY;
292  }
293  GNUNET_MQ_inject_error (cstate->mq,
295  return;
296  }
297  notify_in_flight = (0 == cstate->msg_off);
298  cstate->msg_off += ret;
299  if (cstate->msg_off < len)
300  {
302  "rescheduling message of type %u\n",
303  ntohs (cstate->msg->type));
304  cstate->send_task
306  cstate->sock,
308  cstate);
309  if (notify_in_flight)
311  return;
312  }
314  "sending message of type %u successful\n",
315  ntohs (cstate->msg->type));
316  cstate->msg = NULL;
318 }
319 
320 
331 static int
332 recv_message (void *cls,
333  const struct GNUNET_MessageHeader *msg)
334 {
335  struct ClientState *cstate = cls;
336 
337  if (GNUNET_YES == cstate->in_destroy)
338  return GNUNET_NO;
340  "Received message of type %u and size %u from %s\n",
341  ntohs (msg->type),
342  ntohs (msg->size),
343  cstate->service_name);
344  GNUNET_MQ_inject_message (cstate->mq,
345  msg);
346  if (GNUNET_YES == cstate->in_destroy)
347  return GNUNET_NO;
348  return GNUNET_OK;
349 }
350 
351 
357 static void
359 {
360  struct AddressProbe *pos;
361 
362  while (NULL != (pos = cstate->ap_head))
363  {
368  cstate->ap_tail,
369  pos);
370  GNUNET_free (pos);
371  }
372 }
373 
374 
382 static void
384  void *impl_state)
385 {
386  struct ClientState *cstate = impl_state;
387 
388  (void) mq;
389  if (NULL != cstate->dns_active)
390  {
392  cstate->dns_active = NULL;
393  }
394  if (NULL != cstate->send_task)
395  {
397  cstate->send_task = NULL;
398  }
399  if (NULL != cstate->retry_task)
400  {
402  cstate->retry_task = NULL;
403  }
404  if (GNUNET_SYSERR == cstate->in_destroy)
405  {
406  /* defer destruction */
407  cstate->in_destroy = GNUNET_YES;
408  cstate->mq = NULL;
409  return;
410  }
411  if (NULL != cstate->recv_task)
412  {
414  cstate->recv_task = NULL;
415  }
416  if (NULL != cstate->sock)
417  {
419  "destroying socket: %p\n",
420  cstate->sock);
422  }
423  cancel_aps (cstate);
424  GNUNET_free (cstate->service_name);
425  GNUNET_free_non_null (cstate->hostname);
426  GNUNET_MST_destroy (cstate->mst);
427  GNUNET_free (cstate);
428 }
429 
430 
436 static void
437 receive_ready (void *cls)
438 {
439  struct ClientState *cstate = cls;
440  int ret;
441 
442  cstate->recv_task = NULL;
443  cstate->in_destroy = GNUNET_SYSERR;
444  ret = GNUNET_MST_read (cstate->mst,
445  cstate->sock,
446  GNUNET_NO,
447  GNUNET_NO);
448  if (GNUNET_SYSERR == ret)
449  {
450  if (NULL != cstate->mq)
451  GNUNET_MQ_inject_error (cstate->mq,
453  if (GNUNET_YES == cstate->in_destroy)
455  cstate);
456  return;
457  }
458  if (GNUNET_YES == cstate->in_destroy)
459  {
461  cstate);
462  return;
463  }
464  cstate->in_destroy = GNUNET_NO;
465  cstate->recv_task
467  cstate->sock,
468  &receive_ready,
469  cstate);
470 }
471 
472 
478 static void
480 {
481  GNUNET_assert (NULL == cstate->recv_task);
482  cstate->recv_task
484  cstate->sock,
485  &receive_ready,
486  cstate);
487  if (NULL != cstate->msg)
488  {
489  GNUNET_assert (NULL == cstate->send_task);
490  cstate->send_task
492  cstate->sock,
494  cstate);
495  }
496 }
497 
498 
506 static struct GNUNET_NETWORK_Handle *
508  const struct GNUNET_CONFIGURATION_Handle *cfg)
509 {
510 #if AF_UNIX
511  struct GNUNET_NETWORK_Handle *sock;
512  char *unixpath;
513  struct sockaddr_un s_un;
514 
515  unixpath = NULL;
516  if ((GNUNET_OK ==
518  service_name,
519  "UNIXPATH",
520  &unixpath)) &&
521  (0 < strlen (unixpath)))
522  {
523  /* We have a non-NULL unixpath, need to validate it */
524  if (strlen (unixpath) >= sizeof(s_un.sun_path))
525  {
527  _ ("UNIXPATH `%s' too long, maximum length is %llu\n"),
528  unixpath,
529  (unsigned long long) sizeof(s_un.sun_path));
530  unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
532  _ ("Using `%s' instead\n"),
533  unixpath);
534  if (NULL == unixpath)
535  return NULL;
536  }
537  memset (&s_un,
538  0,
539  sizeof(s_un));
540  s_un.sun_family = AF_UNIX;
541  GNUNET_strlcpy (s_un.sun_path,
542  unixpath,
543  sizeof(s_un.sun_path));
544 #if HAVE_SOCKADDR_UN_SUN_LEN
545  s_un.sun_len = (u_char) sizeof(struct sockaddr_un);
546 #endif
547  sock = GNUNET_NETWORK_socket_create (AF_UNIX,
548  SOCK_STREAM,
549  0);
550  if ((NULL != sock) &&
551  ((GNUNET_OK ==
553  (struct sockaddr *) &s_un,
554  sizeof(s_un))) ||
555  (EINPROGRESS == errno)))
556  {
558  "Successfully connected to unixpath `%s'!\n",
559  unixpath);
560  GNUNET_free (unixpath);
561  return sock;
562  }
563  if (NULL != sock)
565  }
566  GNUNET_free_non_null (unixpath);
567 #endif
568  return NULL;
569 }
570 
571 
578 static void
580 {
581  struct AddressProbe *ap = cls;
582  struct ClientState *cstate = ap->cstate;
583  const struct GNUNET_SCHEDULER_TaskContext *tc;
584  int error;
585  socklen_t len;
586 
587  ap->task = NULL;
588  GNUNET_assert (NULL != ap->sock);
590  cstate->ap_tail,
591  ap);
592  len = sizeof(error);
593  error = 0;
595  if ((0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ||
596  (GNUNET_OK !=
598  SOL_SOCKET,
599  SO_ERROR,
600  &error,
601  &len)) ||
602  (0 != error))
603  {
606  GNUNET_free (ap);
607  if ((NULL == cstate->ap_head) &&
608  // (NULL == cstate->proxy_handshake) &&
609  (NULL == cstate->dns_active))
610  connect_fail_continuation (cstate);
611  return;
612  }
614  "Connection to `%s' succeeded!\n",
615  cstate->service_name);
616  /* trigger jobs that waited for the connection */
617  GNUNET_assert (NULL == cstate->sock);
618  cstate->sock = ap->sock;
619  GNUNET_free (ap);
620  cancel_aps (cstate);
622 }
623 
624 
633 static void
635  const struct sockaddr *addr,
636  socklen_t addrlen)
637 {
638  struct ClientState *cstate = cls;
639  struct AddressProbe *ap;
640 
641  if (NULL == addr)
642  {
643  cstate->dns_active = NULL;
644  if ((NULL == cstate->ap_head) &&
645  // (NULL == cstate->proxy_handshake) &&
646  (NULL == cstate->sock))
647  connect_fail_continuation (cstate);
648  return;
649  }
650  if (NULL != cstate->sock)
651  return; /* already connected */
652  /* try to connect */
654  "Trying to connect using address `%s:%u'\n",
655  GNUNET_a2s (addr,
656  addrlen),
657  cstate->port);
658  ap = GNUNET_malloc (sizeof(struct AddressProbe) + addrlen);
659  ap->addr = (const struct sockaddr *) &ap[1];
660  GNUNET_memcpy (&ap[1],
661  addr,
662  addrlen);
663  ap->addrlen = addrlen;
664  ap->cstate = cstate;
665 
666  switch (ap->addr->sa_family)
667  {
668  case AF_INET:
669  ((struct sockaddr_in *) ap->addr)->sin_port = htons (cstate->port);
670  break;
671 
672  case AF_INET6:
673  ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (cstate->port);
674  break;
675 
676  default:
677  GNUNET_break (0);
678  GNUNET_free (ap);
679  return; /* not supported by us */
680  }
681  ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family,
682  SOCK_STREAM,
683  0);
684  if (NULL == ap->sock)
685  {
686  GNUNET_free (ap);
687  return; /* not supported by OS */
688  }
689  if ((GNUNET_OK !=
691  ap->addr,
692  ap->addrlen)) &&
693  (EINPROGRESS != errno))
694  {
695  /* maybe refused / unsupported address, try next */
697  "connect");
700  GNUNET_free (ap);
701  return;
702  }
704  cstate->ap_tail,
705  ap);
707  ap->sock,
709  ap);
710 }
711 
712 
721 static int
723  const struct GNUNET_CONFIGURATION_Handle *cfg)
724 {
725  int ret = GNUNET_SYSERR;
726  char *hostname = NULL;
727  unsigned long long port;
728 
729 #if AF_UNIX
730  char *unixpath = NULL;
731 
732  if ((GNUNET_OK ==
734  service_name,
735  "UNIXPATH",
736  &unixpath)) &&
737  (0 < strlen (unixpath)))
738  ret = GNUNET_OK;
739  else if ((GNUNET_OK ==
741  service_name,
742  "UNIXPATH")))
743  {
745  service_name,
746  "UNIXPATH",
747  _ ("not a valid filename"));
748  return GNUNET_SYSERR; /* UNIXPATH specified but invalid! */
749  }
750  GNUNET_free_non_null (unixpath);
751 #endif
752 
753  if ((GNUNET_YES ==
755  service_name,
756  "PORT")) &&
757  (GNUNET_OK ==
759  service_name,
760  "PORT",
761  &port)) &&
762  (port <= 65535) &&
763  (0 != port) &&
764  (GNUNET_OK ==
766  service_name,
767  "HOSTNAME",
768  &hostname)) &&
769  (0 != strlen (hostname)))
770  ret = GNUNET_OK;
771  GNUNET_free_non_null (hostname);
772  return ret;
773 }
774 
775 
781 static void
782 start_connect (void *cls)
783 {
784  struct ClientState *cstate = cls;
785 
786  cstate->retry_task = NULL;
787 #if 0
788  /* Never use a local source if a proxy is configured */
789  if (GNUNET_YES ==
791  cstate->cfg))
792  {
793  socks_connect (cstate);
794  return;
795  }
796 #endif
797 
798  if ((0 == (cstate->attempts++ % 2)) ||
799  (0 == cstate->port) ||
800  (NULL == cstate->hostname))
801  {
802  /* on even rounds, try UNIX first, or always
803  if we do not have a DNS name and TCP port. */
804  cstate->sock = try_unixpath (cstate->service_name,
805  cstate->cfg);
806  if (NULL != cstate->sock)
807  {
809  return;
810  }
811  }
812  if ((NULL == cstate->hostname) ||
813  (0 == cstate->port))
814  {
815  /* All options failed. Boo! */
816  connect_fail_continuation (cstate);
817  return;
818  }
819  cstate->dns_active
820  = GNUNET_RESOLVER_ip_get (cstate->hostname,
821  AF_UNSPEC,
824  cstate);
825 }
826 
827 
835 static void
837  const struct GNUNET_MessageHeader *msg,
838  void *impl_state)
839 {
840  struct ClientState *cstate = impl_state;
841 
842  (void) mq;
843  /* only one message at a time allowed */
844  GNUNET_assert (NULL == cstate->msg);
845  GNUNET_assert (NULL == cstate->send_task);
846  cstate->msg = msg;
847  cstate->msg_off = 0;
848  if (NULL == cstate->sock)
849  {
851  "message of type %u waiting for socket\n",
852  ntohs (msg->type));
853  return; /* still waiting for connection */
854  }
855  cstate->send_task
857  cstate);
858 }
859 
860 
867 static void
869  void *impl_state)
870 {
871  struct ClientState *cstate = impl_state;
872 
873  (void) mq;
874  GNUNET_assert (NULL != cstate->msg);
875  GNUNET_assert (0 == cstate->msg_off);
876  cstate->msg = NULL;
877  if (NULL != cstate->send_task)
878  {
880  cstate->send_task = NULL;
881  }
882 }
883 
884 
897 int
899  const char *service_name)
900 {
901  char *hostname = NULL;
902  unsigned long long port;
903  int ret;
904 
905 #if AF_UNIX
906  {
907  char *unixpath = NULL;
908 
909  if (GNUNET_OK ==
911  service_name,
912  "UNIXPATH",
913  &unixpath))
914  {
915  if (0 == strlen (unixpath))
916  {
917  GNUNET_free (unixpath);
918  return GNUNET_SYSERR; /* empty string not OK */
919  }
920  if (0 == access (unixpath,
921  F_OK))
922  {
923  GNUNET_free (unixpath);
924  return GNUNET_OK; /* file exists, we assume service is running */
925  }
926  GNUNET_free (unixpath);
927  }
928  else if (GNUNET_OK ==
930  service_name,
931  "UNIXPATH"))
932  {
933  /* UNIXPATH specified but not a valid path! */
935  service_name,
936  "UNIXPATH",
937  _ ("not a valid filename"));
938  return GNUNET_SYSERR;
939  }
940  }
941 #endif
942 
943  if ( (GNUNET_OK !=
945  service_name,
946  "PORT",
947  &port)) ||
948  (port > 65535) ||
949  (0 == port) )
950  {
951  return GNUNET_SYSERR;
952  }
953  if (GNUNET_OK ==
955  service_name,
956  "HOSTNAME",
957  &hostname))
958  {
959  /* We always assume remotes are up */
960  ret = GNUNET_YES;
961  }
962  else
963  {
964  /* We look for evidence the service is up */
965  ret = GNUNET_NO;
966  }
967  if ( (NULL == hostname) ||
968  (0 == strcasecmp (hostname,
969  "localhost")) ||
970  (0 == strcasecmp (hostname,
971  "ip6-localnet")) )
972  {
973  /* service runs on loopback */
974  struct sockaddr_in v4;
975  struct sockaddr_in6 v6;
976  int sock;
977 
978  memset (&v4, 0, sizeof (v4));
979  memset (&v6, 0, sizeof (v6));
980  v4.sin_family = AF_INET;
981  v4.sin_port = htons ((uint16_t) port);
982 #if HAVE_SOCKADDR_IN_SUN_LEN
983  v4.sin_len = (u_char) sizeof(struct sockaddr_in);
984 #endif
985  inet_pton (AF_INET,
986  "127.0.0.1",
987  &v4.sin_addr);
988  ret = GNUNET_NO;
989  sock = socket (AF_INET,
990  SOCK_STREAM,
991  0);
992  if (-1 != sock)
993  {
994  if (0 != bind (sock,
995  (struct sockaddr *) &v4,
996  sizeof (v4)))
997  {
998  /* bind failed, so someone is listening! */
999  ret = GNUNET_YES;
1000  }
1001  (void) close (sock);
1002  }
1003  else
1004  {
1006  "socket");
1007  if (GNUNET_NO == ret)
1008  ret = GNUNET_SYSERR;
1009  }
1010  v6.sin6_family = AF_INET6;
1011  v6.sin6_port = htons ((uint16_t) port);
1012 #if HAVE_SOCKADDR_IN_SUN_LEN
1013  v6.sin6_len = (u_char) sizeof(struct sockaddr_in6);
1014 #endif
1015  inet_pton (AF_INET6,
1016  "::1",
1017  &v6.sin6_addr);
1018  sock = socket (AF_INET6,
1019  SOCK_STREAM,
1020  0);
1021  if (-1 != sock)
1022  {
1023  if (0 != bind (sock,
1024  (struct sockaddr *) &v6,
1025  sizeof (v6)))
1026  {
1027  /* bind failed, so someone is listening! */
1028  ret = GNUNET_YES;
1029  }
1030  (void) close (sock);
1031  }
1032  else
1033  {
1035  "socket");
1036  /* not changing 'ret' intentionally here, as
1037  v4 succeeding and v6 failing just means we
1038  should use v4 */
1039  }
1040  }
1041  else
1042  {
1043  /* service running remotely */
1044  ret = GNUNET_OK;
1045  }
1046  GNUNET_free_non_null (hostname);
1047  return ret;
1048 }
1049 
1050 
1062 struct GNUNET_MQ_Handle *
1064  const char *service_name,
1065  const struct GNUNET_MQ_MessageHandler *handlers,
1067  void *error_handler_cls)
1068 {
1069  struct ClientState *cstate;
1070 
1071  if (GNUNET_OK !=
1072  test_service_configuration (service_name,
1073  cfg))
1074  return NULL;
1075  cstate = GNUNET_new (struct ClientState);
1076  cstate->service_name = GNUNET_strdup (service_name);
1077  cstate->cfg = cfg;
1079  cstate);
1080  cstate->mst = GNUNET_MST_create (&recv_message,
1081  cstate);
1082  if (GNUNET_YES ==
1084  service_name,
1085  "PORT"))
1086  {
1087  if (! ((GNUNET_OK !=
1089  service_name,
1090  "PORT",
1091  &cstate->port)) ||
1092  (cstate->port > 65535) ||
1093  (GNUNET_OK !=
1095  service_name,
1096  "HOSTNAME",
1097  &cstate->hostname))) &&
1098  (0 == strlen (cstate->hostname)))
1099  {
1100  GNUNET_free (cstate->hostname);
1101  cstate->hostname = NULL;
1103  _ ("Need a non-empty hostname for service `%s'.\n"),
1104  service_name);
1105  }
1106  }
1110  cstate,
1111  handlers,
1112  error_handler,
1113  error_handler_cls);
1114  return cstate->mq;
1115 }
1116 
1117 
1118 /* 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:110
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition: scheduler.c:754
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.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
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:816
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:1063
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:423
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:683
static void cancel_aps(struct ClientState *cstate)
Cancel all remaining connect attempts.
Definition: client.c:358
static void connection_client_cancel_impl(struct GNUNET_MQ_Handle *mq, void *impl_state)
Cancel the currently sent message.
Definition: client.c:868
static void connection_client_destroy_impl(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implement the destruction of a message queue.
Definition: client.c:383
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:1590
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
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_CONFIGURATION_Handle * cfg
Our configuration.
Definition: client.c:115
#define GNUNET_NO
Definition: gnunet_common.h:86
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
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
static void transmit_ready(void *cls)
We are ready to send a message to the service.
Definition: client.c:249
#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...
#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:507
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:132
#define _(String)
GNU gettext support macro.
Definition: platform.h:180
#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:528
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:1271
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:658
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:561
struct GNUNET_SCHEDULER_Task * recv_task
Task for sending messages to the service.
Definition: client.c:157
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:411
struct GNUNET_SCHEDULER_Task * send_task
Task for sending messages to the service.
Definition: client.c:152
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:332
static void connect_success_continuation(struct ClientState *cstate)
We&#39;ve succeeded in establishing a connection.
Definition: client.c:479
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:1298
FIXME: document!
struct AddressProbe * ap_tail
Linked list of sockets we are currently trying out (during connect).
Definition: client.c:127
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:782
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:701
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:85
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:220
const struct GNUNET_MessageHeader * msg
Next message to transmit to the service.
Definition: client.c:142
socklen_t addrlen
Lenth of addr.
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 respectiv...
Definition: client.c:898
Message handler for a specific message type.
unsigned int attempts
How often have we tried to connect?
Definition: client.c:193
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.
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:634
#define GNUNET_SYSERR
Definition: gnunet_common.h:84
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
Handle to a request given to the resolver.
Definition: resolver_api.c:102
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...
static void error_handler(void *cls, enum GNUNET_MQ_Error error)
We encountered an error handling the MQ to the ATS service.
struct GNUNET_MessageStreamTokenizer * mst
Tokenizer for inbound messages.
Definition: client.c:162
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:722
size_t msg_off
Offset in the message where we are for transmission.
Definition: client.c:188
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:121
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:579
unsigned long long port
TCP port (0 for disabled).
Definition: client.c:183
static char * hostname
Our hostname; we give this to all the peers we start.
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
char * hostname
Hostname, if any.
Definition: client.c:137
configuration data
Definition: configuration.c:84
#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:345
struct GNUNET_TIME_Relative back_off
Current value for our incremental back-off (for connect re-tries).
Definition: client.c:178
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:52
struct GNUNET_NETWORK_Handle * sock
The connection handle, NULL if not live.
Definition: client.c:105
struct GNUNET_SCHEDULER_Task * retry_task
Task for trying to connect to the service.
Definition: client.c:147
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:158
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:85
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:1519
static void receive_ready(void *cls)
This function is called once we have data ready to read.
Definition: client.c:437
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:836
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:495
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:220
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:560
#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:912
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:974
struct ClientState * cstate
Connection for which we are probing.
Definition: client.c:83