/** * 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); }
/** * 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); }
/** * 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); }
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); }
/** * 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); }
/** * 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); }
/** * 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); }
/** * 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); }
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); }
/** * 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); }
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; }
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 (¬ify_client_about_neighbour, tc); GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, tc); GNUNET_SERVER_receive_done (client, GNUNET_OK); }
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); }
/** * 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; }
/** * 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); }
/** * 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); }
/** * 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); }
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); }