summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authort3sserakt <t3ss@posteo.de>2020-06-05 16:37:10 +0200
committert3sserakt <t3ss@posteo.de>2020-06-05 16:37:10 +0200
commitd22eacb13eb676b5c096b47c72a3fdbdb332d5a5 (patch)
tree9be948a80a6be2c56080be8826cba747de9dce57
parent59f616a3c5d8a6873de0090d0db1413c8b9c411d (diff)
Fixed bug #5822 by adding a monotonic time to the connection create message of a peer that want to start a KX, and the corresponding test #5823. Credits to dvn, lurchi and xrs for helpful discussions and coding.
-rw-r--r--src/cadet/Makefile.am5
-rw-r--r--src/cadet/cadet.h87
-rw-r--r--src/cadet/cadet_api.c66
-rw-r--r--src/cadet/cadet_protocol.h18
-rw-r--r--src/cadet/gnunet-service-cadet.c112
-rw-r--r--src/cadet/gnunet-service-cadet.h1
-rw-r--r--src/cadet/gnunet-service-cadet_channel.c46
-rw-r--r--src/cadet/gnunet-service-cadet_channel.h17
-rw-r--r--src/cadet/gnunet-service-cadet_connection.c47
-rw-r--r--src/cadet/gnunet-service-cadet_connection.h22
-rw-r--r--src/cadet/gnunet-service-cadet_core.c15
-rw-r--r--src/cadet/gnunet-service-cadet_peer.c63
-rw-r--r--src/cadet/gnunet-service-cadet_peer.h9
-rw-r--r--src/cadet/gnunet-service-cadet_tunnels.c43
-rw-r--r--src/cadet/gnunet-service-cadet_tunnels.h21
-rw-r--r--src/cadet/test_cadet.c365
-rw-r--r--src/cadet/test_cadet.conf7
-rw-r--r--src/include/gnunet_protocols.h10
-rw-r--r--src/include/gnunet_signatures.h4
19 files changed, 780 insertions, 178 deletions
diff --git a/src/cadet/Makefile.am b/src/cadet/Makefile.am
index d8d81bf20..2289a2d96 100644
--- a/src/cadet/Makefile.am
+++ b/src/cadet/Makefile.am
@@ -30,6 +30,7 @@ lib_LTLIBRARIES = \
libgnunetcadet_la_SOURCES = \
cadet_api.c \
+ cadet_api_drop_message.c \
cadet_api_get_channel.c \
cadet_api_get_path.c \
cadet_api_list_peers.c \
@@ -95,6 +96,7 @@ check_PROGRAMS = \
test_cadet_2_speed_reliable \
test_cadet_2_speed_reliable_backwards \
test_cadet_2_reopen \
+ test_cadet_2_destroy \
test_cadet_5_forward \
test_cadet_5_signal \
test_cadet_5_keepalive \
@@ -211,6 +213,9 @@ test_cadet_5_reopen_SOURCES = \
test_cadet.c
test_cadet_5_reopen_LDADD = $(ld_cadet_test_lib)
+test_cadet_2_destroy_SOURCES = \
+ test_cadet.c
+test_cadet_2_destroy_LDADD = $(ld_cadet_test_lib)
if ENABLE_TEST_RUN
AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
diff --git a/src/cadet/cadet.h b/src/cadet/cadet.h
index 29400e39f..d17eab1d6 100644
--- a/src/cadet/cadet.h
+++ b/src/cadet/cadet.h
@@ -95,7 +95,6 @@ extern "C" {
GNUNET_NETWORK_STRUCT_BEGIN
-
/**
* Number uniquely identifying a channel of a client.
*/
@@ -111,6 +110,70 @@ struct GNUNET_CADET_ClientChannelNumber
uint32_t channel_of_client GNUNET_PACKED;
};
+/**
+ * Opaque handle to a channel.
+ */
+struct GNUNET_CADET_Channel
+{
+
+ /**
+ * Other end of the channel.
+ */
+ struct GNUNET_PeerIdentity peer;
+
+ /**
+ * Handle to the cadet this channel belongs to
+ */
+ struct GNUNET_CADET_Handle *cadet;
+
+ /**
+ * Channel's port, if incoming.
+ */
+ struct GNUNET_CADET_Port *incoming_port;
+
+ /**
+ * Any data the caller wants to put in here, used for the
+ * various callbacks (@e disconnects, @e window_changes, handlers).
+ */
+ void *ctx;
+
+ /**
+ * Message Queue for the channel (which we are implementing).
+ */
+ struct GNUNET_MQ_Handle *mq;
+
+ /**
+ * Task to allow mq to send more traffic.
+ */
+ struct GNUNET_SCHEDULER_Task *mq_cont;
+
+ /**
+ * Pending envelope with a message to be transmitted to the
+ * service as soon as we are allowed to. Should only be
+ * non-NULL if @e allow_send is 0.
+ */
+ struct GNUNET_MQ_Envelope *pending_env;
+
+ /**
+ * Window change handler.
+ */
+ GNUNET_CADET_WindowSizeEventHandler window_changes;
+
+ /**
+ * Disconnect handler.
+ */
+ GNUNET_CADET_DisconnectEventHandler disconnects;
+
+ /**
+ * Local ID of the channel, #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI bit is set if outbound.
+ */
+ struct GNUNET_CADET_ClientChannelNumber ccn;
+
+ /**
+ * How many messages are we allowed to send to the service right now?
+ */
+ unsigned int allow_send;
+};
/**
* Message for a client to create and destroy channels.
@@ -252,7 +315,29 @@ struct GNUNET_CADET_LocalInfo
struct GNUNET_PeerIdentity peer;
};
+/**
+ * Message to drop another message of specific type. Used in test context
+ */
+struct GNUNET_CADET_RequestDropCadetMessage
+{
+ /**
+ * Type: #GNUNET_MESSAGE_TYPE_CADET_DROP_CADET_MESSAGE
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Type of the message this handler covers, in host byte order.
+ */
+ uint16_t type;
+
+ /**
+ * ID of the channel we want to drop a message for.
+ */
+ struct GNUNET_CADET_ClientChannelNumber ccn;
+
+};
+
/**
* Message to inform the client about channels in the service.
*/
diff --git a/src/cadet/cadet_api.c b/src/cadet/cadet_api.c
index 3a75266b7..45cb66c1d 100644
--- a/src/cadet/cadet_api.c
+++ b/src/cadet/cadet_api.c
@@ -73,72 +73,6 @@ struct GNUNET_CADET_Handle
struct GNUNET_TIME_Relative reconnect_time;
};
-
-/**
- * Opaque handle to a channel.
- */
-struct GNUNET_CADET_Channel
-{
- /**
- * Other end of the channel.
- */
- struct GNUNET_PeerIdentity peer;
-
- /**
- * Handle to the cadet this channel belongs to
- */
- struct GNUNET_CADET_Handle *cadet;
-
- /**
- * Channel's port, if incoming.
- */
- struct GNUNET_CADET_Port *incoming_port;
-
- /**
- * Any data the caller wants to put in here, used for the
- * various callbacks (@e disconnects, @e window_changes, handlers).
- */
- void *ctx;
-
- /**
- * Message Queue for the channel (which we are implementing).
- */
- struct GNUNET_MQ_Handle *mq;
-
- /**
- * Task to allow mq to send more traffic.
- */
- struct GNUNET_SCHEDULER_Task *mq_cont;
-
- /**
- * Pending envelope with a message to be transmitted to the
- * service as soon as we are allowed to. Should only be
- * non-NULL if @e allow_send is 0.
- */
- struct GNUNET_MQ_Envelope *pending_env;
-
- /**
- * Window change handler.
- */
- GNUNET_CADET_WindowSizeEventHandler window_changes;
-
- /**
- * Disconnect handler.
- */
- GNUNET_CADET_DisconnectEventHandler disconnects;
-
- /**
- * Local ID of the channel, #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI bit is set if outbound.
- */
- struct GNUNET_CADET_ClientChannelNumber ccn;
-
- /**
- * How many messages are we allowed to send to the service right now?
- */
- unsigned int allow_send;
-};
-
-
/**
* Opaque handle to a port.
*/
diff --git a/src/cadet/cadet_protocol.h b/src/cadet/cadet_protocol.h
index e3417f8c4..08298e224 100644
--- a/src/cadet/cadet_protocol.h
+++ b/src/cadet/cadet_protocol.h
@@ -85,6 +85,24 @@ struct GNUNET_CADET_ConnectionCreateMessage
uint32_t options GNUNET_PACKED;
/**
+ * This flag indicates the peer sending the connection create
+ * meassage likes to trigger a KX handshake.
+ */
+ int has_monotime;
+
+ /**
+ * This monotonic time is set, if a peer likes to trigger a KX, but is not
+ * the peer that should start the KX. (xrs,t3ss)
+ */
+ struct GNUNET_TIME_AbsoluteNBO monotime;
+
+ /**
+ * We sign the monotime. The receiving peer can check the signature, to verify
+ * the sending peer.
+ */
+ struct GNUNET_CRYPTO_EddsaSignature monotime_sig;
+
+ /**
* ID of the connection
*/
struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
diff --git a/src/cadet/gnunet-service-cadet.c b/src/cadet/gnunet-service-cadet.c
index ba83fe0fc..03af3d5c0 100644
--- a/src/cadet/gnunet-service-cadet.c
+++ b/src/cadet/gnunet-service-cadet.c
@@ -580,6 +580,7 @@ handle_channel_create (void *cls,
if (ntohl (tcm->ccn.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
{
/* Channel ID not in allowed range. */
+ LOG (GNUNET_ERROR_TYPE_DEBUG,"Channel ID not in allowed range.");
GNUNET_break (0);
GNUNET_SERVICE_client_drop (c->client);
return;
@@ -589,6 +590,7 @@ handle_channel_create (void *cls,
if (NULL != ch)
{
/* Channel ID already in use. Not allowed. */
+ LOG (GNUNET_ERROR_TYPE_DEBUG,"Channel ID already in use. Not allowed.");
GNUNET_break (0);
GNUNET_SERVICE_client_drop (c->client);
return;
@@ -1008,6 +1010,26 @@ handle_info_tunnels (void *cls,
GNUNET_SERVICE_client_continue (c->client);
}
+/**
+ * Handler for client's #GNUNET_MESSAGE_TYPE_CADET_DROP_CADET_MESSAGE request.
+ *
+ * @param cls client Identification of the client.
+ * @param message The actual message.
+ */
+static void
+handle_drop_message (void *cls,
+ const struct GNUNET_CADET_RequestDropCadetMessage *message)
+{
+ struct CadetClient *c = cls;
+ struct CadetChannel *ch;
+
+ ch = lookup_channel (c,
+ message->ccn);
+
+ GCCH_assign_type_to_drop(ch, message);
+
+ GNUNET_SERVICE_client_continue (c->client);
+}
/**
* Callback called when a client connects to the service.
@@ -1305,48 +1327,52 @@ run (void *cls,
* Define "main" method using service macro.
*/
GNUNET_SERVICE_MAIN
- ("cadet",
- GNUNET_SERVICE_OPTION_NONE,
- &run,
- &client_connect_cb,
- &client_disconnect_cb,
- NULL,
- GNUNET_MQ_hd_fixed_size (port_open,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN,
- struct GNUNET_CADET_PortMessage,
- NULL),
- GNUNET_MQ_hd_fixed_size (port_close,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE,
- struct GNUNET_CADET_PortMessage,
- NULL),
- GNUNET_MQ_hd_fixed_size (channel_create,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE,
- struct GNUNET_CADET_LocalChannelCreateMessage,
- NULL),
- GNUNET_MQ_hd_fixed_size (channel_destroy,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY,
- struct GNUNET_CADET_LocalChannelDestroyMessage,
- NULL),
- GNUNET_MQ_hd_var_size (local_data,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA,
- struct GNUNET_CADET_LocalData,
- NULL),
- GNUNET_MQ_hd_fixed_size (local_ack,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK,
- struct GNUNET_CADET_LocalAck,
- NULL),
- GNUNET_MQ_hd_fixed_size (get_peers,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PEERS,
- struct GNUNET_MessageHeader,
- NULL),
- GNUNET_MQ_hd_fixed_size (show_path,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PATH,
- struct GNUNET_CADET_RequestPathInfoMessage,
- NULL),
- GNUNET_MQ_hd_fixed_size (info_tunnels,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_TUNNELS,
- struct GNUNET_MessageHeader,
- NULL),
- GNUNET_MQ_handler_end ());
+("cadet",
+ GNUNET_SERVICE_OPTION_NONE,
+ &run,
+ &client_connect_cb,
+ &client_disconnect_cb,
+ NULL,
+ GNUNET_MQ_hd_fixed_size (port_open,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN,
+ struct GNUNET_CADET_PortMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (port_close,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE,
+ struct GNUNET_CADET_PortMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (channel_create,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE,
+ struct GNUNET_CADET_LocalChannelCreateMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (channel_destroy,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY,
+ struct GNUNET_CADET_LocalChannelDestroyMessage,
+ NULL),
+ GNUNET_MQ_hd_var_size (local_data,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA,
+ struct GNUNET_CADET_LocalData,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (local_ack,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK,
+ struct GNUNET_CADET_LocalAck,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (get_peers,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PEERS,
+ struct GNUNET_MessageHeader,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (show_path,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PATH,
+ struct GNUNET_CADET_RequestPathInfoMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (info_tunnels,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_TUNNELS,
+ struct GNUNET_MessageHeader,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (drop_message,
+ GNUNET_MESSAGE_TYPE_CADET_DROP_CADET_MESSAGE,
+ struct GNUNET_CADET_RequestDropCadetMessage,
+ NULL),
+ GNUNET_MQ_handler_end ());
/* end of gnunet-service-cadet-new.c */
diff --git a/src/cadet/gnunet-service-cadet.h b/src/cadet/gnunet-service-cadet.h
index 6da0950f1..ff216f8c3 100644
--- a/src/cadet/gnunet-service-cadet.h
+++ b/src/cadet/gnunet-service-cadet.h
@@ -325,4 +325,5 @@ const char *
GSC_2s (struct CadetClient *c);
+
#endif
diff --git a/src/cadet/gnunet-service-cadet_channel.c b/src/cadet/gnunet-service-cadet_channel.c
index 5c8103c5e..e6fce562f 100644
--- a/src/cadet/gnunet-service-cadet_channel.c
+++ b/src/cadet/gnunet-service-cadet_channel.c
@@ -380,8 +380,44 @@ struct CadetChannel
* empty.
*/
int destroy;
+
+ /**
+ * Type of message to be droped. See GCT_send.
+ */
+ uint16_t type GNUNET_PACKED;
+
};
+/**
+ * Assign type of message to drop.
+ * @param ch CadetChannel to assign type to drop.
+ * @param message GNUNET_CADET_RequestDropCadetMessage to get the type from.
+ */
+void
+GCCH_assign_type_to_drop(struct CadetChannel *ch, const struct GNUNET_CADET_RequestDropCadetMessage *message)
+{
+
+ ch->type = message->type;
+
+}
+
+/**
+ * Check if type of message is the one to drop.
+ * @param ch CadetChannel to check for message type to drop.
+ * @param message GNUNET_MessageHeader to compare the type with.
+ */
+int
+GCCH_is_type_to_drop(struct CadetChannel *ch, const struct GNUNET_MessageHeader *message)
+{
+
+ if (ch->type == message->type)
+ {
+ ch->type = 0;
+ return GNUNET_YES;
+ }
+ else
+ return GNUNET_NO;
+}
/**
* Get the static string for identification of the channel.
@@ -594,7 +630,7 @@ send_channel_open (void *cls)
if (NULL != ch->last_control_qe)
GCT_send_cancel (ch->last_control_qe);
ch->last_control_qe =
- GCT_send (ch->t, &msgcc.header, &channel_open_sent_cb, ch);
+ GCT_send (ch->t, &msgcc.header, &channel_open_sent_cb, ch, &msgcc.ctn);
GNUNET_assert (NULL == ch->retry_control_task);
}
@@ -818,7 +854,7 @@ send_channel_data_ack (struct CadetChannel *ch)
GCCH_2s (ch));
if (NULL != ch->last_control_qe)
GCT_send_cancel (ch->last_control_qe);
- ch->last_control_qe = GCT_send (ch->t, &msg.header, &send_ack_cb, ch);
+ ch->last_control_qe = GCT_send (ch->t, &msg.header, &send_ack_cb, ch, &msg.ctn);
}
@@ -845,7 +881,7 @@ send_open_ack (void *cls)
msg.port = ch->port;
if (NULL != ch->last_control_qe)
GCT_send_cancel (ch->last_control_qe);
- ch->last_control_qe = GCT_send (ch->t, &msg.header, &send_ack_cb, ch);
+ ch->last_control_qe = GCT_send (ch->t, &msg.header, &send_ack_cb, ch, &msg.ctn);
}
@@ -1477,7 +1513,7 @@ retry_transmission (void *cls)
"Retrying transmission on %s of message %u\n",
GCCH_2s (ch),
(unsigned int) ntohl (crm->data_message->mid.mid));
- crm->qe = GCT_send (ch->t, &crm->data_message->header, &data_sent_cb, crm);
+ crm->qe = GCT_send (ch->t, &crm->data_message->header, &data_sent_cb, crm, &crm->data_message->ctn);
GNUNET_assert (NULL == ch->retry_data_task);
}
@@ -1865,7 +1901,7 @@ GCCH_handle_local_data (struct CadetChannel *ch,
GNUNET_SCHEDULER_cancel (ch->retry_data_task);
ch->retry_data_task = NULL;
}
- crm->qe = GCT_send (ch->t, &crm->data_message->header, &data_sent_cb, crm);
+ crm->qe = GCT_send (ch->t, &crm->data_message->header, &data_sent_cb, crm, &crm->data_message->ctn);
GNUNET_assert (NULL == ch->retry_data_task);
return GNUNET_OK;
}
diff --git a/src/cadet/gnunet-service-cadet_channel.h b/src/cadet/gnunet-service-cadet_channel.h
index 0a6c97329..7a072f128 100644
--- a/src/cadet/gnunet-service-cadet_channel.h
+++ b/src/cadet/gnunet-service-cadet_channel.h
@@ -57,6 +57,23 @@ GCCH_hash_port (struct GNUNET_HashCode *h_port,
const struct GNUNET_HashCode *port,
const struct GNUNET_PeerIdentity *listener);
+/**
+ * Check if type of message is the one to drop.
+ * @param ch CadetChannel to check for message type to drop.
+ * @param message GNUNET_MessageHeader to compare the type with.
+ */
+int
+GCCH_is_type_to_drop (struct CadetChannel *ch, const struct
+ GNUNET_MessageHeader *message);
+
+/**
+ * Check if type of message is the one to drop.
+ * @param ch CadetChannel to assign type to drop.
+ * @param message GNUNET_CADET_RequestDropCadetMessage to get the type from.
+ */
+void
+GCCH_assign_type_to_drop (struct CadetChannel *ch, const struct
+ GNUNET_CADET_RequestDropCadetMessage *message);
/**
* Get the static string for identification of the channel.
diff --git a/src/cadet/gnunet-service-cadet_connection.c b/src/cadet/gnunet-service-cadet_connection.c
index c07339ebc..1dac9eb1e 100644
--- a/src/cadet/gnunet-service-cadet_connection.c
+++ b/src/cadet/gnunet-service-cadet_connection.c
@@ -26,6 +26,7 @@
* @author Christian Grothoff
*/
#include "platform.h"
+#include "gnunet_signatures.h"
#include "gnunet-service-cadet_connection.h"
#include "gnunet-service-cadet_channel.h"
#include "gnunet-service-cadet_paths.h"
@@ -78,7 +79,6 @@ enum CadetConnectionState
CADET_CONNECTION_READY
};
-
/**
* Low-level connection to a destination.
*/
@@ -206,6 +206,14 @@ update_state (struct CadetConnection *cc,
int old_ready;
int new_ready;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Trying to update connection state for %s having old state %d to new %d and mqm_ready old %d to mqm_ready new %d\n",
+ GCT_2s (cc->ct->t),
+ cc->state,
+ new_state,
+ cc->mqm_ready,
+ new_mqm_ready);
+
if ((new_state == cc->state) && (new_mqm_ready == cc->mqm_ready))
return; /* no change, nothing to do */
old_ready =
@@ -214,6 +222,13 @@ update_state (struct CadetConnection *cc,
((CADET_CONNECTION_READY == new_state) && (GNUNET_YES == new_mqm_ready));
cc->state = new_state;
cc->mqm_ready = new_mqm_ready;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Updating connection state for %s having old_ready %d and new_rady %d\n",
+ GCT_2s (cc->ct->t),
+ old_ready,
+ new_ready);
+
if (old_ready != new_ready)
cc->ready_cb (cc->ready_cb_cls, new_ready);
}
@@ -392,7 +407,7 @@ send_keepalive (void *cls)
msg.size = htons (sizeof(msg));
msg.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE);
- cc->keepalive_qe = GCT_send (cc->ct->t, &msg, &keepalive_done, cc);
+ cc->keepalive_qe = GCT_send (cc->ct->t, &msg, &keepalive_done, cc, NULL);
}
@@ -580,6 +595,20 @@ GCC_handle_encrypted (struct CadetConnection *cc,
}
+void
+set_monotime_sig (struct GNUNET_CADET_ConnectionCreateMessage *msg)
+{
+
+ struct CadetConnectionCreatePS cp = { .purpose.purpose = htonl (
+ GNUNET_SIGNATURE_PURPOSE_CADET_CONNECTION_INITIATOR),
+ .purpose.size = htonl (sizeof(cp)),
+ .monotonic_time = msg->monotime};
+
+ GNUNET_CRYPTO_eddsa_sign (my_private_key, &cp,
+ &msg->monotime_sig);
+
+}
+
/**
* Send a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE message to the
* first hop.
@@ -593,6 +622,7 @@ send_create (void *cls)
struct GNUNET_CADET_ConnectionCreateMessage *create_msg;
struct GNUNET_PeerIdentity *pids;
struct GNUNET_MQ_Envelope *env;
+ struct CadetTunnel *t;
cc->task = NULL;
GNUNET_assert (GNUNET_YES == cc->mqm_ready);
@@ -603,6 +633,18 @@ send_create (void *cls)
// TODO This will be removed in a major release, because this will be a protocol breaking change. We set the deprecated 'reliable' bit here that was removed.
create_msg->options = 2;
create_msg->cid = cc->cid;
+
+ // check for tunnel state and set signed monotime (xrs,t3ss)
+ t = GCP_get_tunnel (cc->destination, GNUNET_YES);
+ if ((NULL != t)&& (GCT_get_estate (t) == CADET_TUNNEL_KEY_UNINITIALIZED) &&
+ (GCT_alice_or_betty (GCP_get_id (cc->destination)) == GNUNET_NO))
+ {
+ create_msg->has_monotime = GNUNET_YES;
+ create_msg->monotime = GNUNET_TIME_absolute_hton (
+ GNUNET_TIME_absolute_get_monotonic (cfg));
+ set_monotime_sig (create_msg);
+ }
+
pids = (struct GNUNET_PeerIdentity *) &create_msg[1];
pids[0] = my_full_id;
for (unsigned int i = 0; i <= cc->off; i++)
@@ -792,6 +834,7 @@ connection_create (struct CadetPeer *destination,
cc = GNUNET_new (struct CadetConnection);
cc->state = init_state;
cc->ct = ct;
+ cc->destination = destination; /* xrs,t3ss,lurchi*/
cc->cid = *cid;
cc->retry_delay =
GNUNET_TIME_relative_multiply (INITIAL_CONNECTION_CREATE_RETRY_DELAY, off);
diff --git a/src/cadet/gnunet-service-cadet_connection.h b/src/cadet/gnunet-service-cadet_connection.h
index b05c3b72c..a9ebef567 100644
--- a/src/cadet/gnunet-service-cadet_connection.h
+++ b/src/cadet/gnunet-service-cadet_connection.h
@@ -182,7 +182,29 @@ void
GCC_handle_kx_auth (struct CadetConnection *cc,
const struct
GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg);
+struct CadetConnectionCreatePS
+{
+
+ /**
+ * Purpose is #GNUNET_SIGNATURE_PURPOSE_CADET_CONNECTION_INITIATOR
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+ /**
+ * Time at the initiator when generating the signature.
+ *
+ * Note that the receiver MUST IGNORE the absolute time, and only interpret
+ * the value as a mononic time and reject "older" values than the last one
+ * observed. This is necessary as we do not want to require synchronized
+ * clocks and may not have a bidirectional communication channel.
+ *
+ * Even with this, there is no real guarantee against replay achieved here,
+ * unless the latest timestamp is persisted. Persistence should be
+ * provided via PEERSTORE if possible.
+ */
+ struct GNUNET_TIME_AbsoluteNBO monotonic_time;
+
+};
/**
* Performance metrics for a connection.
diff --git a/src/cadet/gnunet-service-cadet_core.c b/src/cadet/gnunet-service-cadet_core.c
index d54022896..04847f906 100644
--- a/src/cadet/gnunet-service-cadet_core.c
+++ b/src/cadet/gnunet-service-cadet_core.c
@@ -227,7 +227,6 @@ static unsigned long long cur_buffers;
*/
static struct GNUNET_SCHEDULER_Task *timeout_task;
-
/**
* Get the route corresponding to a hash.
*
@@ -724,6 +723,7 @@ handle_connection_create (
uint16_t size = ntohs (msg->header.size) - sizeof(*msg);
unsigned int path_length;
unsigned int off;
+ struct CadetTunnel *t;
path_length = size / sizeof(struct GNUNET_PeerIdentity);
if (0 == path_length)
@@ -822,8 +822,19 @@ handle_connection_create (
GCP_2s (origin),
GNUNET_sh2s (&msg->cid.connection_of_tunnel));
path = GCPP_get_path_from_route (path_length - 1, pids);
+ t = GCP_get_tunnel (sender, GNUNET_YES);
+
+ // Check for CADET state in case the other side has lost the tunnel (xrs,t3ss)
+ if ((GNUNET_YES == msg->has_monotime) &&
+ (GNUNET_YES == GCP_check_and_update_monotime(origin, msg->monotime)) &&
+ ( GNUNET_OK == GCP_check_monotime_sig(origin, msg)) &&
+ (CADET_TUNNEL_KEY_OK == GCT_get_estate(t)))
+ {
+ GCT_change_estate (t, CADET_TUNNEL_KEY_UNINITIALIZED);
+ }
+
if (GNUNET_OK !=
- GCT_add_inbound_connection (GCP_get_tunnel (origin, GNUNET_YES),
+ GCT_add_inbound_connection (t,
&msg->cid,
path))
{
diff --git a/src/cadet/gnunet-service-cadet_peer.c b/src/cadet/gnunet-service-cadet_peer.c
index 8258881d0..0ff4d1fb8 100644
--- a/src/cadet/gnunet-service-cadet_peer.c
+++ b/src/cadet/gnunet-service-cadet_peer.c
@@ -31,6 +31,7 @@
* to take a break if we have some connections and have searched a lot (?))
*/
#include "platform.h"
+#include "gnunet_time_lib.h"
#include "gnunet_util_lib.h"
#include "gnunet_hello_lib.h"
#include "gnunet_signatures.h"
@@ -38,10 +39,10 @@
#include "gnunet_ats_service.h"
#include "gnunet_core_service.h"
#include "gnunet_statistics_service.h"
-#include "cadet_protocol.h"
+#include "gnunet-service-cadet_peer.h"
+#include "gnunet-service-cadet.h"
#include "gnunet-service-cadet_connection.h"
#include "gnunet-service-cadet_dht.h"
-#include "gnunet-service-cadet_peer.h"
#include "gnunet-service-cadet_paths.h"
#include "gnunet-service-cadet_tunnels.h"
@@ -66,7 +67,6 @@
*/
#define MAX_OOO_QUEUE_SIZE 100
-
/**
* Data structure used to track whom we have to notify about changes
* to our message queue.
@@ -118,7 +118,7 @@ struct CadetPeer
/**
* Last time we heard from this peer (currently not used!)
*/
- struct GNUNET_TIME_Absolute last_contactXXX;
+ struct GNUNET_TIME_Absolute last_connection_create;
/**
* Array of DLLs of paths traversing the peer, organized by the
@@ -1552,5 +1552,60 @@ GCP_send_ooo (struct CadetPeer *cp,
env);
}
+/*
+ * FIXME: comment
+ */
+void
+GCP_update_monotime (struct CadetPeer *peer)
+{
+ peer->last_connection_create = GNUNET_TIME_absolute_get_monotonic (cfg);
+}
+
+/*
+ * FIXME: comment
+ */
+int
+GCP_check_and_update_monotime (struct CadetPeer *peer,
+ struct GNUNET_TIME_AbsoluteNBO monotime)
+{
+
+ struct GNUNET_TIME_Absolute mt = GNUNET_TIME_absolute_ntoh (monotime);
+
+ if (mt.abs_value_us > *(&peer->last_connection_create.abs_value_us))
+ {
+ peer->last_connection_create = mt;
+ return GNUNET_YES;
+ }
+ return GNUNET_NO;
+}
+
+/*
+ * FIXME: documentation here
+ */
+int
+GCP_check_monotime_sig (struct CadetPeer *peer, const struct
+ GNUNET_CADET_ConnectionCreateMessage *msg)
+{
+ // struct CadetPeer *peer;
+ // const struct GNUNET_CADET_ConnectionCreateMessage *msg;
+
+ struct CadetConnectionCreatePS cp = { .purpose.purpose = htonl (
+ GNUNET_SIGNATURE_PURPOSE_CADET_CONNECTION_INITIATOR),
+ .purpose.size = htonl (sizeof(cp)),
+ .monotonic_time = msg->monotime};
+
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_eddsa_verify (
+ GNUNET_SIGNATURE_PURPOSE_CADET_CONNECTION_INITIATOR,
+ &cp,
+ &msg->monotime_sig,
+ &peer->pid.public_key))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
/* end of gnunet-service-cadet-new_peer.c */
diff --git a/src/cadet/gnunet-service-cadet_peer.h b/src/cadet/gnunet-service-cadet_peer.h
index bec0606a0..31bd23121 100644
--- a/src/cadet/gnunet-service-cadet_peer.h
+++ b/src/cadet/gnunet-service-cadet_peer.h
@@ -402,5 +402,14 @@ void
GCP_set_mq (struct CadetPeer *cp,
struct GNUNET_MQ_Handle *mq);
+int
+GCP_check_monotime_sig (struct CadetPeer *peer, const struct GNUNET_CADET_ConnectionCreateMessage *msg);
+
+void
+GCP_update_monotime (struct CadetPeer *cp);
+
+int
+GCP_check_and_update_monotime (struct CadetPeer *peer,
+ struct GNUNET_TIME_AbsoluteNBO monotime);
#endif
diff --git a/src/cadet/gnunet-service-cadet_tunnels.c b/src/cadet/gnunet-service-cadet_tunnels.c
index f1f2ec81f..66e7d5b1e 100644
--- a/src/cadet/gnunet-service-cadet_tunnels.c
+++ b/src/cadet/gnunet-service-cadet_tunnels.c
@@ -464,8 +464,8 @@ struct CadetTunnel
* @param other the other peer
* @return #GNUNET_YES for Alice, #GNUNET_NO for Betty, #GNUNET_SYSERR if talking to myself
*/
-static int
-alice_or_betty (const struct GNUNET_PeerIdentity *other)
+int
+GCT_alice_or_betty (const struct GNUNET_PeerIdentity *other)
{
if (0 > GNUNET_memcmp (&my_full_id,
other))
@@ -1345,7 +1345,7 @@ send_kx (struct CadetTunnel *t,
struct GNUNET_CADET_TunnelKeyExchangeMessage *msg;
enum GNUNET_CADET_KX_Flags flags;
- if (GNUNET_YES != alice_or_betty (GCP_get_id (t->destination)))
+ if (GNUNET_YES != GCT_alice_or_betty (GCP_get_id (t->destination)))
return; /* only Alice may send KX */
if ((NULL == ct) ||
(GNUNET_NO == ct->is_ready))
@@ -1521,7 +1521,7 @@ update_ax_by_kx (struct CadetTunnelAxolotl *ax,
const char salt[] = "CADET Axolotl salt";
int am_I_alice;
- if (GNUNET_SYSERR == (am_I_alice = alice_or_betty (pid)))
+ if (GNUNET_SYSERR == (am_I_alice = GCT_alice_or_betty (pid)))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@@ -1726,7 +1726,7 @@ GCT_handle_kx (struct CadetTConnection *ct,
1,
GNUNET_NO);
if (GNUNET_YES ==
- alice_or_betty (GCP_get_id (t->destination)))
+ GCT_alice_or_betty (GCP_get_id (t->destination)))
{
/* Betty/Bob is not allowed to send KX! */
GNUNET_break_op (0);
@@ -2123,9 +2123,10 @@ GCT_add_channel (struct CadetTunnel *t,
ch,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Adding %s to %s\n",
+ "Adding %s to %s with state %d\n",
GCCH_2s (ch),
- GCT_2s (t));
+ GCT_2s (t),
+ t->estate);
switch (t->estate)
{
case CADET_TUNNEL_KEY_UNINITIALIZED:
@@ -2429,12 +2430,21 @@ connection_ready_cb (void *cls,
switch (t->estate)
{
case CADET_TUNNEL_KEY_UNINITIALIZED:
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Do not begin KX for %s if WE have no channels waiting. Retrying after %d\n",
+ GCT_2s (t),
+ GNUNET_TIME_absolute_get_remaining (t->next_kx_attempt).rel_value_us);
/* Do not begin KX if WE have no channels waiting! */
if (0 != GNUNET_TIME_absolute_get_remaining (
t->next_kx_attempt).rel_value_us)
return; /* wait for timeout before retrying */
/* We are uninitialized, just transmit immediately,
without undue delay. */
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Why for %s \n",
+ GCT_2s (t));
+
if (NULL != t->kx_task)
{
GNUNET_SCHEDULER_cancel (t->kx_task);
@@ -3028,7 +3038,8 @@ GCT_send_channel_destroy (struct CadetTunnel *t,
GCT_send (t,
&msg.header,
NULL,
- NULL);
+ NULL,
+ &ctn);
}
@@ -3445,18 +3456,32 @@ GCT_handle_encrypted (struct CadetTConnection *ct,
* @param t Tunnel on which this message is transmitted.
* @param cont Continuation to call once message is really sent.
* @param cont_cls Closure for @c cont.
+ * @param The ID of the channel we are using for sending.
* @return Handle to cancel message
*/
struct CadetTunnelQueueEntry *
GCT_send (struct CadetTunnel *t,
const struct GNUNET_MessageHeader *message,
GCT_SendContinuation cont,
- void *cont_cls)
+ void *cont_cls,
+ struct GNUNET_CADET_ChannelTunnelNumber *ctn)
{
struct CadetTunnelQueueEntry *tq;
uint16_t payload_size;
struct GNUNET_MQ_Envelope *env;
struct GNUNET_CADET_TunnelEncryptedMessage *ax_msg;
+ struct CadetChannel *ch;
+
+ if (NULL != ctn)
+ {
+ ch = lookup_channel (t,
+ *ctn);
+ if ((NULL != ch)&& GCCH_is_type_to_drop (ch, message))
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ }
if (CADET_TUNNEL_KEY_OK != t->estate)
{
diff --git a/src/cadet/gnunet-service-cadet_tunnels.h b/src/cadet/gnunet-service-cadet_tunnels.h
index ef07badea..147f2e56f 100644
--- a/src/cadet/gnunet-service-cadet_tunnels.h
+++ b/src/cadet/gnunet-service-cadet_tunnels.h
@@ -80,6 +80,14 @@ enum CadetTunnelEState
CADET_TUNNEL_KEY_OK
};
+/**
+ * Am I Alice or Betty (some call her Bob), or talking to myself?
+ *
+ * @param other the other peer
+ * @return #GNUNET_YES for Alice, #GNUNET_NO for Betty, #GNUNET_SYSERR if talking to myself
+ */
+int
+GCT_alice_or_betty (const struct GNUNET_PeerIdentity *other);
/**
* Get the static string for the peer this tunnel is directed.
@@ -226,7 +234,8 @@ struct CadetTunnelQueueEntry *
GCT_send (struct CadetTunnel *t,
const struct GNUNET_MessageHeader *message,
GCT_SendContinuation cont,
- void *cont_cls);
+ void *cont_cls,
+ struct GNUNET_CADET_ChannelTunnelNumber *ctn);
/**
@@ -320,6 +329,16 @@ GCT_iterate_channels (struct CadetTunnel *t,
enum CadetTunnelEState
GCT_get_estate (struct CadetTunnel *t);
+/**
+ * Change the tunnel encryption state.
+ * If the encryption state changes to OK, stop the rekey task.
+ *
+ * @param t Tunnel whose encryption state to change, or NULL.
+ * @param state New encryption state.
+ */
+void
+GCT_change_estate (struct CadetTunnel *t,
+ enum CadetTunnelEState state);
/**
* Handle KX message.
diff --git a/src/cadet/test_cadet.c b/src/cadet/test_cadet.c
index 25713709c..779d3bc9f 100644
--- a/src/cadet/test_cadet.c
+++ b/src/cadet/test_cadet.c
@@ -25,6 +25,7 @@
*/
#include <stdio.h>
#include "platform.h"
+#include "cadet.h"
#include "cadet_test_lib.h"
#include "gnunet_cadet_service.h"
#include "gnunet_statistics_service.h"
@@ -74,6 +75,17 @@ struct CadetTestChannelWrapper
#define SPEED_REL 8
#define P2P_SIGNAL 10
#define REOPEN 11
+#define DESTROY 12
+
+/**
+ * Active peer listing operation.
+ */
+static struct GNUNET_CADET_PeersLister *plo;
+
+/*
+ * Task called to check for existing tunnel and depending on that reopen channel
+ */
+static struct GNUNET_SCHEDULER_Task *get_peers_task;
/**
* Which test are we running?
@@ -123,7 +135,12 @@ static struct GNUNET_TESTBED_Operation *t_op[2];
/**
* Peer ids.
*/
-static struct GNUNET_PeerIdentity *p_id[2];
+static struct GNUNET_PeerIdentity *testpeer_id[2];
+
+/**
+ * Peer ids.
+ */
+static struct GNUNET_CONFIGURATION_Handle *p_cfg[2];
/**
* Port ID
@@ -133,7 +150,7 @@ static struct GNUNET_HashCode port;
/**
* Peer ids counter.
*/
-static unsigned int p_ids;
+static unsigned int peerinfo_task_cnt;
/**
* Is the setup initialized?
@@ -196,16 +213,6 @@ static struct GNUNET_SCHEDULER_Task *test_task;
static struct GNUNET_SCHEDULER_Task *send_next_msg_task;
/**
- * Cadet handle for the root peer
- */
-static struct GNUNET_CADET_Handle *h1;
-
-/**
- * Cadet handle for the first leaf peer
- */
-static struct GNUNET_CADET_Handle *h2;
-
-/**
* Channel handle for the root peer
*/
static struct GNUNET_CADET_Channel *outgoing_ch;
@@ -226,6 +233,9 @@ static struct GNUNET_TIME_Absolute start_time;
*/
static struct GNUNET_TESTBED_Peer **testbed_peers;
+
+struct GNUNET_CADET_Handle **cadets_running;
+
/**
* Statistics operation handle.
*/
@@ -246,6 +256,17 @@ static unsigned int ka_received;
*/
static unsigned int msg_dropped;
+/**
+ * Drop the next cadet message of a given type..
+ *
+ * @param mq message queue
+ * @param ccn client channel number.
+ * @param type of cadet message to be dropped.
+ */
+void
+GNUNET_CADET_drop_message (struct GNUNET_MQ_Handle *mq,
+ struct GNUNET_CADET_ClientChannelNumber ccn,
+ uint16_t type);
/******************************************************************************/
@@ -516,6 +537,49 @@ static void
disconnect_handler (void *cls,
const struct GNUNET_CADET_Channel *channel);
+static struct GNUNET_PeerIdentity *
+get_from_p_ids ()
+{
+ if (0 < GNUNET_memcmp (testpeer_id[0], testpeer_id[1]))
+ {
+ return testpeer_id[1];
+ }
+ else
+ {
+ return testpeer_id[0];
+ }
+}
+
+static struct GNUNET_CADET_Handle *
+get_from_cadets ()
+{
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "1\n");
+ if (0 < GNUNET_memcmp (testpeer_id[0], testpeer_id[1]))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "standard peer\n");
+ return cadets_running[0];
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "the other peer\n");
+ return cadets_running[peers_running - 1];
+ }
+
+}
+
+static unsigned int
+get_peer_nr (int outgoing)
+{
+ if (0 < GNUNET_memcmp (testpeer_id[0], testpeer_id[1]))
+ {
+ return GNUNET_YES == outgoing ? 0 : peers_running - 1;
+ }
+ else
+ {
+ return GNUNET_YES == outgoing ? peers_running - 1 : 0;
+ }
+}
/**
* Task to reconnect to other peer.
@@ -534,6 +598,8 @@ reconnect_op (void *cls)
};
long l = (long) cls;
struct CadetTestChannelWrapper *ch;
+ static struct GNUNET_PeerIdentity *p_id;
+ static struct GNUNET_CADET_Handle *h1;
reconnect_task = NULL;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -545,17 +611,127 @@ reconnect_op (void *cls)
outgoing_ch = NULL;
}
ch = GNUNET_new (struct CadetTestChannelWrapper);
+
+ p_id = get_from_p_ids ();
+ h1 = get_from_cadets ();
+
+ outgoing_ch = GNUNET_CADET_channel_create (h1,
+ ch,
+ p_id,
+ &port,
+ NULL,
+ &disconnect_handler,
+ handlers);
+ ch->ch = outgoing_ch;
+ send_test_message (outgoing_ch);
+}
+
+void
+reopen_channel ()
+{
+ struct CadetTestChannelWrapper *ch;
+ static struct GNUNET_CADET_Handle *h1;
+ static struct GNUNET_PeerIdentity *p_id;
+ struct GNUNET_MQ_MessageHandler handlers[] = {
+ GNUNET_MQ_hd_var_size (data,
+ GNUNET_MESSAGE_TYPE_DUMMY,
+ struct GNUNET_MessageHeader,
+ NULL),
+ GNUNET_MQ_handler_end ()
+ };
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "creating channel again\n");
+ p_id = get_from_p_ids ();
+ h1 = get_from_cadets ();
+
+ ch = GNUNET_new (struct CadetTestChannelWrapper);
outgoing_ch = GNUNET_CADET_channel_create (h1,
ch,
- p_id[1],
+ p_id,
&port,
NULL,
&disconnect_handler,
handlers);
ch->ch = outgoing_ch;
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Sending second test data (after destroying the channel) on channel %p...\n",
+ outgoing_ch);
send_test_message (outgoing_ch);
}
+static void
+peers_callback (void *cls, const struct GNUNET_CADET_PeerListEntry *ple);
+
+/**
+ * We ask the monitoring api for all the peers.
+ */
+static void
+get_peers (void *cls)
+{
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "requesting peers info!\n");
+ plo = GNUNET_CADET_list_peers (p_cfg[get_peer_nr (GNUNET_YES)],
+ &peers_callback, NULL);
+
+}
+
+/**
+ * Method called to retrieve information about all peers in CADET, called
+ * once per peer.
+ *
+ * After last peer has been reported, an additional call with NULL is done.
+ *
+ * We check the peer we are interested in, if we have a tunnel. If not, we
+ * reopen the channel
+ *
+ * @param cls Closure.
+ * @param ple information about peer, or NULL on "EOF".
+ */
+static void
+peers_callback (void *cls, const struct GNUNET_CADET_PeerListEntry *ple)
+{
+
+ const struct GNUNET_PeerIdentity *p_id;
+ const struct GNUNET_PeerIdentity *peer;
+
+
+ peer = &ple->peer;
+
+ if (NULL == ple)
+ {
+ plo = NULL;
+ return;
+ }
+ p_id = get_from_p_ids ();
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "ple->peer %s\n",
+ GNUNET_i2s_full (&ple->peer));
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "p_id %s\n",
+ GNUNET_i2s_full (p_id));
+
+ if ((0 == GNUNET_memcmp (&ple->peer, p_id))&& ple->have_tunnel)
+ {
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "schedule get_peers again?\n");
+ get_peers_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
+ &get_peers,
+ NULL);
+
+ }
+ else if (0 == GNUNET_memcmp (&ple->peer, p_id) )
+ {
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "reopen channel\n");
+
+ reopen_channel ();
+
+ }
+}
/**
* Function called whenever an MQ-channel is destroyed, unless the destruction
@@ -575,9 +751,22 @@ disconnect_handler (void *cls,
struct CadetTestChannelWrapper *ch_w = cls;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Channel disconnected at %d\n",
+ "Channel disconnected at ok=%d\n",
ok);
GNUNET_assert (ch_w->ch == channel);
+
+ if ((DESTROY == test) && (3 == ok))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Reopen channel task!\n");
+ if (NULL == get_peers_task)
+ {
+ get_peers_task = GNUNET_SCHEDULER_add_now (&get_peers,
+ NULL);
+ }
+ return;
+ }
+
if (channel == incoming_ch)
{
ok++;
@@ -651,8 +840,8 @@ send_test_message (struct GNUNET_CADET_Channel *channel)
int size;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending test message on channel %p\n",
- channel);
+ "Sending test message on channel %u\n",
+ channel->ccn.channel_of_client);
size = size_payload;
if (GNUNET_NO == initialized)
{
@@ -699,6 +888,10 @@ send_test_message (struct GNUNET_CADET_Channel *channel)
"Sending DATA %u [%d bytes]\n",
data_sent, size);
}
+ else if (DESTROY == test)
+ {
+ payload = data_sent;
+ }
else
{
GNUNET_assert (0);
@@ -826,7 +1019,7 @@ handle_data (void *cls,
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- " ok: (%d/%d)\n",
+ "handle_data ok: (%d/%d)\n",
ok,
ok_goal);
data = (uint32_t *) &message[1];
@@ -844,6 +1037,49 @@ handle_data (void *cls,
payload, *counter);
}
+ if (DESTROY == test)
+ {
+ if (2 == ok)
+ {
+ ok++;
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "dropping message ok: (%d/%d)\n",
+ ok,
+ ok_goal);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "TEST ID 0: %s\n",
+ GNUNET_i2s (testpeer_id[0]));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "TEST ID 1: %s\n",
+ GNUNET_i2s (testpeer_id[1]));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "dropping message\n");
+ GNUNET_CADET_drop_message (GNUNET_CADET_get_mq (outgoing_ch),
+ outgoing_ch->ccn,
+ GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY);
+ if (NULL != outgoing_ch)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Destroying channel %p...\n",
+ outgoing_ch);
+ GNUNET_CADET_channel_destroy (outgoing_ch);
+ outgoing_ch = NULL;
+ }
+ }
+ else if (5 == ok)
+ {
+ ok++;
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "destroy test finished ok: (%d/%d)\n",
+ ok,
+ ok_goal);
+ disconnect_task =
+ GNUNET_SCHEDULER_add_now (&gather_stats_and_exit,
+ (void *) __LINE__);
+ // End of DESTROY test.
+ }
+ }
+
if (GNUNET_NO == initialized)
{
initialized = GNUNET_YES;
@@ -861,7 +1097,7 @@ handle_data (void *cls,
if (get_target_channel () == channel) /* Got "data" */
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO, " received data %u\n", data_received);
- if ((SPEED != test) || ( (ok_goal - 2) == ok) )
+ if ((DESTROY != test) && ((SPEED != test) || ( (ok_goal - 2) == ok)) )
{
/* Send ACK */
send_test_message (channel);
@@ -927,11 +1163,13 @@ connect_handler (void *cls,
channel);
ok++;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- " ok: %d\n",
- ok);
- if (peer == peers_requested - 1)
+ "connect_handler ok: (%d/%d)\n",
+ ok,
+ ok_goal);
+
+ if (peer == get_peer_nr (GNUNET_NO))
{
- if (NULL != incoming_ch)
+ if ((DESTROY != test)&&(NULL != incoming_ch))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Duplicate incoming channel for client %lu\n",
@@ -947,7 +1185,7 @@ connect_handler (void *cls,
(long) cls);
GNUNET_assert (0);
}
- if ((NULL != disconnect_task) && (REOPEN != test))
+ if ((NULL != disconnect_task) && (REOPEN != test) && (DESTROY != test))
{
GNUNET_SCHEDULER_cancel (disconnect_task);
disconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
@@ -971,6 +1209,7 @@ connect_handler (void *cls,
(void *) __LINE__);
}
+
/* TODO: cannot return channel as-is, in order to unify the data handlers */
ch = GNUNET_new (struct CadetTestChannelWrapper);
ch->ch = channel;
@@ -998,6 +1237,8 @@ start_test (void *cls)
GNUNET_MQ_handler_end ()
};
struct CadetTestChannelWrapper *ch;
+ static struct GNUNET_CADET_Handle *h1;
+ static struct GNUNET_PeerIdentity *p_id;
test_task = NULL;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "start_test: %s\n", test_name);
@@ -1012,20 +1253,25 @@ start_test (void *cls)
test = SPEED;
}
+ p_id = get_from_p_ids ();
+ h1 = get_from_cadets ();
+
ch = GNUNET_new (struct CadetTestChannelWrapper);
outgoing_ch = GNUNET_CADET_channel_create (h1,
ch,
- p_id[1],
+ p_id,
&port,
NULL,
&disconnect_handler,
handlers);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "channel created\n");
ch->ch = outgoing_ch;
- disconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
- &gather_stats_and_exit,
- (void *) __LINE__);
+ if (DESTROY != test)
+ disconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
+ &gather_stats_and_exit,
+ (void *) __LINE__);
if (KEEPALIVE == test)
return; /* Don't send any data. */
@@ -1054,7 +1300,7 @@ start_test (void *cls)
/**
* Callback to be called when the requested peer information is available
*
- * @param cls the closure from GNUNET_TESTBED_peer_get_information()
+ * @param cls the closure from GNUNET_TESTBED_peer_getinformation()
* @param op the operation this callback corresponds to
* @param pinfo the result; will be NULL if the operation has failed
* @param emsg error message if the operation has failed;
@@ -1068,9 +1314,6 @@ pi_cb (void *cls,
{
long i = (long) cls;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "ID callback for %ld\n",
- i);
if ((NULL == pinfo) ||
(NULL != emsg))
{
@@ -1080,15 +1323,40 @@ pi_cb (void *cls,
abort_test (__LINE__);
return;
}
- p_id[i] = pinfo->result.id;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "id: %s\n",
- GNUNET_i2s (p_id[i]));
- p_ids++;
- if (p_ids < 2)
+
+ if (GNUNET_TESTBED_PIT_IDENTITY == pinfo->pit)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "ID callback for %ld\n",
+ i);
+ testpeer_id[i] = pinfo->result.id;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "id: %s\n",
+ GNUNET_i2s (testpeer_id[i]));
+ }
+ else if (GNUNET_TESTBED_PIT_CONFIGURATION == pinfo->pit)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "CFG callback for %ld\n",
+ i);
+ p_cfg[i] = pinfo->result.cfg;
+ }
+ else
+ {
+ GNUNET_break (0);
+ }
+
+ peerinfo_task_cnt++;
+ if (peerinfo_task_cnt < 4)
return;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Got all IDs, starting test\n");
+ "Got all peer information, starting test\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "TEST ID 0: %s\n",
+ GNUNET_i2s (testpeer_id[0]));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "TEST ID 1: %s\n",
+ GNUNET_i2s (testpeer_id[1]));
test_task = GNUNET_SCHEDULER_add_now (&start_test, NULL);
}
@@ -1115,8 +1383,8 @@ tmain (void *cls,
peers_running = num_peers;
GNUNET_assert (peers_running == peers_requested);
testbed_peers = peers;
- h1 = cadets[0];
- h2 = cadets[num_peers - 1];
+ cadets_running = cadets;
+
disconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
&disconnect_cadet_peers,
(void *) __LINE__);
@@ -1130,6 +1398,14 @@ tmain (void *cls,
GNUNET_TESTBED_PIT_IDENTITY,
&pi_cb,
(void *) 1L);
+ t_op[0] = GNUNET_TESTBED_peer_get_information (peers[0],
+ GNUNET_TESTBED_PIT_CONFIGURATION,
+ &pi_cb,
+ (void *) 0L);
+ t_op[1] = GNUNET_TESTBED_peer_get_information (peers[num_peers - 1],
+ GNUNET_TESTBED_PIT_CONFIGURATION,
+ &pi_cb,
+ (void *) 1L);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "requested peer ids\n");
}
@@ -1272,6 +1548,13 @@ main (int argc, char *argv[])
// */
ok_goal = 6;
}
+ else if (strstr (argv[0], "_destroy") != NULL)
+ {
+ test = DESTROY;
+ test_name = "destroy";
+ ok_goal = 6;
+ short_time = GNUNET_TIME_relative_multiply (short_time, 5);
+ }
else
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "UNKNOWN\n");
@@ -1286,7 +1569,7 @@ main (int argc, char *argv[])
GNUNET_asprintf (&test_name, "backwards %s", test_name);
}
- p_ids = 0;
+ peerinfo_task_cnt = 0;
ports[0] = &port;
ports[1] = NULL;
GNUNET_CADET_TEST_ruN ("test_cadet_small",
diff --git a/src/cadet/test_cadet.conf b/src/cadet/test_cadet.conf
index 30e496aff..067dd5fb4 100644
--- a/src/cadet/test_cadet.conf
+++ b/src/cadet/test_cadet.conf
@@ -27,7 +27,8 @@ QUOTA = 1 MB
DATABASE = heap
[transport]
-PLUGINS = udp
+#PLUGINS = udp
+PLUGINS = tcp
NEIGHBOUR_LIMIT = 50
#MANIPULATE_DELAY_IN = 10 ms
#MANIPULATE_DELAY_OUT = 10 ms
@@ -102,3 +103,7 @@ START_ON_DEMAND = NO
[rps]
IMMEDIATE_START = NO
START_ON_DEMAND = NO
+
+[rest]
+IMMEDIATE_START = NO
+START_ON_DEMAND = NO
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index a9cd7466a..0db6150aa 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -2734,9 +2734,8 @@ extern "C" {
* 1000-1009 Connection-level Messages
* 1010-1019 Channel-level Messages
* 1020-1029 Local Client-Service
- * 1030-1039 Local Service Monitoring
- * 1040-1049 Application Data
- * 1050-1059 Reserved
+ * 1030-1049 Local Service Monitoring
+ * 1050-1059 Application Data
*/
/******************************** Connection ********************************/
@@ -2932,6 +2931,11 @@ extern "C" {
*/
#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS_END 1041
+/**
+ * Request to drop a message of type X to peer y.
+ */
+#define GNUNET_MESSAGE_TYPE_CADET_DROP_CADET_MESSAGE 1042
+
/******************************** Application *******************************/
diff --git a/src/include/gnunet_signatures.h b/src/include/gnunet_signatures.h
index a00e0372d..503113770 100644
--- a/src/include/gnunet_signatures.h
+++ b/src/include/gnunet_signatures.h
@@ -241,6 +241,10 @@ extern "C"
*/
#define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR 37
+/**
+ * Signature by a peer that like to create a connection.
+ */
+#define GNUNET_SIGNATURE_PURPOSE_CADET_CONNECTION_INITIATOR 38
#if 0 /* keep Emacsens' auto-indent happy */
{