GNUnet 0.27.0-15-g06790e60f
 
Loading...
Searching...
No Matches
CORE

Secure Communication with other peers. More...

Collaboration diagram for CORE:

Data Structures

struct  PeerConnectCls
 Closure used for the peer_connect_task. More...
 
struct  QueuedMessage
 
struct  Connection
 Used to keep track of context of peer. More...
 
struct  GNUNET_CORE_UNDERLAY_DUMMY_Handle
 Opaque handle to the service. More...
 

Macros

#define GNUNET_CORE_UNDERLAY_DUMMY_VERSION   0x00000000
 Version number of the core underlay dummy.
 

Typedefs

typedef 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.
 
typedef 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.
 
typedef 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.
 

Enumerations

enum  ConnectionStatus {
  CONNECTION_INITIALIZING , CONNECTION_INITIALIZING_SEND , CONNECTION_INITIALIZING_RECV , CONNECTION_LIVE ,
  CONNECTION_DESTROY
}
 

Functions

static const char * status2string (enum ConnectionStatus status)
 
static void do_read (void *cls)
 Callback scheduled to run when there is something to read from the socket.
 
static void connection_destroy (struct Connection *connection)
 Destroy a connection.
 
static void set_handlers_closure (struct GNUNET_MQ_MessageHandler *handlers, void *handlers_cls)
 Set the closures for mq handlers.
 
static void do_handle_message (void *cls)
 
static void check_for_messages (struct Connection *connection)
 
static void do_notify_connect (void *cls)
 Notify the api caller about a new connection.
 
static void try_notify_connect (struct Connection *connection)
 
static void cancel_initiating_connections (struct GNUNET_CORE_UNDERLAY_DUMMY_Handle *h, struct Connection *connection)
 
static void write_cb (void *cls)
 Callback scheduled to run once the socket is ready for writing.
 
static void send_init (struct Connection *connection)
 
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 mq_destroy_impl (struct GNUNET_MQ_Handle *mq, void *impl_state)
 Callback to destroy the message queue.
 
static void mq_cancel_impl (struct GNUNET_MQ_Handle *mq, void *impl_state)
 Callback to cancel sending a message.
 
static void mq_error_handler_impl (void *cls, enum GNUNET_MQ_Error error)
 Handle mq errors.
 
static void do_accept (void *cls)
 Accept a connection on the dummy's socket.
 
static void do_connect_to_peer (void *cls)
 Connect to another peer.
 
static void do_notify_address_change (void *cls)
 Notify core about address change.
 
static void try_connect (struct GNUNET_CORE_UNDERLAY_DUMMY_Handle *h, const char *address)
 
static enum GNUNET_GenericReturnValue discovered_socket_cb (void *cls, const char *filename)
 Handle the discovery of a certain socket.
 
static void do_discover_peers (void *cls)
 Discover sockets of other peers.
 
static enum GNUNET_GenericReturnValue try_open_listening_socket (struct GNUNET_CORE_UNDERLAY_DUMMY_Handle *h, char *sock_name)
 
static void do_open_listening_socket (void *cls, uint64_t sock_name_ctr_start)
 Opens UNIX domain socket.
 
static void do_close_listening_socket (void *cls)
 
struct GNUNET_CORE_UNDERLAY_DUMMY_HandleGNUNET_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.
 
void GNUNET_CORE_UNDERLAY_DUMMY_disconnect (struct GNUNET_CORE_UNDERLAY_DUMMY_Handle *handle)
 Disconnect from the core underlay dummy service.
 

Variables

struct PeerConnectClsPeerConnectCls::next
 Linked list next.
 
struct PeerConnectClsPeerConnectCls::prev
 Linked list previous.
 
struct GNUNET_CORE_UNDERLAY_DUMMY_HandlePeerConnectCls::h
 The handle for the service.
 
char * PeerConnectCls::sock_name
 The file name to connect to.
 
struct GNUNET_SCHEDULER_TaskPeerConnectCls::peer_connect_task
 Task to connect to another peer.
 
struct QueuedMessageQueuedMessage::next
 
struct QueuedMessageQueuedMessage::prev
 
struct GNUNET_MessageHeaderQueuedMessage::msg
 
struct ConnectionConnection::next
 Linked list next.
 
struct ConnectionConnection::prev
 Linked list previous.
 
struct GNUNET_MQ_HandleConnection::mq
 Message queue towards the connected peer.
 
struct GNUNET_MQ_MessageHandlerConnection::handlers
 Handlers for mq.
 
void * Connection::cls_mq
 Closure for the mq towards the client.
 
struct GNUNET_NETWORK_HandleConnection::sock
 Socket for the connected peer.
 
char * Connection::peer_addr
 Address of the connected peer.
 
struct GNUNET_SCHEDULER_TaskConnection::recv_task
 Task waiting for incoming messages.
 
struct GNUNET_SCHEDULER_TaskConnection::write_task
 Task waiting until the socket becomes ready to be written to.
 
struct GNUNET_SCHEDULER_TaskConnection::notify_connect_task
 Task to notify the client about an open connection.
 
struct GNUNET_SCHEDULER_TaskConnection::handle_message_task
 Task to pass the message to the client's handlers.
 
enum GNUNET_GenericReturnValue Connection::notify_connect_called
 Whether notify_connect was called already It is used to check whether to call notify_disconnect or not.
 
enum GNUNET_GenericReturnValue Connection::client_ready_to_receive
 Indicating whether the client is ready to receive new messages.
 
enum ConnectionStatus Connection::status
 Status of the connection: Initializing, Live, Destroy.
 
const struct GNUNET_MessageHeaderConnection::message_to_send
 Message about to be sent, given by the message queue, waiting for the socket to be ready.
 
struct QueuedMessageConnection::queued_recv_messages_head
 Queued received messages in a DLL TODO implement cleanup TODO replace with a performant queue.
 
