/**
 * 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;
}
/**
 * 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);
}
예제 #3
0
/**
 * Handler for SET_DEFAULT message from client, updates
 * default identity for some service.
 *
 * @param cls unused
 * @param client who sent the message
 * @param message the message received
 */
static void
handle_set_default_message (void *cls, struct GNUNET_SERVER_Client *client,
			    const struct GNUNET_MessageHeader *message)
{
  const struct GNUNET_IDENTITY_SetDefaultMessage *sdm;
  uint16_t size;
  uint16_t name_len;
  struct Ego *ego;
  const char *str;

  size = ntohs (message->size);
  if (size <= sizeof (struct GNUNET_IDENTITY_SetDefaultMessage))
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  sdm = (const struct GNUNET_IDENTITY_SetDefaultMessage *) message;
  name_len = ntohs (sdm->name_len);
  GNUNET_break (0 == ntohs (sdm->reserved));
  if (name_len + sizeof (struct GNUNET_IDENTITY_SetDefaultMessage) != size)
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  str = (const char *) &sdm[1];
  if ('\0' != str[name_len - 1])
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Received SET_DEFAULT for service `%s' from client\n",
	      str);
  for (ego = ego_head; NULL != ego; ego = ego->next)
  {
    if (0 == key_cmp (ego->pk,
		      &sdm->private_key))
    {
      GNUNET_CONFIGURATION_set_value_string (subsystem_cfg,
					     str,
					     "DEFAULT_IDENTIFIER",
					     ego->identifier);
      if (GNUNET_OK !=
	  GNUNET_CONFIGURATION_write (subsystem_cfg,
				      subsystem_cfg_file))
	GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
		    _("Failed to write subsystem default identifier map to `%s'.\n"),
		    subsystem_cfg_file);
      send_result_code (client, 0, NULL);
      GNUNET_SERVER_receive_done (client, GNUNET_OK);
      return;
    }
  }
  send_result_code (client, 1, _("Unknown ego specified for service (internal error)"));
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
/**
 * Client asked to resolve an address.  Process the request.
 *
 * @param cls unused
 * @param client the client
 * @param message the resolution request
 */
static void
clients_handle_address_to_string (void *cls,
                                  struct GNUNET_SERVER_Client *client,
                                  const struct GNUNET_MessageHeader *message)
{
  const struct AddressLookupMessage *alum;
  struct GNUNET_TRANSPORT_PluginFunctions *papi;
  const char *plugin_name;
  const char *address;
  uint32_t address_len;
  uint16_t size;
  struct GNUNET_SERVER_TransmitContext *tc;
  struct AddressToStringContext *actx;
  struct GNUNET_TIME_Relative rtimeout;
  int32_t numeric;

  size = ntohs (message->size);
  if (size < sizeof (struct AddressLookupMessage))
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  alum = (const struct AddressLookupMessage *) message;
  address_len = ntohs (alum->addrlen);
  if (size <= sizeof (struct AddressLookupMessage) + address_len)
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  address = (const char *) &alum[1];
  plugin_name = (const char *) &address[address_len];
  if ('\0' != plugin_name[size - sizeof (struct AddressLookupMessage) - address_len - 1])
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  rtimeout = GNUNET_TIME_relative_ntoh (alum->timeout);
  numeric = ntohs (alum->numeric_only);
  tc = GNUNET_SERVER_transmit_context_create (client);
  papi = GST_plugins_printer_find (plugin_name);
  if (NULL == papi)
  {
    GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
                                                GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING_REPLY);
    GNUNET_SERVER_transmit_context_run (tc, rtimeout);
    return;
  }
  actx = GNUNET_new (struct AddressToStringContext);
  actx->tc = tc;
  GNUNET_CONTAINER_DLL_insert (a2s_head, a2s_tail, actx);
  GNUNET_SERVER_disable_receive_done_warning (client);
  papi->address_pretty_printer (papi->cls, plugin_name, address, address_len,
                                numeric, rtimeout, &transmit_address_to_client,
                                actx);
}
예제 #5
0
/**
 * Handle ANNOUNCE message.
 *
 * @param cls closure
 * @param client identification of the client
 * @param message the actual message
 */
