Example #1
0
/**
 * Removes a queue entry of an operation from one of the operation queues' lists
 * depending on the state of the operation
 *
 * @param op the operation whose entry has to be removed
 * @param index the index of the entry in the operation's array of queue entries
 */
static void
remove_queue_entry (struct GNUNET_TESTBED_Operation *op, unsigned int index)
{
  struct OperationQueue *opq;
  struct QueueEntry *entry;

  opq = op->queues[index];
  entry = op->qentries[index];
  switch (op->state)
  {
  case OP_STATE_INIT:
    GNUNET_assert (0);
    break;
  case OP_STATE_WAITING:
    GNUNET_CONTAINER_DLL_remove (opq->wq_head, opq->wq_tail, entry);
    break;
  case OP_STATE_READY:
    GNUNET_CONTAINER_DLL_remove (opq->rq_head, opq->rq_tail, entry);
    break;
  case OP_STATE_ACTIVE:
    GNUNET_CONTAINER_DLL_remove (opq->aq_head, opq->aq_tail, entry);
    break;
  case OP_STATE_INACTIVE:
    GNUNET_CONTAINER_DLL_remove (opq->nq_head, opq->nq_tail, entry);
    break;
  }
}
/**
 * Notifies a tree that a connection it might be using is broken.
 * Marks all peers down the paths as disconnected and notifies the client.
 *
 * @param t Tree to use.
 * @param p1 Short id of one of the peers (order unimportant)
 * @param p2 Short id of one of the peers (order unimportant)
 * @param cb Function to call for every peer that is marked as disconnected.
 * @param cbcls Closure for cb.
 *
 * @return Short ID of the first disconnected peer in the tree.
 */
GNUNET_PEER_Id
tree_notify_connection_broken (struct MeshTunnelTree *t, GNUNET_PEER_Id p1,
                               GNUNET_PEER_Id p2, MeshTreeCallback cb,
                               void *cbcls)
{
  struct MeshTunnelTreeNode *n;
  struct MeshTunnelTreeNode *c;

  n = tree_find_peer (t, p1);
  if (NULL == n)
    return 0;
  if (NULL != n->parent && n->parent->peer == p2)
  {
    tree_mark_peers_disconnected (t, n, cb, cbcls);
    GNUNET_CONTAINER_DLL_remove (n->parent->children_head,
                                 n->parent->children_tail, n);
    GNUNET_CONTAINER_DLL_insert (t->disconnected_head, t->disconnected_tail, n);
    return p1;
  }
  for (c = n->children_head; NULL != c; c = c->next)
  {
    if (c->peer == p2)
    {
      tree_mark_peers_disconnected (t, c, cb, cbcls);
      GNUNET_CONTAINER_DLL_remove (n->children_head, n->children_tail, c);
      GNUNET_CONTAINER_DLL_insert (t->disconnected_head, t->disconnected_tail,
                                   c);
      return p2;
    }
  }
  return 0;
}
static void
stop_report_addresses (struct Plugin *plugin)
{
  /* Stop NAT handle */
  GNUNET_NAT_unregister (plugin->nat);

  /* Clean up addresses */
  struct IPv4HttpAddressWrapper *w_t4;
  struct IPv6HttpAddressWrapper *w_t6;

  while (plugin->ipv4_addr_head != NULL)
  {
    w_t4 = plugin->ipv4_addr_head;
    GNUNET_CONTAINER_DLL_remove (plugin->ipv4_addr_head, plugin->ipv4_addr_tail,
                                 w_t4);
    GNUNET_free (w_t4);
  }

  while (plugin->ipv6_addr_head != NULL)
  {
    w_t6 = plugin->ipv6_addr_head;
    GNUNET_CONTAINER_DLL_remove (plugin->ipv6_addr_head, plugin->ipv6_addr_tail,
                                 w_t6);
    GNUNET_free (w_t6);
  }
}
Example #4
0
/**
 * Cancel the specified transmission-ready notification.
 *
 * @param th handle that was returned by "notify_transmit_ready".
 */
