GNUnet 0.25.2-11-g84e94e98c
 
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 105 of file gnunet_core_underlay_dummy.c.

106{
107 /* Created, but neither received, nor sent anything over it */
109
110 /* Created and successfully sent something (probably init) */
112
113 /* Created and successfully received something (probably init) */
115
116 /* Live - usable - successfully received and sent something (probably init) */
118
119 /* In the process of destruction */
121};
@ CONNECTION_INITIALIZING_RECV
@ CONNECTION_INITIALIZING_SEND

Function Documentation

◆ status2string()

static const char * status2string ( enum ConnectionStatus  status)
static

Definition at line 316 of file gnunet_core_underlay_dummy.c.

317{
318 switch (status)
319 {
321 return "C_INITIALIZING";
322 break;
324 return "C_INITIALIZING_SEND";
325 break;
327 return "C_INITIALIZING_RECV";
328 break;
329 case CONNECTION_LIVE:
330 return "C_LIVE";
331 break;
333 return "C_DESTROY";
334 break;
335 }
336 return ""; /* Make compiler happy */
337}
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 588 of file gnunet_core_underlay_dummy.c.

589{
590 struct Connection *connection = cls;
591
592 char buf[65536] GNUNET_ALIGN;
593 ssize_t ret;
595
597 "do_read(): receiving bytes from %s :%s\n",
598 connection->peer_addr,
599 status2string (connection->status));
600 connection->recv_task = NULL;
601 GNUNET_assert (NULL != connection->sock);
602 ret = GNUNET_NETWORK_socket_recv (connection->sock,
603 &buf,
604 sizeof(buf));
605 if (0 > ret)
606 {
607 LOG (GNUNET_ERROR_TYPE_ERROR, "Error reading from socket - MQ_destroy()\n");
608 connection->status = CONNECTION_DESTROY;
609 GNUNET_MQ_destroy (connection->mq); // This triggers mq_destroy_impl()
610 return;
611 }
612 if (0 == ret)
613 {
615 "Other peer closed connection - MQ_destroy()\n");
616 connection->status = CONNECTION_DESTROY;
617 GNUNET_MQ_destroy (connection->mq); // This triggers mq_destroy_impl()
618 return;
619 }
620 LOG (GNUNET_ERROR_TYPE_DEBUG, "Read %d bytes\n", (int) ret);
621 GNUNET_assert (2 <= ret); /* has to have returned enough for one full msg_hdr */
622
623 /* Handle the message itself */
624 {
625 ssize_t ret_remain;
626 char *buf_iter;
627 struct GNUNET_MessageHeader *msg_iter;
628
629 msg = (struct GNUNET_MessageHeader *) buf;
630 ret_remain = ret;
631 buf_iter = buf;
632 /* Just debug logging */
633 while (0 < ret_remain)
634 {
635 msg_iter = (struct GNUNET_MessageHeader *) buf_iter;
636 LOG (GNUNET_ERROR_TYPE_DEBUG, "Length of message: %d bytes\n", ntohs (
637 msg_iter->size));
638 LOG (GNUNET_ERROR_TYPE_DEBUG, "Remaining bytes of buffer: %ld\n",
639 ret_remain);
640
641 {
642 // XXX only for debugging purposes
643 // this shows everything works as expected
644
645 struct GNUNET_UNDERLAY_DUMMY_Message
646 {
647 struct GNUNET_MessageHeader header;
648 // The following will be used for debugging
649 uint64_t id; // id of the message
650 uint64_t batch; // first batch of that peer (for this test 0 or 1)
651 // uint64_t peer; // number of sending peer (for this test 0 or 1)
652 };
653
654
655 struct GNUNET_UNDERLAY_DUMMY_Message *msg_dbg =
656 (struct GNUNET_UNDERLAY_DUMMY_Message *) msg_iter;
657 // LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - id: %u, batch: %u, peer: %u\n",
658 LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - id: %" PRIu64
659 ", batch: %" PRIu64 "\n",
660 GNUNET_ntohll (msg_dbg->id),
661 GNUNET_ntohll (msg_dbg->batch));
662 // LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - size: %u\n",
663 // ntohs (msg_dbg->size));
664 // LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - (sanity) size msghdr: %u\n",
665 // sizeof (struct GNUNET_MessageHeader));
666 // LOG (GNUNET_ERROR_TYPE_DEBUG, "do_read - (sanity) size msg field: %u\n",
667 // sizeof (msg_dbg->id));
668 }
669 buf_iter = buf_iter + ntohs (msg_iter->size);
670 ret_remain = ret_remain - ntohs (msg_iter->size);
671 }
672
673 /* Enqueue the following messages */
674 /* skip the first message */
675 LOG (GNUNET_ERROR_TYPE_DEBUG, "Enqueueing messages\n");
676 buf_iter = buf + ntohs (msg->size);
677 ret_remain = ret - ntohs (msg->size);
678 /* iterate over the rest */
679 while (0 < ret_remain)
680 {
681 struct QueuedMessage *q_msg = GNUNET_new (struct QueuedMessage);
682
683 LOG (GNUNET_ERROR_TYPE_DEBUG, "Enqueueing message\n");
684 msg_iter = (struct GNUNET_MessageHeader *) buf_iter;
685 q_msg->msg = GNUNET_malloc (ntohs (msg_iter->size));
686 GNUNET_memcpy (q_msg->msg, msg_iter, ntohs (msg_iter->size));
688 connection->queued_recv_messages_tail,
689 q_msg);
690
691 buf_iter = buf_iter + ntohs (msg_iter->size);
692 ret_remain = ret_remain - ntohs (msg_iter->size);
693 }
694 }
695
696 /* check for and handle init */
697 if ((0 == ntohs (msg->type)) && /* 0 = GNUNET_MESSAGE_TYPE_TEST is deprecated - usage for this dummy should be fine */
698 (CONNECTION_LIVE != connection->status)) /* ignore if current connection is already live */
699 {
700 char *peer_addr_sent = (char *) &msg[1];
701 // FIXME is it really meaningful to send multiple addresses? probably just
702 // send the address that's used to open the connection
704 "Init-message: %s\n",
705 peer_addr_sent);
706 if ((NULL != connection->peer_addr) &&
707 (0 != strcmp (peer_addr_sent, connection->peer_addr)))
708 {
710 "Peer sent us an Init-message with an address different from the one we already know. -> MQ_destroy()\n");
712 "sent address: %s\n",
713 peer_addr_sent);
715 "old address: %s\n",
716 connection->peer_addr);
717 GNUNET_MQ_destroy (connection->mq);
718 GNUNET_break_op (0);
719 return;
720 }
721 switch (connection->status)
722 {
724 connection->status = CONNECTION_LIVE;
725 break;
728 break;
730 return;
731 default:
732 break;
733 }
735 "Connection to %s is now %s\n",
736 connection->peer_addr,
737 status2string (connection->status));
738 // else: we could skip ahead to end of if - we do already know the peer_addr
739 /* Check whether we already got a connection to that address/peer */
740 LOG (GNUNET_ERROR_TYPE_DEBUG, "Init - checking other connections\n");
741 for (struct Connection *c_iter = connection->handle->connections_head;
742 NULL != c_iter;
743 c_iter = c_iter->next)
744 {
746 " %s (%s)\n",
747 c_iter->peer_addr,
748 status2string (c_iter->status));
749 if ((NULL != c_iter->peer_addr) && /* we can't compare the addr */
750 (0 == strcmp (peer_addr_sent, c_iter->peer_addr)) && /* same peer */
751 (CONNECTION_LIVE == c_iter->status) && /* other connection is live*/
752 (connection != c_iter)) /* discovered the currently handled connection - skip */
753 {
754 /* We already got a connection with this peer - tear the current one
755 * down. */
757 "Init from other peer - already connected: %s - MQ_destroy()\n",
758 peer_addr_sent);
759 connection->status = CONNECTION_DESTROY;
760 GNUNET_MQ_destroy (connection->mq);
761 return;
762 }
763 }
764 connection->peer_addr = strdup (peer_addr_sent);
766 "Init-Message - notifying caller (%s :%s)\n",
767 connection->peer_addr,
768 status2string (connection->status));
769
770 try_notify_connect (connection);
772 "Finished initializing - going to cancel all still initializing connections to this address\n");
773 cancel_initiating_connections (connection->handle, connection);
774
775 /* We need to schedule the recv_task here because this is not a message
776 * passed to the caller an thus the caller will not call
777 * GNUNET_CORE_UNDERLAY_DUMMY_receive_continue () which usually schedules
778 * the recv_task */
779 connection->recv_task =
781 connection->sock,
782 do_read,
783 connection);
784 return;
785 }
786 else if ((0 == ntohs (msg->type)) && /* 0 = GNUNET_MESSAGE_TYPE_TEST is deprecated - usage for this dummy should be fine */
787 (CONNECTION_LIVE == connection->status))
788 {
789 /* We need to schedule the recv_task here because this is not a message
790 * passed to the caller an thus the caller will not call
791 * GNUNET_CORE_UNDERLAY_DUMMY_receive_continue () which usually schedules
792 * the recv_task */
793 connection->recv_task =
795 connection->sock,
796 do_read,
797 connection);
798 return;
799 }
800
801 if (GNUNET_NO == connection->notify_connect_called)
802 {
803 /* Notify connect has not been called yet - the caller doesn't know about
804 * this connection. Enqueue the first message, too; instead of handling it.
805 */
806 struct QueuedMessage *q_msg = GNUNET_new (struct QueuedMessage);
807
808 q_msg->msg = GNUNET_malloc (ntohs (msg->size));
809 GNUNET_memcpy (q_msg->msg, msg, ntohs (msg->size));
811 connection->queued_recv_messages_tail,
812 q_msg);
813 return;
814 }
815
816 if (GNUNET_YES == connection->client_ready_to_receive)
817 {
818 // TODO maybe just call check_for_messages() instead?
819 // check_for_messages (connection);
820 // FIXME for now the above gives only an unsuccessful test - check why
822 // FIXME check return value!!!
824 }
825 // else TODO
826}
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:717
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
#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 363 of file gnunet_core_underlay_dummy.c.

