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 UNIXMessage),
678  0,
680  cs,
681  queue->mq);
682  GNUNET_free (foreign_addr);
683  }
684  return queue;
685 }
686 
687 
695 static void
696 select_read_cb (void *cls);
697 
698 
706 static void
707 receive_complete_cb (void *cls, int success)
708 {
709  (void) cls;
711  if (GNUNET_OK != success)
713  "# transport transmission failures",
714  1,
715  GNUNET_NO);
716  if ((NULL == read_task) && (delivering_messages < max_queue_length) &&
717  (NULL != unix_sock))
719  unix_sock,
721  NULL);
722 }
723 
724 
732 static void
733 select_read_cb (void *cls)
734 {
735  char buf[65536] GNUNET_ALIGN;
736  struct Queue *queue;
737  const struct UNIXMessage *msg;
738  struct sockaddr_un un;
739  socklen_t addrlen;
740  ssize_t ret;
741  uint16_t msize;
742 
743  GNUNET_assert (NULL != unix_sock);
745  unix_sock,
747  NULL);
748  addrlen = sizeof(un);
749  memset (&un, 0, sizeof(un));
750  ret = GNUNET_NETWORK_socket_recvfrom (unix_sock,
751  buf,
752  sizeof(buf),
753  (struct sockaddr *) &un,
754  &addrlen);
755  if ((-1 == ret) && ((EAGAIN == errno) || (ENOBUFS == errno)))
756  return;
757  if (-1 == ret)
758  {
760  return;
761  }
763  "Read %d bytes from socket %s\n",
764  (int) ret,
765  un.sun_path);
766  GNUNET_assert (AF_UNIX == (un.sun_family));
767  msg = (struct UNIXMessage *) buf;
768  msize = ntohs (msg->header.size);
769  if ((msize < sizeof(struct UNIXMessage)) || (msize > ret))
770  {
772  "Wrong message size: %d bytes\n",
773  msize);
774  GNUNET_break_op (0);
775  return;
776  }
777  queue = lookup_queue (&msg->sender, &un, addrlen);
778  if (NULL == queue)
779  queue =
780  setup_queue (&msg->sender, GNUNET_TRANSPORT_CS_INBOUND, &un, addrlen);
781  else
782  reschedule_queue_timeout (queue);
783  if (NULL == queue)
784  {
785  GNUNET_log (
787  _ (
788  "Maximum number of UNIX connections exceeded, dropping incoming message\n"));
789  return;
790  }
791 
792  {
793  uint16_t tsize = msize - sizeof(struct UNIXMessage);
794 
795  const struct GNUNET_MessageHeader *currhdr;
796  struct GNUNET_MessageHeader al_hdr;
797 
798  currhdr = (const struct GNUNET_MessageHeader *) &msg[1];
799  /* ensure aligned access */
800  memcpy (&al_hdr, currhdr, sizeof(al_hdr));
801  if ((tsize < sizeof(struct GNUNET_MessageHeader)) ||
802  (tsize != ntohs(al_hdr.size)))
803  {
804  GNUNET_break_op (0);
805  return;
806  }
808  &msg->sender,
809  currhdr,
812  NULL);
813  if (GNUNET_SYSERR == ret)
814  {
816  "Transport not up!\n");
817  return; /* transport not up */
818  }
819  if (GNUNET_NO == ret)
820  {
822  "Error sending message to transport\n");
823  return;
824  }
826  }
828  {
830  "Back pressure %llu\n", delivering_messages);
831 
832  /* we should try to apply 'back pressure' */
833  GNUNET_SCHEDULER_cancel (read_task);
834  read_task = NULL;
835  }
836 }
837 
838 
856 static int
857 mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
858 {
859  struct Queue *queue;
860  const char *path;
861  struct sockaddr_un *un;
862  socklen_t un_len;
863 
864  (void) cls;
865  if (0 != strncmp (address,
867  strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
868  {
869  GNUNET_break_op (0);
870  return GNUNET_SYSERR;
871  }
872  path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
873  un = unix_address_to_sockaddr (path, &un_len);
874  queue = lookup_queue (peer, un, un_len);
875  if (NULL != queue)
876  {
878  "Address `%s' for %s ignored, queue exists\n",
879  path,
880  GNUNET_i2s (peer));
881  GNUNET_free (un);
882  return GNUNET_OK;
883  }
884  queue = setup_queue (peer, GNUNET_TRANSPORT_CS_OUTBOUND, un, un_len);
885  GNUNET_free (un);
886  if (NULL == queue)
887  {
889  "Failed to setup queue to %s at `%s'\n",
890  GNUNET_i2s (peer),
891  path);
892  return GNUNET_NO;
893  }
894  return GNUNET_OK;
895 }
896 
897 
906 static int
908  const struct GNUNET_PeerIdentity *target,
909  void *value)
910 {
911  struct Queue *queue = value;
912 
913  (void) cls;
914  (void) target;
915  queue_destroy (queue);
916  return GNUNET_OK;
917 }
918 
919 
925 static void
926 do_shutdown (void *cls)
927 {
928  if (NULL != read_task)
929  {
930  GNUNET_SCHEDULER_cancel (read_task);
931  read_task = NULL;
932  }
933  if (NULL != write_task)
934  {
935  GNUNET_SCHEDULER_cancel (write_task);
936  write_task = NULL;
937  }
938  if (NULL != unix_sock)
939  {
941  unix_sock = NULL;
942  }
945  if (NULL != ai)
946  {
948  ai = NULL;
949  }
950  if (NULL != ch)
951  {
953  ch = NULL;
954  }
955  if (NULL != stats)
956  {
958  stats = NULL;
959  }
960 }
961 
962 
974 static void
975 enc_notify_cb (void *cls,
976  const struct GNUNET_PeerIdentity *sender,
977  const struct GNUNET_MessageHeader *msg)
978 {
979  (void) cls;
980  (void) sender;
981  (void) msg;
982  GNUNET_break_op (0);
983 }
984 
985 
994 static void
995 run (void *cls,
996  char *const *args,
997  const char *cfgfile,
998  const struct GNUNET_CONFIGURATION_Handle *cfg)
999 {
1000  char *unix_socket_path;
1001  struct sockaddr_un *un;
1002  socklen_t un_len;
1003  char *my_addr;
1005 
1006  (void) cls;
1007  delivering_messages = 0;
1008 
1010  if (NULL == my_private_key)
1011  {
1012  GNUNET_log (
1014  _ (
1015  "UNIX communicator is lacking key configuration settings. Exiting.\n"));
1017  return;
1018  }
1020 
1021  if (GNUNET_OK !=
1024  "UNIXPATH",
1025  &unix_socket_path))
1026  {
1029  "UNIXPATH");
1030  return;
1031  }
1032  if (GNUNET_OK !=
1035  "MAX_QUEUE_LENGTH",
1036  &max_queue_length))
1038 
1039  un = unix_address_to_sockaddr (unix_socket_path, &un_len);
1040  if (NULL == un)
1041  {
1043  "Failed to setup UNIX domain socket address with path `%s'\n",
1044  unix_socket_path);
1045  GNUNET_free (unix_socket_path);
1046  return;
1047  }
1048  unix_sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_DGRAM, 0);
1049  if (NULL == unix_sock)
1050  {
1052  GNUNET_free (un);
1053  GNUNET_free (unix_socket_path);
1054  return;
1055  }
1056  if (('\0' != un->sun_path[0]) &&
1058  {
1060  _ ("Cannot create path to `%s'\n"),
1061  un->sun_path);
1062  GNUNET_NETWORK_socket_close (unix_sock);
1063  unix_sock = NULL;
1064  GNUNET_free (un);
1065  GNUNET_free (unix_socket_path);
1066  return;
1067  }
1068  if (GNUNET_OK != GNUNET_NETWORK_socket_bind (unix_sock,
1069  (const struct sockaddr *) un,
1070  un_len))
1071  {
1072  GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "bind", un->sun_path);
1073  GNUNET_NETWORK_socket_close (unix_sock);
1074  unix_sock = NULL;
1075  GNUNET_free (un);
1076  GNUNET_free (unix_socket_path);
1077  return;
1078  }
1079  GNUNET_free (un);
1080  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Bound to `%s'\n", unix_socket_path);
1081  stats = GNUNET_STATISTICS_create ("C-UNIX", cfg);
1084  unix_sock,
1085  &select_read_cb,
1086  NULL);
1092  &mq_init,
1093  NULL,
1094  &enc_notify_cb,
1095  NULL);
1096  if (NULL == ch)
1097  {
1098  GNUNET_break (0);
1100  GNUNET_free (unix_socket_path);
1101  return;
1102  }
1103  GNUNET_asprintf (&my_addr,
1104  "%s-%s",
1106  unix_socket_path);
1107  GNUNET_free (unix_socket_path);
1109  my_addr,
1112  GNUNET_free (my_addr);
1113 }
1114 
1115 
1123 int
1124 main (int argc, char *const *argv)
1125 {
1126  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1128  };
1129  int ret;
1130 
1131  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1132  return 2;
1133 
1134  ret = (GNUNET_OK ==
1135  GNUNET_PROGRAM_run (argc,
1136  argv,
1137  "gnunet-communicator-unix",
1138  _ ("GNUnet UNIX domain socket communicator"),
1139  options,
1140  &run,
1141  NULL))
1142  ? 0
1143  : 1;
1144  GNUNET_free_nz ((void *) argv);
1145  return ret;
1146 }
1147 
1148 
1149 #if defined(__linux__) && defined(__GLIBC__)
1150 #include <malloc.h>
1151 
1155 void __attribute__ ((constructor))
1156 GNUNET_ARM_memory_init ()
1157 {
1158  mallopt (M_TRIM_THRESHOLD, 4 * 1024);
1159  mallopt (M_TOP_PAD, 1 * 1024);
1160  malloc_trim (0);
1161 }
1162 
1163 
1164 #endif
1165 
1166 /* 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:1457
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 (!) ...
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: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:561
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:701
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.
#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: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:833
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:495
#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