void
GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle *th)
{
  struct PeerRecord *pr = th->peer;
  struct GNUNET_CORE_Handle *h;

  GNUNET_assert (NULL != th);
  GNUNET_assert (NULL != pr);
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Aborting transmission request to core for %u bytes to `%s'\n",
       (unsigned int) th->msize,
       GNUNET_i2s (&pr->peer));
  th->peer = NULL;
  h = pr->ch;
  if (NULL != th->cm)
  {
    /* we're currently in the control queue, remove */
    GNUNET_CONTAINER_DLL_remove (h->control_pending_head,
                                 h->control_pending_tail, th->cm);
    GNUNET_free (th->cm);
    th->cm = NULL;
  }
  if ((NULL != pr->prev) || (NULL != pr->next) || (pr == h->ready_peer_head))
  {
    /* the request that was 'approved' by core was
     * canceled before it could be transmitted; remove
     * us from the 'ready' list */
    GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr);
  }
  if (GNUNET_SCHEDULER_NO_TASK != pr->ntr_task)
  {
    GNUNET_SCHEDULER_cancel (pr->ntr_task);
    pr->ntr_task = GNUNET_SCHEDULER_NO_TASK;
  }
}
Example #5
0
File: mq.c Project: tg-x/gnunet
/**
 * Cancel sending the message. Message must have been sent with
 * #GNUNET_MQ_send before.  May not be called after the notify sent
 * callback has been called
 *
 * @param ev queued envelope to cancel
 */
void
GNUNET_MQ_send_cancel (struct GNUNET_MQ_Envelope *ev)
{
  struct GNUNET_MQ_Handle *mq = ev->parent_queue;

  GNUNET_assert (NULL != mq);
  GNUNET_assert (NULL != mq->cancel_impl);

  if (mq->current_envelope == ev) {
    // complex case, we already started with transmitting
    // the message
    mq->cancel_impl (mq, mq->impl_state);
    // continue sending the next message, if any
    if (NULL == mq->envelope_head)
    {
      mq->current_envelope = NULL;
    }
    else
    {
      mq->current_envelope = mq->envelope_head;
      GNUNET_CONTAINER_DLL_remove (mq->envelope_head,
                                   mq->envelope_tail,
                                   mq->current_envelope);
      mq->send_impl (mq, mq->current_envelope->mh, mq->impl_state);
    }
  } else {
    // simple case, message is still waiting in the queue
    GNUNET_CONTAINER_DLL_remove (mq->envelope_head, mq->envelope_tail, ev);
  }

  ev->parent_queue = NULL;
  ev->mh = NULL;
  GNUNET_free (ev);
}
Example #6
0
/**
 * Stop an active NAT test.
 *
 * @param tst test to stop.
 */
void
GNUNET_NAT_test_stop (struct GNUNET_NAT_Test *tst)
{
  struct NatActivity *pos;
  struct ClientActivity *cpos;

  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Stopping NAT test\n");
  while (NULL != (cpos = tst->ca_head))
  {
    GNUNET_CONTAINER_DLL_remove (tst->ca_head, tst->ca_tail, cpos);
    GNUNET_CLIENT_disconnect (cpos->client);
    GNUNET_free (cpos);
  }
  while (NULL != (pos = tst->na_head))
  {
    GNUNET_CONTAINER_DLL_remove (tst->na_head, tst->na_tail, pos);
    GNUNET_SCHEDULER_cancel (pos->rtask);
    GNUNET_NETWORK_socket_close (pos->sock);
    GNUNET_free (pos);
  }
  if (NULL != tst->ttask)
    GNUNET_SCHEDULER_cancel (tst->ttask);
  if (NULL != tst->ltask)
    GNUNET_SCHEDULER_cancel (tst->ltask);
  if (NULL != tst->lsock)
    GNUNET_NETWORK_socket_close (tst->lsock);
  if (NULL != tst->nat)
    GNUNET_NAT_unregister (tst->nat);
  GNUNET_free (tst);
}
Example #7
0
/**
 * Cancel a PSYCstore operation. Note that the operation MAY still
 * be executed; this merely cancels the continuation; if the request
 * was already transmitted, the service may still choose to complete
 * the operation.
 *
 * @param op Operation to cancel.
 */
void
GNUNET_PSYCSTORE_operation_cancel (struct GNUNET_PSYCSTORE_OperationHandle *op)
{
  struct GNUNET_PSYCSTORE_Handle *h = op->h;

  if (h->transmit_head != NULL && (h->transmit_head != op || NULL == h->client))
  {
    /* request not active, can simply remove */
    GNUNET_CONTAINER_DLL_remove (h->transmit_head, h->transmit_tail, op);
    GNUNET_free (op);
    return;
  }
  if (NULL != h->th)
  {
    /* request active but not yet with service, can still abort */
    GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
    h->th = NULL;
    GNUNET_CONTAINER_DLL_remove (h->transmit_head, h->transmit_tail, op);
    GNUNET_free (op);
    transmit_next (h);
    return;
  }
  /* request active with service, simply ensure continuations are not called */
  op->res_cb = NULL;
  op->data_cb = NULL;
}
Example #8
0
/**
 * Message timed out. Remove it from the queue.
 *
 * @param cls the message (struct ARMControlMessage *)
 * @param tc task context
 */
static void
control_message_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct ARMControlMessage *cm = cls;
  struct GNUNET_ARM_Message *arm_msg;

  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Control message timed out\n");
  arm_msg = cm->msg;
  if ((NULL == arm_msg) || (0 == arm_msg->request_id))
  {
    GNUNET_CONTAINER_DLL_remove (cm->h->control_pending_head,
                                 cm->h->control_pending_tail, cm);
  }
  else
  {
    GNUNET_CONTAINER_DLL_remove (cm->h->control_sent_head,
                                 cm->h->control_sent_tail, cm);
  }
  if (NULL != cm->result_cont)
    cm->result_cont (cm->cont_cls, GNUNET_ARM_REQUEST_TIMEOUT, NULL, 0);
  else if (NULL != cm->list_cont)
    cm->list_cont (cm->cont_cls, GNUNET_ARM_REQUEST_TIMEOUT, 0, NULL);
  GNUNET_free_non_null (cm->msg);
  GNUNET_free (cm);
}
/**
 * Delete the current path to the peer, including all now unused relays.
 * The destination peer is NOT destroyed, it is returned in order to either set
 * a new path to it or destroy it explicitly, taking care of it's child nodes.
 *
 * @param t Tunnel tree where to delete the path from.
 * @param peer_id Short ID of the destination peer whose path we want to remove.
 * @param cb Callback to use to notify about disconnected peers.
 * @param cbcls Closure for cb.
 *
 * @return pointer to the pathless node.
 *         NULL when not found
 */
struct MeshTunnelTreeNode *
tree_del_path (struct MeshTunnelTree *t, GNUNET_PEER_Id peer_id,
               MeshTreeCallback cb, void *cbcls)
{
  struct MeshTunnelTreeNode *parent;
  struct MeshTunnelTreeNode *node;
  struct MeshTunnelTreeNode *n;

#if MESH_TREE_DEBUG
  struct GNUNET_PeerIdentity id;

  GNUNET_PEER_resolve (peer_id, &id);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree:   Deleting path to %s.\n",
              GNUNET_i2s (&id));
#endif
  if (peer_id == t->root->peer)
    return NULL;

  for (n = t->disconnected_head; NULL != n; n = n->next)
  {
    if (n->peer == peer_id)
    {
      /* Was already pathless, waiting for reconnection */
      GNUNET_CONTAINER_DLL_remove (t->disconnected_head, t->disconnected_tail,
                                   n);
      return n;
    }
  }
  n = tree_find_peer (t, peer_id);
  if (NULL == n)
    return NULL;
  node = n;

  parent = n->parent;
  GNUNET_CONTAINER_DLL_remove (parent->children_head, parent->children_tail, n);
  n->parent = NULL;

  while (MESH_PEER_RELAY == parent->status && NULL == parent->children_head)
  {
#if MESH_TREE_DEBUG
    GNUNET_PEER_resolve (parent->peer, &id);
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree:   Deleting node %s.\n",
                GNUNET_i2s (&id));
#endif
    n = parent->parent;
    tree_node_destroy (parent);
    parent = n;
  }
#if MESH_TREE_DEBUG
  GNUNET_PEER_resolve (parent->peer, &id);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree:   Not deleted peer %s.\n",
              GNUNET_i2s (&id));
#endif

  tree_mark_peers_disconnected (t, node, cb, cbcls);

  return node;
}
static void
nat_remove_address (void *cls, int add_remove, const struct sockaddr *addr,
                    socklen_t addrlen)
{
  struct Plugin *plugin = cls;
  struct IPv4HttpAddressWrapper *w_t4 = NULL;
  struct IPv6HttpAddressWrapper *w_t6 = NULL;
  int af;

  af = addr->sa_family;
  switch (af)
  {
  case AF_INET:
    w_t4 = find_address (plugin, addr, addrlen);
    if (w_t4 == NULL)
      return;


    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
                     "Notifying transport to remove IPv4 address `%s'\n",
                     http_plugin_address_to_string (NULL, &w_t4->addr,
                                                    sizeof (struct
                                                            IPv4HttpAddress)));
    plugin->env->notify_address (plugin->env->cls, add_remove, &w_t4->addr,
                                 sizeof (struct IPv4HttpAddress));

    GNUNET_CONTAINER_DLL_remove (plugin->ipv4_addr_head, plugin->ipv4_addr_tail,
                                 w_t4);
    GNUNET_free (w_t4);
    break;
  case AF_INET6:
    w_t6 = find_address (plugin, addr, addrlen);
    if (w_t6 == NULL)
      return;

    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
                     "Notifying transport to remove IPv6 address `%s'\n",
                     http_plugin_address_to_string (NULL, &w_t6->addr6,
                                                    sizeof (struct
                                                            IPv6HttpAddress)));

    plugin->env->notify_address (plugin->env->cls, add_remove, &w_t6->addr6,
                                 sizeof (struct IPv6HttpAddress));

    GNUNET_CONTAINER_DLL_remove (plugin->ipv6_addr_head, plugin->ipv6_addr_tail,
                                 w_t6);
    GNUNET_free (w_t6);
    break;
  default:
    return;
  }
}
/**
 * End the session with the given peer (we are no longer
 * connected).
 *
 * @param pid identity of peer to kill session with
 */
