GNUnet  0.10.x
gnunet-communicator-unix.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2010-2014, 2018 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19 */
20 
29 #include "platform.h"
30 #include "gnunet_util_lib.h"
31 #include "gnunet_protocols.h"
32 #include "gnunet_constants.h"
33 #include "gnunet_nt_lib.h"
36 
45 #define DEFAULT_MAX_QUEUE_LENGTH 8
46 
50 #define COMMUNICATOR_ADDRESS_PREFIX "unix"
51 
55 #define COMMUNICATOR_CONFIG_SECTION "communicator-unix"
56 
60 #define UNIX_MTU UINT16_MAX
61 
63 
68 {
73 
78 };
79 
81 
82 
86 struct Queue
87 {
88 
92  struct Queue *next;
93 
97  struct Queue *prev;
98 
102  struct GNUNET_PeerIdentity target;
103 
107  struct sockaddr_un *address;
108 
112  socklen_t address_len;
113 
118  const struct GNUNET_MessageHeader *msg;
119 
123  struct GNUNET_MQ_Handle *mq;
124 
128  struct GNUNET_TRANSPORT_QueueHandle *qh;
129 
133  unsigned long long bytes_in_queue;
134 
139 
144 };
145 
146 
151 
156 
160 static unsigned long long delivering_messages;
161 
165 static unsigned long long max_queue_length;
166 
171 
176 
181 
185 static struct Queue *queue_head;
186 
190 static struct Queue *queue_tail;
191 
196 
201 
202 
210 static void
212 {
213  struct GNUNET_MQ_Handle *mq;
214 
216  "Disconnecting queue for peer `%s'\n",
217  GNUNET_i2s (&queue->target));
218  if (0 != queue->bytes_in_queue)
219  {
220  GNUNET_CONTAINER_DLL_remove (queue_head, queue_tail, queue);
221  queue->bytes_in_queue = 0;
222  }
223  if (NULL != (mq = queue->mq))
224  {
225  queue->mq = NULL;
226  GNUNET_MQ_destroy (mq);
227  }
228  GNUNET_assert (
229  GNUNET_YES ==
230  GNUNET_CONTAINER_multipeermap_remove (queue_map, &queue->target, queue));
231  GNUNET_STATISTICS_set (stats,
232  "# queues active",
234  GNUNET_NO);
235  if (NULL != queue->timeout_task)
236  {
238  queue->timeout_task = NULL;
239  }
240  GNUNET_free (queue->address);
241  GNUNET_free (queue);
242 }
243 
244 
250 static void
251 queue_timeout (void *cls)
252 {
253  struct Queue *queue = cls;
254  struct GNUNET_TIME_Relative left;
255 
256  queue->timeout_task = NULL;
258  if (0 != left.rel_value_us)
259  {
260  /* not actually our turn yet, but let's at least update
261  the monitor, it may think we're about to die ... */
262  queue->timeout_task =
264  return;
265  }
267  "Queue %p was idle for %s, disconnecting\n",
268  queue,
271  GNUNET_YES));
272  queue_destroy (queue);
273 }
274 
275 
283 static void
285 {
286  GNUNET_assert (NULL != queue->timeout_task);
287  queue->timeout =
289 }
290 
291 
300 static struct sockaddr_un *
301 unix_address_to_sockaddr (const char *unixpath, socklen_t *sock_len)
302 {
303  struct sockaddr_un *un;
304  size_t slen;
305 
306  GNUNET_assert (0 < strlen (unixpath)); /* sanity check */
307  un = GNUNET_new (struct sockaddr_un);
308  un->sun_family = AF_UNIX;
309  slen = strlen (unixpath);
310  if (slen >= sizeof (un->sun_path))
311  slen = sizeof (un->sun_path) - 1;
312  GNUNET_memcpy (un->sun_path, unixpath, slen);
313  un->sun_path[slen] = '\0';
314  slen = sizeof (struct sockaddr_un);
315 #if HAVE_SOCKADDR_UN_SUN_LEN
316  un->sun_len = (u_char) slen;
317 #endif
318  (*sock_len) = slen;
319  if ('@' == un->sun_path[0])
320  un->sun_path[0] = '\0';
321  return un;
322 }
323 
324 
328 struct LookupCtx
329 {
333  struct Queue *res;
334 
338  const struct sockaddr_un *un;
339 
343  socklen_t un_len;
344 };
345 
346 
355 static int
356 lookup_queue_it (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
357 {
358  struct LookupCtx *lctx = cls;
359  struct Queue *queue = value;
360 
361  if ((queue->address_len = lctx->un_len) &&
362  (0 == memcmp (lctx->un, queue->address, queue->address_len)))
363  {
364  lctx->res = queue;
365  return GNUNET_NO;
366  }
367  return GNUNET_YES;
368 }
369 
370 
378 static struct Queue *
380  const struct sockaddr_un *un,
381  socklen_t un_len)
382 {
383  struct LookupCtx lctx;
384 
385  lctx.un = un;
386  lctx.un_len = un_len;
388  peer,
390  &lctx);
391  return lctx.res;
392 }
393 
394 
401 static void
402 select_write_cb (void *cls)
403 {
404  struct Queue *queue = queue_tail;
405  const struct GNUNET_MessageHeader *msg = queue->msg;
406  size_t msg_size = ntohs (msg->size);
407  ssize_t sent;
408 
409  /* take queue of the ready list */
410  write_task = NULL;
411  GNUNET_CONTAINER_DLL_remove (queue_head, queue_tail, queue);
412  if (NULL != queue_head)
414  unix_sock,
416  NULL);
417 
418  /* send 'msg' */
419  queue->msg = NULL;
421 resend:
422  /* Send the data */
423  sent = GNUNET_NETWORK_socket_sendto (unix_sock,
424  msg,
425  msg_size,
426  (const struct sockaddr *) queue->address,
427  queue->address_len);
429  "UNIX transmitted message to %s (%d/%u: %s)\n",
430  GNUNET_i2s (&queue->target),
431  (int) sent,
432  (unsigned int) msg_size,
433  (sent < 0) ? STRERROR (errno) : "ok");
434  if (-1 != sent)
435  {
437  "# bytes sent",
438  (long long) sent,
439  GNUNET_NO);
440  reschedule_queue_timeout (queue);
441  return; /* all good */
442  }
444  "# network transmission failures",
445  1,
446  GNUNET_NO);
447  switch (errno)
448  {
449  case EAGAIN:
450  case ENOBUFS:
451  /* We should retry later... */
453  return;
454  case EMSGSIZE: {
455  socklen_t size = 0;
456  socklen_t len = sizeof (size);
457 
459  SOL_SOCKET,
460  SO_SNDBUF,
461  &size,
462  &len);
463  if (size > ntohs (msg->size))
464  {
465  /* Buffer is bigger than message: error, no retry
466  * This should never happen!*/
467  GNUNET_break (0);
468  return;
469  }
470  GNUNET_log (
472  "Trying to increase socket buffer size from %u to %u for message size %u\n",
473  (unsigned int) size,
474  (unsigned int) ((msg_size / 1000) + 2) * 1000,
475  (unsigned int) msg_size);
476  size = ((msg_size / 1000) + 2) * 1000;
478  SOL_SOCKET,
479  SO_SNDBUF,
480  &size,
481  sizeof (size)))
482  goto resend; /* Increased buffer size, retry sending */
483  /* Ok, then just try very modest increase */
484  size = msg_size;
486  SOL_SOCKET,
487  SO_SNDBUF,
488  &size,
489  sizeof (size)))
490  goto resend; /* Increased buffer size, retry sending */
491  /* Could not increase buffer size: error, no retry */
493  return;
494  }
495  default:
497  return;
498  }
499 }
500 
501 
510 static void
512  const struct GNUNET_MessageHeader *msg,
513  void *impl_state)
514 {
515  struct Queue *queue = impl_state;
516 
517  GNUNET_assert (mq == queue->mq);
518  GNUNET_assert (NULL == queue->msg);
519  queue->msg = msg;
520  GNUNET_CONTAINER_DLL_insert (queue_head, queue_tail, queue);
521  GNUNET_assert (NULL != unix_sock);
522  if (NULL == write_task)
524  unix_sock,
526  NULL);
527 }
528 
529 
538 static void
539 mq_destroy (struct GNUNET_MQ_Handle *mq, void *impl_state)
540 {
541  struct Queue *queue = impl_state;
542 
543  if (mq == queue->mq)
544  {
545  queue->mq = NULL;
546  queue_destroy (queue);
547  }
548 }
549 
550 
557 static void
558 mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
559 {
560  struct Queue *queue = impl_state;
561 
562  GNUNET_assert (NULL != queue->msg);
563  queue->msg = NULL;
564  GNUNET_CONTAINER_DLL_remove (queue_head, queue_tail, queue);
565  GNUNET_assert (NULL != write_task);
566  if (NULL == queue_head)
567  {
568  GNUNET_SCHEDULER_cancel (write_task);
569  write_task = NULL;
570  }
571 }
572 
573 
583 static void
584 mq_error (void *cls, enum GNUNET_MQ_Error error)
585 {
586  struct Queue *queue = cls;
587 
589  "UNIX MQ error in queue to %s: %d\n",
590  GNUNET_i2s (&queue->target),
591  (int) error);
592  queue_destroy (queue);
593 }
594 
595 
606 static struct Queue *
609  const struct sockaddr_un *un,
610  socklen_t un_len)
611 {
612  struct Queue *queue;
613 
614  queue = GNUNET_new (struct Queue);
615  queue->target = *target;
616  queue->address = GNUNET_memdup (un, un_len);
617  queue->address_len = un_len;
619  queue_map,
620  &queue->target,
621  queue,
623  GNUNET_STATISTICS_set (stats,
624  "# queues active",
626  GNUNET_NO);
627  queue->timeout =
629  queue->timeout_task =
631  &queue_timeout,
632  queue);
634  &mq_destroy,
635  &mq_cancel,
636  queue,
637  NULL,
638  &mq_error,
639  queue);
640  {
641  char *foreign_addr;
642 
643  if ('\0' == un->sun_path[0])
644  GNUNET_asprintf (&foreign_addr,
645  "%s-@%s",
647  &un->sun_path[1]);
648  else
649  GNUNET_asprintf (&foreign_addr,
650  "%s-%s",
652  un->sun_path);
654  &queue->target,
655  foreign_addr,
656  UNIX_MTU,
658  cs,
659  queue->mq);
660  GNUNET_free (foreign_addr);
661  }
662  return queue;
663 }
664 
665 
673 static void
674 select_read_cb (void *cls);
675 
676 
684 static void
685 receive_complete_cb (void *cls, int success)
686 {
687  (void) cls;
689  if (GNUNET_OK != success)
691  "# transport transmission failures",
692  1,
693  GNUNET_NO);
694  GNUNET_assert (NULL != unix_sock);
695  if ((NULL == read_task) && (delivering_messages < max_queue_length))
697  unix_sock,
699  NULL);
700 }
701 
702 
710 static void
711 select_read_cb (void *cls)
712 {
713  char buf[65536] GNUNET_ALIGN;
714  struct Queue *queue;
715  const struct UNIXMessage *msg;
716  struct sockaddr_un un;
717  socklen_t addrlen;
718  ssize_t ret;
719  uint16_t msize;
720 
721  GNUNET_assert (NULL != unix_sock);
723  unix_sock,
725  NULL);
726  addrlen = sizeof (un);
727  memset (&un, 0, sizeof (un));
728  ret = GNUNET_NETWORK_socket_recvfrom (unix_sock,
729  buf,
730  sizeof (buf),
731  (struct sockaddr *) &un,
732  &addrlen);
733  if ((-1 == ret) && ((EAGAIN == errno) || (ENOBUFS == errno)))
734  return;
735  if (-1 == ret)
736  {
738  return;
739  }
741  "Read %d bytes from socket %s\n",
742  (int) ret,
743  un.sun_path);
744  GNUNET_assert (AF_UNIX == (un.sun_family));
745  msg = (struct UNIXMessage *) buf;
746  msize = ntohs (msg->header.size);
747  if ((msize < sizeof (struct UNIXMessage)) || (msize > ret))
748  {
749  GNUNET_break_op (0);
750  return;
751  }
752  queue = lookup_queue (&msg->sender, &un, addrlen);
753  if (NULL == queue)
754  queue =
755  setup_queue (&msg->sender, GNUNET_TRANSPORT_CS_INBOUND, &un, addrlen);
756  else
757  reschedule_queue_timeout (queue);
758  if (NULL == queue)
759  {
760  GNUNET_log (
762  _ (
763  "Maximum number of UNIX connections exceeded, dropping incoming message\n"));
764  return;
765  }
766 
767  {
768  uint16_t offset = 0;
769  uint16_t tsize = msize - sizeof (struct UNIXMessage);
770  const char *msgbuf = (const char *) &msg[1];
771 
772  while (offset + sizeof (struct GNUNET_MessageHeader) <= tsize)
773  {
774  const struct GNUNET_MessageHeader *currhdr;
775  struct GNUNET_MessageHeader al_hdr;
776  uint16_t csize;
777 
778  currhdr = (const struct GNUNET_MessageHeader *) &msgbuf[offset];
779  /* ensure aligned access */
780  memcpy (&al_hdr, currhdr, sizeof (al_hdr));
781  csize = ntohs (al_hdr.size);
782  if ((csize < sizeof (struct GNUNET_MessageHeader)) ||
783  (csize > tsize - offset))
784  {
785  GNUNET_break_op (0);
786  break;
787  }
789  &msg->sender,
790  currhdr,
793  NULL);
794  if (GNUNET_SYSERR == ret)
795  return; /* transport not up */
796  if (GNUNET_NO == ret)
797  break;
799  offset += csize;
800  }
801  }
803  {
804  /* we should try to apply 'back pressure' */
805  GNUNET_SCHEDULER_cancel (read_task);
806  read_task = NULL;
807  }
808 }
809 
810 
828 static int
829 mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
830 {
831  struct Queue *queue;
832  const char *path;
833  struct sockaddr_un *un;
834  socklen_t un_len;
835 
836  (void) cls;
837  if (0 != strncmp (address,
839  strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
840  {
841  GNUNET_break_op (0);
842  return GNUNET_SYSERR;
843  }
844  path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
845  un = unix_address_to_sockaddr (path, &un_len);
846  queue = lookup_queue (peer, un, un_len);
847  if (NULL != queue)
848  {
850  "Address `%s' for %s ignored, queue exists\n",
851  path,
852  GNUNET_i2s (peer));
853  GNUNET_free (un);
854  return GNUNET_OK;
855  }
856  queue = setup_queue (peer, GNUNET_TRANSPORT_CS_OUTBOUND, un, un_len);
857  GNUNET_free (un);
858  if (NULL == queue)
859  {
861  "Failed to setup queue to %s at `%s'\n",
862  GNUNET_i2s (peer),
863  path);
864  return GNUNET_NO;
865  }
866  return GNUNET_OK;
867 }
868 
869 
878 static int
880  const struct GNUNET_PeerIdentity *target,
881  void *value)
882 {
883  struct Queue *queue = value;
884 
885  (void) cls;
886  (void) target;
887  queue_destroy (queue);
888  return GNUNET_OK;
889 }
890 
891 
897 static void
898 do_shutdown (void *cls)
899 {
900  if (NULL != read_task)
901  {
902  GNUNET_SCHEDULER_cancel (read_task);
903  read_task = NULL;
904  }
905  if (NULL != write_task)
906  {
907  GNUNET_SCHEDULER_cancel (write_task);
908  write_task = NULL;
909  }
910  if (NULL != unix_sock)
911  {
913  unix_sock = NULL;
914  }
917  if (NULL != ai)
918  {
920  ai = NULL;
921  }
922  if (NULL != ch)
923  {
925  ch = NULL;
926  }
927  if (NULL != stats)
928  {
930  stats = NULL;
931  }
932 }
933 
934 
946 static void
947 enc_notify_cb (void *cls,
948  const struct GNUNET_PeerIdentity *sender,
949  const struct GNUNET_MessageHeader *msg)
950 {
951  (void) cls;
952  (void) sender;
953  (void) msg;
954  GNUNET_break_op (0);
955 }
956 
957 
966 static void
967 run (void *cls,
968  char *const *args,
969  const char *cfgfile,
970  const struct GNUNET_CONFIGURATION_Handle *cfg)
971 {
972  char *unix_socket_path;
973  struct sockaddr_un *un;
974  socklen_t un_len;
975  char *my_addr;
976  (void) cls;
977 
978  if (GNUNET_OK !=
981  "UNIXPATH",
982  &unix_socket_path))
983  {
986  "UNIXPATH");
987  return;
988  }
989  if (GNUNET_OK !=
992  "MAX_QUEUE_LENGTH",
995 
996  un = unix_address_to_sockaddr (unix_socket_path, &un_len);
997  if (NULL == un)
998  {
1000  "Failed to setup UNIX domain socket address with path `%s'\n",
1001  unix_socket_path);
1002  GNUNET_free (unix_socket_path);
1003  return;
1004  }
1005  unix_sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_DGRAM, 0);
1006  if (NULL == unix_sock)
1007  {
1009  GNUNET_free (un);
1010  GNUNET_free (unix_socket_path);
1011  return;
1012  }
1013  if (('\0' != un->sun_path[0]) &&
1015  {
1017  _ ("Cannot create path to `%s'\n"),
1018  un->sun_path);
1019  GNUNET_NETWORK_socket_close (unix_sock);
1020  unix_sock = NULL;
1021  GNUNET_free (un);
1022  GNUNET_free (unix_socket_path);
1023  return;
1024  }
1025  if (GNUNET_OK != GNUNET_NETWORK_socket_bind (unix_sock,
1026  (const struct sockaddr *) un,
1027  un_len))
1028  {
1029  GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "bind", un->sun_path);
1030  GNUNET_NETWORK_socket_close (unix_sock);
1031  unix_sock = NULL;
1032  GNUNET_free (un);
1033  GNUNET_free (unix_socket_path);
1034  return;
1035  }
1036  GNUNET_free (un);
1037  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Bound to `%s'\n", unix_socket_path);
1038  stats = GNUNET_STATISTICS_create ("C-UNIX", cfg);
1041  unix_sock,
1042  &select_read_cb,
1043  NULL);
1049  &mq_init,
1050  NULL,
1051  &enc_notify_cb,
1052  NULL);
1053  if (NULL == ch)
1054  {
1055  GNUNET_break (0);
1057  GNUNET_free (unix_socket_path);
1058  return;
1059  }
1060  GNUNET_asprintf (&my_addr,
1061  "%s-%s",
1063  unix_socket_path);
1064  GNUNET_free (unix_socket_path);
1066  my_addr,
1069  GNUNET_free (my_addr);
1070 }
1071 
1072 
1080 int
1081 main (int argc, char *const *argv)
1082 {
1083  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1085  int ret;
1086 
1087  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1088  return 2;
1089 
1090  ret = (GNUNET_OK ==
1091  GNUNET_PROGRAM_run (argc,
1092  argv,
1093  "gnunet-communicator-unix",
1094  _ ("GNUnet UNIX domain socket communicator"),
1095  options,
1096  &run,
1097  NULL))
1098  ? 0
1099  : 1;
1100  GNUNET_free ((void *) argv);
1101  return ret;
1102 }
1103 
1104 
1105 #if defined(LINUX) && defined(__GLIBC__)
1106 #include <malloc.h>
1107 
1111 void __attribute__ ((constructor)) GNUNET_ARM_memory_init ()
1112 {
1113  mallopt (M_TRIM_THRESHOLD, 4 * 1024);
1114  mallopt (M_TOP_PAD, 1 * 1024);
1115  malloc_trim (0);
1116 }
1117 #endif
1118 
1119 /* 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:1005
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.
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:1293
#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:1521
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:245
static struct GNUNET_SCHEDULER_Task * write_task
ID of write task.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define STRERROR(i)
Definition: plibc.h:676
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:763
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:522
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:1548
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:833
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:81
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Definition of a command line option.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:524
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).
static int ret
Final status code.
Definition: gnunet-arm.c:89
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:208
void GNUNET_TRANSPORT_communicator_disconnect(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Disconnect from the transport service.
#define UNIX_MTU
Our MTU.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
static void enc_notify_cb(void *cls, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg)
Function called when the transport service has received an acknowledgement for this communicator (!) ...
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1246
#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
User defined timestamp for completing operations.
Definition: gnunet-arm.c:114
struct GNUNET_MQ_Handle * GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send, GNUNET_MQ_DestroyImpl destroy, GNUNET_MQ_CancelImpl cancel, void *impl_state, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *cls)
Create a message queue for the specified handlers.
Definition: mq.c:552
static unsigned int csize
#define GNUNET_memcpy(dst, src, n)
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:727
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:968
struct sockaddr_un * address
Address of the other peer.
static char buf[2048]
struct GNUNET_TRANSPORT_CommunicatorHandle * GNUNET_TRANSPORT_communicator_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section_name, const char *addr_prefix, enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc, GNUNET_TRANSPORT_CommunicatorMqInit mq_init, void *mq_init_cls, GNUNET_TRANSPORT_CommunicatorNotify notify_cb, void *notify_cb_cls)
Connect to the transport service.
this is an inbound connection (communicator initiated)
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
static void select_write_cb(void *cls)
We have been notified that our socket is ready to write.
Internal representation of the hash map.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
static void mq_destroy(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
const struct sockaddr_un * un
Address we are looking for.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
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:79
static unsigned int size
Size of the "table".
Definition: peer.c:67
static struct GNUNET_TRANSPORT_AddressIdentifier * ai
Handle to the operation that publishes our address.
static struct sockaddr_un * unix_address_to_sockaddr(const char *unixpath, socklen_t *sock_len)
Convert unix path to a struct sockaddr_un *
Loopback (same host).
Definition: gnunet_nt_lib.h:45
const struct GNUNET_MessageHeader * msg
Message currently scheduled for transmission, non-NULL if and only if this queue is in the queue_head...
static void queue_timeout(void *cls)
Queue was idle for too long, so disconnect it.
int GNUNET_TRANSPORT_communicator_receive(struct GNUNET_TRANSPORT_CommunicatorHandle *handle, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg, struct GNUNET_TIME_Relative expected_addr_validity, GNUNET_TRANSPORT_MessageCompletedCallback cb, void *cb_cls)
Notify transport service that the communicator has received a message.
Allow multiple values with the same key.
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don&#39;t receive messages from the peer...
Handle to a message queue.
Definition: mq.c:85
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32;.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
static struct Queue * setup_queue(const struct GNUNET_PeerIdentity *target, enum GNUNET_TRANSPORT_ConnectionStatus cs, const struct sockaddr_un *un, socklen_t un_len)
Creates a new outbound queue the transport service will use to send data to another peer...
enum RadiotapType __attribute__
The identity of the host (wraps the signing key of the peer).
struct sockaddr * address
Address of the other peer.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to &#39;struct&#39;s...
static struct GNUNET_CONTAINER_MultiPeerMap * queue_map
Queues (map from peer identity to struct Queue)
configuration data
Definition: configuration.c:85
struct Queue * prev
Queues with pending messages (!) are kept in a DLL.
this is an outbound connection (transport initiated)
static struct GNUNET_NETWORK_Handle * unix_sock
socket that we transmit all data with
enum GNUNET_TRANSPORT_ConnectionStatus cs
Connection status for this queue.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
struct Queue * res
Location to store the queue, if found.
int GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
handle to a socket
Definition: network.c:46
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:361
static void mq_error(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:824
#define GNUNET_YES
Definition: gnunet_common.h:80
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:1478
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:856
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:604
int GNUNET_CONTAINER_multipeermap_get_multiple(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map that match a particular key.
static void receive_complete_cb(void *cls, int success)
Function called when message was successfully passed to transport service.
static unsigned long long delivering_messages
Number of messages we currently have in our queues towards the transport service. ...
static struct Queue * lookup_queue(const struct GNUNET_PeerIdentity *peer, const struct sockaddr_un *un, socklen_t un_len)
Find an existing queue by address.
Internal representation of an address a communicator is currently providing for the transport service...
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:1037
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965