コード例 #1
0
/**
 * We've transmitted the iteration request.  Now get ready to process
 * the results (or handle transmission error).
 *
 * @param cls the 'struct GNUNET_PEERINFO_IteratorContext'
 * @param emsg error message, NULL if transmission worked
 */
static void
iterator_start_receive (void *cls, const char *emsg)
{
  struct GNUNET_PEERINFO_IteratorContext *ic = cls;
  struct GNUNET_PEERINFO_Handle *h = ic->h;
  GNUNET_PEERINFO_Processor cb;
  void *cb_cls;

  ic->ac = NULL;
  if (NULL != emsg)
  {
    cb = ic->callback;
    cb_cls = ic->callback_cls;
    GNUNET_PEERINFO_iterate_cancel (ic);
    reconnect (h);
    if (NULL != cb)
      cb (cb_cls, NULL, NULL, emsg);
    return;
  }
  LOG (GNUNET_ERROR_TYPE_DEBUG, "Waiting for response from `%s' service.\n",
       "PEERINFO");
  ic->in_receive = GNUNET_YES;
  if (GNUNET_NO == h->in_receive)
  {
    h->in_receive = GNUNET_YES;
    GNUNET_CLIENT_receive (h->client, &peerinfo_handler, h,
			   GNUNET_TIME_absolute_get_remaining (ic->timeout));
  }
}
コード例 #2
0
/**
 * PEERINFO calls this function to let us know about a possible peer
 * that we might want to connect to.
 *
 * @param cls closure (not used)
 * @param peer potential peer to connect to
 * @param hello HELLO for this peer (or NULL)
 * @param err_msg NULL if successful, otherwise contains error message
 */
static void
process_notify (void *cls,
                const struct GNUNET_PeerIdentity *peer,
                const struct GNUNET_HELLO_Message *hello,
                const char *err_msg)
{
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Peerinfo is notifying us to rebuild our hostlist\n");
  if (NULL != err_msg)
    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                _("Error in communication with PEERINFO service: %s\n"),
		err_msg);
  if (NULL != builder)
  {
    /* restart re-build already in progress ... */
    if (NULL != builder->pitr)
    {
      GNUNET_PEERINFO_iterate_cancel (builder->pitr);
      builder->pitr = NULL;
    }
    GNUNET_free_non_null (builder->data);
    builder->size = 0;
    builder->data = NULL;
  }
  else
  {
    builder = GNUNET_new (struct HostSet);
  }
  GNUNET_assert (NULL != peerinfo);
  builder->pitr
    = GNUNET_PEERINFO_iterate (peerinfo,
                               GNUNET_NO, NULL,
                               GNUNET_TIME_UNIT_MINUTES,
                               &host_processor, NULL);
}
コード例 #3
0
/**
 * Peerinfo iteration request has timed out.
 *
 * @param cls the 'struct GNUNET_PEERINFO_IteratorContext*'
 * @param tc scheduler context
 */
static void
signal_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct GNUNET_PEERINFO_IteratorContext *ic = cls;
  GNUNET_PEERINFO_Processor cb;
  void *cb_cls;

  ic->timeout_task = GNUNET_SCHEDULER_NO_TASK;
  cb = ic->callback;
  cb_cls = ic->callback_cls;
  GNUNET_PEERINFO_iterate_cancel (ic);
  if (NULL != cb)
    cb (cb_cls, NULL, NULL,
	_("Timeout transmitting iteration request to `PEERINFO' service."));
}
コード例 #4
0
/**
 * Main state machine that goes over all options and
 * runs the next requested function.
 *
 * @param cls unused
 * @param tc scheduler context
 */
static void
shutdown_task (void *cls,
	       const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct PrintContext *pc;
  struct AddressRecord *ar;
  unsigned int i;

  if (NULL != ac)
  {
    GNUNET_PEERINFO_add_peer_cancel (ac);
    ac = NULL;
  }
  if (GNUNET_SCHEDULER_NO_TASK != tt)
  {
    GNUNET_SCHEDULER_cancel (tt);
    tt = GNUNET_SCHEDULER_NO_TASK;
  }
  if (NULL != pic)
  {
    GNUNET_PEERINFO_iterate_cancel (pic);
    pic = NULL;
  }
  while (NULL != (pc = pc_head))
  {
    GNUNET_CONTAINER_DLL_remove (pc_head,
				 pc_tail,
				 pc);
    for (i=0;i<pc->address_list_size;i++)
    {
      ar = &pc->address_list[i];
      GNUNET_free_non_null (ar->result);
      if (NULL != ar->atsc)
      {
	GNUNET_TRANSPORT_address_to_string_cancel (ar->atsc);
	ar->atsc = NULL;
      }
    }
    GNUNET_free_non_null (pc->address_list);
    GNUNET_free (pc);
  }
  GPI_plugins_unload ();
  if (NULL != peerinfo)
  {
    GNUNET_PEERINFO_disconnect (peerinfo);
    peerinfo = NULL;
  }
}
コード例 #5
0
/**
 * Disconnect from the peerinfo service.  Note that all iterators must
 * have completed or have been cancelled by the time this function is
 * called (otherwise, calling this function is a serious error).
 * Furthermore, if 'GNUNET_PEERINFO_add_peer' operations are still
 * pending, they will be cancelled silently on disconnect.
 *
 * @param h handle to disconnect
 */