void
GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid)
{
  struct Session *session;
  struct GSC_ClientActiveRequest *car;
  struct SessionMessageEntry *sme;

  session = find_session (pid);
  if (NULL == session)
    return;
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Destroying session for peer `%4s'\n",
              GNUNET_i2s (&session->peer));
  if (NULL != session->cork_task)
  {
    GNUNET_SCHEDULER_cancel (session->cork_task);
    session->cork_task = NULL;
  }
  while (NULL != (car = session->active_client_request_head))
  {
    GNUNET_CONTAINER_DLL_remove (session->active_client_request_head,
                                 session->active_client_request_tail, car);
    GSC_CLIENTS_reject_request (car,
                                GNUNET_NO);
  }
  while (NULL != (sme = session->sme_head))
  {
    GNUNET_CONTAINER_DLL_remove (session->sme_head,
                                 session->sme_tail,
                                 sme);
    GNUNET_free (sme);
  }
  if (NULL != session->typemap_task)
  {
    GNUNET_SCHEDULER_cancel (session->typemap_task);
    session->typemap_task = NULL;
  }
  GSC_CLIENTS_notify_clients_about_neighbour (&session->peer,
                                              session->tmap, NULL);
  GNUNET_assert (GNUNET_YES ==
                 GNUNET_CONTAINER_multipeermap_remove (sessions,
                                                       &session->peer,
                                                       session));
  GNUNET_STATISTICS_set (GSC_stats, gettext_noop ("# peers connected"),
                         GNUNET_CONTAINER_multipeermap_size (sessions),
                         GNUNET_NO);
  GSC_TYPEMAP_destroy (session->tmap);
  session->tmap = NULL;
  GNUNET_free (session);
}
Example #12
0
/**
 * Cancel pending lookup request
 *
 * @param lr the lookup request to cancel
 */
void
GNUNET_GNS_cancel_lookup_request (struct GNUNET_GNS_LookupRequest *lr)
{
  struct PendingMessage *p = (struct PendingMessage*) &lr[1];

  GNUNET_assert (NULL != lr->gns_handle); 
  if (GNUNET_NO == p->transmitted)
    GNUNET_CONTAINER_DLL_remove (lr->gns_handle->pending_head,
                                 lr->gns_handle->pending_tail,
                                 p);
  GNUNET_CONTAINER_DLL_remove (lr->gns_handle->lookup_head,
                               lr->gns_handle->lookup_tail,
                               lr);
  GNUNET_free (lr);
}
Example #13
0
/**
 * Cancel pending shorten request
 *
 * @param sr the lookup request to cancel
 */
void
GNUNET_GNS_cancel_shorten_request (struct GNUNET_GNS_ShortenRequest *sr)
{
  struct PendingMessage *p = (struct PendingMessage*) &sr[1];

  GNUNET_assert (NULL != sr->gns_handle);
  if (GNUNET_NO == p->transmitted)
    GNUNET_CONTAINER_DLL_remove (sr->gns_handle->pending_head,
                                 sr->gns_handle->pending_tail,
                                 p);
  GNUNET_CONTAINER_DLL_remove (sr->gns_handle->shorten_head,
                               sr->gns_handle->shorten_tail,
                               sr);
  GNUNET_free (sr);
}
Example #14
0
File: dv_api.c Project: tg-x/gnunet
/**
 * Abort send operation (naturally, the message may have
 * already been transmitted; this only stops the 'cb'
 * from being called again).
 *
 * @param th send operation to cancel
 */
void
GNUNET_DV_send_cancel (struct GNUNET_DV_TransmitHandle *th)
{
  struct GNUNET_DV_ServiceHandle *sh = th->sh;

  if (NULL == th->msg)
    GNUNET_CONTAINER_DLL_remove (th->target->head,
				 th->target->tail,
				 th);
  else
    GNUNET_CONTAINER_DLL_remove (sh->th_head,
				 sh->th_tail,
				 th);
  GNUNET_free (th);
}
Example #15
0
/**
 * Cancel pending get auth  request
 *
 * @param gar the lookup request to cancel
 */
void
GNUNET_GNS_cancel_get_auth_request (struct GNUNET_GNS_GetAuthRequest *gar)
{
  struct PendingMessage *p = (struct PendingMessage*) &gar[1];

  GNUNET_assert (NULL != gar->gns_handle); 
  if (GNUNET_NO == p->transmitted)
    GNUNET_CONTAINER_DLL_remove (gar->gns_handle->pending_head,
                                 gar->gns_handle->pending_tail,
                                 p);  
  GNUNET_CONTAINER_DLL_remove (gar->gns_handle->get_auth_head,
                               gar->gns_handle->get_auth_tail,
                               gar);
  GNUNET_free (gar);
}
/**
 * Add or remove an address from this peer's HELLO message.
 *
 * @param addremove GNUNET_YES to add, GNUNET_NO to remove
 * @param address address to add or remove
 */
void
GST_hello_modify_addresses (int addremove,
                            const struct GNUNET_HELLO_Address *address)
{
  struct OwnAddressList *al;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              (addremove ==
               GNUNET_YES) ? "Adding `%s' to the set of our addresses\n" :
              "Removing `%s' from the set of our addresses\n",
              GST_plugins_a2s (address));
  GNUNET_assert (address != NULL);
  if (GNUNET_NO == addremove)
  {
    for (al = oal_head; al != NULL; al = al->next)
      if (0 == GNUNET_HELLO_address_cmp (address, al->address))
      {
        GNUNET_CONTAINER_DLL_remove (oal_head, oal_tail, al);
        GNUNET_HELLO_address_free (al->address);
        GNUNET_free (al);
        refresh_hello ();
        return;
      }
    /* address to be removed not found!? */
    GNUNET_break (0);
    return;
  }
  al = GNUNET_malloc (sizeof (struct OwnAddressList));
  GNUNET_CONTAINER_DLL_insert (oal_head, oal_tail, al);
  al->address = GNUNET_HELLO_address_copy (address);
  refresh_hello ();
}
Example #17
0
/**
 * Iterate over all nodes in the tree.
 *
 * @param tree Tree to use..
 * @param cb Callback to call over each child.
 * @param cb_cls Closure for @c cb.
 *
 * TODO: recursive implementation? (s/heap/stack/g)
 */
