/*
This file is part of GNUnet.
Copyright (C) 2009 GNUnet e.V.
GNUnet is free software: you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License,
or (at your option) any later version.
GNUnet is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
SPDX-License-Identifier: AGPL3.0-or-later
*/
/**
* @file cadet/test_cadeT.c
* @brief testcase for cadet.c
* @author xrs
*
* Goal:
* - test session resumption after a hard channel breakup
*
* ToDos:
* x setup peer A
* x setup peer B
* x setup cadet on peer B listening on port "cadet_port"
* x create a channel from peer A to B
* x create method to find out KX initiator
* x send a message over channel
* x check if message was received
* - breakup the connection without the receiver receiving a channel destroy message
* - assert tunnel is down
* - resume channel (second handshake for tunnel)
* - send second message over channel
* - check if message was receveived
* - end test
*
* Questions:
* - can we simulate hard breakups with TESTBED?
* - GNUNET_TESTBED_underlay_configure_link not implemented
* - GNUNET_TESTBED_underlaylinkmodel_set_link not usable
* - GNUNET_TESTBED_peer_stop evokes standard service disconnect
* - how can we test the sublayers of CADET, e.g. connection, tunnel, channel?
*
* Development
* - red -> green -> refactor (cyclic)
* - be aware of Continuation Passing Style (CPS) programming
*/
#include "platform.h"
#include "gnunet_testbed_service.h"
#include "cadet.h"
#include
#define CONFIG "test_cadet.conf"
#define TESTPROGAM_NAME "test-cadet-channel-resumption"
/**
* Counter for gathering peerinformation.
*/
static int peerinfo_cnt = 0;
/**
* Structure for storing information of testbed peers.
*/
struct TEST_PEERS
{
/**
* Index of the peer.
*/
int idx;
/**
* Peer Identity.
*/
struct GNUNET_PeerIdentity id;
struct GNUNET_TESTBED_Peer *testbed_peer;
int ready;
} test_peers[2];
/****************************** TEST LOGIC ********************************/
static int kx_initiator;
static struct GNUNET_TESTBED_UnderlayLinkModel *model;
static int msg_count;
static struct GNUNET_SCHEDULER_Task *task;
enum RES {
RECEIVED_MESSAGE = 1
};
enum RES check;
static void
set_data_loss_rate (int rate)
{
GNUNET_TESTBED_underlaylinkmodel_set_link (model,
test_peers[0].testbed_peer,
0, rate, 100);
GNUNET_log (GNUNET_ERROR_TYPE_INFO, "%s: %i loss.\n", __func__, rate);
}
static void
send_message ()
{
struct GNUNET_MQ_Envelope *envelope;
struct GNUNET_MessageHeader *msg;
int *data;
GNUNET_log (GNUNET_ERROR_TYPE_INFO, "%s\n", __func__);
envelope = GNUNET_MQ_msg_extra (msg, 1000,
GNUNET_MESSAGE_TYPE_DUMMY);
data = (int *) &msg[1];
*data = 1000;
GNUNET_MQ_send (GNUNET_CADET_get_mq (test_peers[0].channel),
envelope);
msg_count++;
switch (msg_count)
{
case 2: set_data_loss_rate (100); break;
case 4: set_data_loss_rate (0); break;
}
if (msg_count < 5)
task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1),
&send_message,
NULL);
}
int
check_message (void *cls,
const struct GNUNET_MessageHeader *message)
{
return GNUNET_OK; /* all is well-formed */
}
void
handle_message (void *cls,
const struct GNUNET_MessageHeader *msg)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO, "%s\n", __func__);
GNUNET_CADET_receive_done (test_peers[1].channel);
check = RECEIVED_MESSAGE;
}
/**
* This function is called after all testbed management is done and the
* testbed peers are ready for the actual test logic.
* Use struct test_peers[i] to control the peers.
*/
void
run_test ()
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO, "%s\n", __func__);
// Init underlay link model to manipulate links
model = GNUNET_TESTBED_underlaylinkmodel_create (test_peers[1].testbed_peer,
GNUNET_TESTBED_UNDERLAYLINKMODELTYPE_BLACKLIST);
kx_initiator = (0 < GNUNET_memcmp (&test_peers[0].id, &test_peers[1].id)) ? 1 : 0;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"KX initiator is peer %s (idx:%i)\n",
GNUNET_i2s (&test_peers[kx_initiator].id),
kx_initiator);
send_message();
}
int
main (int argc, char *argv[])
{
GNUNET_TESTBED_test_run (TESTPROGAM_NAME,
CONFIG,
REQUESTED_PEERS, 0LL, NULL, NULL,
prepare_test, NULL);
return test_result;
}
/* end of test_template_api.c */