void
GNUNET_PEERINFO_disconnect (struct GNUNET_PEERINFO_Handle *h)
{
  struct GNUNET_PEERINFO_AddContext *ac;
  struct GNUNET_PEERINFO_IteratorContext *ic;

  while (NULL != (ic = h->ic_head))
  {
    GNUNET_break (GNUNET_YES == ic->in_receive);
    ic->in_receive = GNUNET_NO;
    GNUNET_PEERINFO_iterate_cancel (ic);
  }
  while (NULL != (ac = h->ac_head))
  {
    GNUNET_CONTAINER_DLL_remove (h->ac_head, h->ac_tail, ac);
    if (NULL != ac->cont)
      ac->cont (ac->cont_cls, _("aborted due to explicit disconnect request"));
    GNUNET_free (ac);
  }
  if (NULL != h->th)
  {
    GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
    h->th = NULL;
  }
  if (NULL != h->client)
  {
    GNUNET_CLIENT_disconnect (h->client);
    h->client = NULL;
  }
  if (GNUNET_SCHEDULER_NO_TASK != h->r_task)
  {
    GNUNET_SCHEDULER_cancel (h->r_task);
    h->r_task = GNUNET_SCHEDULER_NO_TASK;
  }
  GNUNET_free (h);
}
コード例 #6
0
/**
 * Type of a function to call when we receive a message from the
 * service.  Call the iterator with the result and (if applicable)
 * continue to receive more messages or trigger processing the next
 * event (if applicable).
 *
 * @param cls closure
 * @param msg message received, NULL on timeout or fatal error
 */
