/** * 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, const struct GNUNET_MessageHeader *message) { struct UpdateMessage *ume; struct GNUNET_SERVICE_Client *client = cls; struct GNUNET_MQ_Envelope *env; struct Ego *ego; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received START message from client\n"); GNUNET_SERVICE_client_mark_monitor (client); GNUNET_SERVICE_client_disable_continue_warning (client); GNUNET_notification_context_add (nc, GNUNET_SERVICE_client_get_mq(client)); for (ego = ego_head; NULL != ego; ego = ego->next) { env = create_update_message (ego); GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(client), env); } env = GNUNET_MQ_msg_extra (ume, 0, GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE); ume->end_of_list = htons (GNUNET_YES); ume->name_len = htons (0); GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(client), env); GNUNET_SERVICE_client_continue (client); }
/** * Handler for client's SHOW_TUNNEL request. * * @param cls Identification of the client. * @param msg The actual message. */ static void handle_show_tunnel (void *cls, const struct GNUNET_CADET_LocalInfo *msg) { struct CadetClient *c = cls; struct GNUNET_MQ_Envelope *env; struct GNUNET_CADET_LocalInfoTunnel *resp; struct CadetTunnel *t; struct CadetPeer *p; unsigned int ch_n; unsigned int c_n; p = GCP_get (&msg->peer, GNUNET_NO); t = GCP_get_tunnel (p, GNUNET_NO); if (NULL == t) { /* We don't know the tunnel */ struct GNUNET_MQ_Envelope *env; struct GNUNET_CADET_LocalInfoTunnel *warn; LOG (GNUNET_ERROR_TYPE_INFO, "Tunnel to %s unknown\n", GNUNET_i2s_full (&msg->peer)); env = GNUNET_MQ_msg (warn, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL); warn->destination = msg->peer; GNUNET_MQ_send (c->mq, env); GNUNET_SERVICE_client_continue (c->client); return; } /* Initialize context */ ch_n = GCT_count_channels (t); c_n = GCT_count_any_connections (t); env = GNUNET_MQ_msg_extra (resp, c_n * sizeof (struct GNUNET_CADET_ConnectionTunnelIdentifier) + ch_n * sizeof (struct GCT_ChannelTunnelNumber), GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL); resp->destination = msg->peer; /* Do not reorder! #iter_channel needs counters in HBO! */ GCT_iterate_connections (t, &iter_connection, resp); GCT_iterate_channels (t, &iter_channel, resp); resp->connections = htonl (resp->connections); resp->channels = htonl (resp->channels); resp->cstate = htons (GCT_get_cstate (t)); resp->estate = htons (GCT_get_estate (t)); GNUNET_MQ_send (c->mq, env); GNUNET_SERVICE_client_continue (c->client); }
/** * Establish blacklist connection to transport service. * * @param br overall handle */ static void reconnect (struct GNUNET_TRANSPORT_Blacklist *br) { struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_fixed_size (query, GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_QUERY, struct BlacklistMessage, br), GNUNET_MQ_handler_end () }; struct GNUNET_MQ_Envelope *env; struct GNUNET_MessageHeader *req; if (NULL != br->mq) GNUNET_MQ_destroy (br->mq); br->mq = GNUNET_CLIENT_connect (br->cfg, "transport", handlers, &mq_error_handler, br); if (NULL == br->mq) return; env = GNUNET_MQ_msg (req, GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_INIT); GNUNET_MQ_send (br->mq, env); }
/** * We have updated performance statistics for a given address. Note * that this function can be called for addresses that are currently * in use as well as addresses that are valid but not actively in use. * Furthermore, the peer may not even be connected to us right now (in * which case the call may be ignored or the information may be stored * for later use). Update bandwidth assignments. * * @param ar address record to update information for * @param prop performance data for the address */ void GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar, const struct GNUNET_ATS_Properties *prop) { struct GNUNET_ATS_SchedulingHandle *sh = ar->sh; struct GNUNET_MQ_Envelope *ev; struct AddressUpdateMessage *m; LOG (GNUNET_ERROR_TYPE_DEBUG, "Updating address for peer `%s', plugin `%s', session %p slot %u\n", GNUNET_i2s (&ar->address->peer), ar->address->transport_name, ar->session, ar->slot); GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope); GNUNET_ATS_properties_hton (&ar->properties, prop); if (NULL == sh->mq) return; /* disconnected, skip for now */ ev = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE); m->session_id = htonl (ar->slot); m->peer = ar->address->peer; m->properties = ar->properties; GNUNET_MQ_send (sh->mq, ev); }
/** * Iterate over records matching supplied key information * * @param h handle to the PEERSTORE service * @param sub_system name of sub system * @param peer Peer identity (can be NULL) * @param key entry key string (can be NULL) * @param timeout time after which the iterate request is canceled * @param callback function called with each matching record, all NULL's on end * @param callback_cls closure for @a callback * @return Handle to iteration request */ struct GNUNET_PEERSTORE_IterateContext * GNUNET_PEERSTORE_iterate (struct GNUNET_PEERSTORE_Handle *h, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, struct GNUNET_TIME_Relative timeout, GNUNET_PEERSTORE_Processor callback, void *callback_cls) { struct GNUNET_MQ_Envelope *ev; struct GNUNET_PEERSTORE_IterateContext *ic; ev = PEERSTORE_create_record_mq_envelope (sub_system, peer, key, NULL, 0, NULL, 0, GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE); ic = GNUNET_new (struct GNUNET_PEERSTORE_IterateContext); ic->callback = callback; ic->callback_cls = callback_cls; ic->h = h; ic->sub_system = GNUNET_strdup (sub_system); if (NULL != peer) ic->peer = *peer; if (NULL != key) ic->key = GNUNET_strdup (key); ic->timeout = timeout; GNUNET_CONTAINER_DLL_insert_tail (h->iterate_head, h->iterate_tail, ic); LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending an iterate request for sub system `%s'\n", sub_system); GNUNET_MQ_send (h->mq, ev); ic->timeout_task = GNUNET_SCHEDULER_add_delayed (timeout, &iterate_timeout, ic); return ic; }
/** * Remove an element to the given set. After the element has been * removed (in the sense of the request being transmitted to the set * service), @a cont will be called. Multiple calls to * GNUNET_SET_remove_element() can be queued * * @param set set to remove element from * @param element element to remove from the set * @param cont continuation called after the element has been removed * @param cont_cls closure for @a cont * @return #GNUNET_OK on success, #GNUNET_SYSERR if the * set is invalid (e.g. the set service crashed) */ int GNUNET_SET_remove_element (struct GNUNET_SET_Handle *set, const struct GNUNET_SET_Element *element, GNUNET_SET_Continuation cont, void *cont_cls) { struct GNUNET_MQ_Envelope *mqm; struct GNUNET_SET_ElementMessage *msg; if (GNUNET_YES == set->invalid) { if (NULL != cont) cont (cont_cls); return GNUNET_SYSERR; } mqm = GNUNET_MQ_msg_extra (msg, element->size, GNUNET_MESSAGE_TYPE_SET_REMOVE); msg->element_type = htons (element->element_type); memcpy (&msg[1], element->data, element->size); GNUNET_MQ_notify_sent (mqm, cont, cont_cls); GNUNET_MQ_send (set->mq, mqm); return GNUNET_OK; }
/** * Send a result code back to the client. * * @param client client that should receive the result code * @param result_code code to transmit * @param emsg error message to include (or NULL for none) */ static void send_result_code (struct GNUNET_SERVICE_Client *client, uint32_t result_code, const char *emsg) { struct ResultCodeMessage *rcm; struct GNUNET_MQ_Envelope *env; size_t elen; if (NULL == emsg) elen = 0; else elen = strlen (emsg) + 1; env = GNUNET_MQ_msg_extra (rcm, elen, GNUNET_MESSAGE_TYPE_IDENTITY_RESULT_CODE); rcm->result_code = htonl (result_code); if (0 < elen) GNUNET_memcpy (&rcm[1], emsg, elen); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending result %d (%s) to client\n", (int) result_code, emsg); GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); }
/** * Task to re-try connecting to peerinfo. * * @param cls the `struct GNUNET_PEERINFO_NotifyContext *` */ static void reconnect (void *cls) { struct GNUNET_PEERINFO_NotifyContext *nc = cls; struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size (notification, GNUNET_MESSAGE_TYPE_PEERINFO_INFO, struct InfoMessage, nc), GNUNET_MQ_hd_fixed_size (end_iteration, GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END, struct GNUNET_MessageHeader, nc), GNUNET_MQ_handler_end () }; struct GNUNET_MQ_Envelope *env; struct NotifyMessage *nm; nc->task = NULL; nc->mq = GNUNET_CLIENT_connect (nc->cfg, "peerinfo", handlers, &mq_error_handler, nc); if (NULL == nc->mq) return; env = GNUNET_MQ_msg (nm, GNUNET_MESSAGE_TYPE_PEERINFO_NOTIFY); nm->include_friend_only = htonl (nc->include_friend_only); GNUNET_MQ_send (nc->mq, env); }
static struct GNUNET_SET_Handle * create_internal (const struct GNUNET_CONFIGURATION_Handle *cfg, enum GNUNET_SET_OperationType op, uint32_t *cookie) { static const struct GNUNET_MQ_MessageHandler mq_handlers[] = { { &handle_result, GNUNET_MESSAGE_TYPE_SET_RESULT, 0 }, { &handle_iter_element, GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT, 0 }, { &handle_iter_done, GNUNET_MESSAGE_TYPE_SET_ITER_DONE, sizeof (struct GNUNET_MessageHeader) }, { &handle_copy_lazy, GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_RESPONSE, sizeof (struct GNUNET_SET_CopyLazyResponseMessage) }, GNUNET_MQ_HANDLERS_END }; struct GNUNET_SET_Handle *set; struct GNUNET_MQ_Envelope *mqm; struct GNUNET_SET_CreateMessage *create_msg; struct GNUNET_SET_CopyLazyConnectMessage *copy_msg; set = GNUNET_new (struct GNUNET_SET_Handle); set->client = GNUNET_CLIENT_connect ("set", cfg); set->cfg = cfg; if (NULL == set->client) { GNUNET_free (set); return NULL; } set->mq = GNUNET_MQ_queue_for_connection_client (set->client, mq_handlers, &handle_client_set_error, set); GNUNET_assert (NULL != set->mq); if (NULL == cookie) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating new set (operation %u)\n", op); mqm = GNUNET_MQ_msg (create_msg, GNUNET_MESSAGE_TYPE_SET_CREATE); create_msg->operation = htonl (op); } else { LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating new set (lazy copy)\n", op); mqm = GNUNET_MQ_msg (copy_msg, GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_CONNECT); copy_msg->cookie = *cookie; } GNUNET_MQ_send (set->mq, mqm); return set; }
/** * Bob generates the response message to be sent to Alice. * * @param s the associated requesting session with Alice */ static void transmit_bobs_cryptodata_message (struct BobServiceSession *s) { struct EccBobCryptodataMessage *msg; struct GNUNET_MQ_Envelope *e; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending response to Alice\n"); e = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA); msg->contained_element_count = htonl (2); if (NULL != s->prod_g_i_b_i) GNUNET_CRYPTO_ecc_point_to_bin (edc, s->prod_g_i_b_i, &msg->prod_g_i_b_i); if (NULL != s->prod_h_i_b_i) GNUNET_CRYPTO_ecc_point_to_bin (edc, s->prod_h_i_b_i, &msg->prod_h_i_b_i); GNUNET_MQ_notify_sent (e, &bob_cadet_done_cb, s); GNUNET_MQ_send (s->cadet->cadet_mq, e); }
/** * Iterator over all tunnels to send a monitoring client info about each tunnel. * * @param cls Closure (). * @param peer Peer ID (tunnel remote peer). * @param value a `struct CadetPeer` * @return #GNUNET_YES, to keep iterating. */ static int get_all_tunnels_iterator (void *cls, const struct GNUNET_PeerIdentity *peer, void *value) { struct CadetClient *c = cls; struct CadetPeer *p = value; struct GNUNET_MQ_Envelope *env; struct GNUNET_CADET_LocalInfoTunnel *msg; struct CadetTunnel *t; t = GCP_get_tunnel (p, GNUNET_NO); if (NULL == t) return GNUNET_YES; env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS); msg->destination = *peer; msg->channels = htonl (GCT_count_channels (t)); msg->connections = htonl (GCT_count_any_connections (t)); msg->cstate = htons ((uint16_t) GCT_get_cstate (t)); msg->estate = htons ((uint16_t) GCT_get_estate (t)); GNUNET_MQ_send (c->mq, env); return GNUNET_YES; }
/** * Send a message to a client. * * @param c client to get the message * @param env envelope with the message */ void GSC_send_to_client (struct CadetClient *c, struct GNUNET_MQ_Envelope *env) { GNUNET_MQ_send (c->mq, env); }
/** * Connect to the set service in order to listen for requests. * * @param cls the `struct GNUNET_SET_ListenHandle *` to connect * @param tc task context if invoked as a task, NULL otherwise */ static void listen_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { static const struct GNUNET_MQ_MessageHandler mq_handlers[] = { { &handle_request, GNUNET_MESSAGE_TYPE_SET_REQUEST }, GNUNET_MQ_HANDLERS_END }; struct GNUNET_SET_ListenHandle *lh = cls; struct GNUNET_MQ_Envelope *mqm; struct GNUNET_SET_ListenMessage *msg; if ( (NULL != tc) && (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) ) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Listener not reconnecting due to shutdown\n"); return; } lh->reconnect_task = NULL; GNUNET_assert (NULL == lh->client); lh->client = GNUNET_CLIENT_connect ("set", lh->cfg); if (NULL == lh->client) return; GNUNET_assert (NULL == lh->mq); lh->mq = GNUNET_MQ_queue_for_connection_client (lh->client, mq_handlers, &handle_client_listener_error, lh); mqm = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_LISTEN); msg->operation = htonl (lh->operation); msg->app_id = lh->app_id; GNUNET_MQ_send (lh->mq, mqm); }
static void send_message (struct GNUNET_MQ_Handle *mq, int32_t num) { struct GNUNET_MQ_Envelope *env; struct TestMessage *hdr; unsigned int s; GNUNET_assert (NULL != mq); GNUNET_assert (tr_n < TOTAL_MSGS); s = get_size (tr_n); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending message %u of size %u\n", tr_n, s); env = GNUNET_MQ_msg_extra (hdr, s - sizeof (struct TestMessage), MTYPE); hdr->num = htonl (tr_n); memset (&hdr[1], tr_n, s - sizeof (struct TestMessage)); tr_n++; GNUNET_SCHEDULER_cancel (err_task); err_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &terminate_task_error, NULL); total_bytes += s; GNUNET_MQ_send (mq, env); }
/** * Calculate when we would like to send the next HELLO to this * peer and ask for it. * * @param cls for which peer to schedule the HELLO */ static void schedule_next_hello (void *cls) { struct Peer *pl = cls; struct FindAdvHelloContext fah; struct GNUNET_MQ_Envelope *env; size_t want; struct GNUNET_TIME_Relative delay; struct GNUNET_HashCode hc; pl->hello_delay_task = NULL; GNUNET_assert (NULL != pl->mq); /* find applicable HELLOs */ fah.peer = pl; fah.result = NULL; fah.max_size = GNUNET_SERVER_MAX_MESSAGE_SIZE - 1; fah.next_adv = GNUNET_TIME_UNIT_FOREVER_REL; GNUNET_CONTAINER_multipeermap_iterate (peers, &find_advertisable_hello, &fah); pl->hello_delay_task = GNUNET_SCHEDULER_add_delayed (fah.next_adv, &schedule_next_hello, pl); if (NULL == fah.result) return; delay = GNUNET_TIME_absolute_get_remaining (pl->next_hello_allowed); if (0 != delay.rel_value_us) return; want = GNUNET_HELLO_size (fah.result->hello); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending HELLO with %u bytes", (unsigned int) want); env = GNUNET_MQ_msg_copy (&fah.result->hello->header); GNUNET_MQ_send (pl->mq, env); /* avoid sending this one again soon */ GNUNET_CRYPTO_hash (&pl->pid, sizeof (struct GNUNET_PeerIdentity), &hc); GNUNET_CONTAINER_bloomfilter_add (fah.result->filter, &hc); GNUNET_STATISTICS_update (stats, gettext_noop ("# HELLO messages gossipped"), 1, GNUNET_NO); /* prepare to send the next one */ if (NULL != pl->hello_delay_task) GNUNET_SCHEDULER_cancel (pl->hello_delay_task); pl->next_hello_allowed = GNUNET_TIME_relative_to_absolute (HELLO_ADVERTISEMENT_MIN_FREQUENCY); pl->hello_delay_task = GNUNET_SCHEDULER_add_now (&schedule_next_hello, pl); }
/** * Task that triggers a NSE P2P transmission. * * @param cls the `struct NSEPeerEntry *` */ static void transmit_task_cb (void *cls) { struct NSEPeerEntry *peer_entry = cls; unsigned int idx; struct GNUNET_MQ_Envelope *env; peer_entry->transmit_task = NULL; idx = estimate_index; if (GNUNET_NO == peer_entry->previous_round) { idx = (idx + HISTORY_SIZE - 1) % HISTORY_SIZE; peer_entry->previous_round = GNUNET_YES; peer_entry->transmit_task = GNUNET_SCHEDULER_add_delayed (get_transmit_delay (0), &transmit_task_cb, peer_entry); } if ((0 == ntohl (size_estimate_messages[idx].hop_count)) && (NULL != proof_task)) { GNUNET_STATISTICS_update (stats, "# flood messages not generated (no proof yet)", 1, GNUNET_NO); return; } if (0 == ntohs (size_estimate_messages[idx].header.size)) { GNUNET_STATISTICS_update (stats, "# flood messages not generated (lack of history)", 1, GNUNET_NO); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "In round %s, sending to `%s' estimate with %u bits\n", GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (size_estimate_messages[idx].timestamp)), GNUNET_i2s (peer_entry->id), (unsigned int) ntohl (size_estimate_messages[idx].matching_bits)); if (0 == ntohl (size_estimate_messages[idx].hop_count)) GNUNET_STATISTICS_update (stats, "# flood messages started", 1, GNUNET_NO); GNUNET_STATISTICS_update (stats, "# flood messages transmitted", 1, GNUNET_NO); #if ENABLE_NSE_HISTOGRAM peer_entry->transmitted_messages++; peer_entry->last_transmitted_size = ntohl(size_estimate_messages[idx].matching_bits); #endif env = GNUNET_MQ_msg_copy (&size_estimate_messages[idx].header); GNUNET_MQ_send (peer_entry->mq, env); }
/** * First task run by the scheduler. Initializes the server and * a client and asks for a transmission from the client to the * server. * * @param cls NULL */ static void task (void *cls) { struct sockaddr_in sa; struct sockaddr *sap[2]; socklen_t slens[2]; struct GNUNET_MQ_Envelope *env; struct GNUNET_MessageHeader *msg; struct GNUNET_MQ_MessageHandler chandlers[] = { GNUNET_MQ_hd_fixed_size (reply, MY_TYPE, struct GNUNET_MessageHeader, cls), GNUNET_MQ_handler_end () }; sap[0] = (struct sockaddr *) &sa; slens[0] = sizeof (sa); sap[1] = NULL; slens[1] = 0; memset (&sa, 0, sizeof (sa)); #if HAVE_SOCKADDR_IN_SIN_LEN sa.sin_len = sizeof (sa); #endif sa.sin_family = AF_INET; sa.sin_port = htons (PORT); server = GNUNET_SERVER_create (NULL, NULL, sap, slens, TIMEOUT, GNUNET_NO); GNUNET_assert (server != NULL); GNUNET_SERVER_add_handlers (server, handlers); cfg = GNUNET_CONFIGURATION_create (); GNUNET_CONFIGURATION_set_value_number (cfg, "test-server", "PORT", PORT); GNUNET_CONFIGURATION_set_value_string (cfg, "test-server", "HOSTNAME", "localhost"); GNUNET_CONFIGURATION_set_value_string (cfg, "resolver", "HOSTNAME", "localhost"); mq = GNUNET_CLIENT_connect (cfg, "test-server", chandlers, &mq_error_handler, NULL); GNUNET_assert (NULL != mq); ok = 2; env = GNUNET_MQ_msg (msg, MY_TYPE); GNUNET_MQ_send (mq, env); }
/** * Function to handle a ring message incoming over cadet * * @param cls closure, NULL * @param channel the channel over which the message arrived * @param channel_ctx the channel context, can be NULL * or point to the `struct Channel` * @param message the incoming message * @return #GNUNET_OK */ static int handle_cadet_ring_message (void *cls, struct GNUNET_CADET_Channel *channel, void **channel_ctx, const struct GNUNET_MessageHeader *message) { struct Channel *ch = *channel_ctx; struct Line *line = ch->line; const struct CadetPhoneRingMessage *msg; struct GNUNET_MQ_Envelope *env; struct ClientPhoneRingMessage *cring; struct CadetPhoneRingInfoPS rs; msg = (const struct CadetPhoneRingMessage *) message; rs.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING); rs.purpose.size = htonl (sizeof (struct CadetPhoneRingInfoPS)); rs.line_port = line->line_port; rs.target_peer = my_identity; rs.expiration_time = msg->expiration_time; if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING, &rs.purpose, &msg->signature, &msg->caller_id)) { GNUNET_break_op (0); return GNUNET_SYSERR; } if (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh (msg->expiration_time)).rel_value_us) { /* ancient call, replay? */ GNUNET_break_op (0); /* Note that our reliance on time here is awkward; better would be to use a more complex challenge-response protocol against replay attacks. Left for future work ;-). */ return GNUNET_SYSERR; } if (CS_CALLEE_INIT != ch->status) { GNUNET_break_op (0); return GNUNET_SYSERR; } GNUNET_CADET_receive_done (channel); ch->status = CS_CALLEE_RINGING; env = GNUNET_MQ_msg (cring, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RING); cring->cid = ch->cid; cring->caller_id = msg->caller_id; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending RING message to client. CID is %u\n", (unsigned int) ch->cid); GNUNET_MQ_send (line->mq, env); return GNUNET_OK; }
/** * Function to handle a resume message incoming over cadet * * @param cls closure, NULL * @param channel the channel over which the message arrived * @param channel_ctx the channel context, can be NULL * or point to the `struct Channel` * @param message the incoming message * @return #GNUNET_OK */ static int handle_cadet_resume_message (void *cls, struct GNUNET_CADET_Channel *channel, void **channel_ctx, const struct GNUNET_MessageHeader *message) { struct Channel *ch = *channel_ctx; struct Line *line; struct GNUNET_MQ_Envelope *env; struct ClientPhoneResumeMessage *resume; if (NULL == ch) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "RESUME message received for non-existing line, dropping channel.\n"); return GNUNET_SYSERR; } line = ch->line; GNUNET_CADET_receive_done (channel); if (GNUNET_YES != ch->suspended_remote) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "RESUME message received for non-suspended channel, dropping channel.\n"); return GNUNET_SYSERR; } switch (ch->status) { case CS_CALLEE_INIT: GNUNET_break (0); break; case CS_CALLEE_RINGING: GNUNET_break (0); break; case CS_CALLEE_CONNECTED: ch->suspended_remote = GNUNET_NO; break; case CS_CALLEE_SHUTDOWN: return GNUNET_OK; case CS_CALLER_CALLING: GNUNET_break (0); break; case CS_CALLER_CONNECTED: ch->suspended_remote = GNUNET_NO; break; case CS_CALLER_SHUTDOWN: return GNUNET_OK; } env = GNUNET_MQ_msg (resume, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RESUME); resume->cid = ch->cid; GNUNET_MQ_send (line->mq, env); return GNUNET_OK; }
static void test_mq (struct GNUNET_CLIENT_Connection *client) { struct GNUNET_MQ_Handle *mq; struct GNUNET_MQ_Envelope *mqm; /* FIXME: test handling responses */ mq = GNUNET_MQ_queue_for_connection_client (client, NULL, NULL, NULL); mqm = GNUNET_MQ_msg_header (MY_TYPE); GNUNET_MQ_send (mq, mqm); mqm = GNUNET_MQ_msg_header (MY_TYPE); GNUNET_MQ_notify_sent (mqm, send_trap_cb, NULL); GNUNET_MQ_send (mq, mqm); GNUNET_MQ_send_cancel (mqm); mqm = GNUNET_MQ_msg_header (MY_TYPE); GNUNET_MQ_notify_sent (mqm, send_cb, NULL); GNUNET_MQ_send (mq, mqm); }
/** * Iterator over previous watches to resend them * * @param cls the `struct GNUNET_PEERSTORE_Handle` * @param key key for the watch * @param value the `struct GNUNET_PEERSTORE_WatchContext *` * @return #GNUNET_YES (continue to iterate) */ static int rewatch_it (void *cls, const struct GNUNET_HashCode *key, void *value) { struct GNUNET_PEERSTORE_Handle *h = cls; struct GNUNET_PEERSTORE_WatchContext *wc = value; struct StoreKeyHashMessage *hm; struct GNUNET_MQ_Envelope *ev; ev = GNUNET_MQ_msg (hm, GNUNET_MESSAGE_TYPE_PEERSTORE_WATCH); hm->keyhash = wc->keyhash; GNUNET_MQ_send (h->mq, ev); return GNUNET_YES; }
/** * We have received the reply from the server, check that we are at * the right stage and queue the next message to the server. Cleans * up #argclient. * * @param cls NULL * @param msg message we got from the server */ static void handle_reply (void *cls, const struct GNUNET_MessageHeader *msg) { struct GNUNET_MQ_Envelope *env; struct GNUNET_MessageHeader *m; GNUNET_assert (4 == ok); ok = 6; env = GNUNET_MQ_msg (m, MY_TYPE2); GNUNET_MQ_send (mq, env); }
/** * @brief Send a message to another peer. * * Keeps track about pending messages so they can be properly removed when the * peer is destroyed. * * @param peer receeiver of the message * @param ev envelope of the message * @param type type of the message */ void Peers_send_message (const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Envelope *ev, const char *type) { struct PendingMessage *pending_msg; struct GNUNET_MQ_Handle *mq; pending_msg = insert_pending_message (peer, ev, type); mq = get_mq (peer); GNUNET_MQ_notify_sent (ev, mq_notify_sent_cb, pending_msg); GNUNET_MQ_send (mq, ev); }
/** * Function to send a failure reponse for controller link operation * * @param client the client to send the message to * @param operation_id the operation ID of the controller link request * @param cfg the configuration with which the delegated controller is started. * Can be NULL if the delegated controller is not started but just * linked to. * @param emsg set to an error message explaining why the controller link * failed. Setting this to NULL signifies success. !This should be * NULL if cfg is set! */ static void send_controller_link_response (struct GNUNET_SERVICE_Client *client, uint64_t operation_id, const struct GNUNET_CONFIGURATION_Handle *cfg, const char *emsg) { struct GNUNET_MQ_Envelope *env; struct GNUNET_TESTBED_ControllerLinkResponse *msg; char *xconfig; size_t config_size; size_t xconfig_size; uint16_t msize; GNUNET_assert ((NULL == cfg) || (NULL == emsg)); xconfig = NULL; xconfig_size = 0; config_size = 0; msize = 0; if (NULL != cfg) { xconfig = GNUNET_TESTBED_compress_cfg_ (cfg, &config_size, &xconfig_size); msize += xconfig_size; } if (NULL != emsg) msize += strlen (emsg); env = GNUNET_MQ_msg_extra (msg, msize, GNUNET_MESSAGE_TYPE_TESTBED_LINK_CONTROLLERS_RESULT); if (NULL == emsg) msg->success = htons (GNUNET_YES); msg->operation_id = GNUNET_htonll (operation_id); msg->config_size = htons ((uint16_t) config_size); if (NULL != xconfig) { GNUNET_memcpy (&msg[1], xconfig, xconfig_size); GNUNET_free (xconfig); } if (NULL != emsg) GNUNET_memcpy (&msg[1], emsg, strlen (emsg)); GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); }
/** * Function called whenever an inbound channel is destroyed. Should clean up * any associated state. * * @param cls closure (set from #GNUNET_CADET_connect) * @param channel connection to the other end (henceforth invalid) * @param channel_ctx place where local state associated * with the channel is stored; * may point to the `struct Channel` */ static void inbound_end (void *cls, const struct GNUNET_CADET_Channel *channel, void *channel_ctx) { struct Channel *ch = channel_ctx; struct Line *line; struct GNUNET_MQ_Envelope *env; struct ClientPhoneHangupMessage *hup; if (NULL == ch) { GNUNET_break (0); return; } line = ch->line; GNUNET_assert (channel == ch->channel); ch->channel = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Channel destroyed by CADET in state %d\n", ch->status); switch (ch->status) { case CS_CALLEE_INIT: case CS_CALLEE_SHUTDOWN: case CS_CALLER_SHUTDOWN: break; case CS_CALLEE_RINGING: case CS_CALLEE_CONNECTED: case CS_CALLER_CALLING: case CS_CALLER_CONNECTED: if (NULL != line) { env = GNUNET_MQ_msg (hup, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP); hup->cid = ch->cid; GNUNET_MQ_send (line->mq, env); } break; } destroy_line_cadet_channels (ch); if (NULL != line) GNUNET_CONTAINER_DLL_remove (line->channel_head, line->channel_tail, ch); GNUNET_free (ch); }
/** * Handler for client's INFO TUNNELS request. * * @param cls client Identification of the client. * @param message The actual message. */ static void handle_get_tunnels (void *cls, const struct GNUNET_MessageHeader *message) { struct CadetClient *c = cls; struct GNUNET_MQ_Envelope *env; struct GNUNET_MessageHeader *reply; GCP_iterate_all (&get_all_tunnels_iterator, c); env = GNUNET_MQ_msg (reply, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS); GNUNET_MQ_send (c->mq, env); GNUNET_SERVICE_client_continue (c->client); }
/** * Handle request message for a listen operation * * @param cls the listen handle * @param mh the message */ static void handle_request (void *cls, const struct GNUNET_MessageHeader *mh) { struct GNUNET_SET_ListenHandle *lh = cls; const struct GNUNET_SET_RequestMessage *msg; struct GNUNET_SET_Request req; const struct GNUNET_MessageHeader *context_msg; uint16_t msize; struct GNUNET_MQ_Envelope *mqm; struct GNUNET_SET_RejectMessage *rmsg; LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing incoming operation request\n"); msize = ntohs (mh->size); if (msize < sizeof (struct GNUNET_SET_RequestMessage)) { GNUNET_break (0); GNUNET_CLIENT_disconnect (lh->client); lh->client = NULL; GNUNET_MQ_destroy (lh->mq); lh->mq = NULL; lh->reconnect_task = GNUNET_SCHEDULER_add_delayed (lh->reconnect_backoff, &listen_connect, lh); lh->reconnect_backoff = GNUNET_TIME_STD_BACKOFF (lh->reconnect_backoff); return; } /* we got another valid request => reset the backoff */ lh->reconnect_backoff = GNUNET_TIME_UNIT_MILLISECONDS; msg = (const struct GNUNET_SET_RequestMessage *) mh; req.accept_id = ntohl (msg->accept_id); req.accepted = GNUNET_NO; context_msg = GNUNET_MQ_extract_nested_mh (msg); /* calling #GNUNET_SET_accept() in the listen cb will set req->accepted */ lh->listen_cb (lh->listen_cls, &msg->peer_id, context_msg, &req); if (GNUNET_YES == req.accepted) return; /* the accept-case is handled in #GNUNET_SET_accept() */ LOG (GNUNET_ERROR_TYPE_DEBUG, "Rejecting request\n"); mqm = GNUNET_MQ_msg (rmsg, GNUNET_MESSAGE_TYPE_SET_REJECT); rmsg->accept_reject_id = msg->accept_id; GNUNET_MQ_send (lh->mq, mqm); }
static void connect_cb (void *cls, const struct GNUNET_PeerIdentity *peer) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected to peer %s.\n", GNUNET_i2s (peer)); if (0 == memcmp (peer, &myself, sizeof (struct GNUNET_PeerIdentity))) { unsigned int i; struct GNUNET_MQ_Envelope *ev; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Queueing messages.\n"); for (i = 0; i < NUM_MSG; i++) { ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_TEST); GNUNET_MQ_send (mq, ev); } } }
/** * Handler for GET_DEFAULT message from client, returns * default identity for some service. * * @param cls unused * @param client who sent the message * @param message the message received */ static void handle_get_default_message (void *cls, const struct GetDefaultMessage *gdm) { struct GNUNET_MQ_Envelope *env; struct GNUNET_SERVICE_Client *client = cls; struct Ego *ego; const char *name; char *identifier; name = (const char *) &gdm[1]; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received GET_DEFAULT for service `%s' from client\n", name); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (subsystem_cfg, name, "DEFAULT_IDENTIFIER", &identifier)) { send_result_code (client, 1, gettext_noop ("no default known")); GNUNET_SERVICE_client_continue (client); return; } for (ego = ego_head; NULL != ego; ego = ego->next) { if (0 == strcmp (ego->identifier, identifier)) { env = create_set_default_message (ego, name); GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); GNUNET_SERVICE_client_continue (client); GNUNET_free (identifier); return; } } GNUNET_free (identifier); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to find ego `%s'\n", name); send_result_code (client, 1, gettext_noop ("default configured, but ego unknown (internal error)")); GNUNET_SERVICE_client_continue (client); }
/** * Handle blacklist queries. * * @param cls our overall handle * @param bm query */ static void handle_query (void *cls, const struct BlacklistMessage *bm) { struct GNUNET_TRANSPORT_Blacklist *br = cls; struct GNUNET_MQ_Envelope *env; struct BlacklistMessage *res; GNUNET_break (0 == ntohl (bm->is_allowed)); env = GNUNET_MQ_msg (res, GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY); res->is_allowed = htonl (br->cb (br->cb_cls, &bm->peer)); res->peer = bm->peer; GNUNET_MQ_send (br->mq, env); }