struct QueuedMessageConnection::queued_recv_messages_tail
 
struct GNUNET_CORE_UNDERLAY_DUMMY_HandleConnection::handle
 Handle to the service.
 
GNUNET_CORE_UNDERLAY_DUMMY_NotifyConnect GNUNET_CORE_UNDERLAY_DUMMY_Handle::notify_connect
 Callback (from/to client) to call when another peer connects.
 
GNUNET_CORE_UNDERLAY_DUMMY_NotifyDisconnect GNUNET_CORE_UNDERLAY_DUMMY_Handle::notify_disconnect
 Callback (from/to client) to call when a peer disconnects.
 
GNUNET_CORE_UNDERLAY_DUMMY_NotifyAddressChange GNUNET_CORE_UNDERLAY_DUMMY_Handle::notify_address_change
 Callback (from/to client) to call when our address changes.
 
struct GNUNET_MQ_MessageHandlerGNUNET_CORE_UNDERLAY_DUMMY_Handle::handlers
 Array of message handlers given by the client.
 
void * GNUNET_CORE_UNDERLAY_DUMMY_Handle::cls
 Closure for handlers given by the client - connection-independant (notify_connect, notify_disconnect, notify_address_change) TODO what's the doxygen way of linking to other members of this struct?
 
char * GNUNET_CORE_UNDERLAY_DUMMY_Handle::sock_name
 Name of the listening socket.
 
uint64_t GNUNET_CORE_UNDERLAY_DUMMY_Handle::sock_name_index_start
 
uint64_t GNUNET_CORE_UNDERLAY_DUMMY_Handle::sock_name_index
 
struct GNUNET_NETWORK_HandleGNUNET_CORE_UNDERLAY_DUMMY_Handle::sock_listen
 Socket on which we listen for incoming connections.
 
struct GNUNET_SCHEDULER_TaskGNUNET_CORE_UNDERLAY_DUMMY_Handle::listen_task
 Task that waits for incoming connections.
 
struct GNUNET_SCHEDULER_TaskGNUNET_CORE_UNDERLAY_DUMMY_Handle::notify_address_change_task
 Task to notify core about address changes.
 
struct GNUNET_SCHEDULER_TaskGNUNET_CORE_UNDERLAY_DUMMY_Handle::peer_discovery_task
 Task to discover other peers.
 
struct GNUNET_SCHEDULER_TaskGNUNET_CORE_UNDERLAY_DUMMY_Handle::address_change_task
 
struct PeerConnectClsGNUNET_CORE_UNDERLAY_DUMMY_Handle::peer_connect_cls_head
 Head of linked list with peer connect closures.
 
struct PeerConnectClsGNUNET_CORE_UNDERLAY_DUMMY_Handle::peer_connect_cls_tail
 Tail of linked list with peer connect closures.
 
struct ConnectionGNUNET_CORE_UNDERLAY_DUMMY_Handle::connections_head
 Head of linked list with peer connect closures.
 
struct ConnectionGNUNET_CORE_UNDERLAY_DUMMY_Handle::connections_tail
 Tail of linked list with peer connect closures.
 

Detailed Description

Secure Communication with other peers.

See also
Documentation TODO

Macro Definition Documentation

◆ GNUNET_CORE_UNDERLAY_DUMMY_VERSION

#define GNUNET_CORE_UNDERLAY_DUMMY_VERSION   0x00000000

Version number of the core underlay dummy.

Definition at line 57 of file gnunet_core_underlay_dummy.h.

Typedef Documentation

◆ GNUNET_CORE_UNDERLAY_DUMMY_NotifyConnect

typedef 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.

If the underlay knows the peer id, it should include it in the addresses

Parameters
clsclosure
num_addressesnumber of addresses of the connecting peer
addressesaddress URIs of the connecting peer
mqmessage queue to use to transmit to peer
peer_id(optional, may be NULL) the peer id of the connecting peer
Returns
closure to use in MQ handlers

Definition at line 79 of file gnunet_core_underlay_dummy.h.

◆ GNUNET_CORE_UNDERLAY_DUMMY_NotifyDisconnect

typedef 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.

The message queue that was given to the connect notification will be destroyed and must not be used henceforth.

Parameters
clsclosure from GNUNET_CORE_UNDERLAY_DUMMY_connect
handlers_clsclosure of the handlers, was returned from the connect notification callback

Definition at line 97 of file gnunet_core_underlay_dummy.h.

◆ GNUNET_CORE_UNDERLAY_DUMMY_NotifyAddressChange

typedef 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.

Core will update its peer identity accordingly.

Parameters
clsclosure from GNUNET_CORE_UNDERLAY_DUMMY_connect
num_addressesnumber of addresses now available to this peer
addressescurrent addresses of this peer

Definition at line 110 of file gnunet_core_underlay_dummy.h.

Enumeration Type Documentation

◆ ConnectionStatus

Enumerator
CONNECTION_INITIALIZING 
CONNECTION_INITIALIZING_SEND 
CONNECTION_INITIALIZING_RECV 
CONNECTION_LIVE 
CONNECTION_DESTROY 

Definition at line 106 of file gnunet_core_underlay_dummy.c.

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};
@ CONNECTION_INITIALIZING_RECV
@ CONNECTION_INITIALIZING_SEND

Function Documentation

◆ status2string()

static const char * status2string ( enum ConnectionStatus  status)
static

Definition at line 317 of file gnunet_core_underlay_dummy.c.

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}
static int status
The program status; 0 for success.
Definition gnunet-nse.c:39

References CONNECTION_DESTROY, CONNECTION_INITIALIZING, CONNECTION_INITIALIZING_RECV, CONNECTION_INITIALIZING_SEND, CONNECTION_LIVE, and status.

Referenced by cancel_initiating_connections(), do_read(), try_connect(), and write_cb().

Here is the caller graph for this function:

◆ do_read()

static void do_read ( void *  cls)
static