364{
365 /* The mq should already be cleaned as this function is called from within
366 * mq_destroy_impl. */
367 LOG (GNUNET_ERROR_TYPE_DEBUG, "connection_destroy\n");
368 if ((NULL != connection->handle->notify_disconnect) &&
369 (GNUNET_YES == connection->notify_connect_called))
370 {
371 /* Call the notify disconnect only if the notify_connect_task has been
372 * executed and the client was actually notified about the connection */
373 connection->handle->notify_disconnect (connection->handle->cls, /* connection-independant cls */
374 connection->cls_mq); /* connection-specific cls */
375 }
376 if (NULL != connection->notify_connect_task)
377 {
378 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling notify connect task\n");
380 }
381 if (NULL != connection->handle_message_task)
382 {
383 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling handle message task\n");
385 }
386 if (NULL != connection->write_task)
387 {
388 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling write task\n");
390 }
391 if (NULL != connection->recv_task)
392 {
393 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling recv task\n");
395 }
396 if (NULL != connection->sock)
397 {
398 LOG (GNUNET_ERROR_TYPE_DEBUG, "closing socket\n");
399 GNUNET_NETWORK_socket_close (connection->sock);
400 }
401 GNUNET_free (connection->peer_addr);
402 if (NULL != connection->handlers)
403 GNUNET_free (connection->handlers);
404 /* Don't free the cls_mq - we don't own it! */
406 connection->handle->connections_tail,
407 connection);
408 GNUNET_free (connection);
409 LOG (GNUNET_ERROR_TYPE_DEBUG, "connection_destroy - end\n");
410}
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:980

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 428 of file gnunet_core_underlay_dummy.c.

