/*
This file is part of GNUnet.
(C) 2006, 2009 Christian Grothoff (and other contributing authors)
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 2, 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., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
/**
* @file transport-testing.c
* @brief testing lib for transport service
*
* @author Matthias Wachs
*/
#include "transport-testing.h"
#define HOSTKEYFILESIZE 914
static const char *
get_host_key (struct GNUNET_TRANSPORT_TESTING_handle *tth)
{
if (tth->hostkey_data == NULL)
{
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing",
"No precomputed hostkeys available\n");
return NULL;
}
if (tth->hostkeys_total > tth->hostkeys_last)
{
tth->hostkeys_last++;
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing",
"Used hostkey %u of %u available hostkeys\n",
tth->hostkeys_last, tth->hostkeys_total);
return &tth->hostkey_data[(tth->hostkeys_last - 1) * HOSTKEYFILESIZE];
}
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing",
"No hostkey available (%u of %u already used)\n",
tth->hostkeys_last, tth->hostkeys_total);
return NULL;
}
static struct PeerContext *
find_peer_context (struct GNUNET_TRANSPORT_TESTING_handle *tth,
const struct GNUNET_PeerIdentity *peer)
{
GNUNET_assert (tth != NULL);
struct PeerContext *t = tth->p_head;
while (t != NULL)
{
if (0 == memcmp (&t->id, peer, sizeof (struct GNUNET_PeerIdentity)))
break;
t = t->next;
}
return t;
}
struct ConnectingContext *
find_connecting_context (struct GNUNET_TRANSPORT_TESTING_handle *tth,
struct PeerContext *p1, struct PeerContext *p2)
{
GNUNET_assert (tth != NULL);
struct ConnectingContext *cc = tth->cc_head;
while (cc != NULL)
{
if ((cc->p1 == p1) && (cc->p2 == p2))
break;
if ((cc->p1 == p2) && (cc->p2 == p1))
break;
cc = cc->next;
}
return cc;
}
static void
notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer,
const struct GNUNET_ATS_Information *ats, uint32_t ats_count)
{
struct PeerContext *p = cls;
/* Find PeerContext */
GNUNET_assert (p != 0);
GNUNET_assert (p->tth != NULL);
struct PeerContext *p2 = find_peer_context (p->tth, peer);
if (p == NULL)
return;
if (p->nc != NULL)
p->nc (p->cb_cls, peer, ats, ats_count);
char *p2_s;
if (p2 != NULL)
GNUNET_asprintf (&p2_s, "%u (`%s')", p2->no, GNUNET_i2s (&p2->id));
else
GNUNET_asprintf (&p2_s, "`%s'", GNUNET_i2s (peer));
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing",
"Peers %s connected to peer %u (`%s')\n", p2_s, p->no,
GNUNET_i2s (&p->id));
GNUNET_free (p2_s);
/* Find ConnectingContext */
struct ConnectingContext *cc = find_connecting_context (p->tth, p, p2);
if (cc == NULL)
return;
if (p == cc->p1)
cc->p1_c = GNUNET_YES;
if (p == cc->p2)
cc->p2_c = GNUNET_YES;
if ((cc->p1_c == GNUNET_YES) && (cc->p2_c == GNUNET_YES))
{
cc->cb (cc->p1, cc->p2, cc->cb_cls);
GNUNET_TRANSPORT_TESTING_connect_peers_cancel (p->tth, cc);
}
}
static void
notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
{
struct PeerContext *p = cls;
/* Find PeerContext */
int no = 0;
struct PeerContext *p2 = NULL;
if (p != NULL)
{
GNUNET_assert (p->tth != NULL);
p2 = find_peer_context (p->tth, peer);
no = p->no;
}
char *p2_s;
if (p2 != NULL)
GNUNET_asprintf (&p2_s, "%u (`%s')", p2->no, GNUNET_i2s (&p2->id));
else
GNUNET_asprintf (&p2_s, "`%s'", GNUNET_i2s (peer));
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing",
"Peers %s disconnected from peer %u (`%s')\n", p2_s, no<