static void
handle_announce (void *cls,
		 struct GNUNET_SERVER_Client *client,
		 const struct GNUNET_MessageHeader *message)
{
  const struct AnnounceMessage *am;
  const char *regex;
  struct ClientEntry *ce;
  uint16_t size;

  size = ntohs (message->size);
  am = (const struct AnnounceMessage *) message;
  regex = (const char *) &am[1];
  if ( (size <= sizeof (struct AnnounceMessage)) ||
       ('\0' != regex[size - sizeof (struct AnnounceMessage) - 1]) )
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }

  ce = GNUNET_new (struct ClientEntry);
  ce->client = client;
  ce->frequency = GNUNET_TIME_relative_ntoh (am->refresh_delay);
  ce->refresh_task = GNUNET_SCHEDULER_add_delayed (ce->frequency,
						   &reannounce,
						   ce);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Starting to announce regex `%s' every %s\n",
	      regex,
	      GNUNET_STRINGS_relative_time_to_string (ce->frequency,
						      GNUNET_NO));
  ce->ah = REGEX_INTERNAL_announce (dht,
				    my_private_key,
				    regex,
				    ntohs (am->compression),
				    stats);
  if (NULL == ce->ah)
  {
    GNUNET_break (0);
    GNUNET_SCHEDULER_cancel (ce->refresh_task);
    GNUNET_free (ce);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  GNUNET_CONTAINER_DLL_insert (client_head,
			       client_tail,
			       ce);
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
/**
 * Handler for "GET result seen" messages from the client.
 *
 * @param cls closure for the service
 * @param client the client we received this message from
 * @param message the actual message received
 */
static void
handle_dht_local_get_result_seen (void *cls, struct GNUNET_SERVER_Client *client,
				  const struct GNUNET_MessageHeader *message)
{
  const struct GNUNET_DHT_ClientGetResultSeenMessage *seen;
  uint16_t size;
  unsigned int hash_count;
  unsigned int old_count;
  const struct GNUNET_HashCode *hc;
  struct FindByUniqueIdContext fui_ctx;
  struct ClientQueryRecord *cqr;

  size = ntohs (message->size);
  if (size < sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage))
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  seen = (const struct GNUNET_DHT_ClientGetResultSeenMessage *) message;
  hash_count = (size - sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage)) / sizeof (struct GNUNET_HashCode);
  if (size != sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage) + hash_count * sizeof (struct GNUNET_HashCode))
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  hc = (const struct GNUNET_HashCode*) &seen[1];
  fui_ctx.unique_id = seen->unique_id;
  fui_ctx.cqr = NULL;
  GNUNET_CONTAINER_multihashmap_get_multiple (forward_map,
					      &seen->key,
					      &find_by_unique_id,
					      &fui_ctx);
  if (NULL == (cqr = fui_ctx.cqr))
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  /* finally, update 'seen' list */
  old_count = cqr->seen_replies_count;
  GNUNET_array_grow (cqr->seen_replies,
		     cqr->seen_replies_count,
		     cqr->seen_replies_count + hash_count);
  memcpy (&cqr->seen_replies[old_count],
	  hc,
	  sizeof (struct GNUNET_HashCode) * hash_count);
}
예제 #7
0
static void
recv_cb (void *cls, struct GNUNET_SERVER_Client *argclient,
         const struct GNUNET_MessageHeader *message)
{
  received++;
  if (received == 2)
  {
    GNUNET_SERVER_receive_done (argclient, GNUNET_NO);
    return;
  }

  /* can happen if notify does not work */
  GNUNET_assert (received < 2);

  GNUNET_SERVER_receive_done (argclient, GNUNET_YES);
}
/**
 * Handle request connect message
 *
 * @param cls closure (always NULL)
 * @param client identification of the client
 * @param message the actual message
 */
static void
clients_handle_request_connect (void *cls, struct GNUNET_SERVER_Client *client,
                                const struct GNUNET_MessageHeader *message)
{
  const struct TransportRequestConnectMessage *trcm =
      (const struct TransportRequestConnectMessage *) message;

  GNUNET_STATISTICS_update (GST_stats,
                            gettext_noop
                            ("# REQUEST CONNECT messages received"), 1,
                            GNUNET_NO);

  if (0 == memcmp (&trcm->peer, &GST_my_identity,
  		sizeof (struct GNUNET_PeerIdentity)))
  {
    GNUNET_break_op (0);
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                "Received a request connect message myself `%s'\n",
                GNUNET_i2s (&trcm->peer));
  }
  else
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Received a request connect message for peer `%s'\n",
                GNUNET_i2s (&trcm->peer));

    (void) GST_blacklist_test_allowed (&trcm->peer, NULL, &try_connect_if_allowed,
                                     NULL);
  }
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
/**
 * Client sent us a HELLO.  Process the request.
 *
 * @param cls unused
 * @param client the client
 * @param message the HELLO message
 */
static void
clients_handle_hello (void *cls, struct GNUNET_SERVER_Client *client,
                      const struct GNUNET_MessageHeader *message)
{
  GST_validation_handle_hello (message);
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
/**
 * Handler for monitor start messages
 *
 * @param cls closure for the service
 * @param client the client we received this message from
 * @param message the actual message received
 *
 */
static void
handle_dht_local_monitor (void *cls, struct GNUNET_SERVER_Client *client,
                          const struct GNUNET_MessageHeader *message)
{
  struct ClientMonitorRecord *r;
  const struct GNUNET_DHT_MonitorStartStopMessage *msg;

  msg = (struct GNUNET_DHT_MonitorStartStopMessage *) message;
  r = GNUNET_new (struct ClientMonitorRecord);

  r->client = find_active_client(client);
  r->type = ntohl(msg->type);
  r->get = ntohs(msg->get);
  r->get_resp = ntohs(msg->get_resp);
  r->put = ntohs(msg->put);
  if (0 == ntohs(msg->filter_key))
      r->key = NULL;
  else
  {
    r->key = GNUNET_new (struct GNUNET_HashCode);
    memcpy (r->key, &msg->key, sizeof (struct GNUNET_HashCode));
  }
  GNUNET_CONTAINER_DLL_insert (monitor_head, monitor_tail, r);
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
예제 #11
0
/**
 * Send shorten response back to client
 * 
 * @param cls the closure containing a client shorten handle
 * @param name the shortened name result or NULL if cannot be shortened
 */
static void
send_shorten_response(void* cls, const char* name)
{
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message with %s\n",
              "SHORTEN_RESULT", name);
  struct GNUNET_GNS_ClientShortenResultMessage *rmsg;
  struct ClientShortenHandle *csh = (struct ClientShortenHandle *)cls;
  
  if (name == NULL)
  {
    name = "";
  }

  rmsg = GNUNET_malloc(sizeof(struct GNUNET_GNS_ClientShortenResultMessage)
                       + strlen(name) + 1);
  
  rmsg->id = csh->unique_id;
  rmsg->header.type = htons(GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT);
  rmsg->header.size = 
    htons(sizeof(struct GNUNET_GNS_ClientShortenResultMessage) +
          strlen(name) + 1);

  strcpy((char*)&rmsg[1], name);

  GNUNET_SERVER_notification_context_unicast (nc, csh->client,
                              (const struct GNUNET_MessageHeader *) rmsg,
                              GNUNET_NO);
  GNUNET_SERVER_receive_done (csh->client, GNUNET_OK);
  
  GNUNET_free(rmsg);
  GNUNET_free_non_null(csh->name);
  GNUNET_free_non_null(csh->zone_key);
  GNUNET_free(csh);

}
예제 #12
0
/**
 * Handler for START message from client, sends information
 * about all identities to the client immediately and
 * adds the client to the notification context for future
 * updates.
 *
 * @param cls unused
 * @param client who sent the message
 * @param message the message received
 */
static void
handle_start_message (void *cls, struct GNUNET_SERVER_Client *client,
                      const struct GNUNET_MessageHeader *message)
{
  struct GNUNET_IDENTITY_UpdateMessage *um;
  struct GNUNET_IDENTITY_UpdateMessage ume;
  struct Ego *ego;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Received START message from client\n");
  GNUNET_SERVER_notification_context_add (nc, client);
  for (ego = ego_head; NULL != ego; ego = ego->next)
  {
    um = create_update_message (ego);
    GNUNET_SERVER_notification_context_unicast (nc, client, &um->header, GNUNET_NO);
    GNUNET_free (um);
  }
  memset (&ume, 0, sizeof (ume));
  ume.header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE);
  ume.header.size = htons (sizeof (struct GNUNET_IDENTITY_UpdateMessage));
  ume.end_of_list = htons (GNUNET_YES);
  ume.name_len = htons (0);
  GNUNET_SERVER_notification_context_unicast (nc, client, &ume.header, GNUNET_NO);
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
예제 #13
0
파일: service.c 프로젝트: tg-x/gnunet
/**
 * Send a 'TEST' message back to the client.
 *
 * @param cls the 'struct GNUNET_SERVER_Client' to send TEST to
 * @param size number of bytes available in 'buf'
 * @param buf where to copy the message
 * @return number of bytes written to 'buf'
 */
static size_t
write_test (void *cls, size_t size, void *buf)
{
  struct GNUNET_SERVER_Client *client = cls;
  struct GNUNET_MessageHeader *msg;

  if (size < sizeof (struct GNUNET_MessageHeader))
  {
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return 0;                   /* client disconnected */
  }
  msg = (struct GNUNET_MessageHeader *) buf;
  msg->type = htons (GNUNET_MESSAGE_TYPE_TEST);
  msg->size = htons (sizeof (struct GNUNET_MessageHeader));
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
  return sizeof (struct GNUNET_MessageHeader);
}
예제 #14
0
/**
 * Handler for GNUNET_MESSAGE_TYPE_TESTBED_GETSLAVECONFIG messages
 *
 * @param cls NULL
 * @param client identification of the client
 * @param message the actual message
 */
static void
handle_slave_get_config (void *cls, struct GNUNET_SERVER_Client *client,
                         const struct GNUNET_MessageHeader *message)
{
  struct GNUNET_TESTBED_SlaveGetConfigurationMessage *msg;
  struct Slave *slave;
  struct GNUNET_TESTBED_SlaveConfiguration *reply;
  const struct GNUNET_CONFIGURATION_Handle *cfg;
  char *config;
  char *xconfig;
  size_t config_size;
  size_t xconfig_size;
  size_t reply_size;
  uint64_t op_id;
  uint32_t slave_id;

  msg = (struct GNUNET_TESTBED_SlaveGetConfigurationMessage *) message;
  slave_id = ntohl (msg->slave_id);
  op_id = GNUNET_ntohll (msg->operation_id);
  if ((GST_slave_list_size <= slave_id) || (NULL == GST_slave_list[slave_id]))
  {
    /* FIXME: Add forwardings for this type of message here.. */
    GST_send_operation_fail_msg (client, op_id, "Slave not found");
    GNUNET_SERVER_receive_done (client, GNUNET_OK);
    return;
  }
  slave = GST_slave_list[slave_id];
  GNUNET_assert (NULL != (cfg = GNUNET_TESTBED_host_get_cfg_ (GST_host_list[slave->host_id])));
  config = GNUNET_CONFIGURATION_serialize (cfg, &config_size);
  xconfig_size =
      GNUNET_TESTBED_compress_config_ (config, config_size, &xconfig);
  GNUNET_free (config);
  reply_size = xconfig_size + sizeof (struct GNUNET_TESTBED_SlaveConfiguration);
  GNUNET_break (reply_size <= UINT16_MAX);
  GNUNET_break (config_size <= UINT16_MAX);
  reply = GNUNET_realloc (xconfig, reply_size);
  (void) memmove (&reply[1], reply, xconfig_size);
  reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_SLAVE_CONFIGURATION);
  reply->header.size = htons ((uint16_t) reply_size);
  reply->slave_id = msg->slave_id;
  reply->operation_id = msg->operation_id;
  reply->config_size = htons ((uint16_t) config_size);
  GST_queue_message (client, &reply->header);
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
예제 #15
0
static void
send_done (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct GNUNET_SERVER_Client *argclient = cls;

  GNUNET_assert (ok == 3);
  ok++;
  GNUNET_SERVER_receive_done (argclient, GNUNET_OK);
}
예제 #16
0
/**
 * Destroy a transmission context. This function must not be called
 * after 'GNUNET_SERVER_transmit_context_run'.
 *
 * @param tc transmission context to destroy
 * @param success code to give to 'GNUNET_SERVER_receive_done' for
 *        the client:  GNUNET_OK to keep the connection open and
 *                          continue to receive
 *                GNUNET_NO to close the connection (normal behavior)
 *                GNUNET_SYSERR to close the connection (signal
 *                          serious error)
 */
void
GNUNET_SERVER_transmit_context_destroy (struct GNUNET_SERVER_TransmitContext
                                        *tc, int success)
{
  GNUNET_SERVER_receive_done (tc->client, success);
  GNUNET_SERVER_client_drop (tc->client);
  GNUNET_free_non_null (tc->buf);
  GNUNET_free (tc);
}
예제 #17
0
static void
first_reply_handler (void *cls, const struct GNUNET_MessageHeader *msg)
{
  GNUNET_assert (ok == 4);
  ok = 5;
  GNUNET_SERVER_receive_done (argclient, GNUNET_OK);
  GNUNET_SERVER_client_drop (argclient);
  argclient = NULL;
}
예제 #18
0
static void
recv_fin_cb (void *cls, struct GNUNET_SERVER_Client *client,
             const struct GNUNET_MessageHeader *message)
{
  GNUNET_assert (ok == 5);
  ok = 6;
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
  GNUNET_SCHEDULER_add_now (&finish_up, NULL);
}
/**
 * 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);
}
예제 #20
0
파일: test_service.c 프로젝트: tg-x/gnunet
static void
recv_cb (void *cls, struct GNUNET_SERVER_Client *sc,
         const struct GNUNET_MessageHeader *message)
{
  GNUNET_assert (NULL != message);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receiving client message...\n");
  GNUNET_SERVER_receive_done (sc, GNUNET_OK);
  GNUNET_SCHEDULER_add_now (&do_stop, NULL);
  ok = 0;
}
/**
 * Handle HELLO-message.
 *
 * @param cls closure
 * @param client identification of the client
 * @param message the actual message
 */
static void
handle_hello (void *cls, struct GNUNET_SERVER_Client *client,
              const struct GNUNET_MessageHeader *message)
{
  const struct GNUNET_HELLO_Message *hello;
  struct GNUNET_PeerIdentity pid;

  hello = (const struct GNUNET_HELLO_Message *) message;
  if (GNUNET_OK != GNUNET_HELLO_get_id (hello, &pid))
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s' message received for peer `%4s'\n",
              "HELLO", GNUNET_i2s (&pid));
  bind_address (&pid, hello);
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
/**
 * Handle NOTIFY-message.
 *
 * @param cls closure
 * @param client identification of the client
 * @param message the actual message
 */