void
tree_iterate_all (struct MeshTunnelTree *tree,
                  MeshWholeTreeCallback cb,
                  void *cb_cls)
{
  struct MeshTunnelTreeNode *parent;
  struct MeshTunnelTreeNode *n;
  struct MeshTreePendingNode *head;
  struct MeshTreePendingNode *tail;
  struct MeshTreePendingNode *pending;

  cb (cb_cls, tree->root->peer, 0);
  pending = GNUNET_malloc (sizeof (struct MeshTreePendingNode));
  pending->node = tree->root;
  head = tail = NULL;
  GNUNET_CONTAINER_DLL_insert (head, tail, pending);

  while (NULL != head)
  {
    pending = head;
    parent = pending->node;
    GNUNET_CONTAINER_DLL_remove (head, tail, pending);
    GNUNET_free (pending);
    for (n = parent->children_head; NULL != n; n = n->next)
    {
      cb (cb_cls, n->peer, parent->peer);
      pending = GNUNET_malloc (sizeof (struct MeshTreePendingNode));
      pending->node = n;
      /* Insert_tail: breadth first, Insert: depth first */
      GNUNET_CONTAINER_DLL_insert (head, tail, pending);
    }
  }
}
Example #18
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);
}
Example #19
0
/**
 * A client disconnected.  Remove all of its data structure entries.
 *
 * @param cls closure, NULL
 * @param client identification of the client
 */
