GNUnet 0.27.0-15-g06790e60f
 
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>
51#include "platform.h"
53#include "gnunet_util_lib.h"
55
56#define LOG(kind, ...) GNUNET_log_from (kind, "core-underlay-dummy", __VA_ARGS__ \
57 )
58
59#define SOCK_NAME_BASE "/tmp/gnunet-core-underlay-dummy-socket"
60#define SOCK_EXTENSION ".sock"
61#define BUFF_SIZE 8192
62#define BACKLOG 10
63
64
95
96
104
105
107{
108 /* Created, but neither received, nor sent anything over it */
110
111 /* Created and successfully sent something (probably init) */
113
114 /* Created and successfully received something (probably init) */
116
117 /* Live - usable - successfully received and sent something (probably init) */
119
120 /* In the process of destruction */
122};
123
124
226
227
314
315
316static const char *
318{
319 switch (status)
320 {
322 return "C_INITIALIZING";
323 break;
325 return "C_INITIALIZING_SEND";
326 break;
328 return "C_INITIALIZING_RECV";
329 break;
330 case CONNECTION_LIVE:
331 return "C_LIVE";
332 break;
334 return "C_DESTROY";
335 break;
336 }
337 return ""; /* Make compiler happy */
338}
339
340
347static void
348do_read (void *cls);
349
350
351/*****************************************************************************
352 * Connection-related functions *
353 ****************************************************************************/
354
363static void
364connection_destroy (struct Connection *connection)
365{
366 /* The mq should already be cleaned as this function is called from within
367 * mq_destroy_impl. */
368 LOG (GNUNET_ERROR_TYPE_DEBUG, "connection_destroy\n");
369 if ((NULL != connection->handle->notify_disconnect) &&
370 (GNUNET_YES == connection->notify_connect_called))
371 {
372 /* Call the notify disconnect only if the notify_connect_task has been
373 * executed and the client was actually notified about the connection */
374 connection->handle->notify_disconnect (connection->handle->cls, /* connection-independant cls */
375 connection->cls_mq); /* connection-specific cls */
376 }
377 if (NULL != connection->notify_connect_task)
378 {
379 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling notify connect task\n");
381 }
382 if (NULL != connection->handle_message_task)
383 {
384 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling handle message task\n");
386 }
387 if (NULL != connection->write_task)
388 {
389 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling write task\n");
391 }
392 if (NULL != connection->recv_task)
393 {
394 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling recv task\n");
396 }
397 if (NULL != connection->sock)
398 {
399 LOG (GNUNET_ERROR_TYPE_DEBUG, "closing socket\n");
400 GNUNET_NETWORK_socket_close (connection->sock);
401 }
402 GNUNET_free (connection->peer_addr);
403 if (NULL != connection->handlers)
404 GNUNET_free (connection->handlers);
405 /* Don't free the cls_mq - we don't own it! */
407 connection->handle->connections_tail,
408 connection);
409 GNUNET_free (connection);
410 LOG (GNUNET_ERROR_TYPE_DEBUG, "connection_destroy - end\n");
411}
412
413
414/*****************************************************************************
415 * Connection-related functions (end) *
416 ****************************************************************************/
417
418
428static void
430 void *handlers_cls)
431{
432 GNUNET_assert (NULL != handlers);
433
434 for (unsigned int i = 0; NULL != handlers[i].cb; i++)
435 handlers[i].cls = handlers_cls;
436}
437
438
439static void
441{
442 struct Connection *connection = cls;
443 struct QueuedMessage *q_msg = connection->queued_recv_messages_head;
444 struct GNUNET_MessageHeader *msg = q_msg->msg;
445
446 connection->handle_message_task = NULL;
449 connection->queued_recv_messages_head,
450 connection->queued_recv_messages_tail,
451 q_msg);
452 GNUNET_free (q_msg);
453 // FIXME check return value!!!
455 connection->handlers,
456 msg);
457 // GNUNET_free (msg); // TODO what do we do with this pointer? Who owns it?
458 // Who cleans it?
459}
460
461
462static void
463check_for_messages (struct Connection *connection)
464{
465 if (NULL != connection->queued_recv_messages_head)
466 {
467 LOG (GNUNET_ERROR_TYPE_DEBUG, "got messages in the queue - handle those\n");
468 GNUNET_assert (NULL == connection->handle_message_task);
469 connection->handle_message_task =
471 }
472 else if (NULL == connection->recv_task)
473 {
475 "no messages in the queue - receive more from socket\n");
476 connection->recv_task =
478 connection->sock,
479 do_read,
480 connection);
481 }
482}
483
484
493static void
495{
496 struct Connection *connection = cls;
497 struct GNUNET_CORE_UNDERLAY_DUMMY_Handle *h = connection->handle;
498 void *cls_mq;
499
500 connection->notify_connect_task = NULL;
501 connection->notify_connect_called = GNUNET_YES;
503 /* The global, connection-independant closure is given to notify_connect,
504 * notify_disconnect and notify_address_change, whereas the
505 * connection-specific cls is the return value of notify_connect and given to
506 * the handlers. */
507 cls_mq =
508 h->notify_connect (h->cls,
509 1,
510 (const char **) &connection->peer_addr,
511 connection->mq,
512 NULL); /* peer_id */
513 /* The handlers are copied because the connection-specific closures can be
514 * set. The global handlers remain the same - they are just called with the
515 * connection specific closures. */
516 connection->handlers = GNUNET_MQ_copy_handlers (h->handlers);
517 set_handlers_closure (connection->handlers, h->cls); /* in case there's no connection-specific closure */
518 if (NULL != cls_mq)
519 {
520 connection->cls_mq = cls_mq;
521 // GNUNET_MQ_set_handlers_closure (connection->mq, connection->cls_mq);
522 /* Overwrite the closure set above with the cls_mq */
523 set_handlers_closure (connection->handlers, connection->cls_mq);
524 }
525
526 /* Handle already enqueued messages */
527 check_for_messages (connection);
528}
529
530
531static void
532try_notify_connect (struct Connection *connection)
533{
534 if ((NULL != connection->peer_addr) &&
535 (CONNECTION_LIVE == connection->status) &&
536 (NULL != connection->handle->notify_connect) &&
537 (NULL == connection->notify_connect_task))
538 {
539 connection->notify_connect_task =
541 }
542}
543
544
545static void
547 struct Connection *connection)
548{
549 struct Connection *c_iter_next;
550 char *peer_addr = connection->peer_addr;
551
553 "Going to cancel all initializing connections to %s\n",
554 peer_addr);
555 if (NULL == peer_addr)
556 return; /* No sense in comparing to unknown address */
557 for (struct Connection *c_iter = h->connections_head;
558 NULL != c_iter;
559 c_iter = c_iter_next)
560 {
561 c_iter_next = c_iter->next;
563 " %s :%s\n",
564 c_iter->peer_addr,
565 status2string (c_iter->status));
566 if ((c_iter != connection) && /* Don't shut down current connection */
567 (NULL != c_iter->peer_addr) && /* No address - can't compare */
568 (0 == strcmp (c_iter->peer_addr, peer_addr)) &&
569 (
570 (CONNECTION_INITIALIZING == c_iter->status) ||
571 (CONNECTION_INITIALIZING_SEND == c_iter->status) ||
572 (CONNECTION_INITIALIZING_RECV == c_iter->status)))
573 {
575 " -> Cancelling connection - MQ_destroy()\n");
576 GNUNET_MQ_destroy (c_iter->mq);
577 }
578 }
579}
580
581
588static void
589do_read (void *cls)
590{
591 struct Connection *connection = cls;
592
593 char buf[65536] GNUNET_ALIGN;
594 ssize_t ret;
596
598 "do_read(): receiving bytes from %s :%s\n",
599 connection->peer_addr,
600 status2string (connection->status));
601 connection->recv_task = NULL;
602 GNUNET_assert (NULL != connection->sock);
603 ret = GNUNET_NETWORK_socket_recv (connection->sock,
604 &buf,
605 sizeof(buf));
606 if (0 > ret)
607 {
608 LOG (GNUNET_ERROR_TYPE_ERROR, "Error reading from socket - MQ_destroy()\n");
609 connection->status = CONNECTION_DESTROY;
610 GNUNET_MQ_destroy (connection->mq); // This triggers mq_destroy_impl()
611 return;
612 }
613 if (0 == ret)
614 {
616 "Other peer closed connection - MQ_destroy()\n");
617 connection->status = CONNECTION_DESTROY;
618 GNUNET_MQ_destroy (connection->mq); // This triggers mq_destroy_impl()
619 return;
620 }
621 LOG (GNUNET_ERROR_TYPE_DEBUG, "Read %d bytes\n", (int) ret);
622 GNUNET_assert (2 <= ret); /* has to have returned enough for one full msg_hdr */
623
624 /* Handle the message itself */
625 {
626 ssize_t ret_remain;
627 char *buf_iter;
628 struct GNUNET_MessageHeader *msg_iter;
629
630 msg = (struct GNUNET_MessageHeader *) buf;
631 ret_remain = ret;
632 buf_iter = buf;
633 /* Just debug logging */
634 while (0 < ret_remain)
635 {
636 msg_iter = (struct GNUNET_MessageHeader *) buf_iter;
637 LOG (GNUNET_ERROR_TYPE_DEBUG, "Length of message: %d bytes\n", ntohs (
638 msg_iter->size));
639 LOG (GNUNET_ERROR_TYPE_DEBUG, "Remaining bytes of buffer: %ld\n",
640 ret_remain);
641
642 {
643 // XXX only for debugging purposes
644 // this shows everything works as expected
645
646 struct GNUNET_UNDERLAY_DUMMY_Message
647 {
648 struct GNUNET_MessageHeader header;
649 // The following will be used for debugging
650 uint64_t id; // id of the message
651 uint64_t batch; // first batch of that peer (for this test 0 or 1)
652 // uint64_t peer; // number of sending peer (for this test 0 or 1)
653 };
654
655
656 struct GNUNET_UNDERLAY_DUMMY_Message *msg_dbg =
657 (struct GNUNET_UNDERLAY_DUMMY_Message *) msg_iter;
658 // LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - id: %u, batch: %u, peer: %u\n",
659 LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - id: %" PRIu64
660 ", batch: %" PRIu64 "\n",
661 GNUNET_ntohll (msg_dbg->id),
662 GNUNET_ntohll (msg_dbg->batch));
663 // LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - size: %u\n",
664 // ntohs (msg_dbg->size));
665 // LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - (sanity) size msghdr: %u\n",
666 // sizeof (struct GNUNET_MessageHeader));
667 // LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - (sanity) size msg field: %u\n",
668 // sizeof (msg_dbg->id));
669 }
670 buf_iter = buf_iter + ntohs (msg_iter->size);
671 ret_remain = ret_remain - ntohs (msg_iter->size);
672 }
673
674 /* Enqueue the following messages */
675 /* skip the first message */
676 LOG (GNUNET_ERROR_TYPE_DEBUG, "Enqueueing messages\n");
677 buf_iter = buf + ntohs (msg->size);
678 ret_remain = ret - ntohs (msg->size);
679 /* iterate over the rest */
680 while (0 < ret_remain)
681 {
682 struct QueuedMessage *q_msg = GNUNET_new (struct QueuedMessage);
683
684 LOG (GNUNET_ERROR_TYPE_DEBUG, "Enqueueing message\n");
685 msg_iter = (struct GNUNET_MessageHeader *) buf_iter;
686 q_msg->msg = GNUNET_malloc (ntohs (msg_iter->size));
687 GNUNET_memcpy (q_msg->msg, msg_iter, ntohs (msg_iter->size));
689 connection->queued_recv_messages_tail,
690 q_msg);
691
692 buf_iter = buf_iter + ntohs (msg_iter->size);
693 ret_remain = ret_remain - ntohs (msg_iter->size);
694 }
695 }
696
697 /* check for and handle init */
698 if ((0 == ntohs (msg->type)) && /* 0 = GNUNET_MESSAGE_TYPE_TEST is deprecated - usage for this dummy should be fine */
699 (CONNECTION_LIVE != connection->status)) /* ignore if current connection is already live */
700 {
701 char *peer_addr_sent = (char *) &msg[1];
702 // FIXME is it really meaningful to send multiple addresses? probably just
703 // send the address that's used to open the connection
705 "Init-message: %s\n",
706 peer_addr_sent);
707 if ((NULL != connection->peer_addr) &&
708 (0 != strcmp (peer_addr_sent, connection->peer_addr)))
709 {
711 "Peer sent us an Init-message with an address different from the one we already know. -> MQ_destroy()\n");
713 "sent address: %s\n",
714 peer_addr_sent);
716 "old address: %s\n",
717 connection->peer_addr);
718 GNUNET_MQ_destroy (connection->mq);
719 GNUNET_break_op (0);
720 return;
721 }
722 switch (connection->status)
723 {
725 connection->status = CONNECTION_LIVE;
726 break;
729 break;
731 return;
732 default:
733 break;
734 }
736 "Connection to %s is now %s\n",
737 connection->peer_addr,
738 status2string (connection->status));
739 // else: we could skip ahead to end of if - we do already know the peer_addr
740 /* Check whether we already got a connection to that address/peer */
741 LOG (GNUNET_ERROR_TYPE_DEBUG, "Init - checking other connections\n");
742 for (struct Connection *c_iter = connection->handle->connections_head;
743 NULL != c_iter;
744 c_iter = c_iter->next)
745 {
747 " %s (%s)\n",
748 c_iter->peer_addr,
749 status2string (c_iter->status));
750 if ((NULL != c_iter->peer_addr) && /* we can't compare the addr */
751 (0 == strcmp (peer_addr_sent, c_iter->peer_addr)) && /* same peer */
752 (CONNECTION_LIVE == c_iter->status) && /* other connection is live*/
753 (connection != c_iter)) /* discovered the currently handled connection - skip */
754 {
755 /* We already got a connection with this peer - tear the current one
756 * down. */
758 "Init from other peer - already connected: %s - MQ_destroy()\n",
759 peer_addr_sent);
760 connection->status = CONNECTION_DESTROY;
761 GNUNET_MQ_destroy (connection->mq);
762 return;
763 }
764 }
765 connection->peer_addr = strdup (peer_addr_sent);
767 "Init-Message - notifying caller (%s :%s)\n",
768 connection->peer_addr,
769 status2string (connection->status));
770
771 try_notify_connect (connection);
773 "Finished initializing - going to cancel all still initializing connections to this address\n");
774 cancel_initiating_connections (connection->handle, connection);
775
776 /* We need to schedule the recv_task here because this is not a message
777 * passed to the caller an thus the caller will not call
778 * GNUNET_CORE_UNDERLAY_DUMMY_receive_continue () which usually schedules
779 * the recv_task */
780 connection->recv_task =
782 connection->sock,
783 do_read,
784 connection);
785 return;
786 }
787 else if ((0 == ntohs (msg->type)) && /* 0 = GNUNET_MESSAGE_TYPE_TEST is deprecated - usage for this dummy should be fine */
788 (CONNECTION_LIVE == connection->status))
789 {
790 /* We need to schedule the recv_task here because this is not a message
791 * passed to the caller an thus the caller will not call
792 * GNUNET_CORE_UNDERLAY_DUMMY_receive_continue () which usually schedules
793 * the recv_task */
794 connection->recv_task =
796 connection->sock,
797 do_read,
798 connection);
799 return;
800 }
801
802 if (GNUNET_NO == connection->notify_connect_called)
803 {
804 /* Notify connect has not been called yet - the caller doesn't know about
805 * this connection. Enqueue the first message, too; instead of handling it.
806 */
807 struct QueuedMessage *q_msg = GNUNET_new (struct QueuedMessage);
808
809 q_msg->msg = GNUNET_malloc (ntohs (msg->size));
810 GNUNET_memcpy (q_msg->msg, msg, ntohs (msg->size));
812 connection->queued_recv_messages_tail,
813 q_msg);
814 return;
815 }
816
817 if (GNUNET_YES == connection->client_ready_to_receive)
818 {
819 // TODO maybe just call check_for_messages() instead?
820 // check_for_messages (connection);
821 // FIXME for now the above gives only an unsuccessful test - check why
823 // FIXME check return value!!!
825 }
826 // else TODO
827}
828
829
836static void
837write_cb (void *cls)
838{
839 ssize_t sent;
840 struct Connection *connection = cls;
841
842 connection->write_task = NULL;
843 GNUNET_assert (NULL != connection->sock);
845 "write_cb(): sending bytes to %s :%s\n",
846 connection->peer_addr,
847 status2string (connection->status));
848 {
849 // XXX only for debugging purposes
850 // this shows everything works as expected
851
852 struct GNUNET_UNDERLAY_DUMMY_Message
853 {
854 struct GNUNET_MessageHeader header;
855 // The following will be used for debugging
856 uint64_t id; // id of the message
857 uint64_t batch; // first batch of that peer (for this test 0 or 1)
858 // uint64_t peer; // number of sending peer (for this test 0 or 1)
859 };
860
861
862 struct GNUNET_UNDERLAY_DUMMY_Message *msg_dbg =
863 (struct GNUNET_UNDERLAY_DUMMY_Message *) connection->message_to_send;
864 // LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - id: %u, batch: %u, peer: %u\n",
865 LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - id: %" PRIu64 ", batch: %" PRIu64
866 "\n",
867 GNUNET_ntohll (msg_dbg->id),
868 GNUNET_ntohll (msg_dbg->batch));
869 // LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - size: %u\n",
870 // ntohs (msg_dbg->size));
871 // LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - (sanity) size msghdr: %u\n",
872 // sizeof (struct GNUNET_MessageHeader));
873 // LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - (sanity) size msg field: %u\n",
874 // sizeof (msg_dbg->id));
875 }
876 GNUNET_assert (NULL != connection->message_to_send);
878 connection->sock,
879 connection->message_to_send,
880 ntohs (connection->message_to_send->size));
881 if (GNUNET_SYSERR == sent)
882 {
883 // LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to send message\n");
884 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to send message: %s\n", strerror (
885 errno));
886 if (EPIPE == errno)
887 {
888 /* Tear down the connection */
889 LOG (GNUNET_ERROR_TYPE_DEBUG, "MQ_destroy() (Failed to send message)\n");
890 connection->status = CONNECTION_DESTROY;
891 GNUNET_MQ_destroy (connection->mq); // This triggers mq_destroy_impl()
892 return;
893 }
894 LOG (GNUNET_ERROR_TYPE_ERROR, "Retrying (due to failure)\n");
895 /* retry */
896 connection->write_task =
898 connection->sock,
899 &write_cb,
900 connection);
901 return; // TODO proper handling - don't try to resend on certain errors
902 // (e.g. EPIPE as above)
903 }
904 LOG (GNUNET_ERROR_TYPE_DEBUG, "Successfully sent message\n");
905 connection->message_to_send = NULL;
906 switch (connection->status)
907 {
909 connection->status = CONNECTION_LIVE;
910 try_notify_connect (connection);
912 "Finished initializing - going to cancel all still initializing connections to this address\n");
913 cancel_initiating_connections (connection->handle, connection);
914 break;
917 break;
919 return;
920 default:
921 break;
922 }
924 "Connection to %s is now %s\n",
925 connection->peer_addr,
926 status2string (connection->status));
927 GNUNET_MQ_impl_send_continue (connection->mq);
928}
929
930
931static void
932send_init (struct Connection *connection)
933{
934 struct GNUNET_MQ_Envelope *env;
936 uint32_t peer_addr_len;
937
938 GNUNET_assert (NULL != connection->handle->sock_name);
940 "Sending init: %s\n",
941 connection->handle->sock_name);
942 peer_addr_len = strnlen (connection->handle->sock_name, 128) + 1;
943 env = GNUNET_MQ_msg_header_extra (msg, // usually we wanted to keep the
944 peer_addr_len, // envelopes to potentially cancel the
945 0); // message
946 GNUNET_memcpy (&msg[1], connection->handle->sock_name, peer_addr_len);
947 GNUNET_MQ_send (connection->mq, env);
948}
949
950
959static void
961 const struct GNUNET_MessageHeader *msg,
962 void *impl_state)
963{
964 struct Connection *connection = impl_state;
965
966 LOG (GNUNET_ERROR_TYPE_DEBUG, "from mq_send_impl\n");
967 {
968 // XXX only for debugging purposes
969 // this shows everything works as expected
970
971 struct GNUNET_UNDERLAY_DUMMY_Message
972 {
973 struct GNUNET_MessageHeader header;
974 // The following will be used for debugging
975 uint64_t id; // id of the message
976 uint64_t batch; // first batch of that peer (for this test 0 or 1)
977 // uint64_t peer; // number of sending peer (for this test 0 or 1)
978 };
979
980 struct GNUNET_UNDERLAY_DUMMY_Message *msg_dbg =
981 (struct GNUNET_UNDERLAY_DUMMY_Message *) msg;
982 LOG (GNUNET_ERROR_TYPE_DEBUG, "id: %" PRIu64 ", batch: %" PRIu64 "\n",
983 GNUNET_ntohll (msg_dbg->id),
984 GNUNET_ntohll (msg_dbg->batch));
985 }
986 connection->message_to_send = msg;
987 GNUNET_assert (NULL == connection->write_task);
988 connection->write_task =
990 connection->sock,
991 &write_cb,
992 connection);
993 LOG (GNUNET_ERROR_TYPE_DEBUG, "Scheduled sending of message\n");
994}
995
996
1003static void
1004mq_destroy_impl (struct GNUNET_MQ_Handle *mq, void *impl_state)
1005{
1006 struct Connection *connection = impl_state;
1007
1008 LOG (GNUNET_ERROR_TYPE_DEBUG, "mq_destroy_impl\n");
1009 connection_destroy (connection);
1010}
1011
1012
1019static void
1020mq_cancel_impl (struct GNUNET_MQ_Handle *mq, void *impl_state)
1021{
1022 struct Connection *connection = impl_state;
1023
1024 if (NULL != connection->write_task)
1025 {
1026 GNUNET_SCHEDULER_cancel (connection->write_task);
1027 connection->write_task = NULL;
1028 }
1029}
1030
1031
1040static void
1042{
1044 "mq_error_handler_impl: %u\n",
1045 error);
1046}
1047
1048
1054static void
1055do_accept (void *cls)
1056{
1058
1059 struct Connection *connection;
1060 struct GNUNET_NETWORK_Handle *sock;
1061 struct sockaddr_un addr_other;
1062 socklen_t addr_other_len = sizeof(addr_other);
1063 memset (&addr_other, 0, sizeof (addr_other));
1064
1066 h->sock_listen,
1067 do_accept,
1068 h);
1069
1070 LOG (GNUNET_ERROR_TYPE_DEBUG, "Handling incoming connection\n");
1071
1072 GNUNET_assert (NULL != h->sock_listen);
1073
1074 LOG (GNUNET_ERROR_TYPE_INFO, "Accepting incoming connection\n");
1075 sock = GNUNET_NETWORK_socket_accept (h->sock_listen,
1076 (struct sockaddr *) &addr_other,
1077 &addr_other_len);
1078 if (NULL == sock)
1079 {
1080 // LOG(GNUNET_ERROR_TYPE_ERROR, "Error accepting incoming connection, %s", strerror(errno));
1081 LOG (GNUNET_ERROR_TYPE_ERROR, "Error accepting incoming connection\n");
1082 return;
1083 }
1085 {
1087 "Failed setting socket of incoming connection to non-blocking\n");
1088 return;
1089 }
1090 connection = GNUNET_new (struct Connection);
1091 connection->sock = sock;
1092 connection->peer_addr = NULL; // GNUNET_strdup (addr_other.sun_path); should
1093 // be empty
1094 connection->handle = h;
1095 connection->notify_connect_called = GNUNET_NO;
1096 connection->client_ready_to_receive = GNUNET_NO;
1097 connection->status = CONNECTION_INITIALIZING;
1098 LOG (GNUNET_ERROR_TYPE_INFO, "Peer connected\n");
1099 GNUNET_CONTAINER_DLL_insert (h->connections_head,
1100 h->connections_tail,
1101 connection);
1102 connection->mq =
1106 connection, // impl_state - gets passed to _impls
1107 h->handlers,
1109 connection->cls_mq);
1110 connection->recv_task =
1112 connection->sock,
1113 do_read,
1114 connection);
1115 send_init (connection);
1116}
1117
1118
1127static void
1129{
1130 struct PeerConnectCls *pcc = cls;
1131
1132 pcc->peer_connect_task = NULL;
1135 pcc);
1136 {
1137 struct Connection *connection;
1138 struct GNUNET_CORE_UNDERLAY_DUMMY_Handle *h = pcc->h;
1139 struct sockaddr_un addr_other;
1140 memset (&addr_other, 0, sizeof (addr_other));
1141
1142 connection = GNUNET_new (struct Connection);
1143 connection->handle = pcc->h;
1144 connection->sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
1145 connection->peer_addr = pcc->sock_name;
1146 connection->notify_connect_called = GNUNET_NO;
1147 connection->client_ready_to_receive = GNUNET_NO;
1148 connection->status = CONNECTION_INITIALIZING;
1149 if (NULL == connection->sock)
1150 {
1151 LOG (GNUNET_ERROR_TYPE_ERROR, "Socket does not open\n");
1152 GNUNET_free (connection);
1153 return;
1154 }
1155 if (GNUNET_OK !=
1157 {
1158 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed setting socket to non-blocking\n");
1159 GNUNET_free (connection);
1160 return;
1161 }
1162
1163 addr_other.sun_family = AF_UNIX;
1164 // strcpy (addr_other.sun_path, pcc->sock_name);
1165 GNUNET_memcpy (addr_other.sun_path, pcc->sock_name, strlen (pcc->sock_name))
1166 ;
1167 if (GNUNET_OK != GNUNET_NETWORK_socket_connect (connection->sock,
1168 (struct sockaddr *) &
1169 addr_other,
1170 sizeof(addr_other)))
1171 {
1173 "failed to connect to the socket: %u %s (closing socket)\n",
1174 errno, strerror (errno));
1175 GNUNET_NETWORK_socket_close (connection->sock);
1176 GNUNET_free (connection);
1177 // LOG (GNUNET_ERROR_TYPE_INFO, "Sanity check: %s\n", addr_other.sun_path);
1178 return;
1179 }
1180 connection->peer_addr = GNUNET_strdup (pcc->sock_name);
1181 LOG (GNUNET_ERROR_TYPE_INFO, "Successfully connected to socket\n");
1182 connection->recv_task =
1184 connection->sock,
1185 do_read,
1186 connection);
1187 connection->mq =
1191 connection, // impl_state - gets passed to _impls
1192 h->handlers,
1194 connection->cls_mq);
1195 GNUNET_CONTAINER_DLL_insert (h->connections_head,
1196 h->connections_tail,
1197 connection);
1198 send_init (connection);
1199
1200 // FIXME: proper array
1201 // FIXME: proper address format ("dummy:<sock_name>")
1202 }
1203 GNUNET_free (pcc->sock_name);
1204 GNUNET_free (pcc);
1205}
1206
1207
1216static void
1218{
1220 const char *addresses[1] = {h->sock_name}; // The dummy will only ever know
1221 // about this one address
1222
1223 h->notify_address_change_task = NULL;
1224 h->notify_address_change (h->cls, 1, addresses);
1225}
1226
1227
1228static void
1230{
1231 GNUNET_assert (0 != strcmp (address, ""));
1232 LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to connect to socket: `%s'\n", address);
1233 if (0 == strcmp (address, h->sock_name))
1234 {
1235 LOG (GNUNET_ERROR_TYPE_DEBUG, "Not going to connect to own address\n");
1236 return;
1237 }
1239 "Discovered another peer with address `%s'\n",
1240 address);
1241
1247 LOG (GNUNET_ERROR_TYPE_DEBUG, "checking other connections:\n");
1248 for (struct Connection *conn_iter = h->connections_head;
1249 NULL != conn_iter;
1250 conn_iter = conn_iter->next)
1251 {
1253 " %s (%s)\n",
1254 conn_iter->peer_addr,
1255 status2string (conn_iter->status));
1256 if ((NULL != conn_iter->peer_addr) &&
1257 (0 == strcmp (address, conn_iter->peer_addr)) &&
1258 (CONNECTION_LIVE == conn_iter->status))
1259 {
1261 "Already connected to this peer - don't try to open another connection\n");
1262 return;
1263 }
1264 }
1265 for (struct PeerConnectCls *pcc_iter = h->peer_connect_cls_head;
1266 NULL != pcc_iter;
1267 pcc_iter = pcc_iter->next)
1268 {
1269 if (0 == strcmp (address,
1270 pcc_iter->sock_name))
1271 {
1272 LOG (GNUNET_ERROR_TYPE_DEBUG, "Already waiting to connect to this peer\n")
1273 ;
1274 return;
1275 }
1276 }
1277
1278 {
1279 struct PeerConnectCls *peer_connect_cls;
1280 peer_connect_cls = GNUNET_new (struct PeerConnectCls);
1281 peer_connect_cls->h = h;
1282 peer_connect_cls->sock_name = GNUNET_strdup (address);
1283 peer_connect_cls->peer_connect_task =
1285 peer_connect_cls);
1286 GNUNET_CONTAINER_DLL_insert (h->peer_connect_cls_head,
1287 h->peer_connect_cls_tail,
1288 peer_connect_cls);
1289 }
1290}
1291
1292
1308static enum GNUNET_GenericReturnValue
1310 const char *filename)
1311{
1313
1315
1316 return GNUNET_OK;
1317}
1318
1319
1327static void
1329{
1331 int ret;
1332
1333 ret = GNUNET_DISK_glob (SOCK_NAME_BASE "*" SOCK_EXTENSION,
1335 h);
1336 if (0 > ret)
1337 {
1338 LOG (GNUNET_ERROR_TYPE_WARNING, "Scanning for unix domain sockets failed\n")
1339 ;
1340 }
1341
1342 h->peer_discovery_task = GNUNET_SCHEDULER_add_delayed (
1345 h);
1346}
1347
1348
1349static enum GNUNET_GenericReturnValue
1351 char *sock_name)
1352{
1353 struct sockaddr_un *addr_un;
1354 socklen_t addr_un_len;
1355 uint8_t ret = GNUNET_NO;
1356
1357 h->sock_listen = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
1358 GNUNET_assert (NULL != h->sock_listen);
1359 LOG (GNUNET_ERROR_TYPE_DEBUG, "Opened socket, going to bind to address\n");
1360
1361 addr_un = GNUNET_new (struct sockaddr_un);
1362 addr_un->sun_family = AF_UNIX;
1363 // TODO check that the string is not too long
1364 GNUNET_memcpy (&addr_un->sun_path, sock_name, strlen (sock_name));
1365 addr_un_len = sizeof (struct sockaddr_un);
1366 LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to bind to `%s'\n", addr_un->sun_path);
1367 ret = GNUNET_NETWORK_socket_bind (h->sock_listen,
1368 (struct sockaddr *) addr_un,
1369 addr_un_len);
1370 if ((GNUNET_OK != ret) && (98 != errno))
1371 {
1372 /* Error different from Address already in use - cancel */
1374 "Failed binding to socket: %u %s (closing socket)\n",
1375 errno, strerror (errno));
1376 GNUNET_NETWORK_socket_close (h->sock_listen);
1377 h->sock_listen = NULL;
1378 GNUNET_free (addr_un);
1379 return GNUNET_SYSERR;
1380 }
1381 else if (GNUNET_OK != ret)
1382 {
1384 " -> something went wrong (address is probably in use)\n");
1385 GNUNET_NETWORK_socket_close (h->sock_listen);
1386 h->sock_listen = NULL;
1387 GNUNET_free (addr_un);
1388 }
1389 else if (GNUNET_OK == ret)
1390 {
1392 " -> succeeded! (binding to socket)\n");
1393 h->sock_name = GNUNET_strdup (sock_name);
1394 }
1395 GNUNET_free (addr_un);
1396 return ret;
1397}
1398
1399
1410static void
1412 uint64_t sock_name_ctr_start)
1413{
1415 char *sock_name;
1416 uint64_t sock_name_ctr = sock_name_ctr_start; // Append to the socket name to avoid collisions
1417 uint8_t ret = GNUNET_NO;
1418
1419 /* Open a socket that's not occupied by another 'peer' yet:
1420 * Try opening sockets with an increasing counter in the socket name. */
1421 // TODO we might want to change this loop to schedule a new task
1422 do {
1424 SOCK_NAME_BASE "%" PRIu64 "" SOCK_EXTENSION "\0",
1425 sock_name_ctr++);
1428 if (GNUNET_SYSERR == ret)
1429 return;
1430 } while (GNUNET_YES != ret);
1431 LOG (GNUNET_ERROR_TYPE_INFO, "Bound to `%s'\n", h->sock_name);
1432 h->sock_name_index_start = sock_name_ctr_start;
1433 h->sock_name_index = sock_name_ctr;
1434
1435 LOG (GNUNET_ERROR_TYPE_DEBUG, "Mark socket as accepting connections\n");
1436 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (h->sock_listen, BACKLOG))
1437 {
1438 // LOG (GNUNET_ERROR_TYPE_ERROR, "Failed listening to socket: %s", strerror(errno));
1440 "Failed listening to socket (closing socket)\n");
1442 h->sock_listen = NULL;
1443 GNUNET_free (h->sock_name);
1444 return;
1445 }
1446
1447 if (NULL != h->notify_address_change)
1448 {
1449 // TODO cancel and cleanup task on run and shutdown
1450 LOG (GNUNET_ERROR_TYPE_DEBUG, "schedlue do_notify_address_change()\n");
1451 h->notify_address_change_task =
1453 }
1454
1455 LOG (GNUNET_ERROR_TYPE_DEBUG, "scheudle do_discover_peers()\n");
1456 h->peer_discovery_task = GNUNET_SCHEDULER_add_delayed (
1459 h);
1460
1461 LOG (GNUNET_ERROR_TYPE_INFO, "Going to listen for connections\n");
1463 h->sock_listen,
1464 do_accept,
1465 h);
1466}
1467
1468
1469// TODO
1470static void
1472{
1474 struct PeerConnectCls *pcc_next;
1475 struct Connection *conn_next;
1476
1477 if (NULL != h->notify_address_change_task)
1478 {
1479 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling notify address change task\n");
1480 GNUNET_SCHEDULER_cancel (h->notify_address_change_task);
1481 h->notify_address_change_task = NULL;
1482 }
1483 if (NULL != h->peer_discovery_task)
1484 {
1485 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling peer discovery task\n");
1486 GNUNET_SCHEDULER_cancel (h->peer_discovery_task);
1487 h->peer_discovery_task = NULL;
1488 }
1489 for (struct PeerConnectCls *pcc = h->peer_connect_cls_head;
1490 NULL != pcc;
1491 pcc = pcc_next)
1492 {
1493 pcc_next = pcc->next;
1494 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling peer connect task\n");
1495 GNUNET_SCHEDULER_cancel (pcc->peer_connect_task);
1496 GNUNET_CONTAINER_DLL_remove (h->peer_connect_cls_head,
1497 h->peer_connect_cls_tail,
1498 pcc);
1499 GNUNET_free (pcc->sock_name);
1500 GNUNET_free (pcc);
1501 }
1502 if (NULL != h->listen_task)
1503 {
1504 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling listen task\n");
1505 GNUNET_SCHEDULER_cancel (h->listen_task);
1506 h->listen_task = NULL;
1507 }
1508 if (NULL != h->sock_listen)
1509 {
1510 LOG (GNUNET_ERROR_TYPE_DEBUG, "closing socket\n");
1511 GNUNET_NETWORK_socket_close (h->sock_listen);
1512 h->sock_listen = NULL;
1513 }
1514 for (struct Connection *conn_iter = h->connections_head;
1515 NULL != conn_iter;
1516 conn_iter = conn_next)
1517 {
1518 // TODO consider moving MQ_destroy() into connection_destroy(), but keep in
1519 // mind that connection_destroy() is also called from within
1520 // mq_destroy_impl()
1521 conn_next = conn_iter->next;
1522 LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying a connection - MQ_destroy()\n");
1523 conn_iter->status = CONNECTION_DESTROY;
1524 GNUNET_MQ_destroy (conn_iter->mq); // This triggers mq_destroy_impl()
1525 }
1526}
1527
1528
1546 const struct GNUNET_CONFIGURATION_Handle *cfg,
1547 const struct GNUNET_MQ_MessageHandler *handlers,
1548 void *cls,
1552{
1554
1556 h->notify_connect = nc;
1557 h->notify_disconnect = nd;
1558 h->notify_address_change = na;
1559 if (NULL != handlers)
1560 h->handlers = GNUNET_MQ_copy_handlers (handlers);
1561 h->cls = cls;
1562
1564
1565 // h->address_change_task = GNUNET_SCHEDULER_add_delayed (
1566 // GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5),
1567 // do_change_address,
1568 // h);
1569
1570 LOG (GNUNET_ERROR_TYPE_INFO, "Core connected\n");
1571
1572 return h;
1573}
1574
1575
1581void
1584{
1585 LOG (GNUNET_ERROR_TYPE_INFO, "Core disconnects\n");
1586 // TODO delete, free and close everything
1587 if (NULL != handle->address_change_task)
1588 GNUNET_SCHEDULER_cancel (handle->address_change_task);
1590 if (NULL != handle->handlers)
1591 GNUNET_free (handle->handlers);
1592 GNUNET_free (handle->sock_name);
1594 LOG (GNUNET_ERROR_TYPE_INFO, " -> Disconnected\n");
1595}
1596
1597
1618void
1619GNUNET_CORE_UNDERLAY_DUMMY_receive_continue (
1621 struct GNUNET_MQ_Handle *mq)
1622{
1623 struct Connection *connection;
1624
1625 LOG (GNUNET_ERROR_TYPE_DEBUG, "from _receive_continue()\n");
1626
1627 /* Find the connection belonging to the mq */
1628 for (struct Connection *conn_iter = h->connections_head;
1629 NULL != conn_iter;
1630 conn_iter = conn_iter->next)
1631 {
1632 if (mq == conn_iter->mq)
1633 {
1634 connection = conn_iter;
1635 }
1636 }
1637 GNUNET_assert (NULL != connection);
1638 connection->recv_task = NULL;
1639 connection->client_ready_to_receive = GNUNET_YES;
1640 check_for_messages (connection);
1641}
1642
1643
1657void
1658GNUNET_CORE_UNDERLAY_DUMMY_connect_to_peer (
1660 const char *peer_address,
1663{
1664 // TODO PriorityPreferences
1665 // TODO BANDWIDTH_Value
1666 try_connect (h, peer_address);
1667}
1668
1669
1673void
1674GNUNET_CORE_UNDERLAY_DUMMY_change_address (
1676{
1677 LOG (GNUNET_ERROR_TYPE_DEBUG, "Changing address!\n");
1679 if (0 == h->sock_name_index_start)
1680 {
1682 }
1683 else
1684 {
1686 }
1687}
1688
1689
1690#if 0 /* keep Emacsens' auto-indent happy */
1691{
1692#endif
1693#ifdef __cplusplus
1694}
1695#endif
1696
1697
/* end of group */
1699
/* end of group addition */
1701
1702/* 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:1063
#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:716
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:832
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:601
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:737
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:651
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
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
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
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:1310
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:1283
#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:141
Closure used for the peer_connect_task.