430{
431 GNUNET_assert (NULL != handlers);
432
433 for (unsigned int i = 0; NULL != handlers[i].cb; i++)
434 handlers[i].cls = handlers_cls;
435}
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 439 of file gnunet_core_underlay_dummy.c.

440{
441 struct Connection *connection = cls;
442 struct QueuedMessage *q_msg = connection->queued_recv_messages_head;
443 struct GNUNET_MessageHeader *msg = q_msg->msg;
444
445 connection->handle_message_task = NULL;
448 connection->queued_recv_messages_head,
449 connection->queued_recv_messages_tail,
450 q_msg);
451 GNUNET_free (q_msg);
452 // FIXME check return value!!!
454 connection->handlers,
455 msg);
456 // GNUNET_free (msg); // TODO what do we do with this pointer? Who owns it?
457 // Who cleans it?
458}

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 462 of file gnunet_core_underlay_dummy.c.

463{
464 if (NULL != connection->queued_recv_messages_head)
465 {
466 LOG (GNUNET_ERROR_TYPE_DEBUG, "got messages in the queue - handle those\n");
467 GNUNET_assert (NULL == connection->handle_message_task);
468 connection->handle_message_task =
470 }
471 else if (NULL == connection->recv_task)
472 {
474 "no messages in the queue - receive more from socket\n");
475 connection->recv_task =
477 connection->sock,
478 do_read,
479 connection);
480 }
481}
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:1304

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 493 of file gnunet_core_underlay_dummy.c.

494{
495 struct Connection *connection = cls;
496 struct GNUNET_CORE_UNDERLAY_DUMMY_Handle *h = connection->handle;
497 void *cls_mq;
498
499 connection->notify_connect_task = NULL;
500 connection->notify_connect_called = GNUNET_YES;
502 /* The global, connection-independant closure is given to notify_connect,
503 * notify_disconnect and notify_address_change, whereas the
504 * connection-specific cls is the return value of notify_connect and given to
505 * the handlers. */
506 cls_mq =
507 h->notify_connect (h->cls,
508 1,
509 (const char **) &connection->peer_addr,
510 connection->mq,
511 NULL); /* peer_id */
512 /* The handlers are copied because the connection-specific closures can be
513 * set. The global handlers remain the same - they are just called with the
514 * connection specific closures. */
515 connection->handlers = GNUNET_MQ_copy_handlers (h->handlers);
516 set_handlers_closure (connection->handlers, h->cls); /* in case there's no connection-specific closure */
517 if (NULL != cls_mq)
518 {
519 connection->cls_mq = cls_mq;
520 // GNUNET_MQ_set_handlers_closure (connection->mq, connection->cls_mq);
521 /* Overwrite the closure set above with the cls_mq */
522 set_handlers_closure (connection->handlers, connection->cls_mq);
523 }
524
525 /* Handle already enqueued messages */
526 check_for_messages (connection);
527}
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 531 of file gnunet_core_underlay_dummy.c.