static void
handle_client_disconnect (void *cls,
                          struct GNUNET_SERVER_Client *client)
{
  struct ClientEntry *ce;
  struct ClientEntry *nx;

  nx = client_head;
  for (ce = nx; NULL != ce; ce = nx)
  {
    nx = ce->next;
    if (ce->client == client)
    {
      if (NULL != ce->refresh_task)
      {
	GNUNET_SCHEDULER_cancel (ce->refresh_task);
	ce->refresh_task = NULL;
      }
      if (NULL != ce->ah)
      {
	REGEX_INTERNAL_announce_cancel (ce->ah);
	ce->ah = NULL;
      }
      if (NULL != ce->sh)
      {
	REGEX_INTERNAL_search_cancel (ce->sh);
	ce->sh = NULL;
      }
      GNUNET_CONTAINER_DLL_remove (client_head,
                                   client_tail,
                                   ce);
      GNUNET_free (ce);
    }
  }
}
Example #20
0
/**
 * Task run during shutdown.
 *
 * @param cls unused
 * @param tc unused
 */
static void
shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct Ego *e;

  if (NULL != nc)
  {
    GNUNET_SERVER_notification_context_destroy (nc);
    nc = NULL;
  }
  if (NULL != stats)
  {
    GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
    stats = NULL;
  }
  GNUNET_CONFIGURATION_destroy (subsystem_cfg);
  subsystem_cfg = NULL;
  GNUNET_free (subsystem_cfg_file);
  subsystem_cfg_file = NULL;
  GNUNET_free (ego_directory);
  ego_directory = NULL;
  while (NULL != (e = ego_head))
  {
    GNUNET_CONTAINER_DLL_remove (ego_head, ego_tail, e);
    GNUNET_free (e->pk);
    GNUNET_free (e->identifier);
    GNUNET_free (e);
  }
}
/**
 * Kill a #Slave object
 *
 * @param slave the #Slave object
 */