Callback scheduled to run when there is something to read from the socket.

Reads the data from the socket and passes it to the message queue.

Parameters
clsClosure: Information for this socket

Definition at line 589 of file gnunet_core_underlay_dummy.c.

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}
struct GNUNET_MessageHeader * msg
Definition 005.c:2
static int ret
Final status code.
Definition gnunet-arm.c:93
#define LOG(kind,...)
static struct GNUNET_IDENTITY_Handle * id
Handle to IDENTITY.
struct GNUNET_NETWORK_Handle * sock
Socket for the connected peer.
struct QueuedMessage * queued_recv_messages_tail
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.
char * peer_addr
Address of the connected peer.
static void cancel_initiating_connections(struct GNUNET_CORE_UNDERLAY_DUMMY_Handle *h, struct Connection *connection)
struct QueuedMessage * queued_recv_messages_head
Queued received messages in a DLL TODO implement cleanup TODO replace with a performant queue.
static const char * status2string(enum ConnectionStatus status)
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...
struct GNUNET_MessageHeader * msg
struct GNUNET_MQ_Handle * mq
Message queue towards the connected peer.
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.
enum GNUNET_GenericReturnValue client_ready_to_receive
Indicating whether the client is ready to receive new messages.
struct GNUNET_SCHEDULER_Task * recv_task
Task waiting for incoming messages.
#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.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_YES
@ GNUNET_NO
#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.
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
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
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition mq.c:700
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
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
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
Used to keep track of context of peer.
Header for all communications.

References cancel_initiating_connections(), Connection::client_ready_to_receive, CONNECTION_DESTROY, CONNECTION_INITIALIZING, CONNECTION_INITIALIZING_RECV, CONNECTION_INITIALIZING_SEND, CONNECTION_LIVE, GNUNET_CORE_UNDERLAY_DUMMY_Handle::connections_head, do_read(), GNUNET_ALIGN, GNUNET_assert, GNUNET_break_op, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_malloc, GNUNET_memcpy, GNUNET_MQ_destroy(), GNUNET_MQ_handle_message(), GNUNET_NETWORK_socket_recv(), GNUNET_new, GNUNET_NO, GNUNET_ntohll(), GNUNET_SCHEDULER_add_read_net(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, Connection::handle, Connection::handlers, id, LOG, Connection::mq, msg, QueuedMessage::msg, Connection::notify_connect_called, Connection::peer_addr, Connection::queued_recv_messages_head, Connection::queued_recv_messages_tail, Connection::recv_task, ret, GNUNET_MessageHeader::size, Connection::sock, Connection::status, status2string(), try_notify_connect(), and GNUNET_MessageHeader::type.

Referenced by check_for_messages(), do_accept(), do_connect_to_peer(), and do_read().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ connection_destroy()

static void connection_destroy ( struct Connection connection)
static

Destroy a connection.

cancel all tasks, remove its memory, close sockets, remove it from the DLL, ...

Parameters
connectionThe Connection to destroy

Definition at line 364 of file gnunet_core_underlay_dummy.c.

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}
void * cls
Closure for handlers given by the client - connection-independant (notify_connect,...
struct GNUNET_SCHEDULER_Task * write_task
Task waiting until the socket becomes ready to be written to.
struct Connection * connections_tail
Tail of linked list with peer connect closures.
void * cls_mq
Closure for the mq towards the client.
struct GNUNET_SCHEDULER_Task * handle_message_task
Task to pass the message to the client's handlers.
GNUNET_CORE_UNDERLAY_DUMMY_NotifyDisconnect notify_disconnect
Callback (from/to client) to call when a peer disconnects.
struct GNUNET_SCHEDULER_Task * notify_connect_task
Task to notify the client about an open connection.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_free(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition network.c:508
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986

References GNUNET_CORE_UNDERLAY_DUMMY_Handle::cls, Connection::cls_mq, GNUNET_CORE_UNDERLAY_DUMMY_Handle::connections_head, GNUNET_CORE_UNDERLAY_DUMMY_Handle::connections_tail, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_NETWORK_socket_close(), GNUNET_SCHEDULER_cancel(), GNUNET_YES, Connection::handle, Connection::handle_message_task, Connection::handlers, LOG, Connection::notify_connect_called, Connection::notify_connect_task, GNUNET_CORE_UNDERLAY_DUMMY_Handle::notify_disconnect, Connection::peer_addr, Connection::recv_task, Connection::sock, and Connection::write_task.

Referenced by GCO_init(), and mq_destroy_impl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_handlers_closure()

static void set_handlers_closure ( struct GNUNET_MQ_MessageHandler handlers,
void *  handlers_cls 
)
static

Set the closures for mq handlers.

This is a utility function that sets the closures of the given mq handlers to a given closure

Parameters
handlersthe list of handlers
handlers_clsthe new closure for the handlers

Definition at line 429 of file gnunet_core_underlay_dummy.c.

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}
struct GNUNET_MQ_MessageHandlers handlers[]
Definition 003.c:1

References GNUNET_assert, and handlers.

Referenced by do_notify_connect().

Here is the caller graph for this function:

◆ do_handle_message()

static void do_handle_message ( void *  cls)
static

Definition at line 440 of file gnunet_core_underlay_dummy.c.

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}

References Connection::client_ready_to_receive, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_MQ_handle_message(), GNUNET_NO, Connection::handle_message_task, Connection::handlers, msg, QueuedMessage::msg, Connection::queued_recv_messages_head, and Connection::queued_recv_messages_tail.

Referenced by check_for_messages().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_for_messages()

static void check_for_messages ( struct Connection connection)
static

Definition at line 463 of file gnunet_core_underlay_dummy.c.

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}
static void do_handle_message(void *cls)
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

