/**
* Maximum packet ID authorized.
*/
- struct CadetEncryptedMessageIdentifier cemi;
+ struct CadetEncryptedMessageIdentifier cemi_max;
/**
* ID of the connection.
/**
- * 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;
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
* @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"
/**
* 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.
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;
}
struct GNUNET_CADET_ChannelTunnelNumber
GCCH_get_id (const struct CadetChannel *ch)
{
- return ch->gid;
+ return ch->chid;
}
}
GCT_remove_channel (ch->t,
ch,
- ch->gid);
+ ch->chid);
GNUNET_free (ch);
}
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,
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));
/**
- * 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)
{
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));
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)
return;
}
/* Nothing left to do, just finish destruction */
+ GCT_send_channel_destroy (ch->t,
+ ch->chid);
channel_destroy (ch);
}
return;
}
/* Nothing left to do, just finish destruction */
+ GCT_send_channel_destroy (ch->t,
+ ch->chid);
channel_destroy (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);
return;
if (GNUNET_NO == ch->destroy)
return;
+ GCT_send_channel_destroy (ch->t,
+ ch->chid);
channel_destroy (ch);
}
LOG2 (level,
"CHN Channel %s:%X (%p)\n",
GCT_2s (ch->t),
- ch->gid,
+ ch->chid,
ch);
if (NULL != ch->owner)
{
struct CadetClient *c);
-
/**
* Destroy locally created channel. Called by the
* local client, so no need to tell the client.
/**
- * 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
*/
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);
* @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"
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.
*
* 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"
&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;
}
}
-/**
- * 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
*
msg);
return;
}
-
/* We're just an intermediary peer, route the message along its path */
route_message (peer,
&msg->cid,
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,
-
/*
This file is part of GNUnet.
Copyright (C) 2013, 2017 GNUnet e.V.
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.
* @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"
/**
- * 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;
}
/**
- *
+ * 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
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
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!
}
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,
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.
/* 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,
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),
/*
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
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"