static void
handle_notify (void *cls, struct GNUNET_SERVER_Client *client,
               const struct GNUNET_MessageHeader *message)
{
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s' message received\n", "NOTIFY");
  GNUNET_SERVER_client_mark_monitor (client);
  GNUNET_SERVER_notification_context_add (notify_list, client);
  GNUNET_CONTAINER_multihashmap_iterate (hostmap, &do_notify_entry, client);
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
예제 #23
0
/**
 * Handle SEARCH message.
 *
 * @param cls closure
 * @param client identification of the client
 * @param message the actual message
 */
static void
handle_search (void *cls,
	       struct GNUNET_SERVER_Client *client,
	       const struct GNUNET_MessageHeader *message)
{
  const struct RegexSearchMessage *sm;
  const char *string;
  struct ClientEntry *ce;
  uint16_t size;

  size = ntohs (message->size);
  sm = (const struct RegexSearchMessage *) message;
  string = (const char *) &sm[1];
  if ( (size <= sizeof (struct RegexSearchMessage)) ||
       ('\0' != string[size - sizeof (struct RegexSearchMessage) - 1]) )
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Starting to search for `%s'\n",
	      string);
  ce = GNUNET_new (struct ClientEntry);
  ce->client = client;
  ce->sh = REGEX_INTERNAL_search (dht,
                                  string,
                                  &handle_search_result,
                                  ce,
                                  stats);
  if (NULL == ce->sh)
  {
    GNUNET_break (0);
    GNUNET_free (ce);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  GNUNET_CONTAINER_DLL_insert (client_head,
			       client_tail,
			       ce);
  GNUNET_SERVER_notification_context_add (nc, client);
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
/**
 * Callback to signal successfull startup of the controller process
 *
 * @param cls the handle to the slave whose status is to be found here
 * @param cfg the configuration with which the controller has been started;
 *          NULL if status is not GNUNET_OK
 * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not,
 *          GNUNET_TESTBED_controller_stop() shouldn't be called in this case
 */
static void
slave_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
                 int status)
{
  struct Slave *slave = cls;
  struct LinkControllersContext *lcc;

  lcc = slave->lcc;
  if (GNUNET_SYSERR == status)
  {
    slave->controller_proc = NULL;
    /* Stop all link controller forwarding tasks since we shutdown here anyway
       and as these tasks they depend on the operation queues which are created
       through GNUNET_TESTBED_controller_connect() and in kill_slave() we call
       the destructor function GNUNET_TESTBED_controller_disconnect() */
    GST_free_lcfq ();
    kill_slave (slave);
    destroy_slave (slave);
    slave = NULL;
    LOG (GNUNET_ERROR_TYPE_WARNING, "Unexpected slave shutdown\n");
    GNUNET_SCHEDULER_shutdown ();       /* We too shutdown */
    goto clean_lcc;
  }
  slave->controller =
      GNUNET_TESTBED_controller_connect (GST_host_list[slave->host_id],
                                         EVENT_MASK, &slave_event_cb,
                                         slave);
  if (NULL != slave->controller)
  {
    send_controller_link_response (lcc->client, lcc->operation_id, cfg, NULL);
  }
  else
  {
    send_controller_link_response (lcc->client, lcc->operation_id, NULL,
                                   "Could not connect to delegated controller");
    kill_slave (slave);
    destroy_slave (slave);
    slave = NULL;
  }

 clean_lcc:
  if (NULL != lcc)
  {
    if (NULL != lcc->client)
    {
      GNUNET_SERVER_receive_done (lcc->client, GNUNET_OK);
      GNUNET_SERVER_client_drop (lcc->client);
      lcc->client = NULL;
    }
    GNUNET_free (lcc);
  }
  if (NULL != slave)
    slave->lcc = NULL;
}
예제 #25
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);
}
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);
}
예제 #27
0
파일: service.c 프로젝트: tg-x/gnunet
/**
 * Handler for TEST message.
 *
 * @param cls closure (refers to service)
 * @param client identification of the client
 * @param message the actual message
 */
static void
handle_test (void *cls, struct GNUNET_SERVER_Client *client,
             const struct GNUNET_MessageHeader *message)
{
  /* simply bounce message back to acknowledge */
  if (NULL ==
      GNUNET_SERVER_notify_transmit_ready (client,
                                           sizeof (struct GNUNET_MessageHeader),
                                           GNUNET_TIME_UNIT_FOREVER_REL,
                                           &write_test, client))
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
}
/**
 * Handler for monitor stop messages
 *
 * @param cls closure for the service
 * @param client the client we received this message from
 * @param message the actual message received
 *
 */
static void
handle_dht_local_monitor_stop (void *cls, struct GNUNET_SERVER_Client *client,
                               const struct GNUNET_MessageHeader *message)
{
  struct ClientMonitorRecord *r;
  const struct GNUNET_DHT_MonitorStartStopMessage *msg;
  int keys_match;

  msg = (struct GNUNET_DHT_MonitorStartStopMessage *) message;
  r = monitor_head;

  while (NULL != r)
  {
    if (NULL == r->key)
        keys_match = (0 == ntohs(msg->filter_key));
    else
    {
        keys_match = (0 != ntohs(msg->filter_key)
                      && !memcmp(r->key, &msg->key, sizeof(struct GNUNET_HashCode)));
    }
    if (find_active_client(client) == r->client
        && ntohl(msg->type) == r->type
        && r->get == msg->get
        && r->get_resp == msg->get_resp
        && r->put == msg->put
        && keys_match
        )
    {
        GNUNET_CONTAINER_DLL_remove (monitor_head, monitor_tail, r);
        GNUNET_free_non_null (r->key);
        GNUNET_free (r);
        GNUNET_SERVER_receive_done (client, GNUNET_OK);
        return; /* Delete only ONE entry */
    }
    r = r->next;
  }

  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
예제 #29
0
/**
 * Handle LIST-message.
 *
 * @param cls closure (always NULL)
 * @param client identification of the client
 * @param message the actual message
 */
static void
handle_list (void *cls, struct GNUNET_SERVER_Client *client,
             const struct GNUNET_MessageHeader *message)
{
  struct GNUNET_ARM_ListResultMessage *msg;
  size_t string_list_size;
  size_t total_size;
  struct ServiceList *sl;
  uint16_t count;
  
  if (NULL == client)
    return;
  
  count = 0;
  string_list_size = 0;
  /* first count the running processes get their name's size */
  for (sl = running_head; sl != NULL; sl = sl->next)
  {
    if (sl->proc != NULL)
    {
      string_list_size += strlen (sl->name);
      string_list_size += strlen (sl->binary);
      string_list_size += 4;
      count++;
    }
  }
  total_size = sizeof (struct GNUNET_ARM_ListResultMessage) 
               + string_list_size;
  msg = GNUNET_malloc (total_size);
  msg->header.size = total_size;
  msg->header.type = GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT;
  msg->count = count;
  
  char *pos = (char *)&msg[1];
  for (sl = running_head; sl != NULL; sl = sl->next) 
  {
    if (sl->proc != NULL)
    {
      size_t s = strlen (sl->name) + strlen (sl->binary) + 4;
      GNUNET_snprintf(pos, s, "%s (%s)", sl->name, sl->binary);
      pos += s;
    }
  }
  
  GNUNET_SERVER_notify_transmit_ready (client,
                                       msg->header.size,
                                       GNUNET_TIME_UNIT_FOREVER_REL,
                                       &write_list_result, msg);
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
예제 #30
0
static size_t
copy_msg (void *cls, size_t size, void *buf)
{
  struct CopyContext *ctx = cls;
  struct GNUNET_MessageHeader *cpy = ctx->cpy;

  GNUNET_assert (sizeof (struct GNUNET_MessageHeader) == ntohs (cpy->size));
  GNUNET_assert (size >= ntohs (cpy->size));
  memcpy (buf, cpy, ntohs (cpy->size));
  GNUNET_SERVER_receive_done (ctx->client, GNUNET_OK);
  GNUNET_free (cpy);
  GNUNET_free (ctx);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Message bounced back to client\n");
  return sizeof (struct GNUNET_MessageHeader);
}