References do_handle_message(), do_read(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_add_read_net(), GNUNET_TIME_UNIT_FOREVER_REL, Connection::handle_message_task, LOG, Connection::queued_recv_messages_head, Connection::recv_task, and Connection::sock.

Referenced by do_notify_connect().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_notify_connect()

static void do_notify_connect ( void *  cls)
static

Notify the api caller about a new connection.

This connection could either be initiated by us or the connecting peer. The function is supposed to be called through the scheduler.

Parameters
cls

Definition at line 494 of file gnunet_core_underlay_dummy.c.

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}
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition gnunet-arm.c:98
static void check_for_messages(struct Connection *connection)
static void set_handlers_closure(struct GNUNET_MQ_MessageHandler *handlers, void *handlers_cls)
Set the closures for mq handlers.
struct GNUNET_MQ_MessageHandler * GNUNET_MQ_copy_handlers(const struct GNUNET_MQ_MessageHandler *handlers)
Copy an array of handlers.
Definition mq.c:974

References check_for_messages(), Connection::client_ready_to_receive, Connection::cls_mq, GNUNET_MQ_copy_handlers(), GNUNET_YES, h, Connection::handle, Connection::handlers, Connection::mq, Connection::notify_connect_called, Connection::notify_connect_task, Connection::peer_addr, and set_handlers_closure().

Referenced by try_notify_connect().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_notify_connect()

static void try_notify_connect ( struct Connection connection)
static

Definition at line 532 of file gnunet_core_underlay_dummy.c.

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}
GNUNET_CORE_UNDERLAY_DUMMY_NotifyConnect notify_connect
Callback (from/to client) to call when another peer connects.
static void do_notify_connect(void *cls)
Notify the api caller about a new connection.

References CONNECTION_LIVE, do_notify_connect(), GNUNET_SCHEDULER_add_now(), Connection::handle, GNUNET_CORE_UNDERLAY_DUMMY_Handle::notify_connect, Connection::notify_connect_task, Connection::peer_addr, and Connection::status.

Referenced by do_read(), and write_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cancel_initiating_connections()

static void cancel_initiating_connections ( struct GNUNET_CORE_UNDERLAY_DUMMY_Handle h,
struct Connection connection 
)
static

Definition at line 546 of file gnunet_core_underlay_dummy.c.

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}
struct Connection * next
Linked list next.

References CONNECTION_INITIALIZING, CONNECTION_INITIALIZING_RECV, CONNECTION_INITIALIZING_SEND, GNUNET_ERROR_TYPE_DEBUG, GNUNET_MQ_destroy(), h, LOG, Connection::next, Connection::peer_addr, and status2string().

Referenced by do_read(), and write_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ write_cb()

static void write_cb ( void *  cls)
static

Callback scheduled to run once the socket is ready for writing.

Writes the message to the socket.

Parameters
clsClosure: The handle of the underlay dummy

Definition at line 837 of file gnunet_core_underlay_dummy.c.

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}
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 write_cb(void *cls)
Callback scheduled to run once the socket is ready for writing.
@ GNUNET_SYSERR
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
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
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

References cancel_initiating_connections(), CONNECTION_DESTROY, CONNECTION_INITIALIZING, CONNECTION_INITIALIZING_RECV, CONNECTION_INITIALIZING_SEND, CONNECTION_LIVE, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_MQ_destroy(), GNUNET_MQ_impl_send_continue(), GNUNET_NETWORK_socket_send(), GNUNET_ntohll(), GNUNET_SCHEDULER_add_write_net(), GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_REL, Connection::handle, id, LOG, Connection::message_to_send, Connection::mq, Connection::peer_addr, GNUNET_MessageHeader::size, Connection::sock, Connection::status, status2string(), try_notify_connect(), write_cb(), and Connection::write_task.

Referenced by mq_send_impl(), and write_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_init()

static void send_init ( struct Connection connection)
static

Definition at line 932 of file gnunet_core_underlay_dummy.c.

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}
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
static size_t strnlen(const char *s, size_t n)
char * sock_name
Name of the listening socket.
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
#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.

References env, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_memcpy, GNUNET_MQ_msg_header_extra, GNUNET_MQ_send(), Connection::handle, LOG, Connection::mq, msg, GNUNET_CORE_UNDERLAY_DUMMY_Handle::sock_name, and strnlen().

Referenced by do_accept(), and do_connect_to_peer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mq_send_impl()

static void mq_send_impl ( struct GNUNET_MQ_Handle mq,
const struct GNUNET_MessageHeader msg,
void *  impl_state 
)
static

Callback called from the MQ to send a message over a socket.

Schedules the sending of the message once the socket is ready.

Parameters
mqThe message queue
msgThe message to send
impl_stateThe handle of the underlay dummy

Definition at line 960 of file gnunet_core_underlay_dummy.c.

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}

References GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ntohll(), GNUNET_SCHEDULER_add_write_net(), GNUNET_TIME_UNIT_FOREVER_REL, id, LOG, Connection::message_to_send, msg, Connection::sock, write_cb(), and Connection::write_task.

Referenced by do_accept(), and do_connect_to_peer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mq_destroy_impl()

static void mq_destroy_impl ( struct GNUNET_MQ_Handle mq,
void *  impl_state 
)
static

Callback to destroy the message queue.

Parameters
mqmessage queue to destroy
impl_stateThe handle of the underlay dummy

Definition at line 1004 of file gnunet_core_underlay_dummy.c.

1005{
1006 struct Connection *connection = impl_state;
1007
1008 LOG (GNUNET_ERROR_TYPE_DEBUG, "mq_destroy_impl\n");
1009 connection_destroy (connection);
1010}
static void connection_destroy(struct Connection *connection)
Destroy a connection.

References connection_destroy(), GNUNET_ERROR_TYPE_DEBUG, and LOG.

Referenced by do_accept(), and do_connect_to_peer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mq_cancel_impl()

static void mq_cancel_impl ( struct GNUNET_MQ_Handle mq,
void *  impl_state 
)
static

Callback to cancel sending a message.

