}
+/**
+ *
+ */
+static void
+register_neighbors (struct MeshConnection *c)
+{
+ struct MeshPeer *peer;
+
+ peer = connection_get_next_hop (c);
+ if (GNUNET_NO == GMP_is_neighbor (peer))
+ {
+ GMC_destroy (c);
+ return NULL;
+ }
+ GMP_add_connection (peer, c);
+ peer = connection_get_prev_hop (c);
+ if (GNUNET_NO == GMP_is_neighbor (peer))
+ {
+ GMC_destroy (c);
+ return NULL;
+ }
+ GMP_add_connection (peer, c);
+}
+
+
/**
* Core handler for connection creation.
*
void
GMC_shutdown (void)
{
- if (core_handle != NULL)
- {
- GNUNET_CORE_disconnect (core_handle);
- core_handle = NULL;
- }
}
struct MeshConnection *
-GMC_new (const struct GNUNET_HashCode *cid)
+GMC_new (const struct GNUNET_HashCode *cid,
+ struct MeshTunnel2 *t,
+ struct MeshPeerPath *p,
+ unsigned int own_pos)
{
struct MeshConnection *c;
-
+ unsigned int own_pos;
+
c = GNUNET_new (struct MeshConnection);
c->id = *cid;
GNUNET_CONTAINER_multihashmap_put (connections, &c->id, c,
fc_init (&c->bck_fc);
c->fwd_fc.c = c;
c->bck_fc.c = c;
-
+
+ c->t = t;
+ if (own_pos > p->length - 1)
+ {
+ GNUNET_break (0);
+ GMC_destroy (c);
+ return NULL;
+ }
+ c->own_pos = own_pos;
+ c->path = p;
+
+ if (0 == own_pos)
+ {
+ c->fwd_maintenance_task =
+ GNUNET_SCHEDULER_add_delayed (refresh_connection_time,
+ &connection_fwd_keepalive, c);
+ }
+ register_neighbors (c);
return c;
}
}
+/**
+ * Get the connection ID.
+ *
+ * @param c Connection to get the ID from.
+ *
+ * @return ID of the connection.
+ */
+const struct GNUNET_HashCode *
+GMC_get_id (const struct MeshConnection *c)
+{
+ return &c->id;
+}
+
/**
* Notify other peers on a connection of a broken link. Mark connections
* to destroy after all traffic has been sent.
#include "gnunet_util_lib.h"
+#include "gnunet-service-mesh_channel.h"
+
/**
* Struct containing all information regarding a connection to a peer.
*/
/**
* Create a connection.
*
- * @param cid Connection ID.
+ * @param cid Connection ID (either created locally or imposed remotely).
+ * @param t Tunnel this connection belongs to (or NULL);
+ * @param p Path this connection has to use.
+ * @param own_pos Own position in the @c p path.
*/
struct MeshConnection *
-GMC_new (const struct GNUNET_HashCode *cid);
+GMC_new (const struct GNUNET_HashCode *cid,
+ struct MeshTunnel2 *t,
+ struct MeshPeerPath *p,
+ unsigned int own_pos);
/**
* Connection is no longer needed: destroy it and remove from tunnel.
void
GMC_destroy (struct MeshConnection *c);
+/**
+ * Get the connection ID.
+ *
+ * @param c Connection to get the ID from.
+ *
+ * @return ID of the connection.
+ */
+const struct GNUNET_HashCode *
+GMC_get_id (const struct MeshConnection *c);
+
/**
* Count connections in a DLL.
*/
#include "gnunet-service-mesh_dht.h"
#include "gnunet-service-mesh_connection.h"
#include "gnunet-service-mesh_local.h"
+#include "gnunet-service-mesh_tunnel.h"
#include "mesh_path.h"
#define LOG(level, ...) GNUNET_log_from (level,"mesh-p2p",__VA_ARGS__)
GMP_shutdown (void)
{
GNUNET_CONTAINER_multipeermap_iterate (peers, &shutdown_tunnel, NULL);
+
+ if (core_handle != NULL)
+ {
+ GNUNET_CORE_disconnect (core_handle);
+ core_handle = NULL;
+ }
}
" Starting DHT GET for peer %s\n", peer2s (peer));
peer->search_h = GMD_search (id, &search_handler, peer);
if (MESH_TUNNEL_NEW == t->state)
- tunnel_change_state (t, MESH_TUNNEL_SEARCHING);
+ GMT_change_state (t, MESH_TUNNEL_SEARCHING);
+ }
+}
+
+
+/**
+ * Chech whether there is a direct (core level) connection to peer.
+ *
+ * @param peer Peer to check.
+ *
+ * @return GNUNET_YES if there is a direct connection.
+ */
+int
+GMP_is_neighbor (const struct MeshPeer *peer)
+{
+ struct MeshPeerPath *path;
+
+ if (NULL == peer->connections)
+ return GNUNET_NO;
+
+ for (path = peer->path_head; NULL != path; path = path->next)
+ {
+ if (3 > path->length)
+ return GNUNET_YES;
+ }
+
+ GNUNET_break (0); /* Is not a neighbor but connections is not NULL */
+ return GNUNET_NO;
+}
+
+
+/**
+ * Add a connection to a neighboring peer.
+ *
+ * Store that the peer is the first hop of the connection in one
+ * direction and that on peer disconnect the connection must be
+ * notified and destroyed, for it will no longer be valid.
+ *
+ * @param peer Peer to add connection to.
+ * @param c Connection to add.
+ *
+ * @return GNUNET_OK on success.
+ */
+int
+GMP_add_connection (struct MeshPeer *peer,
+ const struct MeshConnection *c)
+{
+ if (NULL == peer->connections)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
}
+ return GNUNET_CONTAINER_multihashmap_put (peer->connections,
+ GMC_get_id (c),
+ c,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
}
/**
void
GMP_queue_destroy (struct MeshPeerQueue *queue, int clear_cls);
+/**
+ * Chech whether there is a direct (core level) connection to peer.
+ *
+ * @param peer Peer to check.
+ *
+ * @return GNUNET_YES if there is a direct connection.
+ */
+int
+GMP_is_neighbor (const struct MeshPeer *peer);
+
+/**
+ * Add a connection to a neighboring peer.
+ *
+ * Store that the peer is the first hop of the connection in one
+ * direction and that on peer disconnect the connection must be
+ * notified and destroyed, for it will no longer be valid.
+ *
+ * @param peer Peer to add connection to.
+ * @param c Connection to add.
+ *
+ * @return GNUNET_OK on success.
+ */
+int
+GMP_add_connection (struct MeshPeer *peer, struct MeshConnection *c);
/**
* Get the static string for a peer ID.
#include "gnunet-service-mesh_tunnel.h"
#include "gnunet-service-mesh_connection.h"
#include "gnunet-service-mesh_channel.h"
+#include "gnunet-service-mesh_peer.h"
#include "mesh_path.h"
#define LOG(level, ...) GNUNET_log_from(level,"mesh-tun",__VA_ARGS__)
for (c = t->connection_head; NULL != c; c = c->next)
{
LOG (GNUNET_ERROR_TYPE_DEBUG, " connection %s: %u\n",
- GNUNET_h2s (&c->id), c->state);
+ GNUNET_h2s (GMC_get_id (c)), c->state);
if (MESH_CONNECTION_READY == c->state)
{
fc = fwd ? &c->fwd_fc : &c->bck_fc;
{
struct MeshConnection *c;
struct GNUNET_HashCode cid;
- struct MeshPeer *peer;
unsigned int own_pos;
if (NULL == t || NULL == p)
return NULL;
}
- GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, &cid);
-
- c = GMC_new (&cid);
- c->t = t;
- GNUNET_CONTAINER_DLL_insert (t->connection_head, t->connection_tail, c);
for (own_pos = 0; own_pos < p->length; own_pos++)
{
- if (p->peers[own_pos] == myid)
+ if (p->peers[own_pos] == my_short_id)
break;
}
if (own_pos > p->length - 1)
{
GNUNET_break (0);
- connection_destroy (c);
return NULL;
}
- c->own_pos = own_pos;
- c->path = p;
-
- if (0 == own_pos)
- {
- c->fwd_maintenance_task =
- GNUNET_SCHEDULER_add_delayed (refresh_connection_time,
- &connection_fwd_keepalive, c);
- }
- peer = connection_get_next_hop (c);
- if (NULL == peer->connections)
- {
- connection_destroy (c);
- return NULL;
- }
- GNUNET_CONTAINER_multihashmap_put (peer->connections, &c->id, c,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
- peer = connection_get_prev_hop (c);
- if (NULL == peer->connections)
- {
- connection_destroy (c);
- return NULL;
- }
- GNUNET_CONTAINER_multihashmap_put (peer->connections, &c->id, c,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
+ GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, &cid);
+ c = GMC_new (&cid, t, p, own_pos);
+ GNUNET_CONTAINER_DLL_insert (t->connection_head, t->connection_tail, c);
return c;
}
case GNUNET_MESSAGE_TYPE_MESH_BCK:
case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
- msg->cid = c->id;
+ msg->cid = *GMC_get_id (c);
msg->ttl = htonl (default_ttl);
break;
default: