GNUnet 0.25.2-11-g84e94e98c
 
Loading...
Searching...
No Matches
gnunet_core_underlay_dummy.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2023 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 */
37// TODO actually implement rate-limiting
38
39#ifdef __cplusplus
40extern "C" {
41#if 0 /* keep Emacsens' auto-indent happy */
42}
43#endif
44#endif
45
46
47#include <unistd.h>
48#include <errno.h>
49#include <string.h>
50#include <inttypes.h>
52#include "gnunet_util_lib.h"
54
55#define LOG(kind, ...) GNUNET_log_from (kind, "core-underlay-dummy", __VA_ARGS__ \
56 )
57
58#define SOCK_NAME_BASE "/tmp/gnunet-core-underlay-dummy-socket"
59#define SOCK_EXTENSION ".sock"
60#define BUFF_SIZE 8192
61#define BACKLOG 10
62
63
94
95
103
104
106{
107 /* Created, but neither received, nor sent anything over it */
109
110 /* Created and successfully sent something (probably init) */
112
113 /* Created and successfully received something (probably init) */
115
116 /* Live - usable - successfully received and sent something (probably init) */
118
119 /* In the process of destruction */
121};
122
123
225
226
313
314
315static const char *
317{
318 switch (status)
319 {
321 return "C_INITIALIZING";
322 break;
324 return "C_INITIALIZING_SEND";
325 break;
327 return "C_INITIALIZING_RECV";
328 break;
329 case CONNECTION_LIVE:
330 return "C_LIVE";
331 break;
333 return "C_DESTROY";
334 break;
335 }
336 return ""; /* Make compiler happy */
337}
338
339
346static void
347do_read (void *cls);
348
349
350/*****************************************************************************
351 * Connection-related functions *
352 ****************************************************************************/
353
362static void
363connection_destroy (struct Connection *connection)
364{
365 /* The mq should already be cleaned as this function is called from within
366 * mq_destroy_impl. */
367 LOG (GNUNET_ERROR_TYPE_DEBUG, "connection_destroy\n");
368 if ((NULL != connection->handle->notify_disconnect) &&
369 (GNUNET_YES == connection->notify_connect_called))
370 {
371 /* Call the notify disconnect only if the notify_connect_task has been
372 * executed and the client was actually notified about the connection */
373 connection->handle->notify_disconnect (connection->handle->cls, /* connection-independant cls */
374 connection->cls_mq); /* connection-specific cls */
375 }
376 if (NULL != connection->notify_connect_task)
377 {
378 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling notify connect task\n");
380 }
381 if (NULL != connection->handle_message_task)
382 {
383 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling handle message task\n");
385 }
386 if (NULL != connection->write_task)
387 {
388 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling write task\n");
390 }
391 if (NULL != connection->recv_task)
392 {
393 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling recv task\n");
395 }
396 if (NULL != connection->sock)
397 {
398 LOG (GNUNET_ERROR_TYPE_DEBUG, "closing socket\n");
399 GNUNET_NETWORK_socket_close (connection->sock);
400 }
401 GNUNET_free (connection->peer_addr);
402 if (NULL != connection->handlers)
403 GNUNET_free (connection->handlers);
404 /* Don't free the cls_mq - we don't own it! */
406 connection->handle->connections_tail,
407 connection);
408 GNUNET_free (connection);
409 LOG (GNUNET_ERROR_TYPE_DEBUG, "connection_destroy - end\n");
410}
411
412
413/*****************************************************************************
414 * Connection-related functions (end) *
415 ****************************************************************************/
416
417
427static void
429 void *handlers_cls)
430{
431 GNUNET_assert (NULL != handlers);
432
433 for (unsigned int i = 0; NULL != handlers[i].cb; i++)
434 handlers[i].cls = handlers_cls;
435}
436
437
438static void
440{
441 struct Connection *connection = cls;
442 struct QueuedMessage *q_msg = connection->queued_recv_messages_head;
443 struct GNUNET_MessageHeader *msg = q_msg->msg;
444
445 connection->handle_message_task = NULL;
448 connection->queued_recv_messages_head,
449 connection->queued_recv_messages_tail,
450 q_msg);
451 GNUNET_free (q_msg);
452 // FIXME check return value!!!
454 connection->handlers,
455 msg);
456 // GNUNET_free (msg); // TODO what do we do with this pointer? Who owns it?
457 // Who cleans it?
458}
459
460
461static void
462check_for_messages (struct Connection *connection)
463{
464 if (NULL != connection->queued_recv_messages_head)
465 {
466 LOG (GNUNET_ERROR_TYPE_DEBUG, "got messages in the queue - handle those\n");
467 GNUNET_assert (NULL == connection->handle_message_task);
468 connection->handle_message_task =
470 }
471 else if (NULL == connection->recv_task)
472 {
474 "no messages in the queue - receive more from socket\n");
475 connection->recv_task =
477 connection->sock,
478 do_read,
479 connection);
480 }
481}
482
483
492static void
494{
495 struct Connection *connection = cls;
496 struct GNUNET_CORE_UNDERLAY_DUMMY_Handle *h = connection->handle;
497 void *cls_mq;
498
499 connection->notify_connect_task = NULL;
500 connection->notify_connect_called = GNUNET_YES;
502 /* The global, connection-independant closure is given to notify_connect,
503 * notify_disconnect and notify_address_change, whereas the
504 * connection-specific cls is the return value of notify_connect and given to
505 * the handlers. */
506 cls_mq =
507 h->notify_connect (h->cls,
508 1,
509 (const char **) &connection->peer_addr,
510 connection->mq,
511 NULL); /* peer_id */
512 /* The handlers are copied because the connection-specific closures can be
513 * set. The global handlers remain the same - they are just called with the
514 * connection specific closures. */
515 connection->handlers = GNUNET_MQ_copy_handlers (h->handlers);
516 set_handlers_closure (connection->handlers, h->cls); /* in case there's no connection-specific closure */
517 if (NULL != cls_mq)
518 {
519 connection->cls_mq = cls_mq;
520 // GNUNET_MQ_set_handlers_closure (connection->mq, connection->cls_mq);
521 /* Overwrite the closure set above with the cls_mq */
522 set_handlers_closure (connection->handlers, connection->cls_mq);
523 }
524
525 /* Handle already enqueued messages */
526 check_for_messages (connection);
527}
528
529
530static void
531try_notify_connect (struct Connection *connection)
532{
533 if ((NULL != connection->peer_addr) &&
534 (CONNECTION_LIVE == connection->status) &&
535 (NULL != connection->handle->notify_connect) &&
536 (NULL == connection->notify_connect_task))
537 {
538 connection->notify_connect_task =
540 }
541}
542
543
544static void
546 struct Connection *connection)
547{
548 struct Connection *c_iter_next;
549 char *peer_addr = connection->peer_addr;
550
552 "Going to cancel all initializing connections to %s\n",
553 peer_addr);
554 if (NULL == peer_addr)
555 return; /* No sense in comparing to unknown address */
556 for (struct Connection *c_iter = h->connections_head;
557 NULL != c_iter;
558 c_iter = c_iter_next)
559 {
560 c_iter_next = c_iter->next;
562 " %s :%s\n",
563 c_iter->peer_addr,
564 status2string (c_iter->status));
565 if ((c_iter != connection) && /* Don't shut down current connection */
566 (NULL != c_iter->peer_addr) && /* No address - can't compare */
567 (0 == strcmp (c_iter->peer_addr, peer_addr)) &&
568 (
569 (CONNECTION_INITIALIZING == c_iter->status) ||
570 (CONNECTION_INITIALIZING_SEND == c_iter->status) ||
571 (CONNECTION_INITIALIZING_RECV == c_iter->status)))
572 {
574 " -> Cancelling connection - MQ_destroy()\n");
575 GNUNET_MQ_destroy (c_iter->mq);
576 }
577 }
578}
579
580
587static void
588do_read (void *cls)
589{
590 struct Connection *connection = cls;
591
592 char buf[65536] GNUNET_ALIGN;
593 ssize_t ret;
595
597 "do_read(): receiving bytes from %s :%s\n",
598 connection->peer_addr,
599 status2string (connection->status));
600 connection->recv_task = NULL;
601 GNUNET_assert (NULL != connection->sock);
602 ret = GNUNET_NETWORK_socket_recv (connection->sock,
603 &buf,
604 sizeof(buf));
605 if (0 > ret)
606 {
607 LOG (GNUNET_ERROR_TYPE_ERROR, "Error reading from socket - MQ_destroy()\n");
608 connection->status = CONNECTION_DESTROY;
609 GNUNET_MQ_destroy (connection->mq); // This triggers mq_destroy_impl()
610 return;
611 }
612 if (0 == ret)
613 {
615 "Other peer closed connection - MQ_destroy()\n");
616 connection->status = CONNECTION_DESTROY;
617 GNUNET_MQ_destroy (connection->mq); // This triggers mq_destroy_impl()
618 return;
619 }
620 LOG (GNUNET_ERROR_TYPE_DEBUG, "Read %d bytes\n", (int) ret);
621 GNUNET_assert (2 <= ret); /* has to have returned enough for one full msg_hdr */
622
623 /* Handle the message itself */
624 {
625 ssize_t ret_remain;
626 char *buf_iter;
627 struct GNUNET_MessageHeader *msg_iter;
628
629 msg = (struct GNUNET_MessageHeader *) buf;
630 ret_remain = ret;
631 buf_iter = buf;
632 /* Just debug logging */
633 while (0 < ret_remain)
634 {
635 msg_iter = (struct GNUNET_MessageHeader *) buf_iter;
636 LOG (GNUNET_ERROR_TYPE_DEBUG, "Length of message: %d bytes\n", ntohs (
637 msg_iter->size));
638 LOG (GNUNET_ERROR_TYPE_DEBUG, "Remaining bytes of buffer: %ld\n",
639 ret_remain);
640
641 {
642 // XXX only for debugging purposes
643 // this shows everything works as expected
644
645 struct GNUNET_UNDERLAY_DUMMY_Message
646 {
647 struct GNUNET_MessageHeader header;
648 // The following will be used for debugging
649 uint64_t id; // id of the message
650 uint64_t batch; // first batch of that peer (for this test 0 or 1)
651 // uint64_t peer; // number of sending peer (for this test 0 or 1)
652 };
653
654
655 struct GNUNET_UNDERLAY_DUMMY_Message *msg_dbg =
656 (struct GNUNET_UNDERLAY_DUMMY_Message *) msg_iter;
657 // LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - id: %u, batch: %u, peer: %u\n",
658 LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - id: %" PRIu64
659 ", batch: %" PRIu64 "\n",
660 GNUNET_ntohll (msg_dbg->id),
661 GNUNET_ntohll (msg_dbg->batch));
662 // LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - size: %u\n",
663 // ntohs (msg_dbg->size));
664 // LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - (sanity) size msghdr: %u\n",
665 // sizeof (struct GNUNET_MessageHeader));
666 // LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - (sanity) size msg field: %u\n",
667 // sizeof (msg_dbg->id));
668 }
669 buf_iter = buf_iter + ntohs (msg_iter->size);
670 ret_remain = ret_remain - ntohs (msg_iter->size);
671 }
672
673 /* Enqueue the following messages */
674 /* skip the first message */
675 LOG (GNUNET_ERROR_TYPE_DEBUG, "Enqueueing messages\n");
676 buf_iter = buf + ntohs (msg->size);
677 ret_remain = ret - ntohs (msg->size);
678 /* iterate over the rest */
679 while (0 < ret_remain)
680 {
681 struct QueuedMessage *q_msg = GNUNET_new (struct QueuedMessage);
682
683 LOG (GNUNET_ERROR_TYPE_DEBUG, "Enqueueing message\n");
684 msg_iter = (struct GNUNET_MessageHeader *) buf_iter;
685 q_msg->msg = GNUNET_malloc (ntohs (msg_iter->size));
686 GNUNET_memcpy (q_msg->msg, msg_iter, ntohs (msg_iter->size));
688 connection->queued_recv_messages_tail,
689 q_msg);
690
691 buf_iter = buf_iter + ntohs (msg_iter->size);
692 ret_remain = ret_remain - ntohs (msg_iter->size);
693 }
694 }
695
696 /* check for and handle init */
697 if ((0 == ntohs (msg->type)) && /* 0 = GNUNET_MESSAGE_TYPE_TEST is deprecated - usage for this dummy should be fine */
698 (CONNECTION_LIVE != connection->status)) /* ignore if current connection is already live */
699 {
700 char *peer_addr_sent = (char *) &msg[1];
701 // FIXME is it really meaningful to send multiple addresses? probably just
702 // send the address that's used to open the connection
704 "Init-message: %s\n",
705 peer_addr_sent);
706 if ((NULL != connection->peer_addr) &&
707 (0 != strcmp (peer_addr_sent, connection->peer_addr)))
708 {
710 "Peer sent us an Init-message with an address different from the one we already know. -> MQ_destroy()\n");
712 "sent address: %s\n",
713 peer_addr_sent);
715 "old address: %s\n",
716 connection->peer_addr);
717 GNUNET_MQ_destroy (connection->mq);
718 GNUNET_break_op (0);
719 return;
720 }
721 switch (connection->status)
722 {
724 connection->status = CONNECTION_LIVE;
725 break;
728 break;
730 return;
731 default:
732 break;
733 }
735 "Connection to %s is now %s\n",
736 connection->peer_addr,
737 status2string (connection->status));
738 // else: we could skip ahead to end of if - we do already know the peer_addr
739 /* Check whether we already got a connection to that address/peer */
740 LOG (GNUNET_ERROR_TYPE_DEBUG, "Init - checking other connections\n");
741 for (struct Connection *c_iter = connection->handle->connections_head;
742 NULL != c_iter;
743 c_iter = c_iter->next)
744 {
746 " %s (%s)\n",
747 c_iter->peer_addr,
748 status2string (c_iter->status));
749 if ((NULL != c_iter->peer_addr) && /* we can't compare the addr */
750 (0 == strcmp (peer_addr_sent, c_iter->peer_addr)) && /* same peer */
751 (CONNECTION_LIVE == c_iter->status) && /* other connection is live*/
752 (connection != c_iter)) /* discovered the currently handled connection - skip */
753 {
754 /* We already got a connection with this peer - tear the current one
755 * down. */
757 "Init from other peer - already connected: %s - MQ_destroy()\n",
758 peer_addr_sent);
759 connection->status = CONNECTION_DESTROY;
760 GNUNET_MQ_destroy (connection->mq);
761 return;
762 }
763 }
764 connection->peer_addr = strdup (peer_addr_sent);
766 "Init-Message - notifying caller (%s :%s)\n",
767 connection->peer_addr,
768 status2string (connection->status));
769
770 try_notify_connect (connection);
772 "Finished initializing - going to cancel all still initializing connections to this address\n");
773 cancel_initiating_connections (connection->handle, connection);
774
775 /* We need to schedule the recv_task here because this is not a message
776 * passed to the caller an thus the caller will not call
777 * GNUNET_CORE_UNDERLAY_DUMMY_receive_continue () which usually schedules
778 * the recv_task */
779 connection->recv_task =
781 connection->sock,
782 do_read,
783 connection);
784 return;
785 }
786 else if ((0 == ntohs (msg->type)) && /* 0 = GNUNET_MESSAGE_TYPE_TEST is deprecated - usage for this dummy should be fine */
787 (CONNECTION_LIVE == connection->status))
788 {
789 /* We need to schedule the recv_task here because this is not a message
790 * passed to the caller an thus the caller will not call
791 * GNUNET_CORE_UNDERLAY_DUMMY_receive_continue () which usually schedules
792 * the recv_task */
793 connection->recv_task =
795 connection->sock,
796 do_read,
797 connection);
798 return;
799 }
800
801 if (GNUNET_NO == connection->notify_connect_called)
802 {
803 /* Notify connect has not been called yet - the caller doesn't know about
804 * this connection. Enqueue the first message, too; instead of handling it.
805 */
806 struct QueuedMessage *q_msg = GNUNET_new (struct QueuedMessage);
807
808 q_msg->msg = GNUNET_malloc (ntohs (msg->size));
809 GNUNET_memcpy (q_msg->msg, msg, ntohs (msg->size));
811 connection->queued_recv_messages_tail,
812 q_msg);
813 return;
814 }
815
816 if (GNUNET_YES == connection->client_ready_to_receive)
817 {
818 // TODO maybe just call check_for_messages() instead?
819 // check_for_messages (connection);
820 // FIXME for now the above gives only an unsuccessful test - check why
822 // FIXME check return value!!!
824 }
825 // else TODO
826}
827
828
835static void
836write_cb (void *cls)
837{
838 ssize_t sent;
839 struct Connection *connection = cls;
840
841 connection->write_task = NULL;
842 GNUNET_assert (NULL != connection->sock);
844 "write_cb(): sending bytes to %s :%s\n",
845 connection->peer_addr,
846 status2string (connection->status));
847 {
848 // XXX only for debugging purposes
849 // this shows everything works as expected
850
851 struct GNUNET_UNDERLAY_DUMMY_Message
852 {
853 struct GNUNET_MessageHeader header;
854 // The following will be used for debugging
855 uint64_t id; // id of the message
856 uint64_t batch; // first batch of that peer (for this test 0 or 1)
857 // uint64_t peer; // number of sending peer (for this test 0 or 1)
858 };
859
860
861 struct GNUNET_UNDERLAY_DUMMY_Message *msg_dbg =
862 (struct GNUNET_UNDERLAY_DUMMY_Message *) connection->message_to_send;
863 // LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - id: %u, batch: %u, peer: %u\n",
864 LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - id: %" PRIu64 ", batch: %" PRIu64
865 "\n",
866 GNUNET_ntohll (msg_dbg->id),
867 GNUNET_ntohll (msg_dbg->batch));
868 // LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - size: %u\n",
869 // ntohs (msg_dbg->size));
870 // LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - (sanity) size msghdr: %u\n",
871 // sizeof (struct GNUNET_MessageHeader));
872 // LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - (sanity) size msg field: %u\n",
873 // sizeof (msg_dbg->id));
874 }
875 GNUNET_assert (NULL != connection->message_to_send);
877 connection->sock,
878 connection->message_to_send,
879 ntohs (connection->message_to_send->size));
880 if (GNUNET_SYSERR == sent)
881 {
882 // LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to send message\n");
883 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to send message: %s\n", strerror (
884 errno));
885 if (EPIPE == errno)
886 {
887 /* Tear down the connection */
888 LOG (GNUNET_ERROR_TYPE_DEBUG, "MQ_destroy() (Failed to send message)\n");
889 connection->status = CONNECTION_DESTROY;
890 GNUNET_MQ_destroy (connection->mq); // This triggers mq_destroy_impl()
891 return;
892 }
893 LOG (GNUNET_ERROR_TYPE_ERROR, "Retrying (due to failure)\n");
894 /* retry */
895 connection->write_task =
897 connection->sock,
898 &write_cb,
899 connection);
900 return; // TODO proper handling - don't try to resend on certain errors
901 // (e.g. EPIPE as above)
902 }
903 LOG (GNUNET_ERROR_TYPE_DEBUG, "Successfully sent message\n");
904 connection->message_to_send = NULL;
905 switch (connection->status)
906 {
908 connection->status = CONNECTION_LIVE;
909 try_notify_connect (connection);
911 "Finished initializing - going to cancel all still initializing connections to this address\n");
912 cancel_initiating_connections (connection->handle, connection);
913 break;
916 break;
918 return;
919 default:
920 break;
921 }
923 "Connection to %s is now %s\n",
924 connection->peer_addr,
925 status2string (connection->status));
926 GNUNET_MQ_impl_send_continue (connection->mq);
927}
928
929
930static void
931send_init (struct Connection *connection)
932{
933 struct GNUNET_MQ_Envelope *env;
935 uint32_t peer_addr_len;
936
937 GNUNET_assert (NULL != connection->handle->sock_name);
939 "Sending init: %s\n",
940 connection->handle->sock_name);
941 peer_addr_len = strnlen (connection->handle->sock_name, 128) + 1;
942 env = GNUNET_MQ_msg_header_extra (msg, // usually we wanted to keep the
943 peer_addr_len, // envelopes to potentially cancel the
944 0); // message
945 GNUNET_memcpy (&msg[1], connection->handle->sock_name, peer_addr_len);
946 GNUNET_MQ_send (connection->mq, env);
947}
948
949
958static void
960 const struct GNUNET_MessageHeader *msg,
961 void *impl_state)
962{
963 struct Connection *connection = impl_state;
964
965 LOG (GNUNET_ERROR_TYPE_DEBUG, "from mq_send_impl\n");
966 {
967 // XXX only for debugging purposes
968 // this shows everything works as expected
969
970 struct GNUNET_UNDERLAY_DUMMY_Message
971 {
972 struct GNUNET_MessageHeader header;
973 // The following will be used for debugging
974 uint64_t id; // id of the message
975 uint64_t batch; // first batch of that peer (for this test 0 or 1)
976 // uint64_t peer; // number of sending peer (for this test 0 or 1)
977 };
978
979 struct GNUNET_UNDERLAY_DUMMY_Message *msg_dbg =
980 (struct GNUNET_UNDERLAY_DUMMY_Message *) msg;
981 LOG (GNUNET_ERROR_TYPE_DEBUG, "id: %" PRIu64 ", batch: %" PRIu64 "\n",
982 GNUNET_ntohll (msg_dbg->id),
983 GNUNET_ntohll (msg_dbg->batch));
984 }
985 connection->message_to_send = msg;
986 GNUNET_assert (NULL == connection->write_task);
987 connection->write_task =
989 connection->sock,
990 &write_cb,
991 connection);
992 LOG (GNUNET_ERROR_TYPE_DEBUG, "Scheduled sending of message\n");
993}
994
995
1002static void
1003mq_destroy_impl (struct GNUNET_MQ_Handle *mq, void *impl_state)
1004{
1005 struct Connection *connection = impl_state;
1006
1007 LOG (GNUNET_ERROR_TYPE_DEBUG, "mq_destroy_impl\n");
1008 connection_destroy (connection);
1009}
1010
1011
1018static void
1019mq_cancel_impl (struct GNUNET_MQ_Handle *mq, void *impl_state)
1020{
1021 struct Connection *connection = impl_state;
1022
1023 if (NULL != connection->write_task)
1024 {
1025 GNUNET_SCHEDULER_cancel (connection->write_task);
1026 connection->write_task = NULL;
1027 }
1028}
1029
1030
1039static void
1041{
1043 "mq_error_handler_impl: %u\n",
1044 error);
1045}
1046
1047
1053static void
1054do_accept (void *cls)
1055{
1057
1058 struct Connection *connection;
1059 struct GNUNET_NETWORK_Handle *sock;
1060 struct sockaddr_un addr_other;
1061 socklen_t addr_other_len = sizeof(addr_other);
1062 memset (&addr_other, 0, sizeof (addr_other));
1063
1065 h->sock_listen,
1066 do_accept,
1067 h);
1068
1069 LOG (GNUNET_ERROR_TYPE_DEBUG, "Handling incoming connection\n");
1070
1071 GNUNET_assert (NULL != h->sock_listen);
1072
1073 LOG (GNUNET_ERROR_TYPE_INFO, "Accepting incoming connection\n");
1074 sock = GNUNET_NETWORK_socket_accept (h->sock_listen,
1075 (struct sockaddr *) &addr_other,
1076 &addr_other_len);
1077 if (NULL == sock)
1078 {
1079 // LOG(GNUNET_ERROR_TYPE_ERROR, "Error accepting incoming connection, %s", strerror(errno));
1080 LOG (GNUNET_ERROR_TYPE_ERROR, "Error accepting incoming connection\n");
1081 return;
1082 }
1084 {
1086 "Failed setting socket of incoming connection to non-blocking\n");
1087 return;
1088 }
1089 connection = GNUNET_new (struct Connection);
1090 connection->sock = sock;
1091 connection->peer_addr = NULL; // GNUNET_strdup (addr_other.sun_path); should
1092 // be empty
1093 connection->handle = h;
1094 connection->notify_connect_called = GNUNET_NO;
1095 connection->client_ready_to_receive = GNUNET_NO;
1096 connection->status = CONNECTION_INITIALIZING;
1097 LOG (GNUNET_ERROR_TYPE_INFO, "Peer connected\n");
1098 GNUNET_CONTAINER_DLL_insert (h->connections_head,
1099 h->connections_tail,
1100 connection);
1101 connection->mq =
1105 connection, // impl_state - gets passed to _impls
1106 h->handlers,
1108 connection->cls_mq);
1109 connection->recv_task =
1111 connection->sock,
1112 do_read,
1113 connection);
1114 send_init (connection);
1115}
1116
1117
1126static void
1128{
1129 struct PeerConnectCls *pcc = cls;
1130
1131 pcc->peer_connect_task = NULL;
1134 pcc);
1135 {
1136 struct Connection *connection;
1137 struct GNUNET_CORE_UNDERLAY_DUMMY_Handle *h = pcc->h;
1138 struct sockaddr_un addr_other;
1139 memset (&addr_other, 0, sizeof (addr_other));
1140
1141 connection = GNUNET_new (struct Connection);
1142 connection->handle = pcc->h;
1143 connection->sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
1144 connection->peer_addr = pcc->sock_name;
1145 connection->notify_connect_called = GNUNET_NO;
1146 connection->client_ready_to_receive = GNUNET_NO;
1147 connection->status = CONNECTION_INITIALIZING;
1148 if (NULL == connection->sock)
1149 {
1150 LOG (GNUNET_ERROR_TYPE_ERROR, "Socket does not open\n");
1151 GNUNET_free (connection);
1152 return;
1153 }
1154 if (GNUNET_OK !=
1156 {
1157 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed setting socket to non-blocking\n");
1158 GNUNET_free (connection);
1159 return;
1160 }
1161
1162 addr_other.sun_family = AF_UNIX;
1163 // strcpy (addr_other.sun_path, pcc->sock_name);
1164 GNUNET_memcpy (addr_other.sun_path, pcc->sock_name, strlen (pcc->sock_name))
1165 ;
1166 if (GNUNET_OK != GNUNET_NETWORK_socket_connect (connection->sock,
1167 (struct sockaddr *) &
1168 addr_other,
1169 sizeof(addr_other)))
1170 {
1172 "failed to connect to the socket: %u %s (closing socket)\n",
1173 errno, strerror (errno));
1174 GNUNET_NETWORK_socket_close (connection->sock);
1175 GNUNET_free (connection);
1176 // LOG (GNUNET_ERROR_TYPE_INFO, "Sanity check: %s\n", addr_other.sun_path);
1177 return;
1178 }
1179 connection->peer_addr = GNUNET_strdup (pcc->sock_name);
1180 LOG (GNUNET_ERROR_TYPE_INFO, "Successfully connected to socket\n");
1181 connection->recv_task =
1183 connection->sock,
1184 do_read,
1185 connection);
1186 connection->mq =
1190 connection, // impl_state - gets passed to _impls
1191 h->handlers,
1193 connection->cls_mq);
1194 GNUNET_CONTAINER_DLL_insert (h->connections_head,
1195 h->connections_tail,
1196 connection);
1197 send_init (connection);
1198
1199 // FIXME: proper array
1200 // FIXME: proper address format ("dummy:<sock_name>")
1201 }
1202 GNUNET_free (pcc->sock_name);
1203 GNUNET_free (pcc);
1204}
1205
1206
1215static void
1217{
1219 const char *addresses[1] = {h->sock_name}; // The dummy will only ever know
1220 // about this one address
1221
1222 h->notify_address_change_task = NULL;
1223 h->notify_address_change (h->cls, 1, addresses);
1224}
1225
1226
1227static void
1229{
1230 GNUNET_assert (0 != strcmp (address, ""));
1231 LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to connect to socket: `%s'\n", address);
1232 if (0 == strcmp (address, h->sock_name))
1233 {
1234 LOG (GNUNET_ERROR_TYPE_DEBUG, "Not going to connect to own address\n");
1235 return;
1236 }
1238 "Discovered another peer with address `%s'\n",
1239 address);
1240
1246 LOG (GNUNET_ERROR_TYPE_DEBUG, "checking other connections:\n");
1247 for (struct Connection *conn_iter = h->connections_head;
1248 NULL != conn_iter;
1249 conn_iter = conn_iter->next)
1250 {
1252 " %s (%s)\n",
1253 conn_iter->peer_addr,
1254 status2string (conn_iter->status));
1255 if ((NULL != conn_iter->peer_addr) &&
1256 (0 == strcmp (address, conn_iter->peer_addr)) &&
1257 (CONNECTION_LIVE == conn_iter->status))
1258 {
1260 "Already connected to this peer - don't try to open another connection\n");
1261 return;
1262 }
1263 }
1264 for (struct PeerConnectCls *pcc_iter = h->peer_connect_cls_head;
1265 NULL != pcc_iter;
1266 pcc_iter = pcc_iter->next)
1267 {
1268 if (0 == strcmp (address,
1269 pcc_iter->sock_name))
1270 {
1271 LOG (GNUNET_ERROR_TYPE_DEBUG, "Already waiting to connect to this peer\n")
1272 ;
1273 return;
1274 }
1275 }
1276
1277 {
1278 struct PeerConnectCls *peer_connect_cls;
1279 peer_connect_cls = GNUNET_new (struct PeerConnectCls);
1280 peer_connect_cls->h = h;
1281 peer_connect_cls->sock_name = GNUNET_strdup (address);
1282 peer_connect_cls->peer_connect_task =
1284 peer_connect_cls);
1285 GNUNET_CONTAINER_DLL_insert (h->peer_connect_cls_head,
1286 h->peer_connect_cls_tail,
1287 peer_connect_cls);
1288 }
1289}
1290
1291
1307static enum GNUNET_GenericReturnValue
1309 const char *filename)
1310{
1312
1314
1315 return GNUNET_OK;
1316}
1317
1318
1326static void
1328{
1330 int ret;
1331
1332 ret = GNUNET_DISK_glob (SOCK_NAME_BASE "*" SOCK_EXTENSION,
1334 h);
1335 if (0 > ret)
1336 {
1337 LOG (GNUNET_ERROR_TYPE_WARNING, "Scanning for unix domain sockets failed\n")
1338 ;
1339 }
1340
1341 h->peer_discovery_task = GNUNET_SCHEDULER_add_delayed (
1344 h);
1345}
1346
1347
1348static enum GNUNET_GenericReturnValue
1350 char *sock_name)
1351{
1352 struct sockaddr_un *addr_un;
1353 socklen_t addr_un_len;
1354 uint8_t ret = GNUNET_NO;
1355
1356 h->sock_listen = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
1357 GNUNET_assert (NULL != h->sock_listen);
1358 LOG (GNUNET_ERROR_TYPE_DEBUG, "Opened socket, going to bind to address\n");
1359
1360 addr_un = GNUNET_new (struct sockaddr_un);
1361 addr_un->sun_family = AF_UNIX;
1362 // TODO check that the string is not too long
1363 GNUNET_memcpy (&addr_un->sun_path, sock_name, strlen (sock_name));
1364 addr_un_len = sizeof (struct sockaddr_un);
1365 LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to bind to `%s'\n", addr_un->sun_path);
1366 ret = GNUNET_NETWORK_socket_bind (h->sock_listen,
1367 (struct sockaddr *) addr_un,
1368 addr_un_len);
1369 if ((GNUNET_OK != ret) && (98 != errno))
1370 {
1371 /* Error different from Address already in use - cancel */
1373 "Failed binding to socket: %u %s (closing socket)\n",
1374 errno, strerror (errno));
1375 GNUNET_NETWORK_socket_close (h->sock_listen);
1376 h->sock_listen = NULL;
1377 GNUNET_free (addr_un);
1378 return GNUNET_SYSERR;
1379 }
1380 else if (GNUNET_OK != ret)
1381 {
1383 " -> something went wrong (address is probably in use)\n");
1384 GNUNET_NETWORK_socket_close (h->sock_listen);
1385 h->sock_listen = NULL;
1386 GNUNET_free (addr_un);
1387 }
1388 else if (GNUNET_OK == ret)
1389 {
1391 " -> succeeded! (binding to socket)\n");
1392 h->sock_name = GNUNET_strdup (sock_name);
1393 }
1394 GNUNET_free (addr_un);
1395 return ret;
1396}
1397
1398
1409static void
1411 uint64_t sock_name_ctr_start)
1412{
1414 char *sock_name;
1415 uint64_t sock_name_ctr = sock_name_ctr_start; // Append to the socket name to avoid collisions
1416 uint8_t ret = GNUNET_NO;
1417
1418 /* Open a socket that's not occupied by another 'peer' yet:
1419 * Try opening sockets with an increasing counter in the socket name. */
1420 // TODO we might want to change this loop to schedule a new task
1421 do {
1423 SOCK_NAME_BASE "%" PRIu64 "" SOCK_EXTENSION "\0",
1424 sock_name_ctr++);
1427 if (GNUNET_SYSERR == ret)
1428 return;
1429 } while (GNUNET_YES != ret);
1430 LOG (GNUNET_ERROR_TYPE_INFO, "Bound to `%s'\n", h->sock_name);
1431 h->sock_name_index_start = sock_name_ctr_start;
1432 h->sock_name_index = sock_name_ctr;
1433
1434 LOG (GNUNET_ERROR_TYPE_DEBUG, "Mark socket as accepting connections\n");
1435 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (h->sock_listen, BACKLOG))
1436 {
1437 // LOG (GNUNET_ERROR_TYPE_ERROR, "Failed listening to socket: %s", strerror(errno));
1439 "Failed listening to socket (closing socket)\n");
1441 h->sock_listen = NULL;
1442 GNUNET_free (h->sock_name);
1443 return;
1444 }
1445
1446 if (NULL != h->notify_address_change)
1447 {
1448 // TODO cancel and cleanup task on run and shutdown
1449 LOG (GNUNET_ERROR_TYPE_DEBUG, "schedlue do_notify_address_change()\n");
1450 h->notify_address_change_task =
1452 }
1453
1454 LOG (GNUNET_ERROR_TYPE_DEBUG, "scheudle do_discover_peers()\n");
1455 h->peer_discovery_task = GNUNET_SCHEDULER_add_delayed (
1458 h);
1459
1460 LOG (GNUNET_ERROR_TYPE_INFO, "Going to listen for connections\n");
1462 h->sock_listen,
1463 do_accept,
1464 h);
1465}
1466
1467
1468// TODO
1469static void
1471{
1473 struct PeerConnectCls *pcc_next;
1474 struct Connection *conn_next;
1475
1476 if (NULL != h->notify_address_change_task)
1477 {
1478 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling notify address change task\n");
1479 GNUNET_SCHEDULER_cancel (h->notify_address_change_task);
1480 h->notify_address_change_task = NULL;
1481 }
1482 if (NULL != h->peer_discovery_task)
1483 {
1484 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling peer discovery task\n");
1485 GNUNET_SCHEDULER_cancel (h->peer_discovery_task);
1486 h->peer_discovery_task = NULL;
1487 }
1488 for (struct PeerConnectCls *pcc = h->peer_connect_cls_head;
1489 NULL != pcc;
1490 pcc = pcc_next)
1491 {
1492 pcc_next = pcc->next;
1493 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling peer connect task\n");
1494 GNUNET_SCHEDULER_cancel (pcc->peer_connect_task);
1495 GNUNET_CONTAINER_DLL_remove (h->peer_connect_cls_head,
1496 h->peer_connect_cls_tail,
1497 pcc);
1498 GNUNET_free (pcc->sock_name);
1499 GNUNET_free (pcc);
1500 }
1501 if (NULL != h->listen_task)
1502 {
1503 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling listen task\n");
1504 GNUNET_SCHEDULER_cancel (h->listen_task);
1505 h->listen_task = NULL;
1506 }
1507 if (NULL != h->sock_listen)
1508 {
1509 LOG (GNUNET_ERROR_TYPE_DEBUG, "closing socket\n");
1510 GNUNET_NETWORK_socket_close (h->sock_listen);
1511 h->sock_listen = NULL;
1512 }
1513 for (struct Connection *conn_iter = h->connections_head;
1514 NULL != conn_iter;
1515 conn_iter = conn_next)
1516 {
1517 // TODO consider moving MQ_destroy() into connection_destroy(), but keep in
1518 // mind that connection_destroy() is also called from within
1519 // mq_destroy_impl()
1520 conn_next = conn_iter->next;
1521 LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying a connection - MQ_destroy()\n");
1522 conn_iter->status = CONNECTION_DESTROY;
1523 GNUNET_MQ_destroy (conn_iter->mq); // This triggers mq_destroy_impl()
1524 }
1525}
1526
1527
1545 const struct GNUNET_CONFIGURATION_Handle *cfg,
1546 const struct GNUNET_MQ_MessageHandler *handlers,
1547 void *cls,
1551{
1553
1555 h->notify_connect = nc;
1556 h->notify_disconnect = nd;
1557 h->notify_address_change = na;
1558 if (NULL != handlers)
1559 h->handlers = GNUNET_MQ_copy_handlers (handlers);
1560 h->cls = cls;
1561
1563
1564 // h->address_change_task = GNUNET_SCHEDULER_add_delayed (
1565 // GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5),
1566 // do_change_address,
1567 // h);
1568
1569 LOG (GNUNET_ERROR_TYPE_INFO, "Core connected\n");
1570
1571 return h;
1572}
1573
1574
1580void
1583{
1584 LOG (GNUNET_ERROR_TYPE_INFO, "Core disconnects\n");
1585 // TODO delete, free and close everything
1586 if (NULL != handle->address_change_task)
1587 GNUNET_SCHEDULER_cancel (handle->address_change_task);
1589 if (NULL != handle->handlers)
1590 GNUNET_free (handle->handlers);
1591 GNUNET_free (handle->sock_name);
1593 LOG (GNUNET_ERROR_TYPE_INFO, " -> Disconnected\n");
1594}
1595
1596
1617void
1618GNUNET_CORE_UNDERLAY_DUMMY_receive_continue (
1620 struct GNUNET_MQ_Handle *mq)
1621{
1622 struct Connection *connection;
1623
1624 LOG (GNUNET_ERROR_TYPE_DEBUG, "from _receive_continue()\n");
1625
1626 /* Find the connection belonging to the mq */
1627 for (struct Connection *conn_iter = h->connections_head;
1628 NULL != conn_iter;
1629 conn_iter = conn_iter->next)
1630 {
1631 if (mq == conn_iter->mq)
1632 {
1633 connection = conn_iter;
1634 }
1635 }
1636 GNUNET_assert (NULL != connection);
1637 connection->recv_task = NULL;
1638 connection->client_ready_to_receive = GNUNET_YES;
1639 check_for_messages (connection);
1640}
1641
1642
1656void
1657GNUNET_CORE_UNDERLAY_DUMMY_connect_to_peer (
1659 const char *peer_address,
1662{
1663 // TODO PriorityPreferences
1664 // TODO BANDWIDTH_Value
1665 try_connect (h, peer_address);
1666}
1667
1668
1672void
1673GNUNET_CORE_UNDERLAY_DUMMY_change_address (
1675{
1676 LOG (GNUNET_ERROR_TYPE_DEBUG, "Changing address!\n");
1678 if (0 == h->sock_name_index_start)
1679 {
1681 }
1682 else
1683 {
1685 }
1686}
1687
1688
1689#if 0 /* keep Emacsens' auto-indent happy */
1690{
1691#endif
1692#ifdef __cplusplus
1693}
1694#endif
1695
1696
/* end of group */
1698
/* end of group addition */
1700
1701/* end of gnunet_core_underlay_dummy.c */
struct GNUNET_MQ_MessageHandlers handlers[]
Definition 003.c:1
struct GNUNET_MessageHeader * msg
Definition 005.c:2
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
static size_t strnlen(const char *s, size_t n)
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition gnunet-arm.c:98
static int ret
Final status code.
Definition gnunet-arm.c:93
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition gnunet-arm.c:108
static char * address
GNS address for this phone.
#define LOG(kind,...)
static char * filename
static struct GNUNET_IDENTITY_Handle * id
Handle to IDENTITY.
static int status
The program status; 0 for success.
Definition gnunet-nse.c:39
static struct GNUNET_NotificationContext * nc
Notification context for broadcasting to monitors.
static struct GNUNET_VPN_Handle * handle
Handle to vpn service.
Definition gnunet-vpn.c:35
API of the dummy core underlay that uses unix domain sockets.
API to schedule computations using continuation passing style.
struct GNUNET_MQ_MessageHandler * handlers
Array of message handlers given by the client.
const struct GNUNET_MessageHeader * message_to_send
Message about to be sent, given by the message queue, waiting for the socket to be ready.
static void do_close_listening_socket(void *cls)
struct GNUNET_NETWORK_Handle * sock
Socket for the connected peer.
void GNUNET_CORE_UNDERLAY_DUMMY_disconnect(struct GNUNET_CORE_UNDERLAY_DUMMY_Handle *handle)
Disconnect from the core underlay dummy service.
struct QueuedMessage * prev
struct QueuedMessage * queued_recv_messages_tail
GNUNET_CORE_UNDERLAY_DUMMY_NotifyAddressChange notify_address_change
Callback (from/to client) to call when our address changes.
void * cls
Closure for handlers given by the client - connection-independant (notify_connect,...
GNUNET_CORE_UNDERLAY_DUMMY_NotifyConnect notify_connect
Callback (from/to client) to call when another peer connects.
struct GNUNET_SCHEDULER_Task * listen_task
Task that waits for incoming connections.
char * sock_name
Name of the listening socket.
struct Connection * prev
Linked list previous.
struct GNUNET_SCHEDULER_Task * write_task
Task waiting until the socket becomes ready to be written to.
static void do_read(void *cls)
Callback scheduled to run when there is something to read from the socket.
struct Connection * connections_head
Head of linked list with peer connect closures.
struct PeerConnectCls * peer_connect_cls_tail
Tail of linked list with peer connect closures.
struct PeerConnectCls * next
Linked list next.
struct GNUNET_CORE_UNDERLAY_DUMMY_Handle * GNUNET_CORE_UNDERLAY_DUMMY_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_MQ_MessageHandler *handlers, void *cls, GNUNET_CORE_UNDERLAY_DUMMY_NotifyConnect nc, GNUNET_CORE_UNDERLAY_DUMMY_NotifyDisconnect nd, GNUNET_CORE_UNDERLAY_DUMMY_NotifyAddressChange na)
Connect to the core underlay dummy service.
static void connection_destroy(struct Connection *connection)
Destroy a connection.
static void do_notify_address_change(void *cls)
Notify core about address change.
struct Connection * connections_tail
Tail of linked list with peer connect closures.
char * peer_addr
Address of the connected peer.
static void do_discover_peers(void *cls)
Discover sockets of other peers.
struct GNUNET_CORE_UNDERLAY_DUMMY_Handle * h
The handle for the service.
static void cancel_initiating_connections(struct GNUNET_CORE_UNDERLAY_DUMMY_Handle *h, struct Connection *connection)
void * cls_mq
Closure for the mq towards the client.
struct GNUNET_SCHEDULER_Task * address_change_task
struct GNUNET_SCHEDULER_Task * peer_discovery_task
Task to discover other peers.
static void write_cb(void *cls)
Callback scheduled to run once the socket is ready for writing.
struct GNUNET_SCHEDULER_Task * peer_connect_task
Task to connect to another peer.
struct QueuedMessage * queued_recv_messages_head
Queued received messages in a DLL TODO implement cleanup TODO replace with a performant queue.
struct PeerConnectCls * prev
Linked list previous.
static enum GNUNET_GenericReturnValue try_open_listening_socket(struct GNUNET_CORE_UNDERLAY_DUMMY_Handle *h, char *sock_name)
static void do_connect_to_peer(void *cls)
Connect to another peer.
struct GNUNET_SCHEDULER_Task * notify_address_change_task
Task to notify core about address changes.
static void check_for_messages(struct Connection *connection)
struct GNUNET_SCHEDULER_Task * handle_message_task
Task to pass the message to the client's handlers.
void(* GNUNET_CORE_UNDERLAY_DUMMY_NotifyAddressChange)(void *cls, uint32_t num_addresses, const char *addresses[static num_addresses])
Function called to notify core of the now available addresses.
static void mq_destroy_impl(struct GNUNET_MQ_Handle *mq, void *impl_state)
Callback to destroy the message queue.
struct Connection * next
Linked list next.
static const char * status2string(enum ConnectionStatus status)
struct GNUNET_NETWORK_Handle * sock_listen
Socket on which we listen for incoming connections.
static void try_notify_connect(struct Connection *connection)
enum GNUNET_GenericReturnValue notify_connect_called
Whether notify_connect was called already It is used to check whether to call notify_disconnect or no...
static void do_notify_connect(void *cls)
Notify the api caller about a new connection.
struct GNUNET_MessageHeader * msg
struct GNUNET_MQ_Handle * mq
Message queue towards the connected peer.
static void do_handle_message(void *cls)
static void mq_error_handler_impl(void *cls, enum GNUNET_MQ_Error error)
Handle mq errors.
static void do_open_listening_socket(void *cls, uint64_t sock_name_ctr_start)
Opens UNIX domain socket.
struct GNUNET_MQ_MessageHandler * handlers
Handlers for mq.
struct GNUNET_CORE_UNDERLAY_DUMMY_Handle * handle
Handle to the service.
enum ConnectionStatus status
Status of the connection: Initializing, Live, Destroy.
static void do_accept(void *cls)
Accept a connection on the dummy's socket.
static void mq_cancel_impl(struct GNUNET_MQ_Handle *mq, void *impl_state)
Callback to cancel sending a message.
GNUNET_CORE_UNDERLAY_DUMMY_NotifyDisconnect notify_disconnect
Callback (from/to client) to call when a peer disconnects.
struct PeerConnectCls * peer_connect_cls_head
Head of linked list with peer connect closures.
struct QueuedMessage * next
static void set_handlers_closure(struct GNUNET_MQ_MessageHandler *handlers, void *handlers_cls)
Set the closures for mq handlers.
enum GNUNET_GenericReturnValue client_ready_to_receive
Indicating whether the client is ready to receive new messages.
static enum GNUNET_GenericReturnValue discovered_socket_cb(void *cls, const char *filename)
Handle the discovery of a certain socket.
void *(* GNUNET_CORE_UNDERLAY_DUMMY_NotifyConnect)(void *cls, uint32_t num_addresses, const char *addresses[static num_addresses], struct GNUNET_MQ_Handle *mq, const struct GNUNET_PeerIdentity *peer_id)
Function called to notify core underlay dummy users that another peer connected to us.
void(* GNUNET_CORE_UNDERLAY_DUMMY_NotifyDisconnect)(void *cls, void *handler_cls)
Function called to notify core underlay dummy users that another peer disconnected from us.
static void send_init(struct Connection *connection)
struct GNUNET_SCHEDULER_Task * recv_task
Task waiting for incoming messages.
struct GNUNET_SCHEDULER_Task * notify_connect_task
Task to notify the client about an open connection.
char * sock_name
The file name to connect to.
static void try_connect(struct GNUNET_CORE_UNDERLAY_DUMMY_Handle *h, const char *address)
static void mq_send_impl(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
Callback called from the MQ to send a message over a socket.
@ CONNECTION_INITIALIZING_RECV
@ CONNECTION_INITIALIZING_SEND
int GNUNET_DISK_glob(const char *glob_pattern, GNUNET_FileNameCallback callback, void *callback_cls)
Find all files matching a glob pattern.
Definition disk.c:1021
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_Error
Error codes for the queue.
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:482
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition mq.c:305
struct GNUNET_MQ_MessageHandler * GNUNET_MQ_copy_handlers(const struct GNUNET_MQ_MessageHandler *handlers)
Copy an array of handlers.
Definition mq.c:974
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:437
GNUNET_MQ_PriorityPreferences
Per envelope preferences and priorities.
enum GNUNET_GenericReturnValue GNUNET_MQ_handle_message(const struct GNUNET_MQ_MessageHandler *handlers, const struct GNUNET_MessageHeader *mh)
Call the message message handler that was registered for the type of the given message in the given h...
Definition mq.c:205
#define GNUNET_MQ_msg_header_extra(mh, esize, type)
Allocate a GNUNET_MQ_Envelope, where the message only consists of a header and extra space.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition mq.c:700
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_accept(const struct GNUNET_NETWORK_Handle *desc, struct sockaddr *address, socklen_t *address_len)
Accept a new connection on a socket.
Definition network.c:392
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition network.c:508
ssize_t GNUNET_NETWORK_socket_recv(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length)
Read data from a connected socket (always non-blocking).
Definition network.c:717
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_set_blocking(struct GNUNET_NETWORK_Handle *fd, int doBlock)
Set if a socket should use blocking or non-blocking IO.
Definition network.c:224
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition network.c:833
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_connect(const struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Connect a socket to some remote address.
Definition network.c:602
ssize_t GNUNET_NETWORK_socket_send(const struct GNUNET_NETWORK_Handle *desc, const void *buffer, size_t length)
Send data (always non-blocking).
Definition network.c:738
enum GNUNET_GenericReturnValue 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:439
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_listen(const struct GNUNET_NETWORK_Handle *desc, int backlog)
Listen on a socket.
Definition network.c:652
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:1511
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:1582
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:980
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1304
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:1277
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition time.c:486
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
Used to keep track of context of peer.
32-bit bandwidth used for network exchange by GNUnet, in bytes per second.
Handle to a message queue.
Definition mq.c:87
Message handler for a specific message type.
Header for all communications.
handle to a socket
Definition network.c:53
Entry in list of pending tasks.
Definition scheduler.c:136
Closure used for the peer_connect_task.