532{
533 if ((NULL != connection->peer_addr) &&
534 (CONNECTION_LIVE == connection->status) &&
535 (NULL != connection->handle->notify_connect) &&
536 (NULL == connection->notify_connect_task))
537 {
538 connection->notify_connect_task =
540 }
541}
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 545 of file gnunet_core_underlay_dummy.c.

547{
548 struct Connection *c_iter_next;
549 char *peer_addr = connection->peer_addr;
550
552 "Going to cancel all initializing connections to %s\n",
553 peer_addr);
554 if (NULL == peer_addr)
555 return; /* No sense in comparing to unknown address */
556 for (struct Connection *c_iter = h->connections_head;
557 NULL != c_iter;
558 c_iter = c_iter_next)
559 {
560 c_iter_next = c_iter->next;
562 " %s :%s\n",
563 c_iter->peer_addr,
564 status2string (c_iter->status));
565 if ((c_iter != connection) && /* Don't shut down current connection */
566 (NULL != c_iter->peer_addr) && /* No address - can't compare */
567 (0 == strcmp (c_iter->peer_addr, peer_addr)) &&
568 (
569 (CONNECTION_INITIALIZING == c_iter->status) ||
570 (CONNECTION_INITIALIZING_SEND == c_iter->status) ||
571 (CONNECTION_INITIALIZING_RECV == c_iter->status)))
572 {
574 " -> Cancelling connection - MQ_destroy()\n");
575 GNUNET_MQ_destroy (c_iter->mq);
576 }
577 }
578}
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 836 of file gnunet_core_underlay_dummy.c.

837{
838 ssize_t sent;
839 struct Connection *connection = cls;
840
841 connection->write_task = NULL;
842 GNUNET_assert (NULL != connection->sock);
844 "write_cb(): sending bytes to %s :%s\n",
845 connection->peer_addr,
846 status2string (connection->status));
847 {
848 // XXX only for debugging purposes
849 // this shows everything works as expected
850
851 struct GNUNET_UNDERLAY_DUMMY_Message
852 {
853 struct GNUNET_MessageHeader header;
854 // The following will be used for debugging
855 uint64_t id; // id of the message
856 uint64_t batch; // first batch of that peer (for this test 0 or 1)
857 // uint64_t peer; // number of sending peer (for this test 0 or 1)
858 };
859
860
861 struct GNUNET_UNDERLAY_DUMMY_Message *msg_dbg =
862 (struct GNUNET_UNDERLAY_DUMMY_Message *) connection->message_to_send;
863 // LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - id: %u, batch: %u, peer: %u\n",
864 LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - id: %" PRIu64 ", batch: %" PRIu64
865 "\n",
866 GNUNET_ntohll (msg_dbg->id),
867 GNUNET_ntohll (msg_dbg->batch));
868 // LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - size: %u\n",
869 // ntohs (msg_dbg->size));
870 // LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - (sanity) size msghdr: %u\n",
871 // sizeof (struct GNUNET_MessageHeader));
872 // LOG (GNUNET_ERROR_TYPE_DEBUG, "write_cb - (sanity) size msg field: %u\n",
873 // sizeof (msg_dbg->id));
874 }
875 GNUNET_assert (NULL != connection->message_to_send);
877 connection->sock,
878 connection->message_to_send,
879 ntohs (connection->message_to_send->size));
880 if (GNUNET_SYSERR == sent)
881 {
882 // LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to send message\n");
883 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to send message: %s\n", strerror (
884 errno));
885 if (EPIPE == errno)
886 {
887 /* Tear down the connection */
888 LOG (GNUNET_ERROR_TYPE_DEBUG, "MQ_destroy() (Failed to send message)\n");
889 connection->status = CONNECTION_DESTROY;
890 GNUNET_MQ_destroy (connection->mq); // This triggers mq_destroy_impl()
891 return;
892 }
893 LOG (GNUNET_ERROR_TYPE_ERROR, "Retrying (due to failure)\n");
894 /* retry */
895 connection->write_task =
897 connection->sock,
898 &write_cb,
899 connection);
900 return; // TODO proper handling - don't try to resend on certain errors
901 // (e.g. EPIPE as above)
902 }
903 LOG (GNUNET_ERROR_TYPE_DEBUG, "Successfully sent message\n");
904 connection->message_to_send = NULL;
905 switch (connection->status)
906 {
908 connection->status = CONNECTION_LIVE;
909 try_notify_connect (connection);
911 "Finished initializing - going to cancel all still initializing connections to this address\n");
912 cancel_initiating_connections (connection->handle, connection);
913 break;
916 break;
918 return;
919 default:
920 break;
921 }
923 "Connection to %s is now %s\n",
924 connection->peer_addr,
925 status2string (connection->status));
926 GNUNET_MQ_impl_send_continue (connection->mq);
927}
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:738
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

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 931 of file gnunet_core_underlay_dummy.c.

