From c87a389a4f842c20383d8619120b188e104cf64a Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 17 Jan 2017 16:08:38 +0100 Subject: [PATCH] towards actual routing... --- src/cadet/cadet_protocol.h | 6 +- .../gnunet-service-cadet-new_connection.c | 40 +- .../gnunet-service-cadet-new_connection.h | 46 +- src/cadet/gnunet-service-cadet-new_core.c | 460 ++++++++++++++++++ src/cadet/gnunet-service-cadet-new_peer.c | 16 + src/cadet/gnunet-service-cadet-new_peer.h | 11 + src/cadet/gnunet-service-cadet_connection.c | 18 +- 7 files changed, 581 insertions(+), 16 deletions(-) diff --git a/src/cadet/cadet_protocol.h b/src/cadet/cadet_protocol.h index ba2044b0d..e1f768ab7 100644 --- a/src/cadet/cadet_protocol.h +++ b/src/cadet/cadet_protocol.h @@ -322,6 +322,7 @@ struct GNUNET_CADET_Encrypted /******************************* CHANNEL ***********************************/ /******************************************************************************/ +#ifndef NEW_CADET /** * Message to create a Channel. @@ -349,6 +350,7 @@ struct GNUNET_CADET_ChannelCreate struct GNUNET_CADET_ChannelNumber chid; }; +#endif /** * Message to manage a Channel (ACK, NACK, Destroy). @@ -367,6 +369,8 @@ struct GNUNET_CADET_ChannelManage }; +#ifndef NEW_CADET + /** * Message for cadet data traffic. */ @@ -422,7 +426,7 @@ struct GNUNET_CADET_DataACK uint32_t mid GNUNET_PACKED; }; - +#endif GNUNET_NETWORK_STRUCT_END diff --git a/src/cadet/gnunet-service-cadet-new_connection.c b/src/cadet/gnunet-service-cadet-new_connection.c index 6a9c210b8..761bc403a 100644 --- a/src/cadet/gnunet-service-cadet-new_connection.c +++ b/src/cadet/gnunet-service-cadet-new_connection.c @@ -205,9 +205,10 @@ GCC_destroy (struct CadetConnection *cc) * * @param id hash to expand * @return expanded hash + * @param deprecated */ -static const struct GNUNET_HashCode * -h2hc (const struct GNUNET_CADET_Hash *id) +const struct GNUNET_HashCode * +GCC_h2hc (const struct GNUNET_CADET_Hash *id) { static struct GNUNET_HashCode hc; char *ptr = (char *) &hc; @@ -232,7 +233,7 @@ h2hc (const struct GNUNET_CADET_Hash *id) const struct GNUNET_HashCode * GCC_get_h (const struct CadetConnection *cc) { - return h2hc (&cc->cid.connection_of_tunnel); + return GCC_h2hc (&cc->cid.connection_of_tunnel); } @@ -250,12 +251,13 @@ GCC_get_ct (struct CadetConnection *cc) /** - * An ACK was received for this connection, process it. + * A connection ACK was received for this connection, implying + * that the end-to-end connection is up. Process it. * * @param cc the connection that got the ACK. */ void -GCC_handle_ack (struct CadetConnection *cc) +GCC_handle_connection_ack (struct CadetConnection *cc) { GNUNET_SCHEDULER_cancel (cc->task); #if FIXME @@ -268,6 +270,34 @@ GCC_handle_ack (struct CadetConnection *cc) } +/** + * Handle KX message. + * + * @param cc connection that received encrypted message + * @param msg the key exchange message + */ +void +GCC_handle_kx (struct CadetConnection *cc, + const struct GNUNET_CADET_KX *msg) +{ + GNUNET_assert (0); // FIXME: not implemented +} + + +/** + * Handle encrypted message. + * + * @param cc connection that received encrypted message + * @param msg the encrypted message to decrypt + */ +void +GCC_handle_encrypted (struct CadetConnection *cc, + const struct GNUNET_CADET_Encrypted *msg) +{ + GNUNET_assert (0); // FIXME: not implemented +} + + /** * Send a CREATE message to the first hop. * diff --git a/src/cadet/gnunet-service-cadet-new_connection.h b/src/cadet/gnunet-service-cadet-new_connection.h index 66d19ae0c..6ed83575f 100644 --- a/src/cadet/gnunet-service-cadet-new_connection.h +++ b/src/cadet/gnunet-service-cadet-new_connection.h @@ -28,10 +28,12 @@ #ifndef GNUNET_SERVICE_CADET_CONNECTION_H #define GNUNET_SERVICE_CADET_CONNECTION_H +#define NEW_CADET + #include "gnunet_util_lib.h" #include "gnunet-service-cadet-new.h" #include "gnunet-service-cadet-new_peer.h" - +#include "cadet_protocol.h" /** * Is the given connection currently ready for transmission? @@ -88,6 +90,37 @@ GCC_transmit (struct CadetConnection *cc, struct GNUNET_MQ_Envelope *env); +/** + * An ACK was received for this connection, process it. + * + * @param cc the connection that got the ACK. + */ +void +GCC_handle_connection_ack (struct CadetConnection *cc); + + +/** + * Handle KX message. + * + * @param cc connection that received encrypted message + * @param msg the key exchange message + */ +void +GCC_handle_kx (struct CadetConnection *cc, + const struct GNUNET_CADET_KX *msg); + + +/** + * Handle encrypted message. + * + * @param cc connection that received encrypted message + * @param msg the encrypted message to decrypt + */ +void +GCC_handle_encrypted (struct CadetConnection *cc, + const struct GNUNET_CADET_Encrypted *msg); + + /** * Return the tunnel associated with this connection. * @@ -129,6 +162,17 @@ const struct GNUNET_HashCode * GCC_get_h (const struct CadetConnection *cc); +/** + * Expand the shorter CADET hash to a full GNUnet hash. + * + * @param id hash to expand + * @return expanded hash + * @param deprecated + */ +const struct GNUNET_HashCode * +GCC_h2hc (const struct GNUNET_CADET_Hash *id); + + /** * Log connection info. * diff --git a/src/cadet/gnunet-service-cadet-new_core.c b/src/cadet/gnunet-service-cadet-new_core.c index a24f7a3ce..8cc6c843e 100644 --- a/src/cadet/gnunet-service-cadet-new_core.c +++ b/src/cadet/gnunet-service-cadet-new_core.c @@ -28,15 +28,435 @@ */ #include "platform.h" #include "gnunet-service-cadet-new_core.h" +#include "gnunet-service-cadet-new_paths.h" #include "gnunet-service-cadet-new_peer.h" #include "gnunet-service-cadet-new_connection.h" #include "gnunet_core_service.h" +#include "cadet_protocol.h" + + +/** + * Description of a segment of a `struct CadetConnection` at the + * intermediate peers. Routes are basically entries in a peer's + * routing table for forwarding traffic. At both endpoints, the + * routes are terminated by a `struct CadetConnection`, which knows + * the complete `struct CadetPath` that is formed by the individual + * routes. + */ +struct CadetRoute +{ + + /** + * Previous hop on this route. + */ + struct CadetPeer *prev_hop; + + /** + * Next hop on this route. + */ + struct CadetPeer *next_hop; + + /** + * Unique identifier for the connection that uses this route. + */ + struct GNUNET_CADET_ConnectionTunnelIdentifier cid; + + /** + * When was this route last in use? + */ + struct GNUNET_TIME_Absolute last_use; + +}; + /** * Handle to the CORE service. */ static struct GNUNET_CORE_Handle *core; +/** + * Routes on which this peer is an intermediate. + */ +static struct GNUNET_CONTAINER_MultiHashMap *routes; + + +/** + * Get the route corresponding to a hash. + * + * @param cid hash generated from the connection identifier + */ +static struct CadetRoute * +get_route (const struct GNUNET_HashCode *cid) +{ + return GNUNET_CONTAINER_multihashmap_get (routes, + cid); +} + + +/** + * We message @a msg from @a prev. Find its route by @a cid and + * forward to the next hop. Drop and signal broken route if we do not + * have a route. + * + * @param prev previous hop (sender) + * @param cid connection identifier, tells us which route to use + * @param msg the message to forward + */ +static void +route_message (struct CadetPeer *prev, + const struct GNUNET_HashCode *cid, /* FIXME: bad type... */ + const struct GNUNET_MessageHeader *msg) +{ + struct CadetRoute *route; + + route = get_route (cid); + if (NULL == route) + { + struct GNUNET_MQ_Envelope *env; + struct GNUNET_CADET_ConnectionBroken *bm; + + env = GNUNET_MQ_msg (bm, + GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN); + /* FIXME: ugly */ + memcpy (&bm->cid, + cid, + sizeof (bm->cid)); + bm->peer1 = my_full_id; + GCP_send (prev, + env); + return; + } + GNUNET_assert (0); /* FIXME: determine next hop from route and prev! */ + +} + + +/** + * Check if the create_connection message has the appropriate size. + * + * @param cls Closure (unused). + * @param msg Message to check. + * + * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise. + */ +static int +check_create (void *cls, + const struct GNUNET_CADET_ConnectionCreate *msg) +{ + uint16_t size = ntohs (msg->header.size) - sizeof (*msg); + + if (0 != (size % sizeof (struct GNUNET_PeerIdentity))) + { + GNUNET_break_op (0); + return GNUNET_NO; + } + return GNUNET_YES; +} + + +/** + * Destroy our state for @a route. + * + * @param route route to destroy + */ +static void +destroy_route (struct CadetRoute *route) +{ + GNUNET_break (0); // fIXME: implement! +} + + +/** + * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE + * + * @param cls Closure (CadetPeer for neighbor that sent the message). + * @param msg Message itself. + */ +static void +handle_create (void *cls, + const struct GNUNET_CADET_ConnectionCreate *msg) +{ + struct CadetPeer *peer = cls; + uint16_t size = ntohs (msg->header.size) - sizeof (*msg); + unsigned int path_length; + + path_length = size / sizeof (struct GNUNET_PeerIdentity); +#if FIXME + GCC_handle_create (peer, + &msg->cid, + path_length, + (const struct GNUNET_PeerIdentity *) &msg[1]); +#endif +} + + +/** + * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK + * + * @param cls Closure (CadetPeer for neighbor that sent the message). + * @param msg Message itself. + */ +static void +handle_connection_ack (void *cls, + const struct GNUNET_CADET_ConnectionACK *msg) +{ + struct CadetPeer *peer = cls; + const struct GNUNET_HashCode *cid = GCC_h2hc (&msg->cid.connection_of_tunnel); + struct CadetConnection *cc; + + /* First, check if ACK belongs to a connection that ends here. */ + cc = GNUNET_CONTAINER_multihashmap_get (connections, + cid); + if (NULL != cc) + { + /* verify ACK came from the right direction */ + struct CadetPeerPath *path = GCC_get_path (cc); + + if (peer != + GCPP_get_peer_at_offset (path, + 0)) + { + /* received ACK from unexpected direction, ignore! */ + GNUNET_break_op (0); + return; + } + GCC_handle_connection_ack (cc); + return; + } + + /* We're just an intermediary peer, route the message along its path */ + route_message (peer, + cid, + &msg->header); +} + + +/** + * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN + * + * @param cls Closure (CadetPeer for neighbor that sent the message). + * @param msg Message itself. + * @deprecated duplicate logic with #handle_destroy(); dedup! + */ +static void +handle_broken (void *cls, + const struct GNUNET_CADET_ConnectionBroken *msg) +{ + struct CadetPeer *peer = cls; + const struct GNUNET_HashCode *cid = GCC_h2hc (&msg->cid.connection_of_tunnel); + struct CadetConnection *cc; + struct CadetRoute *route; + + /* First, check if message belongs to a connection that ends here. */ + cc = GNUNET_CONTAINER_multihashmap_get (connections, + cid); + if (NULL != cc) + { + /* verify message came from the right direction */ + struct CadetPeerPath *path = GCC_get_path (cc); + + if (peer != + GCPP_get_peer_at_offset (path, + 0)) + { + /* received message from unexpected direction, ignore! */ + GNUNET_break_op (0); + return; + } + GCC_destroy (cc); + return; + } + + /* We're just an intermediary peer, route the message along its path */ + route = get_route (cid); + route_message (peer, + cid, + &msg->header); + destroy_route (route); +} + + +/** + * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY + * + * @param cls Closure (CadetPeer for neighbor that sent the message). + * @param msg Message itself. + */ +static void +handle_destroy (void *cls, + const struct GNUNET_CADET_ConnectionDestroy *msg) +{ + struct CadetPeer *peer = cls; + const struct GNUNET_HashCode *cid = GCC_h2hc (&msg->cid.connection_of_tunnel); + struct CadetConnection *cc; + struct CadetRoute *route; + + /* First, check if message belongs to a connection that ends here. */ + cc = GNUNET_CONTAINER_multihashmap_get (connections, + cid); + if (NULL != cc) + { + /* verify message came from the right direction */ + struct CadetPeerPath *path = GCC_get_path (cc); + + if (peer != + GCPP_get_peer_at_offset (path, + 0)) + { + /* received message from unexpected direction, ignore! */ + GNUNET_break_op (0); + return; + } + GCC_destroy (cc); + return; + } + + /* We're just an intermediary peer, route the message along its path */ + route = get_route (cid); + route_message (peer, + cid, + &msg->header); + destroy_route (route); +} + + +/** + * Handle for #GNUNET_MESSAGE_TYPE_CADET_ACK + * + * @param cls Closure (CadetPeer for neighbor that sent the message). + * @param msg Message itself. + */ +static void +handle_ack (void *cls, + const struct GNUNET_CADET_ACK *msg) +{ + struct CadetPeer *peer = cls; + +#if FIXME + GCC_handle_ack (peer, + msg); +#endif +} + + +/** + * Handle for #GNUNET_MESSAGE_TYPE_CADET_POLL + * + * @param cls Closure (CadetPeer for neighbor that sent the message). + * @param msg Message itself. + */ +static void +handle_poll (void *cls, + const struct GNUNET_CADET_Poll *msg) +{ + struct CadetPeer *peer = cls; + +#if FIXME + GCC_handle_poll (peer, + msg); +#endif +} + + +/** + * Handle for #GNUNET_MESSAGE_TYPE_CADET_KX + * + * @param cls Closure (CadetPeer for neighbor that sent the message). + * @param msg Message itself. + */ +static void +handle_kx (void *cls, + const struct GNUNET_CADET_KX *msg) +{ + struct CadetPeer *peer = cls; + const struct GNUNET_HashCode *cid = GCC_h2hc (&msg->cid.connection_of_tunnel); + struct CadetConnection *cc; + + /* First, check if message belongs to a connection that ends here. */ + cc = GNUNET_CONTAINER_multihashmap_get (connections, + cid); + if (NULL != cc) + { + /* verify message came from the right direction */ + struct CadetPeerPath *path = GCC_get_path (cc); + + if (peer != + GCPP_get_peer_at_offset (path, + 0)) + { + /* received message from unexpected direction, ignore! */ + GNUNET_break_op (0); + return; + } + GCC_handle_kx (cc, + msg); + return; + } + + /* We're just an intermediary peer, route the message along its path */ + route_message (peer, + cid, + &msg->header); +} + + +/** + * Check if the encrypted message has the appropriate size. + * + * @param cls Closure (unused). + * @param msg Message to check. + * + * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise. + */ +static int +check_encrypted (void *cls, + const struct GNUNET_CADET_Encrypted *msg) +{ + return GNUNET_YES; +} + + +/** + * Handle for #GNUNET_MESSAGE_TYPE_CADET_ENCRYPTED. + * + * @param cls Closure (CadetPeer for neighbor that sent the message). + * @param msg Message itself. + */ +static void +handle_encrypted (void *cls, + const struct GNUNET_CADET_Encrypted *msg) +{ + struct CadetPeer *peer = cls; + const struct GNUNET_HashCode *cid = GCC_h2hc (&msg->cid.connection_of_tunnel); + struct CadetConnection *cc; + + /* First, check if message belongs to a connection that ends here. */ + cc = GNUNET_CONTAINER_multihashmap_get (connections, + cid); + if (NULL != cc) + { + /* verify message came from the right direction */ + struct CadetPeerPath *path = GCC_get_path (cc); + + if (peer != + GCPP_get_peer_at_offset (path, + 0)) + { + /* received message from unexpected direction, ignore! */ + GNUNET_break_op (0); + return; + } + GCC_handle_encrypted (cc, + msg); + return; + } + + /* We're just an intermediary peer, route the message along its path */ + route_message (peer, + cid, + &msg->header); +} + /** * Function called after #GNUNET_CORE_connect has succeeded (or failed @@ -100,6 +520,9 @@ core_disconnect_cb (void *cls, { struct CadetPeer *cp = peer_cls; + /* FIXME: also check all routes going via peer and + send broken messages to the other direction! */ + GNUNET_break (0); GCP_set_mq (cp, NULL); } @@ -114,8 +537,43 @@ void GCO_init (const struct GNUNET_CONFIGURATION_Handle *c) { struct GNUNET_MQ_MessageHandler handlers[] = { + GNUNET_MQ_hd_var_size (create, + GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE, + struct GNUNET_CADET_ConnectionCreate, + NULL), + GNUNET_MQ_hd_fixed_size (connection_ack, + GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK, + struct GNUNET_CADET_ConnectionACK, + NULL), + GNUNET_MQ_hd_fixed_size (broken, + GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN, + struct GNUNET_CADET_ConnectionBroken, + NULL), + GNUNET_MQ_hd_fixed_size (destroy, + GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY, + struct GNUNET_CADET_ConnectionDestroy, + NULL), + GNUNET_MQ_hd_fixed_size (ack, + GNUNET_MESSAGE_TYPE_CADET_ACK, + struct GNUNET_CADET_ACK, + NULL), + GNUNET_MQ_hd_fixed_size (poll, + GNUNET_MESSAGE_TYPE_CADET_POLL, + struct GNUNET_CADET_Poll, + NULL), + GNUNET_MQ_hd_fixed_size (kx, + GNUNET_MESSAGE_TYPE_CADET_KX, + struct GNUNET_CADET_KX, + NULL), + GNUNET_MQ_hd_var_size (encrypted, + GNUNET_MESSAGE_TYPE_CADET_ENCRYPTED, + struct GNUNET_CADET_Encrypted, + NULL), GNUNET_MQ_handler_end () }; + + routes = GNUNET_CONTAINER_multihashmap_create (1024, + GNUNET_NO); core = GNUNET_CORE_connect (c, NULL, &core_init_cb, @@ -136,6 +594,8 @@ GCO_shutdown () GNUNET_CORE_disconnect (core); core = NULL; } + GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (routes)); + GNUNET_CONTAINER_multihashmap_destroy (routes); } /* end of gnunet-cadet-service_core.c */ diff --git a/src/cadet/gnunet-service-cadet-new_peer.c b/src/cadet/gnunet-service-cadet-new_peer.c index ed3b24641..5c3e6cf17 100644 --- a/src/cadet/gnunet-service-cadet-new_peer.c +++ b/src/cadet/gnunet-service-cadet-new_peer.c @@ -283,6 +283,22 @@ GCP_set_mq (struct CadetPeer *cp, } +/** + * Send the message in @a env to @a cp. + * + * @param cp the peer + * @param env envelope with the message to send + */ +void +GCP_send (struct CadetPeer *cp, + struct GNUNET_MQ_Envelope *env) +{ + GNUNET_assert (NULL != cp->core_mq); + GNUNET_MQ_send (cp->core_mq, + env); +} + + /** * Function called to destroy a peer now. * diff --git a/src/cadet/gnunet-service-cadet-new_peer.h b/src/cadet/gnunet-service-cadet-new_peer.h index 74988981f..6b0812cc7 100644 --- a/src/cadet/gnunet-service-cadet-new_peer.h +++ b/src/cadet/gnunet-service-cadet-new_peer.h @@ -312,4 +312,15 @@ GCP_set_mq (struct CadetPeer *cp, struct GNUNET_MQ_Handle *mq); +/** + * Send the message in @a env to @a cp. + * + * @param cp the peer + * @param env envelope with the message to send + */ +void +GCP_send (struct CadetPeer *cp, + struct GNUNET_MQ_Envelope *env); + + #endif diff --git a/src/cadet/gnunet-service-cadet_connection.c b/src/cadet/gnunet-service-cadet_connection.c index ffd98bf34..2c21a1686 100644 --- a/src/cadet/gnunet-service-cadet_connection.c +++ b/src/cadet/gnunet-service-cadet_connection.c @@ -473,9 +473,9 @@ fc_init (struct CadetFlowControl *fc) * @return conntection with the given ID @cid or NULL if not found. */ static struct CadetConnection * -connection_get (const struct GNUNET_CADET_Hash *cid) +connection_get (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid) { - return GNUNET_CONTAINER_multihashmap_get (connections, GC_h2hc (cid)); + return GNUNET_CONTAINER_multihashmap_get (connections, GC_h2hc (&cid->connection_of_tunnel)); } @@ -1109,7 +1109,7 @@ send_broken_unknown (const struct GNUNET_CADET_ConnectionTunnelIdentifier *conne GCC_check_connections (); LOG (GNUNET_ERROR_TYPE_INFO, "--> BROKEN on unknown connection %s\n", - GNUNET_h2s (GC_h2hc (connection_id))); + GNUNET_h2s (GC_h2hc (&connection_id->connection_of_tunnel))); msg.header.size = htons (sizeof (struct GNUNET_CADET_ConnectionBroken)); msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN); @@ -1856,7 +1856,7 @@ log_message (const struct GNUNET_MessageHeader *message, arrow = "--"; } LOG (GNUNET_ERROR_TYPE_INFO, "<%s %s on conn %s from %s, %6u bytes\n", - arrow, GC_m2s (type), GNUNET_h2s (GC_h2hc (conn_id)), + arrow, GC_m2s (type), GNUNET_h2s (GC_h2hc (&conn_id->connection_of_tunnel)), GCP_2s(peer), (unsigned int) size); } @@ -2354,7 +2354,7 @@ GCC_handle_poll (struct CadetPeer *peer, GNUNET_NO); LOG (GNUNET_ERROR_TYPE_DEBUG, "POLL message on unknown connection %s!\n", - GNUNET_h2s (GC_h2hc (&msg->cid))); + GNUNET_h2s (GC_h2hc (&msg->cid.connection_of_tunnel))); send_broken_unknown (&msg->cid, &my_full_id, NULL, @@ -2428,7 +2428,7 @@ check_message (const struct GNUNET_MessageHeader *message, LOG (GNUNET_ERROR_TYPE_DEBUG, "%s on unknown connection %s\n", GC_m2s (ntohs (message->type)), - GNUNET_h2s (GC_h2hc (cid))); + GNUNET_h2s (GC_h2hc (&cid->connection_of_tunnel))); GNUNET_break_op (0); send_broken_unknown (cid, &my_full_id, @@ -2888,7 +2888,7 @@ GCC_get_id (const struct CadetConnection *c) const struct GNUNET_HashCode * GCC_get_h (const struct CadetConnection *c) { - return GC_h2hc (&c->id); + return GC_h2hc (&c->id.connection_of_tunnel); } @@ -3559,10 +3559,10 @@ GCC_2s (const struct CadetConnection *c) static char buf[128]; SPRINTF (buf, "%s (->%s)", - GNUNET_h2s (GC_h2hc (GCC_get_id (c))), GCT_2s (c->t)); + GNUNET_h2s (GC_h2hc (&GCC_get_id (c)->connection_of_tunnel)), GCT_2s (c->t)); return buf; } - return GNUNET_h2s (GC_h2hc (&c->id)); + return GNUNET_h2s (GC_h2hc (&c->id.connection_of_tunnel)); } -- 2.25.1