* #GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS
*/
struct GNUNET_MessageHeader header;
+
+ /**
+ * Offset the peer has in the path this message is about.
+ */
+ uint16_t offset GNUNET_PACKED;
/**
* Number of paths.
* Do we have a tunnel toward this peer?
*/
int16_t tunnel GNUNET_PACKED;
+
+ /**
+ * We are finished with the paths.
+ */
+ uint16_t finished_with_paths;
/**
* ID of the peer (can be local peer).
const struct GNUNET_PeerIdentity *paths_array;
size_t esize;
unsigned int epaths;
- unsigned int paths;
unsigned int peers;
esize = ntohs (message->header.size);
peers = (esize - msize) / sizeof (struct GNUNET_PeerIdentity);
epaths = ntohs (message->paths);
paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
- paths = 0;
- for (unsigned int i = 0; i < peers; i++)
- if (0 == memcmp (&paths_array[i],
- &message->destination,
- sizeof (struct GNUNET_PeerIdentity)))
- paths++;
- if (paths != epaths)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
+
return GNUNET_OK;
}
if (NULL == h->info_cb.peer_cb)
return;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "number of paths %u\n",
+ ntohs (message->paths));
+
paths = ntohs (message->paths);
paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
peers = (ntohs (message->header.size) - sizeof (*message))
(int) ntohs (message->tunnel),
neighbor,
paths,
- paths_array);
+ paths_array,
+ (int) ntohs (message->offset),
+ (int) ntohs (message->finished_with_paths));
}
int tunnel,
int neighbor,
unsigned int n_paths,
- const struct GNUNET_PeerIdentity *paths)
+ const struct GNUNET_PeerIdentity *paths,
+ int offset,
+ int finished_with_paths)
{
unsigned int i;
const struct GNUNET_PeerIdentity *p;
-
- FPRINTF (stdout,
- "%s [TUNNEL: %s, NEIGHBOR: %s, PATHS: %u]\n",
- GNUNET_i2s_full (peer),
- tunnel ? "Y" : "N",
- neighbor ? "Y" : "N",
- n_paths);
- p = paths;
- for (i = 0; i < n_paths && NULL != p;)
+
+
+ if (GNUNET_YES == finished_with_paths)
{
+ GNUNET_SCHEDULER_shutdown();
+ return;
+ }
+
+ if (offset == 0){
+ FPRINTF (stdout,
+ "%s [TUNNEL: %s, NEIGHBOR: %s, PATHS: %u]\n",
+ GNUNET_i2s_full (peer),
+ tunnel ? "Y" : "N",
+ neighbor ? "Y" : "N",
+ n_paths);
+ }else{
+ p = paths;
FPRINTF (stdout,
- "%s ",
- GNUNET_i2s (p));
- if (0 == memcmp (p,
- peer,
- sizeof (*p)))
+ "Path with offset %u: ",
+ offset);
+ for (i = 0; i < offset && NULL != p;)
{
- FPRINTF (stdout, "\n");
- i++;
+ FPRINTF (stdout,
+ "%s ",
+ GNUNET_i2s (p));
+ i++;
+ p++;
}
- p++;
+
+ FPRINTF (stdout,
+ "\n");
+
}
+
- GNUNET_SCHEDULER_shutdown();
+
}
struct GNUNET_CADET_LocalInfoPeer *msg;
env = GNUNET_MQ_msg (msg,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
msg->destination = *peer;
msg->paths = htons (GCP_count_paths (p));
msg->tunnel = htons (NULL != GCP_get_tunnel (p,
env = GNUNET_MQ_msg_extra (resp,
path_size,
GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
+
+
+ resp->offset = htons(off);
+ resp->finished_with_paths = htons(0);
+
id = (struct GNUNET_PeerIdentity *) &resp[1];
/* Don't copy first peer. First peer is always the local one. Last
return GNUNET_YES;
}
+/**
+ * Getting summary information about the number of paths and if a tunnel exists,
+ * and the indirect paths to a peer, if there are ones.
+ *
+ * @param cls Closure ().
+ * @param peer Peer ID (tunnel remote peer).
+ * @param value Peer info.
+ * @return #GNUNET_YES, to keep iterating.
+ */
+static void
+get_peer_info (void *cls,
+ const struct GNUNET_PeerIdentity *peer,
+ struct CadetPeer *p)
+{
+ struct CadetClient *c = cls;
+ struct GNUNET_MQ_Envelope *env;
+ struct GNUNET_CADET_LocalInfoPeer *msg;
+
+
+ env = GNUNET_MQ_msg (msg,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
+
+ msg->offset = htons(0);
+ msg->destination = *peer;
+ msg->paths = htons (GCP_count_paths (p));
+ msg->tunnel = htons (NULL != GCP_get_tunnel (p,
+ GNUNET_NO));
+ msg->finished_with_paths = htons(0);
+
+ GNUNET_MQ_send (c->mq,
+ env);
+
+ GCP_iterate_indirect_paths(p,
+ &path_info_iterator,
+ c->mq);
+
+}
+
+
/**
* Handler for client's SHOW_PEER request.
struct CadetClient *c = cls;
struct CadetPeer *p;
struct GNUNET_MQ_Envelope *env;
- struct GNUNET_MessageHeader *resp;
+ struct GNUNET_CADET_LocalInfoPeer *resp;
p = GCP_get (&msg->peer,
GNUNET_NO);
- if (NULL != p)
- GCP_iterate_paths (p,
- &path_info_iterator,
- c->mq);
- /* Send message with 0/0 to indicate the end */
+ if (NULL != p){
+ get_peer_info(c, &(msg->peer), p);
+ }
+
+
env = GNUNET_MQ_msg (resp,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER_END);
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
+ resp->finished_with_paths = htons(1);
+ resp->destination = msg->peer;
+
GNUNET_MQ_send (c->mq,
env);
+
GNUNET_SERVICE_client_continue (c->client);
}
*/
/**
* @file cadet/gnunet-service-cadet_paths.c
- * @brief Information we track per path.
+ * @brief Information we track per path.
* @author Bartlomiej Polot
* @author Christian Grothoff
*/
return ret;
}
+/**
+ * Iterate over the paths to a peer without direct link.
+ *
+ * @param cp Peer to get path info.
+ * @param callback Function to call for every path.
+ * @param callback_cls Closure for @a callback.
+ * @return Number of iterated paths.
+ */
+unsigned int
+GCP_iterate_indirect_paths (struct CadetPeer *cp,
+ GCP_PathIterator callback,
+ void *callback_cls)
+{
+ unsigned int ret = 0;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Iterating over paths to peer %s without direct link\n",
+ GCP_2s (cp));
+ for (unsigned int i=1;i<cp->path_dll_length;i++)
+ {
+ for (struct CadetPeerPathEntry *pe = cp->path_heads[i];
+ NULL != pe;
+ pe = pe->next)
+ {
+ ret++;
+ if (GNUNET_NO ==
+ callback (callback_cls,
+ pe->path,
+ i))
+ return ret;
+ }
+ }
+ return ret;
+}
+
/**
* Iterate over the paths to @a cp where
GCP_PathIterator callback,
void *callback_cls);
+/**
+ * Iterate over the paths to a peer without direct link.
+ *
+ * @param cp Peer to get path info.
+ * @param callback Function to call for every path.
+ * @param callback_cls Closure for @a callback.
+ * @return Number of iterated paths.
+ */
+unsigned int
+GCP_iterate_indirect_paths (struct CadetPeer *cp,
+ GCP_PathIterator callback,
+ void *callback_cls);
+
/**
* Iterate over the paths to @a peer where
int tunnel,
int neighbor,
unsigned int n_paths,
- const struct GNUNET_PeerIdentity *paths);
+ const struct GNUNET_PeerIdentity *paths,
+ int offset,
+ int finished_with_paths);
/**