From 7d96a8234bbd9d9a4dc431c52d92ebb604084c70 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 20 Jan 2017 10:08:07 +0100 Subject: [PATCH] more work on channel/tunnel logic --- src/cadet/cadet_protocol.h | 7 +- src/cadet/gnunet-service-cadet-new_channel.c | 44 ++++---- src/cadet/gnunet-service-cadet-new_channel.h | 7 +- .../gnunet-service-cadet-new_connection.c | 4 +- .../gnunet-service-cadet-new_connection.h | 11 ++ src/cadet/gnunet-service-cadet-new_core.c | 79 +------------- src/cadet/gnunet-service-cadet-new_tunnels.c | 100 ++++++++++++------ src/cadet/gnunet-service-cadet-new_tunnels.h | 11 ++ src/cadet/gnunet-service-cadet_connection.c | 4 +- src/cadet/gnunet-service-cadet_tunnel.c | 11 +- 10 files changed, 136 insertions(+), 142 deletions(-) diff --git a/src/cadet/cadet_protocol.h b/src/cadet/cadet_protocol.h index cf32e0d6d..f85ef17ae 100644 --- a/src/cadet/cadet_protocol.h +++ b/src/cadet/cadet_protocol.h @@ -337,7 +337,7 @@ struct GNUNET_CADET_ConnectionEncryptedAckMessage /** * Maximum packet ID authorized. */ - struct CadetEncryptedMessageIdentifier cemi; + struct CadetEncryptedMessageIdentifier cemi_max; /** * ID of the connection. @@ -379,12 +379,13 @@ struct GNUNET_CADET_ChannelOpenMessage /** - * Message to manage a Channel (ACK, NACK, Destroy). + * Message to manage a Channel (CHANNEL_CREATE_ACK, CHANNEL_DESTROY). */ struct GNUNET_CADET_ChannelManageMessage { /** - * Type: #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_{ACK|NACK|DESTROY} + * Type: #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_CREATE_ACK or + * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY */ struct GNUNET_MessageHeader header; diff --git a/src/cadet/gnunet-service-cadet-new_channel.c b/src/cadet/gnunet-service-cadet-new_channel.c index 5acd098b6..70f16dbe6 100644 --- a/src/cadet/gnunet-service-cadet-new_channel.c +++ b/src/cadet/gnunet-service-cadet-new_channel.c @@ -18,7 +18,6 @@ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * @file cadet/gnunet-service-cadet-new_channel.c * @brief logical links between CADET clients @@ -26,10 +25,11 @@ * @author Christian Grothoff * * TODO: - * - estimate max bandwidth using bursts and use to optimize - * transmission rate(s) + * - estimate max bandwidth using bursts and use to for CONGESTION CONTROL! + * - check that '0xFFULL' really is sufficient for flow control! + * - what about the 'no buffer' option? + * - what about the 'out-of-order' option? */ - #include "platform.h" #include "gnunet_util_lib.h" #include "cadet.h" @@ -259,7 +259,7 @@ struct CadetChannel /** * Number identifying this channel in its tunnel. */ - struct GNUNET_CADET_ChannelTunnelNumber gid; + struct GNUNET_CADET_ChannelTunnelNumber chid; /** * Local tunnel number for local client owning the channel. @@ -324,10 +324,10 @@ GCCH_2s (const struct CadetChannel *ch) return "(NULL Channel)"; GNUNET_snprintf (buf, sizeof (buf), - "%s:%s gid:%X (%X)", + "%s:%s chid:%X (%X)", GCT_2s (ch->t), GNUNET_h2s (&ch->port), - ch->gid, + ch->chid, ntohl (ch->lid.channel_of_client)); return buf; } @@ -343,7 +343,7 @@ GCCH_2s (const struct CadetChannel *ch) struct GNUNET_CADET_ChannelTunnelNumber GCCH_get_id (const struct CadetChannel *ch) { - return ch->gid; + return ch->chid; } @@ -391,7 +391,7 @@ channel_destroy (struct CadetChannel *ch) } GCT_remove_channel (ch->t, ch, - ch->gid); + ch->chid); GNUNET_free (ch); } @@ -447,7 +447,7 @@ send_create (void *cls) msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN); msgcc.opt = htonl (options); msgcc.port = ch->port; - msgcc.chid = ch->gid; + msgcc.chid = ch->chid; ch->state = CADET_CHANNEL_CREATE_SENT; ch->last_control_qe = GCT_send (ch->t, &msgcc.header, @@ -483,8 +483,8 @@ GCCH_channel_local_new (struct CadetClient *owner, ch->port = *port; ch->t = GCP_get_tunnel (destination, GNUNET_YES); - ch->gid = GCT_add_channel (ch->t, - ch); + ch->chid = GCT_add_channel (ch->t, + ch); ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME; ch->nobuffer = (0 != (options & GNUNET_CADET_OPTION_NOBUFFER)); ch->reliable = (0 != (options & GNUNET_CADET_OPTION_RELIABLE)); @@ -516,17 +516,17 @@ timeout_closed_cb (void *cls) /** - * Create a new channel. + * Create a new channel based on a request coming in over the network. * * @param t tunnel to the remote peer - * @param gid identifier of this channel in the tunnel + * @param chid identifier of this channel in the tunnel * @param port desired local port * @param options options for the channel * @return handle to the new channel */ struct CadetChannel * GCCH_channel_incoming_new (struct CadetTunnel *t, - struct GNUNET_CADET_ChannelTunnelNumber gid, + struct GNUNET_CADET_ChannelTunnelNumber chid, const struct GNUNET_HashCode *port, uint32_t options) { @@ -538,7 +538,7 @@ GCCH_channel_incoming_new (struct CadetTunnel *t, or adjust dynamically... */ ch->port = *port; ch->t = t; - ch->gid = gid; + ch->chid = chid; ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME; ch->nobuffer = (0 != (options & GNUNET_CADET_OPTION_NOBUFFER)); ch->reliable = (0 != (options & GNUNET_CADET_OPTION_RELIABLE)); @@ -602,7 +602,7 @@ send_channel_ack (struct CadetChannel *ch) msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK); msg.header.size = htons (sizeof (msg)); - msg.gid = ch->gid; + msg.gid = ch->chid; msg.mid.mid = htonl (ntohl (ch->mid_recv.mid) - 1); msg.futures = GNUNET_htonll (ch->mid_futures); if (NULL != ch->last_control_qe) @@ -694,6 +694,8 @@ GCCH_channel_local_destroy (struct CadetChannel *ch) return; } /* Nothing left to do, just finish destruction */ + GCT_send_channel_destroy (ch->t, + ch->chid); channel_destroy (ch); } @@ -721,6 +723,8 @@ GCCH_channel_incoming_destroy (struct CadetChannel *ch) return; } /* Nothing left to do, just finish destruction */ + GCT_send_channel_destroy (ch->t, + ch->chid); channel_destroy (ch); } @@ -930,7 +934,7 @@ GCCH_handle_local_data (struct CadetChannel *ch, crm->data_message.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA); ch->mid_send.mid = htonl (ntohl (ch->mid_send.mid) + 1); crm->data_message.mid = ch->mid_send; - crm->data_message.gid = ch->gid; + crm->data_message.gid = ch->chid; GNUNET_memcpy (&crm[1], message, payload_size); @@ -1001,6 +1005,8 @@ send_client_buffered_data (struct CadetChannel *ch) return; if (GNUNET_NO == ch->destroy) return; + GCT_send_channel_destroy (ch->t, + ch->chid); channel_destroy (ch); } @@ -1047,7 +1053,7 @@ GCCH_debug (struct CadetChannel *ch, LOG2 (level, "CHN Channel %s:%X (%p)\n", GCT_2s (ch->t), - ch->gid, + ch->chid, ch); if (NULL != ch->owner) { diff --git a/src/cadet/gnunet-service-cadet-new_channel.h b/src/cadet/gnunet-service-cadet-new_channel.h index 8caa254d1..0d56d8ae0 100644 --- a/src/cadet/gnunet-service-cadet-new_channel.h +++ b/src/cadet/gnunet-service-cadet-new_channel.h @@ -107,7 +107,6 @@ GCCH_bind (struct CadetChannel *ch, struct CadetClient *c); - /** * Destroy locally created channel. Called by the * local client, so no need to tell the client. @@ -119,10 +118,10 @@ GCCH_channel_local_destroy (struct CadetChannel *ch); /** - * Create a new channel. + * Create a new channel based on a request coming in over the network. * * @param t tunnel to the remote peer - * @param gid identifier of this channel in the tunnel + * @param chid identifier of this channel in the tunnel * @param origin peer to who initiated the channel * @param port desired local port * @param options options for the channel @@ -130,7 +129,7 @@ GCCH_channel_local_destroy (struct CadetChannel *ch); */ struct CadetChannel * GCCH_channel_incoming_new (struct CadetTunnel *t, - struct GNUNET_CADET_ChannelTunnelNumber gid, + struct GNUNET_CADET_ChannelTunnelNumber chid, 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 bf88d78e1..5eb6335a2 100644 --- a/src/cadet/gnunet-service-cadet-new_connection.c +++ b/src/cadet/gnunet-service-cadet-new_connection.c @@ -27,8 +27,8 @@ * @author Christian Grothoff * * TODO: - * - keepalive messages - * - keep performance metrics (?) + * - Optimization: keepalive messages / timeout (timeout to be done @ peer level!) + * - Optimization: keep performance metrics (?) */ #include "platform.h" #include "gnunet-service-cadet-new_channel.h" diff --git a/src/cadet/gnunet-service-cadet-new_connection.h b/src/cadet/gnunet-service-cadet-new_connection.h index 99426776d..31a2e80bb 100644 --- a/src/cadet/gnunet-service-cadet-new_connection.h +++ b/src/cadet/gnunet-service-cadet-new_connection.h @@ -121,6 +121,17 @@ void GCC_handle_connection_ack (struct CadetConnection *cc); +/** + * We got a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE for a + * connection that we already have. Either our ACK got lost + * or something is fishy. Consider retransmitting the ACK. + * + * @param cc connection that got the duplicate CREATE + */ +void +GCC_handle_duplicate_create (struct CadetConnection *cc); + + /** * Handle KX message. * diff --git a/src/cadet/gnunet-service-cadet-new_core.c b/src/cadet/gnunet-service-cadet-new_core.c index 9ce4418de..a5d114b34 100644 --- a/src/cadet/gnunet-service-cadet-new_core.c +++ b/src/cadet/gnunet-service-cadet-new_core.c @@ -27,10 +27,7 @@ * All functions in this file should use the prefix GCO (Gnunet Cadet cOre (bottom)) * * TODO: - * - pass encrypted ACK to connection (!) - * - given BROKEN messages, destroy paths (?) - * - - * - handle POLL (if needed) + * - Optimization: given BROKEN messages, destroy paths (?) */ #include "platform.h" #include "gnunet-service-cadet-new_core.h" @@ -422,8 +419,7 @@ handle_connection_create (void *cls, &msg->cid.connection_of_tunnel); if (NULL != cc) { - /* Duplicate CREATE, likely our ACK got lost, retransmit the ACK! */ - GNUNET_break (0); // FIXME: not implemented! + GCC_handle_duplicate_create (cc); return; } @@ -603,68 +599,6 @@ handle_connection_destroy (void *cls, } -/** - * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_HOP_BY_HOP_ENCRYPTED_ACK. - * - * @param cls Closure (CadetPeer for neighbor that sent the message). - * @param msg Message itself. - */ -static void -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_ack (peer, - msg); -#endif - return; - } - - /* We're just an intermediary peer, route the message along its path */ - route_message (peer, - &msg->cid, - &msg->header); -} - - -/** - * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED_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_ConnectionHopByHopPollMessage *msg) -{ - struct CadetPeer *peer = cls; - -#if FIXME - GCC_handle_poll (peer, - msg); -#endif -} - - /** * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX * @@ -755,7 +689,6 @@ handle_tunnel_encrypted (void *cls, msg); return; } - /* We're just an intermediary peer, route the message along its path */ route_message (peer, &msg->cid, @@ -855,14 +788,6 @@ GCO_init (const struct GNUNET_CONFIGURATION_Handle *c) GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY, struct GNUNET_CADET_ConnectionDestroyMessage, NULL), - GNUNET_MQ_hd_fixed_size (hop_by_hop_encrypted_ack, - GNUNET_MESSAGE_TYPE_CADET_CONNECTION_HOP_BY_HOP_ENCRYPTED_ACK, - struct GNUNET_CADET_ConnectionEncryptedAckMessage, - NULL), - GNUNET_MQ_hd_fixed_size (poll, - GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED_POLL, - struct GNUNET_CADET_ConnectionHopByHopPollMessage, - NULL), GNUNET_MQ_hd_fixed_size (tunnel_kx, GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX, struct GNUNET_CADET_TunnelKeyExchangeMessage, diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.c b/src/cadet/gnunet-service-cadet-new_tunnels.c index 23b270b82..6873fb396 100644 --- a/src/cadet/gnunet-service-cadet-new_tunnels.c +++ b/src/cadet/gnunet-service-cadet-new_tunnels.c @@ -1,4 +1,3 @@ - /* This file is part of GNUnet. Copyright (C) 2013, 2017 GNUnet e.V. @@ -18,7 +17,6 @@ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * @file cadet/gnunet-service-cadet-new_tunnels.c * @brief Information we track per tunnel. @@ -26,12 +24,12 @@ * @author Christian Grothoff * * FIXME: + * - clean up KX logic! + * - implement sending and receiving KX messages + * - implement processing of incoming decrypted plaintext messages * - when managing connections, distinguish those that * have (recently) had traffic from those that were * never ready (or not recently) - * - implement sending and receiving KX messages - * - implement processing of incoming decrypted plaintext messages - * - clean up KX logic! */ #include "platform.h" #include "gnunet_util_lib.h" @@ -1306,32 +1304,52 @@ GCT_handle_kx (struct CadetTConnection *ct, /** - * Add a channel to a tunnel. + * Compute the next free channel tunnel number for this tunnel. * - * @param t Tunnel. - * @param ch Channel - * @return unique number identifying @a ch within @a t + * @param t the tunnel + * @return unused number that can uniquely identify a channel in the tunnel */ -struct GNUNET_CADET_ChannelTunnelNumber -GCT_add_channel (struct CadetTunnel *t, - struct CadetChannel *ch) +static struct GNUNET_CADET_ChannelTunnelNumber +get_next_free_chid (struct CadetTunnel *t) { struct GNUNET_CADET_ChannelTunnelNumber ret; uint32_t chid; + /* FIXME: this logic does NOT prevent both ends of the + channel from picking the same CHID! + Need to reserve one bit of the CHID for the + direction, i.e. which side established the connection! */ chid = ntohl (t->next_chid.cn); while (NULL != GNUNET_CONTAINER_multihashmap32_get (t->channels, chid)) chid++; + t->next_chid.cn = htonl (chid + 1); + ret.cn = ntohl (chid); + return ret; +} + + +/** + * Add a channel to a tunnel. + * + * @param t Tunnel. + * @param ch Channel + * @return unique number identifying @a ch within @a t + */ +struct GNUNET_CADET_ChannelTunnelNumber +GCT_add_channel (struct CadetTunnel *t, + struct CadetChannel *ch) +{ + struct GNUNET_CADET_ChannelTunnelNumber chid; + + chid = get_next_free_chid (t); GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap32_put (t->channels, - chid, + ntohl (chid.cn), ch, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - t->next_chid.cn = htonl (chid + 1); - ret.cn = htonl (chid); - return ret; + return chid; } @@ -1638,7 +1656,8 @@ handle_plaintext_data_ack (void *cls, /** - * + * We have received a request to open a channel to a port from + * another peer. Creates the incoming channel. * * @param cls the `struct CadetTunnel` for which we decrypted the message * @param cc the message we received on the tunnel @@ -1648,27 +1667,40 @@ handle_plaintext_channel_create (void *cls, const struct GNUNET_CADET_ChannelOpenMessage *cc) { struct CadetTunnel *t = cls; - GNUNET_break (0); // FIXME! + struct CadetChannel *ch; + struct GNUNET_CADET_ChannelTunnelNumber chid; + + chid = get_next_free_chid (t); + ch = GCCH_channel_incoming_new (t, + chid, + &cc->port, + ntohl (cc->opt)); + GNUNET_assert (GNUNET_OK == + GNUNET_CONTAINER_multihashmap32_put (t->channels, + ntohl (chid.cn), + ch, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); } /** + * Send a DESTROY message via the tunnel. * - * - * @param cls the `struct CadetTunnel` for which we decrypted the message - * @param cm the message we received on the tunnel + * @param t the tunnel to transmit over + * @param chid ID of the channel to destroy */ -static void -handle_plaintext_channel_nack (void *cls, - const struct GNUNET_CADET_ChannelManageMessage *cm) +void +GCT_send_channel_destroy (struct CadetTunnel *t, + struct GNUNET_CADET_ChannelTunnelNumber chid) { - struct CadetTunnel *t = cls; GNUNET_break (0); // FIXME! } /** - * + * We have received confirmation from the target peer that the + * given channel could be established (the port is open). + * Tell the client. * * @param cls the `struct CadetTunnel` for which we decrypted the message * @param cm the message we received on the tunnel @@ -1678,6 +1710,18 @@ handle_plaintext_channel_ack (void *cls, const struct GNUNET_CADET_ChannelManageMessage *cm) { struct CadetTunnel *t = cls; + struct CadetChannel *ch; + + ch = lookup_channel (t, + cm->chid); + if (NULL == ch) + { + /* We don't know about such a channel, might have been destroyed on our + end in the meantime, or never existed. Send back a DESTROY. */ + GCT_send_channel_destroy (t, + cm->chid); + return; + } GNUNET_break (0); // FIXME! } @@ -1763,10 +1807,6 @@ GCT_create_tunnel (struct CadetPeer *destination) GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN, struct GNUNET_CADET_ChannelOpenMessage, NULL), - GNUNET_MQ_hd_fixed_size (plaintext_channel_nack, - GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED, - struct GNUNET_CADET_ChannelManageMessage, - NULL), GNUNET_MQ_hd_fixed_size (plaintext_channel_ack, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK, struct GNUNET_CADET_ChannelManageMessage, diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.h b/src/cadet/gnunet-service-cadet-new_tunnels.h index 82e4b0da6..cd96a50bc 100644 --- a/src/cadet/gnunet-service-cadet-new_tunnels.h +++ b/src/cadet/gnunet-service-cadet-new_tunnels.h @@ -201,6 +201,17 @@ GCT_remove_channel (struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber gid); +/** + * Send a DESTROY message via the tunnel. + * + * @param t the tunnel to transmit over + * @param chid ID of the channel to destroy + */ +void +GCT_send_channel_destroy (struct CadetTunnel *t, + struct GNUNET_CADET_ChannelTunnelNumber chid); + + /** * Sends an already built message on a tunnel, encrypting it and * choosing the best connection if not provided. diff --git a/src/cadet/gnunet-service-cadet_connection.c b/src/cadet/gnunet-service-cadet_connection.c index 931b32b95..c4802abde 100644 --- a/src/cadet/gnunet-service-cadet_connection.c +++ b/src/cadet/gnunet-service-cadet_connection.c @@ -617,7 +617,7 @@ send_ack (struct CadetConnection *c, /* Build ACK message and send on conn */ msg.header.size = htons (sizeof (msg)); msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_HOP_BY_HOP_ENCRYPTED_ACK); - msg.cemi = ack_cemi; + msg.cemi_max = ack_cemi; msg.cid = c->id; prev_fc->ack_msg = GCC_send_prebuilt_message (&msg.header, @@ -2373,7 +2373,7 @@ GCC_handle_ack (struct CadetPeer *peer, return; } - ack = msg->cemi; + ack = msg->cemi_max; LOG (GNUNET_ERROR_TYPE_DEBUG, " %s ACK %u (was %u)\n", GC_f2s (fwd), ntohl (ack.pid), diff --git a/src/cadet/gnunet-service-cadet_tunnel.c b/src/cadet/gnunet-service-cadet_tunnel.c index 65775ce66..31c9b9e1c 100644 --- a/src/cadet/gnunet-service-cadet_tunnel.c +++ b/src/cadet/gnunet-service-cadet_tunnel.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2013 GNUnet e.V. + Copyright (C) 2013, 2017 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -17,16 +17,17 @@ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - +/** + * @file cadet/gnunet-service-cadet_tunnel.c + * @brief logical links between CADET clients + * @author Bartlomiej Polot + */ #include "platform.h" #include "gnunet_util_lib.h" - #include "gnunet_signatures.h" #include "gnunet_statistics_service.h" - #include "cadet_protocol.h" #include "cadet_path.h" - #include "gnunet-service-cadet_tunnel.h" #include "gnunet-service-cadet_connection.h" #include "gnunet-service-cadet_channel.h" -- 2.25.1