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 #ifndef DARWIN
61 #define UNIX_MTU UINT16_MAX
62 #else
63 #define UNIX_MTU 2048
64 #endif
65 
67 
72 {
77 
82 };
83 
85 
86 
90 struct Queue
91 {
95  struct Queue *next;
96 
100  struct Queue *prev;
101 
105  struct GNUNET_PeerIdentity target;
106 
110  struct sockaddr_un *address;
111 
115  socklen_t address_len;
116 
121  struct UNIXMessage *msg;
122 
126  struct GNUNET_MQ_Handle *mq;
127 
131  struct GNUNET_TRANSPORT_QueueHandle *qh;
132 
136  unsigned long long bytes_in_queue;
137 
142 
147 };
148 
153 
158 
163 
167 static unsigned long long delivering_messages;
168 
172 static unsigned long long max_queue_length;
173 
178 
183 
188 
192 static struct Queue *queue_head;
193 
197 static struct Queue *queue_tail;
198 
203 
208 
209 
217 static void
219 {
220  struct GNUNET_MQ_Handle *mq;
221 
223  "Disconnecting queue for peer `%s'\n",
224  GNUNET_i2s (&queue->target));
225  if (0 != queue->bytes_in_queue)
226  {
227  GNUNET_CONTAINER_DLL_remove (queue_head, queue_tail, queue);
228  queue->bytes_in_queue = 0;
229  }
230  if (NULL != (mq = queue->mq))
231  {
232  queue->mq = NULL;
233  GNUNET_MQ_destroy (mq);
234  }
235  GNUNET_assert (
236  GNUNET_YES ==
237  GNUNET_CONTAINER_multipeermap_remove (queue_map, &queue->target, queue));
238  GNUNET_STATISTICS_set (stats,
239  "# queues active",
241  GNUNET_NO);
242  if (NULL != queue->timeout_task)
243  {
245  queue->timeout_task = NULL;
246  }
247  GNUNET_free (queue->address);
248  GNUNET_free (queue);
249 }
250 
251 
257 static void
258 queue_timeout (void *cls)
259 {
260  struct Queue *queue = cls;
261  struct GNUNET_TIME_Relative left;
262 
263  queue->timeout_task = NULL;
265  if (0 != left.rel_value_us)
266  {
267  /* not actually our turn yet, but let's at least update
268  the monitor, it may think we're about to die ... */
269  queue->timeout_task =
271  return;
272  }
274  "Queue %p was idle for %s, disconnecting\n",
275  queue,
278  GNUNET_YES));
279  queue_destroy (queue);
280 }
281 
282 
290 static void
292 {
293  GNUNET_assert (NULL != queue->timeout_task);
294  queue->timeout =
296 }
297 
298 
307 static struct sockaddr_un *
308 unix_address_to_sockaddr (const char *unixpath, socklen_t *sock_len)
309 {
310  struct sockaddr_un *un;
311  size_t slen;
312 
313  GNUNET_assert (0 < strlen (unixpath)); /* sanity check */
314  un = GNUNET_new (struct sockaddr_un);
315  un->sun_family = AF_UNIX;
316  slen = strlen (unixpath);
317  if (slen >= sizeof(un->sun_path))
318  slen = sizeof(un->sun_path) - 1;
319  GNUNET_memcpy (un->sun_path, unixpath, slen);
320  un->sun_path[slen] = '\0';
321  slen = sizeof(struct sockaddr_un);
322 #if HAVE_SOCKADDR_UN_SUN_LEN
323  un->sun_len = (u_char) slen;
324 #endif
325  (*sock_len) = slen;
326  if ('@' == un->sun_path[0])
327  un->sun_path[0] = '\0';
328  return un;
329 }
330 
331 
335 struct LookupCtx
336 {
340  struct Queue *res;
341 
345  const struct sockaddr_un *un;
346 
350  socklen_t un_len;
351 };
352 
353 
362 static int
363 lookup_queue_it (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
364 {
365  struct LookupCtx *lctx = cls;
366  struct Queue *queue = value;
367 
368  if ((queue->address_len == lctx->un_len) &&
369  (0 == memcmp (lctx->un, queue->address, queue->address_len)))
370  {
371  lctx->res = queue;
372  return GNUNET_NO;
373  }
374  return GNUNET_YES;
375 }
376 
377 
385 static struct Queue *
387  const struct sockaddr_un *un,
388  socklen_t un_len)
389 {
390  struct LookupCtx lctx;
391 
392  lctx.un = un;
393  lctx.un_len = un_len;
394  lctx.res = NULL;
396  peer,
398  &lctx);
399  return lctx.res;
400 }
401 
402 
409 static void
410 select_write_cb (void *cls)
411 {
412  struct Queue *queue = queue_tail;
413  const struct GNUNET_MessageHeader *msg = &queue->msg->header;
414  size_t msg_size = ntohs (msg->size);
415  ssize_t sent;
416 
417  /* take queue of the ready list */
418  write_task = NULL;
419 resend:
420  /* Send the data */
421  sent = GNUNET_NETWORK_socket_sendto (unix_sock,
422  msg,
423  msg_size,
424  (const struct sockaddr *) queue->address,
425  queue->address_len);
427  "UNIX transmitted message to %s (%d/%u: %s)\n",
428  GNUNET_i2s (&queue->target),
429  (int) sent,
430  (unsigned int) msg_size,
431  (sent < 0) ? strerror (errno) : "ok");
432  if (-1 != sent)
433  {
434  GNUNET_CONTAINER_DLL_remove (queue_head, queue_tail, queue);
435  if (NULL != queue_head)
437  unix_sock,
439  NULL);
440 
441  /* send 'msg' */
442  GNUNET_free (queue->msg);
443  queue->msg = NULL;
446  "# bytes sent",
447  (long long) sent,
448  GNUNET_NO);
449  reschedule_queue_timeout (queue);
450  return; /* all good */
451  }
453  "# network transmission failures",
454  1,
455  GNUNET_NO);
457  unix_sock,
459  NULL);
460  switch (errno)
461  {
462  case EAGAIN:
463  case ENOBUFS:
464  /* We should retry later... */
466  return;
467 
468  case EMSGSIZE: {
469  socklen_t size = 0;
470  socklen_t len = sizeof(size);
471 
473  SOL_SOCKET,
474  SO_SNDBUF,
475  &size,
476  &len);
477  if (size > ntohs (msg->size))
478  {
479  /* Buffer is bigger than message: error, no retry
480  * This should never happen!*/
481  GNUNET_break (0);
482  return;
483  }
484  GNUNET_log (
486  "Trying to increase socket buffer size from %u to %u for message size %u\n",
487  (unsigned int) size,
488  (unsigned int) ((msg_size / 1000) + 2) * 1000,
489  (unsigned int) msg_size);
490  size = ((msg_size / 1000) + 2) * 1000;
492  SOL_SOCKET,
493  SO_SNDBUF,
494  &size,
495  sizeof(size)))
496  goto resend; /* Increased buffer size, retry sending */
497  /* Ok, then just try very modest increase */
498  size = msg_size;
500  SOL_SOCKET,
501  SO_SNDBUF,
502  &size,
503  sizeof(size)))
504  goto resend; /* Increased buffer size, retry sending */
505  /* Could not increase buffer size: error, no retry */
507  return;
508  }
509 
510  default:
512  return;
513  }
514 }
515 
516 
525 static void
527  const struct GNUNET_MessageHeader *msg,
528  void *impl_state)
529 {
530  struct Queue *queue = impl_state;
531  size_t msize = ntohs (msg->size);
532 
533  GNUNET_assert (mq == queue->mq);
534  GNUNET_assert (NULL == queue->msg);
535  // Convert to UNIXMessage
536  queue->msg = GNUNET_malloc (msize + sizeof (struct UNIXMessage));
537  queue->msg->header.size = htons (msize + sizeof (struct UNIXMessage));
538  queue->msg->sender = my_identity;
539  memcpy (&queue->msg[1], msg, msize);
540  GNUNET_CONTAINER_DLL_insert (queue_head, queue_tail, queue);
541  GNUNET_assert (NULL != unix_sock);
542  if (NULL == write_task)
544  unix_sock,
546  NULL);
547 }
548 
549 
558 static void
559 mq_destroy (struct GNUNET_MQ_Handle *mq, void *impl_state)
560 {
561  struct Queue *queue = impl_state;
562 
563  if (mq == queue->mq)
564  {
565  queue->mq = NULL;
566  queue_destroy (queue);
567  }
568 }
569 
570 
577 static void
578 mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
579 {
580  struct Queue *queue = impl_state;
581 
582  GNUNET_assert (NULL != queue->msg);
583  queue->msg = NULL;
584  GNUNET_CONTAINER_DLL_remove (queue_head, queue_tail, queue);
585  GNUNET_assert (NULL != write_task);
586  if (NULL == queue_head)
587  {
588  GNUNET_SCHEDULER_cancel (write_task);
589  write_task = NULL;
590  }
591 }
592 
593 
603 static void
604 mq_error (void *cls, enum GNUNET_MQ_Error error)
605 {
606  struct Queue *queue = cls;
607 
609  "UNIX MQ error in queue to %s: %d\n",
610  GNUNET_i2s (&queue->target),
611  (int) error);
612  queue_destroy (queue);
613 }
614 
615 
626 static struct Queue *
629  const struct sockaddr_un *un,
630  socklen_t un_len)
631 {
632  struct Queue *queue;
633 
634  queue = GNUNET_new (struct Queue);
635  queue->target = *target;
636  queue->address = GNUNET_memdup (un, un_len);
637  queue->address_len = un_len;
639  queue_map,
640  &queue->target,
641  queue,
643  GNUNET_STATISTICS_set (stats,
644  "# queues active",
646  GNUNET_NO);
647  queue->timeout =
649  queue->timeout_task =
651  &queue_timeout,
652  queue);
654  &mq_destroy,
655  &mq_cancel,
656  queue,
657  NULL,
658  &mq_error,
659  queue);
660  {
661  char *foreign_addr;
662 
663  if ('\0' == un->sun_path[0])
664  GNUNET_asprintf (&foreign_addr,
665  "%s-@%s",
667  &un->sun_path[1]);
668  else
669  GNUNET_asprintf (&foreign_addr,
670  "%s-%s",
672  un->sun_path);
674  &queue->target,
675  foreign_addr,
676  UNIX_MTU - sizeof (struct
677  UNIXMessage),
679  0,
681  cs,
682  queue->mq);
683  GNUNET_free (foreign_addr);
684  }
685  return queue;
686 }
687 
688 
696 static void
697 select_read_cb (void *cls);
698 
699 
707 static void
708 receive_complete_cb (void *cls, int success)
709 {
710  (void) cls;
712  if (GNUNET_OK != success)
714  "# transport transmission failures",
715  1,
716  GNUNET_NO);
717  if ((NULL == read_task) && (delivering_messages < max_queue_length) &&
718  (NULL != unix_sock))
720  unix_sock,
722  NULL);
723 }
724 
725 
733 static void
734 select_read_cb (void *cls)
735 {
736  char buf[65536] GNUNET_ALIGN;
737  struct Queue *queue;
738  const struct UNIXMessage *msg;
739  struct sockaddr_un un;
740  socklen_t addrlen;
741  ssize_t ret;
742  uint16_t msize;
743 
744  GNUNET_assert (NULL != unix_sock);
746  unix_sock,
748  NULL);
749  addrlen = sizeof(un);
750  memset (&un, 0, sizeof(un));
751  ret = GNUNET_NETWORK_socket_recvfrom (unix_sock,
752  buf,
753  sizeof(buf),
754  (struct sockaddr *) &un,
755  &addrlen);
756  if ((-1 == ret) && ((EAGAIN == errno) || (ENOBUFS == errno)))
757  return;
758  if (-1 == ret)
759  {
761  return;
762  }
764  "Read %d bytes from socket %s\n",
765  (int) ret,
766  un.sun_path);
767  GNUNET_assert (AF_UNIX == (un.sun_family));
768  msg = (struct UNIXMessage *) buf;
769  msize = ntohs (msg->header.size);
770  if ((msize < sizeof(struct UNIXMessage)) || (msize > ret))
771  {
773  "Wrong message size: %d bytes\n",
774  msize);
775  GNUNET_break_op (0);
776  return;
777  }
778  queue = lookup_queue (&msg->sender, &un, addrlen);
779  if (NULL == queue)
780  queue =
781  setup_queue (&msg->sender, GNUNET_TRANSPORT_CS_INBOUND, &un, addrlen);
782  else
783  reschedule_queue_timeout (queue);
784  if (NULL == queue)
785  {
786  GNUNET_log (
788  _ (
789  "Maximum number of UNIX connections exceeded, dropping incoming message\n"));
790  return;
791  }
792 
793  {
794  uint16_t tsize = msize - sizeof(struct UNIXMessage);
795 
796  const struct GNUNET_MessageHeader *currhdr;
797  struct GNUNET_MessageHeader al_hdr;
798 
799  currhdr = (const struct GNUNET_MessageHeader *) &msg[1];
800  /* ensure aligned access */
801  memcpy (&al_hdr, currhdr, sizeof(al_hdr));
802  if ((tsize < sizeof(struct GNUNET_MessageHeader)) ||
803  (tsize != ntohs (al_hdr.size)))
804  {
805  GNUNET_break_op (0);
806  return;
807  }
809  &msg->sender,
810  currhdr,
813  NULL);
814  if (GNUNET_SYSERR == ret)
815  {
817  "Transport not up!\n");
818  return; /* transport not up */
819  }
820  if (GNUNET_NO == ret)
821  {
823  "Error sending message to transport\n");
824  return;
825  }
827  }
829  {
831  "Back pressure %llu\n", delivering_messages);
832 
833  /* we should try to apply 'back pressure' */
834  GNUNET_SCHEDULER_cancel (read_task);
835  read_task = NULL;
836  }
837 }
838 
839 
857 static int
858 mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
859 {
860  struct Queue *queue;
861  const char *path;
862  struct sockaddr_un *un;
863  socklen_t un_len;
864 
865  (void) cls;
866  if (0 != strncmp (address,
868  strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
869  {
870  GNUNET_break_op (0);
871  return GNUNET_SYSERR;
872  }
873  path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
874  un = unix_address_to_sockaddr (path, &un_len);
875  queue = lookup_queue (peer, un, un_len);
876  if (NULL != queue)
877  {
879  "Address `%s' for %s ignored, queue exists\n",
880  path,
881  GNUNET_i2s (peer));
882  GNUNET_free (un);
883  return GNUNET_OK;
884  }
885  queue = setup_queue (peer, GNUNET_TRANSPORT_CS_OUTBOUND, un, un_len);
886  GNUNET_free (un);
887  if (NULL == queue)
888  {
890  "Failed to setup queue to %s at `%s'\n",
891  GNUNET_i2s (peer),
892  path);
893  return GNUNET_NO;
894  }
895  return GNUNET_OK;
896 }
897 
898 
907 static int
909  const struct GNUNET_PeerIdentity *target,
910  void *value)
911 {
912  struct Queue *queue = value;
913 
914  (void) cls;
915  (void) target;
916  queue_destroy (queue);
917  return GNUNET_OK;
918 }
919 
920 
926 static void
927 do_shutdown (void *cls)
928 {
929  if (NULL != read_task)
930  {
931  GNUNET_SCHEDULER_cancel (read_task);
932  read_task = NULL;
933  }
934  if (NULL != write_task)
935  {
936  GNUNET_SCHEDULER_cancel (write_task);
937  write_task = NULL;
938  }
939  if (NULL != unix_sock)
940  {
942  unix_sock = NULL;
943  }
946  if (NULL != ai)
947  {
949  ai = NULL;
950  }
951  if (NULL != ch)
952  {
954  ch = NULL;
955  }
956  if (NULL != stats)
957  {
959  stats = NULL;
960  }
961 }
962 
963 
975 static void
976 enc_notify_cb (void *cls,
977  const struct GNUNET_PeerIdentity *sender,
978  const struct GNUNET_MessageHeader *msg)
979 {
980  (void) cls;
981  (void) sender;
982  (void) msg;
983  GNUNET_break_op (0);
984 }
985 
986 
995 static void
996 run (void *cls,
997  char *const *args,
998  const char *cfgfile,
999  const struct GNUNET_CONFIGURATION_Handle *cfg)
1000 {
1001  char *unix_socket_path;
1002  struct sockaddr_un *un;
1003  socklen_t un_len;
1004  char *my_addr;
1006 
1007  (void) cls;
1008  delivering_messages = 0;
1009 
1011  if (NULL == my_private_key)
1012  {
1013  GNUNET_log (
1015  _ (
1016  "UNIX communicator is lacking key configuration settings. Exiting.\n"));
1018  return;
1019  }
1021 
1022  if (GNUNET_OK !=
1025  "UNIXPATH",
1026  &unix_socket_path))
1027  {
1030  "UNIXPATH");
1031  return;
1032  }
1033  if (GNUNET_OK !=
1036  "MAX_QUEUE_LENGTH",
1037  &max_queue_length))
1039 
1040  un = unix_address_to_sockaddr (unix_socket_path, &un_len);
1041  if (NULL == un)
1042  {
1044  "Failed to setup UNIX domain socket address with path `%s'\n",
1045  unix_socket_path);
1046  GNUNET_free (unix_socket_path);
1047  return;
1048  }
1049  unix_sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_DGRAM, 0);
1050  if (NULL == unix_sock)
1051  {
1053  GNUNET_free (un);
1054  GNUNET_free (unix_socket_path);
1055  return;
1056  }
1057  if (('\0' != un->sun_path[0]) &&
1059  {
1061  _ ("Cannot create path to `%s'\n"),
1062  un->sun_path);
1063  GNUNET_NETWORK_socket_close (unix_sock);
1064  unix_sock = NULL;
1065  GNUNET_free (un);
1066  GNUNET_free (unix_socket_path);
1067  return;
1068  }
1069  if (GNUNET_OK != GNUNET_NETWORK_socket_bind (unix_sock,
1070  (const struct sockaddr *) un,
1071  un_len))
1072  {
1073  GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "bind", un->sun_path);
1074  GNUNET_NETWORK_socket_close (unix_sock);
1075  unix_sock = NULL;
1076  GNUNET_free (un);
1077  GNUNET_free (unix_socket_path);
1078  return;
1079  }
1080  GNUNET_free (un);
1081  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Bound to `%s'\n", unix_socket_path);
1082  stats = GNUNET_STATISTICS_create ("C-UNIX", cfg);
1085  unix_sock,
1086  &select_read_cb,
1087  NULL);
1093  &mq_init,
1094  NULL,
1095  &enc_notify_cb,
1096  NULL);
1097  if (NULL == ch)
1098  {
1099  GNUNET_break (0);
1101  GNUNET_free (unix_socket_path);
1102  return;
1103  }
1104  GNUNET_asprintf (&my_addr,
1105  "%s-%s",
1107  unix_socket_path);
1108  GNUNET_free (unix_socket_path);
1110  my_addr,
1113  GNUNET_free (my_addr);
1114 }
1115 
1116 
1124 int
1125 main (int argc, char *const *argv)
1126 {
1127  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1129  };
1130  int ret;
1131 
1132  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1133  return 2;
1134 
1135  ret = (GNUNET_OK ==
1136  GNUNET_PROGRAM_run (argc,
1137  argv,
1138  "gnunet-communicator-unix",
1139  _ ("GNUnet UNIX domain socket communicator"),
1140  options,
1141  &run,
1142  NULL))
1143  ? 0
1144  : 1;
1145  GNUNET_free_nz ((void *) argv);
1146  return ret;
1147 }
1148 
1149 
1150 #if defined(__linux__) && defined(__GLIBC__)
1151 #include <malloc.h>
1152 
1156 void __attribute__ ((constructor))
1157 GNUNET_ARM_memory_init ()
1158 {
1159  mallopt (M_TRIM_THRESHOLD, 4 * 1024);
1160  mallopt (M_TOP_PAD, 1 * 1024);
1161  malloc_trim (0);
1162 }
1163 
1164 
1165 #endif
1166 
1167 /* 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:1331
#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:1459
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:1588
#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_memdup(buf, size)
Allocate and initialize a block of memory.
#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:531
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:184
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 (!) ...
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:1269
#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:565
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:702
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.
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_free_nz(ptr)
Wrapper around free.
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.
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 *
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, uint64_t q_len, uint32_t priority, 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...
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:193
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...
#define GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED
Queue length.
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:372
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:837
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:1517
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:499
#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:972