/** * 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 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; }
/** * Connect to the PEERSTORE service. * * @param cfg configuration to use * @return NULL on error */ struct GNUNET_PEERSTORE_Handle * GNUNET_PEERSTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) { struct GNUNET_PEERSTORE_Handle *h; h = GNUNET_new (struct GNUNET_PEERSTORE_Handle); h->client = GNUNET_CLIENT_connect ("peerstore", cfg); if (NULL == h->client) { GNUNET_free (h); return NULL; } h->cfg = cfg; h->disconnecting = GNUNET_NO; h->mq = GNUNET_MQ_queue_for_connection_client (h->client, mq_handlers, &handle_client_error, h); if (NULL == h->mq) { GNUNET_CLIENT_disconnect (h->client); GNUNET_free (h); return NULL; } LOG (GNUNET_ERROR_TYPE_DEBUG, "New connection created\n"); return h; }
/** * 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; } }
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); }
/** * Close the existing connection to PEERSTORE and reconnect. * * @param h handle to the service */ static void reconnect (struct GNUNET_PEERSTORE_Handle *h) { struct GNUNET_PEERSTORE_IterateContext *ic; struct GNUNET_PEERSTORE_IterateContext *next; GNUNET_PEERSTORE_Processor icb; void *icb_cls; struct GNUNET_PEERSTORE_StoreContext *sc; struct GNUNET_MQ_Envelope *ev; LOG (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting...\n"); for (ic = h->iterate_head; NULL != ic; ic = next) { next = ic->next; if (GNUNET_YES == ic->iterating) { icb = ic->callback; icb_cls = ic->callback_cls; GNUNET_PEERSTORE_iterate_cancel (ic); if (NULL != icb) icb (icb_cls, NULL, "Iteration canceled due to reconnection"); } } if (NULL != h->mq) { GNUNET_MQ_destroy (h->mq); h->mq = NULL; } if (NULL != h->client) { GNUNET_CLIENT_disconnect (h->client); h->client = NULL; } h->client = GNUNET_CLIENT_connect ("peerstore", h->cfg); GNUNET_assert (NULL != h->client); h->mq = GNUNET_MQ_queue_for_connection_client (h->client, mq_handlers, &handle_client_error, h); LOG (GNUNET_ERROR_TYPE_DEBUG, "Resending pending requests after reconnect.\n"); if (NULL != h->watches) GNUNET_CONTAINER_multihashmap_iterate (h->watches, &rewatch_it, h); for (ic = h->iterate_head; NULL != ic; ic = ic->next) { ev = PEERSTORE_create_record_mq_envelope (ic->sub_system, &ic->peer, ic->key, NULL, 0, NULL, 0, GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE); GNUNET_MQ_send (h->mq, ev); ic->timeout_task = GNUNET_SCHEDULER_add_delayed (ic->timeout, &iterate_timeout, ic); } for (sc = h->store_head; NULL != sc; sc = sc->next) { ev = PEERSTORE_create_record_mq_envelope (sc->sub_system, &sc->peer, sc->key, sc->value, sc->size, &sc->expiry, sc->options, GNUNET_MESSAGE_TYPE_PEERSTORE_STORE); GNUNET_MQ_notify_sent (ev, &store_request_sent, sc); GNUNET_MQ_send (h->mq, ev); } }