GNUnet  0.20.0
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 
30 #include "platform.h"
31 #include "gnunet_protocols.h"
32 #include "gnunet_util_lib.h"
34 #include "gnunet_socks.h"
35 
36 
37 #define LOG(kind, ...) GNUNET_log_from (kind, "util-client", __VA_ARGS__)
38 
45 #define CONNECT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply ( \
46  GNUNET_TIME_UNIT_SECONDS, 5)
47 
48 
52 struct ClientState;
53 
54 
59 struct AddressProbe
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 {
107 
112 
117 
123 
129 
134 
138  char *hostname;
139 
143  const struct GNUNET_MessageHeader *msg;
144 
149 
154 
159 
164 
169 
174 
180 
184  unsigned long long port;
185 
189  size_t msg_off;
190 
194  unsigned int attempts;
195 
202 };
203 
204 
210 static void
211 start_connect (void *cls);
212 
213 
220 static void
222 {
223  GNUNET_break (NULL == cstate->ap_head);
224  GNUNET_break (NULL == cstate->ap_tail);
225  GNUNET_break (NULL == cstate->dns_active);
226  GNUNET_break (NULL == cstate->sock);
227  GNUNET_assert (NULL == cstate->send_task);
228  GNUNET_assert (NULL == cstate->recv_task);
229  // GNUNET_assert (NULL == cstate->proxy_handshake);
230 
231  cstate->back_off = GNUNET_TIME_STD_BACKOFF (cstate->back_off);
233  "Failed to establish connection to `%s', no further addresses to try, will try again in %s.\n",
234  cstate->service_name,
236  GNUNET_YES));
237  cstate->retry_task
239  &start_connect,
240  cstate);
241 }
242 
243 
249 static void
250 transmit_ready (void *cls)
251 {
252  struct ClientState *cstate = cls;
253  ssize_t ret;
254  size_t len;
255  const char *pos;
256  int notify_in_flight;
257 
258  cstate->send_task = NULL;
259  if (GNUNET_YES == cstate->in_destroy)
260  return;
261  pos = (const char *) cstate->msg;
262  len = ntohs (cstate->msg->size);
263  GNUNET_assert (cstate->msg_off < len);
265  "message of type %u and size %u trying to send with socket %p (MQ: %p\n",
266  ntohs (cstate->msg->type),
267  ntohs (cstate->msg->size),
268  cstate->sock,
269  cstate->mq);
270 
271 RETRY:
273  &pos[cstate->msg_off],
274  len - cstate->msg_off);
275  if ( (-1 == ret) &&
276  ( (EAGAIN == errno) ||
277  (EINTR == errno) ) )
278  {
279  /* ignore */
280  ret = 0;
281  }
282  if (-1 == ret)
283  {
285  "Error during sending message of type %u: %s\n",
286  ntohs (cstate->msg->type),
287  strerror (errno));
288  if (EINTR == errno)
289  {
291  "Retrying message of type %u\n",
292  ntohs (cstate->msg->type));
293  goto RETRY;
294  }
295  GNUNET_MQ_inject_error (cstate->mq,
297  return;
298  }
299  notify_in_flight = (0 == cstate->msg_off);
300  cstate->msg_off += ret;
301  if (cstate->msg_off < len)
302  {
304  "rescheduling message of type %u\n",
305  ntohs (cstate->msg->type));
306  cstate->send_task
308  cstate->sock,
310  cstate);
311  if (notify_in_flight)
313  return;
314  }
316  "sending message of type %u and size %u successful\n",
317  ntohs (cstate->msg->type),
318  ntohs (cstate->msg->size));
319  cstate->msg = NULL;
321 }
322 
323 
334 static enum GNUNET_GenericReturnValue
335 recv_message (void *cls,
336  const struct GNUNET_MessageHeader *msg)
337 {
338  struct ClientState *cstate = cls;
339 
340  if (GNUNET_YES == cstate->in_destroy)
341  return GNUNET_NO;
343  "Received message of type %u and size %u from %s\n",
344  ntohs (msg->type),
345  ntohs (msg->size),
346  cstate->service_name);
347  GNUNET_MQ_inject_message (cstate->mq,
348  msg);
349  if (GNUNET_YES == cstate->in_destroy)
350  return GNUNET_NO;
351  return GNUNET_OK;
352 }
353 
354 
360 static void
361 cancel_aps (struct ClientState *cstate)
362 {
363  struct AddressProbe *pos;
364 
365  while (NULL != (pos = cstate->ap_head))
366  {
371  cstate->ap_tail,
372  pos);
373  GNUNET_free (pos);
374  }
375 }
376 
377 
385 static void
387  void *impl_state)
388 {
389  struct ClientState *cstate = impl_state;
390 
391  (void) mq;
392  if (NULL != cstate->dns_active)
393  {
395  cstate->dns_active = NULL;
396  }
397  if (NULL != cstate->send_task)
398  {
400  cstate->send_task = NULL;
401  }
402  if (NULL != cstate->retry_task)
403  {
405  cstate->retry_task = NULL;
406  }
407  if (GNUNET_SYSERR == cstate->in_destroy)
408  {
409  /* defer destruction */
410  cstate->in_destroy = GNUNET_YES;
411  cstate->mq = NULL;
412  return;
413  }
414  if (NULL != cstate->recv_task)
415  {
417  cstate->recv_task = NULL;
418  }
419  if (NULL != cstate->sock)
420  {
422  "destroying socket: %p\n",
423  cstate->sock);
425  }
426  cancel_aps (cstate);
427  GNUNET_free (cstate->service_name);
428  GNUNET_free (cstate->hostname);
429  GNUNET_MST_destroy (cstate->mst);
430  GNUNET_free (cstate);
431 }
432 
433 
439 static void
440 receive_ready (void *cls)
441 {
442  struct ClientState *cstate = cls;
444 
445  cstate->recv_task = NULL;
446  cstate->in_destroy = GNUNET_SYSERR;
447  ret = GNUNET_MST_read (cstate->mst,
448  cstate->sock,
449  GNUNET_NO,
450  GNUNET_NO);
451  if (GNUNET_SYSERR == ret)
452  {
453  if (NULL != cstate->mq)
454  GNUNET_MQ_inject_error (cstate->mq,
456  if (GNUNET_YES == cstate->in_destroy)
458  cstate);
459  return;
460  }
461  if (GNUNET_YES == cstate->in_destroy)
462  {
464  cstate);
465  return;
466  }
467  cstate->in_destroy = GNUNET_NO;
468  GNUNET_assert (NULL == cstate->recv_task);
469  cstate->recv_task
471  cstate->sock,
472  &receive_ready,
473  cstate);
474 }
475 
476 
482 static void
484 {
485  GNUNET_assert (NULL == cstate->recv_task);
486  cstate->recv_task
488  cstate->sock,
489  &receive_ready,
490  cstate);
491  if (NULL != cstate->msg)
492  {
493  GNUNET_assert (NULL == cstate->send_task);
494  cstate->send_task
496  cstate->sock,
498  cstate);
499  }
500 }
501 
502 
510 static struct GNUNET_NETWORK_Handle *
512  const struct GNUNET_CONFIGURATION_Handle *cfg)
513 {
514 #if AF_UNIX
515  struct GNUNET_NETWORK_Handle *sock;
516  char *unixpath;
517  struct sockaddr_un s_un;
518 
519  unixpath = NULL;
520  if ((GNUNET_OK ==
522  service_name,
523  "UNIXPATH",
524  &unixpath)) &&
525  (0 < strlen (unixpath)))
526  {
527  /* We have a non-NULL unixpath, need to validate it */
528  if (strlen (unixpath) >= sizeof(s_un.sun_path))
529  {
531  _ ("UNIXPATH `%s' too long, maximum length is %llu\n"),
532  unixpath,
533  (unsigned long long) sizeof(s_un.sun_path));
534  unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
536  _ ("Using `%s' instead\n"),
537  unixpath);
538  if (NULL == unixpath)
539  return NULL;
540  }
541  memset (&s_un,
542  0,
543  sizeof(s_un));
544  s_un.sun_family = AF_UNIX;
545  GNUNET_strlcpy (s_un.sun_path,
546  unixpath,
547  sizeof(s_un.sun_path));
548 #if HAVE_SOCKADDR_UN_SUN_LEN
549  s_un.sun_len = (u_char) sizeof(struct sockaddr_un);
550 #endif
551  sock = GNUNET_NETWORK_socket_create (AF_UNIX,
552  SOCK_STREAM,
553  0);
554  if ((NULL != sock) &&
555  ((GNUNET_OK ==
557  (struct sockaddr *) &s_un,
558  sizeof(s_un))) ||
559  (EINPROGRESS == errno)))
560  {
562  "Successfully connected to unixpath `%s'!\n",
563  unixpath);
564  GNUNET_free (unixpath);
565  return sock;
566  }
567  if (NULL != sock)
569  }
570  GNUNET_free (unixpath);
571 #endif
572  return NULL;
573 }
574 
575 
582 static void
584 {
585  struct AddressProbe *ap = cls;
586  struct ClientState *cstate = ap->cstate;
587  const struct GNUNET_SCHEDULER_TaskContext *tc;
588  int error;
589  socklen_t len;
590 
591  ap->task = NULL;
592  GNUNET_assert (NULL != ap->sock);
594  cstate->ap_tail,
595  ap);
596  len = sizeof(error);
597  error = 0;
600  (GNUNET_OK !=
602  SOL_SOCKET,
603  SO_ERROR,
604  &error,
605  &len)) ||
606  (0 != error))
607  {
610  GNUNET_free (ap);
611  if ((NULL == cstate->ap_head) &&
612  // (NULL == cstate->proxy_handshake) &&
613  (NULL == cstate->dns_active))
614  connect_fail_continuation (cstate);
615  return;
616  }
618  "Connection to `%s' succeeded!\n",
619  cstate->service_name);
620  /* trigger jobs that waited for the connection */
621  GNUNET_assert (NULL == cstate->sock);
622  cstate->sock = ap->sock;
623  GNUNET_free (ap);
624  cancel_aps (cstate);
626 }
627 
628 
637 static void
639  const struct sockaddr *addr,
640  socklen_t addrlen)
641 {
642  struct ClientState *cstate = cls;
643  struct AddressProbe *ap;
644 
645  if (NULL == addr)
646  {
647  cstate->dns_active = NULL;
648  if ((NULL == cstate->ap_head) &&
649  // (NULL == cstate->proxy_handshake) &&
650  (NULL == cstate->sock))
652  return;
653  }
654  if (NULL != cstate->sock)
655  return; /* already connected */
656  /* try to connect */
658  "Trying to connect using address `%s:%u'\n",
659  GNUNET_a2s (addr,
660  addrlen),
661  (unsigned int) cstate->port);
662  ap = GNUNET_malloc (sizeof(struct AddressProbe) + addrlen);
663  ap->addr = (const struct sockaddr *) &ap[1];
664  GNUNET_memcpy (&ap[1],
665  addr,
666  addrlen);
667  ap->addrlen = addrlen;
668  ap->cstate = cstate;
669 
670  switch (ap->addr->sa_family)
671  {
672  case AF_INET:
673  ((struct sockaddr_in *) ap->addr)->sin_port = htons (cstate->port);
674  break;
675 
676  case AF_INET6:
677  ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (cstate->port);
678  break;
679 
680  default:
681  GNUNET_break (0);
682  GNUNET_free (ap);
683  return; /* not supported by us */
684  }
685  ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family,
686  SOCK_STREAM,
687  0);
688  if (NULL == ap->sock)
689  {
690  GNUNET_free (ap);
691  return; /* not supported by OS */
692  }
693  if ((GNUNET_OK !=
695  ap->addr,
696  ap->addrlen)) &&
697  (EINPROGRESS != errno))
698  {
699  /* maybe refused / unsupported address, try next */
701  "connect");
704  GNUNET_free (ap);
705  return;
706  }
708  cstate->ap_tail,
709  ap);
711  ap->sock,
713  ap);
714 }
715 
716 
725 static int
727  const struct GNUNET_CONFIGURATION_Handle *cfg)
728 {
729  int ret = GNUNET_SYSERR;
730  char *hostname = NULL;
731  unsigned long long port;
732 
733 #if AF_UNIX
734  char *unixpath = NULL;
735 
736  if ((GNUNET_OK ==
738  service_name,
739  "UNIXPATH",
740  &unixpath)) &&
741  (0 < strlen (unixpath)))
742  ret = GNUNET_OK;
743  else if ((GNUNET_OK ==
745  service_name,
746  "UNIXPATH")))
747  {
749  service_name,
750  "UNIXPATH",
751  _ ("not a valid filename"));
752  GNUNET_free (unixpath);
753  return GNUNET_SYSERR; /* UNIXPATH specified but invalid! */
754  }
755  GNUNET_free (unixpath);
756 #endif
757 
758  if ((GNUNET_YES ==
760  service_name,
761  "PORT")) &&
762  (GNUNET_OK ==
764  service_name,
765  "PORT",
766  &port)) &&
767  (port <= 65535) &&
768  (0 != port) &&
769  (GNUNET_OK ==
771  service_name,
772  "HOSTNAME",
773  &hostname)) &&
774  (0 != strlen (hostname)))
775  ret = GNUNET_OK;
777  return ret;
778 }
779 
780 
786 static void
787 start_connect (void *cls)
788 {
789  struct ClientState *cstate = cls;
790 
791  cstate->retry_task = NULL;
792 #if 0
793  /* Never use a local source if a proxy is configured */
794  if (GNUNET_YES ==
796  cstate->cfg))
797  {
798  socks_connect (cstate);
799  return;
800  }
801 #endif
802 
803  if ((0 == (cstate->attempts++ % 2)) ||
804  (0 == cstate->port) ||
805  (NULL == cstate->hostname))
806  {
807  /* on even rounds, try UNIX first, or always
808  if we do not have a DNS name and TCP port. */
809  cstate->sock = try_unixpath (cstate->service_name,
810  cstate->cfg);
811  if (NULL != cstate->sock)
812  {
814  return;
815  }
816  }
817  if ((NULL == cstate->hostname) ||
818  (0 == cstate->port))
819  {
820  /* All options failed. Boo! */
821  connect_fail_continuation (cstate);
822  return;
823  }
824  cstate->dns_active
825  = GNUNET_RESOLVER_ip_get (cstate->hostname,
826  AF_UNSPEC,
829  cstate);
830 }
831 
832 
840 static void
842  const struct GNUNET_MessageHeader *msg,
843  void *impl_state)
844 {
845  struct ClientState *cstate = impl_state;
846 
847  (void) mq;
848  /* only one message at a time allowed */
849  GNUNET_assert (NULL == cstate->msg);
850  GNUNET_assert (NULL == cstate->send_task);
851  cstate->msg = msg;
852  cstate->msg_off = 0;
853  if (NULL == cstate->sock)
854  {
856  "message of type %u waiting for socket\n",
857  ntohs (msg->type));
858  return; /* still waiting for connection */
859  }
860  cstate->send_task
862  cstate);
863 }
864 
865 
872 static void
874  void *impl_state)
875 {
876  struct ClientState *cstate = impl_state;
877 
878  (void) mq;
879  GNUNET_assert (NULL != cstate->msg);
880  GNUNET_assert (0 == cstate->msg_off);
881  cstate->msg = NULL;
882  if (NULL != cstate->send_task)
883  {
885  cstate->send_task = NULL;
886  }
887 }
888 
889 
902 int
904  const char *service_name)
905 {
906  char *hostname = NULL;
907  unsigned long long port;
908  int ret;
909 
910 #if AF_UNIX
911  {
912  char *unixpath = NULL;
913 
914  if (GNUNET_OK ==
916  service_name,
917  "UNIXPATH",
918  &unixpath))
919  {
920  if (0 == strlen (unixpath))
921  {
922  GNUNET_free (unixpath);
923  return GNUNET_SYSERR; /* empty string not OK */
924  }
925  if (0 == access (unixpath,
926  F_OK))
927  {
928  GNUNET_free (unixpath);
929  return GNUNET_OK; /* file exists, we assume service is running */
930  }
931  GNUNET_free (unixpath);
932  }
933  else if (GNUNET_OK ==
935  service_name,
936  "UNIXPATH"))
937  {
938  /* UNIXPATH specified but not a valid path! */
940  service_name,
941  "UNIXPATH",
942  _ ("not a valid filename"));
943  return GNUNET_SYSERR;
944  }
945  }
946 #endif
947 
948  if ( (GNUNET_OK !=
950  service_name,
951  "PORT",
952  &port)) ||
953  (port > 65535) ||
954  (0 == port) )
955  {
956  return GNUNET_SYSERR;
957  }
958  if (GNUNET_OK ==
960  service_name,
961  "HOSTNAME",
962  &hostname))
963  {
964  /* We always assume remotes are up */
965  ret = GNUNET_YES;
966  }
967  else
968  {
969  /* We look for evidence the service is up */
970  ret = GNUNET_NO;
971  }
972  if ( (NULL == hostname) ||
973  (0 == strcasecmp (hostname,
974  "localhost")) ||
975  (0 == strcasecmp (hostname,
976  "ip6-localnet")) )
977  {
978  /* service runs on loopback */
979  struct sockaddr_in v4;
980  struct sockaddr_in6 v6;
981  int sock;
982 
983  memset (&v4, 0, sizeof (v4));
984  memset (&v6, 0, sizeof (v6));
985  v4.sin_family = AF_INET;
986  v4.sin_port = htons ((uint16_t) port);
987 #if HAVE_SOCKADDR_IN_SUN_LEN
988  v4.sin_len = (u_char) sizeof(struct sockaddr_in);
989 #endif
990  GNUNET_assert (1 == inet_pton (AF_INET,
991  "127.0.0.1",
992  &v4.sin_addr));
993  ret = GNUNET_NO;
994  sock = socket (AF_INET,
995  SOCK_STREAM,
996  0);
997  if (-1 != sock)
998  {
999  if (0 != bind (sock,
1000  (struct sockaddr *) &v4,
1001  sizeof (v4)))
1002  {
1003  /* bind failed, so someone is listening! */
1004  ret = GNUNET_YES;
1005  }
1006  (void) close (sock);
1007  }
1008  else
1009  {
1011  "socket");
1012  if (GNUNET_NO == ret)
1013  ret = GNUNET_SYSERR;
1014  }
1015  v6.sin6_family = AF_INET6;
1016  v6.sin6_port = htons ((uint16_t) port);
1017 #if HAVE_SOCKADDR_IN_SUN_LEN
1018  v6.sin6_len = (u_char) sizeof(struct sockaddr_in6);
1019 #endif
1020  inet_pton (AF_INET6,
1021  "::1",
1022  &v6.sin6_addr);
1023  sock = socket (AF_INET6,
1024  SOCK_STREAM,
1025  0);
1026  if (-1 != sock)
1027  {
1028  if (0 != bind (sock,
1029  (struct sockaddr *) &v6,
1030  sizeof (v6)))
1031  {
1032  /* bind failed, so someone is listening! */
1033  ret = GNUNET_YES;
1034  }
1035  (void) close (sock);
1036  }
1037  else
1038  {
1040  "socket");
1041  /* not changing 'ret' intentionally here, as
1042  v4 succeeding and v6 failing just means we
1043  should use v4 */
1044  }
1045  }
1046  else
1047  {
1048  /* service running remotely */
1049  ret = GNUNET_OK;
1050  }
1052  return ret;
1053 }
1054 
1055 
1056 struct GNUNET_MQ_Handle *
1058  const char *service_name,
1059  const struct GNUNET_MQ_MessageHandler *handlers,
1061  void *error_handler_cls)
1062 {
1063  struct ClientState *cstate;
1064 
1065  if (GNUNET_OK !=
1067  cfg))
1068  return NULL;
1069  cstate = GNUNET_new (struct ClientState);
1071  cstate->cfg = cfg;
1073  cstate);
1074  cstate->mst = GNUNET_MST_create (&recv_message,
1075  cstate);
1076  if (GNUNET_YES ==
1078  service_name,
1079  "PORT"))
1080  {
1081  if (! ((GNUNET_OK !=
1083  service_name,
1084  "PORT",
1085  &cstate->port)) ||
1086  (cstate->port > 65535) ||
1087  (GNUNET_OK !=
1089  service_name,
1090  "HOSTNAME",
1091  &cstate->hostname))) &&
1092  (0 == strlen (cstate->hostname)))
1093  {
1094  GNUNET_free (cstate->hostname);
1095  cstate->hostname = NULL;
1097  _ ("Need a non-empty hostname for service `%s'.\n"),
1098  service_name);
1099  }
1100  }
1104  cstate,
1105  handlers,
1106  error_handler,
1107  error_handler_cls);
1108  return cstate->mq;
1109 }
1110 
1111 
1112 /* end of client.c */
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static void error_handler(void *cls, enum GNUNET_MQ_Error error)
We encountered an error handling the MQ to the ATS service.
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:638
static void connect_success_continuation(struct ClientState *cstate)
We've succeeded in establishing a connection.
Definition: client.c:483
static void connection_client_cancel_impl(struct GNUNET_MQ_Handle *mq, void *impl_state)
Cancel the currently sent message.
Definition: client.c:873
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:841
static void start_connect(void *cls)
Try to connect to the service.
Definition: client.c:787
static void transmit_ready(void *cls)
We are ready to send a message to the service.
Definition: client.c:250
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:583
static enum GNUNET_GenericReturnValue recv_message(void *cls, const struct GNUNET_MessageHeader *msg)
We have received a full message, pass to the MQ dispatcher.
Definition: client.c:335
static void receive_ready(void *cls)
This function is called once we have data ready to read.
Definition: client.c:440
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:511
static void connection_client_destroy_impl(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implement the destruction of a message queue.
Definition: client.c:386
static void cancel_aps(struct ClientState *cstate)
Cancel all remaining connect attempts.
Definition: client.c:361
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:221
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:726
#define LOG(kind,...)
Definition: client.c:37
#define CONNECT_RETRY_TIMEOUT
Timeout we use on TCP connect before trying another result from the DNS resolver.
Definition: client.c:45
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static char * hostname
Our hostname; we give this to all the peers we start.
static char * service_name
Option -s: service name (hash to get service descriptor)
Definition: gnunet-vpn.c:50
Constants for network protocols.
Functions related to doing DNS lookups.
SOCKS proxy for connections.
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:903
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:1057
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.
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.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#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.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#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.
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.
#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).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
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:269
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...
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:465
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:421
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:187
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:444
@ GNUNET_MQ_ERROR_READ
Failed to read message from the network.
@ GNUNET_MQ_ERROR_WRITE
FIXME: document!
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:627
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:509
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:602
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:833
char * GNUNET_NETWORK_shorten_unixpath(char *unixpath)
Given a unixpath that is too long (larger than UNIX_PATH_MAX), shorten it to an acceptable length whi...
Definition: network.c:144
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:738
void GNUNET_RESOLVER_request_cancel(struct GNUNET_RESOLVER_RequestHandle *rh)
Cancel a request that is still pending with the resolver.
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:940
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:1299
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:1577
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:1506
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition: scheduler.c:752
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
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:1272
@ GNUNET_SCHEDULER_REASON_WRITE_READY
The writing socket is ready.
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:404
enum GNUNET_GenericReturnValue 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:338
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:86
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:594
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:138
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
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:569
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
#define RETRY
Return code we give on 'send' if we failed to send right now but it makes sense to retry later.
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:431
During connect, we try multiple possible IP addresses to find out which one might work.
socklen_t addrlen
Length of addr.
struct AddressProbe * prev
This is a doubly-linked list.
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:84
const struct sockaddr * addr
The address; do not free (allocated at the end of this struct).
struct AddressProbe * next
This is a linked list.
State we keep per client.
struct GNUNET_MQ_Handle * mq
MQ to talk to client.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: client.c:116
struct GNUNET_MessageStreamTokenizer * mst
Tokenizer for inbound messages.
Definition: client.c:163
int in_destroy
Are we supposed to die? GNUNET_SYSERR if destruction must be deferred, GNUNET_NO by default,...
Definition: client.c:201
unsigned int attempts
How often have we tried to connect?
Definition: client.c:194
const struct GNUNET_MessageHeader * msg
Next message to transmit to the service.
Definition: client.c:143
size_t msg_off
Offset in the message where we are for transmission.
Definition: client.c:189
struct GNUNET_SCHEDULER_Task * retry_task
Task for trying to connect to the service.
Definition: client.c:148
struct GNUNET_TIME_Relative back_off
Current value for our incremental back-off (for connect re-tries).
Definition: client.c:179
struct GNUNET_SCHEDULER_Task * send_task
Task for sending messages to the service.
Definition: client.c:153
char * hostname
Hostname, if any.
Definition: client.c:138
struct GNUNET_RESOLVER_RequestHandle * dns_active
Handle to a pending DNS lookup request, NULL if DNS is finished.
Definition: client.c:111
unsigned long long port
TCP port (0 for disabled).
Definition: client.c:184
struct GNUNET_TIME_Absolute receive_timeout
Timeout for receiving a response (absolute time).
Definition: client.c:173
struct GNUNET_SCHEDULER_Task * recv_task
Task for sending messages to the service.
Definition: client.c:158
struct GNUNET_NETWORK_Handle * sock
The connection handle, NULL if not live.
Definition: client.c:106
char * service_name
Name of the service we interact with.
Definition: client.c:133
struct AddressProbe * ap_tail
Linked list of sockets we are currently trying out (during connect).
Definition: client.c:128
struct AddressProbe * ap_head
Linked list of sockets we are currently trying out (during connect).
Definition: client.c:122
Handle to a message queue.
Definition: mq.c:87
void * error_handler_cls
Closure for the error handler.
Definition: mq.c:122
Message handler for a specific message type.
Header for all communications.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
Handle to a message stream tokenizer.
Definition: mst.c:45
handle to a socket
Definition: network.c:54
Handle to a request given to the resolver.
Definition: resolver_api.c:104
Context information passed to each scheduler task.
enum GNUNET_SCHEDULER_Reason reason
Reason why the task is run now.
Entry in list of pending tasks.
Definition: scheduler.c:136
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.