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 8000
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  struct UNIXMessage *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 
149 
154 
159 
163 static unsigned long long delivering_messages;
164 
168 static unsigned long long max_queue_length;
169 
174 
179 
184 
188 static struct Queue *queue_head;
189 
193 static struct Queue *queue_tail;
194 
199 
204 
205 
213 static void
215 {
216  struct GNUNET_MQ_Handle *mq;
217 
219  "Disconnecting queue for peer `%s'\n",
220  GNUNET_i2s (&queue->target));
221  if (0 != queue->bytes_in_queue)
222  {
223  GNUNET_CONTAINER_DLL_remove (queue_head, queue_tail, queue);
224  queue->bytes_in_queue = 0;
225  }
226  if (NULL != (mq = queue->mq))
227  {
228  queue->mq = NULL;
229  GNUNET_MQ_destroy (mq);
230  }
231  GNUNET_assert (
232  GNUNET_YES ==
233  GNUNET_CONTAINER_multipeermap_remove (queue_map, &queue->target, queue));
234  GNUNET_STATISTICS_set (stats,
235  "# queues active",
237  GNUNET_NO);
238  if (NULL != queue->timeout_task)
239  {
241  queue->timeout_task = NULL;
242  }
243  GNUNET_free (queue->address);
244  GNUNET_free (queue);
245 }
246 
247 
253 static void
254 queue_timeout (void *cls)
255 {
256  struct Queue *queue = cls;
257  struct GNUNET_TIME_Relative left;
258 
259  queue->timeout_task = NULL;
261  if (0 != left.rel_value_us)
262  {
263  /* not actually our turn yet, but let's at least update
264  the monitor, it may think we're about to die ... */
265  queue->timeout_task =
267  return;
268  }
270  "Queue %p was idle for %s, disconnecting\n",
271  queue,
274  GNUNET_YES));
275  queue_destroy (queue);
276 }
277 
278 
286 static void
288 {
289  GNUNET_assert (NULL != queue->timeout_task);
290  queue->timeout =
292 }
293 
294 
303 static struct sockaddr_un *
304 unix_address_to_sockaddr (const char *unixpath, socklen_t *sock_len)
305 {
306  struct sockaddr_un *un;
307  size_t slen;
308 
309  GNUNET_assert (0 < strlen (unixpath)); /* sanity check */
310  un = GNUNET_new (struct sockaddr_un);
311  un->sun_family = AF_UNIX;
312  slen = strlen (unixpath);
313  if (slen >= sizeof(un->sun_path))
314  slen = sizeof(un->sun_path) - 1;
315  GNUNET_memcpy (un->sun_path, unixpath, slen);
316  un->sun_path[slen] = '\0';
317  slen = sizeof(struct sockaddr_un);
318 #if HAVE_SOCKADDR_UN_SUN_LEN
319  un->sun_len = (u_char) slen;
320 #endif
321  (*sock_len) = slen;
322  if ('@' == un->sun_path[0])
323  un->sun_path[0] = '\0';
324  return un;
325 }
326 
327 
331 struct LookupCtx
332 {
336  struct Queue *res;
337 
341  const struct sockaddr_un *un;
342 
346  socklen_t un_len;
347 };
348 
349 
358 static int
359 lookup_queue_it (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
360 {
361  struct LookupCtx *lctx = cls;
362  struct Queue *queue = value;
363 
364  if ((queue->address_len == lctx->un_len) &&
365  (0 == memcmp (lctx->un, queue->address, queue->address_len)))
366  {
367  lctx->res = queue;
368  return GNUNET_NO;
369  }
370  return GNUNET_YES;
371 }
372 
373 
381 static struct Queue *
383  const struct sockaddr_un *un,
384  socklen_t un_len)
385 {
386  struct LookupCtx lctx;
387 
388  lctx.un = un;
389  lctx.un_len = un_len;
390  lctx.res = NULL;
392  peer,
394  &lctx);
395  return lctx.res;
396 }
397 
398 
405 static void
406 select_write_cb (void *cls)
407 {
408  struct Queue *queue = queue_tail;
409  const struct GNUNET_MessageHeader *msg = &queue->msg->header;
410  size_t msg_size = ntohs (msg->size);
411  ssize_t sent;
412 
413  /* take queue of the ready list */
414  write_task = NULL;
415 resend:
416  /* Send the data */
417  sent = GNUNET_NETWORK_socket_sendto (unix_sock,
418  msg,
419  msg_size,
420  (const struct sockaddr *) queue->address,
421  queue->address_len);
423  "UNIX transmitted message to %s (%d/%u: %s)\n",
424  GNUNET_i2s (&queue->target),
425  (int) sent,
426  (unsigned int) msg_size,
427  (sent < 0) ? strerror (errno) : "ok");
428  if (-1 != sent)
429  {
430  GNUNET_CONTAINER_DLL_remove (queue_head, queue_tail, queue);
431  if (NULL != queue_head)
433  unix_sock,
435  NULL);
436 
437  /* send 'msg' */
438  GNUNET_free (queue->msg);
439  queue->msg = NULL;
442  "# bytes sent",
443  (long long) sent,
444  GNUNET_NO);
445  reschedule_queue_timeout (queue);
446  return; /* all good */
447  }
449  "# network transmission failures",
450  1,
451  GNUNET_NO);
453  unix_sock,
455  NULL);
456  switch (errno)
457  {
458  case EAGAIN:
459  case ENOBUFS:
460  /* We should retry later... */
462  return;
463 
464  case EMSGSIZE: {
465  socklen_t size = 0;
466  socklen_t len = sizeof(size);
467 
469  SOL_SOCKET,
470  SO_SNDBUF,
471  &size,
472  &len);
473  if (size > ntohs (msg->size))
474  {
475  /* Buffer is bigger than message: error, no retry
476  * This should never happen!*/
477  GNUNET_break (0);
478  return;
479  }
480  GNUNET_log (
482  "Trying to increase socket buffer size from %u to %u for message size %u\n",
483  (unsigned int) size,
484  (unsigned int) ((msg_size / 1000) + 2) * 1000,
485  (unsigned int) msg_size);
486  size = ((msg_size / 1000) + 2) * 1000;
488  SOL_SOCKET,
489  SO_SNDBUF,
490  &size,
491  sizeof(size)))
492  goto resend; /* Increased buffer size, retry sending */
493  /* Ok, then just try very modest increase */
494  size = msg_size;
496  SOL_SOCKET,
497  SO_SNDBUF,
498  &size,
499  sizeof(size)))
500  goto resend; /* Increased buffer size, retry sending */
501  /* Could not increase buffer size: error, no retry */
503  return;
504  }
505 
506  default:
508  return;
509  }
510 }
511 
512 
521 static void
523  const struct GNUNET_MessageHeader *msg,
524  void *impl_state)
525 {
526  struct Queue *queue = impl_state;
527  size_t msize = ntohs (msg->size);
528 
529  GNUNET_assert (mq == queue->mq);
530  GNUNET_assert (NULL == queue->msg);
531  // Convert to UNIXMessage
532  queue->msg = GNUNET_malloc (msize + sizeof (struct UNIXMessage));
533  queue->msg->header.size = htons (msize + sizeof (struct UNIXMessage));
534  queue->msg->sender = my_identity;
535  memcpy (&queue->msg[1], msg, msize);
536  GNUNET_CONTAINER_DLL_insert (queue_head, queue_tail, queue);
537  GNUNET_assert (NULL != unix_sock);
538  if (NULL == write_task)
540  unix_sock,
542  NULL);
543 }
544 
545 
554 static void
555 mq_destroy (struct GNUNET_MQ_Handle *mq, void *impl_state)
556 {
557  struct Queue *queue = impl_state;
558 
559  if (mq == queue->mq)
560  {
561  queue->mq = NULL;
562  queue_destroy (queue);
563  }
564 }
565 
566 
573 static void
574 mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
575 {
576  struct Queue *queue = impl_state;
577 
578  GNUNET_assert (NULL != queue->msg);
579  queue->msg = NULL;
580  GNUNET_CONTAINER_DLL_remove (queue_head, queue_tail, queue);
581  GNUNET_assert (NULL != write_task);
582  if (NULL == queue_head)
583  {
584  GNUNET_SCHEDULER_cancel (write_task);
585  write_task = NULL;
586  }
587 }
588 
589 
599 static void
600 mq_error (void *cls, enum GNUNET_MQ_Error error)
601 {
602  struct Queue *queue = cls;
603 
605  "UNIX MQ error in queue to %s: %d\n",
606  GNUNET_i2s (&queue->target),
607  (int) error);
608  queue_destroy (queue);
609 }
610 
611 
622 static struct Queue *
625  const struct sockaddr_un *un,
626  socklen_t un_len)
627 {
628  struct Queue *queue;
629 
630  queue = GNUNET_new (struct Queue);
631  queue->target = *target;
632  queue->address = GNUNET_memdup (un, un_len);
633  queue->address_len = un_len;
635  queue_map,
636  &queue->target,
637  queue,
639  GNUNET_STATISTICS_set (stats,
640  "# queues active",
642  GNUNET_NO);
643  queue->timeout =
645  queue->timeout_task =
647  &queue_timeout,
648  queue);
650  &mq_destroy,
651  &mq_cancel,
652  queue,
653  NULL,
654  &mq_error,
655  queue);
656  {
657  char *foreign_addr;
658 
659  if ('\0' == un->sun_path[0])
660  GNUNET_asprintf (&foreign_addr,
661  "%s-@%s",
663  &un->sun_path[1]);
664  else
665  GNUNET_asprintf (&foreign_addr,
666  "%s-%s",
668  un->sun_path);
670  &queue->target,
671  foreign_addr,
672  UNIX_MTU,
674  cs,
675  queue->mq);
676  GNUNET_free (foreign_addr);
677  }
678  return queue;
679 }
680 
681 
689 static void
690 select_read_cb (void *cls);
691 
692 
700 static void
701 receive_complete_cb (void *cls, int success)
702 {
703  (void) cls;
705  if (GNUNET_OK != success)
707  "# transport transmission failures",
708  1,
709  GNUNET_NO);
710  if ((NULL == read_task) && (delivering_messages < max_queue_length) &&
711  (NULL != unix_sock))
713  unix_sock,
715  NULL);
716 }
717 
718 
726 static void
727 select_read_cb (void *cls)
728 {
729  char buf[65536] GNUNET_ALIGN;
730  struct Queue *queue;
731  const struct UNIXMessage *msg;
732  struct sockaddr_un un;
733  socklen_t addrlen;
734  ssize_t ret;
735  uint16_t msize;
736 
737  GNUNET_assert (NULL != unix_sock);
739  unix_sock,
741  NULL);
742  addrlen = sizeof(un);
743  memset (&un, 0, sizeof(un));
744  ret = GNUNET_NETWORK_socket_recvfrom (unix_sock,
745  buf,
746  sizeof(buf),
747  (struct sockaddr *) &un,
748  &addrlen);
749  if ((-1 == ret) && ((EAGAIN == errno) || (ENOBUFS == errno)))
750  return;
751  if (-1 == ret)
752  {
754  return;
755  }
757  "Read %d bytes from socket %s\n",
758  (int) ret,
759  un.sun_path);
760  GNUNET_assert (AF_UNIX == (un.sun_family));
761  msg = (struct UNIXMessage *) buf;
762  msize = ntohs (msg->header.size);
763  if ((msize < sizeof(struct UNIXMessage)) || (msize > ret))
764  {
766  "Wrong message size: %d bytes\n",
767  msize);
768  GNUNET_break_op (0);
769  return;
770  }
771  queue = lookup_queue (&msg->sender, &un, addrlen);
772  if (NULL == queue)
773  queue =
774  setup_queue (&msg->sender, GNUNET_TRANSPORT_CS_INBOUND, &un, addrlen);
775  else
776  reschedule_queue_timeout (queue);
777  if (NULL == queue)
778  {
779  GNUNET_log (
781  _ (
782  "Maximum number of UNIX connections exceeded, dropping incoming message\n"));
783  return;
784  }
785 
786  {
787  uint16_t tsize = msize - sizeof(struct UNIXMessage);
788 
789  const struct GNUNET_MessageHeader *currhdr;
790  struct GNUNET_MessageHeader al_hdr;
791 
792  currhdr = (const struct GNUNET_MessageHeader *) &msg[1];
793  /* ensure aligned access */
794  memcpy (&al_hdr, currhdr, sizeof(al_hdr));
795  if ((tsize < sizeof(struct GNUNET_MessageHeader)) ||
796  (tsize != ntohs(al_hdr.size)))
797  {
798  GNUNET_break_op (0);
799  return;
800  }
802  &msg->sender,
803  currhdr,
806  NULL);
807  if (GNUNET_SYSERR == ret)
808  {
810  "Transport not up!\n");
811  return; /* transport not up */
812  }
813  if (GNUNET_NO == ret)
814  {
816  "Error sending message to transport\n");
817  return;
818  }
820  }
822  {
824  "Back pressure %llu\n", delivering_messages);
825 
826  /* we should try to apply 'back pressure' */
827  GNUNET_SCHEDULER_cancel (read_task);
828  read_task = NULL;
829  }
830 }
831 
832 
850 static int
851 mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
852 {
853  struct Queue *queue;
854  const char *path;
855  struct sockaddr_un *un;
856  socklen_t un_len;
857 
858  (void) cls;
859  if (0 != strncmp (address,
861  strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
862  {
863  GNUNET_break_op (0);
864  return GNUNET_SYSERR;
865  }
866  path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
867  un = unix_address_to_sockaddr (path, &un_len);
868  queue = lookup_queue (peer, un, un_len);
869  if (NULL != queue)
870  {
872  "Address `%s' for %s ignored, queue exists\n",
873  path,
874  GNUNET_i2s (peer));
875  GNUNET_free (un);
876  return GNUNET_OK;
877  }
878  queue = setup_queue (peer, GNUNET_TRANSPORT_CS_OUTBOUND, un, un_len);
879  GNUNET_free (un);
880  if (NULL == queue)
881  {
883  "Failed to setup queue to %s at `%s'\n",
884  GNUNET_i2s (peer),
885  path);
886  return GNUNET_NO;
887  }
888  return GNUNET_OK;
889 }
890 
891 
900 static int
902  const struct GNUNET_PeerIdentity *target,
903  void *value)
904 {
905  struct Queue *queue = value;
906 
907  (void) cls;
908  (void) target;
909  queue_destroy (queue);
910  return GNUNET_OK;
911 }
912 
913 
919 static void
920 do_shutdown (void *cls)
921 {
922  if (NULL != read_task)
923  {
924  GNUNET_SCHEDULER_cancel (read_task);
925  read_task = NULL;
926  }
927  if (NULL != write_task)
928  {
929  GNUNET_SCHEDULER_cancel (write_task);
930  write_task = NULL;
931  }
932  if (NULL != unix_sock)
933  {
935  unix_sock = NULL;
936  }
939  if (NULL != ai)
940  {
942  ai = NULL;
943  }
944  if (NULL != ch)
945  {
947  ch = NULL;
948  }
949  if (NULL != stats)
950  {
952  stats = NULL;
953  }
954 }
955 
956 
968 static void
969 enc_notify_cb (void *cls,
970  const struct GNUNET_PeerIdentity *sender,
971  const struct GNUNET_MessageHeader *msg)
972 {
973  (void) cls;
974  (void) sender;
975  (void) msg;
976  GNUNET_break_op (0);
977 }
978 
979 
988 static void
989 run (void *cls,
990  char *const *args,
991  const char *cfgfile,
992  const struct GNUNET_CONFIGURATION_Handle *cfg)
993 {
994  char *unix_socket_path;
995  struct sockaddr_un *un;
996  socklen_t un_len;
997  char *my_addr;
999 
1000  (void) cls;
1001  delivering_messages = 0;
1002 
1004  if (NULL == my_private_key)
1005  {
1006  GNUNET_log (
1008  _ (
1009  "UNIX communicator is lacking key configuration settings. Exiting.\n"));
1011  return;
1012  }
1014 
1015  if (GNUNET_OK !=
1018  "UNIXPATH",
1019  &unix_socket_path))
1020  {
1023  "UNIXPATH");
1024  return;
1025  }
1026  if (GNUNET_OK !=
1029  "MAX_QUEUE_LENGTH",
1030  &max_queue_length))
1032 
1033  un = unix_address_to_sockaddr (unix_socket_path, &un_len);
1034  if (NULL == un)
1035  {
1037  "Failed to setup UNIX domain socket address with path `%s'\n",
1038  unix_socket_path);
1039  GNUNET_free (unix_socket_path);
1040  return;
1041  }
1042  unix_sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_DGRAM, 0);
1043  if (NULL == unix_sock)
1044  {
1046  GNUNET_free (un);
1047  GNUNET_free (unix_socket_path);
1048  return;
1049  }
1050  if (('\0' != un->sun_path[0]) &&
1052  {
1054  _ ("Cannot create path to `%s'\n"),
1055  un->sun_path);
1056  GNUNET_NETWORK_socket_close (unix_sock);
1057  unix_sock = NULL;
1058  GNUNET_free (un);
1059  GNUNET_free (unix_socket_path);
1060  return;
1061  }
1062  if (GNUNET_OK != GNUNET_NETWORK_socket_bind (unix_sock,
1063  (const struct sockaddr *) un,
1064  un_len))
1065  {
1066  GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "bind", un->sun_path);
1067  GNUNET_NETWORK_socket_close (unix_sock);
1068  unix_sock = NULL;
1069  GNUNET_free (un);
1070  GNUNET_free (unix_socket_path);
1071  return;
1072  }
1073  GNUNET_free (un);
1074  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Bound to `%s'\n", unix_socket_path);
1075  stats = GNUNET_STATISTICS_create ("C-UNIX", cfg);
1078  unix_sock,
1079  &select_read_cb,
1080  NULL);
1086  &mq_init,
1087  NULL,
1088  &enc_notify_cb,
1089  NULL);
1090  if (NULL == ch)
1091  {
1092  GNUNET_break (0);
1094  GNUNET_free (unix_socket_path);
1095  return;
1096  }
1097  GNUNET_asprintf (&my_addr,
1098  "%s-%s",
1100  unix_socket_path);
1101  GNUNET_free (unix_socket_path);
1103  my_addr,
1106  GNUNET_free (my_addr);
1107 }
1108 
1109 
1117 int
1118 main (int argc, char *const *argv)
1119 {
1120  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1122  };
1123  int ret;
1124 
1125  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1126  return 2;
1127 
1128  ret = (GNUNET_OK ==
1129  GNUNET_PROGRAM_run (argc,
1130  argv,
1131  "gnunet-communicator-unix",
1132  _ ("GNUnet UNIX domain socket communicator"),
1133  options,
1134  &run,
1135  NULL))
1136  ? 0
1137  : 1;
1138  GNUNET_free ((void *) argv);
1139  return ret;
1140 }
1141 
1142 
1143 #if defined(__linux__) && defined(__GLIBC__)
1144 #include <malloc.h>
1145 
1149 void __attribute__ ((constructor))
1150 GNUNET_ARM_memory_init ()
1151 {
1152  mallopt (M_TRIM_THRESHOLD, 4 * 1024);
1153  mallopt (M_TOP_PAD, 1 * 1024);
1154  malloc_trim (0);
1155 }
1156 
1157 
1158 #endif
1159 
1160 /* 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:86
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
#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.
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).
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:526
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:180
void GNUNET_TRANSPORT_communicator_disconnect(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Disconnect from the transport service.
struct UNIXMessage * msg
Message currently scheduled for transmission, non-NULL if and only if this queue is in the queue_head...
#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
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]
static struct GNUNET_PeerIdentity my_identity
My Peer Identity.
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:84
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
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.
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:189
struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Own private key.
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;.
Private ECC key encoded for transmission.
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:84
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_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_create_from_configuration(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create a new private key by reading our peer&#39;s key from the file specified in the configuration...
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:85
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c: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.
#define GNUNET_malloc(size)
Wrapper around malloc.
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.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
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