GNUnet  0.11.x
gnunet-communicator-unix.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2010-2014, 2018 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_util_lib.h"
31 #include "gnunet_protocols.h"
32 #include "gnunet_constants.h"
33 #include "gnunet_nt_lib.h"
36 
45 #define DEFAULT_MAX_QUEUE_LENGTH 8
46 
50 #define COMMUNICATOR_ADDRESS_PREFIX "unix"
51 
55 #define COMMUNICATOR_CONFIG_SECTION "communicator-unix"
56 
60 #define UNIX_MTU UINT16_MAX
61 
63 
68 {
73 
78 };
79 
81 
82 
86 struct Queue
87 {
91  struct Queue *next;
92 
96  struct Queue *prev;
97 
101  struct GNUNET_PeerIdentity target;
102 
106  struct sockaddr_un *address;
107 
111  socklen_t address_len;
112 
117  const struct GNUNET_MessageHeader *msg;
118 
122  struct GNUNET_MQ_Handle *mq;
123 
127  struct GNUNET_TRANSPORT_QueueHandle *qh;
128 
132  unsigned long long bytes_in_queue;
133 
138 
143 };
144 
145 
150 
155 
159 static unsigned long long delivering_messages;
160 
164 static unsigned long long max_queue_length;
165 
170 
175 
180 
184 static struct Queue *queue_head;
185 
189 static struct Queue *queue_tail;
190 
195 
200 
201 
209 static void
211 {
212  struct GNUNET_MQ_Handle *mq;
213 
215  "Disconnecting queue for peer `%s'\n",
216  GNUNET_i2s (&queue->target));
217  if (0 != queue->bytes_in_queue)
218  {
219  GNUNET_CONTAINER_DLL_remove (queue_head, queue_tail, queue);
220  queue->bytes_in_queue = 0;
221  }
222  if (NULL != (mq = queue->mq))
223  {
224  queue->mq = NULL;
225  GNUNET_MQ_destroy (mq);
226  }
227  GNUNET_assert (
228  GNUNET_YES ==
229  GNUNET_CONTAINER_multipeermap_remove (queue_map, &queue->target, queue));
230  GNUNET_STATISTICS_set (stats,
231  "# queues active",
233  GNUNET_NO);
234  if (NULL != queue->timeout_task)
235  {
237  queue->timeout_task = NULL;
238  }
239  GNUNET_free (queue->address);
240  GNUNET_free (queue);
241 }
242 
243 
249 static void
250 queue_timeout (void *cls)
251 {
252  struct Queue *queue = cls;
253  struct GNUNET_TIME_Relative left;
254 
255  queue->timeout_task = NULL;
257  if (0 != left.rel_value_us)
258  {
259  /* not actually our turn yet, but let's at least update
260  the monitor, it may think we're about to die ... */
261  queue->timeout_task =
263  return;
264  }
266  "Queue %p was idle for %s, disconnecting\n",
267  queue,
270  GNUNET_YES));
271  queue_destroy (queue);
272 }
273 
274 
282 static void
284 {
285  GNUNET_assert (NULL != queue->timeout_task);
286  queue->timeout =
288 }
289 
290 
299 static struct sockaddr_un *
300 unix_address_to_sockaddr (const char *unixpath, socklen_t *sock_len)
301 {
302  struct sockaddr_un *un;
303  size_t slen;
304 
305  GNUNET_assert (0 < strlen (unixpath)); /* sanity check */
306  un = GNUNET_new (struct sockaddr_un);
307  un->sun_family = AF_UNIX;
308  slen = strlen (unixpath);
309  if (slen >= sizeof(un->sun_path))
310  slen = sizeof(un->sun_path) - 1;
311  GNUNET_memcpy (un->sun_path, unixpath, slen);
312  un->sun_path[slen] = '\0';
313  slen = sizeof(struct sockaddr_un);
314 #if HAVE_SOCKADDR_UN_SUN_LEN
315  un->sun_len = (u_char) slen;
316 #endif
317  (*sock_len) = slen;
318  if ('@' == un->sun_path[0])
319  un->sun_path[0] = '\0';
320  return un;
321 }
322 
323 
327 struct LookupCtx
328 {
332  struct Queue *res;
333 
337  const struct sockaddr_un *un;
338 
342  socklen_t un_len;
343 };
344 
345 
354 static int
355 lookup_queue_it (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
356 {
357  struct LookupCtx *lctx = cls;
358  struct Queue *queue = value;
359 
360  if ((queue->address_len = lctx->un_len) &&
361  (0 == memcmp (lctx->un, queue->address, queue->address_len)))
362  {
363  lctx->res = queue;
364  return GNUNET_NO;
365  }
366  return GNUNET_YES;
367 }
368 
369 
377 static struct Queue *
379  const struct sockaddr_un *un,
380  socklen_t un_len)
381 {
382  struct LookupCtx lctx;
383 
384  lctx.un = un;
385  lctx.un_len = un_len;
387  peer,
389  &lctx);
390  return lctx.res;
391 }
392 
393 
400 static void
401 select_write_cb (void *cls)
402 {
403  struct Queue *queue = queue_tail;
404  const struct GNUNET_MessageHeader *msg = queue->msg;
405  size_t msg_size = ntohs (msg->size);
406  ssize_t sent;
407 
408  /* take queue of the ready list */
409  write_task = NULL;
410  GNUNET_CONTAINER_DLL_remove (queue_head, queue_tail, queue);
411  if (NULL != queue_head)
413  unix_sock,
415  NULL);
416 
417  /* send 'msg' */
418  queue->msg = NULL;
420 resend:
421  /* Send the data */
422  sent = GNUNET_NETWORK_socket_sendto (unix_sock,
423  msg,
424  msg_size,
425  (const struct sockaddr *) queue->address,
426  queue->address_len);
428  "UNIX transmitted message to %s (%d/%u: %s)\n",
429  GNUNET_i2s (&queue->target),
430  (int) sent,
431  (unsigned int) msg_size,
432  (sent < 0) ? strerror (errno) : "ok");
433  if (-1 != sent)
434  {
436  "# bytes sent",
437  (long long) sent,
438  GNUNET_NO);
439  reschedule_queue_timeout (queue);
440  return; /* all good */
441  }
443  "# network transmission failures",
444  1,
445  GNUNET_NO);
446  switch (errno)
447  {
448  case EAGAIN:
449  case ENOBUFS:
450  /* We should retry later... */
452  return;
453 
454  case EMSGSIZE: {
455  socklen_t size = 0;
456  socklen_t len = sizeof(size);
457 
459  SOL_SOCKET,
460  SO_SNDBUF,
461  &size,
462  &len);
463  if (size > ntohs (msg->size))
464  {
465  /* Buffer is bigger than message: error, no retry
466  * This should never happen!*/
467  GNUNET_break (0);
468  return;
469  }
470  GNUNET_log (
472  "Trying to increase socket buffer size from %u to %u for message size %u\n",
473  (unsigned int) size,
474  (unsigned int) ((msg_size / 1000) + 2) * 1000,
475  (unsigned int) msg_size);
476  size = ((msg_size / 1000) + 2) * 1000;
478  SOL_SOCKET,
479  SO_SNDBUF,
480  &size,
481  sizeof(size)))
482  goto resend; /* Increased buffer size, retry sending */
483  /* Ok, then just try very modest increase */
484  size = msg_size;
486  SOL_SOCKET,
487  SO_SNDBUF,
488  &size,
489  sizeof(size)))
490  goto resend; /* Increased buffer size, retry sending */
491  /* Could not increase buffer size: error, no retry */
493  return;
494  }
495 
496  default:
498  return;
499  }
500 }
501 
502 
511 static void
513  const struct GNUNET_MessageHeader *msg,
514  void *impl_state)
515 {
516  struct Queue *queue = impl_state;
517 
518  GNUNET_assert (mq == queue->mq);
519  GNUNET_assert (NULL == queue->msg);
520  queue->msg = msg;
521  GNUNET_CONTAINER_DLL_insert (queue_head, queue_tail, queue);
522  GNUNET_assert (NULL != unix_sock);
523  if (NULL == write_task)
525  unix_sock,
527  NULL);
528 }
529 
530 
539 static void
540 mq_destroy (struct GNUNET_MQ_Handle *mq, void *impl_state)
541 {
542  struct Queue *queue = impl_state;
543 
544  if (mq == queue->mq)
545  {
546  queue->mq = NULL;
547  queue_destroy (queue);
548  }
549 }
550 
551 
558 static void
559 mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
560 {
561  struct Queue *queue = impl_state;
562 
563  GNUNET_assert (NULL != queue->msg);
564  queue->msg = NULL;
565  GNUNET_CONTAINER_DLL_remove (queue_head, queue_tail, queue);
566  GNUNET_assert (NULL != write_task);
567  if (NULL == queue_head)
568  {
569  GNUNET_SCHEDULER_cancel (write_task);
570  write_task = NULL;
571  }
572 }
573 
574 
584 static void
585 mq_error (void *cls, enum GNUNET_MQ_Error error)
586 {
587  struct Queue *queue = cls;
588 
590  "UNIX MQ error in queue to %s: %d\n",
591  GNUNET_i2s (&queue->target),
592  (int) error);
593  queue_destroy (queue);
594 }
595 
596 
607 static struct Queue *
610  const struct sockaddr_un *un,
611  socklen_t un_len)
612 {
613  struct Queue *queue;
614 
615  queue = GNUNET_new (struct Queue);
616  queue->target = *target;
617  queue->address = GNUNET_memdup (un, un_len);
618  queue->address_len = un_len;
620  queue_map,
621  &queue->target,
622  queue,
624  GNUNET_STATISTICS_set (stats,
625  "# queues active",
627  GNUNET_NO);
628  queue->timeout =
630  queue->timeout_task =
632  &queue_timeout,
633  queue);
635  &mq_destroy,
636  &mq_cancel,
637  queue,
638  NULL,
639  &mq_error,
640  queue);
641  {
642  char *foreign_addr;
643 
644  if ('\0' == un->sun_path[0])
645  GNUNET_asprintf (&foreign_addr,
646  "%s-@%s",
648  &un->sun_path[1]);
649  else
650  GNUNET_asprintf (&foreign_addr,
651  "%s-%s",
653  un->sun_path);
655  &queue->target,
656  foreign_addr,
657  UNIX_MTU,
659  cs,
660  queue->mq);
661  GNUNET_free (foreign_addr);
662  }
663  return queue;
664 }
665 
666 
674 static void
675 select_read_cb (void *cls);
676 
677 
685 static void
686 receive_complete_cb (void *cls, int success)
687 {
688  (void) cls;
690  if (GNUNET_OK != success)
692  "# transport transmission failures",
693  1,
694  GNUNET_NO);
695  GNUNET_assert (NULL != unix_sock);
696  if ((NULL == read_task) && (delivering_messages < max_queue_length))
698  unix_sock,
700  NULL);
701 }
702 
703 
711 static void
712 select_read_cb (void *cls)
713 {
714  char buf[65536] GNUNET_ALIGN;
715  struct Queue *queue;
716  const struct UNIXMessage *msg;
717  struct sockaddr_un un;
718  socklen_t addrlen;
719  ssize_t ret;
720  uint16_t msize;
721 
722  GNUNET_assert (NULL != unix_sock);
724  unix_sock,
726  NULL);
727  addrlen = sizeof(un);
728  memset (&un, 0, sizeof(un));
729  ret = GNUNET_NETWORK_socket_recvfrom (unix_sock,
730  buf,
731  sizeof(buf),
732  (struct sockaddr *) &un,
733  &addrlen);
734  if ((-1 == ret) && ((EAGAIN == errno) || (ENOBUFS == errno)))
735  return;
736  if (-1 == ret)
737  {
739  return;
740  }
742  "Read %d bytes from socket %s\n",
743  (int) ret,
744  un.sun_path);
745  GNUNET_assert (AF_UNIX == (un.sun_family));
746  msg = (struct UNIXMessage *) buf;
747  msize = ntohs (msg->header.size);
748  if ((msize < sizeof(struct UNIXMessage)) || (msize > ret))
749  {
750  GNUNET_break_op (0);
751  return;
752  }
753  queue = lookup_queue (&msg->sender, &un, addrlen);
754  if (NULL == queue)
755  queue =
756  setup_queue (&msg->sender, GNUNET_TRANSPORT_CS_INBOUND, &un, addrlen);
757  else
758  reschedule_queue_timeout (queue);
759  if (NULL == queue)
760  {
761  GNUNET_log (
763  _ (
764  "Maximum number of UNIX connections exceeded, dropping incoming message\n"));
765  return;
766  }
767 
768  {
769  uint16_t offset = 0;
770  uint16_t tsize = msize - sizeof(struct UNIXMessage);
771  const char *msgbuf = (const char *) &msg[1];
772 
773  while (offset + sizeof(struct GNUNET_MessageHeader) <= tsize)
774  {
775  const struct GNUNET_MessageHeader *currhdr;
776  struct GNUNET_MessageHeader al_hdr;
777  uint16_t csize;
778 
779  currhdr = (const struct GNUNET_MessageHeader *) &msgbuf[offset];
780  /* ensure aligned access */
781  memcpy (&al_hdr, currhdr, sizeof(al_hdr));
782  csize = ntohs (al_hdr.size);
783  if ((csize < sizeof(struct GNUNET_MessageHeader)) ||
784  (csize > tsize - offset))
785  {
786  GNUNET_break_op (0);
787  break;
788  }
790  &msg->sender,
791  currhdr,
794  NULL);
795  if (GNUNET_SYSERR == ret)
796  return; /* transport not up */
797  if (GNUNET_NO == ret)
798  break;
800  offset += csize;
801  }
802  }
804  {
805  /* we should try to apply 'back pressure' */
806  GNUNET_SCHEDULER_cancel (read_task);
807  read_task = NULL;
808  }
809 }
810 
811 
829 static int
830 mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
831 {
832  struct Queue *queue;
833  const char *path;
834  struct sockaddr_un *un;
835  socklen_t un_len;
836 
837  (void) cls;
838  if (0 != strncmp (address,
840  strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
841  {
842  GNUNET_break_op (0);
843  return GNUNET_SYSERR;
844  }
845  path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
846  un = unix_address_to_sockaddr (path, &un_len);
847  queue = lookup_queue (peer, un, un_len);
848  if (NULL != queue)
849  {
851  "Address `%s' for %s ignored, queue exists\n",
852  path,
853  GNUNET_i2s (peer));
854  GNUNET_free (un);
855  return GNUNET_OK;
856  }
857  queue = setup_queue (peer, GNUNET_TRANSPORT_CS_OUTBOUND, un, un_len);
858  GNUNET_free (un);
859  if (NULL == queue)
860  {
862  "Failed to setup queue to %s at `%s'\n",
863  GNUNET_i2s (peer),
864  path);
865  return GNUNET_NO;
866  }
867  return GNUNET_OK;
868 }
869 
870 
879 static int
881  const struct GNUNET_PeerIdentity *target,
882  void *value)
883 {
884  struct Queue *queue = value;
885 
886  (void) cls;
887  (void) target;
888  queue_destroy (queue);
889  return GNUNET_OK;
890 }
891 
892 
898 static void
899 do_shutdown (void *cls)
900 {
901  if (NULL != read_task)
902  {
903  GNUNET_SCHEDULER_cancel (read_task);
904  read_task = NULL;
905  }
906  if (NULL != write_task)
907  {
908  GNUNET_SCHEDULER_cancel (write_task);
909  write_task = NULL;
910  }
911  if (NULL != unix_sock)
912  {
914  unix_sock = NULL;
915  }
918  if (NULL != ai)
919  {
921  ai = NULL;
922  }
923  if (NULL != ch)
924  {
926  ch = NULL;
927  }
928  if (NULL != stats)
929  {
931  stats = NULL;
932  }
933 }
934 
935 
947 static void
948 enc_notify_cb (void *cls,
949  const struct GNUNET_PeerIdentity *sender,
950  const struct GNUNET_MessageHeader *msg)
951 {
952  (void) cls;
953  (void) sender;
954  (void) msg;
955  GNUNET_break_op (0);
956 }
957 
958 
967 static void
968 run (void *cls,
969  char *const *args,
970  const char *cfgfile,
971  const struct GNUNET_CONFIGURATION_Handle *cfg)
972 {
973  char *unix_socket_path;
974  struct sockaddr_un *un;
975  socklen_t un_len;
976  char *my_addr;
977 
978  (void) cls;
979 
980  if (GNUNET_OK !=
983  "UNIXPATH",
984  &unix_socket_path))
985  {
988  "UNIXPATH");
989  return;
990  }
991  if (GNUNET_OK !=
994  "MAX_QUEUE_LENGTH",
997 
998  un = unix_address_to_sockaddr (unix_socket_path, &un_len);
999  if (NULL == un)
1000  {
1002  "Failed to setup UNIX domain socket address with path `%s'\n",
1003  unix_socket_path);
1004  GNUNET_free (unix_socket_path);
1005  return;
1006  }
1007  unix_sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_DGRAM, 0);
1008  if (NULL == unix_sock)
1009  {
1011  GNUNET_free (un);
1012  GNUNET_free (unix_socket_path);
1013  return;
1014  }
1015  if (('\0' != un->sun_path[0]) &&
1017  {
1019  _ ("Cannot create path to `%s'\n"),
1020  un->sun_path);
1021  GNUNET_NETWORK_socket_close (unix_sock);
1022  unix_sock = NULL;
1023  GNUNET_free (un);
1024  GNUNET_free (unix_socket_path);
1025  return;
1026  }
1027  if (GNUNET_OK != GNUNET_NETWORK_socket_bind (unix_sock,
1028  (const struct sockaddr *) un,
1029  un_len))
1030  {
1031  GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "bind", un->sun_path);
1032  GNUNET_NETWORK_socket_close (unix_sock);
1033  unix_sock = NULL;
1034  GNUNET_free (un);
1035  GNUNET_free (unix_socket_path);
1036  return;
1037  }
1038  GNUNET_free (un);
1039  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Bound to `%s'\n", unix_socket_path);
1040  stats = GNUNET_STATISTICS_create ("C-UNIX", cfg);
1043  unix_sock,
1044  &select_read_cb,
1045  NULL);
1051  &mq_init,
1052  NULL,
1053  &enc_notify_cb,
1054  NULL);
1055  if (NULL == ch)
1056  {
1057  GNUNET_break (0);
1059  GNUNET_free (unix_socket_path);
1060  return;
1061  }
1062  GNUNET_asprintf (&my_addr,
1063  "%s-%s",
1065  unix_socket_path);
1066  GNUNET_free (unix_socket_path);
1068  my_addr,
1071  GNUNET_free (my_addr);
1072 }
1073 
1074 
1082 int
1083 main (int argc, char *const *argv)
1084 {
1085  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1087  };
1088  int ret;
1089 
1090  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1091  return 2;
1092 
1093  ret = (GNUNET_OK ==
1094  GNUNET_PROGRAM_run (argc,
1095  argv,
1096  "gnunet-communicator-unix",
1097  _ ("GNUnet UNIX domain socket communicator"),
1098  options,
1099  &run,
1100  NULL))
1101  ? 0
1102  : 1;
1103  GNUNET_free ((void *) argv);
1104  return ret;
1105 }
1106 
1107 
1108 #if defined(LINUX) && defined(__GLIBC__)
1109 #include <malloc.h>
1110 
1114 void __attribute__ ((constructor))
1115 GNUNET_ARM_memory_init ()
1116 {
1117  mallopt (M_TRIM_THRESHOLD, 4 * 1024);
1118  mallopt (M_TOP_PAD, 1 * 1024);
1119  malloc_trim (0);
1120 }
1121 
1122 
1123 #endif
1124 
1125 /* end of gnunet-communicator-unix.c */
static void mq_send(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
Signature of functions implementing the sending functionality of a message queue. ...
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static void queue(const char *hostname)
Add hostname to the list of requests to be made.
int GNUNET_NETWORK_socket_setsockopt(struct GNUNET_NETWORK_Handle *fd, int level, int option_name, const void *option_value, socklen_t option_len)
Set socket option.
Definition: network.c:883
Transmission is reliabile (with ACKs), i.e.
static void do_shutdown(void *cls)
Shutdown the UNIX communicator.
static struct GNUNET_SCHEDULER_Task * read_task
ID of read task.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_PeerIdentity target
To whom are we talking to.
static int lookup_queue_it(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Function called to find a queue by address.
socklen_t un_len
Number of bytes in un.
static void queue_destroy(struct Queue *queue)
Functions with this signature are called whenever we need to close a queue due to a disconnect or fai...
int GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
uint64_t rel_value_us
The actual value.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
socklen_t address_len
Length of the address.
static struct GNUNET_TRANSPORT_CommunicatorHandle * ch
Our environment.
struct GNUNET_TRANSPORT_AddressIdentifier * GNUNET_TRANSPORT_communicator_address_add(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const char *address, enum GNUNET_NetworkType nt, struct GNUNET_TIME_Relative expiration)
Notify transport service about an address that this communicator provides for this peer...
static int get_queue_delete_it(void *cls, const struct GNUNET_PeerIdentity *target, void *value)
Iterator over all message queues to clean up.
GNUNET_MQ_Error
Error codes for the queue.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1300
#define COMMUNICATOR_CONFIG_SECTION
Configuration section used by the communicator.
static int mq_init(void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
Function called by the transport service to initialize a message queue given address information abou...
struct GNUNET_MessageHeader header
Message header.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
int GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1438
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
static struct GNUNET_SCHEDULER_Task * write_task
ID of write task.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int main(int argc, char *const *argv)
The main function for the UNIX communicator.
int GNUNET_NETWORK_socket_getsockopt(const struct GNUNET_NETWORK_Handle *desc, int level, int optname, void *optval, socklen_t *optlen)
Get socket options.
Definition: network.c:683
int GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition: network.c:485
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
Setup communicator and launch network interactions.
Closure to lookup_queue_it().
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:1557
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:684
int GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Definition of a command line option.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:526
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
Handle for the service.
static void reschedule_queue_timeout(struct Queue *queue)
Increment queue timeout due to activity.
struct GNUNET_MQ_Handle * mq
Message queue we are providing for the ch.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_SCHEDULER_Task * timeout_task
Queue timeout task.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
Opaque handle to the transport service for communicators.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
void GNUNET_TRANSPORT_communicator_disconnect(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Disconnect from the transport service.
#define UNIX_MTU
Our MTU.
#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...
static void enc_notify_cb(void *cls, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg)
Function called when the transport service has received an acknowledgement for this communicator (!) ...
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
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:1253
#define COMMUNICATOR_ADDRESS_PREFIX
Address prefix used by the communicator.
unsigned long long bytes_in_queue
Number of bytes we currently have in our write queue.
UNIX Message-Packet header.
static struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
Definition: gnunet-abd.c:61
struct GNUNET_MQ_Handle * GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send, GNUNET_MQ_DestroyImpl destroy, GNUNET_MQ_CancelImpl cancel, void *impl_state, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *cls)
Create a message queue for the specified handlers.
Definition: mq.c:552
static unsigned int csize
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
static char * value
Value of the record to add/remove.
static struct Queue * queue_head
Head of queue of messages to transmit.
static struct GNUNET_STATISTICS_Handle * stats
For logging statistics.
Handle for a queue.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
static unsigned long long max_queue_length
Maximum queue length before we stop reading towards the transport service.
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:687
static void select_read_cb(void *cls)
We have been notified that our socket has something to read.
ssize_t GNUNET_NETWORK_socket_sendto(const struct GNUNET_NETWORK_Handle *desc, const void *message, size_t length, const struct sockaddr *dest_addr, socklen_t dest_len)
Send data to a particular destination (always non-blocking).
Definition: network.c:850
struct sockaddr_un * address
Address of the other peer.
static char buf[2048]
struct GNUNET_TRANSPORT_CommunicatorHandle * GNUNET_TRANSPORT_communicator_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section_name, const char *addr_prefix, enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc, GNUNET_TRANSPORT_CommunicatorMqInit mq_init, void *mq_init_cls, GNUNET_TRANSPORT_CommunicatorNotify notify_cb, void *notify_cb_cls)
Connect to the transport service.
this is an inbound connection (communicator initiated)
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
static void select_write_cb(void *cls)
We have been notified that our socket is ready to write.
Internal representation of the hash map.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
static void mq_destroy(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
const struct sockaddr_un * un
Address we are looking for.
void GNUNET_TRANSPORT_communicator_address_remove(struct GNUNET_TRANSPORT_AddressIdentifier *ai)
Notify transport service about an address that this communicator no longer provides for this peer...
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
struct GNUNET_HashCode key
The key used in the DHT.
static void mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implementation function that cancels the currently sent message.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:67
static struct GNUNET_TRANSPORT_AddressIdentifier * ai
Handle to the operation that publishes our address.
static struct sockaddr_un * unix_address_to_sockaddr(const char *unixpath, socklen_t *sock_len)
Convert unix path to a struct sockaddr_un *
Loopback (same host).
Definition: gnunet_nt_lib.h:45
const struct GNUNET_MessageHeader * msg
Message currently scheduled for transmission, non-NULL if and only if this queue is in the queue_head...
static void queue_timeout(void *cls)
Queue was idle for too long, so disconnect it.
int GNUNET_TRANSPORT_communicator_receive(struct GNUNET_TRANSPORT_CommunicatorHandle *handle, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg, struct GNUNET_TIME_Relative expected_addr_validity, GNUNET_TRANSPORT_MessageCompletedCallback cb, void *cb_cls)
Notify transport service that the communicator has received a message.
Allow multiple values with the same key.
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don&#39;t receive messages from the peer...
Handle to a message queue.
Definition: mq.c:85
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32;.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
static struct Queue * setup_queue(const struct GNUNET_PeerIdentity *target, enum GNUNET_TRANSPORT_ConnectionStatus cs, const struct sockaddr_un *un, socklen_t un_len)
Creates a new outbound queue the transport service will use to send data to another peer...
enum RadiotapType __attribute__
The identity of the host (wraps the signing key of the peer).
struct sockaddr * address
Address of the other peer.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to &#39;struct&#39;s...
static struct GNUNET_CONTAINER_MultiPeerMap * queue_map
Queues (map from peer identity to struct Queue)
configuration data
Definition: configuration.c:85
struct Queue * prev
Queues with pending messages (!) are kept in a DLL.
this is an outbound connection (transport initiated)
static struct GNUNET_NETWORK_Handle * unix_sock
socket that we transmit all data with
enum GNUNET_TRANSPORT_ConnectionStatus cs
Connection status for this queue.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
struct Queue * res
Location to store the queue, if found.
int GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
handle to a socket
Definition: network.c:52
int GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration, parse options).
Definition: program.c:367
static void mq_error(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_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:824
#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:1486
struct GNUNET_TRANSPORT_QueueHandle * GNUNET_TRANSPORT_communicator_mq_add(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_PeerIdentity *peer, const char *address, uint32_t mtu, enum GNUNET_NetworkType nt, enum GNUNET_TRANSPORT_ConnectionStatus cs, struct GNUNET_MQ_Handle *mq)
Notify transport service that a MQ became available due to an "inbound" connection or because the com...
GNUNET_TRANSPORT_ConnectionStatus
Possible states of a connection.
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
struct GNUNET_TIME_Absolute timeout
Timeout for this queue.
static struct Queue * queue_tail
Tail of queue of messages to transmit.
ssize_t GNUNET_NETWORK_socket_recvfrom(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length, struct sockaddr *src_addr, socklen_t *addrlen)
Read data from a socket (always non-blocking).
Definition: network.c:754
struct GNUNET_PeerIdentity sender
What is the identity of the sender (GNUNET_hash of public key)
struct GNUNET_TRANSPORT_QueueHandle * qh
handle for this queue with the ch.
struct Queue * next
Queues with pending messages (!) are kept in a DLL.
static char * address
GNS address for this phone.
void GNUNET_MQ_impl_send_continue(struct GNUNET_MQ_Handle *mq)
Call the send implementation for the next queued message, if any.
Definition: mq.c:486
#define DEFAULT_MAX_QUEUE_LENGTH
How many messages do we keep at most in the queue to the transport service before we start to drop (d...
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
Handle returned to identify the internal data structure the transport API has created to manage a mes...
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:560
int GNUNET_CONTAINER_multipeermap_get_multiple(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map that match a particular key.
static void receive_complete_cb(void *cls, int success)
Function called when message was successfully passed to transport service.
static unsigned long long delivering_messages
Number of messages we currently have in our queues towards the transport service. ...
static struct Queue * lookup_queue(const struct GNUNET_PeerIdentity *peer, const struct sockaddr_un *un, socklen_t un_len)
Find an existing queue by address.
Internal representation of an address a communicator is currently providing for the transport service...
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:912
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966