GNUnet  0.10.x
client.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2001-2016 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
29 #include "platform.h"
30 #include "gnunet_protocols.h"
31 #include "gnunet_util_lib.h"
33 #include "gnunet_socks.h"
34 
35 
36 #define LOG(kind, ...) GNUNET_log_from(kind, "util-client", __VA_ARGS__)
37 
44 #define CONNECT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5)
45 
46 
47 
51 struct ClientState;
52 
53 
58 struct AddressProbe {
62  struct AddressProbe *next;
63 
67  struct AddressProbe *prev;
68 
72  const struct sockaddr *addr;
73 
78 
83 
87  socklen_t addrlen;
88 
93 };
94 
95 
99 struct ClientState {
104 
109 
114 
120 
126 
131 
135  char *hostname;
136 
140  const struct GNUNET_MessageHeader *msg;
141 
146 
151 
156 
161 
165  struct GNUNET_MQ_Handle *mq;
166 
170  struct GNUNET_TIME_Absolute receive_timeout;
171 
176  struct GNUNET_TIME_Relative back_off;
177 
181  unsigned long long port;
182 
186  size_t msg_off;
187 
191  unsigned int attempts;
192 
199 };
200 
201 
207 static void
208 start_connect(void *cls);
209 
210 
217 static void
219 {
220  GNUNET_break(NULL == cstate->ap_head);
221  GNUNET_break(NULL == cstate->ap_tail);
222  GNUNET_break(NULL == cstate->dns_active);
223  GNUNET_break(NULL == cstate->sock);
224  GNUNET_assert(NULL == cstate->send_task);
225  GNUNET_assert(NULL == cstate->recv_task);
226  // GNUNET_assert (NULL == cstate->proxy_handshake);
227 
228  cstate->back_off = GNUNET_TIME_STD_BACKOFF(cstate->back_off);
230  "Failed to establish connection to `%s', no further addresses to try, will try again in %s.\n",
231  cstate->service_name,
233  GNUNET_YES));
234  cstate->retry_task
236  &start_connect,
237  cstate);
238 }
239 
240 
246 static void
247 transmit_ready(void *cls)
248 {
249  struct ClientState *cstate = cls;
250  ssize_t ret;
251  size_t len;
252  const char *pos;
253  int notify_in_flight;
254 
255  cstate->send_task = NULL;
256  if (GNUNET_YES == cstate->in_destroy)
257  return;
258  pos = (const char *)cstate->msg;
259  len = ntohs(cstate->msg->size);
260  GNUNET_assert(cstate->msg_off < len);
262  "message of type %u trying to send with socket %p (MQ: %p\n",
263  ntohs(cstate->msg->type),
264  cstate->sock,
265  cstate->mq);
266 
267 RETRY:
268  ret = GNUNET_NETWORK_socket_send(cstate->sock,
269  &pos[cstate->msg_off],
270  len - cstate->msg_off);
271  if (-1 == ret)
272  {
274  "Error during sending message of type %u\n",
275  ntohs(cstate->msg->type));
276  if (EINTR == errno)
277  {
279  "Retrying message of type %u\n",
280  ntohs(cstate->msg->type));
281  goto RETRY;
282  }
283  GNUNET_MQ_inject_error(cstate->mq,
285  return;
286  }
287  notify_in_flight = (0 == cstate->msg_off);
288  cstate->msg_off += ret;
289  if (cstate->msg_off < len)
290  {
292  "rescheduling message of type %u\n",
293  ntohs(cstate->msg->type));
294  cstate->send_task
296  cstate->sock,
298  cstate);
299  if (notify_in_flight)
301  return;
302  }
304  "sending message of type %u successful\n",
305  ntohs(cstate->msg->type));
306  cstate->msg = NULL;
308 }
309 
310 
321 static int
322 recv_message(void *cls,
323  const struct GNUNET_MessageHeader *msg)
324 {
325  struct ClientState *cstate = cls;
326 
327  if (GNUNET_YES == cstate->in_destroy)
328  return GNUNET_NO;
330  "Received message of type %u and size %u from %s\n",
331  ntohs(msg->type),
332  ntohs(msg->size),
333  cstate->service_name);
335  msg);
336  if (GNUNET_YES == cstate->in_destroy)
337  return GNUNET_NO;
338  return GNUNET_OK;
339 }
340 
341 
347 static void
349 {
350  struct AddressProbe *pos;
351 
352  while (NULL != (pos = cstate->ap_head))
353  {
358  cstate->ap_tail,
359  pos);
360  GNUNET_free(pos);
361  }
362 }
363 
364 
372 static void
374  void *impl_state)
375 {
376  struct ClientState *cstate = impl_state;
377 
378  (void)mq;
379  if (NULL != cstate->dns_active)
380  {
382  cstate->dns_active = NULL;
383  }
384  if (NULL != cstate->send_task)
385  {
387  cstate->send_task = NULL;
388  }
389  if (NULL != cstate->retry_task)
390  {
392  cstate->retry_task = NULL;
393  }
394  if (GNUNET_SYSERR == cstate->in_destroy)
395  {
396  /* defer destruction */
397  cstate->in_destroy = GNUNET_YES;
398  cstate->mq = NULL;
399  return;
400  }
401  if (NULL != cstate->recv_task)
402  {
404  cstate->recv_task = NULL;
405  }
406  if (NULL != cstate->sock)
407  {
409  "destroying socket: %p\n",
410  cstate->sock);
412  }
413  cancel_aps(cstate);
414  GNUNET_free(cstate->service_name);
416  GNUNET_MST_destroy(cstate->mst);
417  GNUNET_free(cstate);
418 }
419 
420 
426 static void
427 receive_ready(void *cls)
428 {
429  struct ClientState *cstate = cls;
430  int ret;
431 
432  cstate->recv_task = NULL;
433  cstate->in_destroy = GNUNET_SYSERR;
434  ret = GNUNET_MST_read(cstate->mst,
435  cstate->sock,
436  GNUNET_NO,
437  GNUNET_NO);
438  if (GNUNET_SYSERR == ret)
439  {
440  if (NULL != cstate->mq)
441  GNUNET_MQ_inject_error(cstate->mq,
443  if (GNUNET_YES == cstate->in_destroy)
445  cstate);
446  return;
447  }
448  if (GNUNET_YES == cstate->in_destroy)
449  {
451  cstate);
452  return;
453  }
454  cstate->in_destroy = GNUNET_NO;
455  cstate->recv_task
457  cstate->sock,
458  &receive_ready,
459  cstate);
460 }
461 
462 
468 static void
470 {
471  GNUNET_assert(NULL == cstate->recv_task);
472  cstate->recv_task
474  cstate->sock,
475  &receive_ready,
476  cstate);
477  if (NULL != cstate->msg)
478  {
479  GNUNET_assert(NULL == cstate->send_task);
480  cstate->send_task
482  cstate->sock,
484  cstate);
485  }
486 }
487 
488 
496 static struct GNUNET_NETWORK_Handle *
498  const struct GNUNET_CONFIGURATION_Handle *cfg)
499 {
500 #if AF_UNIX
501  struct GNUNET_NETWORK_Handle *sock;
502  char *unixpath;
503  struct sockaddr_un s_un;
504 
505  unixpath = NULL;
506  if ((GNUNET_OK ==
508  service_name,
509  "UNIXPATH",
510  &unixpath)) &&
511  (0 < strlen(unixpath)))
512  {
513  /* We have a non-NULL unixpath, need to validate it */
514  if (strlen(unixpath) >= sizeof(s_un.sun_path))
515  {
517  _("UNIXPATH `%s' too long, maximum length is %llu\n"),
518  unixpath,
519  (unsigned long long)sizeof(s_un.sun_path));
520  unixpath = GNUNET_NETWORK_shorten_unixpath(unixpath);
522  _("Using `%s' instead\n"),
523  unixpath);
524  if (NULL == unixpath)
525  return NULL;
526  }
527  memset(&s_un,
528  0,
529  sizeof(s_un));
530  s_un.sun_family = AF_UNIX;
531  GNUNET_strlcpy(s_un.sun_path,
532  unixpath,
533  sizeof(s_un.sun_path));
534 #ifdef LINUX
535  {
536  int abstract;
537 
539  "TESTING",
540  "USE_ABSTRACT_SOCKETS");
541  if (GNUNET_YES == abstract)
542  s_un.sun_path[0] = '\0';
543  }
544 #endif
545 #if HAVE_SOCKADDR_UN_SUN_LEN
546  s_un.sun_len = (u_char)sizeof(struct sockaddr_un);
547 #endif
548  sock = GNUNET_NETWORK_socket_create(AF_UNIX,
549  SOCK_STREAM,
550  0);
551  if ((NULL != sock) &&
552  ((GNUNET_OK ==
554  (struct sockaddr *)&s_un,
555  sizeof(s_un))) ||
556  (EINPROGRESS == errno)))
557  {
559  "Successfully connected to unixpath `%s'!\n",
560  unixpath);
561  GNUNET_free(unixpath);
562  return sock;
563  }
564  if (NULL != sock)
566  }
567  GNUNET_free_non_null(unixpath);
568 #endif
569  return NULL;
570 }
571 
572 
579 static void
581 {
582  struct AddressProbe *ap = cls;
583  struct ClientState *cstate = ap->cstate;
584  const struct GNUNET_SCHEDULER_TaskContext *tc;
585  int error;
586  socklen_t len;
587 
588  ap->task = NULL;
589  GNUNET_assert(NULL != ap->sock);
591  cstate->ap_tail,
592  ap);
593  len = sizeof(error);
594  error = 0;
596  if ((0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ||
597  (GNUNET_OK !=
599  SOL_SOCKET,
600  SO_ERROR,
601  &error,
602  &len)) ||
603  (0 != error))
604  {
607  GNUNET_free(ap);
608  if ((NULL == cstate->ap_head) &&
609  // (NULL == cstate->proxy_handshake) &&
610  (NULL == cstate->dns_active))
612  return;
613  }
615  "Connection to `%s' succeeded!\n",
616  cstate->service_name);
617  /* trigger jobs that waited for the connection */
618  GNUNET_assert(NULL == cstate->sock);
619  cstate->sock = ap->sock;
620  GNUNET_free(ap);
621  cancel_aps(cstate);
623 }
624 
625 
634 static void
636  const struct sockaddr *addr,
637  socklen_t addrlen)
638 {
639  struct ClientState *cstate = cls;
640  struct AddressProbe *ap;
641 
642  if (NULL == addr)
643  {
644  cstate->dns_active = NULL;
645  if ((NULL == cstate->ap_head) &&
646  // (NULL == cstate->proxy_handshake) &&
647  (NULL == cstate->sock))
649  return;
650  }
651  if (NULL != cstate->sock)
652  return; /* already connected */
653  /* try to connect */
655  "Trying to connect using address `%s:%u'\n",
656  GNUNET_a2s(addr,
657  addrlen),
658  cstate->port);
659  ap = GNUNET_malloc(sizeof(struct AddressProbe) + addrlen);
660  ap->addr = (const struct sockaddr *)&ap[1];
661  GNUNET_memcpy(&ap[1],
662  addr,
663  addrlen);
664  ap->addrlen = addrlen;
665  ap->cstate = cstate;
666 
667  switch (ap->addr->sa_family)
668  {
669  case AF_INET:
670  ((struct sockaddr_in *)ap->addr)->sin_port = htons(cstate->port);
671  break;
672 
673  case AF_INET6:
674  ((struct sockaddr_in6 *)ap->addr)->sin6_port = htons(cstate->port);
675  break;
676 
677  default:
678  GNUNET_break(0);
679  GNUNET_free(ap);
680  return; /* not supported by us */
681  }
682  ap->sock = GNUNET_NETWORK_socket_create(ap->addr->sa_family,
683  SOCK_STREAM,
684  0);
685  if (NULL == ap->sock)
686  {
687  GNUNET_free(ap);
688  return; /* not supported by OS */
689  }
690  if ((GNUNET_OK !=
692  ap->addr,
693  ap->addrlen)) &&
694  (EINPROGRESS != errno))
695  {
696  /* maybe refused / unsupported address, try next */
698  "connect");
701  GNUNET_free(ap);
702  return;
703  }
705  cstate->ap_tail,
706  ap);
708  ap->sock,
710  ap);
711 }
712 
713 
722 static int
724  const struct GNUNET_CONFIGURATION_Handle *cfg)
725 {
726  int ret = GNUNET_SYSERR;
727  char *hostname = NULL;
728  unsigned long long port;
729 
730 #if AF_UNIX
731  char *unixpath = NULL;
732 
733  if ((GNUNET_OK ==
735  service_name,
736  "UNIXPATH",
737  &unixpath)) &&
738  (0 < strlen(unixpath)))
739  ret = GNUNET_OK;
740  else if ((GNUNET_OK ==
742  service_name,
743  "UNIXPATH")))
744  {
746  service_name,
747  "UNIXPATH",
748  _("not a valid filename"));
749  return GNUNET_SYSERR; /* UNIXPATH specified but invalid! */
750  }
751  GNUNET_free_non_null(unixpath);
752 #endif
753 
754  if ((GNUNET_YES ==
756  service_name,
757  "PORT")) &&
758  (GNUNET_OK ==
760  service_name,
761  "PORT",
762  &port)) &&
763  (port <= 65535) &&
764  (0 != port) &&
765  (GNUNET_OK ==
767  service_name,
768  "HOSTNAME",
769  &hostname)) &&
770  (0 != strlen(hostname)))
771  ret = GNUNET_OK;
772  GNUNET_free_non_null(hostname);
773  return ret;
774 }
775 
776 
782 static void
783 start_connect(void *cls)
784 {
785  struct ClientState *cstate = cls;
786 
787  cstate->retry_task = NULL;
788 #if 0
789  /* Never use a local source if a proxy is configured */
790  if (GNUNET_YES ==
792  cstate->cfg))
793  {
794  socks_connect(cstate);
795  return;
796  }
797 #endif
798 
799  if ((0 == (cstate->attempts++ % 2)) ||
800  (0 == cstate->port) ||
801  (NULL == cstate->hostname))
802  {
803  /* on even rounds, try UNIX first, or always
804  if we do not have a DNS name and TCP port. */
805  cstate->sock = try_unixpath(cstate->service_name,
806  cstate->cfg);
807  if (NULL != cstate->sock)
808  {
810  return;
811  }
812  }
813  if ((NULL == cstate->hostname) ||
814  (0 == cstate->port))
815  {
816  /* All options failed. Boo! */
818  return;
819  }
820  cstate->dns_active
822  AF_UNSPEC,
825  cstate);
826 }
827 
828 
836 static void
838  const struct GNUNET_MessageHeader *msg,
839  void *impl_state)
840 {
841  struct ClientState *cstate = impl_state;
842 
843  (void)mq;
844  /* only one message at a time allowed */
845  GNUNET_assert(NULL == cstate->msg);
846  GNUNET_assert(NULL == cstate->send_task);
847  cstate->msg = msg;
848  cstate->msg_off = 0;
849  if (NULL == cstate->sock)
850  {
852  "message of type %u waiting for socket\n",
853  ntohs(msg->type));
854  return; /* still waiting for connection */
855  }
856  cstate->send_task
858  cstate->sock,
860  cstate);
861 }
862 
863 
870 static void
872  void *impl_state)
873 {
874  struct ClientState *cstate = impl_state;
875 
876  (void)mq;
877  GNUNET_assert(NULL != cstate->msg);
878  GNUNET_assert(0 == cstate->msg_off);
879  cstate->msg = NULL;
880  if (NULL != cstate->send_task)
881  {
883  cstate->send_task = NULL;
884  }
885 }
886 
887 
899 struct GNUNET_MQ_Handle *
901  const char *service_name,
902  const struct GNUNET_MQ_MessageHandler *handlers,
904  void *error_handler_cls)
905 {
906  struct ClientState *cstate;
907 
908  if (GNUNET_OK !=
909  test_service_configuration(service_name,
910  cfg))
911  return NULL;
912  cstate = GNUNET_new(struct ClientState);
913  cstate->service_name = GNUNET_strdup(service_name);
914  cstate->cfg = cfg;
916  cstate);
918  cstate);
919  if (GNUNET_YES ==
921  service_name,
922  "PORT"))
923  {
924  if (!((GNUNET_OK !=
926  service_name,
927  "PORT",
928  &cstate->port)) ||
929  (cstate->port > 65535) ||
930  (GNUNET_OK !=
932  service_name,
933  "HOSTNAME",
934  &cstate->hostname))) &&
935  (0 == strlen(cstate->hostname)))
936  {
937  GNUNET_free(cstate->hostname);
938  cstate->hostname = NULL;
940  _("Need a non-empty hostname for service `%s'.\n"),
941  service_name);
942  }
943  }
947  cstate,
948  handlers,
949  error_handler,
950  error_handler_cls);
951  return cstate->mq;
952 }
953 
954 /* 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:108
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition: scheduler.c:737
static void error_handler(void *cls, enum GNUNET_MQ_Error error)
We encountered an error handling the MQ to the ATS service.
const struct sockaddr * addr
The address; do not free (allocated at the end of this struct).
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
State we keep per client.
void GNUNET_RESOLVER_request_cancel(struct GNUNET_RESOLVER_RequestHandle *rh)
Cancel a request that is still pending with the resolver.
int GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
struct AddressProbe * prev
This is a doubly-linked list.
void GNUNET_MQ_inject_error(struct GNUNET_MQ_Handle *mq, enum GNUNET_MQ_Error error)
Call the error handler of a message queue with the given error code.
Definition: mq.c:298
#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:804
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:900
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:410
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:671
static void cancel_aps(struct ClientState *cstate)
Cancel all remaining connect attempts.
Definition: client.c:348
static void connection_client_cancel_impl(struct GNUNET_MQ_Handle *mq, void *impl_state)
Cancel the currently sent message.
Definition: client.c:871
static void connection_client_destroy_impl(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implement the destruction of a message queue.
Definition: client.c:373
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:1537
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
int in_destroy
Are we supposed to die? GNUNET_SYSERR if destruction must be deferred, GNUNET_NO by default...
Definition: client.c:198
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: client.c:113
#define GNUNET_NO
Definition: gnunet_common.h:78
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:933
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static void transmit_ready(void *cls)
We are ready to send a message to the service.
Definition: client.c:247
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_SCHEDULER_Task * task
Task waiting for the connection to finish connecting.
void GNUNET_log_config_invalid(enum GNUNET_ErrorType kind, const char *section, const char *option, const char *required)
Log error message about invalid configuration option value.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
static int ret
Final status code.
Definition: gnunet-arm.c:89
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static struct GNUNET_NETWORK_Handle * try_unixpath(const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg)
Try connecting to the server using UNIX domain sockets.
Definition: client.c:497
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:130
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
#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:517
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:1237
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:646
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:550
struct GNUNET_SCHEDULER_Task * recv_task
Task for sending messages to the service.
Definition: client.c:155
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:410
struct GNUNET_SCHEDULER_Task * send_task
Task for sending messages to the service.
Definition: client.c:150
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:322
static void connect_success_continuation(struct ClientState *cstate)
We&#39;ve succeeded in establishing a connection.
Definition: client.c:469
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:1264
FIXME: document!
struct AddressProbe * ap_tail
Linked list of sockets we are currently trying out (during connect).
Definition: client.c:125
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:783
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:686
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:84
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:200
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:218
const struct GNUNET_MessageHeader * msg
Next message to transmit to the service.
Definition: client.c:140
socklen_t addrlen
Lenth of addr.
Message handler for a specific message type.
unsigned int attempts
How often have we tried to connect?
Definition: client.c:191
struct GNUNET_NETWORK_Handle * sock
Underlying OS&#39;s socket.
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
The writing socket is ready.
static void try_connect_using_address(void *cls, const struct sockaddr *addr, socklen_t addrlen)
Try to establish a connection given the specified address.
Definition: client.c:635
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
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:592
Handle to a request given to the resolver.
Definition: resolver_api.c:100
void * error_handler_cls
Closure for the error handler.
Definition: mq.c:119
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
struct GNUNET_MessageStreamTokenizer * mst
Tokenizer for inbound messages.
Definition: client.c:160
Handle to a message queue.
Definition: mq.c:84
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:723
size_t msg_off
Offset in the message where we are for transmission.
Definition: client.c:186
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:119
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:580
unsigned long long port
TCP port (0 for disabled).
Definition: client.c:181
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:135
configuration data
Definition: configuration.c:83
#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:131
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:344
struct GNUNET_TIME_Relative back_off
Current value for our incremental back-off (for connect re-tries).
Definition: client.c:176
int GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
handle to a socket
Definition: network.c:46
struct GNUNET_NETWORK_Handle * sock
The connection handle, NULL if not live.
Definition: client.c:103
struct GNUNET_SCHEDULER_Task * retry_task
Task for trying to connect to the service.
Definition: client.c:145
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:151
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
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:1467
static void receive_ready(void *cls)
This function is called once we have data ready to read.
Definition: client.c:427
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:837
int GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
void GNUNET_MQ_impl_send_continue(struct GNUNET_MQ_Handle *mq)
Call the send implementation for the next queued message, if any.
Definition: mq.c:484
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:219
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:548
#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:900
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
struct ClientState * cstate
Connection for which we are probing.
Definition: client.c:82