static void
kill_slave (struct Slave *slave)
{
  struct HostRegistration *hr_entry;

  while (NULL != (hr_entry = slave->hr_dll_head))
  {
    GNUNET_CONTAINER_DLL_remove (slave->hr_dll_head, slave->hr_dll_tail,
                                 hr_entry);
    GNUNET_free (hr_entry);
  }
  if (NULL != slave->rhandle)
    GNUNET_TESTBED_cancel_registration (slave->rhandle);
  GNUNET_assert (GNUNET_SYSERR !=
                 GNUNET_CONTAINER_multihashmap_iterate (slave->reghost_map,
                                                        reghost_free_iterator,
                                                        slave));
  GNUNET_CONTAINER_multihashmap_destroy (slave->reghost_map);
  if (NULL != slave->controller)
    GNUNET_TESTBED_controller_disconnect (slave->controller);
  if (NULL != slave->controller_proc)
  {
    LOG_DEBUG ("Stopping a slave\n");
    GNUNET_TESTBED_controller_kill_ (slave->controller_proc);
  }
}
/**
 * Cleans up the queue used for forwarding link controllers requests
 */
void
GST_free_lcf ()
{
  struct LCFContext *lcf;

  if (NULL != lcf_head)
  {
    if (NULL != lcf_proc_task_id)
    {
      GNUNET_SCHEDULER_cancel (lcf_proc_task_id);
      lcf_proc_task_id = NULL;
    }
  }
  GNUNET_assert (NULL == lcf_proc_task_id);
  for (lcf = lcf_head; NULL != lcf; lcf = lcf_head)
  {
    if (NULL != lcf->op)
      GNUNET_TESTBED_operation_done (lcf->op);
    if (NULL != lcf->timeout_task)
      GNUNET_SCHEDULER_cancel (lcf->timeout_task);
    GNUNET_CONTAINER_DLL_remove (lcf_head,
                                 lcf_tail,
                                 lcf);
    GNUNET_free (lcf);
  }
}
/**
 * Cancel the request for opening a connection to the neighbour
 *
 * @param h the notification handle
 */
void
GST_neighbour_get_connection_cancel (struct NeighbourConnectNotification *h)
{
  struct Neighbour *n;
  int cleanup_task;

  n = h->n;
  cleanup_task = (h == n->nl_head) ? GNUNET_YES : GNUNET_NO;
  GNUNET_CONTAINER_DLL_remove (n->nl_head, n->nl_tail, h);
  GNUNET_free (h);
  if (GNUNET_NO == cleanup_task)
    return;
  if (NULL == n->notify_task)
    return;
  GNUNET_assert (0 < n->reference_cnt);
  n->reference_cnt--;
  GNUNET_SCHEDULER_cancel (n->notify_task);
  n->notify_task = NULL;
  if (NULL == n->nl_head)
  {
    if ( (0 == n->reference_cnt) && (0 == n->inactive) )
    {
      n->inactive = 1;
      GNUNET_TESTBED_operation_inactivate_ (n->conn_op);
    }
    return;
  }
  trigger_notifications (n);
}
Example #24
0
/**
 * Stop monitoring.
 *
 * @param handle The handle to the monitor request returned by monitor_start.
 *
 * On return get_handle will no longer be valid, caller must not use again!!!
 */