Parameters
mqThe message queue the message was supposed to be sent over.
impl_stateThe handle of the underlay dummy

Definition at line 1020 of file gnunet_core_underlay_dummy.c.

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}

References GNUNET_SCHEDULER_cancel(), and Connection::write_task.

Referenced by do_accept(), and do_connect_to_peer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mq_error_handler_impl()

static void mq_error_handler_impl ( void *  cls,
enum GNUNET_MQ_Error  error 
)
static

Handle mq errors.

This is currently a stub that only logs.

Parameters
clsclosure is unused
errorthe kind of error

Definition at line 1041 of file gnunet_core_underlay_dummy.c.

1042{
1044 "mq_error_handler_impl: %u\n",
1045 error);
1046}

References GNUNET_ERROR_TYPE_ERROR, and LOG.

Referenced by do_accept(), and do_connect_to_peer().

Here is the caller graph for this function:

◆ do_accept()

static void do_accept ( void *  cls)
static

Accept a connection on the dummy's socket.

Parameters
clsthe handle to the dummy passed as closure

Definition at line 1055 of file gnunet_core_underlay_dummy.c.

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}
static void mq_destroy_impl(struct GNUNET_MQ_Handle *mq, void *impl_state)
Callback to destroy the message queue.
static void mq_error_handler_impl(void *cls, enum GNUNET_MQ_Error error)
Handle mq errors.
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.
static void send_init(struct Connection *connection)
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.
@ GNUNET_OK
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
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_set_blocking(struct GNUNET_NETWORK_Handle *fd, int doBlock)
Set if a socket should use blocking or non-blocking IO.
Definition network.c:224
handle to a socket
Definition network.c:53

References Connection::client_ready_to_receive, GNUNET_CORE_UNDERLAY_DUMMY_Handle::cls, Connection::cls_mq, CONNECTION_INITIALIZING, do_accept(), do_read(), GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_MQ_queue_for_callbacks(), GNUNET_NETWORK_socket_accept(), GNUNET_NETWORK_socket_set_blocking(), GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_read_net(), GNUNET_TIME_UNIT_FOREVER_REL, h, Connection::handle, LOG, Connection::mq, mq_cancel_impl(), mq_destroy_impl(), mq_error_handler_impl(), mq_send_impl(), Connection::notify_connect_called, Connection::peer_addr, Connection::recv_task, send_init(), Connection::sock, and Connection::status.

Referenced by do_accept(), and do_open_listening_socket().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_connect_to_peer()

static void do_connect_to_peer ( void *  cls)
static

Connect to another peer.

This function is scheduled and pays attention that it's not called unnecessarily.

Parameters
cls

Definition at line 1128 of file gnunet_core_underlay_dummy.c.

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}
struct PeerConnectCls * peer_connect_cls_tail
Tail of linked list with peer connect closures.
struct GNUNET_CORE_UNDERLAY_DUMMY_Handle * h
The handle for the service.
struct GNUNET_SCHEDULER_Task * peer_connect_task
Task to connect to another peer.
struct PeerConnectCls * peer_connect_cls_head
Head of linked list with peer connect closures.
char * sock_name
The file name to connect to.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
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
Closure used for the peer_connect_task.

References Connection::client_ready_to_receive, Connection::cls_mq, CONNECTION_INITIALIZING, do_read(), GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_memcpy, GNUNET_MQ_queue_for_callbacks(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_connect(), GNUNET_NETWORK_socket_create(), GNUNET_NETWORK_socket_set_blocking(), GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_read_net(), GNUNET_strdup, GNUNET_TIME_UNIT_FOREVER_REL, h, PeerConnectCls::h, Connection::handle, LOG, Connection::mq, mq_cancel_impl(), mq_destroy_impl(), mq_error_handler_impl(), mq_send_impl(), Connection::notify_connect_called, Connection::peer_addr, GNUNET_CORE_UNDERLAY_DUMMY_Handle::peer_connect_cls_head, GNUNET_CORE_UNDERLAY_DUMMY_Handle::peer_connect_cls_tail, PeerConnectCls::peer_connect_task, Connection::recv_task, send_init(), Connection::sock, PeerConnectCls::sock_name, and Connection::status.

Referenced by try_connect().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_notify_address_change()

static void do_notify_address_change ( void *  cls)
static

Notify core about address change.

This is in an extra function so the callback gets called after the GNUNET_CORE_UNDERLAY_DUMMY_connect() finishes.

Parameters
clsClosure: The handle of the dummy underlay.

Definition at line 1217 of file gnunet_core_underlay_dummy.c.

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}

References GNUNET_CORE_UNDERLAY_DUMMY_Handle::cls, and h.

Referenced by do_open_listening_socket().

Here is the caller graph for this function:

◆ try_connect()

static void try_connect ( struct GNUNET_CORE_UNDERLAY_DUMMY_Handle h,
const char *  address 
)
static

Check whether we are already connected to this peer

This is limited as we don't always have the socket name of the other peer

Definition at line 1229 of file gnunet_core_underlay_dummy.c.

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}
static char * address
GNS address for this phone.
static void do_connect_to_peer(void *cls)
Connect to another peer.

References address, CONNECTION_LIVE, do_connect_to_peer(), GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_new, GNUNET_SCHEDULER_add_now(), GNUNET_strdup, h, PeerConnectCls::h, LOG, PeerConnectCls::peer_connect_task, PeerConnectCls::sock_name, and status2string().

Referenced by discovered_socket_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ discovered_socket_cb()

static enum GNUNET_GenericReturnValue discovered_socket_cb ( void *  cls,
const char *  filename 
)
static

Handle the discovery of a certain socket.

This is called from within the discovery of file names with the correct pattern. It checks whether we are already connected to this socket, are waiting for a reply, it's our own socket. Issue a connection if the conditions are given.

Parameters
clshandle to the dummy service
filenamethe discovered filename
Returns
GNUNET_OK indicating that the iteration through filenames is supposed to continue

