/* This file is part of GNUnet. (C) 2013 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNUnet; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /** * @file mesh/gnunet-service-mesh_connection.h * @brief mesh service; dealing with connections * @author Bartlomiej Polot * * All functions in this file should use the prefix GMC (Gnunet Mesh Connection) */ #ifndef GNUNET_SERVICE_MESH_CONNECTION_H #define GNUNET_SERVICE_MESH_CONNECTION_H #ifdef __cplusplus extern "C" { #if 0 /* keep Emacsens' auto-indent happy */ } #endif #endif #include "gnunet_util_lib.h" /** * All the states a connection can be in. */ enum MeshConnectionState { /** * Uninitialized status, should never appear in operation. */ MESH_CONNECTION_NEW, /** * Connection create message sent, waiting for ACK. */ MESH_CONNECTION_SENT, /** * Connection ACK sent, waiting for ACK. */ MESH_CONNECTION_ACK, /** * Connection confirmed, ready to carry traffic. */ MESH_CONNECTION_READY, /** * Connection to be destroyed, just waiting to empty queues. */ MESH_CONNECTION_DESTROYED, }; /** * Struct containing all information regarding a connection to a peer. */ struct MeshConnection; /** * Handle for messages queued but not yet sent. */ struct MeshConnectionQueue; #include "mesh_path.h" #include "gnunet-service-mesh_channel.h" #include "gnunet-service-mesh_peer.h" /** * Callback called when a queued message is sent. * * @param cls Closure. * @param c Connection this message was on. * @param type Type of message sent. * @param fwd Was this a FWD going message? * @param size Size of the message. */ typedef void (*GMC_sent) (void *cls, struct MeshConnection *c, struct MeshConnectionQueue *q, uint16_t type, int fwd, size_t size); /** * Core handler for connection creation. * * @param cls Closure (unused). * @param peer Sender (neighbor). * @param message Message. * * @return GNUNET_OK to keep the connection open, * GNUNET_SYSERR to close it (signal serious error) */ int GMC_handle_create (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message); /** * Core handler for path confirmations. * * @param cls closure * @param message message * @param peer peer identity this notification is about * * @return GNUNET_OK to keep the connection open, * GNUNET_SYSERR to close it (signal serious error) */ int GMC_handle_confirm (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message); /** * Core handler for notifications of broken paths * * @param cls Closure (unused). * @param id Peer identity of sending neighbor. * @param message Message. * * @return GNUNET_OK to keep the connection open, * GNUNET_SYSERR to close it (signal serious error) */ int GMC_handle_broken (void* cls, const struct GNUNET_PeerIdentity* id, const struct GNUNET_MessageHeader* message); /** * Core handler for tunnel destruction * * @param cls Closure (unused). * @param peer Peer identity of sending neighbor. * @param message Message. * * @return GNUNET_OK to keep the connection open, * GNUNET_SYSERR to close it (signal serious error) */ int GMC_handle_destroy (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message); /** * Core handler for encrypted mesh network traffic (channel mgmt, data). * * @param cls Closure (unused). * @param message Message received. * @param peer Peer who sent the message. * * @return GNUNET_OK to keep the connection open, * GNUNET_SYSERR to close it (signal serious error) */ int GMC_handle_encrypted (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message); /** * Core handler for key exchange traffic (ephemeral key, ping, pong). * * @param cls Closure (unused). * @param message Message received. * @param peer Peer who sent the message. * * @return GNUNET_OK to keep the connection open, * GNUNET_SYSERR to close it (signal serious error) */ int GMC_handle_kx (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message); /** * Core handler for mesh network traffic point-to-point acks. * * @param cls closure * @param message message * @param peer peer identity this notification is about * * @return GNUNET_OK to keep the connection open, * GNUNET_SYSERR to close it (signal serious error) */ int GMC_handle_ack (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message); /** * Core handler for mesh network traffic point-to-point ack polls. * * @param cls closure * @param message message * @param peer peer identity this notification is about * * @return GNUNET_OK to keep the connection open, * GNUNET_SYSERR to close it (signal serious error) */ int GMC_handle_poll (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message); /** * Core handler for mesh keepalives. * * @param cls closure * @param message message * @param peer peer identity this notification is about * @return GNUNET_OK to keep the connection open, * GNUNET_SYSERR to close it (signal serious error) * * TODO: Check who we got this from, to validate route. */ int GMC_handle_keepalive (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message); /** * Send an ACK on the appropriate connection/channel, depending on * the direction and the position of the peer. * * @param c Which connection to send the hop-by-hop ACK. * @param fwd Is this a fwd ACK? (will go dest->root). * @param force Send the ACK even if suboptimal (e.g. requested by POLL). */ void GMC_send_ack (struct MeshConnection *c, int fwd, int force); /** * Initialize the connections subsystem * * @param c Configuration handle. */ void GMC_init (const struct GNUNET_CONFIGURATION_Handle *c); /** * Shut down the connections subsystem. */ void GMC_shutdown (void); /** * Create a connection. * * @param cid Connection ID (either created locally or imposed remotely). * @param t Tunnel this connection belongs to (or NULL); * @param p Path this connection has to use. * @param own_pos Own position in the @c p path. * * @return Newly created connection, NULL in case of error (own id not in path). */ struct MeshConnection * GMC_new (const struct GNUNET_MESH_Hash *cid, struct MeshTunnel3 *t, struct MeshPeerPath *p, unsigned int own_pos); /** * Connection is no longer needed: destroy it. * * Cancels all pending traffic (including possible DESTROY messages), all * maintenance tasks and removes the connection from neighbor peers and tunnel. * * @param c Connection to destroy. */ void GMC_destroy (struct MeshConnection *c); /** * Get the connection ID. * * @param c Connection to get the ID from. * * @return ID of the connection. */ const struct GNUNET_MESH_Hash * GMC_get_id (const struct MeshConnection *c); /** * Get a hash for the connection ID. * * @param c Connection to get the hash. * * @return Hash expanded from the ID of the connection. */ const struct GNUNET_HashCode * GMC_get_h (const struct MeshConnection *c); /** * Get the connection path. * * @param c Connection to get the path from. * * @return path used by the connection. */ const struct MeshPeerPath * GMC_get_path (const struct MeshConnection *c); /** * Get the connection state. * * @param c Connection to get the state from. * * @return state of the connection. */ enum MeshConnectionState GMC_get_state (const struct MeshConnection *c); /** * Get the connection tunnel. * * @param c Connection to get the tunnel from. * * @return tunnel of the connection. */ struct MeshTunnel3 * GMC_get_tunnel (const struct MeshConnection *c); /** * Get free buffer space in a connection. * * @param c Connection. * @param fwd Is query about FWD traffic? * * @return Free buffer space [0 - max_msgs_queue/max_connections] */ unsigned int GMC_get_buffer (struct MeshConnection *c, int fwd); /** * Get how many messages have we allowed to send to us from a direction. * * @param c Connection. * @param fwd Are we asking about traffic from FWD (BCK messages)? * * @return last_ack_sent - last_pid_recv */ unsigned int GMC_get_allowed (struct MeshConnection *c, int fwd); /** * Get messages queued in a connection. * * @param c Connection. * @param fwd Is query about FWD traffic? * * @return Number of messages queued. */ unsigned int GMC_get_qn (struct MeshConnection *c, int fwd); /** * Allow the connection to advertise a buffer of the given size. * * The connection will send an @c fwd ACK message (so: in direction !fwd) * allowing up to last_pid_recv + buffer. * * @param c Connection. * @param buffer How many more messages the connection can accept. * @param fwd Is this about FWD traffic? (The ack will go dest->root). */ void GMC_allow (struct MeshConnection *c, unsigned int buffer, int fwd); /** * Send FWD keepalive packets for a connection. * * @param cls Closure (connection for which to send the keepalive). * @param tc Notification context. */ void GMC_fwd_keepalive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); /** * Send BCK keepalive packets for a connection. * * @param cls Closure (connection for which to send the keepalive). * @param tc Notification context. */ void GMC_bck_keepalive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); /** * Notify other peers on a connection of a broken link. Mark connections * to destroy after all traffic has been sent. * * @param c Connection on which there has been a disconnection. * @param peer Peer that disconnected. */ void GMC_notify_broken (struct MeshConnection *c, struct MeshPeer *peer); /** * Is this peer the first one on the connection? * * @param c Connection. * @param fwd Is this about fwd traffic? * * @return #GNUNET_YES if origin, #GNUNET_NO if relay/terminal. */ int GMC_is_origin (struct MeshConnection *c, int fwd); /** * Is this peer the last one on the connection? * * @param c Connection. * @param fwd Is this about fwd traffic? * Note that the ROOT is the terminal for BCK traffic! * * @return #GNUNET_YES if terminal, #GNUNET_NO if relay/origin. */ int GMC_is_terminal (struct MeshConnection *c, int fwd); /** * See if we are allowed to send by the next hop in the given direction. * * @param c Connection. * @param fwd Is this about fwd traffic? * * @return #GNUNET_YES in case it's OK to send. */ int GMC_is_sendable (struct MeshConnection *c, int fwd); /** * Cancel a previously sent message while it's in the queue. * * ONLY can be called before the continuation given to the send function * is called. Once the continuation is called, the message is no longer in the * queue. * * @param q Handle to the queue. */ void GMC_cancel (struct MeshConnectionQueue *q); /** * Sends an already built message on a connection, properly registering * all used resources. * * @param message Message to send. Function makes a copy of it. * If message is not hop-by-hop, decrements TTL of copy. * @param c Connection on which this message is transmitted. * @param fwd Is this a fwd message? * @param force Force the connection to accept the message (buffer overfill). * @param cont Continuation called once message is sent. Can be NULL. * @param cont_cls Closure for @c cont. * * @return Handle to cancel the message before it's sent. * NULL on error or if @c cont is NULL. * Invalid on @c cont call. */ struct MeshConnectionQueue * GMC_send_prebuilt_message (const struct GNUNET_MessageHeader *message, struct MeshConnection *c, int fwd, int force, GMC_sent cont, void *cont_cls); /** * Sends a CREATE CONNECTION message for a path to a peer. * Changes the connection and tunnel states if necessary. * * @param connection Connection to create. */ void GMC_send_create (struct MeshConnection *connection); /** * Send a message to all peers in this connection that the connection * is no longer valid. * * If some peer should not receive the message, it should be zero'ed out * before calling this function. * * @param c The connection whose peers to notify. */ void GMC_send_destroy (struct MeshConnection *c); /** * @brief Start a polling timer for the connection. * * When a neighbor does not accept more traffic on the connection it could be * caused by a simple congestion or by a lost ACK. Polling enables to check * for the lastest ACK status for a connection. * * @param c Connection. * @param fwd Should we poll in the FWD direction? */ void GMC_start_poll (struct MeshConnection *c, int fwd); /** * @brief Stop polling a connection for ACKs. * * Once we have enough ACKs for future traffic, polls are no longer necessary. * * @param c Connection. * @param fwd Should we stop the poll in the FWD direction? */ void GMC_stop_poll (struct MeshConnection *c, int fwd); /** * Get a (static) string for a connection. * * @param c Connection. */ const char * GMC_2s (const struct MeshConnection *c); #if 0 /* keep Emacsens' auto-indent happy */ { #endif #ifdef __cplusplus } #endif /* ifndef GNUNET_SERVICE_MESH_CONNECTION_H */ #endif /* end of gnunet-service-mesh_connection.h */