/*
This file is part of GNUnet.
Copyright (C) 2006, 2009, 2015, 2016 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 <http://www.gnu.org/licenses/>.
*/
/**
* @file transport-testing.c
* @brief testing lib for transport service
* @author Matthias Wachs
* @author Christian Grothoff
*/
#include "transport-testing.h"
#define LOG(kind,...) GNUNET_log_from(kind, "transport-testing", __VA_ARGS__)
static struct GNUNET_TRANSPORT_TESTING_PeerContext *
find_peer_context (struct GNUNET_TRANSPORT_TESTING_Handle *tth,
const struct GNUNET_PeerIdentity *peer)
{
struct GNUNET_TRANSPORT_TESTING_PeerContext *t;
for (t = tth->p_head; NULL != t; t = t->next)
if (0 == memcmp (&t->id,
peer,
sizeof (struct GNUNET_PeerIdentity)))
return t;
return NULL;
}
/**
* Find any connecting context matching the given pair of peers.
*
* @param p1 first peer
* @param p2 second peer
* @param cb function to call
* @param cb_cls closure for @a cb
*/
void
GNUNET_TRANSPORT_TESTING_find_connecting_context (struct GNUNET_TRANSPORT_TESTING_PeerContext *p1,
struct GNUNET_TRANSPORT_TESTING_PeerContext *p2,
GNUNET_TRANSPORT_TESTING_ConnectContextCallback cb,
void *cb_cls)
{
struct GNUNET_TRANSPORT_TESTING_Handle *tth = p1->tth;
struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc;
struct GNUNET_TRANSPORT_TESTING_ConnectRequest *ccn;
for (cc = tth->cc_head; NULL != cc; cc = ccn)
{
ccn = cc->next;
if ( (cc->p1 == p1) &&
(cc->p2 == p2) )
cb (cb_cls,
cc);
}
}
static void
set_p1c (void *cls,
struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cx)
{
int *found = cls;
if (NULL != found)
*found = GNUNET_YES;
cx->p1_c = GNUNET_YES;
}
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)
{
int *found = cls;
if (NULL != found)
*found = GNUNET_YES;
cx->p2_c = GNUNET_YES;
}
static void
clear_p1c (void *cls,
struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cx)
{
int *found = cls;
if (NULL != found)
*found = GNUNET_YES;
cx->p1_c = GNUNET_NO;
}
static void
clear_p2c (void *cls,
struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cx)
{
int *found = cls;
if (NULL != found)
*found = GNUNET_YES;
cx->p2_c = GNUNET_NO;
}
static void *
notify_connect (void *cls,
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;
char *p2_s;
struct GNUNET_TRANSPORT_TESTING_PeerContext *p2;
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)
ret = p->nc (p->cb_cls,
peer,
mq);
else
ret = NULL;
if (NULL != p2)
GNUNET_asprintf (&p2_s,
"%u (`%s')",
p2->no,
GNUNET_i2s (&p2->id));
else
GNUNET_asprintf (&p2_s,
"`%s'",
GNUNET_i2s (peer));
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Peers %s connected to peer %u (`%s')\n",
p2_s,
p->no,
GNUNET_i2s (&p->id));
GNUNET_free (p2_s);
/* update flags in connecting contexts */
found = GNUNET_NO;
GNUNET_TRANSPORT_TESTING_find_connecting_context (p,
p2,
&set_p1c,
&found);
if (GNUNET_NO == found)
{
cc = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_ConnectRequest);
cc->p1 = p;
cc->p2 = p2;
cc->p1_c = GNUNET_YES;
GNUNET_CONTAINER_DLL_insert (tth->cc_head,
tth->cc_tail,
cc);
}
found = GNUNET_NO;
GNUNET_TRANSPORT_TESTING_find_connecting_context (p2,
p,
&set_p2c,
&found);
if (GNUNET_NO == found)
{
cc = GNUNET_new (struct GNUNET_TRANSP