Definition at line 1309 of file gnunet_core_underlay_dummy.c.

1311{
1313
1315
1316 return GNUNET_OK;
1317}
static char * filename
static void try_connect(struct GNUNET_CORE_UNDERLAY_DUMMY_Handle *h, const char *address)

References GNUNET_CORE_UNDERLAY_DUMMY_Handle::cls, filename, GNUNET_OK, h, and try_connect().

Referenced by do_discover_peers().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_discover_peers()

static void do_discover_peers ( void *  cls)
static

Discover sockets of other peers.

Sockets with a certain file name pattern are treated as candidates.

Parameters
cls

Definition at line 1328 of file gnunet_core_underlay_dummy.c.

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}
static void do_discover_peers(void *cls)
Discover sockets of other peers.
static enum GNUNET_GenericReturnValue discovered_socket_cb(void *cls, const char *filename)
Handle the discovery of a certain socket.
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
@ GNUNET_ERROR_TYPE_WARNING
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_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

References GNUNET_CORE_UNDERLAY_DUMMY_Handle::cls, discovered_socket_cb(), do_discover_peers(), GNUNET_DISK_glob(), GNUNET_ERROR_TYPE_WARNING, GNUNET_SCHEDULER_add_delayed(), GNUNET_TIME_relative_multiply(), GNUNET_TIME_UNIT_MILLISECONDS, h, LOG, and ret.

Referenced by do_discover_peers(), and do_open_listening_socket().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_open_listening_socket()

static enum GNUNET_GenericReturnValue try_open_listening_socket ( struct GNUNET_CORE_UNDERLAY_DUMMY_Handle h,
char *  sock_name 
)
static

Definition at line 1350 of file gnunet_core_underlay_dummy.c.

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}
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

References GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_memcpy, GNUNET_NETWORK_socket_bind(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_create(), GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_strdup, GNUNET_SYSERR, h, LOG, and ret.

Referenced by do_open_listening_socket().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_open_listening_socket()

static void do_open_listening_socket ( void *  cls,
uint64_t  sock_name_ctr_start 
)
static

Opens UNIX domain socket.

It start trying with a default name and successively increases a number within it, when it encounters already used sockets.

Parameters
clsClosure: The handle of the dummy underlay.
sock_name_ctrTODO Append to the socket name to avoid collisions TODO

Definition at line 1411 of file gnunet_core_underlay_dummy.c.

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}
static void do_notify_address_change(void *cls)
Notify core about address change.
static enum GNUNET_GenericReturnValue try_open_listening_socket(struct GNUNET_CORE_UNDERLAY_DUMMY_Handle *h, char *sock_name)
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_listen(const struct GNUNET_NETWORK_Handle *desc, int backlog)
Listen on a socket.
Definition network.c:651

References GNUNET_CORE_UNDERLAY_DUMMY_Handle::cls, do_accept(), do_discover_peers(), do_notify_address_change(), GNUNET_asprintf(), GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_listen(), GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_add_read_net(), GNUNET_SYSERR, GNUNET_TIME_relative_multiply(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_TIME_UNIT_MILLISECONDS, GNUNET_YES, h, LOG, ret, GNUNET_CORE_UNDERLAY_DUMMY_Handle::sock_name, and try_open_listening_socket().

Referenced by GNUNET_CORE_UNDERLAY_DUMMY_connect().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_close_listening_socket()

static void do_close_listening_socket ( void *  cls)
static

Definition at line 1471 of file gnunet_core_underlay_dummy.c.

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}
struct PeerConnectCls * next
Linked list next.

References GNUNET_CORE_UNDERLAY_DUMMY_Handle::cls, CONNECTION_DESTROY, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_MQ_destroy(), GNUNET_NETWORK_socket_close(), GNUNET_SCHEDULER_cancel(), h, LOG, PeerConnectCls::next, and Connection::next.

Referenced by GNUNET_CORE_UNDERLAY_DUMMY_disconnect().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_CORE_UNDERLAY_DUMMY_connect()

Connect to the core underlay dummy service.

Note that the connection may complete (or fail) asynchronously.

Parameters
cfgconfiguration to use
handlersarray of message handlers or NULL; note that the closures provided will be ignored and replaced with the respective return value from nc
clsclosure for the nc, nd and na callbacks
ncfunction to call on connect events, or NULL. Returns the closure for message handlers for this opened connection.
ndfunction to call on disconnect events, or NULL
nafunction to call on address changes, or NULL
Returns
NULL on error

Note that the connection may complete (or fail) asynchronously.

Parameters
cfgconfiguration to use
handlersarray of message handlers or NULL; note that the closures provided will be ignored and replaced with the respective return value from nc
clsclosure for the nc, nd and na callbacks
ncfunction to call on connect events, or NULL
ndfunction to call on disconnect events, or NULL
nafunction to call on address changes, or NULL
Returns
NULL on error

Definition at line 1545 of file gnunet_core_underlay_dummy.c.

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}
static struct GNUNET_NotificationContext * nc
Notification context for broadcasting to monitors.
static void do_open_listening_socket(void *cls, uint64_t sock_name_ctr_start)
Opens UNIX domain socket.

References GNUNET_CORE_UNDERLAY_DUMMY_Handle::cls, do_open_listening_socket(), GNUNET_ERROR_TYPE_INFO, GNUNET_malloc, GNUNET_MQ_copy_handlers(), h, handlers, LOG, and nc.

Here is the call graph for this function:

◆ GNUNET_CORE_UNDERLAY_DUMMY_disconnect()

void GNUNET_CORE_UNDERLAY_DUMMY_disconnect ( struct GNUNET_CORE_UNDERLAY_DUMMY_Handle handle)

Disconnect from the core underlay dummy service.

Parameters
handlehandle returned from connect

