gnunet_testing_lib.h \
gnunet_time_lib.h \
gnunet_transport_service.h \
+ gnunet_transport_communication_service.h \
+ gnunet_transport_core_service.h \
+ gnunet_transport_hello_service.h \
+ gnunet_transport_manipulation_service.h \
+ gnunet_transport_monitor_service.h \
gnunet_transport_plugin.h \
gnunet_tun_lib.h \
gnunet_util_lib.h \
* peer connected to us.
*
* @param cls closure
- * @param peer the peer that connected
+ * @param peer the identity of the peer that connected; this
+ * pointer will remain valid until the disconnect, hence
+ * applications do not necessarily have to make a copy
+ * of the value if they only need it until disconnect
* @param mq message queue to use to transmit to @a peer
* @return closure to use in MQ handlers
*/
--- /dev/null
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2009-2014, 2016 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
+ by the Free Software Foundation; either version 3, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @author Christian Grothoff
+ *
+ * @file
+ * Low-level P2P IO
+ *
+ * @defgroup transport Transport service
+ * Low-level P2P IO
+ *
+ * @see [Documentation](https://gnunet.org/transport-service)
+ *
+ * @{
+ */
+
+#ifndef GNUNET_TRANSPORT_MANIPULATION_SERVICE_H
+#define GNUNET_TRANSPORT_MANIPULATION_SERVICE_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#if 0 /* keep Emacsens' auto-indent happy */
+}
+#endif
+#endif
+
+#include "gnunet_util_lib.h"
+#include "gnunet_ats_service.h"
+
+/**
+ * Version number of the transport API.
+ */
+#define GNUNET_TRANSPORT_MANIPULATION_VERSION 0x00000003
+
+/**
+ * Handle for transport manipulation.
+ */
+struct GNUNET_TRANSPORT_ManipulationHandle;
+
+
+/**
+ * Connect to the transport service. Note that the connection may
+ * complete (or fail) asynchronously.
+ *
+ * @param cfg configuration to use
+ * @return NULL on error
+ */
+struct GNUNET_TRANSPORT_ManipulationHandle *
+GNUNET_TRANSPORT_manipulation_connect (const struct GNUNET_CONFIGURATION_Handle *cfg);
+
+
+/**
+ * Disconnect from the transport service.
+ *
+ * @param handle handle returned from connect
+ */
+void
+GNUNET_TRANSPORT_manipulation_disconnect (struct GNUNET_TRANSPORT_ManipulationHandle *handle);
+
+
+/**
+ * Set transport metrics for a peer and a direction
+ *
+ * @param handle transport handle
+ * @param peer the peer to set the metric for
+ * @param prop the performance metrics to set
+ * @param delay_in inbound delay to introduce
+ * @param delay_out outbound delay to introduce
+ *
+ * Note: Delay restrictions in receiving direction will be enforced
+ * with one message delay.
+ */
+void
+GNUNET_TRANSPORT_manipulation_set (struct GNUNET_TRANSPORT_ManipulationHandle *handle,
+ const struct GNUNET_PeerIdentity *peer,
+ const struct GNUNET_ATS_Properties *prop,
+ struct GNUNET_TIME_Relative delay_in,
+ struct GNUNET_TIME_Relative delay_out);
+
+
+#if 0 /* keep Emacsens' auto-indent happy */
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+/* ifndef GNUNET_TRANSPORT_MANIPULATION_SERVICE_H */
+#endif
+
+/** @} */ /* end of group */
+
+/* end of gnunet_transport_manipulation_service.h */
transport_api_blacklist.c \
transport_api_core.c \
transport_api_get_hello.c \
+ transport_api_manipulation.c \
transport_api_monitor_peers.c \
transport_api_monitor_plugins.c \
transport_api_offer_hello.c
int may_drop)
{
struct TransportClient *tc;
+ int done;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Asked to broadcast message of type %u with %u bytes\n",
(unsigned int) ntohs (msg->type),
(unsigned int) ntohs (msg->size));
+ done = GNUNET_NO;
for (tc = clients_head; NULL != tc; tc = tc->next)
{
if ( (GNUNET_YES == may_drop) &&
(GNUNET_YES != tc->send_payload) )
continue; /* skip, this client does not care about payload */
unicast (tc, msg, may_drop);
+ done = GNUNET_YES;
}
+ if (GNUNET_NO == done)
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Message not delivered, is CORE service up?\n");
}
break;
default:
GNUNET_break (0);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
+ LOG (GNUNET_ERROR_TYPE_ERROR,
"Unexpected message of type %u (%u bytes)",
- ntohs (hdr->type), ntohs (hdr->size));
+ ntohs (hdr->type),
+ ntohs (hdr->size));
break;
}
return GNUNET_OK;
notify_receive (void *cls,
struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message)
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *hdr)
{
- const struct GNUNET_TRANSPORT_TESTING_TestMessage *hdr;
- hdr = (const struct GNUNET_TRANSPORT_TESTING_TestMessage *) message;
- if (GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE != ntohs (message->type))
+ if (GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE != ntohs (hdr->header.type))
return;
- total_bytes_recv += ntohs (message->size);
+ total_bytes_recv += ntohs (hdr->header.size);
{
char *ps = GNUNET_strdup (GNUNET_i2s (&receiver->id));
receiver->no,
ps,
ntohl (hdr->num),
- ntohs (message->size),
+ ntohs (hdr->header.size),
GNUNET_i2s (sender));
GNUNET_free (ps);
}
notify_receive (void *cls,
struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message)
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *hdr)
{
- const struct GNUNET_TRANSPORT_TESTING_TestMessage *hdr;
-
- hdr = (const struct GNUNET_TRANSPORT_TESTING_TestMessage *) message;
- if (GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE != ntohs (message->type))
+ if (GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE != ntohs (hdr->header.type))
return;
{
receiver->no,
ps,
ntohl (hdr->num),
- ntohs (message->size),
+ ntohs (hdr->header.size),
GNUNET_i2s (sender));
GNUNET_free (ps);
}
notify_receive (void *cls,
struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message)
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
{
{
char *ps = GNUNET_strdup (GNUNET_i2s (&receiver->id));
"Peer %u (`%s') received message of type %d and size %u size from peer %s!\n",
receiver->no,
ps,
- ntohs (message->type),
- ntohs (message->size),
+ ntohs (message->header.type),
+ ntohs (message->header.size),
GNUNET_i2s (sender));
GNUNET_free (ps);
}
- if ((GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE == ntohs (message->type)) &&
- (GNUNET_TRANSPORT_TESTING_LARGE_MESSAGE_SIZE == ntohs (message->size)))
+ if ((GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE == ntohs (message->header.type)) &&
+ (GNUNET_TRANSPORT_TESTING_LARGE_MESSAGE_SIZE == ntohs (message->header.size)))
{
ccc->global_ret = GNUNET_OK;
GNUNET_SCHEDULER_shutdown ();
notify_receive (void *cls,
struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message)
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpectedly even received the message despite blacklist\n");
notify_receive (void *cls,
struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message)
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
{
{
char *ps = GNUNET_strdup (GNUNET_i2s (&receiver->id));
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Peer %u (`%4s') received message of type %d and size %u size from peer %s!\n",
+ "Peer %u (`%s') received message of type %d and size %u size from peer %s!\n",
receiver->no,
ps,
- ntohs (message->type),
- ntohs (message->size),
+ ntohs (message->header.type),
+ ntohs (message->header.size),
GNUNET_i2s (sender));
GNUNET_free (ps);
}
- if ((GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE == ntohs (message->type)) &&
- (sizeof (struct GNUNET_TRANSPORT_TESTING_TestMessage) == ntohs (message->size)))
+ if ((GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE == ntohs (message->header.type)) &&
+ (sizeof (struct GNUNET_TRANSPORT_TESTING_TestMessage) == ntohs (message->header.size)))
{
GNUNET_SCHEDULER_add_now (&stop_peer,
NULL);
notify_receive (void *cls,
struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message)
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received message of type %d from peer %s!\n",
- ntohs (message->type),
+ ntohs (message->header.type),
GNUNET_i2s (sender));
if ( (GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE ==
- ntohs (message->type)) &&
+ ntohs (message->header.type)) &&
(sizeof (struct GNUNET_TRANSPORT_TESTING_TestMessage) ==
- ntohs (message->size)) )
+ ntohs (message->header.size)) )
{
ccc->global_ret = GNUNET_OK;
}
#define TEST_MESSAGE_SIZE 2600
-#define TEST_RESPONSE_MESSAGE_TYPE 12346
+#define TEST_RESPONSE_MESSAGE_TYPE
/**
* Test delay, in microseconds.
start_response = GNUNET_TIME_absolute_get();
ret = GNUNET_TRANSPORT_TESTING_send (ccc->p[1],
ccc->p[0],
- TEST_RESPONSE_MESSAGE_TYPE,
+ GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE2,
TEST_MESSAGE_SIZE,
1,
NULL,
notify_receive (void *cls,
struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message)
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
{
struct GNUNET_TIME_Relative duration;
"Peer %u (`%s') received message of type %d and size %u size from peer %s)!\n",
receiver->no,
ps,
- ntohs (message->type),
- ntohs (message->size),
+ ntohs (message->header.type),
+ ntohs (message->header.size),
GNUNET_i2s (sender));
GNUNET_free (ps);
}
- switch (ntohs (message->type)) {
+ switch (ntohs (message->header.type)) {
case GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE:
duration = GNUNET_TIME_absolute_get_difference (start_request,
GNUNET_TIME_absolute_get());
GNUNET_SCHEDULER_add_now (&sendtask_response_task,
NULL);
return;
- case TEST_RESPONSE_MESSAGE_TYPE:
+ case GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE2:
duration = GNUNET_TIME_absolute_get_difference(start_response,
GNUNET_TIME_absolute_get());
if (duration.rel_value_us >= TEST_DELAY)
{
memset (&prop, 0, sizeof (prop));
delay = GNUNET_TIME_UNIT_SECONDS;
- GNUNET_TRANSPORT_set_traffic_metric (ccc->p[1]->th,
- &ccc->p[0]->id,
- &prop,
- delay,
- GNUNET_TIME_UNIT_ZERO);
+ GNUNET_TRANSPORT_manipulation_set (ccc->p[1]->tmh,
+ &ccc->p[0]->id,
+ &prop,
+ delay,
+ GNUNET_TIME_UNIT_ZERO);
start_delayed = GNUNET_TIME_absolute_get();
}
GNUNET_TRANSPORT_TESTING_large_send (sc);
notify_receive (void *cls,
struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message)
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
{
{
char *ps = GNUNET_strdup (GNUNET_i2s (&receiver->id));
"Peer %u (`%s') received message of type %d and size %u size from peer %s)!\n",
receiver->no,
ps,
- ntohs (message->type),
- ntohs (message->size),
+ ntohs (message->header.type),
+ ntohs (message->header.size),
GNUNET_i2s (sender));
GNUNET_free (ps);
}
- if ( (GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE != ntohs (message->type)) ||
- (GNUNET_TRANSPORT_TESTING_LARGE_MESSAGE_SIZE != ntohs (message->size)) )
+ if ( (GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE != ntohs (message->header.type)) ||
+ (GNUNET_TRANSPORT_TESTING_LARGE_MESSAGE_SIZE != ntohs (message->header.size)) )
{
GNUNET_break (0);
ccc->global_ret = GNUNET_SYSERR;
{
memset (&prop, 0, sizeof (prop));
delay = GNUNET_TIME_UNIT_SECONDS;
- GNUNET_TRANSPORT_set_traffic_metric (ccc->p[0]->th,
- &ccc->p[1]->id,
- &prop,
- GNUNET_TIME_UNIT_ZERO,
- delay);
+ GNUNET_TRANSPORT_manipulation_set (ccc->p[0]->tmh,
+ &ccc->p[1]->id,
+ &prop,
+ GNUNET_TIME_UNIT_ZERO,
+ delay);
start_delayed = GNUNET_TIME_absolute_get();
}
GNUNET_TRANSPORT_TESTING_large_send (sc);
notify_receive (void *cls,
struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message)
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
{
{
char *ps = GNUNET_strdup (GNUNET_i2s (&receiver->id));
"Peer %u (`%s') received message of type %d and size %u size from peer %s)!\n",
receiver->no,
ps,
- ntohs (message->type),
- ntohs (message->size),
+ ntohs (message->header.type),
+ ntohs (message->header.size),
GNUNET_i2s (sender));
GNUNET_free (ps);
}
- if ( (GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE != ntohs (message->type)) ||
- (GNUNET_TRANSPORT_TESTING_LARGE_MESSAGE_SIZE != ntohs (message->size)) )
+ if ( (GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE != ntohs (message->header.type)) ||
+ (GNUNET_TRANSPORT_TESTING_LARGE_MESSAGE_SIZE != ntohs (message->header.size)) )
{
GNUNET_break (0);
ccc->global_ret = GNUNET_SYSERR;
notify_receive (void *cls,
struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message)
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
{
char *ps = GNUNET_strdup (GNUNET_i2s (&receiver->id));
"Peer %u (`%s') received message of type %d and size %u size from peer %s!\n",
receiver->no,
ps,
- ntohs (message->type),
- ntohs (message->size),
+ ntohs (message->header.type),
+ ntohs (message->header.size),
GNUNET_i2s (sender));
GNUNET_free (ps);
}
*/
#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 450 * FACTOR)
+/**
+ * If we are in an "xhdr" test, the factor by which we divide
+ * #TOTAL_MSGS for a more sane test duration.
+ */
+static unsigned int xhdr = 1;
static struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc;
static size_t
get_size_cnt (unsigned int cnt_down)
{
- size_t ret = get_size (TOTAL_MSGS - 1 - cnt_down);
+ size_t ret = get_size (TOTAL_MSGS / xhdr - 1 - cnt_down);
total_bytes += ret;
return ret;
}
ok = 0;
- for (unsigned int i = 0; i < TOTAL_MSGS; i++)
+ for (unsigned int i = 0; i < TOTAL_MSGS / xhdr; i++)
{
if (get_bit (bitmap, i) == 0)
{
notify_receive (void *cls,
struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message)
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *hdr)
{
static int n;
unsigned int s;
char cbuf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
- const struct GNUNET_TRANSPORT_TESTING_TestMessage *hdr;
-
- hdr = (const struct GNUNET_TRANSPORT_TESTING_TestMessage *) message;
- if (GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE != ntohs (message->type))
+ if (GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE != ntohs (hdr->header.type))
return;
msg_recv = ntohl (hdr->num);
s = get_size (ntohl (hdr->num));
- if (ntohs (message->size) != s)
+ if (ntohs (hdr->header.size) != s)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Expected message %u of size %u, got %u bytes of message %u\n",
ntohl (hdr->num),
s,
- ntohs (message->size),
+ ntohs (hdr->header.size),
ntohl (hdr->num));
ccc->global_ret = GNUNET_SYSERR;
GNUNET_SCHEDULER_shutdown ();
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Got message %u of size %u\n",
ntohl (hdr->num),
- ntohs (message->size));
+ ntohs (hdr->header.size));
}
#endif
n++;
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Message id %u is bigger than maxmimum number of messages %u expected\n",
ntohl (hdr->num),
- TOTAL_MSGS);
+ TOTAL_MSGS / xhdr);
}
- if (0 == (n % (TOTAL_MSGS / 100)))
+ if (0 == (n % (TOTAL_MSGS / xhdr / 100)))
{
FPRINTF (stderr, "%s", ".");
}
- if (n == TOTAL_MSGS)
+ if (n == TOTAL_MSGS / xhdr)
{
/* end testcase with success */
ccc->global_ret = GNUNET_OK;
int
main (int argc, char *argv[])
{
+ if (0 == strstr (argv[0], "xhdr"))
+ xhdr = 30;
struct GNUNET_TRANSPORT_TESTING_SendClosure sc = {
- .num_messages = TOTAL_MSGS,
+ .num_messages = TOTAL_MSGS / xhdr,
.get_size_cb = &get_size_cnt
};
struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext my_ccc = {
static void
-restart_cb (struct GNUNET_TRANSPORT_TESTING_PeerContext *p,
- void *cls)
+restart_cb (void *cls)
{
static unsigned int c;
-
+ struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
+
c++;
if ( (2 != c) &&
(NULL != strstr (ccc->test_name,
notify_receive (void *cls,
struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message)
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
{
{
char *ps = GNUNET_strdup (GNUNET_i2s (&receiver->id));
"Peer %u (`%s') received message of type %d and size %u size from peer %s!\n",
receiver->no,
ps,
- ntohs (message->type),
- ntohs (message->size),
+ ntohs (message->header.type),
+ ntohs (message->header.size),
GNUNET_i2s (sender));
GNUNET_free (ps);
}
- if ( (GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE == ntohs (message->type)) &&
- (sizeof (struct GNUNET_TRANSPORT_TESTING_TestMessage) == ntohs (message->size)) )
+ if ( (GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE == ntohs (message->header.type)) &&
+ (sizeof (struct GNUNET_TRANSPORT_TESTING_TestMessage) == ntohs (message->header.size)) )
{
if (GNUNET_NO == restarted)
{
notify_receive (void *cls,
struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message)
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received message of type %d from peer %s!\n",
- ntohs (message->type),
+ ntohs (message->header.type),
GNUNET_i2s (sender));
}
static void
-restart_cb (struct GNUNET_TRANSPORT_TESTING_PeerContext *p,
- void *cls)
+restart_cb (void *cls)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Peer %u (`%s') successfully restarted\n",
static void
-start_cb (struct GNUNET_TRANSPORT_TESTING_PeerContext *p,
- void *cls)
+start_cb (void *cls)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Peer %u (`%s') successfully started\n",
static void
-start_cb (struct GNUNET_TRANSPORT_TESTING_PeerContext *p,
- void *cls)
+start_cb (void *cls)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Peer %u (`%s') successfully started\n",
};
+/**
+ * Information tracked per connected peer.
+ */
+struct ConnectPairInfo
+{
+ /**
+ * Peer this is about.
+ */
+ const struct GNUNET_PeerIdentity *sender;
+
+ /**
+ * Information about the receiving peer.
+ */
+ struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *ipi;
+};
+
+
/**
* Function called when we connected two peers. Once we have gotten
* to the clique, launch test-specific logic.
*
* @param cls our `struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *`
* @param peer peer we got connected to
+ * @param mq message queue for transmissions to @a peer
+ * @return closure for message handlers
*/
-static void
+static void *
my_nc (void *cls,
- const struct GNUNET_PeerIdentity *peer)
+ const struct GNUNET_PeerIdentity *peer,
+ struct GNUNET_MQ_Handle *mq)
{
struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *ipi = cls;
struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = ipi->ccc;
-
+ struct ConnectPairInfo *cpi;
+
if (NULL != ccc->nc)
ccc->nc (ccc->cls,
ccc->p[ipi->off],
peer);
+ cpi = GNUNET_new (struct ConnectPairInfo);
+ cpi->ipi = ipi;
+ cpi->sender = peer; /* valid until disconnect */
+ return cpi;
}
-
/**
* Wrapper around peers disconnecting. Calls client's nd function.
*
* @param cls our `struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *`
* @param peer peer we got disconnected from
+ * @param custom_cls return value from @my_nc
*/
static void
my_nd (void *cls,
- const struct GNUNET_PeerIdentity *peer)
+ const struct GNUNET_PeerIdentity *peer,
+ void *custom_cls)
{
struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *ipi = cls;
struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = ipi->ccc;
-
+ struct ConnectPairInfo *cpi = custom_cls;
+
if (NULL != ccc->nd)
ccc->nd (ccc->cls,
ccc->p[ipi->off],
peer);
+ GNUNET_free (cpi);
}
/**
* Wrapper around receiving data. Calls client's rec function.
*
- * @param cls our `struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *`
- * @param peer peer we got a message from
+ * @param cls our `struct ConnectPairInfo *`
+ * @param message message we received
+ * @return #GNUNET_OK (all messages are fine)
+ */
+static int
+check_test (void *cls,
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
+{
+ return GNUNET_OK;
+}
+
+
+/**
+ * Wrapper around receiving data. Calls client's rec function.
+ *
+ * @param cls our `struct ConnectPairInfo *`
* @param message message we received
*/
static void
-my_rec (void *cls,
- const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message)
+handle_test (void *cls,
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
{
- struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *ipi = cls;
+ struct ConnectPairInfo *cpi = cls;
+ struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *ipi = cpi->ipi;
+ struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = ipi->ccc;
+
+ if (NULL != ccc->rec)
+ ccc->rec (ccc->cls,
+ ccc->p[ipi->off],
+ cpi->sender,
+ message);
+}
+
+
+/**
+ * Wrapper around receiving data. Calls client's rec function.
+ *
+ * @param cls our `struct ConnectPairInfo *`
+ * @param message message we received
+ * @return #GNUNET_OK (all messages are fine)
+ */
+static int
+check_test2 (void *cls,
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
+{
+ return GNUNET_OK;
+}
+
+
+/**
+ * Wrapper around receiving data. Calls client's rec function.
+ *
+ * @param cls our `struct ConnectPairInfo *`
+ * @param message message we received
+ */
+static void
+handle_test2 (void *cls,
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
+{
+ struct ConnectPairInfo *cpi = cls;
+ struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *ipi = cpi->ipi;
struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = ipi->ccc;
if (NULL != ccc->rec)
ccc->rec (ccc->cls,
ccc->p[ipi->off],
- peer,
+ cpi->sender,
message);
}
* Once all peers have been launched, we connect all of them
* in a clique.
*
- * @param p peer that was launched (redundant, kill ASAP)
* @param cls our `struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *`
*/
static void
-start_cb (struct GNUNET_TRANSPORT_TESTING_PeerContext *p,
- void *cls)
+start_cb (void *cls)
{
struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *ipi = cls;
struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = ipi->ccc;
+ struct GNUNET_TRANSPORT_TESTING_PeerContext *p = ccc->p[ipi->off];
ccc->started++;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
const char *cfgfile,
const struct GNUNET_CONFIGURATION_Handle *cfg)
{
+ GNUNET_MQ_hd_var_size (test,
+ GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE,
+ struct GNUNET_TRANSPORT_TESTING_TestMessage);
+ GNUNET_MQ_hd_var_size (test2,
+ GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE2,
+ struct GNUNET_TRANSPORT_TESTING_TestMessage);
struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = cls;
int ok;
ok = GNUNET_OK;
for (unsigned int i=0;i<ccc->num_peers;i++)
{
+ struct GNUNET_MQ_MessageHandler handlers[] = {
+ make_test_handler (NULL),
+ make_test2_handler (NULL),
+ GNUNET_MQ_handler_end()
+ };
ccc->p[i] = GNUNET_TRANSPORT_TESTING_start_peer (ccc->tth,
ccc->cfg_files[i],
i + 1,
- &my_rec,
+ handlers,
&my_nc,
&my_nd,
&ccc->ip[i],
#define TIMEOUT_TRANSMIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
-static size_t
-notify_ready (void *cls,
- size_t size,
- void *buf)
-{
- struct TRANSPORT_TESTING_SendJob *sj = cls;
- struct GNUNET_TRANSPORT_TESTING_PeerContext *sender = sj->sender;
- struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver = sj->receiver;
- struct GNUNET_TRANSPORT_TESTING_Handle *tth = sender->tth;
- uint16_t msize = sj->msize;
- struct GNUNET_TRANSPORT_TESTING_TestMessage *test;
-
- sj->th = NULL;
- GNUNET_CONTAINER_DLL_remove (tth->sj_head,
- tth->sj_tail,
- sj);
- if (NULL == buf)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Timeout occurred while waiting for transmit_ready\n");
- GNUNET_SCHEDULER_shutdown ();
- GNUNET_free (sj);
- return 0;
- }
-
- GNUNET_assert (size >= msize);
- if (NULL != buf)
- {
- memset (buf, sj->num, msize);
- test = buf;
- test->header.size = htons (msize);
- test->header.type = htons (sj->mtype);
- test->num = htonl (sj->num);
- }
-
- {
- char *ps = GNUNET_strdup (GNUNET_i2s (&sender->id));
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Sending message %u from %u (%s) with type %u and size %u bytes to peer %u (%s)\n",
- (unsigned int) sj->num,
- sender->no,
- ps,
- sj->mtype,
- msize,
- receiver->no,
- GNUNET_i2s (&receiver->id));
- GNUNET_free (ps);
- }
- if (NULL != sj->cont)
- GNUNET_SCHEDULER_add_now (sj->cont,
- sj->cont_cls);
- GNUNET_free (sj);
- return msize;
-}
-
-
/**
* Return @a cx in @a cls.
*/
GNUNET_SCHEDULER_TaskCallback cont,
void *cont_cls)
{
- struct GNUNET_TRANSPORT_TESTING_Handle *tth = sender->tth;
- struct TRANSPORT_TESTING_SendJob *sj;
struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cr;
-
+ struct GNUNET_MQ_Envelope *env;
+ struct GNUNET_TRANSPORT_TESTING_TestMessage *test;
+
if (msize < sizeof (struct GNUNET_TRANSPORT_TESTING_TestMessage))
{
GNUNET_break (0);
GNUNET_break (0);
return GNUNET_NO;
}
- sj = GNUNET_new (struct TRANSPORT_TESTING_SendJob);
- sj->num = num;
- sj->sender = sender;
- sj->receiver = receiver;
- sj->cont = cont;
- sj->cont_cls = cont_cls;
- sj->mtype = mtype;
- sj->msize = msize;
- GNUNET_CONTAINER_DLL_insert (tth->sj_head,
- tth->sj_tail,
- sj);
+ if (NULL == cr->mq)
+ {
+ GNUNET_break (0);
+ return GNUNET_NO;
+ }
{
char *receiver_s = GNUNET_strdup (GNUNET_i2s (&receiver->id));
receiver_s);
GNUNET_free (receiver_s);
}
- sj->th = GNUNET_TRANSPORT_notify_transmit_ready (sender->th,
- &receiver->id,
- msize,
- TIMEOUT_TRANSMIT,
- ¬ify_ready,
- sj);
- GNUNET_assert (NULL != sj->th);
+ env = GNUNET_MQ_msg_extra (test,
+ msize - sizeof (*test),
+ mtype);
+ test->num = htonl (num);
+ memset (&test[1],
+ num,
+ msize - sizeof (*test));
+ GNUNET_MQ_notify_sent (env,
+ cont,
+ cont_cls);
+ GNUNET_MQ_send (cr->mq,
+ env);
return GNUNET_OK;
}
}
+static void
+set_mq (void *cls,
+ struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cx)
+{
+ struct GNUNET_MQ_Handle *mq = cls;
+
+ cx->mq = mq;
+}
+
+
static void
set_p2c (void *cls,
struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cx)
}
-static void
+static void *
notify_connect (void *cls,
- const struct GNUNET_PeerIdentity *peer)
+ const struct GNUNET_PeerIdentity *peer,
+ struct GNUNET_MQ_Handle *mq)
{
struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
struct GNUNET_TRANSPORT_TESTING_Handle *tth = p->tth;
struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ccn;
int found;
+ void *ret;
p2 = find_peer_context (p->tth,
peer);
if (NULL != p->nc)
- p->nc (p->cb_cls,
- peer);
+ ret = p->nc (p->cb_cls,
+ peer,
+ mq);
+ else
+ ret = NULL;
if (p2 != NULL)
GNUNET_asprintf (&p2_s,
tth->cc_tail,
cc);
}
+ GNUNET_TRANSPORT_TESTING_find_connecting_context (p,
+ p2,
+ &set_mq,
+ mq);
/* update set connected flag for all requests */
for (cc = tth->cc_head; NULL != cc; cc = cc->next)
{
cc->cb = NULL; /* only notify once! */
}
}
+ return ret;
}
static void
notify_disconnect (void *cls,
- const struct GNUNET_PeerIdentity *peer)
+ const struct GNUNET_PeerIdentity *peer,
+ void *handler_cls)
{
struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
struct GNUNET_TRANSPORT_TESTING_Handle *tth = p->tth;
/* Find PeerContext */
int no = 0;
struct GNUNET_TRANSPORT_TESTING_PeerContext *p2 = NULL;
- struct TRANSPORT_TESTING_SendJob *sj;
- struct TRANSPORT_TESTING_SendJob *sjn;
struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
p2 = find_peer_context (p->tth,
/* notify about disconnect */
if (NULL != p->nd)
p->nd (p->cb_cls,
- peer);
+ peer,
+ handler_cls);
if (NULL == p2)
return;
- /* abort all transmissions this disconnected pair is involved in */
- for (sj = tth->sj_head; NULL != sj; sj = sjn)
- {
- sjn = sj->next;
- if ( ( (sj->sender == p2) &&
- (sj->receiver == p) ) ||
- ( (sj->receiver == p2) &&
- (sj->sender == p) ) )
- {
- GNUNET_CONTAINER_DLL_remove (tth->sj_head,
- tth->sj_tail,
- sj);
- GNUNET_TRANSPORT_notify_transmit_ready_cancel (sj->th);
- GNUNET_free (sj);
- }
- }
+ /* clear MQ, it is now invalid */
+ GNUNET_TRANSPORT_TESTING_find_connecting_context (p,
+ p2,
+ &set_mq,
+ NULL);
/* update set connected flags for all requests */
GNUNET_TRANSPORT_TESTING_find_connecting_context (p,
p2,
}
-static void
-notify_receive (void *cls,
- const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
-
- if (NULL == p)
- return;
- if (NULL != p->rec)
- p->rec (p->cb_cls,
- peer,
- message);
-}
-
-
static void
get_hello (void *cb_cls,
const struct GNUNET_MessageHeader *message)
"Peer %u (`%s') successfully started\n",
p->no,
GNUNET_i2s (&p->id));
- p->start_cb (p,
- p->start_cb_cls);
+ p->start_cb (p->start_cb_cls);
p->start_cb = NULL;
}
}
* @param tth the testing handle
* @param cfgname configuration file
* @param peer_id a unique number to identify the peer
- * @param rec receive callback
+ * @param handlers functions for receiving messages
* @param nc connect callback
* @param nd disconnect callback
* @param cb_cls closure for callback
GNUNET_TRANSPORT_TESTING_start_peer (struct GNUNET_TRANSPORT_TESTING_Handle *tth,
const char *cfgname,
int peer_id,
- GNUNET_TRANSPORT_ReceiveCallback rec,
- GNUNET_TRANSPORT_NotifyConnect nc,
- GNUNET_TRANSPORT_NotifyDisconnect nd,
+ const struct GNUNET_MQ_MessageHandler *handlers,
+ GNUNET_TRANSPORT_NotifyConnecT nc,
+ GNUNET_TRANSPORT_NotifyDisconnecT nd,
void *cb_cls,
- GNUNET_TRANSPORT_TESTING_StartCallback start_cb,
+ GNUNET_SCHEDULER_TaskCallback start_cb,
void *start_cb_cls)
{
char *emsg = NULL;
struct GNUNET_TRANSPORT_TESTING_PeerContext *p;
struct GNUNET_PeerIdentity *dummy;
-
+ unsigned int i;
+
if (GNUNET_NO == GNUNET_DISK_file_test (cfgname))
{
LOG (GNUNET_ERROR_TYPE_ERROR,
p->tth = tth;
p->nc = nc;
p->nd = nd;
- p->rec = rec;
+ if (NULL != handlers)
+ {
+ for (i=0;NULL != handlers[i].cb;i++) ;
+ p->handlers = GNUNET_new_array (i + 1,
+ struct GNUNET_MQ_MessageHandler);
+ GNUNET_memcpy (p->handlers,
+ handlers,
+ i * sizeof (struct GNUNET_MQ_MessageHandler));
+ }
if (NULL != cb_cls)
p->cb_cls = cb_cls;
else
"Peer %u configured with identity `%s'\n",
p->no,
GNUNET_i2s_full (&p->id));
-
- p->th = GNUNET_TRANSPORT_connect (p->cfg,
- NULL,
- p,
- ¬ify_receive,
- ¬ify_connect,
- ¬ify_disconnect);
- if (NULL == p->th)
+ p->tmh = GNUNET_TRANSPORT_manipulation_connect (p->cfg);
+ p->th = GNUNET_TRANSPORT_core_connect (p->cfg,
+ NULL,
+ handlers,
+ p,
+ ¬ify_connect,
+ ¬ify_disconnect,
+ NULL);
+ if ( (NULL == p->th) ||
+ (NULL == p->tmh) )
{
LOG (GNUNET_ERROR_TYPE_ERROR,
"Failed to connect to transport service for peer `%s': `%s'\n",
*/
int
GNUNET_TRANSPORT_TESTING_restart_peer (struct GNUNET_TRANSPORT_TESTING_PeerContext *p,
- GNUNET_TRANSPORT_TESTING_StartCallback restart_cb,
+ GNUNET_SCHEDULER_TaskCallback restart_cb,
void *restart_cb_cls)
{
struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
}
if (NULL != p->th)
{
- GNUNET_TRANSPORT_disconnect (p->th);
+ GNUNET_TRANSPORT_core_disconnect (p->th);
p->th = NULL;
}
+ if (NULL != p->tmh)
+ {
+ GNUNET_TRANSPORT_manipulation_disconnect (p->tmh);
+ p->tmh = NULL;
+ }
for (cc = p->tth->cc_head; NULL != cc; cc = ccn)
{
ccn = cc->next;
p->start_cb = restart_cb;
p->start_cb_cls = restart_cb_cls;
- p->th = GNUNET_TRANSPORT_connect (p->cfg,
- NULL,
- p,
- ¬ify_receive,
- ¬ify_connect,
- ¬ify_disconnect);
+ p->th = GNUNET_TRANSPORT_core_connect (p->cfg,
+ NULL,
+ p->handlers,
+ p,
+ ¬ify_connect,
+ ¬ify_disconnect,
+ NULL);
GNUNET_assert (NULL != p->th);
p->ats = GNUNET_ATS_connectivity_init (p->cfg);
p->ghh = GNUNET_TRANSPORT_get_hello (p->cfg,
GNUNET_TRANSPORT_get_hello_cancel (p->ghh);
p->ghh = NULL;
}
+ if (NULL != p->tmh)
+ {
+ GNUNET_TRANSPORT_manipulation_disconnect (p->tmh);
+ p->tmh = NULL;
+ }
if (NULL != p->th)
{
- GNUNET_TRANSPORT_disconnect (p->th);
+ GNUNET_TRANSPORT_core_disconnect (p->th);
p->th = NULL;
}
if (NULL != p->peer)
#include "gnunet_util_lib.h"
#include "gnunet_hello_lib.h"
#include "gnunet_transport_service.h"
+#include "gnunet_transport_core_service.h"
+#include "gnunet_transport_manipulation_service.h"
#include "gnunet_testing_lib.h"
struct GNUNET_TRANSPORT_TESTING_Handle;
-/**
- * Callback when two peers are connected and both have called the connect callback
- * to notify clients about a new peer
- *
- * @param p FIXME: remove ASAP.
- * @param cls closure
- */
-typedef void
-(*GNUNET_TRANSPORT_TESTING_StartCallback) (struct GNUNET_TRANSPORT_TESTING_PeerContext *p,
- void *cls);
-
-
-
/**
* Context for a single peer
*/
/**
* Peer's transport service handle
*/
- struct GNUNET_TRANSPORT_Handle *th;
+ struct GNUNET_TRANSPORT_CoreHandle *th;
+
+ /**
+ * Peer's transport service manipulation handle
+ */
+ struct GNUNET_TRANSPORT_ManipulationHandle *tmh;
/**
* Peer's ATS handle.
/**
* Receive callback
*/
- GNUNET_TRANSPORT_ReceiveCallback rec;
+ struct GNUNET_MQ_MessageHandler *handlers;
/**
* Notify connect callback
*/
- GNUNET_TRANSPORT_NotifyConnect nc;
+ GNUNET_TRANSPORT_NotifyConnecT nc;
/**
* Notify disconnect callback
*/
- GNUNET_TRANSPORT_NotifyDisconnect nd;
+ GNUNET_TRANSPORT_NotifyDisconnecT nd;
/**
* Startup completed callback
*/
- GNUNET_TRANSPORT_TESTING_StartCallback start_cb;
+ GNUNET_SCHEDULER_TaskCallback start_cb;
/**
* Peers HELLO Message
*/
void *cb_cls;
+ /**
+ * Message queue for sending from @a p1 to @a p2.
+ */
+ struct GNUNET_MQ_Handle *mq;
+
/**
* Set if peer1 says the connection is up to peer2.
*/
};
-/**
- * Information we keep for active transmission jobs.
- */
-struct TRANSPORT_TESTING_SendJob
-{
-
- /**
- * Kept in a DLL.
- */
- struct TRANSPORT_TESTING_SendJob *next;
-
- /**
- * Kept in a DLL.
- */
- struct TRANSPORT_TESTING_SendJob *prev;
-
- /**
- * Sender of the message.
- */
- struct GNUNET_TRANSPORT_TESTING_PeerContext *sender;
-
- /**
- * Receiver of the message.
- */
- struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver;
-
- /**
- * Operation handle.
- */
- struct GNUNET_TRANSPORT_TransmitHandle *th;
-
- /**
- * Function to call upon completion.
- */
- GNUNET_SCHEDULER_TaskCallback cont;
-
- /**
- * Closure for @e cont.
- */
- void *cont_cls;
-
- /**
- * Number of the message.
- */
- uint32_t num;
-
- /**
- * Type of message to send.
- */
- uint16_t mtype;
-
- /**
- * Length of the message.
- */
- uint16_t msize;
-
-};
-
-
/**
* Handle for a test run.
*/
*/
struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc_tail;
- /**
- * Kept in a DLL.
- */
- struct TRANSPORT_TESTING_SendJob *sj_head;
-
- /**
- * Kept in a DLL.
- */
- struct TRANSPORT_TESTING_SendJob *sj_tail;
-
/**
* head DLL of peers
*/
* @param tth the testing handle
* @param cfgname configuration file
* @param peer_id the peer_id
- * @param rec receive callback
+ * @param handlers functions for receiving messages
* @param nc connect callback
* @param nd disconnect callback
* @param cb_cls closure for @a nc and @a nd callback
GNUNET_TRANSPORT_TESTING_start_peer (struct GNUNET_TRANSPORT_TESTING_Handle *tth,
const char *cfgname,
int peer_id,
- GNUNET_TRANSPORT_ReceiveCallback rec,
- GNUNET_TRANSPORT_NotifyConnect nc,
- GNUNET_TRANSPORT_NotifyDisconnect nd,
+ const struct GNUNET_MQ_MessageHandler *handlers,
+ GNUNET_TRANSPORT_NotifyConnecT nc,
+ GNUNET_TRANSPORT_NotifyDisconnecT nd,
void *cb_cls,
- GNUNET_TRANSPORT_TESTING_StartCallback start_cb,
+ GNUNET_SCHEDULER_TaskCallback start_cb,
void *start_cb_cls);
*/
int
GNUNET_TRANSPORT_TESTING_restart_peer (struct GNUNET_TRANSPORT_TESTING_PeerContext *p,
- GNUNET_TRANSPORT_TESTING_StartCallback restart_cb,
+ GNUNET_SCHEDULER_TaskCallback restart_cb,
void *restart_cb_cls);
struct GNUNET_TRANSPORT_TESTING_InternalPeerContext;
+GNUNET_NETWORK_STRUCT_BEGIN
+struct GNUNET_TRANSPORT_TESTING_TestMessage
+{
+ /**
+ * Type is (usually) #GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE.
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Monotonically increasing counter throughout the test.
+ */
+ uint32_t num GNUNET_PACKED;
+};
+GNUNET_NETWORK_STRUCT_END
+
+
+
/**
* Function called by the transport for each received message.
*
(*GNUNET_TRANSPORT_TESTING_ReceiveCallback) (void *cls,
struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message);
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *message);
/**
*/
#define GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE 12345
-GNUNET_NETWORK_STRUCT_BEGIN
-struct GNUNET_TRANSPORT_TESTING_TestMessage
-{
- /**
- * Type is (usually) #GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE.
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * Monotonically increasing counter throughout the test.
- */
- uint32_t num GNUNET_PACKED;
-};
-GNUNET_NETWORK_STRUCT_END
+/**
+ * Alternative message type for tests.
+ */
+#define GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE2 12346
/**
GNUNET_SCHEDULER_cancel (n->timeout_task);
n->timeout_task = NULL;
}
- GNUNET_MQ_destroy (n->mq);
if (NULL != n->env)
{
GNUNET_MQ_send_cancel (n->env);
n->env = NULL;
}
+ GNUNET_MQ_destroy (n->mq);
GNUNET_assert (NULL == n->mq);
GNUNET_assert (GNUNET_YES ==
GNUNET_CONTAINER_multipeermap_remove (handle->neighbours,
GNUNET_MESSAGE_TYPE_TRANSPORT_SEND,
msg);
obm->reserved = htonl (0);
- obm->timeout = GNUNET_TIME_relative_hton (GNUNET_TIME_UNIT_ZERO); /* FIXME: to be removed */
+ obm->timeout = GNUNET_TIME_relative_hton (GNUNET_TIME_UNIT_MINUTES); /* FIXME: to be removed */
obm->peer = n->id;
GNUNET_assert (NULL == n->timeout_task);
n->is_ready = GNUNET_NO;
n);
GNUNET_MQ_send (h->mq,
n->env);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Queued message for neighbour `%s'.\n",
+ GNUNET_i2s (&n->id));
}
const struct GNUNET_MessageHeader *imm;
uint16_t size;
- size = ntohs (im->header.size);
- if (size <
- sizeof (struct InboundMessage) + sizeof (struct GNUNET_MessageHeader))
+ size = ntohs (im->header.size) - sizeof (*im);
+ if (size < sizeof (struct GNUNET_MessageHeader))
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
imm = (const struct GNUNET_MessageHeader *) &im[1];
- if (ntohs (imm->size) + sizeof (struct InboundMessage) != size)
+ if (ntohs (imm->size) != size)
{
GNUNET_break (0);
return GNUNET_SYSERR;
disconnect_and_schedule_reconnect (struct GNUNET_TRANSPORT_CoreHandle *h)
{
GNUNET_assert (NULL == h->reconnect_task);
+ /* Forget about all neighbours that we used to be connected to */
+ GNUNET_CONTAINER_multipeermap_iterate (h->neighbours,
+ &neighbour_delete,
+ h);
if (NULL != h->mq)
{
GNUNET_MQ_destroy (h->mq);
h->mq = NULL;
}
- /* Forget about all neighbours that we used to be connected to */
- GNUNET_CONTAINER_multipeermap_iterate (h->neighbours,
- &neighbour_delete,
- h);
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Scheduling task to reconnect to transport service in %s.\n",
GNUNET_STRINGS_relative_time_to_string (h->reconnect_delay,
* @return NULL on error
*/
struct GNUNET_TRANSPORT_CoreHandle *
-GNUNET_TRANSPORT_connecT (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const struct GNUNET_PeerIdentity *self,
- const struct GNUNET_MQ_MessageHandler *handlers,
- void *cls,
- GNUNET_TRANSPORT_NotifyConnecT nc,
- GNUNET_TRANSPORT_NotifyDisconnecT nd,
- GNUNET_TRANSPORT_NotifyExcessBandwidtH neb)
+GNUNET_TRANSPORT_core_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_PeerIdentity *self,
+ const struct GNUNET_MQ_MessageHandler *handlers,
+ void *cls,
+ GNUNET_TRANSPORT_NotifyConnecT nc,
+ GNUNET_TRANSPORT_NotifyDisconnecT nd,
+ GNUNET_TRANSPORT_NotifyExcessBandwidtH neb)
{
struct GNUNET_TRANSPORT_CoreHandle *h;
unsigned int i;
h->nd_cb = nd;
h->neb_cb = neb;
h->reconnect_delay = GNUNET_TIME_UNIT_ZERO;
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Connecting to transport service.\n");
- reconnect (h);
- if (NULL == h->mq)
- {
- GNUNET_free (h);
- return NULL;
- }
if (NULL != handlers)
{
for (i=0;NULL != handlers[i].cb; i++) ;
h->handlers = GNUNET_new_array (i + 1,
struct GNUNET_MQ_MessageHandler);
GNUNET_memcpy (h->handlers,
- handlers,
- i * sizeof (struct GNUNET_MQ_MessageHandler));
+ handlers,
+ i * sizeof (struct GNUNET_MQ_MessageHandler));
+ }
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Connecting to transport service\n");
+ reconnect (h);
+ if (NULL == h->mq)
+ {
+ GNUNET_free_non_null (h->handlers);
+ GNUNET_free (h);
+ return NULL;
}
h->neighbours =
GNUNET_CONTAINER_multipeermap_create (STARTING_NEIGHBOURS_SIZE,
*/
/**
- * @file transport/transport_api.c
+ * @file transport/transport_api_get_hello.c
* @brief library to obtain our HELLO from our transport service
* @author Christian Grothoff
*/
--- /dev/null
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2009-2013, 2016 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
+ by the Free Software Foundation; either version 3, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @file transport/transport_api_manipulation.c
+ * @brief library to access the low-level P2P IO service
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_constants.h"
+#include "gnunet_arm_service.h"
+#include "gnunet_hello_lib.h"
+#include "gnunet_protocols.h"
+#include "gnunet_transport_service.h"
+#include "transport.h"
+
+#define LOG(kind,...) GNUNET_log_from (kind, "transport-api",__VA_ARGS__)
+
+
+/**
+ * Handle for the transport service (includes all of the
+ * state for the transport service).
+ */
+struct GNUNET_TRANSPORT_ManipulationHandle
+{
+
+ /**
+ * My client connection to the transport service.
+ */
+ struct GNUNET_MQ_Handle *mq;
+
+ /**
+ * My configuration.
+ */
+ const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+ /**
+ * ID of the task trying to reconnect to the service.
+ */
+ struct GNUNET_SCHEDULER_Task *reconnect_task;
+
+ /**
+ * Delay until we try to reconnect.
+ */
+ struct GNUNET_TIME_Relative reconnect_delay;
+
+ /**
+ * Reconnect in progress
+ */
+ int reconnecting;
+};
+
+
+/**
+ * Function that will schedule the job that will try
+ * to connect us again to the client.
+ *
+ * @param h transport service to reconnect
+ */
+static void
+disconnect_and_schedule_reconnect (struct GNUNET_TRANSPORT_ManipulationHandle *h);
+
+
+/**
+ * Generic error handler, called with the appropriate
+ * error code and the same closure specified at the creation of
+ * the message queue.
+ * Not every message queue implementation supports an error handler.
+ *
+ * @param cls closure with the `struct GNUNET_TRANSPORT_ManipulationHandle *`
+ * @param error error code
+ */
+static void
+mq_error_handler (void *cls,
+ enum GNUNET_MQ_Error error)
+{
+ struct GNUNET_TRANSPORT_ManipulationHandle *h = cls;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Error receiving from transport service, disconnecting temporarily.\n");
+ h->reconnecting = GNUNET_YES;
+ disconnect_and_schedule_reconnect (h);
+}
+
+
+/**
+ * Try again to connect to transport service.
+ *
+ * @param cls the handle to the transport service
+ */
+static void
+reconnect (void *cls)
+{
+ struct GNUNET_TRANSPORT_ManipulationHandle *h = cls;
+ struct GNUNET_MQ_MessageHandler handlers[] = {
+ GNUNET_MQ_handler_end ()
+ };
+ struct GNUNET_MQ_Envelope *env;
+ struct StartMessage *s;
+
+ h->reconnect_task = NULL;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Connecting to transport service.\n");
+ GNUNET_assert (NULL == h->mq);
+ h->reconnecting = GNUNET_NO;
+ h->mq = GNUNET_CLIENT_connecT (h->cfg,
+ "transport",
+ handlers,
+ &mq_error_handler,
+ h);
+ if (NULL == h->mq)
+ return;
+ env = GNUNET_MQ_msg (s,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_START);
+ GNUNET_MQ_send (h->mq,
+ env);
+}
+
+
+/**
+ * Function that will schedule the job that will try
+ * to connect us again to the client.
+ *
+ * @param h transport service to reconnect
+ */
+static void
+disconnect_and_schedule_reconnect (struct GNUNET_TRANSPORT_ManipulationHandle *h)
+{
+ GNUNET_assert (NULL == h->reconnect_task);
+ if (NULL != h->mq)
+ {
+ GNUNET_MQ_destroy (h->mq);
+ h->mq = NULL;
+ }
+ h->reconnect_task =
+ GNUNET_SCHEDULER_add_delayed (h->reconnect_delay,
+ &reconnect,
+ h);
+ h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay);
+}
+
+
+/**
+ * Set transport metrics for a peer and a direction.
+ *
+ * @param handle transport handle
+ * @param peer the peer to set the metric for
+ * @param prop the performance metrics to set
+ * @param delay_in inbound delay to introduce
+ * @param delay_out outbound delay to introduce
+ *
+ * Note: Delay restrictions in receiving direction will be enforced
+ * with one message delay.
+ */
+void
+GNUNET_TRANSPORT_manipulation_set (struct GNUNET_TRANSPORT_ManipulationHandle *handle,
+ const struct GNUNET_PeerIdentity *peer,
+ const struct GNUNET_ATS_Properties *prop,
+ struct GNUNET_TIME_Relative delay_in,
+ struct GNUNET_TIME_Relative delay_out)
+{
+ struct GNUNET_MQ_Envelope *env;
+ struct TrafficMetricMessage *msg;
+
+ if (NULL == handle->mq)
+ return;
+ env = GNUNET_MQ_msg (msg,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_TRAFFIC_METRIC);
+ msg->reserved = htonl (0);
+ msg->peer = *peer;
+ GNUNET_ATS_properties_hton (&msg->properties,
+ prop);
+ msg->delay_in = GNUNET_TIME_relative_hton (delay_in);
+ msg->delay_out = GNUNET_TIME_relative_hton (delay_out);
+ GNUNET_MQ_send (handle->mq,
+ env);
+}
+
+
+/**
+ * Connect to the transport service. Note that the connection may
+ * complete (or fail) asynchronously.
+ *
+ * @param cfg configuration to use
+ * @return NULL on error
+ */
+struct GNUNET_TRANSPORT_ManipulationHandle *
+GNUNET_TRANSPORT_manipulation_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ struct GNUNET_TRANSPORT_ManipulationHandle *h;
+
+ h = GNUNET_new (struct GNUNET_TRANSPORT_ManipulationHandle);
+ h->cfg = cfg;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Connecting to transport service.\n");
+ reconnect (h);
+ if (NULL == h->mq)
+ {
+ GNUNET_free (h);
+ return NULL;
+ }
+ return h;
+}
+
+
+/**
+ * Disconnect from the transport service.
+ *
+ * @param handle handle to the service as returned from #GNUNET_TRANSPORT_manipulation_connect()
+ */
+void
+GNUNET_TRANSPORT_manipulation_disconnect (struct GNUNET_TRANSPORT_ManipulationHandle *handle)
+{
+ if (NULL == handle->reconnect_task)
+ disconnect_and_schedule_reconnect (handle);
+ /* and now we stop trying to connect again... */
+ if (NULL != handle->reconnect_task)
+ {
+ GNUNET_SCHEDULER_cancel (handle->reconnect_task);
+ handle->reconnect_task = NULL;
+ }
+ GNUNET_free (handle);
+}
+
+
+/* end of transport_api_manipulation.c */
{
struct ClientConnectionState *state = impl_state;
- GNUNET_assert (NULL != state->th);
- GNUNET_CLIENT_notify_transmit_ready_cancel (state->th);
- state->th = NULL;
+ if (NULL != state->th)
+ {
+ GNUNET_CLIENT_notify_transmit_ready_cancel (state->th);
+ state->th = NULL;
+ }
+ else if (NULL != mq->continue_task)
+ {
+ GNUNET_SCHEDULER_cancel (mq->continue_task);
+ mq->continue_task = NULL;
+ }
+ else
+ GNUNET_assert (0);
}