From dfde8ea01a08a32340a47df29ffc2571c031488b Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 18 Jan 2017 19:24:33 +0100 Subject: [PATCH] create matching connection objects for inbound connections --- src/cadet/cadet_api.c | 6 +- src/cadet/cadet_protocol.h | 85 ++++++++- src/cadet/gnunet-cadet.c | 2 +- src/cadet/gnunet-service-cadet-new.c | 6 +- src/cadet/gnunet-service-cadet-new.h | 11 ++ src/cadet/gnunet-service-cadet-new_channel.c | 110 +---------- src/cadet/gnunet-service-cadet-new_channel.h | 4 +- .../gnunet-service-cadet-new_connection.c | 92 +++++++-- .../gnunet-service-cadet-new_connection.h | 23 ++- src/cadet/gnunet-service-cadet-new_core.c | 174 ++++++++++++++++-- src/cadet/gnunet-service-cadet-new_paths.c | 18 +- src/cadet/gnunet-service-cadet-new_paths.h | 14 +- src/cadet/gnunet-service-cadet-new_peer.c | 13 ++ src/cadet/gnunet-service-cadet-new_peer.h | 10 + src/cadet/gnunet-service-cadet-new_tunnels.c | 53 +++++- src/cadet/gnunet-service-cadet-new_tunnels.h | 26 +-- src/cadet/gnunet-service-cadet_channel.c | 6 +- src/cadet/gnunet-service-cadet_channel.h | 2 +- src/cadet/gnunet-service-cadet_local.c | 4 +- src/cadet/gnunet-service-cadet_tunnel.c | 12 +- src/cadet/gnunet-service-cadet_tunnel.h | 4 +- src/include/gnunet_cadet_service.h | 20 +- 22 files changed, 499 insertions(+), 196 deletions(-) diff --git a/src/cadet/cadet_api.c b/src/cadet/cadet_api.c index 4a662487c..8f1274d63 100644 --- a/src/cadet/cadet_api.c +++ b/src/cadet/cadet_api.c @@ -1209,7 +1209,7 @@ check_get_tunnel (void *cls, } ch_n = ntohl (msg->channels); c_n = ntohl (msg->connections); - esize += ch_n * sizeof (struct GNUNET_CADET_ChannelNumber); + esize += ch_n * sizeof (struct GNUNET_CADET_ChannelTunnelNumber); esize += c_n * sizeof (struct GNUNET_CADET_ConnectionTunnelIdentifier); if (msize != esize) { @@ -1248,14 +1248,14 @@ handle_get_tunnel (void *cls, unsigned int ch_n; unsigned int c_n; const struct GNUNET_CADET_ConnectionTunnelIdentifier *conns; - const struct GNUNET_CADET_ChannelNumber *chns; + const struct GNUNET_CADET_ChannelTunnelNumber *chns; ch_n = ntohl (msg->channels); c_n = ntohl (msg->connections); /* Call Callback with tunnel info. */ conns = (const struct GNUNET_CADET_ConnectionTunnelIdentifier *) &msg[1]; - chns = (const struct GNUNET_CADET_ChannelNumber *) &conns[c_n]; + chns = (const struct GNUNET_CADET_ChannelTunnelNumber *) &conns[c_n]; h->info_cb.tunnel_cb (h->info_cls, &msg->destination, ch_n, diff --git a/src/cadet/cadet_protocol.h b/src/cadet/cadet_protocol.h index 7e4a6ae16..cf32e0d6d 100644 --- a/src/cadet/cadet_protocol.h +++ b/src/cadet/cadet_protocol.h @@ -113,7 +113,7 @@ struct GNUNET_CADET_ConnectionCreateMessageAckMessage struct GNUNET_CADET_ConnectionBrokenMessage { /** - * Type: #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN + * Type: #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN. */ struct GNUNET_MessageHeader header; @@ -350,7 +350,6 @@ struct GNUNET_CADET_ConnectionEncryptedAckMessage /******************************* CHANNEL ***********************************/ /******************************************************************************/ -#ifndef NEW_CADET /** * Message to create a Channel. @@ -373,12 +372,11 @@ struct GNUNET_CADET_ChannelOpenMessage struct GNUNET_HashCode port; /** - * ID of the channel + * ID of the channel within the tunnel. */ - struct GNUNET_CADET_ChannelNumber chid; + struct GNUNET_CADET_ChannelTunnelNumber chid; }; -#endif /** * Message to manage a Channel (ACK, NACK, Destroy). @@ -400,7 +398,7 @@ struct GNUNET_CADET_ChannelManageMessage /** * ID of the channel */ - struct GNUNET_CADET_ChannelNumber chid; + struct GNUNET_CADET_ChannelTunnelNumber chid; }; @@ -426,7 +424,7 @@ struct GNUNET_CADET_ChannelAppDataMessage /** * ID of the channel */ - struct GNUNET_CADET_ChannelNumber chid; + struct GNUNET_CADET_ChannelTunnelNumber chid; /** * Payload follows @@ -447,7 +445,7 @@ struct GNUNET_CADET_ChannelDataAckMessage /** * ID of the channel */ - struct GNUNET_CADET_ChannelNumber chid; + struct GNUNET_CADET_ChannelTunnelNumber chid; /** * Bitfield of already-received newer messages @@ -463,6 +461,77 @@ struct GNUNET_CADET_ChannelDataAckMessage uint32_t mid GNUNET_PACKED; }; +#else + + +/** + * Number used to uniquely identify messages in a CADET Channel. + */ +struct ChannelMessageIdentifier +{ + /** + * Unique ID of the message, cycles around, in NBO. + */ + uint32_t mid GNUNET_PACKED; +}; + + +/** + * Message for cadet data traffic. + */ +struct GNUNET_CADET_ChannelAppDataMessage +{ + /** + * Type: #GNUNET_MESSAGE_TYPE_CADET_UNICAST, + * #GNUNET_MESSAGE_TYPE_CADET_TO_ORIGIN + */ + struct GNUNET_MessageHeader header; + + /** + * Unique ID of the payload message. + */ + struct ChannelMessageIdentifier mid; + + /** + * ID of the channel + */ + struct GNUNET_CADET_ChannelTunnelNumber gid; + + /** + * Payload follows + */ +}; + + +/** + * Message to acknowledge end-to-end data. + */ +struct GNUNET_CADET_ChannelDataAckMessage +{ + /** + * Type: #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK + */ + struct GNUNET_MessageHeader header; + + /** + * ID of the channel + */ + struct GNUNET_CADET_ChannelTunnelNumber gid; + + /** + * Bitfield of already-received messages past @e mid. + * pid + 1 @ LSB + * pid + 64 @ MSB + */ + uint64_t futures GNUNET_PACKED; + + /** + * Last message ID received. + */ + struct ChannelMessageIdentifier mid; +}; + + #endif GNUNET_NETWORK_STRUCT_END diff --git a/src/cadet/gnunet-cadet.c b/src/cadet/gnunet-cadet.c index 72d7bf8a9..80010ec54 100644 --- a/src/cadet/gnunet-cadet.c +++ b/src/cadet/gnunet-cadet.c @@ -727,7 +727,7 @@ tunnel_callback (void *cls, const struct GNUNET_PeerIdentity *peer, unsigned int n_channels, unsigned int n_connections, - const struct GNUNET_CADET_ChannelNumber *channels, + const struct GNUNET_CADET_ChannelTunnelNumber *channels, const struct GNUNET_CADET_ConnectionTunnelIdentifier *connections, unsigned int estate, unsigned int cstate) diff --git a/src/cadet/gnunet-service-cadet-new.c b/src/cadet/gnunet-service-cadet-new.c index 3e149e9bb..2f6cc7b11 100644 --- a/src/cadet/gnunet-service-cadet-new.c +++ b/src/cadet/gnunet-service-cadet-new.c @@ -911,8 +911,8 @@ iter_channel (void *cls, { struct GNUNET_CADET_LocalInfoTunnel *msg = cls; struct GNUNET_CADET_ConnectionTunnelIdentifier *h = (struct GNUNET_CADET_ConnectionTunnelIdentifier *) &msg[1]; - struct GCT_ChannelTunnelNumber *chn - = (struct GCT_ChannelTunnelNumber *) &h[msg->connections]; + struct GNUNET_CADET_ChannelTunnelNumber *chn + = (struct GNUNET_CADET_ChannelTunnelNumber *) &h[msg->connections]; chn[msg->channels++] = GCCH_get_id (ch); } @@ -963,7 +963,7 @@ handle_show_tunnel (void *cls, c_n = GCT_count_any_connections (t); env = GNUNET_MQ_msg_extra (resp, c_n * sizeof (struct GNUNET_CADET_ConnectionTunnelIdentifier) + - ch_n * sizeof (struct GCT_ChannelTunnelNumber), + ch_n * sizeof (struct GNUNET_CADET_ChannelTunnelNumber), GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL); resp->destination = msg->peer; /* Do not reorder! #iter_channel needs counters in HBO! */ diff --git a/src/cadet/gnunet-service-cadet-new.h b/src/cadet/gnunet-service-cadet-new.h index 3258a6666..862a0f088 100644 --- a/src/cadet/gnunet-service-cadet-new.h +++ b/src/cadet/gnunet-service-cadet-new.h @@ -29,6 +29,7 @@ #define GNUNET_SERVICE_CADET_H #include "gnunet_util_lib.h" +#define NEW_CADET 1 /** * A client to the CADET service. Each client gets a unique handle. @@ -112,6 +113,16 @@ struct CadetTConnection; */ struct CadetConnection; +/** + * 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; + /** * Logical end-to-end conenction between clients. There can be * any number of channels between clients. diff --git a/src/cadet/gnunet-service-cadet-new_channel.c b/src/cadet/gnunet-service-cadet-new_channel.c index 32e4c6269..dcbc5614f 100644 --- a/src/cadet/gnunet-service-cadet-new_channel.c +++ b/src/cadet/gnunet-service-cadet-new_channel.c @@ -51,108 +51,6 @@ #define TIMEOUT_CLOSED_PORT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30) -GNUNET_NETWORK_STRUCT_BEGIN - -/** - * Number used to uniquely identify messages in a CADET Channel. - */ -struct ChannelMessageIdentifier -{ - /** - * Unique ID of the message, cycles around, in NBO. - */ - uint32_t mid GNUNET_PACKED; -}; - - -/** - * Message to create a Channel. - */ -struct GNUNET_CADET_ChannelOpenMessage -{ - /** - * Type: #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN - */ - struct GNUNET_MessageHeader header; - - /** - * Channel options. - */ - uint32_t opt GNUNET_PACKED; - - /** - * Destination port. - */ - struct GNUNET_HashCode port; - - /** - * ID of the channel - */ - struct GCT_ChannelTunnelNumber gid; -}; - - - -/** - * Message for cadet data traffic. - */ -struct GNUNET_CADET_ChannelAppDataMessage -{ - /** - * Type: #GNUNET_MESSAGE_TYPE_CADET_UNICAST, - * #GNUNET_MESSAGE_TYPE_CADET_TO_ORIGIN - */ - struct GNUNET_MessageHeader header; - - /** - * Unique ID of the payload message. - */ - struct ChannelMessageIdentifier mid; - - /** - * ID of the channel - */ - struct GCT_ChannelTunnelNumber gid; - - /** - * Payload follows - */ -}; - - -/** - * Message to acknowledge end-to-end data. - */ -struct GNUNET_CADET_ChannelDataAckMessage -{ - /** - * Type: #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK - */ - struct GNUNET_MessageHeader header; - - /** - * ID of the channel - */ - struct GCT_ChannelTunnelNumber gid; - - /** - * Bitfield of already-received messages past @e mid. - * pid + 1 @ LSB - * pid + 64 @ MSB - */ - uint64_t futures GNUNET_PACKED; - - /** - * Last message ID received. - */ - struct ChannelMessageIdentifier mid; -}; - - - -GNUNET_NETWORK_STRUCT_END - - /** * All the states a connection can be in. */ @@ -357,7 +255,7 @@ struct CadetChannel /** * Number identifying this channel in its tunnel. */ - struct GCT_ChannelTunnelNumber gid; + struct GNUNET_CADET_ChannelTunnelNumber gid; /** * Local tunnel number for local client owning the channel. @@ -438,7 +336,7 @@ GCCH_2s (const struct CadetChannel *ch) * * @return ID used to identify the channel with the remote peer. */ -struct GCT_ChannelTunnelNumber +struct GNUNET_CADET_ChannelTunnelNumber GCCH_get_id (const struct CadetChannel *ch) { return ch->gid; @@ -545,7 +443,7 @@ send_create (void *cls) msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN); msgcc.opt = htonl (options); msgcc.port = ch->port; - msgcc.gid = ch->gid; + msgcc.chid = ch->gid; ch->state = CADET_CHANNEL_CREATE_SENT; ch->last_control_qe = GCT_send (ch->t, &msgcc.header, @@ -624,7 +522,7 @@ timeout_closed_cb (void *cls) */ struct CadetChannel * GCCH_channel_incoming_new (struct CadetTunnel *t, - struct GCT_ChannelTunnelNumber gid, + struct GNUNET_CADET_ChannelTunnelNumber gid, const struct GNUNET_HashCode *port, uint32_t options) { diff --git a/src/cadet/gnunet-service-cadet-new_channel.h b/src/cadet/gnunet-service-cadet-new_channel.h index 5cf42a894..85302ea0a 100644 --- a/src/cadet/gnunet-service-cadet-new_channel.h +++ b/src/cadet/gnunet-service-cadet-new_channel.h @@ -72,7 +72,7 @@ GCCH_debug (struct CadetChannel *ch, * * @return ID used to identify the channel with the remote peer. */ -struct GCT_ChannelTunnelNumber +struct GNUNET_CADET_ChannelTunnelNumber GCCH_get_id (const struct CadetChannel *ch); @@ -130,7 +130,7 @@ GCCH_channel_local_destroy (struct CadetChannel *ch); */ struct CadetChannel * GCCH_channel_incoming_new (struct CadetTunnel *t, - struct GCT_ChannelTunnelNumber gid, + struct GNUNET_CADET_ChannelTunnelNumber gid, const struct GNUNET_HashCode *port, uint32_t options); diff --git a/src/cadet/gnunet-service-cadet-new_connection.c b/src/cadet/gnunet-service-cadet-new_connection.c index 440d64fb6..5123f9d45 100644 --- a/src/cadet/gnunet-service-cadet-new_connection.c +++ b/src/cadet/gnunet-service-cadet-new_connection.c @@ -376,22 +376,24 @@ manage_first_hop_mq (void *cls, /** - * Create a connection to @a destination via @a path and - * notify @a cb whenever we are ready for more data. + * Create a connection to @a destination via @a path and notify @a cb + * whenever we are ready for more data. Shared logic independent of + * who is initiating the connection. * * @param destination where to go * @param path which path to take (may not be the full path) - * @param ct tunnel that uses the connection + * @param ct which tunnel uses this connection * @param ready_cb function to call when ready to transmit * @param ready_cb_cls closure for @a cb * @return handle to the connection */ -struct CadetConnection * -GCC_create (struct CadetPeer *destination, - struct CadetPeerPath *path, - struct CadetTConnection *ct, - GNUNET_SCHEDULER_TaskCallback ready_cb, - void *ready_cb_cls) +static struct CadetConnection * +connection_create (struct CadetPeer *destination, + struct CadetPeerPath *path, + struct CadetTConnection *ct, + const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, + GNUNET_SCHEDULER_TaskCallback ready_cb, + void *ready_cb_cls) { struct CadetConnection *cc; struct CadetPeer *first_hop; @@ -402,9 +404,7 @@ GCC_create (struct CadetPeer *destination, GNUNET_assert (UINT_MAX > off); cc = GNUNET_new (struct CadetConnection); cc->ct = ct; - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, - &cc->cid, - sizeof (cc->cid)); + cc->cid = *cid; GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multishortmap_put (connections, &GCC_get_id (cc)->connection_of_tunnel, @@ -431,6 +431,74 @@ GCC_create (struct CadetPeer *destination, } +/** + * Create a connection to @a destination via @a path and + * notify @a cb whenever we are ready for more data. This + * is an inbound tunnel, so we must use the existing @a cid + * + * @param destination where to go + * @param path which path to take (may not be the full path) + * @param ct which tunnel uses this connection + * @param ready_cb function to call when ready to transmit + * @param ready_cb_cls closure for @a cb + * @return handle to the connection + */ +struct CadetConnection * +GCC_create_inbound (struct CadetPeer *destination, + struct CadetPeerPath *path, + struct CadetTConnection *ct, + const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, + GNUNET_SCHEDULER_TaskCallback ready_cb, + void *ready_cb_cls) +{ + struct CadetConnection *cc; + + cc = connection_create (destination, + path, + ct, + cid, + ready_cb, + ready_cb_cls); + /* FIXME: send CREATE_ACK? */ + return cc; +} + + +/** + * Create a connection to @a destination via @a path and + * notify @a cb whenever we are ready for more data. + * + * @param destination where to go + * @param path which path to take (may not be the full path) + * @param ct tunnel that uses the connection + * @param ready_cb function to call when ready to transmit + * @param ready_cb_cls closure for @a cb + * @return handle to the connection + */ +struct CadetConnection * +GCC_create (struct CadetPeer *destination, + struct CadetPeerPath *path, + struct CadetTConnection *ct, + GNUNET_SCHEDULER_TaskCallback ready_cb, + void *ready_cb_cls) +{ + struct GNUNET_CADET_ConnectionTunnelIdentifier cid; + struct CadetConnection *cc; + + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, + &cid, + sizeof (cid)); + cc = connection_create (destination, + path, + ct, + &cid, + ready_cb, + ready_cb_cls); + /* FIXME: send CREATE? */ + return cc; +} + + /** * We finished transmission of a message, if we are still ready, tell * the tunnel! diff --git a/src/cadet/gnunet-service-cadet-new_connection.h b/src/cadet/gnunet-service-cadet-new_connection.h index 32452024c..f2364dea4 100644 --- a/src/cadet/gnunet-service-cadet-new_connection.h +++ b/src/cadet/gnunet-service-cadet-new_connection.h @@ -28,8 +28,6 @@ #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" @@ -73,6 +71,27 @@ GCC_create (struct CadetPeer *destination, void *ready_cb_cls); +/** + * Create a connection to @a destination via @a path and + * notify @a cb whenever we are ready for more data. This + * is an inbound tunnel, so we must use the existing @a cid + * + * @param destination where to go + * @param path which path to take (may not be the full path) + * @param ct which tunnel uses this connection + * @param ready_cb function to call when ready to transmit + * @param ready_cb_cls closure for @a cb + * @return handle to the connection + */ +struct CadetConnection * +GCC_create_inbound (struct CadetPeer *destination, + struct CadetPeerPath *path, + struct CadetTConnection *ct, + const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, + GNUNET_SCHEDULER_TaskCallback ready_cb, + void *ready_cb_cls); + + /** * Transmit message @a msg via connection @a cc. Must only be called * (once) after the connection has signalled that it is ready via the diff --git a/src/cadet/gnunet-service-cadet-new_core.c b/src/cadet/gnunet-service-cadet-new_core.c index e9fc6bf05..3d8406dc9 100644 --- a/src/cadet/gnunet-service-cadet-new_core.c +++ b/src/cadet/gnunet-service-cadet-new_core.c @@ -31,6 +31,7 @@ #include "gnunet-service-cadet-new_paths.h" #include "gnunet-service-cadet-new_peer.h" #include "gnunet-service-cadet-new_connection.h" +#include "gnunet-service-cadet-new_tunnels.h" #include "gnunet_core_service.h" #include "cadet_protocol.h" @@ -76,6 +77,12 @@ struct CadetRoute */ struct GNUNET_TIME_Absolute last_use; + /** + * Counter, used to verify that both MQs are up when the route is + * initialized. + */ + unsigned int up; + }; @@ -176,6 +183,91 @@ destroy_route (struct CadetRoute *route) } +/** + * Send message that a route is broken between @a peer1 and @a peer2. + * + * @param target where to send the message + * @param cid connection identifier to use + * @param peer1 one of the peers where a link is broken + * @param peer2 another one of the peers where a link is broken + */ +static void +send_broken (struct CadetPeer *target, + const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, + const struct GNUNET_PeerIdentity *peer1, + const struct GNUNET_PeerIdentity *peer2) +{ + struct GNUNET_MQ_Envelope *env; + struct GNUNET_CADET_ConnectionBrokenMessage *bm; + + env = GNUNET_MQ_msg (bm, + GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN); + bm->cid = *cid; + if (NULL != peer1) + bm->peer1 = *peer1; + if (NULL != peer2) + bm->peer2 = *peer2; + GCP_send (target, + env); +} + + +/** + * Function called when the message queue to the previous hop + * becomes available/unavailable. We expect this function to + * be called immediately when we register, and then again + * later if the connection ever goes down. + * + * @param cls the `struct CadetRoute` + * @param mq the message queue, NULL if connection went down + */ +static void +mqm_cr_destroy_prev (void *cls, + struct GNUNET_MQ_Handle *mq) +{ + struct CadetRoute *route = cls; + + if (NULL != mq) + { + route->up |= 1; + return; + } + send_broken (route->next_hop, + &route->cid, + GCP_get_id (route->prev_hop), + &my_full_id); + destroy_route (route); +} + + +/** + * Function called when the message queue to the previous hop + * becomes available/unavailable. We expect this function to + * be called immediately when we register, and then again + * later if the connection ever goes down. + * + * @param cls the `struct CadetRoute` + * @param mq the message queue, NULL if connection went down + */ +static void +mqm_cr_destroy_next (void *cls, + struct GNUNET_MQ_Handle *mq) +{ + struct CadetRoute *route = cls; + + if (NULL != mq) + { + route->up |= 2; + return; + } + send_broken (route->prev_hop, + &route->cid, + GCP_get_id (route->next_hop), + &my_full_id); + destroy_route (route); +} + + /** * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE * @@ -215,29 +307,60 @@ handle_connection_create (void *cls, GNUNET_break_op (0); return; } + if (NULL != + get_route (&msg->cid)) + { + /* CID not chosen at random, collides */ + GNUNET_break_op (0); + return; + } if (off == path_length - 1) { /* We are the destination, create connection */ + struct CadetPeerPath *path; + struct CadetPeer *origin; + + path = GCPP_get_path_from_route (path_length, + pids); + origin = GCP_get (&pids[0], + GNUNET_YES); + GCT_add_inbound_connection (GCT_create_tunnel (origin), + &msg->cid, + path); + return; } /* We are merely a hop on the way, check if we can support the route */ next = GCP_get (&pids[off + 1], GNUNET_NO); - if (NULL == next) + if ( (NULL == next) || + (NULL == GCP_get_mq (next)) ) { - /* unworkable, send back BROKEN */ - GNUNET_break (0); // FIXME... + /* unworkable, send back BROKEN notification */ + send_broken (sender, + &msg->cid, + &pids[off + 1], + &my_full_id); return; } + /* Workable route, create routing entry */ route = GNUNET_new (struct CadetRoute); - -#if FIXME - GCC_handle_create (peer, - &msg->cid, - path_length, - route); -#endif + route->cid = msg->cid; + route->prev_mqm = GCP_request_mq (sender, + &mqm_cr_destroy_prev, + route); + route->next_mqm = GCP_request_mq (next, + &mqm_cr_destroy_next, + route); + route->prev_hop = sender; + route->next_hop = next; + GNUNET_assert ((1|2) == route->up); + GNUNET_assert (GNUNET_OK == + GNUNET_CONTAINER_multishortmap_put (routes, + &route->cid.connection_of_tunnel, + route, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); } @@ -382,11 +505,35 @@ handle_hop_by_hop_encrypted_ack (void *cls, const struct GNUNET_CADET_ConnectionEncryptedAckMessage *msg) { struct CadetPeer *peer = cls; + struct CadetConnection *cc; + + /* First, check if message belongs to a connection that ends here. */ + cc = GNUNET_CONTAINER_multishortmap_get (connections, + &msg->cid.connection_of_tunnel); + 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; + } #if FIXME - GCC_handle_poll (peer, - msg); + GCC_handle_ack (peer, + msg); #endif + return; + } + + /* We're just an intermediary peer, route the message along its path */ + route_message (peer, + &msg->cid, + &msg->header); } @@ -569,9 +716,6 @@ 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); } diff --git a/src/cadet/gnunet-service-cadet-new_paths.c b/src/cadet/gnunet-service-cadet-new_paths.c index 96f32a87b..3f6edef39 100644 --- a/src/cadet/gnunet-service-cadet-new_paths.c +++ b/src/cadet/gnunet-service-cadet-new_paths.c @@ -100,7 +100,7 @@ GCPP_get_desirability (const struct CadetPeerPath *path) * @param path path to traverse * @param destination destination node to get to, must be on path * @param off offset of @a destination on @a path - * @return NULL if @a create is NO and we have no existing connection + * @return NULL if we have no existing connection * otherwise connection from us to @a destination via @a path */ struct CadetConnection * @@ -459,6 +459,22 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity *get_path, } +/** + * We got an incoming connection, obtain the corresponding path. + * + * @param path_length number of segments on the @a path + * @param path through the network, in reverse order (we are at the end!) + * @return corresponding path object + */ +struct CadetPeerPath * +GCPP_get_path_from_route (unsigned int path_length, + const struct GNUNET_PeerIdentity *pids) +{ + GNUNET_assert (0); // FIXME! + return NULL; +} + + /** * Return the length of the path. Excludes one end of the * path, so the loopback path has length 0. diff --git a/src/cadet/gnunet-service-cadet-new_paths.h b/src/cadet/gnunet-service-cadet-new_paths.h index f08d4a705..6a864e8ec 100644 --- a/src/cadet/gnunet-service-cadet-new_paths.h +++ b/src/cadet/gnunet-service-cadet-new_paths.h @@ -49,6 +49,18 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity *get_path, unsigned int put_path_length); +/** + * We got an incoming connection, obtain the corresponding path. + * + * @param path_length number of segments on the @a path + * @param path through the network, in reverse order (we are at the end!) + * @return corresponding path object + */ +struct CadetPeerPath * +GCPP_get_path_from_route (unsigned int path_length, + const struct GNUNET_PeerIdentity *pids); + + /** * Return the length of the path. Excludes one end of the * path, so the loopback path has length 0. @@ -67,7 +79,7 @@ GCPP_get_length (struct CadetPeerPath *path); * @param path path to traverse * @param destination destination node to get to, must be on path * @param off offset of @a destination on @a path - * @return NULL if @a create is NO and we have no existing connection + * @return NULL if we have no existing connection * otherwise connection from us to @a destination via @a path */ struct CadetConnection * diff --git a/src/cadet/gnunet-service-cadet-new_peer.c b/src/cadet/gnunet-service-cadet-new_peer.c index 55a03a206..c57622181 100644 --- a/src/cadet/gnunet-service-cadet-new_peer.c +++ b/src/cadet/gnunet-service-cadet-new_peer.c @@ -264,6 +264,19 @@ destroy_peer (void *cls) } +/** + * Get the message queue for peer @a cp. + * + * @param cp peer to modify + * @return message queue (can be NULL) + */ +struct GNUNET_MQ_Handle * +GCP_get_mq (struct CadetPeer *cp) +{ + return cp->core_mq; +} + + /** * Set the message queue to @a mq for peer @a cp and notify watchers. * diff --git a/src/cadet/gnunet-service-cadet-new_peer.h b/src/cadet/gnunet-service-cadet-new_peer.h index 6b0812cc7..6b4ee1b56 100644 --- a/src/cadet/gnunet-service-cadet-new_peer.h +++ b/src/cadet/gnunet-service-cadet-new_peer.h @@ -312,6 +312,16 @@ GCP_set_mq (struct CadetPeer *cp, struct GNUNET_MQ_Handle *mq); +/** + * Get the message queue for peer @a cp. + * + * @param cp peer to modify + * @return message queue (can be NULL) + */ +struct GNUNET_MQ_Handle * +GCP_get_mq (struct CadetPeer *cp); + + /** * Send the message in @a env to @a cp. * diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.c b/src/cadet/gnunet-service-cadet-new_tunnels.c index d874011aa..67af76109 100644 --- a/src/cadet/gnunet-service-cadet-new_tunnels.c +++ b/src/cadet/gnunet-service-cadet-new_tunnels.c @@ -374,14 +374,14 @@ struct CadetTunnel /** * Channels inside this tunnel. Maps - * `struct GCT_ChannelTunnelNumber` to a `struct CadetChannel`. + * `struct GNUNET_CADET_ChannelTunnelNumber` to a `struct CadetChannel`. */ struct GNUNET_CONTAINER_MultiHashMap32 *channels; /** * Channel ID for the next created channel in this tunnel. */ - struct GCT_ChannelTunnelNumber next_chid; + struct GNUNET_CADET_ChannelTunnelNumber next_chid; /** * Queued messages, to transmit once tunnel gets connected. @@ -1137,14 +1137,14 @@ t_ax_decrypt_and_validate (struct CadetTunnel *t, * @param ch Channel * @return unique number identifying @a ch within @a t */ -struct GCT_ChannelTunnelNumber +struct GNUNET_CADET_ChannelTunnelNumber GCT_add_channel (struct CadetTunnel *t, struct CadetChannel *ch) { - struct GCT_ChannelTunnelNumber ret; + struct GNUNET_CADET_ChannelTunnelNumber ret; uint32_t chid; - chid = ntohl (t->next_chid.channel_in_tunnel); + chid = ntohl (t->next_chid.cn); while (NULL != GNUNET_CONTAINER_multihashmap32_get (t->channels, chid)) @@ -1154,8 +1154,8 @@ GCT_add_channel (struct CadetTunnel *t, chid, ch, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - t->next_chid.channel_in_tunnel = htonl (chid + 1); - ret.channel_in_tunnel = htonl (chid); + t->next_chid.cn = htonl (chid + 1); + ret.cn = htonl (chid); return ret; } @@ -1617,11 +1617,11 @@ GCT_create_tunnel (struct CadetPeer *destination) void GCT_remove_channel (struct CadetTunnel *t, struct CadetChannel *ch, - struct GCT_ChannelTunnelNumber gid) + struct GNUNET_CADET_ChannelTunnelNumber gid) { GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap32_remove (t->channels, - ntohl (gid.channel_in_tunnel), + ntohl (gid.cn), ch)); if (0 == GNUNET_CONTAINER_multihashmap32_size (t->channels)) @@ -1670,6 +1670,41 @@ GCT_change_estate (struct CadetTunnel *t, } +/** + * Add a @a connection to the @a tunnel. + * + * @param t a tunnel + * @param cid connection identifer to use for the connection + * @param path path to use for the connection + */ +void +GCT_add_inbound_connection (struct CadetTunnel *t, + const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, + struct CadetPeerPath *path) +{ + struct CadetConnection *cc; + struct CadetTConnection *ct; + + ct = GNUNET_new (struct CadetTConnection); + ct->created = GNUNET_TIME_absolute_get (); + ct->t = t; + ct->cc = GCC_create_inbound (t->destination, + path, + ct, + cid, + &connection_ready_cb, + t); + /* FIXME: schedule job to kill connection (and path?) if it takes + too long to get ready! (And track performance data on how long + other connections took with the tunnel!) + => Note: to be done within 'connection'-logic! */ + GNUNET_CONTAINER_DLL_insert (t->connection_head, + t->connection_tail, + ct); + t->num_connections++; +} + + /** * Handle KX message. * diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.h b/src/cadet/gnunet-service-cadet-new_tunnels.h index 59a5a1958..82e4b0da6 100644 --- a/src/cadet/gnunet-service-cadet-new_tunnels.h +++ b/src/cadet/gnunet-service-cadet-new_tunnels.h @@ -117,15 +117,6 @@ enum CadetTunnelEState }; -/** - * Number uniquely identifying a channel within a tunnel. - */ -struct GCT_ChannelTunnelNumber -{ - uint32_t channel_in_tunnel GNUNET_PACKED; -}; - - /** * Get the static string for the peer this tunnel is directed. * @@ -148,6 +139,19 @@ struct CadetTunnel * GCT_create_tunnel (struct CadetPeer *destination); +/** + * Add a @a connection to the @a tunnel. + * + * @param t a tunnel + * @param cid connection identifer to use for the connection + * @param path path to use for the connection + */ +void +GCT_add_inbound_connection (struct CadetTunnel *t, + const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, + struct CadetPeerPath *path); + + /** * Return the peer to which this tunnel goes. * @@ -179,7 +183,7 @@ GCT_consider_path (struct CadetTunnel *t, * @param ch Channel * @return unique number identifying @a ch within @a t */ -struct GCT_ChannelTunnelNumber +struct GNUNET_CADET_ChannelTunnelNumber GCT_add_channel (struct CadetTunnel *t, struct CadetChannel *ch); @@ -194,7 +198,7 @@ GCT_add_channel (struct CadetTunnel *t, void GCT_remove_channel (struct CadetTunnel *t, struct CadetChannel *ch, - struct GCT_ChannelTunnelNumber gid); + struct GNUNET_CADET_ChannelTunnelNumber gid); /** diff --git a/src/cadet/gnunet-service-cadet_channel.c b/src/cadet/gnunet-service-cadet_channel.c index 20ed582bd..dee0c37d7 100644 --- a/src/cadet/gnunet-service-cadet_channel.c +++ b/src/cadet/gnunet-service-cadet_channel.c @@ -216,7 +216,7 @@ struct CadetChannel /** * Global channel number ( < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) */ - struct GNUNET_CADET_ChannelNumber gid; + struct GNUNET_CADET_ChannelTunnelNumber gid; /** * Local tunnel number for root (owner) client. @@ -1398,7 +1398,7 @@ GCCH_destroy (struct CadetChannel *ch) * * @return ID used to identify the channel with the remote peer. */ -struct GNUNET_CADET_ChannelNumber +struct GNUNET_CADET_ChannelTunnelNumber GCCH_get_id (const struct CadetChannel *ch) { return ch->gid; @@ -2154,7 +2154,7 @@ GCCH_handle_create (struct CadetTunnel *t, const struct GNUNET_CADET_ChannelOpenMessage *msg) { struct GNUNET_CADET_ClientChannelNumber chid; - struct GNUNET_CADET_ChannelNumber gid; + struct GNUNET_CADET_ChannelTunnelNumber gid; struct CadetChannel *ch; struct CadetClient *c; int new_channel; diff --git a/src/cadet/gnunet-service-cadet_channel.h b/src/cadet/gnunet-service-cadet_channel.h index 9e887362b..1eeebf34b 100644 --- a/src/cadet/gnunet-service-cadet_channel.h +++ b/src/cadet/gnunet-service-cadet_channel.h @@ -69,7 +69,7 @@ GCCH_destroy (struct CadetChannel *ch); * * @return ID used to identify the channel with the remote peer. */ -struct GNUNET_CADET_ChannelNumber +struct GNUNET_CADET_ChannelTunnelNumber GCCH_get_id (const struct CadetChannel *ch); /** diff --git a/src/cadet/gnunet-service-cadet_local.c b/src/cadet/gnunet-service-cadet_local.c index 7ba7077aa..e1f6ac4c3 100644 --- a/src/cadet/gnunet-service-cadet_local.c +++ b/src/cadet/gnunet-service-cadet_local.c @@ -977,7 +977,7 @@ iter_channel (void *cls, struct CadetChannel *ch) { struct GNUNET_CADET_LocalInfoTunnel *msg = cls; struct GNUNET_CADET_ConnectionTunnelIdentifier *h = (struct GNUNET_CADET_ConnectionTunnelIdentifier *) &msg[1]; - struct GNUNET_CADET_ChannelNumber *chn = (struct GNUNET_CADET_ChannelNumber *) &h[msg->connections]; + struct GNUNET_CADET_ChannelTunnelNumber *chn = (struct GNUNET_CADET_ChannelTunnelNumber *) &h[msg->connections]; chn[msg->channels] = GCCH_get_id (ch); msg->channels++; @@ -1045,7 +1045,7 @@ handle_show_tunnel (void *cls, struct GNUNET_SERVER_Client *client, size = sizeof (struct GNUNET_CADET_LocalInfoTunnel); size += c_n * sizeof (struct GNUNET_CADET_ConnectionTunnelIdentifier); - size += ch_n * sizeof (struct GNUNET_CADET_ChannelNumber); + size += ch_n * sizeof (struct GNUNET_CADET_ChannelTunnelNumber); resp = GNUNET_malloc (size); resp->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL); diff --git a/src/cadet/gnunet-service-cadet_tunnel.c b/src/cadet/gnunet-service-cadet_tunnel.c index b2d91c995..65775ce66 100644 --- a/src/cadet/gnunet-service-cadet_tunnel.c +++ b/src/cadet/gnunet-service-cadet_tunnel.c @@ -310,7 +310,7 @@ struct CadetTunnel /** * Channel ID for the next created channel. */ - struct GNUNET_CADET_ChannelNumber next_chid; + struct GNUNET_CADET_ChannelTunnelNumber next_chid; /** * Destroy flag: if true, destroy on last message. @@ -1556,7 +1556,7 @@ destroy_iterator (void *cls, */ static void send_channel_destroy (struct CadetTunnel *t, - struct GNUNET_CADET_ChannelNumber gid) + struct GNUNET_CADET_ChannelTunnelNumber gid) { struct GNUNET_CADET_ChannelManageMessage msg; @@ -2515,7 +2515,7 @@ GCT_remove_channel (struct CadetTunnel *t, struct CadetChannel *ch) */ struct CadetChannel * GCT_get_channel (struct CadetTunnel *t, - struct GNUNET_CADET_ChannelNumber chid) + struct GNUNET_CADET_ChannelTunnelNumber chid) { struct CadetTChannel *iter; @@ -2971,11 +2971,11 @@ GCT_get_destination (struct CadetTunnel *t) * * @return GID of a channel free to use. */ -struct GNUNET_CADET_ChannelNumber +struct GNUNET_CADET_ChannelTunnelNumber GCT_get_next_chid (struct CadetTunnel *t) { - struct GNUNET_CADET_ChannelNumber chid; - struct GNUNET_CADET_ChannelNumber mask; + struct GNUNET_CADET_ChannelTunnelNumber chid; + struct GNUNET_CADET_ChannelTunnelNumber mask; int result; /* Set bit 30 depending on the ID relationship. Bit 31 is always 0 for GID. diff --git a/src/cadet/gnunet-service-cadet_tunnel.h b/src/cadet/gnunet-service-cadet_tunnel.h index 65f54e373..c10815a3b 100644 --- a/src/cadet/gnunet-service-cadet_tunnel.h +++ b/src/cadet/gnunet-service-cadet_tunnel.h @@ -291,7 +291,7 @@ GCT_remove_channel (struct CadetTunnel *t, struct CadetChannel *ch); * @return channel handler, NULL if doesn't exist */ struct CadetChannel * -GCT_get_channel (struct CadetTunnel *t, struct GNUNET_CADET_ChannelNumber chid); +GCT_get_channel (struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber chid); /** @@ -427,7 +427,7 @@ GCT_get_destination (struct CadetTunnel *t); * * @return ID of a channel free to use. */ -struct GNUNET_CADET_ChannelNumber +struct GNUNET_CADET_ChannelTunnelNumber GCT_get_next_chid (struct CadetTunnel *t); diff --git a/src/include/gnunet_cadet_service.h b/src/include/gnunet_cadet_service.h index c17cb983c..7090d4410 100644 --- a/src/include/gnunet_cadet_service.h +++ b/src/include/gnunet_cadet_service.h @@ -412,10 +412,10 @@ typedef void (*GNUNET_CADET_ChannelCB) (void *cls, const struct GNUNET_PeerIdentity *root, const struct GNUNET_PeerIdentity *dest, - uint32_t port, - uint32_t root_channel_number, - uint32_t dest_channel_number, - uint32_t public_channel_number); + uint32_t /* UGH */ port, + uint32_t /* ugh */ root_channel_number, + uint32_t /* ugh */ dest_channel_number, + uint32_t /* ugh */ public_channel_number); /** * Method called to retrieve information about all peers in CADET, called @@ -491,10 +491,14 @@ struct GNUNET_CADET_ConnectionTunnelIdentifier /** - * Number identifying a CADET channel. + * Number identifying a CADET channel within a tunnel. */ -struct GNUNET_CADET_ChannelNumber +struct GNUNET_CADET_ChannelTunnelNumber { + /** + * Which number does this channel have that uniquely identfies + * it within its tunnel? + */ uint32_t cn GNUNET_PACKED; }; @@ -517,7 +521,7 @@ typedef void const struct GNUNET_PeerIdentity *peer, unsigned int n_channels, unsigned int n_connections, - const struct GNUNET_CADET_ChannelNumber *channels, + const struct GNUNET_CADET_ChannelTunnelNumber *channels, const struct GNUNET_CADET_ConnectionTunnelIdentifier *connections, unsigned int estate, unsigned int cstate); @@ -537,7 +541,7 @@ typedef void void GNUNET_CADET_get_channel (struct GNUNET_CADET_Handle *h, struct GNUNET_PeerIdentity *peer, - uint32_t channel_number, + uint32_t /* UGH */ channel_number, GNUNET_CADET_ChannelCB callback, void *callback_cls); -- 2.25.1