932{
933 struct GNUNET_MQ_Envelope *env;
935 uint32_t peer_addr_len;
936
937 GNUNET_assert (NULL != connection->handle->sock_name);
939 "Sending init: %s\n",
940 connection->handle->sock_name);
941 peer_addr_len = strnlen (connection->handle->sock_name, 128) + 1;
942 env = GNUNET_MQ_msg_header_extra (msg, // usually we wanted to keep the
943 peer_addr_len, // envelopes to potentially cancel the
944 0); // message
945 GNUNET_memcpy (&msg[1], connection->handle->sock_name, peer_addr_len);
946 GNUNET_MQ_send (connection->mq, env);
947}
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 959 of file gnunet_core_underlay_dummy.c.

962{
963 struct Connection *connection = impl_state;
964
965 LOG (GNUNET_ERROR_TYPE_DEBUG, "from mq_send_impl\n");
966 {
967 // XXX only for debugging purposes
968 // this shows everything works as expected
969
970 struct GNUNET_UNDERLAY_DUMMY_Message
971 {
972 struct GNUNET_MessageHeader header;
973 // The following will be used for debugging
974 uint64_t id; // id of the message
975 uint64_t batch; // first batch of that peer (for this test 0 or 1)
976 // uint64_t peer; // number of sending peer (for this test 0 or 1)
977 };
978
979 struct GNUNET_UNDERLAY_DUMMY_Message *msg_dbg =
980 (struct GNUNET_UNDERLAY_DUMMY_Message *) msg;
981 LOG (GNUNET_ERROR_TYPE_DEBUG, "id: %" PRIu64 ", batch: %" PRIu64 "\n",
982 GNUNET_ntohll (msg_dbg->id),
983 GNUNET_ntohll (msg_dbg->batch));
984 }
985 connection->message_to_send = msg;
986 GNUNET_assert (NULL == connection->write_task);
987 connection->write_task =
989 connection->sock,
990 &write_cb,
991 connection);
992 LOG (GNUNET_ERROR_TYPE_DEBUG, "Scheduled sending of message\n");
993}

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 1003 of file gnunet_core_underlay_dummy.c.

1004{
1005 struct Connection *connection = impl_state;
1006
1007 LOG (GNUNET_ERROR_TYPE_DEBUG, "mq_destroy_impl\n");
1008 connection_destroy (connection);
1009}
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 1019 of file gnunet_core_underlay_dummy.c.

1020{
1021 struct Connection *connection = impl_state;
1022
1023 if (NULL != connection->write_task)
1024 {
1025 GNUNET_SCHEDULER_cancel (connection->write_task);
1026 connection->write_task = NULL;
1027 }
1028}

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 1040 of file gnunet_core_underlay_dummy.c.

1041{
1043 "mq_error_handler_impl: %u\n",
1044 error);
1045}

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 1054 of file gnunet_core_underlay_dummy.c.

1055{
1057
1058 struct Connection *connection;
1059 struct GNUNET_NETWORK_Handle *sock;
1060 struct sockaddr_un addr_other;
1061 socklen_t addr_other_len = sizeof(addr_other);
1062 memset (&addr_other, 0, sizeof (addr_other));
1063
1065 h->sock_listen,
1066 do_accept,
1067 h);
1068
1069 LOG (GNUNET_ERROR_TYPE_DEBUG, "Handling incoming connection\n");
1070
1071 GNUNET_assert (NULL != h->sock_listen);
1072
1073 LOG (GNUNET_ERROR_TYPE_INFO, "Accepting incoming connection\n");
1074 sock = GNUNET_NETWORK_socket_accept (h->sock_listen,
1075 (struct sockaddr *) &addr_other,
1076 &addr_other_len);
1077 if (NULL == sock)
1078 {
1079 // LOG(GNUNET_ERROR_TYPE_ERROR, "Error accepting incoming connection, %s", strerror(errno));
1080 LOG (GNUNET_ERROR_TYPE_ERROR, "Error accepting incoming connection\n");
1081 return;
1082 }
1084 {
1086 "Failed setting socket of incoming connection to non-blocking\n");
1087 return;
1088 }
1089 connection = GNUNET_new (struct Connection);
1090 connection->sock = sock;
1091 connection->peer_addr = NULL; // GNUNET_strdup (addr_other.sun_path); should
1092 // be empty
1093 connection->handle = h;
1094 connection->notify_connect_called = GNUNET_NO;
1095 connection->client_ready_to_receive = GNUNET_NO;
1096 connection->status = CONNECTION_INITIALIZING;
1097 LOG (GNUNET_ERROR_TYPE_INFO, "Peer connected\n");
1098 GNUNET_CONTAINER_DLL_insert (h->connections_head,
1099 h->connections_tail,
1100 connection);
1101 connection->mq =
1105 connection, // impl_state - gets passed to _impls
1106 h->handlers,
1108 connection->cls_mq);
1109 connection->recv_task =
1111 connection->sock,
1112 do_read,
1113 connection);
1114 send_init (connection);
1115}
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 1127 of file gnunet_core_underlay_dummy.c.

