aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-01-18 19:24:33 +0100
committerChristian Grothoff <christian@grothoff.org>2017-01-18 19:24:33 +0100
commitdfde8ea01a08a32340a47df29ffc2571c031488b (patch)
tree81abde784965de4a4d3f32f882a39353cc96a88d /src
parent3edc21c27d208e45dc1af76131a480a3ebf1e8d3 (diff)
create matching connection objects for inbound connections
Diffstat (limited to 'src')
-rw-r--r--src/cadet/cadet_api.c6
-rw-r--r--src/cadet/cadet_protocol.h85
-rw-r--r--src/cadet/gnunet-cadet.c2
-rw-r--r--src/cadet/gnunet-service-cadet-new.c6
-rw-r--r--src/cadet/gnunet-service-cadet-new.h11
-rw-r--r--src/cadet/gnunet-service-cadet-new_channel.c110
-rw-r--r--src/cadet/gnunet-service-cadet-new_channel.h4
-rw-r--r--src/cadet/gnunet-service-cadet-new_connection.c92
-rw-r--r--src/cadet/gnunet-service-cadet-new_connection.h23
-rw-r--r--src/cadet/gnunet-service-cadet-new_core.c174
-rw-r--r--src/cadet/gnunet-service-cadet-new_paths.c18
-rw-r--r--src/cadet/gnunet-service-cadet-new_paths.h14
-rw-r--r--src/cadet/gnunet-service-cadet-new_peer.c13
-rw-r--r--src/cadet/gnunet-service-cadet-new_peer.h10
-rw-r--r--src/cadet/gnunet-service-cadet-new_tunnels.c53
-rw-r--r--src/cadet/gnunet-service-cadet-new_tunnels.h26
-rw-r--r--src/cadet/gnunet-service-cadet_channel.c6
-rw-r--r--src/cadet/gnunet-service-cadet_channel.h2
-rw-r--r--src/cadet/gnunet-service-cadet_local.c4
-rw-r--r--src/cadet/gnunet-service-cadet_tunnel.c12
-rw-r--r--src/cadet/gnunet-service-cadet_tunnel.h4
-rw-r--r--src/include/gnunet_cadet_service.h20
22 files changed, 499 insertions, 196 deletions
diff --git a/src/cadet/cadet_api.c b/src/cadet/cadet_api.c
index 4a662487c6..8f1274d633 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 7e4a6ae16f..cf32e0d6d6 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 72d7bf8a93..80010ec54b 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 3e149e9bbc..2f6cc7b11c 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 3258a6666a..862a0f0884 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.
@@ -113,6 +114,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 32e4c62696..dcbc5614f7 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 5cf42a8949..85302ea0ae 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 440d64fb6b..5123f9d458 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,
@@ -432,6 +432,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 32452024c1..f2364dea46 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"
@@ -74,6 +72,27 @@ 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);
+
+
+/**
* Transmit message @a msg via connection @a cc. Must only be called
* (once) after the connection has signalled that it is ready via the
* `ready_cb`. Clients can also use #GCC_is_ready() to check if the
diff --git a/src/cadet/gnunet-service-cadet-new_core.c b/src/cadet/gnunet-service-cadet-new_core.c
index e9fc6bf05e..3d8406dc9f 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;
+
};
@@ -177,6 +184,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
*
* @param cls Closure (CadetPeer for neighbor that sent the message).
@@ -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 96f32a87b3..3f6edef399 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 *
@@ -460,6 +460,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 f08d4a705f..6a864e8ecf 100644
--- a/src/cadet/gnunet-service-cadet-new_paths.h
+++ b/src/cadet/gnunet-service-cadet-new_paths.h
@@ -50,6 +50,18 @@ 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);
+
+
+/**
* 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 55a03a206e..c57622181e 100644
--- a/src/cadet/gnunet-service-cadet-new_peer.c
+++ b/src/cadet/gnunet-service-cadet-new_peer.c
@@ -265,6 +265,19 @@ destroy_peer (void *cls)
/**
+ * Get the message queue for peer @a cp.
+ *
+ * @param cp p