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; }
/** * Bind incoming channel to this client, and notify client * about incoming connection. * * @param c client to bind to * @param ch channel to be bound * @param dest peer that establishes the connection * @param port port number * @param options options * @return local channel number assigned to the new client */ struct GNUNET_CADET_ClientChannelNumber GSC_bind (struct CadetClient *c, struct CadetChannel *ch, struct CadetPeer *dest, const struct GNUNET_HashCode *port, uint32_t options) { struct GNUNET_MQ_Envelope *env; struct GNUNET_CADET_ChannelCreateMessage *msg; struct GNUNET_CADET_ClientChannelNumber lid; lid = client_get_next_lid (c); GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap32_put (c->incoming_channels, ntohl (lid.channel_of_client), ch, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); /* notify local client about incoming connection! */ env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_CREATE); msg->channel_id = lid; msg->port = *port; msg->opt = htonl (options); msg->peer = *GCP_get_id (dest); GSC_send_to_client (c, env); return lid; }
/** * 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); }
/** * 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); }
/** * 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); }
/** * 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); }
/** * 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; }
/** * 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); }
/** * 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; }
/** * 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); }
/** * 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); }
/** * Cancel a watch request * * @param wc handle to the watch request */ void GNUNET_PEERSTORE_watch_cancel (struct GNUNET_PEERSTORE_WatchContext *wc) { struct GNUNET_PEERSTORE_Handle *h = wc->h; struct GNUNET_MQ_Envelope *ev; struct StoreKeyHashMessage *hm; LOG (GNUNET_ERROR_TYPE_DEBUG, "Canceling watch.\n"); ev = GNUNET_MQ_msg (hm, GNUNET_MESSAGE_TYPE_PEERSTORE_WATCH_CANCEL); hm->keyhash = wc->keyhash; GNUNET_MQ_send (h->mq, ev); GNUNET_CONTAINER_multihashmap_remove (h->watches, &wc->keyhash, wc); GNUNET_free (wc); }
/** * 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); }
/** * Function to handle call request from the client * * @param cls the `struct Line` the message is about * @param msg the message from the client */ static void handle_client_call_message (void *cls, const struct ClientCallMessage *msg) { struct Line *line = cls; struct Channel *ch; struct GNUNET_MQ_Envelope *e; struct CadetPhoneRingMessage *ring; struct CadetPhoneRingInfoPS rs; line->line_port = msg->line_port; 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 = msg->target; rs.expiration_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (RING_TIMEOUT)); ch = GNUNET_new (struct Channel); ch->line = line; GNUNET_CONTAINER_DLL_insert (line->channel_head, line->channel_tail, ch); ch->status = CS_CALLER_CALLING; ch->channel = GNUNET_CADET_channel_create (cadet, ch, &msg->target, &msg->line_port, GNUNET_CADET_OPTION_RELIABLE); ch->mq = GNUNET_CADET_mq_create (ch->channel); e = GNUNET_MQ_msg (ring, GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RING); GNUNET_CRYPTO_ecdsa_key_get_public (&msg->caller_id, &ring->caller_id); ring->expiration_time = rs.expiration_time; GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_sign (&msg->caller_id, &rs.purpose, &ring->signature)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending RING message via CADET\n"); GNUNET_MQ_send (ch->mq, e); GNUNET_SERVICE_client_continue (line->client); }
/** * Re-establish the connection to the ATS service. * * @param sh handle to use to re-connect. */ static void reconnect (struct GNUNET_ATS_SchedulingHandle *sh) { static const struct GNUNET_MQ_MessageHandler handlers[] = { { &process_ats_session_release_message, GNUNET_MESSAGE_TYPE_ATS_SESSION_RELEASE, sizeof (struct GNUNET_ATS_SessionReleaseMessage) }, { &process_ats_address_suggestion_message, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION, sizeof (struct AddressSuggestionMessage) }, { NULL, 0, 0 } }; struct GNUNET_MQ_Envelope *ev; struct ClientStartMessage *init; unsigned int i; struct GNUNET_ATS_AddressRecord *ar; GNUNET_assert (NULL == sh->client); sh->client = GNUNET_CLIENT_connect ("ats", sh->cfg); if (NULL == sh->client) { GNUNET_break (0); force_reconnect (sh); return; } sh->mq = GNUNET_MQ_queue_for_connection_client (sh->client, handlers, &error_handler, sh); ev = GNUNET_MQ_msg (init, GNUNET_MESSAGE_TYPE_ATS_START); init->start_flag = htonl (START_FLAG_SCHEDULING); GNUNET_MQ_send (sh->mq, ev); if (NULL == sh->mq) return; for (i=0;i<sh->session_array_size;i++) { ar = sh->session_array[i]; if (NULL == ar) continue; send_add_address_message (sh, ar); if (NULL == sh->mq) return; } }
/** * Function to handle a suspend 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_suspend_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; struct GNUNET_MQ_Envelope *env; struct ClientPhoneSuspendMessage *suspend; GNUNET_CADET_receive_done (channel); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suspending channel CID: %u\n", ch->cid); switch (ch->status) { case CS_CALLEE_INIT: GNUNET_break_op (0); break; case CS_CALLEE_RINGING: GNUNET_break_op (0); break; case CS_CALLEE_CONNECTED: ch->suspended_remote = GNUNET_YES; break; case CS_CALLEE_SHUTDOWN: return GNUNET_OK; case CS_CALLER_CALLING: GNUNET_break_op (0); break; case CS_CALLER_CONNECTED: ch->suspended_remote = GNUNET_YES; break; case CS_CALLER_SHUTDOWN: return GNUNET_OK; } env = GNUNET_MQ_msg (suspend, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND); suspend->cid = ch->cid; GNUNET_MQ_send (line->mq, env); return GNUNET_OK; }
/** * Function to handle a pickup 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 if message was OK, * #GNUNET_SYSERR if message violated the protocol */ static int handle_cadet_pickup_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; struct GNUNET_MQ_Envelope *env; struct ClientPhonePickedupMessage *pick; GNUNET_CADET_receive_done (channel); switch (ch->status) { case CS_CALLEE_INIT: case CS_CALLEE_RINGING: case CS_CALLEE_CONNECTED: GNUNET_break_op (0); destroy_line_cadet_channels (ch); return GNUNET_SYSERR; case CS_CALLEE_SHUTDOWN: GNUNET_break_op (0); destroy_line_cadet_channels (ch); return GNUNET_SYSERR; case CS_CALLER_CALLING: ch->status = CS_CALLER_CONNECTED; break; case CS_CALLER_CONNECTED: GNUNET_break_op (0); return GNUNET_OK; case CS_CALLER_SHUTDOWN: GNUNET_break_op (0); mq_done_finish_caller_shutdown (ch); return GNUNET_SYSERR; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending PICKED UP message to client\n"); env = GNUNET_MQ_msg (pick, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICKED_UP); pick->cid = ch->cid; GNUNET_MQ_send (line->mq, env); return GNUNET_OK; }
static void * connect_notify (void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq) { struct PeerContext *pc = cls; struct GNUNET_MQ_Envelope *env; struct GNUNET_MessageHeader *msg; if (0 == memcmp (&pc->id, peer, sizeof (struct GNUNET_PeerIdentity))) return (void *) peer; GNUNET_assert (pc->connect_status == 0); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypted connection established to peer `%s'\n", GNUNET_i2s (peer)); pc->connect_status = 1; if (pc == &p1) { uint64_t flags; const void *extra; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Asking core (1) for transmission to peer `%s'\n", GNUNET_i2s (&p2.id)); env = GNUNET_MQ_msg (msg, MTYPE); /* enable corking for this test */ extra = GNUNET_CORE_get_mq_options (GNUNET_YES, GNUNET_CORE_PRIO_BEST_EFFORT, &flags); GNUNET_MQ_env_set_options (env, flags, extra); /* now actually transmit message */ GNUNET_assert (ok == 4); OKPP; GNUNET_MQ_send (mq, env); } return (void *) peer; }
/** * Function to handle a hangup 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_hangup_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; struct GNUNET_MQ_Envelope *env; struct ClientPhoneHangupMessage *hup; enum ChannelStatus status; uint32_t cid; GNUNET_CADET_receive_done (channel); cid = ch->cid; status = ch->status; destroy_line_cadet_channels (ch); switch (status) { case CS_CALLEE_INIT: GNUNET_break_op (0); return GNUNET_OK; case CS_CALLEE_RINGING: case CS_CALLEE_CONNECTED: break; case CS_CALLEE_SHUTDOWN: return GNUNET_OK; case CS_CALLER_CALLING: case CS_CALLER_CONNECTED: break; case CS_CALLER_SHUTDOWN: return GNUNET_OK; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending HANG UP message to client\n"); env = GNUNET_MQ_msg (hup, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP); hup->cid = cid; GNUNET_MQ_send (line->mq, env); return GNUNET_OK; }
/** * Handle element for iteration over the set. Notifies the * iterator and sends an acknowledgement to the service. * * @param cls the `struct GNUNET_SET_Handle *` * @param mh the message */ static void handle_iter_element (void *cls, const struct GNUNET_MessageHeader *mh) { struct GNUNET_SET_Handle *set = cls; GNUNET_SET_ElementIterator iter = set->iterator; struct GNUNET_SET_Element element; const struct GNUNET_SET_IterResponseMessage *msg; struct GNUNET_SET_IterAckMessage *ack_msg; struct GNUNET_MQ_Envelope *ev; uint16_t msize; msize = ntohs (mh->size); if (msize < sizeof (sizeof (struct GNUNET_SET_IterResponseMessage))) { /* message malformed */ GNUNET_break (0); set->iterator = NULL; set->iteration_id++; iter (set->iterator_cls, NULL); iter = NULL; } msg = (const struct GNUNET_SET_IterResponseMessage *) mh; if (set->iteration_id != ntohs (msg->iteration_id)) { /* element from a previous iteration, skip! */ iter = NULL; } if (NULL != iter) { element.size = msize - sizeof (struct GNUNET_SET_IterResponseMessage); element.element_type = ntohs (msg->element_type); element.data = &msg[1]; iter (set->iterator_cls, &element); } ev = GNUNET_MQ_msg (ack_msg, GNUNET_MESSAGE_TYPE_SET_ITER_ACK); ack_msg->send_more = htonl ((NULL != iter)); GNUNET_MQ_send (set->mq, ev); }
/** * Notify the client that the session has succeeded or failed. This * message gets sent to Bob's client if the operation completed or * Alice disconnected. * * @param session the associated client session to fail or succeed */ static void prepare_client_end_notification (struct BobServiceSession *session) { struct ClientResponseMessage *msg; struct GNUNET_MQ_Envelope *e; if (NULL == session->client_mq) return; /* no client left to be notified */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending session-end notification with status %d to client for session %s\n", session->status, GNUNET_h2s (&session->session_id)); e = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_RESULT); msg->range = 0; msg->product_length = htonl (0); msg->status = htonl (session->status); GNUNET_MQ_send (session->client_mq, e); }
/** * Iterator over all peers to send a monitoring client info about each peer. * * @param cls Closure (). * @param peer Peer ID (tunnel remote peer). * @param value Peer info. * @return #GNUNET_YES, to keep iterating. */ static int get_all_peers_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_LocalInfoPeer *msg; env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS); msg->destination = *peer; msg->paths = htons (GCP_count_paths (p)); msg->tunnel = htons (NULL != GCP_get_tunnel (p, GNUNET_NO)); GNUNET_MQ_send (c->mq, env); return GNUNET_YES; }
static void kill_task (void *cbData) { struct ShutdownContext *shutdown_ctx = GNUNET_new (struct ShutdownContext); struct GNUNET_MQ_Envelope *env; struct GNUNET_MessageHeader *msg; struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_handler_end () }; kt = NULL; if (trialCount == 13) { LOG ("Saw enough kills, asking ARM to stop mock service for good\n"); GNUNET_ARM_request_service_stop (arm, SERVICE, NULL, NULL); ok = 0; trialCount++; GNUNET_free (shutdown_ctx); return; } shutdown_ctx->mq = GNUNET_CLIENT_connect (cfg, SERVICE, handlers, &mq_error_handler, shutdown_ctx); GNUNET_assert (NULL != shutdown_ctx->mq); trialCount++; LOG ("Sending a shutdown request to the mock service\n"); env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_ARM_STOP); /* FIXME: abuse of message type */ GNUNET_MQ_send (shutdown_ctx->mq, env); shutdown_ctx->cancel_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &service_shutdown_timeout, shutdown_ctx); }
/** * Accept a request we got via #GNUNET_SET_listen. Must be called during * #GNUNET_SET_listen, as the 'struct GNUNET_SET_Request' becomes invalid * afterwards. * Call #GNUNET_SET_commit to provide the local set to use for the operation, * and to begin the exchange with the remote peer. * * @param request request to accept * @param result_mode specified how results will be returned, * see `enum GNUNET_SET_ResultMode`. * @param result_cb callback for the results * @param result_cls closure for @a result_cb * @return a handle to cancel the operation */ struct GNUNET_SET_OperationHandle * GNUNET_SET_accept (struct GNUNET_SET_Request *request, enum GNUNET_SET_ResultMode result_mode, GNUNET_SET_ResultIterator result_cb, void *result_cls) { struct GNUNET_MQ_Envelope *mqm; struct GNUNET_SET_OperationHandle *oh; struct GNUNET_SET_AcceptMessage *msg; GNUNET_assert (GNUNET_NO == request->accepted); request->accepted = GNUNET_YES; mqm = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_ACCEPT); msg->accept_reject_id = htonl (request->accept_id); msg->result_mode = htonl (result_mode); oh = GNUNET_new (struct GNUNET_SET_OperationHandle); oh->result_cb = result_cb; oh->result_cls = result_cls; oh->conclude_mqm = mqm; oh->request_id_addr = &msg->request_id; return oh; }