static void
peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg)
{
  struct GNUNET_PEERINFO_Handle *h = cls;
  struct GNUNET_PEERINFO_IteratorContext *ic = h->ic_head;
  const struct InfoMessage *im;
  const struct GNUNET_HELLO_Message *hello;
  GNUNET_PEERINFO_Processor cb;
  struct GNUNET_PeerIdentity id;
  void *cb_cls;
  uint16_t ms;

  GNUNET_assert (NULL != ic);
  h->in_receive = GNUNET_NO;
  ic->in_receive = GNUNET_NO;
  cb = ic->callback;
  cb_cls = ic->callback_cls;
  if (NULL == msg)
  {
    /* peerinfo service died, signal error */
    GNUNET_PEERINFO_iterate_cancel (ic);
    reconnect (h);
    if (NULL != cb)
      cb (cb_cls, NULL, NULL,
	  _("Failed to receive response from `PEERINFO' service."));
    return;
  }

  if (GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END == ntohs (msg->type))
  {
    /* normal end of list of peers, signal end, process next pending request */
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Received end of list of peers from `%s' service\n", "PEERINFO");
    GNUNET_PEERINFO_iterate_cancel (ic);   
    trigger_transmit (h);
    if (NULL != cb)
      cb (cb_cls, NULL, NULL, NULL);
    return;
  }

  ms = ntohs (msg->size);
  if ((ms < sizeof (struct InfoMessage)) ||
      (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_PEERINFO_INFO))
  {
    /* malformed message */
    GNUNET_break (0);
    GNUNET_PEERINFO_iterate_cancel (ic);
    reconnect (h);
    if (NULL != cb)
      cb (cb_cls, NULL, NULL,
	  _("Received invalid message from `PEERINFO' service."));
    return;
  }
  im = (const struct InfoMessage *) msg;
  GNUNET_break (0 == ntohl (im->reserved));
  if ( (GNUNET_YES == ic->have_peer) &&
       (0 != memcmp (&ic->peer, &im->peer, sizeof (struct GNUNET_PeerIdentity))) )
  {
    /* bogus message (from a different iteration call?); out of sequence! */
    LOG (GNUNET_ERROR_TYPE_ERROR,
         "Received HELLO for peer `%s', expected peer `%s'\n",
	 GNUNET_h2s (&im->peer.hashPubKey),
	 GNUNET_i2s (&ic->peer));
    
    GNUNET_break (0);
    GNUNET_PEERINFO_iterate_cancel (ic);
    reconnect (h);
    if (NULL != cb)      
      cb (cb_cls, NULL, NULL,
	  _("Received invalid message from `PEERINFO' service."));
    return;
  }
  hello = NULL;
  if (ms > sizeof (struct InfoMessage) + sizeof (struct GNUNET_MessageHeader))
  {
    hello = (const struct GNUNET_HELLO_Message *) &im[1];
    if (ms != sizeof (struct InfoMessage) + GNUNET_HELLO_size (hello))
    {
      /* malformed message */
      GNUNET_break (0);
      GNUNET_PEERINFO_iterate_cancel (ic);
      reconnect (h);
      if (NULL != cb)      
        cb (cb_cls, NULL, NULL,
	    _("Received invalid message from `PEERINFO' service."));
      return;
    }
    if (GNUNET_OK != GNUNET_HELLO_get_id (hello, &id))
    {
      /* malformed message */
      GNUNET_break (0);
      GNUNET_PEERINFO_iterate_cancel (ic);
      reconnect (h);
      if (NULL != cb)      
        cb (cb_cls, NULL, NULL,
	    _("Received invalid message from `PEERINFO' service."));
      return;
    }
    if (0 != memcmp (&im->peer, &id, sizeof (struct GNUNET_PeerIdentity)))
    {
      /* malformed message */
      GNUNET_break (0);
      GNUNET_PEERINFO_iterate_cancel (ic);
      reconnect (h);
      if (NULL != cb)      
        cb (cb_cls, NULL, NULL,
	    _("Received invalid message from `PEERINFO' service."));
      return;
    }
  }

  /* normal data message */
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Received %u bytes of `%s' information about peer `%s' from `%s' service\n",
       (hello == NULL) ? 0 : (unsigned int) GNUNET_HELLO_size (hello), "HELLO",
       GNUNET_i2s (&im->peer), "PEERINFO");
  h->in_receive = GNUNET_YES;
  ic->in_receive = GNUNET_YES;
  GNUNET_CLIENT_receive (h->client, &peerinfo_handler, h,
                         GNUNET_TIME_absolute_get_remaining (ic->timeout));
  if (NULL != cb)
    cb (cb_cls, &im->peer, hello, NULL);
}
コード例 #7
0
/**
 * Stop server offering our hostlist.
 */
void
GNUNET_HOSTLIST_server_stop ()
{
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Hostlist server shutdown\n");
  if (NULL != hostlist_task_v6)
  {
    GNUNET_SCHEDULER_cancel (hostlist_task_v6);
    hostlist_task_v6 = NULL;
  }
  if (NULL != hostlist_task_v4)
  {
    GNUNET_SCHEDULER_cancel (hostlist_task_v4);
    hostlist_task_v4 = NULL;
  }
  if (NULL != daemon_handle_v4)
  {
    MHD_stop_daemon (daemon_handle_v4);
    daemon_handle_v4 = NULL;
  }
  if (NULL != daemon_handle_v6)
  {
    MHD_stop_daemon (daemon_handle_v6);
    daemon_handle_v6 = NULL;
  }
  if (NULL != response)
  {
    MHD_destroy_response (response);
    response = NULL;
  }
  if (NULL != notify)
  {
    GNUNET_PEERINFO_notify_cancel (notify);
    notify = NULL;
  }
  if (NULL != builder)
  {
    if (NULL != builder->pitr)
    {
      GNUNET_PEERINFO_iterate_cancel (builder->pitr);
      builder->pitr = NULL;
    }
    GNUNET_free_non_null (builder->data);
    GNUNET_free (builder);
    builder = NULL;
  }
  if (NULL != peerinfo)
  {
    GNUNET_PEERINFO_disconnect (peerinfo);
    peerinfo = NULL;
  }
  if (NULL != advertisements)
  {
    GNUNET_break (0 ==
                  GNUNET_CONTAINER_multipeermap_size (advertisements));
    GNUNET_CONTAINER_multipeermap_destroy (advertisements);
    advertisements = NULL;
  }
  cfg = NULL;
  stats = NULL;
  core = NULL;
}