[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r11782 - gnunet/src/dv
From: |
gnunet |
Subject: |
[GNUnet-SVN] r11782 - gnunet/src/dv |
Date: |
Thu, 17 Jun 2010 17:27:20 +0200 |
Author: nevans
Date: 2010-06-17 17:27:19 +0200 (Thu, 17 Jun 2010)
New Revision: 11782
Modified:
gnunet/src/dv/dv.h
gnunet/src/dv/dv_api.c
gnunet/src/dv/gnunet-service-dv.c
gnunet/src/dv/plugin_transport_dv.c
gnunet/src/dv/test_transport_api_data.conf
gnunet/src/dv/test_transport_api_dv.c
Log:
working distance vector transport plugin implementation. after spending days
on it I think the problem (not all peers connect all the time) either lies in
core, or is related to latency
Modified: gnunet/src/dv/dv.h
===================================================================
--- gnunet/src/dv/dv.h 2010-06-17 13:25:59 UTC (rev 11781)
+++ gnunet/src/dv/dv.h 2010-06-17 15:27:19 UTC (rev 11782)
@@ -29,10 +29,12 @@
#include "gnunet_common.h"
#define DEBUG_DV_GOSSIP GNUNET_NO
-#define DEBUG_DV_GOSSIP_SEND GNUNET_YES
-#define DEBUG_DV_GOSSIP_RECEIPT GNUNET_YES
+#define DEBUG_DV_GOSSIP_SEND GNUNET_NO
+#define DEBUG_DV_GOSSIP_RECEIPT GNUNET_NO
+#define DEBUG_DV_MESSAGES GNUNET_NO
#define DEBUG_DV GNUNET_NO
-#define DEBUG_DV_API GNUNET_YES
+#define DEBUG_DV_PEER_NUMBERS GNUNET_NO
+#define DEBUG_MESSAGE_DROP GNUNET_YES
typedef void (*GNUNET_DV_MessageReceivedHandler) (void *cls,
struct GNUNET_PeerIdentity
*sender,
@@ -238,6 +240,13 @@
*/
unsigned int recipient GNUNET_PACKED;
+#if TRACK_MESSAGES
+ /**
+ * Unique ID for this message.
+ */
+ unsigned int uid GNUNET_PACKED;
+#endif
+
} p2p_dv_MESSAGE_Data;
/**
Modified: gnunet/src/dv/dv_api.c
===================================================================
--- gnunet/src/dv/dv_api.c 2010-06-17 13:25:59 UTC (rev 11781)
+++ gnunet/src/dv/dv_api.c 2010-06-17 15:27:19 UTC (rev 11782)
@@ -456,10 +456,13 @@
struct SendCallbackContext *send_ctx;
char *end_of_message;
GNUNET_HashCode uidhash;
-#if DEBUG_DV
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV SEND called with message of size %d,
address size %d, total size to send is %d\n", msgbuf_size, addrlen,
sizeof(struct GNUNET_DV_SendMessage) + msgbuf_size + addrlen);
-#endif
+#if DEBUG_DV_MESSAGES
+ dv_handle->uid_gen = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG,
UINT32_MAX);
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "GNUNET_DV_send called with message of
size %d, address size %d, total size %d, uid %u\n", msgbuf_size, addrlen,
sizeof(struct GNUNET_DV_SendMessage) + msgbuf_size + addrlen,
dv_handle->uid_gen);
+#else
dv_handle->uid_gen++;
+#endif
+
msg = GNUNET_malloc(sizeof(struct GNUNET_DV_SendMessage) + addrlen +
msgbuf_size);
msg->header.size = htons(sizeof(struct GNUNET_DV_SendMessage) + addrlen +
msgbuf_size);
msg->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND);
@@ -474,17 +477,11 @@
end_of_message = &end_of_message[addrlen];
memcpy(end_of_message, msgbuf, msgbuf_size);
add_pending(dv_handle, msg);
-
send_ctx = GNUNET_malloc(sizeof(struct SendCallbackContext));
-
send_ctx->cont = cont;
-
send_ctx->cont_cls = cont_cls;
memcpy(&send_ctx->target, target, sizeof(struct GNUNET_PeerIdentity));
-
hash_from_uid(dv_handle->uid_gen, &uidhash);
-
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "set uid of %u or %u, hash of %s
!!!!\n", dv_handle->uid_gen, htonl(dv_handle->uid_gen), GNUNET_h2s(&uidhash));
GNUNET_CONTAINER_multihashmap_put(dv_handle->send_callbacks, &uidhash,
send_ctx, GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
return GNUNET_OK;
Modified: gnunet/src/dv/gnunet-service-dv.c
===================================================================
--- gnunet/src/dv/gnunet-service-dv.c 2010-06-17 13:25:59 UTC (rev 11781)
+++ gnunet/src/dv/gnunet-service-dv.c 2010-06-17 15:27:19 UTC (rev 11782)
@@ -45,8 +45,14 @@
#include "gnunet_crypto_lib.h"
#include "dv.h"
-#define DEBUG_DV_PEER_NUMBERS GNUNET_YES
+/**
+ * For testing mostly, remember only the
+ * shortest path to a distant neighbor.
+ */
+#define AT_MOST_ONE GNUNET_YES
+#define USE_PEER_ID GNUNET_YES
+
/**
* DV Service Context stuff goes here...
*/
@@ -75,12 +81,12 @@
* How often do we check about sending out more peer information (if
* we are connected to no peers previously).
*/
-#define GNUNET_DV_DEFAULT_SEND_INTERVAL
GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 50000)
+#define GNUNET_DV_DEFAULT_SEND_INTERVAL
GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 500000)
/**
* How long do we wait at most between sending out information?
*/
-#define GNUNET_DV_MAX_SEND_INTERVAL
GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 50000)
+#define GNUNET_DV_MAX_SEND_INTERVAL
GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 500000)
/**
* How long can we have not heard from a peer and
@@ -154,7 +160,9 @@
static size_t default_dv_priority = 0;
+char *my_short_id;
+
/**
* Linked list of messages to send to clients.
*/
@@ -170,8 +178,32 @@
*/
struct PendingMessage *prev;
+ /**
+ * The PeerIdentity to send to
+ */
+ struct GNUNET_PeerIdentity recipient;
+
+ /**
+ * The result of message sending.
+ */
struct GNUNET_DV_SendResultMessage *send_result;
+
/**
+ * Message importance level.
+ */
+ unsigned int importance;
+
+ /**
+ * Size of message.
+ */
+ unsigned int msg_size;
+
+ /**
+ * How long to wait before sending message.
+ */
+ struct GNUNET_TIME_Relative timeout;
+
+ /**
* Actual message to be sent; // avoid allocation
*/
const struct GNUNET_MessageHeader *msg; // msg = (cast) &pm[1]; // memcpy
(&pm[1], data, len);
@@ -289,6 +321,12 @@
* The time we heard about this peer
*/
struct GNUNET_TIME_Absolute now;
+
+ /**
+ * Peer id this peer uses to refer to neighbor.
+ */
+ unsigned int referrer_peer_id;
+
};
/**
@@ -414,6 +452,11 @@
*/
struct DirectNeighbor *neighbor;
+ /**
+ * The distant neighbor entry for this direct neighbor.
+ */
+ struct DistantNeighbor *distant;
+
};
/**
@@ -530,6 +573,13 @@
struct DistantNeighbor *dest;
};
+struct FindIDContext
+{
+ unsigned int tid;
+ struct GNUNET_PeerIdentity *dest;
+ const struct GNUNET_PeerIdentity *via;
+};
+
struct DisconnectContext
{
/**
@@ -562,7 +612,29 @@
return GNUNET_NO;
}
+
/**
+ * We've been given a target ID based on the random numbers that
+ * we assigned to our DV-neighborhood. Find the entry for the
+ * respective neighbor.
+ */
+static int
+find_specific_id (void *cls,
+ const GNUNET_HashCode *key,
+ void *value)
+{
+ struct FindIDContext *fdc = cls;
+ struct DistantNeighbor *dn = value;
+
+ if (memcmp(&dn->referrer->identity, fdc->via, sizeof(struct
GNUNET_PeerIdentity)) == 0)
+ {
+ fdc->tid = dn->referrer_id;
+ return GNUNET_NO;
+ }
+ return GNUNET_YES;
+}
+
+/**
* Find a distant peer whose referrer_id matches what we're
* looking for. For looking up a peer we've gossipped about
* but is now disconnected. Need to do this because we don't
@@ -765,11 +837,12 @@
core_transmit_handle = NULL;
off = 0;
- while ( (NULL != (reply = core_pending_head)) &&
- (size >= off + (msize = ntohs (reply->msg->size))))
+ reply = core_pending_head;
+ if ( (reply != NULL) &&
+ (size >= (msize = ntohs (reply->msg->size))))
{
#if DEBUG_DV
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "`%s' : transmit_notify (core) called
with size %d\n", "dv service", msize);
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "`%s' : transmit_notify (core)
called with size %d\n", "dv service", msize);
#endif
GNUNET_CONTAINER_DLL_remove (core_pending_head,
core_pending_tail,
@@ -801,6 +874,10 @@
GNUNET_free (reply);
off += msize;
}
+ reply = core_pending_head;
+ if (reply != NULL)
+ core_transmit_handle = GNUNET_CORE_notify_transmit_ready(coreAPI,
reply->importance, reply->timeout, &reply->recipient, reply->msg_size,
&core_transmit_notify, NULL);
+
return off;
}
@@ -809,57 +886,72 @@
* Send a DV data message via DV.
*
* @param sender the original sender of the message
- * @param specific_neighbor the specific DistantNeighbor to use, complete with
referrer!
+ * @param recipient the next hop recipient, may be our direct peer, maybe not
* @param send_context the send context
*/
static int
-send_message_via (const struct GNUNET_PeerIdentity * sender,
- const struct DistantNeighbor * specific_neighbor,
- struct DV_SendContext *send_context)
+send_message_via (const struct GNUNET_PeerIdentity *sender,
+ const struct GNUNET_PeerIdentity *recipient,
+ struct DV_SendContext *send_context)
{
p2p_dv_MESSAGE_Data *toSend;
unsigned int msg_size;
- unsigned int cost;
unsigned int recipient_id;
unsigned int sender_id;
struct DistantNeighbor *source;
struct PendingMessage *pending_message;
+ struct FindIDContext find_context;
#if DEBUG_DV
char shortname[5];
#endif
msg_size = send_context->message_size + sizeof (p2p_dv_MESSAGE_Data);
- if (specific_neighbor == NULL)
+ find_context.dest = send_context->distant_peer;
+ find_context.via = recipient;
+ find_context.tid = 0;
+ //specific_neighbor =
GNUNET_CONTAINER_multihashmap_get(ctx.extended_neighbors,
&send_context->distant_peer->hashPubKey);
+
+ //GNUNET_CONTAINER_multihashmap_iterate(ctx.extended_neighbors,
&find_specific_id, &find_context);
+ GNUNET_CONTAINER_multihashmap_get_multiple (ctx.extended_neighbors,
&send_context->distant_peer->hashPubKey,
+ &find_specific_id,
&find_context);
+
+ if (find_context.tid == 0)
{
+ GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s: find_specific_id failed to
find peer!\n", my_short_id);
/* target unknown to us, drop! */
return GNUNET_SYSERR;
}
- recipient_id = specific_neighbor->referrer_id;
+ recipient_id = find_context.tid;
- source = GNUNET_CONTAINER_multihashmap_get (ctx.extended_neighbors,
- &sender->hashPubKey);
- if (source == NULL)
- {
- if (0 != (memcmp (&my_identity,
+ if (0 == (memcmp (&my_identity,
sender, sizeof (struct GNUNET_PeerIdentity))))
- {
- /* sender unknown to us, drop! */
- return GNUNET_SYSERR;
- }
- sender_id = 0; /* 0 == us */
- }
+ {
+ sender_id = 0;
+ source = GNUNET_CONTAINER_multihashmap_get (ctx.extended_neighbors,
+ &sender->hashPubKey);
+ if (source != NULL)
+ GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s: send_message_via found %s,
myself in extended peer list???\n", my_short_id, GNUNET_i2s(&source->identity));
+ }
else
- {
- /* find out the number that we use when we gossip about
- the sender */
- sender_id = source->our_id;
- }
+ {
+ source = GNUNET_CONTAINER_multihashmap_get (ctx.extended_neighbors,
+ &sender->hashPubKey);
+ if (source == NULL)
+ {
+ /* sender unknown to us, drop! */
+ return GNUNET_SYSERR;
+ }
+ sender_id = source->our_id;
+ }
- cost = specific_neighbor->cost;
pending_message = GNUNET_malloc(sizeof(struct PendingMessage) + msg_size);
pending_message->msg = (struct GNUNET_MessageHeader *)&pending_message[1];
pending_message->send_result = send_context->send_result;
+ memcpy(&pending_message->recipient, recipient, sizeof(struct
GNUNET_PeerIdentity));
+ pending_message->msg_size = msg_size;
+ pending_message->importance = send_context->importance;
+ pending_message->timeout = send_context->timeout;
toSend = (p2p_dv_MESSAGE_Data *)pending_message->msg;
toSend->header.size = htons (msg_size);
toSend->header.type = htons (GNUNET_MESSAGE_TYPE_DV_DATA);
@@ -877,16 +969,55 @@
core_pending_tail,
core_pending_tail,
pending_message);
+
if (core_transmit_handle == NULL)
- core_transmit_handle = GNUNET_CORE_notify_transmit_ready(coreAPI,
send_context->importance, send_context->timeout,
&specific_neighbor->referrer->identity, msg_size, &core_transmit_notify, NULL);
+ core_transmit_handle = GNUNET_CORE_notify_transmit_ready(coreAPI,
send_context->importance, send_context->timeout, recipient, msg_size,
&core_transmit_notify, NULL);
else
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "`%s': Failed to schedule pending
transmission (must be one in progress!)\n", "dv service");
- return (int) cost;
+ return GNUNET_YES;
}
/**
+ * Context for finding the least cost peer to send to.
+ * Transport selection can only go so far.
+ */
+struct FindLeastCostContext
+{
+ struct DistantNeighbor *target;
+ unsigned int least_cost;
+};
+
+
+/**
+ * Given a FindLeastCostContext, and a set
+ * of peers that match the target, return the cheapest.
+ *
+ * @param cls closure, a struct FindLeastCostContext
+ * @param key the key identifying the target peer
+ * @param value the target peer
+ *
+ * @return GNUNET_YES to continue iteration, GNUNET_NO to stop
+ */
+static int
+find_least_cost_peer (void *cls,
+ const GNUNET_HashCode *key,
+ void *value)
+{
+ struct FindLeastCostContext *find_context = cls;
+ struct DistantNeighbor *dn = value;
+
+ if (dn->cost < find_context->least_cost)
+ {
+ find_context->target = dn;
+ }
+ if (dn->cost == DIRECT_NEIGHBOR_COST)
+ return GNUNET_NO;
+ return GNUNET_YES;
+}
+
+/**
* Send a DV data message via DV.
*
* @param recipient the ultimate recipient of this message
@@ -913,11 +1044,26 @@
struct DistantNeighbor *target;
struct DistantNeighbor *source;
struct PendingMessage *pending_message;
-
+ struct FindLeastCostContext find_least_ctx;
+#if DEBUG_DV_PEER_NUMBERS
+ struct GNUNET_CRYPTO_HashAsciiEncoded encPeerFrom;
+ struct GNUNET_CRYPTO_HashAsciiEncoded encPeerTo;
+ struct GNUNET_CRYPTO_HashAsciiEncoded encPeerVia;
+#endif
msg_size = message_size + sizeof (p2p_dv_MESSAGE_Data);
- target = GNUNET_CONTAINER_multihashmap_get (ctx.extended_neighbors,
- &recipient->hashPubKey);
+ find_least_ctx.least_cost = -1;
+ find_least_ctx.target = NULL;
+ /*
+ * Need to find the least cost peer, lest the transport selection keep
+ * picking the same DV route for the same destination which results
+ * in messages looping forever. Relatively cheap, we don't iterate
+ * over all known peers, just those that apply.
+ */
+ GNUNET_CONTAINER_multihashmap_get_multiple (ctx.extended_neighbors,
+ &recipient->hashPubKey,
&find_least_cost_peer, &find_least_ctx);
+ target = find_least_ctx.target;
+
if (target == NULL)
{
/* target unknown to us, drop! */
@@ -944,17 +1090,36 @@
sender_id = source->our_id;
}
+#if DEBUG_DV_PEER_NUMBERS
+ GNUNET_CRYPTO_hash_to_enc (&source->identity.hashPubKey, &encPeerFrom);
+ GNUNET_CRYPTO_hash_to_enc (&target->referrer->identity.hashPubKey,
&encPeerVia);
+ encPeerFrom.encoding[4] = '\0';
+ encPeerVia.encoding[4] = '\0';
+#endif
+ if (0 == memcmp(&source->identity, &target->referrer->identity,
sizeof(struct GNUNET_PeerIdentity)))
+ {
+ return 0;
+ }
+
cost = target->cost;
pending_message = GNUNET_malloc(sizeof(struct PendingMessage) + msg_size);
pending_message->msg = (struct GNUNET_MessageHeader *)&pending_message[1];
pending_message->send_result = NULL;
+ pending_message->importance = importance;
+ pending_message->timeout = timeout;
+ memcpy(&pending_message->recipient, &target->referrer->identity,
sizeof(struct GNUNET_PeerIdentity));
+ pending_message->msg_size = msg_size;
toSend = (p2p_dv_MESSAGE_Data *)pending_message->msg;
toSend->header.size = htons (msg_size);
toSend->header.type = htons (GNUNET_MESSAGE_TYPE_DV_DATA);
toSend->sender = htonl (sender_id);
toSend->recipient = htonl (recipient_id);
+#if DEBUG_DV_PEER_NUMBERS
+ GNUNET_CRYPTO_hash_to_enc (&target->identity.hashPubKey, &encPeerTo);
+ encPeerTo.encoding[4] = '\0';
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s: Sending DATA message. Sender id %u,
source %s, destination %s, via %s\n", GNUNET_i2s(&my_identity), sender_id,
&encPeerFrom, &encPeerTo, &encPeerVia);
+#endif
memcpy (&toSend[1], message, message_size);
-
GNUNET_CONTAINER_DLL_insert_after (core_pending_head,
core_pending_tail,
core_pending_tail,
@@ -964,12 +1129,53 @@
#endif
if (core_transmit_handle == NULL)
core_transmit_handle = GNUNET_CORE_notify_transmit_ready(coreAPI,
importance, timeout, &target->referrer->identity, msg_size,
&core_transmit_notify, NULL);
-
+ else
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s: CORE ALREADY SENDING\n", "DV SEND
MESSAGE", msg_size);
return (int) cost;
}
+#if USE_PEER_ID
+struct CheckPeerContext
+{
+ /**
+ * Peer we found
+ */
+ struct DistantNeighbor *peer;
+ /**
+ * Sender id to search for
+ */
+ unsigned int sender_id;
+};
+
/**
+ * Iterator over hash map entries.
+ *
+ * @param cls closure
+ * @param key current key code
+ * @param value value in the hash map
+ * @return GNUNET_YES if we should continue to
+ * iterate,
+ * GNUNET_NO if not.
+ */
+int checkPeerID (void *cls,
+ const GNUNET_HashCode * key,
+ void *value)
+{
+ struct CheckPeerContext *ctx = cls;
+ struct DistantNeighbor *distant = value;
+
+ if (memcmp(key, &ctx->sender_id, sizeof(unsigned int)) == 0)
+ {
+ ctx->peer = distant;
+ return GNUNET_NO;
+ }
+ return GNUNET_YES;
+
+}
+#endif
+
+/**
* Core handler for dv data messages. Whatever this message
* contains all we really have to do is rip it out of its
* DV layering and give it to our pal the DV plugin to report
@@ -996,6 +1202,13 @@
struct GNUNET_PeerIdentity original_sender;
struct GNUNET_PeerIdentity destination;
struct FindDestinationContext fdc;
+#if USE_PEER_ID
+ struct CheckPeerContext checkPeerCtx;
+#endif
+ char *sender_id;
+
+ char *direct_id;
+
int ret;
size_t packed_message_size;
char *cbuf;
@@ -1003,15 +1216,18 @@
packed_message_size = ntohs(incoming->header.size) -
sizeof(p2p_dv_MESSAGE_Data);
+
#if DEBUG_DV
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%s: Receives %s message size %d, packed message size %d!\n",
"dv", "DV DATA", ntohs(incoming->header.size), packed_message_size);
+ "%s: Receives DATA message from %s size %d, packed size %d!\n",
my_short_id, GNUNET_i2s(peer) , ntohs(incoming->header.size),
packed_message_size);
#endif
+
if (ntohs (incoming->header.size) < sizeof (p2p_dv_MESSAGE_Data) + sizeof
(struct GNUNET_MessageHeader))
{
+
#if DEBUG_DV
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "`%s': Message sizes don't add up, total size %u, expected at
least %u!\n", "dv service", ntohs(incoming->header.size), sizeof
(p2p_dv_MESSAGE_Data) + sizeof (struct GNUNET_MessageHeader));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "`%s': Message sizes don't add up, total size %u, expected at
least %u!\n", "dv service", ntohs(incoming->header.size), sizeof
(p2p_dv_MESSAGE_Data) + sizeof (struct GNUNET_MessageHeader));
#endif
return GNUNET_SYSERR;
}
@@ -1027,16 +1243,48 @@
return GNUNET_OK;
}
sid = ntohl (incoming->sender);
+#if USE_PEER_ID
+ if (sid != 0)
+ {
+ checkPeerCtx.sender_id = sid;
+ checkPeerCtx.peer = NULL;
+ GNUNET_CONTAINER_multihashmap_iterate(ctx.extended_neighbors,
&checkPeerID, &checkPeerCtx);
+ pos = checkPeerCtx.peer;
+ }
+ else
+ {
+ pos = GNUNET_CONTAINER_multihashmap_get (ctx.extended_neighbors,
+ &peer->hashPubKey);
+ }
+#else
pos = dn->referee_head;
while ((NULL != pos) && (pos->referrer_id != sid))
pos = pos->next;
+#endif
if (pos == NULL)
{
-#if DEBUG_DV_PEER_NUMBERS
+ direct_id = GNUNET_strdup(GNUNET_i2s(&dn->identity));
+#if DEBUG_DV
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%s peer %s: unknown sender (%d)!\n", "DV SERVICE",
GNUNET_i2s(&my_identity), ntohl(incoming->sender),
GNUNET_CONTAINER_multihashmap_size (ctx.extended_neighbors));
+ "%s: unknown sender (%u), Message from %s!\n",
GNUNET_i2s(&my_identity), ntohl(incoming->sender), direct_id);
#endif
+ GNUNET_free(direct_id);
+ pos = dn->referee_head;
+ while ((NULL != pos) && (pos->referrer_id != sid))
+ {
+ sender_id = strdup(GNUNET_i2s(&pos->identity));
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "I know sender %u %s\n",
pos->referrer_id, sender_id);
+ GNUNET_free(sender_id);
+ pos = pos->next;
+ }
+
+#if DEBUG_MESSAGE_DROP
+ direct_id = GNUNET_strdup(GNUNET_i2s(&dn->identity));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "%s: DROPPING MESSAGE type %d, unknown sender! Message
immediately from %s!\n", GNUNET_i2s(&my_identity), ntohs(((struct
GNUNET_MessageHeader *)&incoming[1])->type), direct_id);
+ GNUNET_free(direct_id);
+#endif
/* unknown sender */
return GNUNET_OK;
}
@@ -1050,6 +1298,7 @@
while(offset < packed_message_size)
{
packed_message = (struct GNUNET_MessageHeader *)&cbuf[offset];
+
#if DEBUG_DV
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"%s: Receives %s message for me, size %d type %d, cost
%u!\n", "dv", "DV DATA", ntohs(packed_message->size),
ntohs(packed_message->type), pos->cost);
@@ -1059,6 +1308,7 @@
if ( (ntohs (packed_message->type) != GNUNET_MESSAGE_TYPE_DV_GOSSIP)
&&
(ntohs (packed_message->type) != GNUNET_MESSAGE_TYPE_DV_DATA) )
{
+ GNUNET_assert(memcmp(peer, &pos->identity, sizeof(struct
GNUNET_PeerIdentity)) != 0);
send_to_plugin(peer, packed_message, ntohs(packed_message->size),
&pos->identity, pos->cost);
}
offset += ntohs(packed_message->size);
@@ -1087,16 +1337,26 @@
if (fdc.dest == NULL)
{
- return GNUNET_OK;
+#if DEBUG_DV
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "%s: Receives %s message for someone else that we don't know
(id %u)!\n", "dv", "DV DATA", tid);
+#endif
+ return GNUNET_OK;
}
destination = fdc.dest->identity;
if (0 == memcmp (&destination, peer, sizeof (struct GNUNET_PeerIdentity)))
{
/* FIXME: create stat: routing loop-discard! */
-#if DEBUG_DV
+#if DEBUG_DV_PEER_NUMBERS
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "\n\n\nLoopy loo message\n\n\n");
#endif
+
+#if DEBUG_MESSAGE_DROP
+ direct_id = GNUNET_strdup(GNUNET_i2s(&dn->identity));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "%s: DROPPING MESSAGE type %d, routing loop! Message
immediately from %s!\n", GNUNET_i2s(&my_identity), ntohs(((struct
GNUNET_MessageHeader *)&incoming[1])->type), direct_id);
+#endif
return GNUNET_OK;
}
@@ -1109,6 +1369,7 @@
/*ret = send_message (&destination,
&original_sender,
packed_message, DV_PRIORITY, DV_DELAY);*/
+
#if DEBUG_DV
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"%s: Sends message size %d on!\n", "dv", packed_message_size);
@@ -1118,10 +1379,44 @@
if (ret != GNUNET_SYSERR)
return GNUNET_OK;
else
- return GNUNET_SYSERR;
+ {
+#if DEBUG_MESSAGE_DROP
+ direct_id = GNUNET_strdup(GNUNET_i2s(&dn->identity));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "%s: DROPPING MESSAGE type %d, forwarding failed! Message
immediately from %s!\n", GNUNET_i2s(&my_identity), ntohs(((struct
GNUNET_MessageHeader *)&incoming[1])->type), direct_id);
+#endif
+ return GNUNET_SYSERR;
+ }
}
+#if DEBUG_DV
+/**
+ * Iterator over hash map entries.
+ *
+ * @param cls closure (NULL)
+ * @param key current key code
+ * @param value value in the hash map (DistantNeighbor)
+ * @return GNUNET_YES if we should continue to
+ * iterate,
+ * GNUNET_NO if not.
+ */
+int print_neighbors (void *cls,
+ const GNUNET_HashCode * key,
+ void *value)
+{
+ struct DistantNeighbor *distant_neighbor = value;
+ char my_shortname[5];
+ char referrer_shortname[5];
+ memcpy(&my_shortname, GNUNET_i2s(&my_identity), 4);
+ my_shortname[4] = '\0';
+ memcpy(&referrer_shortname,
GNUNET_i2s(&distant_neighbor->referrer->identity), 4);
+ referrer_shortname[4] = '\0';
+ GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "`%s' %s: Peer `%s', distance %d,
referrer `%s' pkey: %s\n", &my_shortname, "DV",
GNUNET_i2s(&distant_neighbor->identity), distant_neighbor->cost,
&referrer_shortname, distant_neighbor->pkey == NULL ? "no" : "yes");
+ return GNUNET_YES;
+}
+#endif
+
/**
* Scheduled task which gossips about known direct peers to other connected
* peers. Will run until called with reason shutdown.
@@ -1149,14 +1444,13 @@
"%s: Called with reason shutdown, shutting down!\n",
GNUNET_i2s(&my_identity));
#endif
- send_context->task = GNUNET_SCHEDULER_NO_TASK;
return;
}
if (send_context->fast_gossip_list_head != NULL)
{
about_list = send_context->fast_gossip_list_head;
- about = send_context->fast_gossip_list_head->about;
+ about = about_list->about;
GNUNET_CONTAINER_DLL_remove(send_context->fast_gossip_list_head,
send_context->fast_gossip_list_tail,
about_list);
@@ -1173,6 +1467,8 @@
* once to get a list of peers to gossip about and gossip them over
time... But then if one goes away
* in the mean time that becomes nasty. For now we'll just assume that
the walking is done
* asynchronously enough to avoid major problems (-;
+ *
+ * NOTE: probably fixed once we decided send rate based on allowed
bandwidth.
*/
about = GNUNET_CONTAINER_heap_walk_get_next (ctx.neighbor_min_heap);
}
@@ -1199,6 +1495,10 @@
#endif
pending_message = GNUNET_malloc(sizeof(struct PendingMessage) +
sizeof(p2p_dv_MESSAGE_NeighborInfo));
pending_message->msg = (struct GNUNET_MessageHeader
*)&pending_message[1];
+ pending_message->importance = default_dv_priority;
+ pending_message->timeout = GNUNET_TIME_relative_get_forever();
+ memcpy(&pending_message->recipient, &to->identity, sizeof(struct
GNUNET_PeerIdentity));
+ pending_message->msg_size = sizeof(p2p_dv_MESSAGE_NeighborInfo);
message = (p2p_dv_MESSAGE_NeighborInfo *)pending_message->msg;
message->header.size = htons (sizeof (p2p_dv_MESSAGE_NeighborInfo));
message->header.type = htons (GNUNET_MESSAGE_TYPE_DV_GOSSIP);
@@ -1221,15 +1521,15 @@
if (send_context->fast_gossip_list_head != NULL) /* If there are other peers
in the fast list, schedule right away */
{
-#if DEBUG_DV
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV SERVICE: still in fast send
mode\n");
+#if DEBUG_DV_PEER_NUMBERS
+ GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "DV SERVICE: still in fast send
mode\n");
#endif
send_context->task = GNUNET_SCHEDULER_add_now(sched,
&neighbor_send_task, send_context);
}
else
{
-#if DEBUG_DV
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV SERVICE: entering slow send
mode\n");
+#if DEBUG_DV_PEER_NUMBERS
+ GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "DV SERVICE: entering slow send
mode\n");
#endif
send_context->task = GNUNET_SCHEDULER_add_delayed(sched,
GNUNET_DV_DEFAULT_SEND_INTERVAL, &neighbor_send_task, send_context);
}
@@ -1263,7 +1563,7 @@
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
-
+#if UNSIMPLER
/**
* Iterate over hash map entries for a distant neighbor,
* if direct neighbor matches context call send message
@@ -1289,6 +1589,7 @@
}
return GNUNET_YES;
}
+#endif
/**
* Service server's handler for message send requests (which come
@@ -1311,6 +1612,7 @@
struct GNUNET_PeerIdentity *direct;
struct GNUNET_MessageHeader *message_buf;
char *temp_pos;
+
int offset;
static struct GNUNET_CRYPTO_HashAsciiEncoded dest_hash;
struct DV_SendContext *send_context;
@@ -1325,8 +1627,10 @@
{
client_handle = client;
/* What should we do in this case, assert fail or just log the warning? */
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+#if DEBUG_DV
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"%s: Setting client handle (was a different client!)!\n",
"dv");
+#endif
}
GNUNET_assert(ntohs(message->size) > sizeof(struct GNUNET_DV_SendMessage));
@@ -1359,10 +1663,11 @@
GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s: asked to send message to
`%s', but address is for `%s'!", "DV SERVICE", GNUNET_i2s(&send_msg->target),
(const char *)&dest_hash.encoding);
}
-#if DEBUG_DV
+
GNUNET_CRYPTO_hash_to_enc (&destination->hashPubKey, &dest_hash); /*
GNUNET_i2s won't properly work, need to hash one ourselves */
dest_hash.encoding[4] = '\0';
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV SEND called with message of size %d
type %d, destination `%s' via `%s'\n", message_size, ntohs(message_buf->type),
(const char *)&dest_hash.encoding, GNUNET_i2s(direct));
+#if DEBUG_DV_MESSAGES
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s DV SEND called with message of size
%d type %d, destination `%s' via `%s'\n", my_short_id, message_size,
ntohs(message_buf->type), (const char *)&dest_hash.encoding,
GNUNET_i2s(direct));
#endif
send_context = GNUNET_malloc(sizeof(struct DV_SendContext));
@@ -1379,8 +1684,7 @@
send_context->message_size = message_size;
send_context->send_result = send_result_msg;
- /* In bizarro world GNUNET_SYSERR indicates that we succeeded */
- if (GNUNET_SYSERR !=
GNUNET_CONTAINER_multihashmap_get_multiple(ctx.extended_neighbors,
&destination->hashPubKey, &send_iterator, send_context))
+ if (send_message_via(&my_identity, direct, send_context) != GNUNET_YES)
{
send_result_msg->result = htons(1);
pending_message = GNUNET_malloc(sizeof(struct PendingMessage) +
sizeof(struct GNUNET_DV_SendResultMessage));
@@ -1404,13 +1708,42 @@
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to queue message
for plugin, must be one in progress already!!\n");
}
}
- GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "DV SEND failed to send message to
destination `%s' via `%s'\n", (const char *)&dest_hash.encoding,
GNUNET_i2s(direct));
+ GNUNET_CRYPTO_hash_to_enc (&destination->hashPubKey, &dest_hash); /*
GNUNET_i2s won't properly work, need to hash one ourselves */
+ dest_hash.encoding[4] = '\0';
+ GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s DV SEND failed to send message
to destination `%s' via `%s'\n", my_short_id, (const char
*)&dest_hash.encoding, GNUNET_i2s(direct));
}
- else
+
+ /* In bizarro world GNUNET_SYSERR indicates that we succeeded */
+#if UNSIMPLER
+ if (GNUNET_SYSERR !=
GNUNET_CONTAINER_multihashmap_get_multiple(ctx.extended_neighbors,
&destination->hashPubKey, &send_iterator, send_context))
{
+ send_result_msg->result = htons(1);
+ pending_message = GNUNET_malloc(sizeof(struct PendingMessage) +
sizeof(struct GNUNET_DV_SendResultMessage));
+ pending_message->msg = (struct GNUNET_MessageHeader
*)&pending_message[1];
+ memcpy(&pending_message[1], send_result_msg, sizeof(struct
GNUNET_DV_SendResultMessage));
+ GNUNET_free(send_result_msg);
+ GNUNET_CONTAINER_DLL_insert_after(plugin_pending_head,
plugin_pending_tail, plugin_pending_tail, pending_message);
+
+ if (client_handle != NULL)
+ {
+ if (plugin_transmit_handle == NULL)
+ {
+ plugin_transmit_handle = GNUNET_SERVER_notify_transmit_ready
(client_handle,
+
sizeof(struct GNUNET_DV_SendResultMessage),
+
GNUNET_TIME_UNIT_FOREVER_REL,
+
&transmit_to_plugin, NULL);
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to queue message
for plugin, must be one in progress already!!\n");
+ }
+ }
+ GNUNET_CRYPTO_hash_to_enc (&destination->hashPubKey, &dest_hash); /*
GNUNET_i2s won't properly work, need to hash one ourselves */
+ dest_hash.encoding[4] = '\0';
+ GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s DV SEND failed to send message
to destination `%s' via `%s'\n", my_short_id, (const char
*)&dest_hash.encoding, GNUNET_i2s(direct));
}
-
+#endif
GNUNET_free(message_buf);
GNUNET_free(send_context);
GNUNET_free(direct);
@@ -1476,7 +1809,7 @@
GNUNET_CONTAINER_heap_remove_node (ctx.neighbor_min_heap, referee->min_loc);
GNUNET_CONTAINER_multihashmap_remove_all (ctx.extended_neighbors,
&referee->identity.hashPubKey);
- GNUNET_free (referee->pkey);
+ GNUNET_free_non_null (referee->pkey);
GNUNET_free (referee);
}
@@ -1533,6 +1866,10 @@
pending_message = GNUNET_malloc(sizeof(struct PendingMessage) +
sizeof(p2p_dv_MESSAGE_Disconnect));
pending_message->msg = (struct GNUNET_MessageHeader *)&pending_message[1];
+ pending_message->importance = default_dv_priority;
+ pending_message->timeout = GNUNET_TIME_relative_get_forever();
+ memcpy(&pending_message->recipient, ¬ify->identity, sizeof(struct
GNUNET_PeerIdentity));
+ pending_message->msg_size = sizeof(p2p_dv_MESSAGE_Disconnect);
disconnect_message = (p2p_dv_MESSAGE_Disconnect *)pending_message->msg;
disconnect_message->header.size = htons (sizeof (p2p_dv_MESSAGE_Disconnect));
disconnect_message->header.type = htons (GNUNET_MESSAGE_TYPE_DV_DISCONNECT);
@@ -1597,6 +1934,7 @@
{
#if DEBUG_DV
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "calling CORE_DISCONNECT\n");
+ GNUNET_CONTAINER_multihashmap_iterate(ctx.extended_neighbors,
&print_neighbors, NULL);
#endif
GNUNET_CONTAINER_multihashmap_iterate(ctx.extended_neighbors,
&free_extended_neighbors, NULL);
GNUNET_CONTAINER_multihashmap_destroy(ctx.extended_neighbors);
@@ -1608,6 +1946,8 @@
GNUNET_CORE_disconnect (coreAPI);
GNUNET_PEERINFO_disconnect(peerinfo_handle);
+
+ GNUNET_free_non_null(my_short_id);
#if DEBUG_DV
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "CORE_DISCONNECT completed\n");
#endif
@@ -1633,9 +1973,12 @@
"%s: Core connection initialized, I am peer: %s\n", "dv",
GNUNET_i2s(identity));
#endif
memcpy(&my_identity, identity, sizeof(struct GNUNET_PeerIdentity));
+ my_short_id = GNUNET_strdup(GNUNET_i2s(&my_identity));
coreAPI = server;
}
+
+#if PKEY_NO_NEIGHBOR_ON_ADD
/**
* Iterator over hash map entries.
*
@@ -1661,6 +2004,7 @@
return GNUNET_YES;
}
+#endif
/**
* Iterator over hash map entries.
@@ -1688,6 +2032,7 @@
update_info->neighbor->min_loc,
update_info->cost);
update_info->neighbor->last_activity = update_info->now;
update_info->neighbor->cost = update_info->cost;
+ update_info->neighbor->referrer_id = update_info->referrer_peer_id;
return GNUNET_NO;
}
@@ -1695,35 +2040,68 @@
}
-#if DEBUG_DV_GOSSIP
/**
- * Iterator over hash map entries.
+ * Iterate over all current direct peers, add DISTANT newly connected
+ * peer to the fast gossip list for that peer so we get DV routing
+ * information out as fast as possible!
*
- * @param cls closure (NULL)
- * @param key current key code
- * @param value value in the hash map (DistantNeighbor)
- * @return GNUNET_YES if we should continue to
- * iterate,
- * GNUNET_NO if not.
+ * @param cls the newly connected neighbor we will gossip about
+ * @param key the hashcode of the peer
+ * @param value the direct neighbor we should gossip to
+ *
+ * @return GNUNET_YES to continue iteration, GNUNET_NO otherwise
*/
-int print_neighbors (void *cls,
- const GNUNET_HashCode * key,
- void *value)
+static int add_distant_all_direct_neighbors (void *cls,
+ const GNUNET_HashCode * key,
+ void *value)
{
- struct DistantNeighbor *distant_neighbor = value;
- char my_shortname[5];
- char referrer_shortname[5];
- memcpy(&my_shortname, GNUNET_i2s(&my_identity), 4);
- my_shortname[4] = '\0';
- memcpy(&referrer_shortname,
GNUNET_i2s(&distant_neighbor->referrer->identity), 4);
- referrer_shortname[4] = '\0';
+ struct DirectNeighbor *direct = (struct DirectNeighbor *)value;
+ struct DistantNeighbor *distant = (struct DistantNeighbor *)cls;
+ struct NeighborSendContext *send_context = direct->send_context;
+ struct FastGossipNeighborList *gossip_entry;
+#if DEBUG_DV
+ char *encPeerAbout;
+ char *encPeerTo;
+#endif
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "`%s' %s: Peer `%s', distance %d,
referrer `%s'\n", &my_shortname, "DV", GNUNET_i2s(&distant_neighbor->identity),
distant_neighbor->cost, &referrer_shortname);
+ if (distant == NULL)
+ {
+ return GNUNET_YES;
+ }
+
+ if (memcmp(&direct->identity, &distant->identity, sizeof(struct
GNUNET_PeerIdentity)) == 0)
+ {
+ return GNUNET_YES; /* Don't gossip to a peer about itself! */
+ }
+
+#if SUPPORT_HIDING
+ if (distant->hidden == GNUNET_YES)
+ return GNUNET_YES; /* This peer should not be gossipped about (hidden) */
+#endif
+ gossip_entry = GNUNET_malloc(sizeof(struct FastGossipNeighborList));
+ gossip_entry->about = distant;
+
+ GNUNET_CONTAINER_DLL_insert_after(send_context->fast_gossip_list_head,
+ send_context->fast_gossip_list_tail,
+ send_context->fast_gossip_list_tail,
+ gossip_entry);
+#if DEBUG_DV
+ encPeerAbout = GNUNET_strdup(GNUNET_i2s(&distant->identity));
+ encPeerTo = GNUNET_strdup(GNUNET_i2s(&direct->identity));
+
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s: Fast send info about peer %s id %u
for directly connected peer %s\n",
+ GNUNET_i2s(&my_identity),
+ encPeerAbout, distant->our_id, encPeerTo);
+ GNUNET_free(encPeerAbout);
+ GNUNET_free(encPeerTo);
+#endif
+ /*if (send_context->task != GNUNET_SCHEDULER_NO_TASK)
+ GNUNET_SCHEDULER_cancel(sched, send_context->task);*/
+
+ send_context->task = GNUNET_SCHEDULER_add_now(sched, &neighbor_send_task,
send_context);
return GNUNET_YES;
}
-#endif
-
/**
* Handles when a peer is either added due to being newly connected
* or having been gossiped about, also called when the cost for a neighbor
@@ -1734,8 +2112,11 @@
* @param referrer_peer_id id to use when sending to 'peer'
* @param referrer if this is a gossiped peer, who did we hear it from?
* @param cost the cost of communicating with this peer via 'referrer'
+ *
+ * @return the added neighbor, the updated neighbor or NULL (neighbor
+ * not added)
*/
-static void
+static struct DistantNeighbor *
addUpdateNeighbor (const struct GNUNET_PeerIdentity * peer, struct
GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pkey,
unsigned int referrer_peer_id,
struct DirectNeighbor *referrer, unsigned int cost)
@@ -1747,6 +2128,7 @@
unsigned int our_id;
#if DEBUG_DV_PEER_NUMBERS
+ char *encAbout;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"%s Received sender id (%u)!\n", "DV SERVICE", referrer_peer_id);
#endif
@@ -1759,13 +2141,24 @@
neighbor_update->cost = cost;
neighbor_update->now = now;
neighbor_update->referrer = referrer;
+ neighbor_update->referrer_peer_id = referrer_peer_id;
-
- our_id = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, RAND_MAX -
1) + 1;
-#if DEBUG_DV_PEER_NUMBERS
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%s Chose NEW id (%u)!\n", "DV SERVICE", our_id);
+ if (neighbor != NULL)
+ {
+#if USE_PEER_ID
+ memcpy(&our_id, &neighbor->identity, sizeof(unsigned int));
+#else
+ our_id = neighbor->our_id;
#endif
+ }
+ else
+ {
+#if USE_PEER_ID
+ memcpy(&our_id, peer, sizeof(unsigned int));
+#else
+ our_id = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG,
RAND_MAX - 1) + 1;
+#endif
+ }
/* Either we do not know this peer, or we already do but via a different
immediate peer */
if ((neighbor == NULL) ||
@@ -1774,13 +2167,32 @@
&update_matching_neighbors,
neighbor_update) !=
GNUNET_SYSERR))
{
+
+#if AT_MOST_ONE
+ if ((neighbor != NULL) && (cost < neighbor->cost)) /* New cost is less
than old, remove old */
+ {
+ distant_neighbor_free(neighbor);
+ }
+ else if ((neighbor != NULL) && (cost >= neighbor->cost)) /* Only allow one
DV connection to each peer */
+ {
+ return NULL;
+ }
+#endif
/* new neighbor! */
if (cost > ctx.fisheye_depth)
{
/* too costly */
GNUNET_free(neighbor_update);
- return;
+ return NULL;
}
+
+#if DEBUG_DV_PEER_NUMBERS
+ encAbout = GNUNET_strdup(GNUNET_i2s(peer));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "%s: %s Chose NEW id (%u) for peer %s!\n",
GNUNET_i2s(&my_identity), "DV SERVICE", our_id, encAbout);
+ GNUNET_free(encAbout);
+#endif
+
if (ctx.max_table_size <=
GNUNET_CONTAINER_multihashmap_size (ctx.extended_neighbors))
{
@@ -1790,7 +2202,7 @@
{
/* new entry most expensive, don't create */
GNUNET_free(neighbor_update);
- return;
+ return NULL;
}
if (max->cost > 1)
{
@@ -1829,6 +2241,7 @@
GNUNET_CONTAINER_multihashmap_put (ctx.extended_neighbors,
&peer->hashPubKey,
neighbor,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+
}
else
{
@@ -1841,8 +2254,9 @@
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"%s: Size of extended_neighbors is %d\n", "dv",
GNUNET_CONTAINER_multihashmap_size(ctx.extended_neighbors));
#endif
+
GNUNET_free(neighbor_update);
-
+ return neighbor;
}
@@ -1921,6 +2335,7 @@
{
distant_neighbor_free(distant);
}
+ distant = referrer->referee_head;
}
return GNUNET_OK;
@@ -1963,7 +2378,7 @@
encPeerAbout = GNUNET_strdup(GNUNET_i2s(&enc_message->neighbor));
encPeerFrom = GNUNET_strdup(GNUNET_i2s(peer));
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%s: Receives %s message from peer %s about peer %s id %u
distance %d!\n", "dv", "DV GOSSIP", encPeerFrom, encPeerAbout,
ntohl(enc_message->neighbor_id), ntohl (enc_message->cost) + 1);
+ "%s: Received %s message from peer %s about peer %s id %u
distance %d!\n", GNUNET_i2s(&my_identity), "DV GOSSIP", encPeerFrom,
encPeerAbout, ntohl(enc_message->neighbor_id), ntohl (enc_message->cost) + 1);
GNUNET_free(encPeerAbout);
GNUNET_free(encPeerFrom);
#endif
@@ -1982,7 +2397,7 @@
memcpy(&hello_context->distant_peer, &enc_message->neighbor, sizeof(struct
GNUNET_PeerIdentity));
hello_context->addresses_to_add = 1;
hello_msg = GNUNET_HELLO_create(&enc_message->pkey, &generate_hello_address,
hello_context);
-
+ GNUNET_assert(memcmp(hello_context->direct_peer,
&hello_context->distant_peer, sizeof(struct GNUNET_PeerIdentity)) != 0);
send_to_plugin(hello_context->direct_peer,
GNUNET_HELLO_get_header(hello_msg), GNUNET_HELLO_size(hello_msg),
&hello_context->distant_peer, ntohl(enc_message->cost) + 1);
GNUNET_free(hello_context);
GNUNET_free(hello_msg);
@@ -2027,57 +2442,7 @@
return GNUNET_YES;
}
-
/**
- * Iterate over all current direct peers, add DISTANT newly connected
- * peer to the fast gossip list for that peer so we get DV routing
- * information out as fast as possible!
- *
- * @param cls the newly connected neighbor we will gossip about
- * @param key the hashcode of the peer
- * @param value the direct neighbor we should gossip to
- *
- * @return GNUNET_YES to continue iteration, GNUNET_NO otherwise
- */
-static int add_distant_all_direct_neighbors (void *cls,
- const GNUNET_HashCode * key,
- void *value)
-{
- struct DirectNeighbor *direct = (struct DirectNeighbor *)value;
- struct DistantNeighbor *distant = (struct DistantNeighbor *)cls;
- struct NeighborSendContext *send_context = direct->send_context;
- struct FastGossipNeighborList *gossip_entry;
-
- if (distant == NULL)
- {
- return GNUNET_YES;
- }
-
- if (memcmp(&direct->identity, &distant->identity, sizeof(struct
GNUNET_PeerIdentity)) == 0)
- {
- return GNUNET_YES; /* Don't gossip to a peer about itself! */
- }
-
-#if SUPPORT_HIDING
- if (distant->hidden == GNUNET_YES)
- return GNUNET_YES; /* This peer should not be gossipped about (hidden) */
-#endif
- gossip_entry = GNUNET_malloc(sizeof(struct FastGossipNeighborList));
- gossip_entry->about = distant;
-
- GNUNET_CONTAINER_DLL_insert_after(send_context->fast_gossip_list_head,
- send_context->fast_gossip_list_tail,
- send_context->fast_gossip_list_tail,
- gossip_entry);
- if (send_context->task != GNUNET_SCHEDULER_NO_TASK)
- GNUNET_SCHEDULER_cancel(sched, send_context->task);
-
- send_context->task = GNUNET_SCHEDULER_add_now(sched, &neighbor_send_task,
send_context);
- return GNUNET_YES;
-}
-
-
-/**
* Iterate over all current direct peers, add newly connected peer
* to the fast gossip list for that peer so we get DV routing
* information out as fast as possible!
@@ -2097,7 +2462,9 @@
struct DistantNeighbor *distant;
struct NeighborSendContext *send_context = direct->send_context;
struct FastGossipNeighborList *gossip_entry;
+ char *direct_id;
+
distant = GNUNET_CONTAINER_multihashmap_get(ctx.extended_neighbors,
&to->identity.hashPubKey);
if (distant == NULL)
{
@@ -2113,6 +2480,11 @@
if (distant->hidden == GNUNET_YES)
return GNUNET_YES; /* This peer should not be gossipped about (hidden) */
#endif
+ direct_id = GNUNET_strdup(GNUNET_i2s(&direct->identity));
+#if DEBUG_DV_GOSSIP
+ GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s: adding peer %s to fast send list
for %s\n", my_short_id, GNUNET_i2s(&distant->identity), direct_id);
+#endif
+ GNUNET_free(direct_id);
gossip_entry = GNUNET_malloc(sizeof(struct FastGossipNeighborList));
gossip_entry->about = distant;
@@ -2124,10 +2496,20 @@
GNUNET_SCHEDULER_cancel(sched, send_context->task);
send_context->task = GNUNET_SCHEDULER_add_now(sched, &neighbor_send_task,
send_context);
+ //tc.reason = GNUNET_SCHEDULER_REASON_TIMEOUT;
+ //neighbor_send_task(send_context, &tc);
return GNUNET_YES;
}
-
+/**
+ * Type of an iterator over the hosts. Note that each
+ * host will be called with each available protocol.
+ *
+ * @param cls closure
+ * @param peer id of the peer, NULL for last call
+ * @param hello hello message for the peer (can be NULL)
+ * @param trust amount of trust we have in the peer
+ */
static void
process_peerinfo (void *cls,
const struct GNUNET_PeerIdentity *peer,
@@ -2135,11 +2517,30 @@
{
struct PeerIteratorContext *peerinfo_iterator = cls;
struct DirectNeighbor *neighbor = peerinfo_iterator->neighbor;
+ struct DistantNeighbor *distant = peerinfo_iterator->distant;
+#if DEBUG_DV_PEER_NUMBERS
+ char *neighbor_pid;
+#endif
+ int sent;
- if ((peer == NULL))/* && (neighbor->pkey == NULL))*/
+ if (peer == NULL) /* && (neighbor->pkey == NULL))*/
{
- /* FIXME: Remove peer! */
- GNUNET_free(peerinfo_iterator);
+ if (distant->pkey == NULL) /* FIXME: Reschedule? */
+ {
+#if DEBUG_DV
+ GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Failed to get peerinfo
information for this peer, retrying!\n");
+#endif
+ peerinfo_iterator->ic = GNUNET_PEERINFO_iterate(peerinfo_handle,
+
&peerinfo_iterator->neighbor->identity,
+ 0,
+
GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3),
+ &process_peerinfo,
+ peerinfo_iterator);
+ }
+ else
+ {
+ GNUNET_free(peerinfo_iterator);
+ }
return;
}
@@ -2148,14 +2549,29 @@
if ((hello != NULL) && (GNUNET_HELLO_get_key (hello, &neighbor->pkey) ==
GNUNET_OK))
{
- GNUNET_CONTAINER_multihashmap_get_multiple(ctx.extended_neighbors,
+ if (distant->pkey == NULL)
+ {
+ distant->pkey = GNUNET_malloc(sizeof(struct
GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
+ memcpy(distant->pkey, &neighbor->pkey, sizeof(struct
GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
+ }
+
+ /* Why do it this way, now we have the distant neighbor! */
+ /*GNUNET_CONTAINER_multihashmap_get_multiple(ctx.extended_neighbors,
&peer->hashPubKey,
&add_pkey_to_extended,
- &neighbor->pkey);
+ &neighbor->pkey);*/
- GNUNET_CONTAINER_multihashmap_iterate (ctx.extended_neighbors,
&add_all_extended_peers, neighbor->send_context);
+ sent = GNUNET_CONTAINER_multihashmap_iterate (ctx.extended_neighbors,
&add_all_extended_peers, neighbor->send_context);
- GNUNET_CONTAINER_multihashmap_iterate (ctx.direct_neighbors,
&add_all_direct_neighbors, neighbor);
+#if DEBUG_DV_PEER_NUMBERS
+ neighbor_pid = GNUNET_strdup(GNUNET_i2s(&neighbor->identity));
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s: Gossipped %d extended peers to
%s\n", GNUNET_i2s(&my_identity), sent, neighbor_pid);
+#endif
+ sent = GNUNET_CONTAINER_multihashmap_iterate (ctx.direct_neighbors,
&add_all_direct_neighbors, neighbor);
+#if DEBUG_DV_PEER_NUMBERS
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s: Gossipped about %s to %d direct
peers\n", GNUNET_i2s(&my_identity), neighbor_pid, sent);
+ GNUNET_free(neighbor_pid);
+#endif
neighbor->send_context->task = GNUNET_SCHEDULER_add_now(sched,
&neighbor_send_task, neighbor->send_context);
}
}
@@ -2177,6 +2593,7 @@
struct DirectNeighbor *neighbor;
struct DistantNeighbor *about;
struct PeerIteratorContext *peerinfo_iterator;
+ int sent;
#if DEBUG_DV
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"%s: Receives core connect message for peer %s distance %d!\n",
"dv", GNUNET_i2s(peer), distance);
@@ -2190,29 +2607,35 @@
neighbor->send_context->toNeighbor = neighbor;
memcpy (&neighbor->identity, peer, sizeof (struct GNUNET_PeerIdentity));
- GNUNET_CONTAINER_multihashmap_put (ctx.direct_neighbors,
+ GNUNET_assert(GNUNET_SYSERR != GNUNET_CONTAINER_multihashmap_put
(ctx.direct_neighbors,
&peer->hashPubKey,
- neighbor,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
- addUpdateNeighbor (peer, NULL, 0, neighbor, DIRECT_NEIGHBOR_COST);
+ neighbor,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+ about = addUpdateNeighbor (peer, NULL, 0, neighbor, DIRECT_NEIGHBOR_COST);
+ peerinfo_iterator->distant = about;
peerinfo_iterator->neighbor = neighbor;
peerinfo_iterator->ic = GNUNET_PEERINFO_iterate (peerinfo_handle,
peer,
0,
-
GNUNET_TIME_UNIT_FOREVER_REL,
+
GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3),
&process_peerinfo,
peerinfo_iterator);
- /* Only add once we get the publicKey of this guy
- *
- * neighbor->send_context->task = GNUNET_SCHEDULER_add_now(sched,
&neighbor_send_task, neighbor->send_context);
- */
+ if ((about != NULL) && (about->pkey == NULL))
+ {
+#if DEBUG_DV
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Newly added peer %s has NULL
pkey!\n", GNUNET_i2s(peer));
+#endif
+ }
+ else if (about != NULL)
+ {
+ GNUNET_free(peerinfo_iterator);
+ }
}
else
{
about = GNUNET_CONTAINER_multihashmap_get(ctx.extended_neighbors,
&peer->hashPubKey);
if ((GNUNET_CONTAINER_multihashmap_get(ctx.direct_neighbors,
&peer->hashPubKey) == NULL) && (about != NULL))
- GNUNET_CONTAINER_multihashmap_iterate(ctx.direct_neighbors,
&add_distant_all_direct_neighbors, about);
-
+ sent = GNUNET_CONTAINER_multihashmap_iterate(ctx.direct_neighbors,
&add_distant_all_direct_neighbors, about);
#if DEBUG_DV
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"%s: Distance (%d) greater than %d or already know about peer
(%s), not re-adding!\n", "dv", distance, DIRECT_NEIGHBOR_COST,
GNUNET_i2s(peer));
@@ -2234,6 +2657,7 @@
struct DistantNeighbor *referee;
struct FindDestinationContext fdc;
struct DisconnectContext disconnect_context;
+
#if DEBUG_DV
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"%s: Receives core peer disconnect message!\n", "dv");
@@ -2261,8 +2685,11 @@
}
GNUNET_assert (neighbor->referee_tail == NULL);
- GNUNET_CONTAINER_multihashmap_remove (ctx.direct_neighbors,
- &peer->hashPubKey, neighbor);
+ if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_remove (ctx.direct_neighbors,
+ &peer->hashPubKey, neighbor))
+ {
+ GNUNET_break(0);
+ }
if ((neighbor->send_context != NULL) && (neighbor->send_context->task !=
GNUNET_SCHEDULER_NO_TASK))
GNUNET_SCHEDULER_cancel(sched, neighbor->send_context->task);
GNUNET_free (neighbor);
@@ -2293,19 +2720,14 @@
ctx.fisheye_depth = DEFAULT_FISHEYE_DEPTH;
if (GNUNET_CONFIGURATION_have_value(cfg, "dv", "max_direct_connections"))
- {
- GNUNET_CONFIGURATION_get_value_number(cfg, "dv",
"max_direct_connections", &max_hosts);
- }
+ GNUNET_assert(GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(cfg,
"dv", "max_direct_connections", &max_hosts));
if (GNUNET_CONFIGURATION_have_value(cfg, "dv", "max_total_connections"))
- {
- GNUNET_CONFIGURATION_get_value_number(cfg, "dv",
"max_total_connections", &ctx.max_table_size);
- }
+ GNUNET_assert(GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(cfg,
"dv", "max_total_connections", &ctx.max_table_size));
+
if (GNUNET_CONFIGURATION_have_value(cfg, "dv", "fisheye_depth"))
- {
- GNUNET_CONFIGURATION_get_value_number(cfg, "dv", "fisheye_depth",
&ctx.fisheye_depth);
- }
+ GNUNET_assert(GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(cfg,
"dv", "fisheye_depth", &ctx.fisheye_depth));
ctx.neighbor_min_heap =
GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
Modified: gnunet/src/dv/plugin_transport_dv.c
===================================================================
--- gnunet/src/dv/plugin_transport_dv.c 2010-06-17 13:25:59 UTC (rev 11781)
+++ gnunet/src/dv/plugin_transport_dv.c 2010-06-17 15:27:19 UTC (rev 11782)
@@ -173,17 +173,20 @@
size_t sender_address_len)
{
struct Plugin *plugin = cls;
-
+#if DEBUG_DV_MESSAGES
+ char *my_id;
+ my_id = GNUNET_strdup(GNUNET_i2s(plugin->env->my_identity));
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
"plugin_transport_dv",
- _("PLUGIN Received message from %s of type %d, distance
%u!\n"),
- "DV SERVICE", ntohs(((struct GNUNET_MessageHeader
*)msg)->type), distance);
-
+ _("%s Received message from %s) of type %d, distance
%u!\n"),
+ my_id, GNUNET_i2s(sender), ntohs(((struct
GNUNET_MessageHeader *)msg)->type), distance);
+ GNUNET_free_non_null(my_id);
+#endif
plugin->env->receive(plugin->env->cls,
sender,
(struct GNUNET_MessageHeader *)msg,
distance,
- NULL, /* FIXME: pass session! */
+ NULL,
sender_address,
sender_address_len);
@@ -237,10 +240,24 @@
{
int ret = 0;
struct Plugin *plugin = cls;
-
+ const char *tempbuf;
+ int temp_size;
#if DEBUG_DV
+ char *my_identity;
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV API: Received send request from
transport, calling GNUNET_DV_send\n");
+ my_identity = GNUNET_strdup(GNUNET_i2s(plugin->env->my_identity));
#endif
+ temp_size = htons(((struct GNUNET_MessageHeader *)msgbuf)->size);
+ if (msgbuf_size > temp_size)
+ {
+ tempbuf = &msgbuf[temp_size];
+#if DEBUG_DV
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s DV PLUGIN SEND SPECIAL type %d
to %s\n", my_identity, ntohs(((struct GNUNET_MessageHeader *)tempbuf)->type),
GNUNET_i2s(target));
+#endif
+ }
+#if DEBUG_DV
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s DV PLUGIN SEND type %d to %s\n",
my_identity, ntohs(((struct GNUNET_MessageHeader *)msgbuf)->type),
GNUNET_i2s(target));
+#endif
ret = GNUNET_DV_send(plugin->dv_handle,
target,
msgbuf,
@@ -251,6 +268,9 @@
addrlen,
cont,
cont_cls);
+#if DEBUG_DV
+ GNUNET_free_non_null(my_identity);
+#endif
return ret;
}
Modified: gnunet/src/dv/test_transport_api_data.conf
===================================================================
--- gnunet/src/dv/test_transport_api_data.conf 2010-06-17 13:25:59 UTC (rev
11781)
+++ gnunet/src/dv/test_transport_api_data.conf 2010-06-17 15:27:19 UTC (rev
11782)
@@ -59,6 +59,7 @@
HOME = $SERVICEHOME
HOSTNAME = localhost
PORT = 2092
+DEBUG = YES
[transport]
plugins = tcp
Modified: gnunet/src/dv/test_transport_api_dv.c
===================================================================
--- gnunet/src/dv/test_transport_api_dv.c 2010-06-17 13:25:59 UTC (rev
11781)
+++ gnunet/src/dv/test_transport_api_dv.c 2010-06-17 15:27:19 UTC (rev
11782)
@@ -27,6 +27,8 @@
#define VERBOSE GNUNET_YES
+#define TEST_ALL GNUNET_NO
+
/**
* How long until we fail the whole testcase?
*/
@@ -55,6 +57,12 @@
static unsigned int total_messages_received;
+static unsigned int total_other_expected_messages;
+
+static unsigned int temp_total_other_messages;
+
+static unsigned int total_other_messages;
+
static unsigned int expected_messages;
static unsigned int expected_connections;
@@ -93,6 +101,8 @@
static char *test_directory;
+struct GNUNET_CONTAINER_MultiHashMap *peer_daemon_hash;
+
#define MTYPE 12345
struct GNUNET_TestMessage
@@ -113,6 +123,11 @@
/* This is a linked list */
struct PeerContext *next;
+ /**
+ * Handle to the daemon
+ */
+ struct GNUNET_TESTING_Daemon *daemon;
+
/* Handle to the peer core */
struct GNUNET_CORE_Handle *peer_handle;
};
@@ -145,6 +160,8 @@
static struct TestMessageContext *test_messages;
+static struct TestMessageContext *other_test_messages;
+
static void
finish_testing ()
{
@@ -153,6 +170,8 @@
struct PeerContext *free_peer_pos;
struct TestMessageContext *pos;
struct TestMessageContext *free_pos;
+ int count;
+
#if VERBOSE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Called finish testing, stopping daemons.\n");
@@ -160,15 +179,14 @@
peer_pos = all_peers;
while (peer_pos != NULL)
{
- fprintf(stderr, "Disconnecting from peer core\n");
if (peer_pos->peer_handle != NULL)
GNUNET_CORE_disconnect(peer_pos->peer_handle);
free_peer_pos = peer_pos;
peer_pos = peer_pos->next;
GNUNET_free(free_peer_pos);
}
+ all_peers = NULL;
- int count;
count = 0;
pos = test_messages;
while (pos != NULL)
@@ -191,6 +209,28 @@
}
GNUNET_free(free_pos);
}
+
+ pos = other_test_messages;
+ while (pos != NULL)
+ {
+ if (pos->peer1handle != NULL)
+ {
+ GNUNET_CORE_disconnect(pos->peer1handle);
+ pos->peer1handle = NULL;
+ }
+ if (pos->peer2handle != NULL)
+ {
+ GNUNET_CORE_disconnect(pos->peer2handle);
+ pos->peer2handle = NULL;
+ }
+ free_pos = pos;
+ pos = pos->next;
+ if (free_pos->disconnect_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel(sched, free_pos->disconnect_task);
+ }
+ GNUNET_free(free_pos);
+ }
#if VERBOSE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"transmit_ready's scheduled %d, failed %d,
transmit_ready's called %d\n", transmit_ready_scheduled, transmit_ready_failed,
transmit_ready_called);
@@ -242,10 +282,7 @@
}
static void
-send_other_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
-{
- die_task = GNUNET_SCHEDULER_add_delayed (sched,
GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 25), &finish_testing,
NULL);
-}
+send_other_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext *
tc);
static int
process_mtype (void *cls,
@@ -259,19 +296,37 @@
if (pos->uid != ntohl(msg->uid))
return GNUNET_OK;
- total_messages_received++;
+ if (total_other_expected_messages == 0)
+ {
+ total_messages_received++;
#if VERBOSE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received message from `%4s', type %d, distance %u.\n",
GNUNET_i2s (peer), ntohs(message->type), distance);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Total messages received %d, expected %d.\n",
total_messages_received, expected_messages);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received message from `%4s', type %d, distance %u.\n",
GNUNET_i2s (peer), ntohs(message->type), distance);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Total messages received %d, expected %d.\n",
total_messages_received, expected_messages);
#endif
+ }
+ else
+ {
+ total_other_messages++;
+#if VERBOSE
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received message from `%4s', type %d, distance %u.\n",
GNUNET_i2s (peer), ntohs(message->type), distance);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Total messages received %d, expected %d.\n",
total_other_messages, total_other_expected_messages);
+#endif
+ }
- if (total_messages_received == expected_messages)
+ if ((total_messages_received == expected_messages) && (total_other_messages
== 0))
{
GNUNET_SCHEDULER_cancel (sched, die_task);
- GNUNET_SCHEDULER_add_now (sched, &send_other_messages, NULL);
+ GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, 40), &send_other_messages, NULL);
}
+ else if ((total_other_expected_messages > 0) && (total_other_messages ==
total_other_expected_messages))
+ {
+ GNUNET_SCHEDULER_cancel (sched, die_task);
+ GNUNET_SCHEDULER_add_now (sched, &finish_testing, NULL);
+ }
else
{
pos->disconnect_task = GNUNET_SCHEDULER_add_now(sched,
&disconnect_cores, pos);
@@ -288,7 +343,20 @@
"End badly was called (%s)... stopping daemons.\n", msg);
struct TestMessageContext *pos;
struct TestMessageContext *free_pos;
+ struct PeerContext * peer_pos;
+ struct PeerContext * free_peer_pos;
+ peer_pos = all_peers;
+ while (peer_pos != NULL)
+ {
+ if (peer_pos->peer_handle != NULL)
+ GNUNET_CORE_disconnect(peer_pos->peer_handle);
+ free_peer_pos = peer_pos;
+ peer_pos = peer_pos->next;
+ GNUNET_free(free_peer_pos);
+ }
+ all_peers = NULL;
+
pos = test_messages;
while (pos != NULL)
{
@@ -307,6 +375,28 @@
GNUNET_free(free_pos);
}
+ pos = other_test_messages;
+ while (pos != NULL)
+ {
+ if (pos->peer1handle != NULL)
+ {
+ GNUNET_CORE_disconnect(pos->peer1handle);
+ pos->peer1handle = NULL;
+ }
+ if (pos->peer2handle != NULL)
+ {
+ GNUNET_CORE_disconnect(pos->peer2handle);
+ pos->peer2handle = NULL;
+ }
+ free_pos = pos;
+ pos = pos->next;
+ if (free_pos->disconnect_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel(sched, free_pos->disconnect_task);
+ }
+ GNUNET_free(free_pos);
+ }
+
if (pg != NULL)
{
GNUNET_TESTING_daemons_stop (pg, TIMEOUT);
@@ -437,7 +527,9 @@
&send_test_messages, pos);
return; /* Otherwise we'll double schedule messages here! */
}
-
+#if VERBOSE
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Attempting to send test message from %s
to %s\n", pos->peer1->shortname, pos->peer2->shortname);
+#endif
/*
* Connect to the sending peer
*/
@@ -465,7 +557,78 @@
}
}
+static void
+send_other_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
+{
+ struct TestMessageContext *pos;
+ struct TestMessageContext *free_pos;
+ struct PeerContext *peer_pos;
+#if TEST_ALL
+ struct PeerContext *inner_peer_pos;
+ struct TestMessageContext *temp_context;
+#endif
+ peer_pos = all_peers;
+ while (peer_pos != NULL)
+ {
+ if (peer_pos->peer_handle != NULL)
+ {
+ GNUNET_CORE_disconnect(peer_pos->peer_handle);
+ peer_pos->peer_handle = NULL;
+ }
+#if TEST_ALL
+ inner_peer_pos = all_peers;
+ while (inner_peer_pos != NULL)
+ {
+ if (inner_peer_pos != peer_pos)
+ {
+ temp_total_other_messages++;
+ temp_context = GNUNET_malloc(sizeof(struct TestMessageContext));
+ temp_context->peer1 = peer_pos->daemon;
+ temp_context->peer2 = inner_peer_pos->daemon;
+ temp_context->next = other_test_messages;
+ temp_context->uid = total_connections + temp_total_other_messages;
+ temp_context->disconnect_task = GNUNET_SCHEDULER_NO_TASK;
+ other_test_messages = temp_context;
+ }
+ inner_peer_pos = inner_peer_pos->next;
+ }
+#endif
+ peer_pos = peer_pos->next;
+ }
+ all_peers = NULL;
+ pos = test_messages;
+ while (pos != NULL)
+ {
+ if (pos->peer1handle != NULL)
+ {
+ GNUNET_CORE_disconnect(pos->peer1handle);
+ pos->peer1handle = NULL;
+ }
+ if (pos->peer2handle != NULL)
+ {
+ GNUNET_CORE_disconnect(pos->peer2handle);
+ pos->peer2handle = NULL;
+ }
+ free_pos = pos;
+ pos = pos->next;
+ if (free_pos->disconnect_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel(sched, free_pos->disconnect_task);
+ }
+ GNUNET_free(free_pos);
+ }
+ test_messages = NULL;
+
+ total_other_expected_messages = temp_total_other_messages;
+#if VERBOSE
+ GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Preparing to send %d other test
messages\n", total_other_expected_messages);
+#endif
+
+ GNUNET_SCHEDULER_add_now (sched, &send_test_messages, other_test_messages);
+ die_task = GNUNET_SCHEDULER_add_delayed (sched,
GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 250), &end_badly,
"from send_other_messages");
+}
+
void
topology_callback (void *cls,
const struct GNUNET_PeerIdentity *first,
@@ -496,16 +659,7 @@
test_messages = temp_context;
expected_messages++;
- /*if (dotOutFile != NULL)
- {
- if (distance == 1)
- fprintf(dotOutFile, "\tn%s -- n%s;\n", first_daemon->shortname,
second_daemon->shortname);
- else if (distance == 2)
- fprintf(dotOutFile, "\tn%s -- n%s [color=blue];\n",
first_daemon->shortname, second_daemon->shortname);
- else if (distance == 3)
- fprintf(dotOutFile, "\tn%s -- n%s [color=red];\n",
first_daemon->shortname, second_daemon->shortname);
- }
- */
+
}
#if VERBOSE
else
@@ -620,22 +774,40 @@
uint32_t distance)
{
struct GNUNET_TESTING_Daemon *d = cls;
+ struct GNUNET_TESTING_Daemon *second_daemon;
char *second_shortname = strdup(GNUNET_i2s(peer));
-
+#if !TEST_ALL
+ struct TestMessageContext *temp_context;
+#endif
#if VERBOSE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connected peer %s to peer %s, distance
%u\n",
d->shortname,
second_shortname,
distance);
#endif
- /*temp_context = GNUNET_malloc(sizeof(struct TestMessageContext));
- temp_context->peer1 = first_daemon;
- temp_context->peer2 = second_daemon;
- temp_context->next = test_messages;
- temp_context->uid = total_connections;
- temp_context->disconnect_task = GNUNET_SCHEDULER_NO_TASK;
- test_messages = temp_context;*/
+ second_daemon = GNUNET_CONTAINER_multihashmap_get(peer_daemon_hash,
&peer->hashPubKey);
+
+ if (second_daemon == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Couldn't find second peer!\n");
+ return;
+ }
+#if !TEST_ALL
+ if (distance > 1)
+ {
+ temp_total_other_messages++;
+ temp_context = GNUNET_malloc(sizeof(struct TestMessageContext));
+ temp_context->peer1 = d;
+ temp_context->peer2 = second_daemon;
+ temp_context->next = other_test_messages;
+ temp_context->uid = total_connections;
+ temp_context->disconnect_task = GNUNET_SCHEDULER_NO_TASK;
+ other_test_messages = temp_context;
+ }
+#endif
+
+
if (dotOutFile != NULL)
{
if (distance == 1)
@@ -644,6 +816,8 @@
fprintf(dotOutFile, "\tn%s -- n%s [color=blue];\n", d->shortname,
second_shortname);
else if (distance == 3)
fprintf(dotOutFile, "\tn%s -- n%s [color=red];\n", d->shortname,
second_shortname);
+ else if (distance == 4)
+ fprintf(dotOutFile, "\tn%s -- n%s [color=green];\n", d->shortname,
second_shortname);
}
GNUNET_free(second_shortname);
}
@@ -666,8 +840,11 @@
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Started daemon %llu out of %llu\n",
(num_peers - peers_left) + 1, num_peers);
#endif
+ GNUNET_assert(GNUNET_SYSERR !=
GNUNET_CONTAINER_multihashmap_put(peer_daemon_hash, &id->hashPubKey, d,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+
new_peer = GNUNET_malloc(sizeof(struct PeerContext));
new_peer->peer_handle = GNUNET_CORE_connect(sched, cfg,
GNUNET_TIME_UNIT_FOREVER_REL, d, NULL, &all_connect_handler, NULL, NULL,
GNUNET_NO, NULL, GNUNET_NO, no_handlers);
+ new_peer->daemon = d;
new_peer->next = all_peers;
all_peers = new_peer;
peers_left--;
@@ -782,7 +959,7 @@
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Invalid connect topology `%s' given for section %s option
%s\n", connect_topology_str, "TESTING", "CONNECT_TOPOLOGY");
}
-
+ GNUNET_free_non_null(connect_topology_str);
if ((GNUNET_YES ==
GNUNET_CONFIGURATION_get_value_string(cfg, "testing",
"connect_topology_option",
&connect_topology_option_str)) &&
(GNUNET_NO == GNUNET_TESTING_topology_option_get(&connect_topology_option,
connect_topology_option_str)))
@@ -791,7 +968,7 @@
"Invalid connect topology option `%s' given for section %s
option %s\n", connect_topology_option_str, "TESTING",
"CONNECT_TOPOLOGY_OPTION");
connect_topology_option = GNUNET_TESTING_TOPOLOGY_OPTION_ALL; /*
Defaults to NONE, set to ALL */
}
-
+ GNUNET_free_non_null(connect_topology_option_str);
if (GNUNET_YES ==
GNUNET_CONFIGURATION_get_value_string (cfg, "testing",
"connect_topology_option_modifier",
&connect_topology_option_modifier_string))
@@ -813,12 +990,13 @@
if ((GNUNET_YES ==
GNUNET_CONFIGURATION_get_value_string(cfg, "testing",
"blacklist_topology",
- & blacklist_topology_str)) &&
(GNUNET_NO == GNUNET_TESTING_topology_get(&blacklist_topology,
blacklist_topology_str)))
+ &blacklist_topology_str)) &&
(GNUNET_NO == GNUNET_TESTING_topology_get(&blacklist_topology,
blacklist_topology_str)))
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Invalid topology `%s' given for section %s option %s\n",
topology_str, "TESTING", "BLACKLIST_TOPOLOGY");
}
-
+ GNUNET_free_non_null(topology_str);
+ GNUNET_free_non_null(blacklist_topology_str);
if (GNUNET_SYSERR ==
GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers",
&num_peers))
@@ -834,6 +1012,7 @@
(GNUNET_TIME_UNIT_MINUTES, 5),
&end_badly, "didn't start all
daemons in reasonable amount of time!!!");
+ peer_daemon_hash = GNUNET_CONTAINER_multihashmap_create(peers_left);
pg = GNUNET_TESTING_daemons_start (sched, cfg,
peers_left, TIMEOUT, &hostkey_callback,
NULL, &peers_started_callback, NULL,
&topology_callback, NULL, NULL);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r11782 - gnunet/src/dv,
gnunet <=