GNUnet debian-0.24.3-23-g589b01d60
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#define SOCK_NAME_BASE "/tmp/gnunet-core-underlay-dummy-socket"
58#define SOCK_EXTENSION ".sock"
59#define BUFF_SIZE 8192
60#define BACKLOG 10
61
62
67{
72
77
82
86 char *sock_name;
87
92};
93
94
96{
99
101};
102
103
105{
106 /* Created, but neither received, nor sent anything over it */
108
109 /* Created and successfully sent something (probably init) */
111
112 /* Created and successfully received something (probably init) */
114
115 /* Live - usable - successfully received and sent something (probably init) */
117
118 /* In the process of destruction */
120};
121
122
127{
132
137
142
147
153 void *cls_mq;
154
159
164
169
174
179
184
190
199
204
210
218
223};
224
225
230{
235
240
245
251
257 void *cls;
258
263
264 // TODO
266 // TODO
268
273
278
283
288
289 // TODO
291
296
301
306
311};
312
313
314static const char *
316{
317 switch (status)
318 {
320 return "C_INITIALIZING";
321 break;
323 return "C_INITIALIZING_SEND";
324 break;
326 return "C_INITIALIZING_RECV";
327 break;
328 case CONNECTION_LIVE:
329 return "C_LIVE";
330 break;
332 return "C_DESTROY";
333 break;
334 }
335 return ""; /* Make compiler happy */
336}
337
338
345static void
346do_read (void *cls);
347
348
349/*****************************************************************************
350 * Connection-related functions *
351 ****************************************************************************/
352
361static void
362connection_destroy (struct Connection *connection)
363{
364 /* The mq should already be cleaned as this function is called from within
365 * mq_destroy_impl. */
366 LOG (GNUNET_ERROR_TYPE_DEBUG, "connection_destroy\n");
367 if ((NULL != connection->handle->notify_disconnect) &&
368 (GNUNET_YES == connection->notify_connect_called))
369 {
370 /* Call the notify disconnect only if the notify_connect_task has been
371 * executed and the client was actually notified about the connection */
372 connection->handle->notify_disconnect (connection->handle->cls, /* connection-independant cls */
373 connection->cls_mq); /* connection-specific cls */
374 }
375 if (NULL != connection->notify_connect_task)
376 {
377 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling notify connect task\n");
379 }
380 if (NULL != connection->handle_message_task)
381 {
382 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling handle message task\n");
384 }
385 if (NULL != connection->write_task)
386 {
387 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling write task\n");
389 }
390 if (NULL != connection->recv_task)
391 {
392 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling recv task\n");
394 }
395 if (NULL != connection->sock)
396 {
397 LOG (GNUNET_ERROR_TYPE_DEBUG, "closing socket\n");
398 GNUNET_NETWORK_socket_close (connection->sock);
399 }
400 GNUNET_free (connection->peer_addr);
401 if (NULL != connection->handlers) GNUNET_free (connection->handlers);
402 /* Don't free the cls_mq - we don't own it! */
404 connection->handle->connections_tail,
405 connection);
406 GNUNET_free (connection);
407 LOG (GNUNET_ERROR_TYPE_DEBUG, "connection_destroy - end\n");
408}
409
410/*****************************************************************************
411 * Connection-related functions (end) *
412 ****************************************************************************/
413
414
424static void
426 void *handlers_cls)
427{
428 GNUNET_assert (NULL != handlers);
429
430 for (unsigned int i = 0; NULL != handlers[i].cb; i++)
431 handlers[i].cls = handlers_cls;
432}
433
434
435static void
437{
438 struct Connection *connection = cls;
439 struct QueuedMessage *q_msg = connection->queued_recv_messages_head;
440 struct GNUNET_MessageHeader *msg = q_msg->msg;
441
442 connection->handle_message_task = NULL;
445 connection->queued_recv_messages_head,
446 connection->queued_recv_messages_tail,
447 q_msg);
448 GNUNET_free (q_msg);
449 // FIXME check return value!!!
451 connection->handlers,
452 msg);
453 //GNUNET_free (msg); // TODO what do we do with this pointer? Who owns it?
454 // Who cleans it?
455}
456
457
458static void
459check_for_messages (struct Connection *connection)
460{
461 if (NULL != connection->queued_recv_messages_head)
462 {
463 LOG (GNUNET_ERROR_TYPE_DEBUG, "got messages in the queue - handle those\n");
464 GNUNET_assert (NULL == connection->handle_message_task);
465 connection->handle_message_task =
467 }
468 else if (NULL == connection->recv_task)
469 {
470 LOG (GNUNET_ERROR_TYPE_DEBUG, "no messages in the queue - receive more from socket\n");
471 connection->recv_task =
473 connection->sock,
474 do_read,
475 connection);
476 }
477}
478
479
488static void
490{
491 struct Connection *connection = cls;
492 struct GNUNET_CORE_UNDERLAY_DUMMY_Handle *h = connection->handle;
493 void *cls_mq;
494
495 connection->notify_connect_task = NULL;
496 connection->notify_connect_called = GNUNET_YES;
498 /* The global, connection-independant closure is given to notify_connect,
499 * notify_disconnect and notify_address_change, whereas the
500 * connection-specific cls is the return value of notify_connect and given to
501 * the handlers. */
502 cls_mq =
503 h->notify_connect(h->cls,
504 1,
505 (const char **) &connection->peer_addr,
506 connection->mq,
507 NULL); /* peer_id */
508 /* The handlers are copied because the connection-specific closures can be
509 * set. The global handlers remain the same - they are just called with the
510 * connection specific closures. */
511 connection->handlers = GNUNET_MQ_copy_handlers (h->handlers);
512 set_handlers_closure (connection->handlers, h->cls); /* in case there's no connection-specific closure */
513 if (NULL != cls_mq)
514 {
515 connection->cls_mq = cls_mq;
516 //GNUNET_MQ_set_handlers_closure (connection->mq, connection->cls_mq);
517 /* Overwrite the closure set above with the cls_mq */
518 set_handlers_closure (connection->handlers, connection->cls_mq);
519 }
520
521 /* Handle already enqueued messages */
522 check_for_messages (connection);
523}
524
525
526static void
527try_notify_connect (struct Connection *connection)
528{
529 if ((NULL != connection->peer_addr) &&
530 (CONNECTION_LIVE == connection->status) &&
531 (NULL != connection->handle->notify_connect) &&
532 (NULL == connection->notify_connect_task))
533 {
534 connection->notify_connect_task =
536 }
537}
538
539
540static void
542 struct Connection *connection)
543{
544 struct Connection *c_iter_next;
545 char *peer_addr = connection->peer_addr;
546
548 "Going to cancle all initializing connections to %s\n",
549 peer_addr);
550 if (NULL == peer_addr) return; /* No sense in comparing to unknown address */
551 for (struct Connection *c_iter = h->connections_head;
552 NULL != c_iter;
553 c_iter = c_iter_next)
554 {
555 c_iter_next = c_iter->next;
557 " %s :%s\n",
558 c_iter->peer_addr,
559 status2string (c_iter->status));
560 if ((c_iter != connection) && /* Don't shut down current connection */
561 (NULL != c_iter->peer_addr) && /* No address - can't compare */
562 (0 == strcmp (c_iter->peer_addr, peer_addr)) &&
563 (
564 (CONNECTION_INITIALIZING == c_iter->status) ||
565 (CONNECTION_INITIALIZING_SEND == c_iter->status) ||
566 (CONNECTION_INITIALIZING_RECV == c_iter->status)))
567 {
569 " -> Cancelling connection - MQ_destroy()\n");
570 GNUNET_MQ_destroy (c_iter->mq);
571 }
572 }
573}
574
575
582static void
583do_read (void *cls)
584{
585 struct Connection *connection = cls;
586
587 char buf[65536] GNUNET_ALIGN;
588 ssize_t ret;
590
592 "do_read(): receiving bytes from %s :%s\n",
593 connection->peer_addr,
594 status2string (connection->status));
595 connection->recv_task = NULL;
596 GNUNET_assert (NULL != connection->sock);
597 ret = GNUNET_NETWORK_socket_recv (connection->sock,
598 &buf,
599 sizeof(buf));
600 if (0 > ret)
601 {
602 LOG (GNUNET_ERROR_TYPE_ERROR, "Error reading from socket - MQ_destroy()\n");
603 connection->status = CONNECTION_DESTROY;
604 GNUNET_MQ_destroy (connection->mq); // This triggers mq_destroy_impl()
605 return;
606 }
607 if (0 == ret)
608 {
609 LOG (GNUNET_ERROR_TYPE_INFO, "Other peer closed connection - MQ_destroy()\n");
610 connection->status = CONNECTION_DESTROY;
611 GNUNET_MQ_destroy (connection->mq); // This triggers mq_destroy_impl()
612 return;
613 }
614 LOG (GNUNET_ERROR_TYPE_DEBUG, "Read %d bytes\n", (int) ret);
615 GNUNET_assert (2 <= ret); /* has to have returned enough for one full msg_hdr */
616
617 /* Handle the message itself */
618 {
619 ssize_t ret_remain;
620 char *buf_iter;
621 struct GNUNET_MessageHeader *msg_iter;
622
623 msg = (struct GNUNET_MessageHeader *) buf;
624 ret_remain = ret;
625 buf_iter = buf;
626 /* Just debug logging */
627 while (0 < ret_remain)
628 {
629 msg_iter = (struct GNUNET_MessageHeader *) buf_iter;
630 LOG (GNUNET_ERROR_TYPE_DEBUG, "Length of message: %d bytes\n", ntohs (msg_iter->size));
631 LOG (GNUNET_ERROR_TYPE_DEBUG, "Remaining bytes of buffer: %ld\n", ret_remain);
632
633 {
634 // XXX only for debugging purposes
635 // this shows everything works as expected
636
637 struct GNUNET_UNDERLAY_DUMMY_Message
638 {
639 struct GNUNET_MessageHeader header;
640 // The following will be used for debugging
641 uint64_t id; // id of the message
642 uint64_t batch; // first batch of that peer (for this test 0 or 1)
643 //uint64_t peer; // number of sending peer (for this test 0 or 1)
644 };
645
646
647
648 struct GNUNET_UNDERLAY_DUMMY_Message *msg_dbg =
649 (struct GNUNET_UNDERLAY_DUMMY_Message *) msg_iter;
650 //LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - id: %u, batch: %u, peer: %u\n",
651 LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - id: %" PRIu64 ", batch: %" PRIu64 "\n",
652 GNUNET_ntohll (msg_dbg->id),
653 GNUNET_ntohll (msg_dbg->batch));
654 //LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - size: %u\n",
655 // ntohs (msg_dbg->size));
656 //LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - (sanity) size msghdr: %u\n",
657 // sizeof (struct GNUNET_MessageHeader));
658 //LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - (sanity) size msg field: %u\n",
659 // sizeof (msg_dbg->id));
660 }
661 buf_iter = buf_iter + ntohs (msg_iter->size);
662 ret_remain = ret_remain - ntohs (msg_iter->size);
663 }
664
665 /* Enqueue the following messages */
666 /* skip the first message */
667 LOG (GNUNET_ERROR_TYPE_DEBUG, "Enqueueing messages\n");
668 buf_iter = buf + ntohs (msg->size);
669 ret_remain = ret - ntohs (msg->size);
670 /* iterate over the rest */
671 while (0 < ret_remain)
672 {
673 struct QueuedMessage *q_msg = GNUNET_new (struct QueuedMessage);
674
675 LOG (GNUNET_ERROR_TYPE_DEBUG, "Enqueueing message\n");
676 msg_iter = (struct GNUNET_MessageHeader *) buf_iter;
677 q_msg->msg = GNUNET_malloc (ntohs (msg_iter->size));
678 GNUNET_memcpy (q_msg->msg, msg_iter, ntohs (msg_iter->size));
680 connection->queued_recv_messages_tail,
681 q_msg);
682
683 buf_iter = buf_iter + ntohs (msg_iter->size);
684 ret_remain = ret_remain - ntohs (msg_iter->size);
685 }
686 }
687
688 /* check for and handle init */
689 if ((0 == ntohs (msg->type)) && /* 0 = GNUNET_MESSAGE_TYPE_TEST is deprecated - usage for this dummy should be fine */
690 (CONNECTION_LIVE != connection->status)) /* ignore if current connection is already live */
691 {
692 char *peer_addr_sent = (char *) &msg[1];
693 // FIXME is it really meaningful to send multiple addresses? probably just
694 // send the address that's used to open the connection
696 "Init-message: %s\n",
697 peer_addr_sent);
698 if ((NULL != connection->peer_addr) &&
699 (0 != strcmp (peer_addr_sent, connection->peer_addr)))
700 {
702 "Peer sent us an Init-message with an address different from the one we already know. -> MQ_destroy()\n");
704 "sent address: %s\n",
705 peer_addr_sent);
707 "old address: %s\n",
708 connection->peer_addr);
709 GNUNET_MQ_destroy (connection->mq);
710 GNUNET_break_op (0);
711 return;
712 }
713 switch (connection->status)
714 {
716 connection->status = CONNECTION_LIVE;
717 break;
720 break;
722 return;
723 default:
724 break;
725 }
727 "Connection to %s is now %s\n",
728 connection->peer_addr,
729 status2string (connection->status));
730 // else: we could skip ahead to end of if - we do already know the peer_addr
731 /* Check whether we already got a connection to that address/peer */
732 LOG (GNUNET_ERROR_TYPE_DEBUG, "Init - checking other connections\n");
733 for (struct Connection *c_iter = connection->handle->connections_head;
734 NULL != c_iter;
735 c_iter = c_iter->next)
736 {
738 " %s (%s)\n",
739 c_iter->peer_addr,
740 status2string (c_iter->status));
741 if ((NULL != c_iter->peer_addr) && /* we can't compare the addr */
742 (0 == strcmp (peer_addr_sent, c_iter->peer_addr)) && /* same peer */
743 (CONNECTION_LIVE == c_iter->status) && /* other connection is live*/
744 (connection != c_iter)) /* discovered the currently handled connection - skip */
745 {
746 /* We already got a connection with this peer - tear the current one
747 * down. */
749 "Init from other peer - already connected: %s - MQ_destroy()\n",
750 peer_addr_sent);
751 connection->status = CONNECTION_DESTROY;
752 GNUNET_MQ_destroy (connection->mq);
753 return;
754 }
755 }
756 connection->peer_addr = strdup (peer_addr_sent);
758 "Init-Message - notifying caller (%s :%s)\n",
759 connection->peer_addr,
760 status2string (connection->status));
761
762 try_notify_connect (connection);
764 "Finished initializing - going to cancle all still initializing connections to this address\n");
765 cancle_initiating_connections (connection->handle, connection);
766
767 /* We need to schedule the recv_task here because this is not a message
768 * passed to the caller an thus the caller will not call
769 * GNUNET_CORE_UNDERLAY_DUMMY_receive_continue () which usually schedules
770 * the recv_task */
771 connection->recv_task =
773 connection->sock,
774 do_read,
775 connection);
776 return;
777 }
778 else if ((0 == ntohs (msg->type)) && /* 0 = GNUNET_MESSAGE_TYPE_TEST is deprecated - usage for this dummy should be fine */
779 (CONNECTION_LIVE == connection->status))
780 {
781 /* We need to schedule the recv_task here because this is not a message
782 * passed to the caller an thus the caller will not call
783 * GNUNET_CORE_UNDERLAY_DUMMY_receive_continue () which usually schedules
784 * the recv_task */
785 connection->recv_task =
787 connection->sock,
788 do_read,
789 connection);
790 return;
791 }
792
793 if (GNUNET_NO == connection->notify_connect_called)
794 {
795 /* Notify connect has not been called yet - the caller doesn't know about
796 * this connection. Enqueue the first message, too; instead of handling it.
797 */
798 struct QueuedMessage *q_msg = GNUNET_new (struct QueuedMessage);
799
800 q_msg->msg = GNUNET_malloc (ntohs (msg->size));
801 GNUNET_memcpy (q_msg->msg, msg, ntohs (msg->size));
803 connection->queued_recv_messages_tail,
804 q_msg);
805 return;
806 }
807
808 if (GNUNET_YES == connection->client_ready_to_receive)
809 {
810 // TODO maybe just call check_for_messages() instead?
811 //check_for_messages (connection);
812 // FIXME for now the above gives only an unsuccessful test - check why
814 // FIXME check return value!!!
816 }
817 // else TODO
818}
819
820
827static void
828write_cb (void *cls)
829{
830 ssize_t sent;
831 struct Connection *connection = cls;
832
833 connection->write_task = NULL;
834 GNUNET_assert (NULL != connection->sock);
836 "write_cb(): sending bytes to %s :%s\n",
837 connection->peer_addr,
838 status2string (connection->status));
839 {
840 // XXX only for debugging purposes
841 // this shows everything works as expected
842
843 struct GNUNET_UNDERLAY_DUMMY_Message
844 {
845 struct GNUNET_MessageHeader header;
846 // The following will be used for debugging
847 uint64_t id; // id of the message
848 uint64_t batch; // first batch of that peer (for this test 0 or 1)
849 //uint64_t peer; // number of sending peer (for this test 0 or 1)
850 };
851
852
853
854 struct GNUNET_UNDERLAY_DUMMY_Message *msg_dbg =
855 (struct GNUNET_UNDERLAY_DUMMY_Message *) connection->message_to_send;
856 //LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - id: %u, batch: %u, peer: %u\n",
857 LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - id: %" PRIu64 ", batch: %" PRIu64"\n",
858 GNUNET_ntohll (msg_dbg->id),
859 GNUNET_ntohll (msg_dbg->batch));
860 //LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - size: %u\n",
861 // ntohs (msg_dbg->size));
862 //LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - (sanity) size msghdr: %u\n",
863 // sizeof (struct GNUNET_MessageHeader));
864 //LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - (sanity) size msg field: %u\n",
865 // sizeof (msg_dbg->id));
866 }
867 GNUNET_assert (NULL != connection->message_to_send);
869 connection->sock,
870 connection->message_to_send,
871 ntohs (connection->message_to_send->size));
872 if (GNUNET_SYSERR == sent)
873 {
874 //LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to send message\n");
875 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to send message: %s\n", strerror(errno));
876 if (EPIPE == errno)
877 {
878 /* Tear down the connection */
879 LOG (GNUNET_ERROR_TYPE_DEBUG, "MQ_destroy() (Failed to send message)\n");
880 connection->status = CONNECTION_DESTROY;
881 GNUNET_MQ_destroy (connection->mq); // This triggers mq_destroy_impl()
882 return;
883 }
884 LOG (GNUNET_ERROR_TYPE_ERROR, "Retrying (due to failure)\n");
885 /* retry */
886 connection->write_task =
888 connection->sock,
889 &write_cb,
890 connection);
891 return; // TODO proper handling - don't try to resend on certain errors
892 // (e.g. EPIPE as above)
893 }
894 LOG (GNUNET_ERROR_TYPE_DEBUG, "Successfully sent message\n");
895 connection->message_to_send = NULL;
896 switch (connection->status)
897 {
899 connection->status = CONNECTION_LIVE;
900 try_notify_connect (connection);
902 "Finished initializing - going to cancle all still initializing connections to this address\n");
903 cancle_initiating_connections (connection->handle, connection);
904 break;
907 break;
909 return;
910 default:
911 break;
912 }
914 "Connection to %s is now %s\n",
915 connection->peer_addr,
916 status2string (connection->status));
917 GNUNET_MQ_impl_send_continue (connection->mq);
918}
919
920
921static void
922send_init (struct Connection *connection)
923{
924 struct GNUNET_MQ_Envelope *env;
926 uint32_t peer_addr_len;
927
928 GNUNET_assert (NULL != connection->handle->sock_name);
930 "Sending init: %s\n",
931 connection->handle->sock_name);
932 peer_addr_len = strnlen (connection->handle->sock_name, 128) + 1;
933 env = GNUNET_MQ_msg_header_extra (msg, // usually we wanted to keep the
934 peer_addr_len, // envelopes to potentially cancel the
935 0); // message
936 GNUNET_memcpy (&msg[1], connection->handle->sock_name, peer_addr_len);
937 GNUNET_MQ_send (connection->mq, env);
938}
939
940
949static void
951 const struct GNUNET_MessageHeader *msg,
952 void *impl_state)
953{
954 struct Connection *connection = impl_state;
955
956 LOG (GNUNET_ERROR_TYPE_DEBUG, "from mq_send_impl\n");
957 {
958 // XXX only for debugging purposes
959 // this shows everything works as expected
960
961 struct GNUNET_UNDERLAY_DUMMY_Message
962 {
963 struct GNUNET_MessageHeader header;
964 // The following will be used for debugging
965 uint64_t id; // id of the message
966 uint64_t batch; // first batch of that peer (for this test 0 or 1)
967 //uint64_t peer; // number of sending peer (for this test 0 or 1)
968 };
969
970 struct GNUNET_UNDERLAY_DUMMY_Message *msg_dbg =
971 (struct GNUNET_UNDERLAY_DUMMY_Message *) msg;
972 LOG (GNUNET_ERROR_TYPE_DEBUG, "id: %" PRIu64 ", batch: %" PRIu64 "\n",
973 GNUNET_ntohll (msg_dbg->id),
974 GNUNET_ntohll (msg_dbg->batch));
975 }
976 connection->message_to_send = msg;
977 GNUNET_assert (NULL == connection->write_task);
978 connection->write_task =
980 connection->sock,
981 &write_cb,
982 connection);
983 LOG (GNUNET_ERROR_TYPE_DEBUG, "Scheduled sending of message\n");
984}
985
986
993static void
994mq_destroy_impl (struct GNUNET_MQ_Handle *mq, void *impl_state)
995{
996 struct Connection *connection = impl_state;
997
998 LOG (GNUNET_ERROR_TYPE_DEBUG, "mq_destroy_impl\n");
999 connection_destroy (connection);
1000}
1001
1002
1009static void
1010mq_cancel_impl (struct GNUNET_MQ_Handle *mq, void *impl_state)
1011{
1012 struct Connection *connection = impl_state;
1013
1014 if (NULL != connection->write_task)
1015 {
1016 GNUNET_SCHEDULER_cancel (connection->write_task);
1017 connection->write_task = NULL;
1018 }
1019}
1020
1021
1030static void
1032{
1034 "mq_error_handler_impl: %u\n",
1035 error);
1036}
1037
1038
1044static void
1045do_accept (void *cls)
1046{
1048
1049 struct Connection *connection;
1050 struct GNUNET_NETWORK_Handle *sock;
1051 struct sockaddr_un addr_other;
1052 socklen_t addr_other_len = sizeof(addr_other);
1053 memset (&addr_other, 0, sizeof (addr_other));
1054
1056 h->sock_listen,
1057 do_accept,
1058 h);
1059
1060 LOG (GNUNET_ERROR_TYPE_DEBUG, "Handling incoming connection\n");
1061
1062 GNUNET_assert (NULL != h->sock_listen);
1063
1064 LOG (GNUNET_ERROR_TYPE_INFO, "Accepting incoming connection\n");
1065 sock = GNUNET_NETWORK_socket_accept (h->sock_listen,
1066 (struct sockaddr *) &addr_other,
1067 &addr_other_len);
1068 if (NULL == sock)
1069 {
1070 //LOG(GNUNET_ERROR_TYPE_ERROR, "Error accepting incoming connection, %s", strerror(errno));
1071 LOG (GNUNET_ERROR_TYPE_ERROR, "Error accepting incoming connection\n");
1072 return;
1073 }
1075 {
1077 "Failed setting socket of incoming connection to non-blocking\n");
1078 return;
1079 }
1080 connection = GNUNET_new (struct Connection);
1081 connection->sock = sock;
1082 connection->peer_addr = NULL; // GNUNET_strdup (addr_other.sun_path); should
1083 // be empty
1084 connection->handle = h;
1085 connection->notify_connect_called = GNUNET_NO;
1086 connection->client_ready_to_receive = GNUNET_NO;
1087 connection->status = CONNECTION_INITIALIZING;
1088 LOG (GNUNET_ERROR_TYPE_INFO, "Peer connected\n");
1089 GNUNET_CONTAINER_DLL_insert (h->connections_head,
1090 h->connections_tail,
1091 connection);
1092 connection->mq =
1096 connection, // impl_state - gets passed to _impls
1097 h->handlers,
1099 connection->cls_mq);
1100 connection->recv_task =
1102 connection->sock,
1103 do_read,
1104 connection);
1105 send_init (connection);
1106}
1107
1108
1117static void
1119{
1120 struct PeerConnectCls *pcc = cls;
1121
1122 pcc->peer_connect_task = NULL;
1125 pcc);
1126 {
1127 struct Connection *connection;
1128 struct GNUNET_CORE_UNDERLAY_DUMMY_Handle *h = pcc->h;
1129 struct sockaddr_un addr_other;
1130 memset (&addr_other, 0, sizeof (addr_other));
1131
1132 connection = GNUNET_new (struct Connection);
1133 connection->handle = pcc->h;
1134 connection->sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
1135 connection->peer_addr = pcc->sock_name;
1136 connection->notify_connect_called = GNUNET_NO;
1137 connection->client_ready_to_receive = GNUNET_NO;
1138 connection->status = CONNECTION_INITIALIZING;
1139 if (NULL == connection->sock)
1140 {
1141 LOG (GNUNET_ERROR_TYPE_ERROR, "Socket does not open\n");
1142 GNUNET_free (connection);
1143 return;
1144 }
1145 if (GNUNET_OK !=
1147 {
1148 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed setting socket to non-blocking\n");
1149 GNUNET_free (connection);
1150 return;
1151 }
1152
1153 addr_other.sun_family = AF_UNIX;
1154 //strcpy (addr_other.sun_path, pcc->sock_name);
1155 GNUNET_memcpy (addr_other.sun_path, pcc->sock_name, strlen (pcc->sock_name));
1156 if (GNUNET_OK != GNUNET_NETWORK_socket_connect (connection->sock,
1157 (struct sockaddr *) &addr_other,
1158 sizeof(addr_other)))
1159 {
1161 "failed to connect to the socket: %u %s (closing socket)\n",
1162 errno, strerror(errno));
1163 GNUNET_NETWORK_socket_close (connection->sock);
1164 GNUNET_free (connection);
1165 //LOG (GNUNET_ERROR_TYPE_INFO, "Sanity check: %s\n", addr_other.sun_path);
1166 return;
1167 }
1168 connection->peer_addr = GNUNET_strdup (pcc->sock_name);
1169 LOG (GNUNET_ERROR_TYPE_INFO, "Successfully connected to socket\n");
1170 connection->recv_task =
1172 connection->sock,
1173 do_read,
1174 connection);
1175 connection->mq =
1179 connection, // impl_state - gets passed to _impls
1180 h->handlers,
1182 connection->cls_mq);
1183 GNUNET_CONTAINER_DLL_insert (h->connections_head,
1184 h->connections_tail,
1185 connection);
1186 send_init (connection);
1187
1188 // FIXME: proper array
1189 // FIXME: proper address format ("dummy:<sock_name>")
1190 }
1191 GNUNET_free (pcc->sock_name);
1192 GNUNET_free (pcc);
1193}
1194
1195
1204static void
1206{
1208 const char *addresses[1] = {h->sock_name}; // The dummy will only ever know
1209 // about this one address
1210
1211 h->notify_address_change_task = NULL;
1212 h->notify_address_change (h->cls, 1, addresses);
1213}
1214
1215
1216static void
1218{
1219 GNUNET_assert (0 != strcmp (address, ""));
1220 LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to connect to socket: `%s'\n", address);
1221 if (0 == strcmp (address, h->sock_name))
1222 {
1223 LOG (GNUNET_ERROR_TYPE_DEBUG, "Not going to connect to own address\n");
1224 return;
1225 }
1227 "Discovered another peer with address `%s'\n",
1228 address);
1229
1235 LOG (GNUNET_ERROR_TYPE_DEBUG, "checking other connections:\n");
1236 for (struct Connection *conn_iter = h->connections_head;
1237 NULL != conn_iter;
1238 conn_iter = conn_iter->next)
1239 {
1241 " %s (%s)\n",
1242 conn_iter->peer_addr,
1243 status2string (conn_iter->status));
1244 if ((NULL != conn_iter->peer_addr) &&
1245 (0 == strcmp (address, conn_iter->peer_addr)) &&
1246 (CONNECTION_LIVE == conn_iter->status))
1247 {
1248 LOG (GNUNET_ERROR_TYPE_DEBUG, "Already connected to this peer - don't try to open another connection\n");
1249 return;
1250 }
1251 }
1252 for (struct PeerConnectCls *pcc_iter = h->peer_connect_cls_head;
1253 NULL != pcc_iter;
1254 pcc_iter = pcc_iter->next)
1255 {
1256 if (0 == strcmp (address,
1257 pcc_iter->sock_name))
1258 {
1259 LOG (GNUNET_ERROR_TYPE_DEBUG, "Already waiting to connect to this peer\n");
1260 return;
1261 }
1262 }
1263
1264 {
1265 struct PeerConnectCls *peer_connect_cls;
1266 peer_connect_cls = GNUNET_new (struct PeerConnectCls);
1267 peer_connect_cls->h = h;
1268 peer_connect_cls->sock_name = GNUNET_strdup (address);
1269 peer_connect_cls->peer_connect_task =
1271 peer_connect_cls);
1272 GNUNET_CONTAINER_DLL_insert (h->peer_connect_cls_head,
1273 h->peer_connect_cls_tail,
1274 peer_connect_cls);
1275 }
1276}
1277
1278
1294static enum GNUNET_GenericReturnValue
1296 const char *filename)
1297{
1299
1301
1302 return GNUNET_OK;
1303}
1304
1305
1313static void
1315{
1317 int ret;
1318
1319 ret = GNUNET_DISK_glob (SOCK_NAME_BASE "*" SOCK_EXTENSION,
1321 h);
1322 if (0 > ret)
1323 {
1324 LOG (GNUNET_ERROR_TYPE_WARNING, "Scanning for unix domain sockets failed\n");
1325 }
1326
1327 h->peer_discovery_task = GNUNET_SCHEDULER_add_delayed (
1330 h);
1331}
1332
1333
1334static enum GNUNET_GenericReturnValue
1336 char *sock_name)
1337{
1338 struct sockaddr_un *addr_un;
1339 socklen_t addr_un_len;
1340 uint8_t ret = GNUNET_NO;
1341
1342 h->sock_listen = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
1343 GNUNET_assert (NULL != h->sock_listen);
1344 LOG (GNUNET_ERROR_TYPE_DEBUG, "Opened socket, going to bind to address\n");
1345
1346 addr_un = GNUNET_new (struct sockaddr_un);
1347 addr_un->sun_family = AF_UNIX;
1348 // TODO check that the string is not too long
1349 GNUNET_memcpy (&addr_un->sun_path, sock_name, strlen (sock_name));
1350 addr_un_len = sizeof (struct sockaddr_un);
1351 LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to bind to `%s'\n", addr_un->sun_path);
1352 ret = GNUNET_NETWORK_socket_bind (h->sock_listen,
1353 (struct sockaddr *) addr_un,
1354 addr_un_len);
1355 if ((GNUNET_OK != ret) && (98 != errno))
1356 {
1357 /* Error different from Address already in use - cancel */
1359 "Faild binding to socket: %u %s (closing socket)\n",
1360 errno, strerror(errno));
1361 GNUNET_NETWORK_socket_close (h->sock_listen);
1362 h->sock_listen = NULL;
1363 GNUNET_free (addr_un);
1364 return GNUNET_SYSERR;
1365 }
1366 else if (GNUNET_OK != ret)
1367 {
1369 " -> something went wrong (address is probably in use)\n");
1370 GNUNET_NETWORK_socket_close (h->sock_listen);
1371 h->sock_listen = NULL;
1372 GNUNET_free (addr_un);
1373 }
1374 else if (GNUNET_OK == ret)
1375 {
1377 " -> succeeded! (binding to socket)\n");
1378 h->sock_name = GNUNET_strdup (sock_name);
1379 }
1380 GNUNET_free (addr_un);
1381 return ret;
1382}
1383
1384
1385
1396static void
1398 uint64_t sock_name_ctr_start)
1399{
1401 char *sock_name;
1402 uint64_t sock_name_ctr = sock_name_ctr_start; // Append to the socket name to avoid collisions
1403 uint8_t ret = GNUNET_NO;
1404
1405 /* Open a socket that's not occupied by another 'peer' yet:
1406 * Try opening sockets with an increasing counter in the socket name. */
1407 // TODO we might want to change this loop to schedule a new task
1408 do {
1410 SOCK_NAME_BASE "%" PRIu64 "" SOCK_EXTENSION "\0", sock_name_ctr++);
1413 if (GNUNET_SYSERR == ret) return;
1414 } while (GNUNET_YES != ret);
1415 LOG (GNUNET_ERROR_TYPE_INFO, "Bound to `%s'\n", h->sock_name);
1416 h->sock_name_index_start = sock_name_ctr_start;
1417 h->sock_name_index = sock_name_ctr;
1418
1419 LOG (GNUNET_ERROR_TYPE_DEBUG, "Mark socket as accepting connections\n");
1420 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (h->sock_listen, BACKLOG))
1421 {
1422 //LOG (GNUNET_ERROR_TYPE_ERROR, "Failed listening to socket: %s", strerror(errno));
1423 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed listening to socket (closing socket)\n");
1425 h->sock_listen = NULL;
1426 GNUNET_free (h->sock_name);
1427 return;
1428 }
1429
1430 if (NULL != h->notify_address_change)
1431 {
1432 // TODO cancel and cleanup task on run and shutdown
1433 LOG (GNUNET_ERROR_TYPE_DEBUG, "schedlue do_notify_address_change()\n");
1434 h->notify_address_change_task =
1436 }
1437
1438 LOG (GNUNET_ERROR_TYPE_DEBUG, "scheudle do_discover_peers()\n");
1439 h->peer_discovery_task = GNUNET_SCHEDULER_add_delayed (
1442 h);
1443
1444 LOG (GNUNET_ERROR_TYPE_INFO, "Going to listen for connections\n");
1446 h->sock_listen,
1447 do_accept,
1448 h);
1449}
1450
1451
1452// TODO
1453static void
1455{
1457 struct PeerConnectCls *pcc_next;
1458 struct Connection *conn_next;
1459
1460 if (NULL != h->notify_address_change_task)
1461 {
1462 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling notify address change task\n");
1463 GNUNET_SCHEDULER_cancel (h->notify_address_change_task);
1464 h->notify_address_change_task = NULL;
1465 }
1466 if (NULL != h->peer_discovery_task)
1467 {
1468 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling peer discovery task\n");
1469 GNUNET_SCHEDULER_cancel (h->peer_discovery_task);
1470 h->peer_discovery_task = NULL;
1471 }
1472 for (struct PeerConnectCls *pcc = h->peer_connect_cls_head;
1473 NULL != pcc;
1474 pcc = pcc_next)
1475 {
1476 pcc_next = pcc->next;
1477 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling peer connect task\n");
1478 GNUNET_SCHEDULER_cancel (pcc->peer_connect_task);
1479 GNUNET_CONTAINER_DLL_remove (h->peer_connect_cls_head,
1480 h->peer_connect_cls_tail,
1481 pcc);
1482 GNUNET_free (pcc->sock_name);
1483 GNUNET_free (pcc);
1484 }
1485 if (NULL != h->listen_task)
1486 {
1487 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling listen task\n");
1488 GNUNET_SCHEDULER_cancel (h->listen_task);
1489 h->listen_task = NULL;
1490 }
1491 if (NULL != h->sock_listen)
1492 {
1493 LOG (GNUNET_ERROR_TYPE_DEBUG, "closing socket\n");
1494 GNUNET_NETWORK_socket_close (h->sock_listen);
1495 h->sock_listen = NULL;
1496 }
1497 for (struct Connection *conn_iter = h->connections_head;
1498 NULL != conn_iter;
1499 conn_iter = conn_next)
1500 {
1501 // TODO consider moving MQ_destroy() into connection_destroy(), but keep in
1502 // mind that connection_destroy() is also called from within
1503 // mq_destroy_impl()
1504 conn_next = conn_iter->next;
1505 LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying a connection - MQ_destroy()\n");
1506 conn_iter->status = CONNECTION_DESTROY;
1507 GNUNET_MQ_destroy (conn_iter->mq); // This triggers mq_destroy_impl()
1508 }
1509}
1510
1511
1512static void
1514{
1516 GNUNET_CORE_UNDERLAY_DUMMY_change_address (h);
1517 h->address_change_task = GNUNET_SCHEDULER_add_delayed (
1520 h);
1521}
1522
1523
1541 const struct GNUNET_CONFIGURATION_Handle *cfg,
1542 const struct GNUNET_MQ_MessageHandler *handlers,
1543 void *cls,
1547{
1549
1551 h->notify_connect = nc;
1552 h->notify_disconnect = nd;
1553 h->notify_address_change = na;
1554 if (NULL != handlers) h->handlers = GNUNET_MQ_copy_handlers (handlers);
1555 h->cls = cls;
1556
1558
1559 //h->address_change_task = GNUNET_SCHEDULER_add_delayed (
1560 // GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5),
1561 // do_change_address,
1562 // h);
1563
1564 LOG (GNUNET_ERROR_TYPE_INFO, "Core connected\n");
1565
1566 return h;
1567}
1568
1569
1575void
1578{
1579 LOG (GNUNET_ERROR_TYPE_INFO, "Core disconnects\n");
1580 // TODO delete, free and close everything
1581 if (NULL != handle->address_change_task)
1582 GNUNET_SCHEDULER_cancel (handle->address_change_task);
1584 if (NULL != handle->handlers) GNUNET_free (handle->handlers);
1585 GNUNET_free (handle->sock_name);
1587 LOG (GNUNET_ERROR_TYPE_INFO, " -> Disconnected\n");
1588}
1589
1590
1611void
1612GNUNET_CORE_UNDERLAY_DUMMY_receive_continue (
1614 struct GNUNET_MQ_Handle *mq)
1615{
1616 struct Connection *connection;
1617
1618 LOG (GNUNET_ERROR_TYPE_DEBUG, "from _receive_continue()\n");
1619
1620 /* Find the connection beloning to the mq */
1621 for (struct Connection *conn_iter = h->connections_head;
1622 NULL != conn_iter;
1623 conn_iter = conn_iter->next)
1624 {
1625 if (mq == conn_iter->mq)
1626 {
1627 connection = conn_iter;
1628 }
1629 }
1630 GNUNET_assert (NULL != connection);
1631 connection->recv_task = NULL;
1632 connection->client_ready_to_receive = GNUNET_YES;
1633 check_for_messages (connection);
1634}
1635
1636
1650void
1651GNUNET_CORE_UNDERLAY_DUMMY_connect_to_peer (
1653 const char *peer_address,
1656{
1657 // TODO PriorityPreferences
1658 // TODO BANDWIDTH_Value
1659 try_connect (h, peer_address);
1660}
1661
1662
1666void
1667GNUNET_CORE_UNDERLAY_DUMMY_change_address (
1669{
1670 LOG (GNUNET_ERROR_TYPE_DEBUG, "Changing address!\n");
1672 if (0 == h->sock_name_index_start)
1673 {
1675 }
1676 else
1677 {
1679 }
1680}
1681
1682
1683#if 0 /* keep Emacsens' auto-indent happy */
1684{
1685#endif
1686#ifdef __cplusplus
1687}
1688#endif
1689
1690 /* end of group */
1692 /* end of group addition */
1694
1695/* end of gnunet_core_underlay_dummy.c */
struct GNUNET_MQ_MessageHandlers handlers[]
Definition: 003.c:1
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
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 cancle_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.
static void do_change_address(void *cls)
@ CONNECTION_INITIALIZING
@ 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.
Definition: common_endian.c:54
#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.
Definition: gnunet_mq_lib.h:97
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_SECONDS
One second.
#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
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.