Example #1
0
/**
 * Disconnect from the PEERSTORE service. Any pending ITERATE and WATCH requests
 * will be canceled.
 * Any pending STORE requests will depend on @e snyc_first flag.
 *
 * @param h handle to disconnect
 * @param sync_first send any pending STORE requests before disconnecting
 */
void
GNUNET_PEERSTORE_disconnect (struct GNUNET_PEERSTORE_Handle *h,
                             int sync_first)
{
  struct GNUNET_PEERSTORE_IterateContext *ic;
  struct GNUNET_PEERSTORE_StoreContext *sc;

  LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting.\n");
  if (NULL != h->watches)
  {
    GNUNET_CONTAINER_multihashmap_iterate (h->watches, &destroy_watch, NULL);
    GNUNET_CONTAINER_multihashmap_destroy (h->watches);
    h->watches = NULL;
  }
  while (NULL != (ic = h->iterate_head))
  {
    GNUNET_break (0);
    GNUNET_PEERSTORE_iterate_cancel (ic);
  }
  if (NULL != h->store_head)
  {
    if (GNUNET_YES == sync_first)
    {
      LOG (GNUNET_ERROR_TYPE_DEBUG,
           "Delaying disconnection due to pending store requests.\n");
      h->disconnecting = GNUNET_YES;
      return;
    }
    while (NULL != (sc = h->store_head))
      GNUNET_PEERSTORE_store_cancel (sc);
  }
  do_disconnect (h);
}
Example #2
0
/**
 * When a response for iterate request is received
 *
 * @param cls a `struct GNUNET_PEERSTORE_Handle *`
 * @param msg message received, NULL on timeout or fatal error
 */
static void
handle_iterate_result (void *cls, const struct GNUNET_MessageHeader *msg)
{
  struct GNUNET_PEERSTORE_Handle *h = cls;
  struct GNUNET_PEERSTORE_IterateContext *ic;
  GNUNET_PEERSTORE_Processor callback;
  void *callback_cls;
  uint16_t msg_type;
  struct GNUNET_PEERSTORE_Record *record;
  int continue_iter;

  ic = h->iterate_head;
  if (NULL == ic)
  {
    LOG (GNUNET_ERROR_TYPE_ERROR,
         _("Unexpected iteration response, this should not happen.\n"));
    reconnect (h);
    return;
  }
  ic->iterating = GNUNET_YES;
  callback = ic->callback;
  callback_cls = ic->callback_cls;
  if (NULL == msg)              /* Connection error */
  {
    if (NULL != callback)
      callback (callback_cls, NULL,
                _("Error communicating with `PEERSTORE' service."));
    reconnect (h);
    return;
  }
  msg_type = ntohs (msg->type);
  if (GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_END == msg_type)
  {
    ic->iterating = GNUNET_NO;
    GNUNET_PEERSTORE_iterate_cancel (ic);
    if (NULL != callback)
      callback (callback_cls, NULL, NULL);
    return;
  }
  if (NULL != callback)
  {
    record = PEERSTORE_parse_record_message (msg);
    if (NULL == record)
      continue_iter =
          callback (callback_cls, NULL,
                    _("Received a malformed response from service."));
    else
    {
      continue_iter = callback (callback_cls, record, NULL);
      PEERSTORE_destroy_record (record);
    }
    if (GNUNET_NO == continue_iter)
      ic->callback = NULL;
  }
}
Example #3
0
/**
 * Called when the iterate request is timedout
 *
 * @param cls a `struct GNUNET_PEERSTORE_IterateContext *`
 * @param tc Scheduler task context (unused)
 */
static void
iterate_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct GNUNET_PEERSTORE_IterateContext *ic = cls;
  GNUNET_PEERSTORE_Processor callback;
  void *callback_cls;

  ic->timeout_task = NULL;
  callback = ic->callback;
  callback_cls = ic->callback_cls;
  GNUNET_PEERSTORE_iterate_cancel (ic);
  if (NULL != callback)
    callback (callback_cls, NULL, _("timeout"));
}
static void
iter1_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record,
          const char *emsg)
{
  if (NULL != emsg)
  {
    GNUNET_PEERSTORE_iterate_cancel (ic);
    return;
  }
  if (NULL != record)
  {
    count++;
    return;
  }
  GNUNET_assert (count == 1);
  count = 0;
  ic = GNUNET_PEERSTORE_iterate (h, ss, &p1, NULL, GNUNET_TIME_UNIT_FOREVER_REL,
                            iter2_cb, NULL);
}
static void
iter3_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record,
          const char *emsg)
{
  if (NULL != emsg)
  {
    GNUNET_PEERSTORE_iterate_cancel (ic);
    return;
  }
  if (NULL != record)
  {
    count++;
    return;
  }
  GNUNET_assert (count == 3);
  ok = 0;
  GNUNET_PEERSTORE_disconnect (h, GNUNET_NO);
  GNUNET_SCHEDULER_shutdown ();
}
Example #6
0
/**
 * Close the existing connection to PEERSTORE and reconnect.
 *
 * @param h handle to the service
 */
static void
reconnect (struct GNUNET_PEERSTORE_Handle *h)
{
  struct GNUNET_PEERSTORE_IterateContext *ic;
  struct GNUNET_PEERSTORE_IterateContext *next;
  GNUNET_PEERSTORE_Processor icb;
  void *icb_cls;
  struct GNUNET_PEERSTORE_StoreContext *sc;
  struct GNUNET_MQ_Envelope *ev;

  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Reconnecting...\n");
  for (ic = h->iterate_head; NULL != ic; ic = next)
  {
    next = ic->next;
    if (GNUNET_YES == ic->iterating)
    {
      icb = ic->callback;
      icb_cls = ic->callback_cls;
      GNUNET_PEERSTORE_iterate_cancel (ic);
      if (NULL != icb)
        icb (icb_cls,
             NULL,
             "Iteration canceled due to reconnection");
    }
  }
  if (NULL != h->mq)
  {
    GNUNET_MQ_destroy (h->mq);
    h->mq = NULL;
  }
  if (NULL != h->client)
  {
    GNUNET_CLIENT_disconnect (h->client);
    h->client = NULL;
  }

  h->client = GNUNET_CLIENT_connect ("peerstore", h->cfg);
  GNUNET_assert (NULL != h->client);
  h->mq =
      GNUNET_MQ_queue_for_connection_client (h->client, mq_handlers,
                                             &handle_client_error, h);
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Resending pending requests after reconnect.\n");
  if (NULL != h->watches)
    GNUNET_CONTAINER_multihashmap_iterate (h->watches, &rewatch_it, h);
  for (ic = h->iterate_head; NULL != ic; ic = ic->next)
  {
    ev =
      PEERSTORE_create_record_mq_envelope (ic->sub_system, &ic->peer, ic->key,
                                           NULL, 0, NULL, 0,
                                           GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE);
    GNUNET_MQ_send (h->mq, ev);
    ic->timeout_task =
        GNUNET_SCHEDULER_add_delayed (ic->timeout, &iterate_timeout, ic);
  }
  for (sc = h->store_head; NULL != sc; sc = sc->next)
  {
    ev =
      PEERSTORE_create_record_mq_envelope (sc->sub_system, &sc->peer, sc->key,
                                           sc->value, sc->size, &sc->expiry,
                                           sc->options,
                                           GNUNET_MESSAGE_TYPE_PEERSTORE_STORE);
    GNUNET_MQ_notify_sent (ev, &store_request_sent, sc);
    GNUNET_MQ_send (h->mq, ev);
  }
}