void
GNUNET_DHT_monitor_stop (struct GNUNET_DHT_MonitorHandle *handle)
{
  struct GNUNET_DHT_MonitorStartStopMessage *m;
  struct PendingMessage *pending;

  GNUNET_CONTAINER_DLL_remove (handle->dht_handle->monitor_head,
                               handle->dht_handle->monitor_tail,
                               handle);

  pending = GNUNET_malloc (sizeof (struct GNUNET_DHT_MonitorStartStopMessage) +
                           sizeof (struct PendingMessage));
  m = (struct GNUNET_DHT_MonitorStartStopMessage *) &pending[1];
  pending->msg = &m->header;
  pending->handle = handle->dht_handle;
  pending->free_on_send = GNUNET_YES;
  m->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP);
  m->header.size = htons (sizeof (struct GNUNET_DHT_MonitorStartStopMessage));
  m->type = htonl(handle->type);
  m->get = htons(NULL != handle->get_cb);
  m->get_resp = htons(NULL != handle->get_resp_cb);
  m->put = htons(NULL != handle->put_cb);
  if (NULL != handle->key) {
    m->filter_key = htons(1);
    memcpy (&m->key, handle->key, sizeof(GNUNET_HashCode));
  }
  GNUNET_CONTAINER_DLL_insert (handle->dht_handle->pending_head,
                               handle->dht_handle->pending_tail,
                               pending);
  pending->in_pending_queue = GNUNET_YES;
  process_pending_messages (handle->dht_handle);
  
  GNUNET_free_non_null (handle->key);
  GNUNET_free (handle);
}
Example #25
0
File: dv_api.c Project: tg-x/gnunet
/**
 * Disconnect from DV service.
 *
 * @param sh service handle
 */
void
GNUNET_DV_service_disconnect (struct GNUNET_DV_ServiceHandle *sh)
{
  struct GNUNET_DV_TransmitHandle *pos;

  if (NULL == sh)
    return;
  if (NULL != sh->th)
  {
    GNUNET_CLIENT_notify_transmit_ready_cancel (sh->th);
    sh->th = NULL;
  }
  while (NULL != (pos = sh->th_head))
  {
    GNUNET_CONTAINER_DLL_remove (sh->th_head,
				 sh->th_tail,
				 pos);
    GNUNET_free (pos);
  }
  if (NULL != sh->client)
  {
    GNUNET_CLIENT_disconnect (sh->client);
    sh->client = NULL;
  }
  GNUNET_CONTAINER_multipeermap_iterate (sh->peers,
					 &cleanup_send_cb,
					 sh);
  GNUNET_CONTAINER_multipeermap_destroy (sh->peers);
  GNUNET_free (sh);
}
/**
 * Destroy a given client peer context
 *
 * @param cp client peer context
 */
static void
destroy_clientpeer (struct ClientPeerContext *cp)
{
  struct PendingMessage *pm;

  cp->destroying = GNUNET_YES;
  if (NULL != cp->th)
  {
    GNUNET_CADET_notify_transmit_ready_cancel (cp->th);
    cp->th = NULL;
  }
  pm = cp->pm_head;
  while (NULL != pm)
  {
    GNUNET_CONTAINER_DLL_remove (cp->pm_head, cp->pm_tail, pm);
    GNUNET_free (pm->msg);
    GNUNET_free (pm);
    pm = cp->pm_head;
  }
  if (NULL != cp->ch)
  {
    GNUNET_CADET_channel_destroy (cp->ch);
    cp->ch = NULL;
  }
  GNUNET_free (cp);
}
/**
 * Function called to notify a client about the socket
 * begin ready to queue more data.  "buf" will be
 * NULL and "size" zero if the socket was closed for
 * writing in the meantime.
 *
 * @param cls closure
 * @param size number of bytes available in buf
 * @param buf where the callee should write the message
 * @return number of bytes written to buf
 */