1128{
1129 struct PeerConnectCls *pcc = cls;
1130
1131 pcc->peer_connect_task = NULL;
1134 pcc);
1135 {
1136 struct Connection *connection;
1137 struct GNUNET_CORE_UNDERLAY_DUMMY_Handle *h = pcc->h;
1138 struct sockaddr_un addr_other;
1139 memset (&addr_other, 0, sizeof (addr_other));
1140
1141 connection = GNUNET_new (struct Connection);
1142 connection->handle = pcc->h;
1143 connection->sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
1144 connection->peer_addr = pcc->sock_name;
1145 connection->notify_connect_called = GNUNET_NO;
1146 connection->client_ready_to_receive = GNUNET_NO;
1147 connection->status = CONNECTION_INITIALIZING;
1148 if (NULL == connection->sock)
1149 {
1150 LOG (GNUNET_ERROR_TYPE_ERROR, "Socket does not open\n");
1151 GNUNET_free (connection);
1152 return;
1153 }
1154 if (GNUNET_OK !=
1156 {
1157 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed setting socket to non-blocking\n");
1158 GNUNET_free (connection);
1159 return;
1160 }
1161
1162 addr_other.sun_family = AF_UNIX;
1163 // strcpy (addr_other.sun_path, pcc->sock_name);
1164 GNUNET_memcpy (addr_other.sun_path, pcc->sock_name, strlen (pcc->sock_name))
1165 ;
1166 if (GNUNET_OK != GNUNET_NETWORK_socket_connect (connection->sock,
1167 (struct sockaddr *) &
1168 addr_other,
1169 sizeof(addr_other)))
1170 {
1172 "failed to connect to the socket: %u %s (closing socket)\n",
1173 errno, strerror (errno));
1174 GNUNET_NETWORK_socket_close (connection->sock);
1175 GNUNET_free (connection);
1176 // LOG (GNUNET_ERROR_TYPE_INFO, "Sanity check: %s\n", addr_other.sun_path);
1177 return;
1178 }
1179 connection->peer_addr = GNUNET_strdup (pcc->sock_name);
1180 LOG (GNUNET_ERROR_TYPE_INFO, "Successfully connected to socket\n");
1181 connection->recv_task =
1183 connection->sock,
1184 do_read,
1185 connection);
1186 connection->mq =
1190 connection, // impl_state - gets passed to _impls
1191 h->handlers,
1193 connection->cls_mq);
1194 GNUNET_CONTAINER_DLL_insert (h->connections_head,
1195 h->connections_tail,
1196 connection);
1197 send_init (connection);
1198
1199 // FIXME: proper array
1200 // FIXME: proper address format ("dummy:<sock_name>")
1201 }
1202 GNUNET_free (pcc->sock_name);
1203 GNUNET_free (pcc);
1204}
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: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
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 1216 of file gnunet_core_underlay_dummy.c.

1217{
1219 const char *addresses[1] = {h->sock_name}; // The dummy will only ever know
1220 // about this one address
1221
1222 h->notify_address_change_task = NULL;
1223 h->notify_address_change (h->cls, 1, addresses);
1224}

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 1228 of file gnunet_core_underlay_dummy.c.

1229{
1230 GNUNET_assert (0 != strcmp (address, ""));
1231 LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to connect to socket: `%s'\n", address);
1232 if (0 == strcmp (address, h->sock_name))
1233 {
1234 LOG (GNUNET_ERROR_TYPE_DEBUG, "Not going to connect to own address\n");
1235 return;
1236 }
1238 "Discovered another peer with address `%s'\n",
1239 address);
1240
1246 LOG (GNUNET_ERROR_TYPE_DEBUG, "checking other connections:\n");
1247 for (struct Connection *conn_iter = h->connections_head;
1248 NULL != conn_iter;
1249 conn_iter = conn_iter->next)
1250 {
1252 " %s (%s)\n",
1253 conn_iter->peer_addr,
1254 status2string (conn_iter->status));
1255 if ((NULL != conn_iter->peer_addr) &&
1256 (0 == strcmp (address, conn_iter->peer_addr)) &&
1257 (CONNECTION_LIVE == conn_iter->status))
1258 {
1260 "Already connected to this peer - don't try to open another connection\n");
1261 return;
1262 }
1263 }
1264 for (struct PeerConnectCls *pcc_iter = h->peer_connect_cls_head;
1265 NULL != pcc_iter;
1266 pcc_iter = pcc_iter->next)
1267 {
1268 if (0 == strcmp (address,
1269 pcc_iter->sock_name))
1270 {
1271 LOG (GNUNET_ERROR_TYPE_DEBUG, "Already waiting to connect to this peer\n")
1272 ;
1273 return;
1274 }
1275 }
1276
1277 {
1278 struct PeerConnectCls *peer_connect_cls;
1279 peer_connect_cls = GNUNET_new (struct PeerConnectCls);
1280 peer_connect_cls->h = h;
1281 peer_connect_cls->sock_name = GNUNET_strdup (address);
1282 peer_connect_cls->peer_connect_task =
1284 peer_connect_cls);
1285 GNUNET_CONTAINER_DLL_insert (h->peer_connect_cls_head,
1286 h->peer_connect_cls_tail,
1287 peer_connect_cls);
1288 }
1289}
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 1308 of file gnunet_core_underlay_dummy.c.

