/** * 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); }
/** * Function called whenever a channel is destroyed. Should clean up * any associated state. * * It must NOT call #GNUNET_CADET_channel_destroy() on the channel. * * @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 */ static void cb_channel_destruction (void *cls, const struct GNUNET_CADET_Channel *channel, void *channel_ctx) { struct CadetIncomingSession *in = channel_ctx; struct BobServiceSession *s; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer disconnected, terminating session %s with peer %s\n", GNUNET_h2s (&in->session_id), GNUNET_i2s (&in->peer)); if (NULL != in->cadet_mq) { GNUNET_MQ_destroy (in->cadet_mq); in->cadet_mq = NULL; } in->channel = NULL; if (NULL != (s = in->s)) { if (GNUNET_SCALARPRODUCT_STATUS_ACTIVE == s->status) { s->status = GNUNET_SCALARPRODUCT_STATUS_FAILURE; prepare_client_end_notification (s); } } destroy_cadet_session (in); }
/** * Client is done with ATS scheduling, release resources. * * @param sh handle to release */ void GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh) { struct GNUNET_ATS_AddressRecord *ar; unsigned int i; if (NULL != sh->mq) { GNUNET_MQ_destroy (sh->mq); sh->mq = NULL; } if (NULL != sh->client) { GNUNET_CLIENT_disconnect (sh->client); sh->client = NULL; } if (NULL != sh->task) { GNUNET_SCHEDULER_cancel (sh->task); sh->task = NULL; } for (i=0;i<sh->session_array_size;i++) { if (NULL != (ar = sh->session_array[i])) { GNUNET_HELLO_address_free (ar->address); GNUNET_free (ar); sh->session_array[i] = NULL; } } GNUNET_array_grow (sh->session_array, sh->session_array_size, 0); GNUNET_free (sh); }
/** * Destroy the set handle if no operations are left, mark the set * for destruction otherwise. * * @param set set handle to destroy */ void GNUNET_SET_destroy (struct GNUNET_SET_Handle *set) { /* destroying set while iterator is active is currently not supported; we should expand the API to allow clients to explicitly cancel the iteration! */ GNUNET_assert (NULL == set->iterator); if (NULL != set->ops_head) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Set operations are pending, delaying set destruction\n"); set->destroy_requested = GNUNET_YES; return; } LOG (GNUNET_ERROR_TYPE_DEBUG, "Really destroying set\n"); if (NULL != set->client) { GNUNET_CLIENT_disconnect (set->client); set->client = NULL; } if (NULL != set->mq) { GNUNET_MQ_destroy (set->mq); set->mq = NULL; } GNUNET_free (set); }
/** * Destroy incoming CADET session state, we are done with it. * * @param in the session to free elements from */ static void destroy_cadet_session (struct CadetIncomingSession *in) { struct BobServiceSession *s; if (GNUNET_YES == in->in_destroy) return; in->in_destroy = GNUNET_YES; if (NULL != (s = in->s)) { in->s = NULL; destroy_service_session (s); } if (GNUNET_YES == in->in_map) { GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (cadet_sessions, &in->session_id, in)); in->in_map = GNUNET_NO; } if (NULL != in->cadet_mq) { GNUNET_MQ_destroy (in->cadet_mq); in->cadet_mq = NULL; } if (NULL != in->channel) { GNUNET_CADET_channel_destroy (in->channel); in->channel = NULL; } GNUNET_free (in); }
static void shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n"); GNUNET_MQ_destroy (mq); GNUNET_CORE_disconnect (core); }
/** * We encountered an error, reconnect to the service. * * @param nc context to reconnect */ static void do_reconnect (struct GNUNET_PEERINFO_NotifyContext *nc) { GNUNET_MQ_destroy (nc->mq); nc->mq = NULL; nc->task = GNUNET_SCHEDULER_add_now (&reconnect, nc); }
static void finish_up (void *cls) { GNUNET_assert (ok == 5); ok = 0; GNUNET_SERVER_destroy (server); GNUNET_MQ_destroy (mq); GNUNET_CONFIGURATION_destroy (cfg); }
/** * Stop monitoring a zone for changes. * * @param zm handle to the monitor activity to stop */ void GNUNET_NAMESTORE_zone_monitor_stop (struct GNUNET_NAMESTORE_ZoneMonitor *zm) { if (NULL != zm->mq) { GNUNET_MQ_destroy (zm->mq); zm->mq = NULL; } GNUNET_free (zm); }
/** * Generic error handler, called with the appropriate error code and * the same closure specified at the creation of the message queue. * Not every message queue implementation supports an error handler. * * @param cls closure with the `struct ShutdownContext *` * @param error error code */ static void mq_error_handler (void *cls, enum GNUNET_MQ_Error error) { struct ShutdownContext *shutdown_ctx = cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service shutdown complete (MQ error).\n"); GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task); GNUNET_MQ_destroy (shutdown_ctx->mq); GNUNET_free (shutdown_ctx); }
/** * Disconnect from service and then reconnect. * * @param handle our handle */ static void force_reconnect (struct GNUNET_GNS_Handle *handle) { GNUNET_MQ_destroy (handle->mq); handle->mq = NULL; handle->reconnect_backoff = GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff); handle->reconnect_task = GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff, &reconnect_task, handle); }
/** * Destroy a channel. * * @param ch channel to destroy. */ static void destroy_line_cadet_channels (struct Channel *ch) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying cadet channels\n"); if (NULL != ch->mq) { GNUNET_MQ_destroy (ch->mq); ch->mq = NULL; } if (NULL != ch->channel) GNUNET_CADET_channel_destroy (ch->channel); }
/** * Kill the connection to the service. This can be delayed in case of pending * STORE requests and the user explicitly asked to sync first. Otherwise it is * performed instantly. * * @param h Handle to the service. */ static void do_disconnect (struct GNUNET_PEERSTORE_Handle *h) { if (NULL != h->mq) { GNUNET_MQ_destroy (h->mq); h->mq = NULL; } if (NULL != h->client) { GNUNET_CLIENT_disconnect (h->client); h->client = NULL; } GNUNET_free (h); }
/** * Stop notifying about changes. * * @param nc context to stop notifying */ void GNUNET_PEERINFO_notify_cancel (struct GNUNET_PEERINFO_NotifyContext *nc) { if (NULL != nc->mq) { GNUNET_MQ_destroy (nc->mq); nc->mq = NULL; } if (NULL != nc->task) { GNUNET_SCHEDULER_cancel (nc->task); nc->task = NULL; } GNUNET_free (nc); }
/** * 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); }
/** * Shutdown connection with the GNS service. * * @param handle handle of the GNS connection to stop */ void GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle) { if (NULL != handle->mq) { GNUNET_MQ_destroy (handle->mq); handle->mq = NULL; } if (NULL != handle->reconnect_task) { GNUNET_SCHEDULER_cancel (handle->reconnect_task); handle->reconnect_task = NULL; } GNUNET_assert (NULL == handle->lookup_head); GNUNET_assert (NULL == handle->rev_lookup_head); GNUNET_free (handle); }
/** * Our connection with the set service encountered an error, * re-initialize with exponential back-off. * * @param cls the `struct GNUNET_SET_ListenHandle *` * @param error reason for the disconnect */ static void handle_client_listener_error (void *cls, enum GNUNET_MQ_Error error) { struct GNUNET_SET_ListenHandle *lh = cls; LOG (GNUNET_ERROR_TYPE_DEBUG, "Listener broke down (%d), re-connecting\n", (int) error); 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); }
/** * Cancel the given listen operation. * * @param lh handle for the listen operation */ void GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Canceling listener\n"); if (NULL != lh->mq) { GNUNET_MQ_destroy (lh->mq); lh->mq = NULL; } if (NULL != lh->client) { GNUNET_CLIENT_disconnect (lh->client); lh->client = NULL; } if (NULL != lh->reconnect_task) { GNUNET_SCHEDULER_cancel (lh->reconnect_task); lh->reconnect_task = NULL; } GNUNET_free (lh); }
/** * Disconnect from ATS and then reconnect. * * @param sh our handle */ static void force_reconnect (struct GNUNET_ATS_SchedulingHandle *sh) { if (NULL != sh->mq) { GNUNET_MQ_destroy (sh->mq); sh->mq = NULL; } if (NULL != sh->client) { GNUNET_CLIENT_disconnect (sh->client); sh->client = NULL; } sh->suggest_cb (sh->suggest_cb_cls, NULL, NULL, NULL, GNUNET_BANDWIDTH_ZERO, GNUNET_BANDWIDTH_ZERO); sh->backoff = GNUNET_TIME_STD_BACKOFF (sh->backoff); sh->task = GNUNET_SCHEDULER_add_delayed (sh->backoff, &reconnect_task, sh); }
/** * Reconnect to the namestore service. * * @param zm monitor to reconnect */ static void reconnect (struct GNUNET_NAMESTORE_ZoneMonitor *zm) { struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_fixed_size (sync, GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_SYNC, struct GNUNET_MessageHeader, zm), GNUNET_MQ_hd_var_size (result, GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT, struct RecordResultMessage, zm), GNUNET_MQ_handler_end () }; struct GNUNET_MQ_Envelope *env; struct ZoneMonitorStartMessage *sm; if (NULL != zm->mq) { GNUNET_MQ_destroy (zm->mq); zm->error_cb (zm->error_cb_cls); } zm->mq = GNUNET_CLIENT_connect (zm->cfg, "namestore", handlers, &mq_error_handler, zm); if (NULL == zm->mq) return; env = GNUNET_MQ_msg (sm, GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START); sm->iterate_first = htonl (zm->iterate_first); sm->zone = zm->zone; GNUNET_MQ_send (zm->mq, env); }
/** * 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); } }
/** * Abort the blacklist. Note that this function is the only way for * removing a peer from the blacklist. * * @param br handle of the request that is to be cancelled */ void GNUNET_TRANSPORT_blacklist_cancel (struct GNUNET_TRANSPORT_Blacklist *br) { GNUNET_MQ_destroy (br->mq); GNUNET_free (br); }
/** * @brief Remove peer * * @param peer the peer to clean * @return #GNUNET_YES if peer was removed * #GNUNET_NO otherwise */ int Peers_remove_peer (const struct GNUNET_PeerIdentity *peer) { struct PeerContext *peer_ctx; if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (peer_map, peer)) { return GNUNET_NO; } peer_ctx = get_peer_ctx (peer); set_peer_flag (peer_ctx, Peers_TO_DESTROY); LOG (GNUNET_ERROR_TYPE_DEBUG, "Going to remove peer %s\n", GNUNET_i2s (&peer_ctx->peer_id)); Peers_unset_peer_flag (peer, Peers_ONLINE); GNUNET_array_grow (peer_ctx->pending_ops, peer_ctx->num_pending_ops, 0); while (NULL != peer_ctx->pending_messages_head) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Removing unsent %s\n", peer_ctx->pending_messages_head->type); remove_pending_message (peer_ctx->pending_messages_head); } /* If we are still waiting for notification whether this peer is live * cancel the according task */ if (NULL != peer_ctx->liveliness_check_pending) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing pending liveliness check for peer %s\n", GNUNET_i2s (&peer_ctx->peer_id)); // TODO wait until cadet sets mq->cancel_impl //GNUNET_MQ_send_cancel (peer_ctx->liveliness_check_pending->ev); GNUNET_free (peer_ctx->liveliness_check_pending); peer_ctx->liveliness_check_pending = NULL; } if (NULL != peer_ctx->send_channel) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying send channel\n"); GNUNET_CADET_channel_destroy (peer_ctx->send_channel); peer_ctx->send_channel = NULL; } if (NULL != peer_ctx->recv_channel) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying recv channel\n"); GNUNET_CADET_channel_destroy (peer_ctx->recv_channel); peer_ctx->recv_channel = NULL; } if (NULL != peer_ctx->mq) { GNUNET_MQ_destroy (peer_ctx->mq); peer_ctx->mq = NULL; } GNUNET_free (peer_ctx->send_channel_flags); GNUNET_free (peer_ctx->recv_channel_flags); if (GNUNET_YES != GNUNET_CONTAINER_multipeermap_remove_all (peer_map, &peer_ctx->peer_id)) { LOG (GNUNET_ERROR_TYPE_WARNING, "removing peer from peer_map failed\n"); } GNUNET_free (peer_ctx); return GNUNET_YES; }