Definition at line 1582 of file gnunet_core_underlay_dummy.c.

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}
static struct GNUNET_VPN_Handle * handle
Handle to vpn service.
Definition gnunet-vpn.c:35
static void do_close_listening_socket(void *cls)

References do_close_listening_socket(), GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_SCHEDULER_cancel(), handle, and LOG.

Here is the call graph for this function:

Variable Documentation

◆ next [1/3]

struct PeerConnectCls* PeerConnectCls::next

Linked list next.

Definition at line 73 of file gnunet_core_underlay_dummy.c.

Referenced by do_close_listening_socket().

◆ prev [1/3]

struct PeerConnectCls* PeerConnectCls::prev

Linked list previous.

Definition at line 78 of file gnunet_core_underlay_dummy.c.

◆ h

struct GNUNET_CORE_UNDERLAY_DUMMY_Handle* PeerConnectCls::h

The handle for the service.

Definition at line 83 of file gnunet_core_underlay_dummy.c.

Referenced by do_connect_to_peer(), and try_connect().

◆ sock_name [1/2]

char* PeerConnectCls::sock_name

The file name to connect to.

Definition at line 88 of file gnunet_core_underlay_dummy.c.

Referenced by do_connect_to_peer(), and try_connect().

◆ peer_connect_task

struct GNUNET_SCHEDULER_Task* PeerConnectCls::peer_connect_task

Task to connect to another peer.

Definition at line 93 of file gnunet_core_underlay_dummy.c.

Referenced by do_connect_to_peer(), and try_connect().

◆ next [2/3]

struct QueuedMessage* QueuedMessage::next

Definition at line 99 of file gnunet_core_underlay_dummy.c.

◆ prev [2/3]

struct QueuedMessage* QueuedMessage::prev

Definition at line 100 of file gnunet_core_underlay_dummy.c.

◆ msg

struct GNUNET_MessageHeader* QueuedMessage::msg

Definition at line 102 of file gnunet_core_underlay_dummy.c.

Referenced by do_handle_message(), and do_read().

◆ next [3/3]

struct Connection* Connection::next

Linked list next.

Definition at line 133 of file gnunet_core_underlay_dummy.c.

Referenced by cancel_initiating_connections(), and do_close_listening_socket().

◆ prev [3/3]

struct Connection* Connection::prev

Linked list previous.

Definition at line 138 of file gnunet_core_underlay_dummy.c.

◆ mq

struct GNUNET_MQ_Handle* Connection::mq

Message queue towards the connected peer.

Definition at line 143 of file gnunet_core_underlay_dummy.c.

Referenced by do_accept(), do_connect_to_peer(), do_notify_connect(), do_read(), send_init(), and write_cb().

◆ handlers [1/2]

struct GNUNET_MQ_MessageHandler* Connection::handlers

Handlers for mq.

Definition at line 148 of file gnunet_core_underlay_dummy.c.

Referenced by connection_destroy(), do_handle_message(), do_notify_connect(), and do_read().

◆ cls_mq

void* Connection::cls_mq

Closure for the mq towards the client.

Connection-specific, given to handlers and disconnect_cb/notify_disconnect

Definition at line 155 of file gnunet_core_underlay_dummy.c.

Referenced by connection_destroy(), do_accept(), do_connect_to_peer(), and do_notify_connect().

◆ sock

struct GNUNET_NETWORK_Handle* Connection::sock

Socket for the connected peer.

Definition at line 160 of file gnunet_core_underlay_dummy.c.

Referenced by check_for_messages(), connection_destroy(), do_accept(), do_connect_to_peer(), do_read(), mq_send_impl(), and write_cb().

◆ peer_addr

◆ recv_task

struct GNUNET_SCHEDULER_Task* Connection::recv_task

Task waiting for incoming messages.

Definition at line 170 of file gnunet_core_underlay_dummy.c.

Referenced by check_for_messages(), connection_destroy(), do_accept(), do_connect_to_peer(), and do_read().

◆ write_task

struct GNUNET_SCHEDULER_Task* Connection::write_task

Task waiting until the socket becomes ready to be written to.

Definition at line 175 of file gnunet_core_underlay_dummy.c.

Referenced by connection_destroy(), mq_cancel_impl(), mq_send_impl(), and write_cb().

◆ notify_connect_task

struct GNUNET_SCHEDULER_Task* Connection::notify_connect_task

Task to notify the client about an open connection.

Definition at line 180 of file gnunet_core_underlay_dummy.c.

Referenced by connection_destroy(), do_notify_connect(), and try_notify_connect().

◆ handle_message_task

struct GNUNET_SCHEDULER_Task* Connection::handle_message_task

Task to pass the message to the client's handlers.

Definition at line 185 of file gnunet_core_underlay_dummy.c.

Referenced by check_for_messages(), connection_destroy(), and do_handle_message().

◆ notify_connect_called

enum GNUNET_GenericReturnValue Connection::notify_connect_called

Whether notify_connect was called already It is used to check whether to call notify_disconnect or not.

Definition at line 191 of file gnunet_core_underlay_dummy.c.

Referenced by connection_destroy(), do_accept(), do_connect_to_peer(), do_notify_connect(), and do_read().

◆ client_ready_to_receive

enum GNUNET_GenericReturnValue Connection::client_ready_to_receive

Indicating whether the client is ready to receive new messages.

This is set to GNUNET_YES after the client called #GNUNET_CORE_UNDERLAY_DUMMY_receive_continue() and to GNUNET_NO after GNUNET_MQ_handle_message() was called. TODO might be a duplicate to handle_message_task being NULL or not

Definition at line 200 of file gnunet_core_underlay_dummy.c.

Referenced by do_accept(), do_connect_to_peer(), do_handle_message(), do_notify_connect(), and do_read().

◆ status

enum ConnectionStatus Connection::status

Status of the connection: Initializing, Live, Destroy.

Definition at line 205 of file gnunet_core_underlay_dummy.c.

Referenced by do_accept(), do_connect_to_peer(), do_read(), try_notify_connect(), and write_cb().