1310{
1312
1314
1315 return GNUNET_OK;
1316}
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 1327 of file gnunet_core_underlay_dummy.c.

1328{
1330 int ret;
1331
1332 ret = GNUNET_DISK_glob (SOCK_NAME_BASE "*" SOCK_EXTENSION,
1334 h);
1335 if (0 > ret)
1336 {
1337 LOG (GNUNET_ERROR_TYPE_WARNING, "Scanning for unix domain sockets failed\n")
1338 ;
1339 }
1340
1341 h->peer_discovery_task = GNUNET_SCHEDULER_add_delayed (
1344 h);
1345}
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:1021
@ 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:1277
#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 1349 of file gnunet_core_underlay_dummy.c.

1351{
1352 struct sockaddr_un *addr_un;
1353 socklen_t addr_un_len;
1354 uint8_t ret = GNUNET_NO;
1355
1356 h->sock_listen = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
1357 GNUNET_assert (NULL != h->sock_listen);
1358 LOG (GNUNET_ERROR_TYPE_DEBUG, "Opened socket, going to bind to address\n");
1359
1360 addr_un = GNUNET_new (struct sockaddr_un);
1361 addr_un->sun_family = AF_UNIX;
1362 // TODO check that the string is not too long
1363 GNUNET_memcpy (&addr_un->sun_path, sock_name, strlen (sock_name));
1364 addr_un_len = sizeof (struct sockaddr_un);
1365 LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to bind to `%s'\n", addr_un->sun_path);
1366 ret = GNUNET_NETWORK_socket_bind (h->sock_listen,
1367 (struct sockaddr *) addr_un,
1368 addr_un_len);
1369 if ((GNUNET_OK != ret) && (98 != errno))
1370 {
1371 /* Error different from Address already in use - cancel */
1373 "Failed binding to socket: %u %s (closing socket)\n",
1374 errno, strerror (errno));
1375 GNUNET_NETWORK_socket_close (h->sock_listen);
1376 h->sock_listen = NULL;
1377 GNUNET_free (addr_un);
1378 return GNUNET_SYSERR;
1379 }
1380 else if (GNUNET_OK != ret)
1381 {
1383 " -> something went wrong (address is probably in use)\n");
1384 GNUNET_NETWORK_socket_close (h->sock_listen);
1385 h->sock_listen = NULL;
1386 GNUNET_free (addr_un);
1387 }
1388 else if (GNUNET_OK == ret)
1389 {
1391 " -> succeeded! (binding to socket)\n");
1392 h->sock_name = GNUNET_strdup (sock_name);
1393 }
1394 GNUNET_free (addr_un);
1395 return ret;
1396}
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 1410 of file gnunet_core_underlay_dummy.c.

1412{
1414 char *sock_name;
1415 uint64_t sock_name_ctr = sock_name_ctr_start; // Append to the socket name to avoid collisions
1416 uint8_t ret = GNUNET_NO;
1417
1418 /* Open a socket that's not occupied by another 'peer' yet:
1419 * Try opening sockets with an increasing counter in the socket name. */
1420 // TODO we might want to change this loop to schedule a new task
1421 do {
1423 SOCK_NAME_BASE "%" PRIu64 "" SOCK_EXTENSION "\0",
1424 sock_name_ctr++);
1427 if (GNUNET_SYSERR == ret)
1428 return;
1429 } while (GNUNET_YES != ret);
1430 LOG (GNUNET_ERROR_TYPE_INFO, "Bound to `%s'\n", h->sock_name);
1431 h->sock_name_index_start = sock_name_ctr_start;
1432 h->sock_name_index = sock_name_ctr;
1433
1434 LOG (GNUNET_ERROR_TYPE_DEBUG, "Mark socket as accepting connections\n");
1435 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (h->sock_listen, BACKLOG))
1436 {
1437 // LOG (GNUNET_ERROR_TYPE_ERROR, "Failed listening to socket: %s", strerror(errno));
1439 "Failed listening to socket (closing socket)\n");
1441 h->sock_listen = NULL;
1442 GNUNET_free (h->sock_name);
1443 return;
1444 }
1445
1446 if (NULL != h->notify_address_change)
1447 {
1448 // TODO cancel and cleanup task on run and shutdown
1449 LOG (GNUNET_ERROR_TYPE_DEBUG, "schedlue do_notify_address_change()\n");
1450 h->notify_address_change_task =
1452 }
1453
1454 LOG (GNUNET_ERROR_TYPE_DEBUG, "scheudle do_discover_peers()\n");
1455 h->peer_discovery_task = GNUNET_SCHEDULER_add_delayed (
1458 h);
1459
1460 LOG (GNUNET_ERROR_TYPE_INFO, "Going to listen for connections\n");
1462 h->sock_listen,
1463 do_accept,
1464 h);
1465}
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:652

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 1470 of file gnunet_core_underlay_dummy.c.

