struct GNUNET_CORE_PeerRequestHandle *ret;
struct ControlMessage *cm;
struct ConnectMessage *msg;
- struct PeerRecord *pr;
- static struct GNUNET_TRANSPORT_ATS_Information distance[2];
if (NULL != GNUNET_CONTAINER_multihashmap_get (h->peers,
&peer->hashPubKey))
- {
- pr = GNUNET_CONTAINER_multihashmap_get(h->peers, &peer->hashPubKey);
- GNUNET_assert(pr != NULL);
- distance[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
- distance[0].value = htonl (1);
- distance[1].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
- distance[1].value = htonl (0);
+ return NULL; /* Already connected, means callback should have happened already! */
- if (NULL != h->connects)
- h->connects (h->cls,
- &pr->peer,
- &distance[0]);
- return NULL;
- }
cm = GNUNET_malloc (sizeof (struct ControlMessage) +
sizeof (struct ConnectMessage));
struct GNUNET_CORE_RequestContext
{
-
/**
* Our connection to the service.
*/
*/
GNUNET_CORE_ConnectEventHandler peer_cb;
+ /**
+ * Peer to check for.
+ */
+ struct GNUNET_PeerIdentity *peer;
+
/**
* Closure for peer_cb.
*/
size_t size, void *buf)
{
struct GNUNET_MessageHeader *msg;
- if ((size < sizeof(struct GNUNET_MessageHeader)) || (buf == NULL))
+ struct GNUNET_PeerIdentity *peer = cls;
+ int msize;
+
+ if (peer == NULL)
+ msize = sizeof(struct GNUNET_MessageHeader);
+ else
+ msize = sizeof(struct GNUNET_MessageHeader) + sizeof(struct GNUNET_PeerIdentity);
+
+ if ((size < msize) || (buf == NULL))
return 0;
msg = (struct GNUNET_MessageHeader *)buf;
msg->size = htons (sizeof (struct GNUNET_MessageHeader));
msg->type = htons (GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS);
- return sizeof(struct GNUNET_MessageHeader);
+ memcpy(&msg[1], peer, sizeof(struct GNUNET_PeerIdentity));
+
+ return msize;
}
/**
- * Obtain statistics and/or change preferences for the given peer.
+ * Iterate over all currently connected peers.
+ * Calls peer_cb with each connected peer, and then
+ * once with NULL to indicate that all peers have
+ * been handled.
*
* @param cfg configuration to use
+ * @param peer the specific peer to check for
* @param peer_cb function to call with the peer information
* @param cb_cls closure for peer_cb
+ *
+ * @return GNUNET_OK if iterating, GNUNET_SYSERR on error
+ */
+int
+GNUNET_CORE_is_peer_connected (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ struct GNUNET_PeerIdentity *peer,
+ GNUNET_CORE_ConnectEventHandler peer_cb,
+ void *cb_cls)
+{
+ struct GNUNET_CORE_RequestContext *request_context;
+ struct GNUNET_CLIENT_Connection *client;
+
+ client = GNUNET_CLIENT_connect ("core", cfg);
+ if (client == NULL)
+ return GNUNET_SYSERR;
+ GNUNET_assert(peer != NULL);
+ request_context = GNUNET_malloc (sizeof (struct GNUNET_CORE_RequestContext));
+ request_context->client = client;
+ request_context->peer_cb = peer_cb;
+ request_context->cb_cls = cb_cls;
+ request_context->peer = peer;
+
+ request_context->th = GNUNET_CLIENT_notify_transmit_ready(client,
+ sizeof(struct GNUNET_MessageHeader) + sizeof(struct GNUNET_PeerIdentity),
+ GNUNET_TIME_relative_get_forever(),
+ GNUNET_YES,
+ &transmit_request,
+ peer);
+
+ GNUNET_CLIENT_receive(client, &receive_info, request_context, GNUNET_TIME_relative_get_forever());
+ return GNUNET_OK;
+}
+
+/**
+ * Iterate over all currently connected peers.
+ * Calls peer_cb with each connected peer, and then
+ * once with NULL to indicate that all peers have
+ * been handled.
+ *
+ * @param cfg configuration to use
+ * @param peer_cb function to call with the peer information
+ * @param cb_cls closure for peer_cb
+ *
* @return GNUNET_OK if iterating, GNUNET_SYSERR on error
*/
int
{
struct GNUNET_MessageHeader done_msg;
struct GNUNET_SERVER_TransmitContext *tc;
-
+ struct GNUNET_PeerIdentity *peer;
+ int msize;
/* notify new client about existing neighbours */
+
+ msize = ntohs(message->size);
tc = GNUNET_SERVER_transmit_context_create (client);
- GNUNET_CONTAINER_multihashmap_iterate (neighbours, &queue_connect_message, tc);
+ if (msize == sizeof(struct GNUNET_MessageHeader))
+ GNUNET_CONTAINER_multihashmap_iterate (neighbours, &queue_connect_message, tc);
+ else if (msize == sizeof(struct GNUNET_MessageHeader) + sizeof(struct GNUNET_PeerIdentity))
+ {
+ peer = (struct GNUNET_PeerIdentity *)&message[1];
+ GNUNET_CONTAINER_multihashmap_get_multiple(neighbours, &peer->hashPubKey, &queue_connect_message, tc);
+ }
+ else
+ GNUNET_break(0);
+
done_msg.size = htons (sizeof (struct GNUNET_MessageHeader));
done_msg.type = htons (GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS_END);
GNUNET_SERVER_transmit_context_append_message (tc, &done_msg);
}
if (buf == NULL)
{
+ GNUNET_STATISTICS_update (stats,
+ gettext_noop ("# connection requests timed out in transport"),
+ 1,
+ GNUNET_NO);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
_("Failed to connect to `%4s': transport failed to connect\n"),
GNUNET_i2s (&n->peer));
1,
GNUNET_NO);
else
- GNUNET_STATISTICS_update (stats,
- gettext_noop ("# connection requests ignored (already trying)"),
- 1,
- GNUNET_NO);
+ {
+ GNUNET_TRANSPORT_notify_transmit_ready_cancel(n->th);
+ n->th = GNUNET_TRANSPORT_notify_transmit_ready (transport,
+ &cm->peer,
+ sizeof (struct GNUNET_MessageHeader), 0,
+ timeout,
+ ¬ify_transport_connect_done,
+ n);
+ GNUNET_break (NULL != n->th);
+ GNUNET_STATISTICS_update (stats,
+ gettext_noop ("# connection requests retried (due to repeat request connect)"),
+ 1,
+ GNUNET_NO);
+ }
return; /* already connected, or at least trying */
}
GNUNET_STATISTICS_update (stats,