/**
 * Transmit the given message to the client.
 *
 * @param client target of the message
 * @param msg message to transmit, will be freed!
 */
static void
transmit (struct GNUNET_SERVER_Client *client, struct GNUNET_MessageHeader *msg)
{
  struct TransmitCallbackContext *tcc;

  if (GNUNET_YES == cleaning_done)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                _("Shutdown in progress, aborting transmission.\n"));
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    GNUNET_free (msg);
    return;
  }
  tcc = GNUNET_new (struct TransmitCallbackContext);
  tcc->msg = msg;
  tcc->client = client;
  if (NULL ==
      (tcc->th =
       GNUNET_SERVER_notify_transmit_ready (client, ntohs (msg->size),
                                            GNUNET_TIME_UNIT_FOREVER_REL,
                                            &transmit_callback, tcc)))
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    GNUNET_free (msg);
    GNUNET_free (tcc);
    return;
  }
  GNUNET_SERVER_client_keep (client);
  GNUNET_CONTAINER_DLL_insert (tcc_head, tcc_tail, tcc);
}
Ejemplo n.º 2
0
/**
 * Queues a message in send queue for sending to the service
 *
 * @param client the client to whom the queued message has to be sent
 * @param msg the message to queue
 */
void
GST_queue_message (struct GNUNET_SERVER_Client *client,
                   struct GNUNET_MessageHeader *msg)
{
  struct MessageQueue *mq_entry;
  uint16_t type;
  uint16_t size;

  type = ntohs (msg->type);
  size = ntohs (msg->size);
  GNUNET_assert ((GNUNET_MESSAGE_TYPE_TESTBED_INIT <= type) &&
                 (GNUNET_MESSAGE_TYPE_TESTBED_MAX > type));
  mq_entry = GNUNET_new (struct MessageQueue);
  mq_entry->msg = msg;
  mq_entry->client = client;
  GNUNET_SERVER_client_keep (client);
  LOG_DEBUG ("Queueing message of type %u, size %u for sending\n", type,
             ntohs (msg->size));
  GNUNET_CONTAINER_DLL_insert_tail (mq_head, mq_tail, mq_entry);
  if (NULL == transmit_handle)
    transmit_handle =
        GNUNET_SERVER_notify_transmit_ready (client, size,
                                             GNUNET_TIME_UNIT_FOREVER_REL,
                                             &transmit_ready_notify, NULL);
}
Ejemplo n.º 3
0
/**
 * Handle STOP-message.
 *
 * @param cls closure (always NULL)
 * @param client identification of the client
 * @param message the actual message
 * @return GNUNET_OK to keep the connection open,
 *         GNUNET_SYSERR to close it (signal serious error)
 */