1471{
1473 struct PeerConnectCls *pcc_next;
1474 struct Connection *conn_next;
1475
1476 if (NULL != h->notify_address_change_task)
1477 {
1478 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling notify address change task\n");
1479 GNUNET_SCHEDULER_cancel (h->notify_address_change_task);
1480 h->notify_address_change_task = NULL;
1481 }
1482 if (NULL != h->peer_discovery_task)
1483 {
1484 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling peer discovery task\n");
1485 GNUNET_SCHEDULER_cancel (h->peer_discovery_task);
1486 h->peer_discovery_task = NULL;
1487 }
1488 for (struct PeerConnectCls *pcc = h->peer_connect_cls_head;
1489 NULL != pcc;
1490 pcc = pcc_next)
1491 {
1492 pcc_next = pcc->next;
1493 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling peer connect task\n");
1494 GNUNET_SCHEDULER_cancel (pcc->peer_connect_task);
1495 GNUNET_CONTAINER_DLL_remove (h->peer_connect_cls_head,
1496 h->peer_connect_cls_tail,
1497 pcc);
1498 GNUNET_free (pcc->sock_name);
1499 GNUNET_free (pcc);
1500 }
1501 if (NULL != h->listen_task)
1502 {
1503 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancelling listen task\n");
1504 GNUNET_SCHEDULER_cancel (h->listen_task);
1505 h->listen_task = NULL;
1506 }
1507 if (NULL != h->sock_listen)
1508 {
1509 LOG (GNUNET_ERROR_TYPE_DEBUG, "closing socket\n");
1510 GNUNET_NETWORK_socket_close (h->sock_listen);
1511 h->sock_listen = NULL;
1512 }
1513 for (struct Connection *conn_iter = h->connections_head;
1514 NULL != conn_iter;
1515 conn_iter = conn_next)
1516 {
1517 // TODO consider moving MQ_destroy() into connection_destroy(), but keep in
1518 // mind that connection_destroy() is also called from within
1519 // mq_destroy_impl()
1520 conn_next = conn_iter->next;
1521 LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying a connection - MQ_destroy()\n");
1522 conn_iter->status = CONNECTION_DESTROY;
1523 GNUNET_MQ_destroy (conn_iter->mq); // This triggers mq_destroy_impl()
1524 }
1525}
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 1544 of file gnunet_core_underlay_dummy.c.

1551{
1553
1555 h->notify_connect = nc;
1556 h->notify_disconnect = nd;
1557 h->notify_address_change = na;
1558 if (NULL != handlers)
1559 h->handlers = GNUNET_MQ_copy_handlers (handlers);
1560 h->cls = cls;
1561
1563
1564 // h->address_change_task = GNUNET_SCHEDULER_add_delayed (
1565 // GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5),
1566 // do_change_address,
1567 // h);
1568
1569 LOG (GNUNET_ERROR_TYPE_INFO, "Core connected\n");
1570
1571 return h;
1572}
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 1581 of file gnunet_core_underlay_dummy.c.

1583{
1584 LOG (GNUNET_ERROR_TYPE_INFO, "Core disconnects\n");
1585 // TODO delete, free and close everything
1586 if (NULL != handle->address_change_task)
1587 GNUNET_SCHEDULER_cancel (handle->address_change_task);
1589 if (NULL != handle->handlers)
1590 GNUNET_free (handle->handlers);
1591 GNUNET_free (handle->sock_name);
1593 LOG (GNUNET_ERROR_TYPE_INFO, " -> Disconnected\n");
1594}
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 72 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 77 of file gnunet_core_underlay_dummy.c.

◆ h

struct GNUNET_CORE_UNDERLAY_DUMMY_Handle* PeerConnectCls::h

The handle for the service.

Definition at line 82 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 87 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 92 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 98 of file gnunet_core_underlay_dummy.c.

◆ prev [2/3]

struct QueuedMessage* QueuedMessage::prev

Definition at line 99 of file gnunet_core_underlay_dummy.c.

◆ msg

struct GNUNET_MessageHeader* QueuedMessage::msg

Definition at line 101 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 132 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 137 of file gnunet_core_underlay_dummy.c.

◆ mq

struct GNUNET_MQ_Handle* Connection::mq

Message queue towards the connected peer.

Definition at line 142 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 147 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 154 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 159 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 169 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 174 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 179 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 184 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 190 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 199 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 204 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 210 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 217 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 218 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 235 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 240 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 245 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 251 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 258 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 263 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 266 of file gnunet_core_underlay_dummy.c.

◆ sock_name_index

uint64_t GNUNET_CORE_UNDERLAY_DUMMY_Handle::sock_name_index

Definition at line 268 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 273 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 278 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 283 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 288 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 291 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 296 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 301 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 306 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 311 of file gnunet_core_underlay_dummy.c.

Referenced by connection_destroy().