static size_t
transmit_callback (void *cls, size_t size, void *buf)
{
  struct TransmitCallbackContext *tcc = cls;
  size_t msize;

  tcc->th = NULL;
  GNUNET_CONTAINER_DLL_remove (tcc_head, tcc_tail, tcc);
  msize = ntohs (tcc->msg->size);
  if (size == 0)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                _("Transmission to client failed!\n"));
    GNUNET_SERVER_receive_done (tcc->client, GNUNET_SYSERR);
    GNUNET_SERVER_client_drop (tcc->client);
    GNUNET_free (tcc->msg);
    GNUNET_free (tcc);
    return 0;
  }
  GNUNET_assert (size >= msize);
  memcpy (buf, tcc->msg, msize);
  GNUNET_SERVER_receive_done (tcc->client, GNUNET_OK);
  GNUNET_SERVER_client_drop (tcc->client);
  GNUNET_free (tcc->msg);
  GNUNET_free (tcc);
  return msize;
}
/**
 * Task run during shutdown.
 *
 * @param cls unused
 * @param tc unused
 */
static void
cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct ClientPeerContext *cp;

  cp = cp_head;
  while (NULL != cp)
  {
    GNUNET_CONTAINER_DLL_remove (cp_head, cp_tail, cp);
    destroy_clientpeer (cp);
    cp = cp_head;
  }
  if (NULL != cadet)
  {
    GNUNET_CADET_disconnect (cadet);
    cadet = NULL;
  }
  if (NULL != peerstore)
  {
    GNUNET_PEERSTORE_disconnect (peerstore, GNUNET_YES);
    peerstore = NULL;
  }
  GNUNET_SENSOR_destroy_sensors (sensors);
  if (NULL != sensor_dir)
  {
    GNUNET_free (sensor_dir);
    sensor_dir = NULL;
  }
  GNUNET_SCHEDULER_shutdown ();
}
/**
 * Callback called as a result of issuing a GNUNET_SERVER_notify_transmit_ready
 * request.  A ClientList is passed as closure, take the head of the list
 * and copy it into buf, which has the result of sending the message to the
 * client.
 *
 * @param cls closure to this call
 * @param size maximum number of bytes available to send
 * @param buf where to copy the actual message to
 *
 * @return the number of bytes actually copied, 0 indicates failure
 */
static size_t
send_reply_to_client (void *cls, size_t size, void *buf)
{
  struct ClientList *client = cls;
  char *cbuf = buf;
  struct PendingMessage *reply;
  size_t off;
  size_t msize;

  client->transmit_handle = NULL;
  if (buf == NULL)
  {
    /* client disconnected */
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Client %p disconnected, pending messages will be discarded\n",
                client->client_handle);
    return 0;
  }
  off = 0;
  while ((NULL != (reply = client->pending_head)) &&
         (size >= off + (msize = ntohs (reply->msg->size))))
  {
    GNUNET_CONTAINER_DLL_remove (client->pending_head, client->pending_tail,
                                 reply);
    memcpy (&cbuf[off], reply->msg, msize);
    GNUNET_free (reply);
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting %u bytes to client %p\n",
                msize, client->client_handle);
    off += msize;
  }
  process_pending_messages (client);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitted %u/%u bytes to client %p\n",
              (unsigned int) off, (unsigned int) size, client->client_handle);
  return off;
}
Example #30
0
/**
 * Function called to notify a client about the connection begin ready to queue
 * more data.  "buf" will be NULL and "size" zero if the connection was closed
 * for writing in the meantime.
 *
 * @param cls NULL
 * @param size number of bytes available in buf
 * @param buf where the callee should write the message
 * @return number of bytes written to buf
 */
static size_t
transmit_ready_notify (void *cls, size_t size, void *buf)
{
  struct MessageQueue *mq_entry;

  transmit_handle = NULL;
  mq_entry = mq_head;
  GNUNET_assert (NULL != mq_entry);
  if (0 == size)
    return 0;
  GNUNET_assert (ntohs (mq_entry->msg->size) <= size);
  size = ntohs (mq_entry->msg->size);
  memcpy (buf, mq_entry->msg, size);
  GNUNET_free (mq_entry->msg);
  GNUNET_SERVER_client_drop (mq_entry->client);
  GNUNET_CONTAINER_DLL_remove (mq_head, mq_tail, mq_entry);
  GNUNET_free (mq_entry);
  mq_entry = mq_head;
  if (NULL != mq_entry)
    transmit_handle =
        GNUNET_SERVER_notify_transmit_ready (mq_entry->client,
                                             ntohs (mq_entry->msg->size),
                                             GNUNET_TIME_UNIT_FOREVER_REL,
                                             &transmit_ready_notify, NULL);
  return size;
}