GNUnet 0.21.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
52struct ClientState;
53
54
60{
65
70
74 const struct sockaddr *addr;
75
80
85
89 socklen_t addrlen;
90
95};
96
97
101struct ClientState
102{
107
112
117
123
129
134
138 char *hostname;
139
144
149
154
159
164
168 struct GNUNET_MQ_Handle *mq;
169
174
180
184 unsigned long long port;
185
189 size_t msg_off;
190
194 unsigned int attempts;
195
202};
203
204
210static void
211start_connect (void *cls);
212
213
220static 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
240 cstate);
241}
242
243
249static void
250transmit_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
271RETRY:
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
335recv_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);
348 msg);
349 if (GNUNET_YES == cstate->in_destroy)
350 return GNUNET_NO;
351 return GNUNET_OK;
352}
353
354
360static void
361cancel_aps (struct ClientState *cstate)
362{
363 struct AddressProbe *pos;
364
365 while (NULL != (pos = cstate->ap_head))
366 {
372 pos);
373 GNUNET_free (pos);
374 }
375}
376
377
385static 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
439static void
440receive_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,
473 cstate);
474}
475
476
482static void
484{
485 GNUNET_assert (NULL == cstate->recv_task);
486 cstate->recv_task
488 cstate->sock,
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
510static 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 ==
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
582static 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))
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
637static 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",
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
725static 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 ==
739 "UNIXPATH",
740 &unixpath)) &&
741 (0 < strlen (unixpath)))
742 ret = GNUNET_OK;
743 else if ((GNUNET_OK ==
746 "UNIXPATH")))
747 {
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 ==
761 "PORT")) &&
762 (GNUNET_OK ==
765 "PORT",
766 &port)) &&
767 (port <= 65535) &&
768 (0 != port) &&
769 (GNUNET_OK ==
772 "HOSTNAME",
773 &hostname)) &&
774 (0 != strlen (hostname)))
775 ret = GNUNET_OK;
776 GNUNET_free (hostname);
777 return ret;
778}
779
780
786static void
787start_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! */
822 return;
823 }
824 cstate->dns_active
826 AF_UNSPEC,
829 cstate);
830}
831
832
840static 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
872static 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
902int
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 ==
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 ==
936 "UNIXPATH"))
937 {
938 /* UNIXPATH specified but not a valid path! */
941 "UNIXPATH",
942 _ ("not a valid filename"));
943 return GNUNET_SYSERR;
944 }
945 }
946#endif
947
948 if ( (GNUNET_OK !=
951 "PORT",
952 &port)) ||
953 (port > 65535) ||
954 (0 == port) )
955 {
956 return GNUNET_SYSERR;
957 }
958 if (GNUNET_OK ==
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)
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 }
1051 GNUNET_free (hostname);
1052 return ret;
1053}
1054
1055
1056struct 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);
1075 cstate);
1076 if (GNUNET_YES ==
1079 "PORT"))
1080 {
1081 if (! ((GNUNET_OK !=
1084 "PORT",
1085 &cstate->port)) ||
1086 (cstate->port > 65535) ||
1087 (GNUNET_OK !=
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,
1107 error_handler_cls);
1108 return cstate->mq;
1109}
1110
1111
1112/* end of client.c */
struct GNUNET_MQ_MessageHandlers handlers[]
Definition: 003.c:1
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)
Function called on connection trouble.
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 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
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
#define CONNECT_RETRY_TIMEOUT
Timeout we use on TCP connect before trying another result from the DNS resolver.
Definition: client.c:45
static int ret
Final status code.
Definition: gnunet-arm.c:94
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:109
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
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.
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
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
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.
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_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...
@ 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
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_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...
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:626
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
char * GNUNET_NETWORK_shorten_unixpath(char *unixpath)
Given a unixpath that is too long (larger than UNIX_PATH_MAX), shorten it to an acceptable length whi...
Definition: network.c:143
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:832
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:601
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:737
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
void GNUNET_RESOLVER_request_cancel(struct GNUNET_RESOLVER_RequestHandle *rh)
Cancel a request that is still pending with the resolver.
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
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
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_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_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.
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:86
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
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:570
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
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.
Definition: client.c:60
const struct sockaddr * addr
The address; do not free (allocated at the end of this struct).
Definition: client.c:74
socklen_t addrlen
Length of addr.
Definition: client.c:89
struct GNUNET_SCHEDULER_Task * task
Task waiting for the connection to finish connecting.
Definition: client.c:94
struct AddressProbe * next
This is a linked list.
Definition: client.c:64
struct ClientState * cstate
Connection for which we are probing.
Definition: client.c:84
struct AddressProbe * prev
This is a doubly-linked list.
Definition: client.c:69
struct GNUNET_NETWORK_Handle * sock
Underlying OS's socket.
Definition: client.c:79
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:53
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.