Пример #1
0
/**
 * My HELLO has changed. Tell everyone who should know.
 *
 * @param cls unused
 * @param hello new HELLO
 */
static void
process_hello_update (void *cls,
                      const struct GNUNET_MessageHeader *hello)
{
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Broadcasting HELLO to clients\n");
  GST_clients_broadcast (hello, GNUNET_NO);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Broadcasting HELLO to neighbours\n");
  GST_neighbours_iterate (&transmit_our_hello,
                          (void *) hello);
}
/**
 * Initialize a normal client.  We got a start message from this
 * client, add him to the list of clients for broadcasting of inbound
 * messages.
 *
 * @param cls unused
 * @param client the client
 * @param message the start message that was sent
 */
static void
clients_handle_start (void *cls, struct GNUNET_SERVER_Client *client,
                      const struct GNUNET_MessageHeader *message)
{
  const struct StartMessage *start;
  struct TransportClient *tc;
  uint32_t options;

  tc = lookup_client (client);

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
              "Client %p sent START\n", tc);
  if (tc != NULL)
  {
    /* got 'start' twice from the same client, not allowed */
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
                "TransportClient %p ServerClient %p sent multiple START messages\n",
                tc, tc->client);
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  start = (const struct StartMessage *) message;
  options = ntohl (start->options);
  if ((0 != (1 & options)) &&
      (0 !=
       memcmp (&start->self, &GST_my_identity,
               sizeof (struct GNUNET_PeerIdentity))))
  {
    /* client thinks this is a different peer, reject */
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _
                ("Rejecting control connection from peer `%s', which is not me!\n"),
                GNUNET_i2s (&start->self));
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  tc = setup_client (client);
  tc->send_payload = (0 != (2 & options));
  unicast (tc, GST_hello_get (), GNUNET_NO);
  GST_neighbours_iterate (&notify_client_about_neighbour, tc);
  GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, tc);
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
/**
 * My HELLO has changed. Tell everyone who should know.
 *
 * @param cls unused
 * @param hello new HELLO
 */
static void
process_hello_update (void *cls, const struct GNUNET_MessageHeader *hello)
{
  GST_clients_broadcast (hello, GNUNET_NO);
  GST_neighbours_iterate (&transmit_our_hello, (void *) hello);
}
/**
 * Client asked to obtain information about a specific or all peers
 * Process the request.
 *
 * @param cls unused
 * @param client the client
 * @param message the peer address information request
 */
static void
clients_handle_monitor_peers (void *cls, struct GNUNET_SERVER_Client *client,
                                const struct GNUNET_MessageHeader *message)
{
  static struct GNUNET_PeerIdentity all_zeros;
  struct GNUNET_SERVER_TransmitContext *tc;
  struct PeerMonitorMessage *msg;
  struct IterationContext pc;

  if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_REQUEST)
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  if (ntohs (message->size) != sizeof (struct PeerMonitorMessage))
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  msg = (struct PeerMonitorMessage *) message;
  if ( (GNUNET_YES != ntohl (msg->one_shot)) &&
       (NULL != lookup_monitoring_client (peer_monitoring_clients_head, client)) )
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
		"ServerClient %p tried to start monitoring twice\n",
		client);
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  GNUNET_SERVER_disable_receive_done_warning (client);
  pc.tc = tc = GNUNET_SERVER_transmit_context_create (client);

  /* Send initial list */
  if (0 == memcmp (&msg->peer, &all_zeros, sizeof (struct GNUNET_PeerIdentity)))
  {
    /* iterate over all neighbours */
    pc.all = GNUNET_YES;
    pc.id = msg->peer;
  }
  else
  {
    /* just return one neighbour */
    pc.all = GNUNET_NO;
    pc.id = msg->peer;
  }
  GST_neighbours_iterate (&send_peer_information, &pc);

  if (GNUNET_YES != ntohl (msg->one_shot))
  {
    setup_peer_monitoring_client (client, &msg->peer);
  }
  else
  {
    GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
        GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE);
  }

  GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
}