예제 #1
0
/**
 * Return a newly allocated individual path to reach a peer from the local peer,
 * according to the path tree of some tunnel.
 *
 * @param t Tunnel from which to read the path tree.
 * @param peer Short ID of the destination peer to whom we want a path.
 *
 * @return A newly allocated individual path to reach the destination peer.
 *         Path must be destroyed afterwards.
 */
struct MeshPeerPath *
tree_get_path_to_peer (struct MeshTunnelTree *t, GNUNET_PEER_Id peer)
{
  struct MeshTunnelTreeNode *n;
  struct MeshPeerPath *p;

  n = tree_find_peer (t, peer);
  if (NULL == n)
  {
    GNUNET_break (0);
    return NULL;
  }
  p = path_new (0);

  /* Building the path (inverted!) */
  while (n->peer != 1)
  {
    GNUNET_array_append (p->peers, p->length, n->peer);
    GNUNET_PEER_change_rc (n->peer, 1);
    n = n->parent;
    if (NULL == n)
    {
      GNUNET_break (0);
      path_destroy (p);
      return NULL;
    }
  }
  GNUNET_array_append (p->peers, p->length, 1);
  GNUNET_PEER_change_rc (1, 1);

  path_invert (p);

  return p;
}
예제 #2
0
/**
 * Destroys and frees the node and all children
 *
 * @param parent Parent node to be destroyed
 */
static void
tree_node_destroy (struct MeshTunnelTreeNode *parent)
{
  struct MeshTunnelTreeNode *n;
  struct MeshTunnelTreeNode *next;

#if MESH_TREE_DEBUG
  struct GNUNET_PeerIdentity id;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: Destroying node %u\n",
              parent->peer);
  GNUNET_PEER_resolve (parent->peer, &id);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree:   (%s)\n", GNUNET_i2s (&id));
#endif
  n = parent->children_head;
  while (NULL != n)
  {
    next = n->next;
    tree_node_destroy (n);
    n = next;
  }
  GNUNET_PEER_change_rc (parent->peer, -1);
  if (NULL != parent->parent)
    GNUNET_CONTAINER_DLL_remove (parent->parent->children_head,
                                 parent->parent->children_tail, parent);
  GNUNET_free (parent);
}
예제 #3
0
/**
 * Duplicate a path, incrementing short peer's rc.
 *
 * @param path The path to duplicate.
 */
struct MeshPeerPath *
path_duplicate (struct MeshPeerPath *path)
{
  struct MeshPeerPath *aux;
  unsigned int i;

  aux = path_new (path->length);
  memcpy (aux->peers, path->peers, path->length * sizeof (GNUNET_PEER_Id));
  for (i = 0; i < path->length; i++)
    GNUNET_PEER_change_rc (path->peers[i], 1);
  return aux;
}
예제 #4
0
/**
 * Builds a path from a PeerIdentity array.
 *
 * @param peers PeerIdentity array.
 * @param size Size of the @c peers array.
 * @param myid ID of local peer, to find @c own_pos.
 * @param own_pos Output parameter: own position in the path.
 *
 * @return Fixed and shortened path.
 */