◆ message_to_send

const struct GNUNET_MessageHeader* Connection::message_to_send

Message about to be sent, given by the message queue, waiting for the socket to be ready.

Definition at line 211 of file gnunet_core_underlay_dummy.c.

Referenced by mq_send_impl(), and write_cb().

◆ queued_recv_messages_head

struct QueuedMessage* Connection::queued_recv_messages_head

Queued received messages in a DLL TODO implement cleanup TODO replace with a performant queue.

Definition at line 218 of file gnunet_core_underlay_dummy.c.

Referenced by check_for_messages(), do_handle_message(), and do_read().

◆ queued_recv_messages_tail

struct QueuedMessage* Connection::queued_recv_messages_tail

Definition at line 219 of file gnunet_core_underlay_dummy.c.

Referenced by do_handle_message(), and do_read().

◆ handle

◆ notify_connect

GNUNET_CORE_UNDERLAY_DUMMY_NotifyConnect GNUNET_CORE_UNDERLAY_DUMMY_Handle::notify_connect

Callback (from/to client) to call when another peer connects.

Definition at line 236 of file gnunet_core_underlay_dummy.c.

Referenced by try_notify_connect().

◆ notify_disconnect

GNUNET_CORE_UNDERLAY_DUMMY_NotifyDisconnect GNUNET_CORE_UNDERLAY_DUMMY_Handle::notify_disconnect

Callback (from/to client) to call when a peer disconnects.

Definition at line 241 of file gnunet_core_underlay_dummy.c.

Referenced by connection_destroy().

◆ notify_address_change

GNUNET_CORE_UNDERLAY_DUMMY_NotifyAddressChange GNUNET_CORE_UNDERLAY_DUMMY_Handle::notify_address_change

Callback (from/to client) to call when our address changes.

Definition at line 246 of file gnunet_core_underlay_dummy.c.

◆ handlers [2/2]

struct GNUNET_MQ_MessageHandler* GNUNET_CORE_UNDERLAY_DUMMY_Handle::handlers

Array of message handlers given by the client.

Don't use for handling of messages - this discards the per-mq-cls;

Definition at line 252 of file gnunet_core_underlay_dummy.c.

◆ cls

void* GNUNET_CORE_UNDERLAY_DUMMY_Handle::cls

Closure for handlers given by the client - connection-independant (notify_connect, notify_disconnect, notify_address_change) TODO what's the doxygen way of linking to other members of this struct?

Definition at line 259 of file gnunet_core_underlay_dummy.c.

Referenced by connection_destroy(), discovered_socket_cb(), do_accept(), do_close_listening_socket(), do_discover_peers(), do_notify_address_change(), do_open_listening_socket(), and GNUNET_CORE_UNDERLAY_DUMMY_connect().

◆ sock_name [2/2]

char* GNUNET_CORE_UNDERLAY_DUMMY_Handle::sock_name

Name of the listening socket.

Definition at line 264 of file gnunet_core_underlay_dummy.c.

Referenced by do_open_listening_socket(), and send_init().

◆ sock_name_index_start

uint64_t GNUNET_CORE_UNDERLAY_DUMMY_Handle::sock_name_index_start

Definition at line 267 of file gnunet_core_underlay_dummy.c.

◆ sock_name_index

uint64_t GNUNET_CORE_UNDERLAY_DUMMY_Handle::sock_name_index

Definition at line 269 of file gnunet_core_underlay_dummy.c.

◆ sock_listen

struct GNUNET_NETWORK_Handle* GNUNET_CORE_UNDERLAY_DUMMY_Handle::sock_listen

Socket on which we listen for incoming connections.

Definition at line 274 of file gnunet_core_underlay_dummy.c.

◆ listen_task

struct GNUNET_SCHEDULER_Task* GNUNET_CORE_UNDERLAY_DUMMY_Handle::listen_task

Task that waits for incoming connections.

Definition at line 279 of file gnunet_core_underlay_dummy.c.

◆ notify_address_change_task

struct GNUNET_SCHEDULER_Task* GNUNET_CORE_UNDERLAY_DUMMY_Handle::notify_address_change_task

Task to notify core about address changes.

Definition at line 284 of file gnunet_core_underlay_dummy.c.

◆ peer_discovery_task

struct GNUNET_SCHEDULER_Task* GNUNET_CORE_UNDERLAY_DUMMY_Handle::peer_discovery_task

Task to discover other peers.

Definition at line 289 of file gnunet_core_underlay_dummy.c.

◆ address_change_task

struct GNUNET_SCHEDULER_Task* GNUNET_CORE_UNDERLAY_DUMMY_Handle::address_change_task

Definition at line 292 of file gnunet_core_underlay_dummy.c.

◆ peer_connect_cls_head

struct PeerConnectCls* GNUNET_CORE_UNDERLAY_DUMMY_Handle::peer_connect_cls_head

Head of linked list with peer connect closures.

Definition at line 297 of file gnunet_core_underlay_dummy.c.

Referenced by do_connect_to_peer().

◆ peer_connect_cls_tail

struct PeerConnectCls* GNUNET_CORE_UNDERLAY_DUMMY_Handle::peer_connect_cls_tail

Tail of linked list with peer connect closures.

Definition at line 302 of file gnunet_core_underlay_dummy.c.

Referenced by do_connect_to_peer().

◆ connections_head

struct Connection* GNUNET_CORE_UNDERLAY_DUMMY_Handle::connections_head

Head of linked list with peer connect closures.

Definition at line 307 of file gnunet_core_underlay_dummy.c.

Referenced by connection_destroy(), and do_read().

◆ connections_tail

struct Connection* GNUNET_CORE_UNDERLAY_DUMMY_Handle::connections_tail

Tail of linked list with peer connect closures.

Definition at line 312 of file gnunet_core_underlay_dummy.c.

Referenced by connection_destroy().