* @brief convenience API for writing testcases for GNUnet
* @author Nathan Evans
* @author Christian Grothoff
- *
*/
#include "platform.h"
#include "gnunet_constants.h"
void *notify_cls;
};
+struct ConnectContext;
+
/**
* Handle to a group of GNUnet peers.
*/
*/
const struct GNUNET_CONFIGURATION_Handle *cfg;
+ struct ConnectContext *cc_head;
+
+ struct ConnectContext *cc_tail;
+
/**
* Function to call on each started daemon.
*/
struct ConnectContext
{
+
+ struct ConnectContext *next;
+
+ struct ConnectContext *prev;
+
/**
* Index of peer to connect second to.
*/
*/
uint32_t second_index;
+ /**
+ * Task associated with the attempt to connect.
+ */
+ GNUNET_SCHEDULER_TaskIdentifier task;
+
+ /**
+ * Context in 'testing.c', to cancel connection attempt.
+ */
+ struct GNUNET_TESTING_ConnectContext *cc;
+
/**
* Higher level topology connection context.
*/
}
#else
if (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_contains (pg->peers[first].
- blacklisted_peers, &hash_second))
+ GNUNET_CONTAINER_multihashmap_contains (pg->
+ peers[first].blacklisted_peers,
+ &hash_second))
{
- GNUNET_CONTAINER_multihashmap_remove_all (pg->peers[first].
- blacklisted_peers, &hash_second);
+ GNUNET_CONTAINER_multihashmap_remove_all (pg->
+ peers[first].blacklisted_peers,
+ &hash_second);
}
if (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_contains (pg->peers[second].
- blacklisted_peers, &hash_first))
+ GNUNET_CONTAINER_multihashmap_contains (pg->
+ peers[second].blacklisted_peers,
+ &hash_first))
{
- GNUNET_CONTAINER_multihashmap_remove_all (pg->peers[second].
- blacklisted_peers, &hash_first);
+ GNUNET_CONTAINER_multihashmap_remove_all (pg->
+ peers[second].blacklisted_peers,
+ &hash_first);
}
#endif
conn_iter = pg->peers[pg_iter].allowed_peers_head;
while (conn_iter != NULL)
{
- GNUNET_CRYPTO_hash_to_enc (&pg->peers[conn_iter->index].daemon->id.
- hashPubKey, &peer_enc);
+ GNUNET_CRYPTO_hash_to_enc (&pg->peers[conn_iter->index].daemon->
+ id.hashPubKey, &peer_enc);
fprintf (temp_friend_handle, "%s\n", (char *) &peer_enc);
conn_iter = conn_iter->next;
}
conn_iter = pg->peers[pg_iter].blacklisted_peers_head;
while (conn_iter != NULL)
{
- GNUNET_CRYPTO_hash_to_enc (&pg->peers[conn_iter->index].daemon->id.
- hashPubKey, &peer_enc);
+ GNUNET_CRYPTO_hash_to_enc (&pg->peers[conn_iter->index].daemon->
+ id.hashPubKey, &peer_enc);
fprintf (temp_file_handle, "%s:%s\n", pos, (char *) &peer_enc);
conn_iter = conn_iter->next;
}
#else
blacklist_ctx.transport = pos;
- (void) GNUNET_CONTAINER_multihashmap_iterate (pg->peers[pg_iter].
- blacklisted_peers,
+ (void) GNUNET_CONTAINER_multihashmap_iterate (pg->
+ peers
+ [pg_iter].blacklisted_peers,
&blacklist_file_iterator,
&blacklist_ctx);
#endif
}
/* Forward Declaration */
-static void schedule_connect (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc);
+static void
+schedule_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
/**
* Choose a random peer's next connection to create, and
* call schedule_connect to set up the connect task.
*
- * @param ct_ctx the overall connection context
+ * @param pg the peer group to connect
*/
static void
preschedule_connect (struct GNUNET_TESTING_PeerGroup *pg)
connect_context->first_index = random_peer;
connect_context->second_index = connection_iter->index;
connect_context->ct_ctx = ct_ctx;
- GNUNET_SCHEDULER_add_now (&schedule_connect, connect_context);
+ connect_context->task =
+ GNUNET_SCHEDULER_add_now (&schedule_connect, connect_context);
+ GNUNET_CONTAINER_DLL_insert (pg->cc_head, pg->cc_tail, connect_context);
GNUNET_CONTAINER_DLL_remove (pg->peers[random_peer].connect_peers_head,
pg->peers[random_peer].connect_peers_tail,
connection_iter);
#if USE_SEND_HELLOS
/* Forward declaration */
-static void schedule_send_hellos (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext
- *tc);
+static void
+schedule_send_hellos (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
/**
* Close connections and free the hello context.
conn = send_hello_context->peer->connect_peers_head;
while (conn != NULL)
{
- GNUNET_CORE_peer_request_connect (send_hello_context->peer->daemon->
- server,
- &send_hello_context->pg->peers[conn->
- index].
- daemon->id, NULL, NULL);
+ GNUNET_CORE_peer_request_connect (send_hello_context->peer->
+ daemon->server,
+ &send_hello_context->pg->
+ peers[conn->index].daemon->id, NULL,
+ NULL);
conn = conn->next;
}
send_hello_context->core_connect_task =
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide
- (send_hello_context->pg->ct_ctx.
- connect_timeout,
- send_hello_context->pg->ct_ctx.
- connect_attempts),
+ (send_hello_context->pg->
+ ct_ctx.connect_timeout,
+ send_hello_context->pg->
+ ct_ctx.connect_attempts),
&send_core_connect_requests,
send_hello_context);
}
GNUNET_assert (send_hello_context->peer->daemon->th != NULL);
GNUNET_TRANSPORT_disconnect (send_hello_context->peer->daemon->th);
send_hello_context->peer->daemon->th = NULL;
-
- /*if (send_hello_context->pg->remaining_hellos == 0)
- * {
- * for (pg_iter = 0; pg_iter < send_hello_context->pg->max_outstanding_connections; pg_iter++)
- * {
- * preschedule_connect(&send_hello_context->pg->ct_ctx);
- * }
- * }
- */
GNUNET_assert (send_hello_context->peer->daemon->server == NULL);
send_hello_context->peer->daemon->server =
GNUNET_CORE_connect (send_hello_context->peer->cfg, 1,
send_hello_context->core_connect_task =
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide
- (send_hello_context->pg->ct_ctx.
- connect_timeout,
- send_hello_context->pg->ct_ctx.
- connect_attempts),
+ (send_hello_context->pg->
+ ct_ctx.connect_timeout,
+ send_hello_context->pg->
+ ct_ctx.connect_attempts),
&send_core_connect_requests,
send_hello_context);
}
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
_("Offering Hello of peer %s to peer %s\n"),
send_hello_context->peer->daemon->shortname,
- pg->peers[send_hello_context->peer_pos->index].daemon->
- shortname);
+ pg->peers[send_hello_context->peer_pos->index].
+ daemon->shortname);
#endif
GNUNET_TRANSPORT_offer_hello (send_hello_context->peer->daemon->th,
- (const struct GNUNET_MessageHeader *) pg->
- peers[send_hello_context->peer_pos->index].
- daemon->hello, &hello_sent_callback,
- send_hello_context);
+ (const struct GNUNET_MessageHeader *)
+ pg->peers[send_hello_context->peer_pos->
+ index].daemon->hello,
+ &hello_sent_callback, send_hello_context);
send_hello_context->peer_pos = send_hello_context->peer_pos->next;
GNUNET_assert (send_hello_context->peer->daemon->th != NULL);
}
struct GNUNET_TESTING_PeerGroup *pg = ct_ctx->pg;
struct PeerConnection *connection;
+ GNUNET_assert (NULL != connect_ctx->cc);
+ connect_ctx->cc = NULL;
GNUNET_assert (0 < pg->outstanding_connects);
pg->outstanding_connects--;
-
+ GNUNET_CONTAINER_DLL_remove (pg->cc_head, pg->cc_tail, connect_ctx);
/*
* Check whether the inverse connection has been scheduled yet,
* if not, we can remove it from the other peers list and avoid
(0 !=
memcmp (first, &pg->peers[connection->index].daemon->id,
sizeof (struct GNUNET_PeerIdentity))))
- {
connection = connection->next;
- }
if (connection != NULL) /* Can safely remove! */
{
second_cfg, first_cfg, second_daemon, first_daemon,
emsg);
- GNUNET_CONTAINER_DLL_remove (pg->peers[connect_ctx->second_index].
- connect_peers_head,
- pg->peers[connect_ctx->second_index].
- connect_peers_tail, connection);
+ GNUNET_CONTAINER_DLL_remove (pg->
+ peers[connect_ctx->
+ second_index].connect_peers_head,
+ pg->peers[connect_ctx->
+ second_index].connect_peers_tail,
+ connection);
GNUNET_free (connection);
}
pg->notify_connection (pg->notify_connection_cls, first, second, distance,
first_cfg, second_cfg, first_daemon, second_daemon,
emsg);
-
GNUNET_free (connect_ctx);
}
struct ConnectContext *connect_context = cls;
struct GNUNET_TESTING_PeerGroup *pg = connect_context->ct_ctx->pg;
+ connect_context->task = GNUNET_SCHEDULER_NO_TASK;
if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
return;
_
("Delaying connect, we have too many outstanding connections!\n"));
#endif
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
- (GNUNET_TIME_UNIT_MILLISECONDS, 100),
- &schedule_connect, connect_context);
+ connect_context->task =
+ GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
+ (GNUNET_TIME_UNIT_MILLISECONDS, 100),
+ &schedule_connect, connect_context);
+ return;
}
- else
- {
#if VERBOSE_TESTING
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- _
- ("Creating connection, outstanding_connections is %d (max %d)\n"),
- pg->outstanding_connects, pg->max_outstanding_connections);
-#endif
- pg->outstanding_connects++;
- pg->total_connects_scheduled++;
- GNUNET_TESTING_daemons_connect (pg->peers[connect_context->first_index].
- daemon,
- pg->peers[connect_context->second_index].
- daemon,
- connect_context->ct_ctx->connect_timeout,
- connect_context->ct_ctx->connect_attempts,
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _
+ ("Creating connection, outstanding_connections is %d (max %d)\n"),
+ pg->outstanding_connects, pg->max_outstanding_connections);
+#endif
+ pg->outstanding_connects++;
+ pg->total_connects_scheduled++;
+ GNUNET_assert (NULL == connect_context->cc);
+ connect_context->cc =
+ GNUNET_TESTING_daemons_connect (pg->
+ peers[connect_context->
+ first_index].daemon,
+ pg->peers[connect_context->
+ second_index].daemon,
+ connect_context->ct_ctx->connect_timeout,
+ connect_context->ct_ctx->connect_attempts,
#if USE_SEND_HELLOS
- GNUNET_NO,
+ GNUNET_NO,
#else
- GNUNET_YES,
+ GNUNET_YES,
#endif
- &internal_connect_notify, connect_context); /* FIXME: free connect context! */
- }
+ &internal_connect_notify,
+ connect_context);
+
}
#if !OLD
connect_context->first = first->daemon;
connect_context->second = second;
connect_context->ct_ctx = ct_ctx;
- GNUNET_SCHEDULER_add_now (&schedule_connect, connect_context);
-
+ connect_context->task =
+ GNUNET_SCHEDULER_add_now (&schedule_connect, connect_context);
+ GNUNET_CONTAINER_DLL_insert (ct_ctx->pg->cc_head, ct_ctx->pg->cc_tail,
+ connect_context);
return GNUNET_YES;
}
#endif
if (random_number < random_ctx->percentage)
{
GNUNET_assert (GNUNET_OK ==
- GNUNET_CONTAINER_multihashmap_put (random_ctx->first->
- connect_peers_working_set,
+ GNUNET_CONTAINER_multihashmap_put (random_ctx->
+ first->connect_peers_working_set,
key, value,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
}
hash_from_uid (random_ctx->first_uid, &first_hash);
GNUNET_assert (random_ctx->pg->total > second_pos);
GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_remove (random_ctx->pg->
- peers[second_pos].
- connect_peers,
+ GNUNET_CONTAINER_multihashmap_remove (random_ctx->
+ pg->peers
+ [second_pos].connect_peers,
&first_hash,
- random_ctx->first->
- daemon));
+ random_ctx->
+ first->daemon));
return GNUNET_YES;
}
if (min_ctx->pg_array[i] == min_ctx->current)
{
GNUNET_assert (GNUNET_OK ==
- GNUNET_CONTAINER_multihashmap_put (min_ctx->first->
- connect_peers_working_set,
+ GNUNET_CONTAINER_multihashmap_put (min_ctx->
+ first->connect_peers_working_set,
key, value,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
uid_from_hash (key, &second_pos);
hash_from_uid (min_ctx->first_uid, &first_hash);
GNUNET_assert (min_ctx->pg->total > second_pos);
GNUNET_assert (GNUNET_OK ==
- GNUNET_CONTAINER_multihashmap_put (min_ctx->pg->
- peers[second_pos].
- connect_peers_working_set,
+ GNUNET_CONTAINER_multihashmap_put (min_ctx->
+ pg->peers
+ [second_pos].connect_peers_working_set,
&first_hash,
- min_ctx->
- first->daemon,
+ min_ctx->first->
+ daemon,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
/* Now we have added this particular connection, remove it from the second peer's map so it's not double counted */
GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_remove (min_ctx->pg->
- peers[second_pos].
- connect_peers,
+ GNUNET_CONTAINER_multihashmap_remove (min_ctx->
+ pg->peers
+ [second_pos].connect_peers,
&first_hash,
- min_ctx->first->
- daemon));
+ min_ctx->
+ first->daemon));
}
}
min_ctx->current++;
if (dfs_ctx->current == dfs_ctx->chosen)
{
GNUNET_assert (GNUNET_OK ==
- GNUNET_CONTAINER_multihashmap_put (dfs_ctx->first->
- connect_peers_working_set,
+ GNUNET_CONTAINER_multihashmap_put (dfs_ctx->
+ first->connect_peers_working_set,
key, value,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
uid_from_hash (key, &dfs_ctx->second_uid);
hash_from_uid (dfs_ctx->first_uid, &first_hash);
GNUNET_assert (GNUNET_OK ==
- GNUNET_CONTAINER_multihashmap_put (dfs_ctx->pg->
- peers
- [dfs_ctx->second_uid].
- connect_peers_working_set,
+ GNUNET_CONTAINER_multihashmap_put (dfs_ctx->
+ pg->peers[dfs_ctx->
+ second_uid].connect_peers_working_set,
&first_hash,
dfs_ctx->first->daemon,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_remove (dfs_ctx->pg->
- peers[dfs_ctx->
- second_uid].
- connect_peers,
+ GNUNET_CONTAINER_multihashmap_remove (dfs_ctx->
+ pg->peers
+ [dfs_ctx->second_uid].connect_peers,
&first_hash,
- dfs_ctx->first->
- daemon));
+ dfs_ctx->
+ first->daemon));
/* Can't remove second from first yet because we are currently iterating, hence the return value in the DFSContext! */
return GNUNET_NO; /* We have found our peer, don't iterate more */
}
}
#else
count +=
- GNUNET_CONTAINER_multihashmap_size (pg->peers[pg_iter].
- connect_peers_working_set);
+ GNUNET_CONTAINER_multihashmap_size (pg->
+ peers
+ [pg_iter].connect_peers_working_set);
#endif
}
minimum_ctx.first_uid = pg_iter;
minimum_ctx.pg_array =
GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK,
- GNUNET_CONTAINER_multihashmap_size (pg->
- peers
- [pg_iter].
- connect_peers));
+ GNUNET_CONTAINER_multihashmap_size
+ (pg->peers[pg_iter].connect_peers));
minimum_ctx.first = &pg->peers[pg_iter];
minimum_ctx.pg = pg;
minimum_ctx.num_to_add = num;
&closest_ctx->curr_peer->daemon->id.hashPubKey) >
closest_ctx->closest_dist)) &&
(GNUNET_YES !=
- GNUNET_CONTAINER_multihashmap_contains (closest_ctx->curr_peer->
- connect_peers, key)))
+ GNUNET_CONTAINER_multihashmap_contains (closest_ctx->
+ curr_peer->connect_peers, key)))
{
closest_ctx->closest_dist =
GNUNET_CRYPTO_hash_matching_bits (&daemon->id.hashPubKey,
- &closest_ctx->curr_peer->daemon->id.
- hashPubKey);
+ &closest_ctx->curr_peer->daemon->
+ id.hashPubKey);
closest_ctx->closest = daemon;
uid_from_hash (key, &closest_ctx->closest_num);
}
for (pg_iter = 0; pg_iter < pg->total; pg_iter++)
{
temp_count =
- count_connections (pg->peers[pg_iter].
- connect_peers_working_set_head);
+ count_connections (pg->
+ peers[pg_iter].connect_peers_working_set_head);
if (temp_count < least_connections)
{
starting_peer = pg_iter;
{
starting_peer = pg_iter;
least_connections =
- GNUNET_CONTAINER_multihashmap_size (pg->peers[pg_iter].
- connect_peers_working_set);
+ GNUNET_CONTAINER_multihashmap_size (pg->
+ peers
+ [pg_iter].connect_peers_working_set);
}
}
}
/* Choose a random peer from the chosen peers set of connections to add */
dfs_ctx.chosen =
GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
- GNUNET_CONTAINER_multihashmap_size (pg->
- peers
- [starting_peer].
- connect_peers));
+ GNUNET_CONTAINER_multihashmap_size (pg->peers
+ [starting_peer].connect_peers));
dfs_ctx.first_uid = starting_peer;
dfs_ctx.first = &pg->peers[starting_peer];
dfs_ctx.pg = pg;
dfs_ctx.current = 0;
- GNUNET_CONTAINER_multihashmap_iterate (pg->peers[starting_peer].
- connect_peers, &dfs_connect_iterator,
- &dfs_ctx);
+ GNUNET_CONTAINER_multihashmap_iterate (pg->
+ peers[starting_peer].connect_peers,
+ &dfs_connect_iterator, &dfs_ctx);
/* Remove the second from the first, since we will be continuing the search and may encounter the first peer again! */
hash_from_uid (dfs_ctx.second_uid, &second_hash);
GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_remove (pg->
- peers[starting_peer].
- connect_peers,
+ GNUNET_CONTAINER_multihashmap_remove (pg->peers
+ [starting_peer].connect_peers,
&second_hash,
- pg->peers[dfs_ctx.
- second_uid].
- daemon));
+ pg->
+ peers
+ [dfs_ctx.second_uid].daemon));
starting_peer = dfs_ctx.second_uid;
}
{
if (startup_ctx->churn_ctx->service != NULL)
GNUNET_TESTING_daemon_start_stopped_service (peer_restart_ctx->daemon,
- startup_ctx->churn_ctx->
- service,
+ startup_ctx->
+ churn_ctx->service,
startup_ctx->timeout,
&churn_start_callback,
startup_ctx);
for (i = 0; i < pg->total; i++)
{
if (pg->peers[i].internal_context.hostkey_callback != NULL)
- pg->peers[i].internal_context.hostkey_callback (pg->
- peers[i].internal_context.
- hostkey_cls,
+ pg->peers[i].internal_context.hostkey_callback (pg->peers[i].
+ internal_context.hostkey_cls,
&pg->peers[i].daemon->id,
pg->peers[i].daemon,
NULL);
struct PeerConnection *conn_iter;
struct PeerConnection *temp_conn;
#endif
+ struct ConnectContext *cc;
GNUNET_assert (pg->total > 0);
+ while (NULL != (cc = pg->cc_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (pg->cc_head, pg->cc_tail, cc);
+ if (GNUNET_SCHEDULER_NO_TASK != cc->task)
+ GNUNET_SCHEDULER_cancel (cc->task);
+ if (NULL != cc->cc)
+ GNUNET_TESTING_daemons_connect_cancel (cc->cc);
+ GNUNET_free (cc);
+ }
shutdown_ctx = GNUNET_malloc (sizeof (struct ShutdownContext));
shutdown_ctx->delete_files =
shutdown_ctx->total_peers = pg->total;
shutdown_ctx->timeout = timeout;
shutdown_ctx->pg = pg;
- /* shtudown_ctx->outstanding = 0; */
for (off = 0; off < pg->total; off++)
{