struct CadetPeerPath *
path_build_from_peer_ids (struct GNUNET_PeerIdentity *peers,
                          unsigned int size,
                          GNUNET_PEER_Id myid,
                          unsigned int *own_pos)
{
  struct CadetPeerPath *path;
  GNUNET_PEER_Id shortid;
  unsigned int i;
  unsigned int j;
  unsigned int offset;

  /* Create path */
  LOG (GNUNET_ERROR_TYPE_DEBUG, "  Creating path...\n");
  path = path_new (size);
  *own_pos = 0;
  offset = 0;
  for (i = 0; i < size; i++)
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG, "  - %u: taking %s\n",
         i, GNUNET_i2s (&peers[i]));
    shortid = GNUNET_PEER_intern (&peers[i]);

    /* Check for loops / duplicates */
    for (j = 0; j < i - offset; j++)
    {
      if (path->peers[j] == shortid)
      {
        LOG (GNUNET_ERROR_TYPE_DEBUG, "    already exists at pos %u\n", j);
        offset = i - j;
        LOG (GNUNET_ERROR_TYPE_DEBUG, "    offset now %u\n", offset);
        GNUNET_PEER_change_rc (shortid, -1);
      }
    }
    LOG (GNUNET_ERROR_TYPE_DEBUG, "    storing at %u\n", i - offset);
    path->peers[i - offset] = shortid;
    if (path->peers[i - offset] == myid)
      *own_pos = i - offset;
  }
  path->length -= offset;

  if (path->peers[*own_pos] != myid)
  {
    /* create path: self not found in path through self */
    GNUNET_break_op (0);
    path_destroy (path);
    return NULL;
  }

  return path;
}
예제 #5
0
/**
 * Allocates and initializes a new node.
 * Sets ID and parent of the new node and inserts it in the DLL of the parent
 *
 * @param parent Node that will be the parent from the new node, NULL for root
 * @param peer Short Id of the new node
 *
 * @return Newly allocated node
 */
static struct MeshTunnelTreeNode *
tree_node_new (struct MeshTunnelTreeNode *parent, GNUNET_PEER_Id peer)
{
  struct MeshTunnelTreeNode *node;

  node = GNUNET_malloc (sizeof (struct MeshTunnelTreeNode));
  node->peer = peer;
  GNUNET_PEER_change_rc (peer, 1);
  node->parent = parent;
  if (NULL != parent)
    GNUNET_CONTAINER_DLL_insert (parent->children_head, parent->children_tail,
                                 node);

  return node;
}
예제 #6
0
static int
check ()
{
  int i;
  GNUNET_PEER_Id pid;
  struct GNUNET_PeerIdentity res;
  struct GNUNET_PeerIdentity zero;
  GNUNET_PEER_Id ids[] = { 1, 2, 3 };

  GNUNET_assert (0 == GNUNET_PEER_intern (NULL));
  /* Insert Peers into PeerEntry table and hashmap */
  for (i = 0; i < NUMBER_OF_PEERS; i++)
  {
    pid = GNUNET_PEER_intern (&pidArr[i]);
    if (pid != (i + 1))
    {
      FPRINTF (stderr, "%s",  "Unexpected Peer ID returned by intern function\n");
      return 1;
    }
  }

  /* Referencing the first 3 peers once again */
  for (i = 0; i < 3; i++)
  {
    pid = GNUNET_PEER_intern (&pidArr[i]);
    if (pid != (i + 1))
    {
      FPRINTF (stderr, "%s",  "Unexpected Peer ID returned by intern function\n");
      return 1;
    }
  }

  /* Dereferencing the first 3 peers once [decrementing their reference count] */
  GNUNET_PEER_decrement_rcs (ids, 3);

  /* re-referencing the first 3 peers using the change_rc function */
  for (i = 1; i <= 3; i++)
    GNUNET_PEER_change_rc (i, 1);

  /* Removing the second Peer from the PeerEntry hash map */
  GNUNET_PEER_change_rc (2, -2);

  /* convert the pid of the first PeerEntry into that of the third */
  GNUNET_PEER_resolve (1, &res);
  GNUNET_assert (0 == memcmp (&res, &pidArr[0], sizeof (res)));

  /*
   * Attempt to convert pid = 0 (which is reserved)
   * into a peer identity object, the peer identity memory
   * is expected to be set to zero
   */
  memset (&zero, 0, sizeof (struct GNUNET_PeerIdentity));
  GNUNET_log_skip (1, GNUNET_YES);
  GNUNET_PEER_resolve (0, &res);
  GNUNET_assert (0 == memcmp (&res, &zero, sizeof (res)));

  /* Removing peer entries 1 and 3 from table using the list decrement function */
  /* If count = 0, nothing should be done whatsoever */
  GNUNET_PEER_decrement_rcs (ids, 0);

  ids[1] = 3;
  GNUNET_PEER_decrement_rcs (ids, 2);
  GNUNET_PEER_decrement_rcs (ids, 2);

  return 0;
}