#include "gnunet-service-core_typemap.h"
#include "core.h"
-#define DEBUG_CONNECTS GNUNET_YES
/**
* How many messages do we queue up at most for optional
*/
struct GNUNET_CONTAINER_MultiHashMap *requests;
-#if DEBUG_CONNECTS
/**
* Map containing all peers that this client knows we're connected to.
*/
struct GNUNET_CONTAINER_MultiHashMap *connectmap;
-#endif
/**
* Options for messages this client cares about,
* Send a message to all of our current clients that have the right
* options set.
*
+ * @param sender origin of the message (used to check that this peer is
+ * known to be connected to the respective client)
* @param msg message to multicast
* @param can_drop can this message be discarded if the queue is too long
* @param options mask to use
"Sending message to client interested in messages of type %u.\n",
(unsigned int) type);
#endif
-#if DEBUG_CONNECTS
GNUNET_assert (GNUNET_YES ==
GNUNET_CONTAINER_multihashmap_contains (c->connectmap,
&sender->hashPubKey));
-#endif
send_to_client (c, msg, can_drop);
}
}
c->tcnt = msize / sizeof (uint16_t);
c->options = ntohl (im->options);
c->types = (const uint16_t *) &c[1];
-#if DEBUG_CONNECTS
c->connectmap = GNUNET_CONTAINER_multihashmap_create (16);
GNUNET_assert (GNUNET_YES ==
GNUNET_CONTAINER_multihashmap_put (c->connectmap,
&GSC_my_identity.hashPubKey,
NULL,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
-#endif
-
wtypes = (uint16_t *) & c[1];
for (i = 0; i < c->tcnt; i++)
wtypes[i] = ntohs (types[i]);
const struct SendMessageRequest *req;
struct GSC_Client *c;
struct GSC_ClientActiveRequest *car;
+ int is_loopback;
req = (const struct SendMessageRequest *) message;
c = find_client (client);
"Client asked for transmission to `%s'\n",
GNUNET_i2s (&req->peer));
#endif
+ is_loopback =
+ (0 ==
+ memcmp (&req->peer, &GSC_my_identity,
+ sizeof (struct GNUNET_PeerIdentity)));
+ if ((!is_loopback) &&
+ (GNUNET_YES !=
+ GNUNET_CONTAINER_multihashmap_contains (c->connectmap,
+ &req->peer.hashPubKey)))
+ {
+ /* neighbour must have disconnected since request was issued,
+ * ignore (client will realize it once it processes the
+ * disconnect notification) */
+ GNUNET_STATISTICS_update (GSC_stats,
+ gettext_noop
+ ("# send requests dropped (disconnected)"), 1,
+ GNUNET_NO);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
+ }
+
car = GNUNET_CONTAINER_multihashmap_get (c->requests, &req->peer.hashPubKey);
if (car == NULL)
{
car->msize = ntohs (req->size);
car->smr_id = req->smr_id;
car->was_solicited = GNUNET_NO;
- if (0 ==
- memcmp (&req->peer, &GSC_my_identity,
- sizeof (struct GNUNET_PeerIdentity)))
+ if (is_loopback)
+ {
+ /* loopback, satisfy immediately */
GSC_CLIENTS_solicit_request (car);
- else
- GSC_SESSIONS_queue_request (car);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
+ }
+ GSC_SESSIONS_queue_request (car);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
NULL);
GNUNET_CONTAINER_multihashmap_destroy (c->requests);
}
-#if DEBUG_CONNECTS
GNUNET_CONTAINER_multihashmap_destroy (c->connectmap);
-#endif
+ c->connectmap = NULL;
GSC_TYPEMAP_remove (c->types, c->tcnt);
GNUNET_free (c);
}
struct SendMessageReady smr;
c = car->client_handle;
+ if (GNUNET_YES !=
+ GNUNET_CONTAINER_multihashmap_contains (c->connectmap,
+ &car->target.hashPubKey))
+ {
+ /* connection has gone down since, drop request */
+ GNUNET_assert (0 !=
+ memcmp (&car->target, &GSC_my_identity,
+ sizeof (struct GNUNET_PeerIdentity)));
+ GSC_SESSIONS_dequeue_request (car);
+ GSC_CLIENTS_reject_request (car);
+ return;
+ }
smr.header.size = htons (sizeof (struct SendMessageReady));
smr.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND_READY);
smr.size = htons (car->msize);
smr.smr_id = car->smr_id;
smr.peer = car->target;
-#if DEBUG_CONNECTS
- GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_contains (c->connectmap,
- &car->
- target.hashPubKey));
-#endif
send_to_client (c, &smr.header, GNUNET_NO);
}
* @param atsi_count number of entries in 'ats' array
* @param tmap_old previous type map for the neighbour, NULL for disconnect
* @param tmap_new updated type map for the neighbour, NULL for disconnect
- * @param is_new GNUNET_YES if this is a completely new neighbour
*/
void
GSC_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client,
if (old_match == GNUNET_NO)
{
/* send connect */
-#if DEBUG_CONNECTS
GNUNET_assert (GNUNET_NO ==
GNUNET_CONTAINER_multihashmap_contains (client->connectmap,
&neighbour->hashPubKey));
&neighbour->hashPubKey,
NULL,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
-#endif
size =
sizeof (struct ConnectNotifyMessage) +
(atsi_count) * sizeof (struct GNUNET_ATS_Information);
else
{
/* send disconnect */
-#if DEBUG_CONNECTS
GNUNET_assert (GNUNET_YES ==
GNUNET_CONTAINER_multihashmap_contains (client->connectmap,
&neighbour->hashPubKey));
GNUNET_CONTAINER_multihashmap_remove (client->connectmap,
&neighbour->hashPubKey,
NULL));
-#endif
dcm.header.size = htons (sizeof (struct DisconnectNotifyMessage));
dcm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT);
dcm.reserved = htonl (0);