remove double connect notify, add is connected optimization for peer iterate call
authorNathan S. Evans <evans@in.tum.de>
Wed, 16 Feb 2011 16:24:32 +0000 (16:24 +0000)
committerNathan S. Evans <evans@in.tum.de>
Wed, 16 Feb 2011 16:24:32 +0000 (16:24 +0000)
src/core/core_api.c
src/core/core_api_iterate_peers.c
src/core/gnunet-service-core.c

index 57bf64ad72bb406314347c81909e309a2a659d1d..e9a38271bf317cce14072f629e842e521ca4fa6d 100644 (file)
@@ -1730,25 +1730,11 @@ GNUNET_CORE_peer_request_connect (struct GNUNET_CORE_Handle *h,
   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));
index fb9c01fee3bb36506339f374cafcbb429f0ad953..8175b70c6ed067784360b61309e2f800b28a195d 100644 (file)
@@ -31,7 +31,6 @@
 
 struct GNUNET_CORE_RequestContext
 {
-  
   /**
    * Our connection to the service.
    */
@@ -47,6 +46,11 @@ struct GNUNET_CORE_RequestContext
    */
   GNUNET_CORE_ConnectEventHandler peer_cb;
 
+  /**
+   * Peer to check for.
+   */
+  struct GNUNET_PeerIdentity *peer;
+
   /**
    * Closure for peer_cb.
    */
@@ -136,21 +140,78 @@ transmit_request(void *cls,
                  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
index 4519991b3c93d779c09894b5e5659a8630dddb27..81d851265ff3fde3524205c42f0bb056bd2da753 100644 (file)
@@ -1498,10 +1498,22 @@ handle_client_iterate_peers (void *cls,
 {
   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);
@@ -2908,6 +2920,10 @@ notify_transport_connect_done (void *cls,
     }
   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));
@@ -2966,10 +2982,20 @@ handle_client_request_connect (void *cls,
                                  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,
+                                                          &notify_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,