static void
handle_stop (void *cls, struct GNUNET_SERVER_Client *client,
	     const struct GNUNET_MessageHeader *message)
{
  struct ServiceList *sl;
  const char *servicename;
  uint16_t size;

  size = ntohs (message->size);
  size -= sizeof (struct GNUNET_MessageHeader);
  servicename = (const char *) &message[1];
  if ((size == 0) || (servicename[size - 1] != '\0'))
    {
      GNUNET_break (0);
      GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
      return;
    }
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
	      _("Preparing to stop `%s'\n"), servicename);
  sl = find_service (servicename);
  if (sl == NULL)
    {
      signal_result (client, servicename, GNUNET_ARM_PROCESS_UNKNOWN);
      return;
    }
  sl->is_default = GNUNET_NO;
  if (GNUNET_YES == in_shutdown)
    {
      /* shutdown in progress */
      signal_result (client, servicename, GNUNET_ARM_PROCESS_SHUTDOWN);
      return;
    }
  if (sl->killing_client != NULL)
    {
      /* killing already in progress */
      signal_result (client, servicename,
		     GNUNET_ARM_PROCESS_ALREADY_STOPPING);
      return;
    }
  if (sl->proc == NULL)
    {
      /* process is down */
      signal_result (client, servicename, GNUNET_ARM_PROCESS_ALREADY_DOWN);
      return;
    }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Sending kill signal to service `%s', waiting for process to die.\n",
	      servicename);
  sl->killed_at = GNUNET_TIME_absolute_get ();
  if (0 != GNUNET_OS_process_kill (sl->proc, SIGTERM))
    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
  sl->killing_client = client;
  GNUNET_SERVER_client_keep (client);
}
Ejemplo n.º 4
0
/**
 * Create a new transmission context for the
 * given client.
 *
 * @param client client to create the context for.
 * @return NULL on error
 */
struct GNUNET_SERVER_TransmitContext *
GNUNET_SERVER_transmit_context_create (struct GNUNET_SERVER_Client *client)
{
  struct GNUNET_SERVER_TransmitContext *tc;

  GNUNET_assert (NULL != client);
  tc = GNUNET_new (struct GNUNET_SERVER_TransmitContext);
  GNUNET_SERVER_client_keep (client);
  tc->client = client;
  return tc;
}
static void
recv_cb (void *cls, struct GNUNET_SERVER_Client *client,
         const struct GNUNET_MessageHeader *message)
{
    GNUNET_assert (ok == 2);
    ok = 3;
    GNUNET_SERVER_client_keep (client);
    GNUNET_SCHEDULER_add_now (&server_disconnect, client);
    GNUNET_assert (sizeof (struct GNUNET_MessageHeader) == ntohs (message->size));
    GNUNET_assert (MY_TYPE == ntohs (message->type));
    GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
Ejemplo n.º 6
0
Archivo: mq.c Proyecto: tg-x/gnunet
struct GNUNET_MQ_Handle *
GNUNET_MQ_queue_for_server_client (struct GNUNET_SERVER_Client *client)
{
  struct GNUNET_MQ_Handle *mq;
  struct ServerClientSocketState *scss;

  mq = GNUNET_new (struct GNUNET_MQ_Handle);
  scss = GNUNET_new (struct ServerClientSocketState);
  mq->impl_state = scss;
  scss->client = client;
  GNUNET_SERVER_client_keep (client);
  mq->send_impl = server_client_send_impl;
  mq->destroy_impl = server_client_destroy_impl;
  return mq;
}
Ejemplo n.º 7
0
static void
recv_cb (void *cls, struct GNUNET_SERVER_Client *client,
         const struct GNUNET_MessageHeader *message)
{
  GNUNET_assert (ok == 2);
  ok = 3;
  argclient = client;
  GNUNET_SERVER_client_keep (argclient);
  GNUNET_assert (sizeof (struct GNUNET_MessageHeader) == ntohs (message->size));
  GNUNET_assert (MY_TYPE == ntohs (message->type));
  GNUNET_assert (NULL !=
                 GNUNET_SERVER_notify_transmit_ready (client,
                                                      ntohs (message->size),
                                                      TIMEOUT, &reply_msg,
                                                      NULL));
}
Ejemplo n.º 8
0
/**
 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_INIT messages
 *
 * @param cls NULL
 * @param client identification of the client
 * @param message the actual message
 */
static void
handle_init (void *cls, struct GNUNET_SERVER_Client *client,
             const struct GNUNET_MessageHeader *message)
{
  const struct GNUNET_TESTBED_InitMessage *msg;
  struct GNUNET_TESTBED_Host *host;
  const char *controller_hostname;
  char *ss_str;
  struct GNUNET_TESTING_SharedService *ss;
  unsigned int cnt;
  uint16_t msize;

  if (NULL != GST_context)
  {
    LOG_DEBUG ("We are being connected to laterally\n");
    GNUNET_SERVER_receive_done (client, GNUNET_OK);
    return;
  }
  msg = (const struct GNUNET_TESTBED_InitMessage *) message;
  msize = ntohs (message->size);
  if (msize <= sizeof (struct GNUNET_TESTBED_InitMessage))
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  msize -= sizeof (struct GNUNET_TESTBED_InitMessage);
  controller_hostname = (const char *) &msg[1];
  if ('\0' != controller_hostname[msize - 1])
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  ss_str = NULL;
  ss = NULL;
  if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (GST_config, "TESTBED",
                                                          "SHARED_SERVICES",
                                                          &ss_str))
  {
    ss = parse_shared_services (ss_str, GST_config);
    GNUNET_free (ss_str);
    ss_str = NULL;
  }
  GST_context = GNUNET_new (struct Context);
  GNUNET_SERVER_client_keep (client);
  GST_context->client = client;
  GST_context->host_id = ntohl (msg->host_id);
  GST_context->master_ip = GNUNET_strdup (controller_hostname);
  LOG_DEBUG ("Our IP: %s\n", GST_context->master_ip);
  GST_context->system =
      GNUNET_TESTING_system_create ("testbed", GST_context->master_ip,
                                    hostname, ss);
  if (NULL != ss)
  {
    for (cnt = 0; NULL != ss[cnt].service; cnt++)
    {
      ss_str = (char *) ss[cnt].service;
      GNUNET_free (ss_str);
    }
    GNUNET_free (ss);
    ss = NULL;
  }
  host =
      GNUNET_TESTBED_host_create_with_id (GST_context->host_id,
                                          GST_context->master_ip, NULL,
                                          GST_config, 0);
  host_list_add (host);
  LOG_DEBUG ("Created master context with host ID: %u\n", GST_context->host_id);
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
/**
 * Client asked for transmission to a peer.  Process the request.
 *
 * @param cls unused
 * @param client the client
 * @param message the send message that was sent
 */
static void
clients_handle_send (void *cls,
                     struct GNUNET_SERVER_Client *client,
                     const struct GNUNET_MessageHeader *message)
{
  const struct OutboundMessage *obm;
  const struct GNUNET_MessageHeader *obmm;
  struct SendTransmitContinuationContext *stcc;
  uint16_t size;
  uint16_t msize;
  struct TransportClient *tc;

  tc = lookup_client (client);
  if (NULL == tc)
  {
    /* client asked for transmission before 'START' */
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }

  size = ntohs (message->size);
  if (size <
      sizeof (struct OutboundMessage) + sizeof (struct GNUNET_MessageHeader))
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  obm = (const struct OutboundMessage *) message;
  obmm = (const struct GNUNET_MessageHeader *) &obm[1];
  msize = size - sizeof (struct OutboundMessage);
  if (msize < sizeof (struct GNUNET_MessageHeader))
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Received `%s' request from client with target `%4s' and first message of type %u and total size %u\n",
              "SEND",
              GNUNET_i2s (&obm->peer),
              ntohs (obmm->type),
              msize);
  if (GNUNET_NO == GST_neighbours_test_connected (&obm->peer))
  {
    /* not connected, not allowed to send; can happen due to asynchronous operations */
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Could not send message to peer `%s': not connected\n",
                GNUNET_i2s (&obm->peer));
    GNUNET_STATISTICS_update (GST_stats,
                              gettext_noop
                              ("# bytes payload dropped (other peer was not connected)"),
                              msize, GNUNET_NO);
    GNUNET_SERVER_receive_done (client, GNUNET_OK);
    return;
  }
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
  stcc = GNUNET_new (struct SendTransmitContinuationContext);
  stcc->target = obm->peer;
  stcc->client = client;
  GNUNET_SERVER_client_keep (client);
  GST_manipulation_send (&obm->peer, obmm, msize,
                       GNUNET_TIME_relative_ntoh (obm->timeout),
                       &handle_send_transmit_continuation, stcc);
}
Ejemplo n.º 10
0
/**
 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_LCONTROLLERS message
 *
 * @param cls NULL
 * @param client identification of the client
 * @param message the actual message
 */
void
GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client,
                             const struct GNUNET_MessageHeader *message)
{
  const struct GNUNET_TESTBED_ControllerLinkRequest *msg;
  struct LCFContextQueue *lcfq;
  struct Route *route;
  struct Route *new_route;
  uint64_t op_id;
  uint32_t delegated_host_id;
  uint32_t slave_host_id;

  if (NULL == GST_context)
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  msg = (const struct GNUNET_TESTBED_ControllerLinkRequest *) message;
  delegated_host_id = ntohl (msg->delegated_host_id);
  if (delegated_host_id == GST_context->host_id)
  {
    GNUNET_break (0);
    LOG (GNUNET_ERROR_TYPE_WARNING, "Trying to link ourselves\n");
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  if ((delegated_host_id >= GST_host_list_size) ||
      (NULL == GST_host_list[delegated_host_id]))
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
         "Delegated host %u not registered with us\n", delegated_host_id);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  slave_host_id = ntohl (msg->slave_host_id);
  if ((slave_host_id >= GST_host_list_size) ||
      (NULL == GST_host_list[slave_host_id]))
  {
    LOG (GNUNET_ERROR_TYPE_WARNING, "Slave host %u not registered with us\n",
         slave_host_id);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  if (slave_host_id == delegated_host_id)
  {
    LOG (GNUNET_ERROR_TYPE_WARNING, "Slave and delegated host are same\n");
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  op_id = GNUNET_ntohll (msg->operation_id);
  if (slave_host_id == GST_context->host_id)    /* Link from us */
  {
    struct Slave *slave;
    struct LinkControllersContext *lcc;


    if (1 != msg->is_subordinate)
    {
      struct Neighbour *n;
      struct NeighbourConnectCtxt *ncc;

      if ((delegated_host_id < neighbour_list_size) &&
        (NULL != neighbour_list[delegated_host_id]))
      {
        GNUNET_break (0);
        GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
        return;
      }
      LOG_DEBUG ("Received request to establish a link to host %u\n",
                 delegated_host_id);
      n = GST_create_neighbour (GST_host_list[delegated_host_id]);
      ncc = GNUNET_new (struct NeighbourConnectCtxt);
      ncc->n = n;
      ncc->op_id = op_id;
      ncc->client = client;
      GNUNET_SERVER_client_keep (client);
      ncc->nh = GST_neighbour_get_connection (n, neighbour_connect_cb, ncc);
      ncc->timeout_task = GNUNET_SCHEDULER_add_delayed (GST_timeout,
                                                        &timeout_neighbour_connect,
                                                        ncc);
      GNUNET_CONTAINER_DLL_insert_tail (ncc_head, ncc_tail, ncc);
      GNUNET_SERVER_receive_done (client, GNUNET_OK);
      return;
    }
    if ((delegated_host_id < GST_slave_list_size) &&
        (NULL != GST_slave_list[delegated_host_id]))
    {
      GNUNET_break (0);
      GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
      return;
    }
    LOG_DEBUG ("Received request to start and establish a link to host %u\n",
               delegated_host_id);
    slave = GNUNET_new (struct Slave);
    slave->host_id = delegated_host_id;
    slave->reghost_map = GNUNET_CONTAINER_multihashmap_create (100, GNUNET_NO);
    slave_list_add (slave);
    lcc = GNUNET_new (struct LinkControllersContext);
    lcc->operation_id = op_id;
    GNUNET_SERVER_client_keep (client);
    lcc->client = client;
    slave->lcc = lcc;
    slave->controller_proc =
        GNUNET_TESTBED_controller_start (GST_context->master_ip,
                                         GST_host_list[slave->host_id],
                                         &slave_status_cb, slave);
    new_route = GNUNET_new (struct Route);
    new_route->dest = delegated_host_id;
    new_route->thru = GST_context->host_id;
    route_list_add (new_route);
    return;
  }

  /* Route the request */
  if (slave_host_id >= route_list_size)
  {
    LOG (GNUNET_ERROR_TYPE_WARNING, "No route towards slave host");
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  lcfq = GNUNET_new (struct LCFContextQueue);
  lcfq->lcf = GNUNET_new (struct LCFContext);
  lcfq->lcf->delegated_host_id = delegated_host_id;
  lcfq->lcf->slave_host_id = slave_host_id;
  route = GST_find_dest_route (slave_host_id);
  GNUNET_assert (NULL != route);        /* because we add routes carefully */
  GNUNET_assert (route->dest < GST_slave_list_size);
  GNUNET_assert (NULL != GST_slave_list[route->dest]);
  lcfq->lcf->is_subordinate = msg->is_subordinate;
  lcfq->lcf->state = INIT;
  lcfq->lcf->operation_id = op_id;
  lcfq->lcf->gateway = GST_slave_list[route->dest];
  GNUNET_SERVER_client_keep (client);
  lcfq->lcf->client = client;
  if (NULL == lcfq_head)
  {
    GNUNET_assert (NULL == lcf_proc_task_id);
    GNUNET_CONTAINER_DLL_insert_tail (lcfq_head, lcfq_tail, lcfq);
    lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcfq->lcf);
  }
  else
    GNUNET_CONTAINER_DLL_insert_tail (lcfq_head, lcfq_tail, lcfq);
  /* FIXME: Adding a new route should happen after the controllers are linked
   * successfully */
  if (1 != msg->is_subordinate)
  {
    GNUNET_SERVER_receive_done (client, GNUNET_OK);
    return;
  }
  if ((delegated_host_id < route_list_size) &&
      (NULL != route_list[delegated_host_id]))
  {
    GNUNET_break_op (0);        /* Are you trying to link delegated host twice
                                 * with is subordinate flag set to GNUNET_YES? */
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  new_route = GNUNET_new (struct Route);
  new_route->dest = delegated_host_id;
  new_route->thru = route->dest;
  route_list_add (new_route);
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}