diff options
Diffstat (limited to 'implementation/routing')
-rw-r--r-- | implementation/routing/include/event.hpp | 2 | ||||
-rw-r--r-- | implementation/routing/include/eventgroupinfo.hpp | 5 | ||||
-rw-r--r-- | implementation/routing/include/remote_subscription.hpp | 4 | ||||
-rw-r--r-- | implementation/routing/include/routing_manager_impl.hpp | 16 | ||||
-rw-r--r-- | implementation/routing/include/routing_manager_proxy.hpp | 4 | ||||
-rw-r--r-- | implementation/routing/src/event.cpp | 2 | ||||
-rw-r--r-- | implementation/routing/src/eventgroupinfo.cpp | 108 | ||||
-rw-r--r-- | implementation/routing/src/remote_subscription.cpp | 3 | ||||
-rw-r--r-- | implementation/routing/src/routing_manager_base.cpp | 12 | ||||
-rw-r--r-- | implementation/routing/src/routing_manager_impl.cpp | 250 | ||||
-rw-r--r-- | implementation/routing/src/routing_manager_proxy.cpp | 102 | ||||
-rw-r--r-- | implementation/routing/src/routing_manager_stub.cpp | 4 |
12 files changed, 332 insertions, 180 deletions
diff --git a/implementation/routing/include/event.hpp b/implementation/routing/include/event.hpp index 684a49b..b22b6ed 100644 --- a/implementation/routing/include/event.hpp +++ b/implementation/routing/include/event.hpp @@ -104,7 +104,7 @@ public: void remove_subscriber(eventgroup_t _eventgroup, client_t _client); bool has_subscriber(eventgroup_t _eventgroup, client_t _client); std::set<client_t> get_subscribers(); - std::set<client_t> get_subscribers(eventgroup_t _eventgroup); + VSOMEIP_EXPORT std::set<client_t> get_subscribers(eventgroup_t _eventgroup); void clear_subscribers(); void add_ref(client_t _client, bool _is_provided); diff --git a/implementation/routing/include/eventgroupinfo.hpp b/implementation/routing/include/eventgroupinfo.hpp index 65f7e89..32ce5f2 100644 --- a/implementation/routing/include/eventgroupinfo.hpp +++ b/implementation/routing/include/eventgroupinfo.hpp @@ -71,6 +71,8 @@ public: VSOMEIP_EXPORT void add_event(const std::shared_ptr<event>& _event); VSOMEIP_EXPORT void remove_event(const std::shared_ptr<event>& _event); VSOMEIP_EXPORT reliability_type_e get_reliability() const; + VSOMEIP_EXPORT void set_reliability(reliability_type_e _reliability); + VSOMEIP_EXPORT bool is_reliability_auto_mode() const; VSOMEIP_EXPORT std::set<std::shared_ptr<remote_subscription>> get_remote_subscriptions() const; @@ -90,6 +92,8 @@ public: VSOMEIP_EXPORT void remove_remote_subscription( const remote_subscription_id_t _id); + void clear_remote_subscriptions(); + VSOMEIP_EXPORT std::set<std::shared_ptr<endpoint_definition> > get_unicast_targets() const; VSOMEIP_EXPORT std::set<std::shared_ptr<endpoint_definition> > @@ -129,6 +133,7 @@ private: remote_subscription_id_t id_; std::atomic<reliability_type_e> reliability_; + std::atomic<bool> reliability_auto_mode_; }; } // namespace vsomeip_v3 diff --git a/implementation/routing/include/remote_subscription.hpp b/implementation/routing/include/remote_subscription.hpp index 00f2b57..685aad9 100644 --- a/implementation/routing/include/remote_subscription.hpp +++ b/implementation/routing/include/remote_subscription.hpp @@ -43,7 +43,7 @@ public: remote_subscription_id_t get_id() const; void set_id(const remote_subscription_id_t _id); - std::shared_ptr<remote_subscription> get_parent() const; + VSOMEIP_EXPORT std::shared_ptr<remote_subscription> get_parent() const; void set_parent(const std::shared_ptr<remote_subscription> &_parent); VSOMEIP_EXPORT std::shared_ptr<eventgroupinfo> get_eventgroupinfo() const; @@ -87,7 +87,7 @@ public: const bool _is_subscribe); VSOMEIP_EXPORT std::uint32_t get_answers() const; - void set_answers(const std::uint32_t _answers); + VSOMEIP_EXPORT void set_answers(const std::uint32_t _answers); private: std::atomic<remote_subscription_id_t> id_; diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp index bead207..767d60e 100644 --- a/implementation/routing/include/routing_manager_impl.hpp +++ b/implementation/routing/include/routing_manager_impl.hpp @@ -153,8 +153,7 @@ public: } std::shared_ptr<endpoint> find_or_create_remote_client( - service_t _service, instance_t _instance, bool _reliable, - client_t _client); + service_t _service, instance_t _instance, bool _reliable); void remove_local(client_t _client, bool _remove_uid); void on_stop_offer_service(client_t _client, @@ -230,7 +229,16 @@ public: std::shared_ptr<remote_subscription> &_subscription); void expire_subscriptions(const boost::asio::ip::address &_address); + void expire_subscriptions(const boost::asio::ip::address &_address, + std::uint16_t _port, bool _reliable); + void expire_subscriptions(const boost::asio::ip::address &_address, + const configuration::port_range_t& _range, + bool _reliable); void expire_services(const boost::asio::ip::address &_address); + void expire_services(const boost::asio::ip::address &_address, + std::uint16_t _port , bool _reliable); + void expire_services(const boost::asio::ip::address &_address, + const configuration::port_range_t& _range , bool _reliable); std::chrono::steady_clock::time_point expire_subscriptions(bool _force); @@ -269,7 +277,9 @@ public: void register_reboot_notification_handler(const reboot_notification_handler_t& _handler) const; void register_routing_ready_handler(const routing_ready_handler_t& _handler); void register_routing_state_handler(const routing_state_handler_t& _handler); - void sd_acceptance_enabled(const boost::asio::ip::address& _address); + void sd_acceptance_enabled(const boost::asio::ip::address& _address, + const configuration::port_range_t& _range, + bool _reliable); void on_resend_provided_events_response(pending_remote_offer_id_t _id); bool update_security_policy_configuration(uint32_t _uid, uint32_t _gid, const std::shared_ptr<policy>& _policy, diff --git a/implementation/routing/include/routing_manager_proxy.hpp b/implementation/routing/include/routing_manager_proxy.hpp index d1a29df..346e733 100644 --- a/implementation/routing/include/routing_manager_proxy.hpp +++ b/implementation/routing/include/routing_manager_proxy.hpp @@ -25,8 +25,6 @@ class configuration; class event; class routing_manager_host; -class logger; - class routing_manager_proxy: public routing_manager_base { public: routing_manager_proxy(routing_manager_host *_host, bool _client_side_logging, @@ -252,8 +250,6 @@ private: boost::asio::steady_timer register_application_timer_; - std::shared_ptr<logger> logger_; - std::mutex request_timer_mutex_; boost::asio::steady_timer request_debounce_timer_; bool request_debounce_timer_running_; diff --git a/implementation/routing/src/event.cpp b/implementation/routing/src/event.cpp index 7575733..bc0ba3e 100644 --- a/implementation/routing/src/event.cpp +++ b/implementation/routing/src/event.cpp @@ -67,7 +67,7 @@ event_t event::get_event() const { } void event::set_event(event_t _event) { - message_->set_method(_event); // TODO: maybe we should check for the leading 0-bit + message_->set_method(_event); } event_type_e event::get_type() const { diff --git a/implementation/routing/src/eventgroupinfo.cpp b/implementation/routing/src/eventgroupinfo.cpp index 52c6c1e..3b3a808 100644 --- a/implementation/routing/src/eventgroupinfo.cpp +++ b/implementation/routing/src/eventgroupinfo.cpp @@ -25,7 +25,8 @@ eventgroupinfo::eventgroupinfo() port_(ILLEGAL_PORT), threshold_(0), id_(PENDING_SUBSCRIPTION_ID), - reliability_(reliability_type_e::RT_UNKNOWN) { + reliability_(reliability_type_e::RT_UNKNOWN), + reliability_auto_mode_(false) { } eventgroupinfo::eventgroupinfo( @@ -40,7 +41,8 @@ eventgroupinfo::eventgroupinfo( port_(ILLEGAL_PORT), threshold_(0), id_(PENDING_SUBSCRIPTION_ID), - reliability_(reliability_type_e::RT_UNKNOWN) { + reliability_(reliability_type_e::RT_UNKNOWN), + reliability_auto_mode_(false) { } eventgroupinfo::~eventgroupinfo() { @@ -124,6 +126,12 @@ void eventgroupinfo::add_event(const std::shared_ptr<event>& _event) { std::lock_guard<std::mutex> its_lock(events_mutex_); events_.insert(_event); + if (!reliability_auto_mode_ && + _event->get_reliability() == reliability_type_e::RT_UNKNOWN) { + reliability_auto_mode_ = true; + return; + } + switch (_event->get_reliability()) { case reliability_type_e::RT_RELIABLE: if (reliability_ == reliability_type_e::RT_UNRELIABLE) { @@ -156,6 +164,14 @@ reliability_type_e eventgroupinfo::get_reliability() const { return reliability_; } +void eventgroupinfo::set_reliability(reliability_type_e _reliability) { + reliability_ = _reliability; +} + +bool eventgroupinfo::is_reliability_auto_mode() const { + return reliability_auto_mode_; +} + uint32_t eventgroupinfo::get_unreliable_target_count() const { uint32_t its_count(0); @@ -228,6 +244,8 @@ eventgroupinfo::update_remote_subscription( } else { its_item.second->set_answers( its_item.second->get_answers() + 1); + _subscription->set_parent(its_item.second); + _subscription->set_answers(0); } } } else { @@ -276,6 +294,12 @@ eventgroupinfo::remove_remote_subscription( subscriptions_.erase(_id); } +void +eventgroupinfo::clear_remote_subscriptions() { + std::lock_guard<std::mutex> its_lock(subscriptions_mutex_); + subscriptions_.clear(); +} + std::set<std::shared_ptr<endpoint_definition> > eventgroupinfo::get_unicast_targets() const { std::set<std::shared_ptr<endpoint_definition>> its_targets; @@ -300,7 +324,7 @@ eventgroupinfo::get_multicast_targets() const { } bool eventgroupinfo::is_selective() const { - /* Selective eventgroups always contain a single event */ + // Selective eventgroups always contain a single event std::lock_guard<std::mutex> its_lock(events_mutex_); if (events_.size() != 1) return false; @@ -320,39 +344,57 @@ void eventgroupinfo::send_initial_events( const std::shared_ptr<endpoint_definition> &_reliable, const std::shared_ptr<endpoint_definition> &_unreliable) const { - std::lock_guard<std::mutex> its_lock(events_mutex_); - for (const auto &its_event : events_) { - if (its_event && its_event->get_type() == event_type_e::ET_FIELD) { -#ifndef VSOMEIP_ENABLE_COMPAT - const auto its_reliability = its_event->get_reliability(); - switch (its_reliability) { - case reliability_type_e::RT_RELIABLE: - its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable); - break; - case reliability_type_e::RT_UNRELIABLE: - its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable); - break; - case reliability_type_e::RT_BOTH: - its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable); - its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable); - break; - default: - VSOMEIP_WARNING << __func__ << "Event reliability unknown: [" - << std::hex << std::setw(4) << std::setfill('0') << service_ << "." - << std::hex << std::setw(4) << std::setfill('0') << instance_ << "." - << std::hex << std::setw(4) << std::setfill('0') << eventgroup_ << "." - << std::hex << std::setw(4) << std::setfill('0') << its_event->get_event() << "]"; - } -#else - if (_reliable) { - its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable); - } - if (_unreliable) { - its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable); - } + + std::set<std::shared_ptr<event> > its_reliable_events, its_unreliable_events; + + // Build sets of reliable/unreliable events first to avoid having to + // hold the "events_mutex_" in parallel to the internal event mutexes. + { + std::lock_guard<std::mutex> its_lock(events_mutex_); + for (const auto &its_event : events_) { + if (its_event && its_event->get_type() == event_type_e::ET_FIELD) { + auto its_reliability = its_event->get_reliability(); +#ifdef VSOMEIP_ENABLE_COMPAT + if (its_reliability == reliability_type_e::RT_UNKNOWN) { + if (_reliable) { + if (_unreliable) { + its_reliability = reliability_type_e::RT_BOTH; + } else { + its_reliability = reliability_type_e::RT_RELIABLE; + } + } else if (_unreliable) { + its_reliability = reliability_type_e::RT_UNRELIABLE; + } + } #endif + switch (its_reliability) { + case reliability_type_e::RT_RELIABLE: + its_reliable_events.insert(its_event); + break; + case reliability_type_e::RT_UNRELIABLE: + its_unreliable_events.insert(its_event); + break; + case reliability_type_e::RT_BOTH: + its_reliable_events.insert(its_event); + its_unreliable_events.insert(its_event); + break; + default: + VSOMEIP_WARNING << __func__ << "Event reliability unknown: [" + << std::hex << std::setw(4) << std::setfill('0') << service_ << "." + << std::hex << std::setw(4) << std::setfill('0') << instance_ << "." + << std::hex << std::setw(4) << std::setfill('0') << eventgroup_ << "." + << std::hex << std::setw(4) << std::setfill('0') << its_event->get_event() << "]"; + } + } } } + + // Send events + for (const auto its_event : its_reliable_events) + its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable); + + for (const auto its_event : its_unreliable_events) + its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable); } } // namespace vsomeip_v3 diff --git a/implementation/routing/src/remote_subscription.cpp b/implementation/routing/src/remote_subscription.cpp index a896b36..939e0d1 100644 --- a/implementation/routing/src/remote_subscription.cpp +++ b/implementation/routing/src/remote_subscription.cpp @@ -178,7 +178,8 @@ remote_subscription::set_client_state(const client_t _client, if (found_item->second.second == std::chrono::steady_clock::time_point() && (_state == remote_subscription_state_e::SUBSCRIPTION_ACKED || _state == remote_subscription_state_e::SUBSCRIPTION_NACKED)) { - found_item->second.second = std::chrono::steady_clock::now(); + found_item->second.second = std::chrono::steady_clock::now() + + std::chrono::seconds(ttl_); } } } diff --git a/implementation/routing/src/routing_manager_base.cpp b/implementation/routing/src/routing_manager_base.cpp index 77e5b83..5b1149e 100644 --- a/implementation/routing/src/routing_manager_base.cpp +++ b/implementation/routing/src/routing_manager_base.cpp @@ -1265,11 +1265,15 @@ std::shared_ptr<serializer> routing_manager_base::get_serializer() { std::unique_lock<std::mutex> its_lock(serializer_mutex_); while (serializers_.empty()) { - VSOMEIP_INFO << std::hex << "client " << get_client() << - "routing_manager_base::get_serializer ~> all in use!"; + VSOMEIP_INFO << __func__ << ": Client " + << std::hex << std::setw(4) << std::setfill('0') + << get_client() + << " has no available serializer. Waiting..."; serializer_condition_.wait(its_lock); - VSOMEIP_INFO << std::hex << "client " << get_client() << - "routing_manager_base::get_serializer ~> wait finished!"; + VSOMEIP_INFO << __func__ << ": Client " + << std::hex << std::setw(4) << std::setfill('0') + << get_client() + << " now checking for available serializer."; } auto its_serializer = serializers_.front(); diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp index 48e2cb5..c132569 100644 --- a/implementation/routing/src/routing_manager_impl.cpp +++ b/implementation/routing/src/routing_manager_impl.cpp @@ -162,9 +162,17 @@ void routing_manager_impl::init() { void routing_manager_impl::start() { #ifndef _WIN32 - netlink_connector_ = std::make_shared<netlink_connector>(host_->get_io(), - configuration_->get_unicast_address(), - boost::asio::ip::address::from_string(configuration_->get_sd_multicast())); + boost::asio::ip::address its_multicast; + try { + its_multicast = boost::asio::ip::address::from_string(configuration_->get_sd_multicast()); + } catch (...) { + VSOMEIP_ERROR << "Illegal multicast address \"" + << configuration_->get_sd_multicast() + << "\". Please check your configuration."; + } + + netlink_connector_ = std::make_shared<netlink_connector>( + host_->get_io(), configuration_->get_unicast_address(), its_multicast); netlink_connector_->register_net_if_changes_handler( std::bind(&routing_manager_impl::on_net_interface_or_route_state_changed, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); @@ -326,7 +334,7 @@ bool routing_manager_impl::offer_service(client_t _client, << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << ":" << std::dec << int(_major) << "." << std::dec << _minor << "]" - << " (" << _must_queue << ")"; + << " (" << std::boolalpha << _must_queue << ")"; // only queue commands if method was NOT called via erase_offer_command() if (_must_queue) { @@ -420,7 +428,7 @@ void routing_manager_impl::stop_offer_service(client_t _client, << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << ":" << std::dec << int(_major) << "." << _minor << "]" - << " (" << _must_queue << ")"; + << " (" << std::boolalpha << _must_queue << ")"; if (_must_queue) { if (!insert_offer_command(_service, _instance, VSOMEIP_STOP_OFFER_SERVICE, @@ -505,7 +513,7 @@ void routing_manager_impl::request_service(client_t _client, service_t _service, } its_info->add_client(_client); ep_mgr_impl_->find_or_create_remote_client( - _service, _instance, true, VSOMEIP_ROUTING_CLIENT); + _service, _instance, true); } } } @@ -617,7 +625,8 @@ void routing_manager_impl::subscribe(client_t _client, uid_t _uid, gid_t _gid, if (its_info) { discovery_->subscribe(_service, _instance, _eventgroup, _major, configured_ttl, - its_info->is_selective() ? _client : VSOMEIP_ROUTING_CLIENT); + its_info->is_selective() ? _client : VSOMEIP_ROUTING_CLIENT, + its_info); } } else { its_critical.unlock(); @@ -653,7 +662,6 @@ void routing_manager_impl::unsubscribe(client_t _client, uid_t _uid, gid_t _gid, bool last_subscriber_removed(true); - auto its_event = find_event(_service, _instance, _event); std::shared_ptr<eventgroupinfo> its_info = find_eventgroup(_service, _instance, _eventgroup); if (its_info) { @@ -682,12 +690,11 @@ void routing_manager_impl::unsubscribe(client_t _client, uid_t _uid, gid_t _gid, } } - if (last_subscriber_removed - || (its_event && its_event->get_type() == event_type_e::ET_SELECTIVE_EVENT)) { - if (its_info) { - discovery_->unsubscribe(_service, _instance, _eventgroup, - its_info->is_selective() ? _client : VSOMEIP_ROUTING_CLIENT); - } + if (its_info && + (last_subscriber_removed || its_info->is_selective())) { + + discovery_->unsubscribe(_service, _instance, _eventgroup, + its_info->is_selective() ? _client : VSOMEIP_ROUTING_CLIENT); } } else { if (get_client() == _client) { @@ -797,9 +804,8 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, } } if (is_request) { - client_t client = VSOMEIP_ROUTING_CLIENT; its_target = ep_mgr_impl_->find_or_create_remote_client( - its_service, _instance, _reliable, client); + its_service, _instance, _reliable); if (its_target) { #ifdef USE_DLT const uint16_t its_data_size @@ -1089,7 +1095,7 @@ void routing_manager_impl::register_event(client_t _client, << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << "." << std::hex << std::setw(4) << std::setfill('0') << _notifier - << ":is_provider=" << _is_provided << "]"; + << ":is_provider=" << std::boolalpha << _is_provided << "]"; } void routing_manager_impl::register_shadow_event(client_t _client, @@ -1681,6 +1687,17 @@ void routing_manager_impl::on_stop_offer_service(client_t _client, service_t _se } erase_offer_command(_service, _instance); } + + std::lock_guard<std::mutex> its_eventgroups_lock(eventgroups_mutex_); + auto find_service = eventgroups_.find(_service); + if (find_service != eventgroups_.end()) { + auto find_instance = find_service->second.find(_instance); + if (find_instance != find_service->second.end()) { + for (auto e : find_instance->second) { + e.second->clear_remote_subscriptions(); + } + } + } } else { erase_offer_command(_service, _instance); } @@ -2186,10 +2203,10 @@ void routing_manager_impl::add_routing_info( if (udp_inserted) { // atomically create reliable and unreliable endpoint ep_mgr_impl_->find_or_create_remote_client( - _service, _instance, VSOMEIP_ROUTING_CLIENT); + _service, _instance); } else { ep_mgr_impl_->find_or_create_remote_client( - _service, _instance, true, VSOMEIP_ROUTING_CLIENT); + _service, _instance, true); } connected = true; } @@ -2265,7 +2282,7 @@ void routing_manager_impl::add_routing_info( == ANY_MINOR)) { if(!connected) { ep_mgr_impl_->find_or_create_remote_client(_service, _instance, - false, VSOMEIP_ROUTING_CLIENT); + false); connected = true; } its_info->add_client(client_id.first); @@ -2463,45 +2480,59 @@ void routing_manager_impl::update_routing_info(std::chrono::milliseconds _elapse } } -void routing_manager_impl::expire_services(const boost::asio::ip::address &_address) { +void routing_manager_impl::expire_services( + const boost::asio::ip::address &_address) { + expire_services(_address, configuration::port_range_t(ANY_PORT, ANY_PORT), + false); +} + +void routing_manager_impl::expire_services( + const boost::asio::ip::address &_address, std::uint16_t _port, + bool _reliable) { + expire_services(_address, configuration::port_range_t(_port, _port), + _reliable); +} + +void routing_manager_impl::expire_services( + const boost::asio::ip::address &_address, + const configuration::port_range_t& _range, bool _reliable) { std::map<service_t, std::vector<instance_t> > its_expired_offers; + const bool expire_all = (_range.first == ANY_PORT + && _range.second == ANY_PORT); + for (auto &s : get_services_remote()) { for (auto &i : s.second) { - bool is_gone(false); boost::asio::ip::address its_address; std::shared_ptr<client_endpoint> its_client_endpoint = std::dynamic_pointer_cast<client_endpoint>( - i.second->get_endpoint(true)); + i.second->get_endpoint(_reliable)); + if (!its_client_endpoint && expire_all) { + its_client_endpoint = std::dynamic_pointer_cast<client_endpoint>( + i.second->get_endpoint(!_reliable)); + } if (its_client_endpoint) { - if (its_client_endpoint->get_remote_address(its_address)) { - is_gone = (its_address == _address); - } - } else { - its_client_endpoint = - std::dynamic_pointer_cast<client_endpoint>( - i.second->get_endpoint(false)); - if (its_client_endpoint) { - if (its_client_endpoint->get_remote_address(its_address)) { - is_gone = (its_address == _address); + if ((expire_all || (its_client_endpoint->get_remote_port() >= _range.first + && its_client_endpoint->get_remote_port() <= _range.second)) + && its_client_endpoint->get_remote_address(its_address) + && its_address == _address) { + if (discovery_) { + discovery_->unsubscribe_all(s.first, i.first); } + its_expired_offers[s.first].push_back(i.first); } } - - if (is_gone) { - if (discovery_) - discovery_->unsubscribe_all(s.first, i.first); - its_expired_offers[s.first].push_back(i.first); - } } } for (auto &s : its_expired_offers) { for (auto &i : s.second) { - VSOMEIP_INFO << "expire_services for address: " << _address.to_string() + VSOMEIP_INFO << "expire_services for address: " << _address << " : delete service/instance " << std::hex << std::setw(4) << std::setfill('0') << s.first - << "." << std::hex << std::setw(4) << std::setfill('0') << i; + << "." << std::hex << std::setw(4) << std::setfill('0') << i + << " port [" << std::dec << _range.first << "," << _range.second + << "] reliability=" << std::boolalpha << _reliable; del_routing_info(s.first, i, true, true); } } @@ -2510,49 +2541,74 @@ void routing_manager_impl::expire_services(const boost::asio::ip::address &_addr void routing_manager_impl::expire_subscriptions( const boost::asio::ip::address &_address) { - { - std::lock_guard<std::mutex> its_lock(eventgroups_mutex_); - for (const auto &its_service : eventgroups_) { - for (const auto &its_instance : its_service.second) { - for (const auto &its_eventgroup : its_instance.second) { - const auto its_info = its_eventgroup.second; - for (auto its_subscription - : its_info->get_remote_subscriptions()) { - // Note: get_remote_subscription delivers a copied - // set of subscriptions. Thus, its is possible to - // to remove them within the loop. - const auto its_reliable = its_subscription->get_reliable(); - const auto its_unreliable = its_subscription->get_unreliable(); - if ((its_reliable && its_reliable->get_address() == _address) - || (its_unreliable && its_unreliable->get_address() == _address)) { - - // TODO: Check whether subscriptions to different hosts are valid. - // IF yes, we probably need to simply reset the corresponding - // endpoint instead of removing the subscription... - - if (its_reliable) { - VSOMEIP_ERROR << __func__ - << ": removing subscription to " - << std::hex << its_info->get_service() << "." - << std::hex << its_info->get_instance() << "." - << std::hex << its_info->get_eventgroup() - << " from target " - << its_reliable->get_address().to_string() << ":" - << std::dec << its_reliable->get_port(); - } - if (its_unreliable) { + expire_subscriptions(_address, + configuration::port_range_t(ANY_PORT, ANY_PORT), false); +} + +void +routing_manager_impl::expire_subscriptions( + const boost::asio::ip::address &_address, std::uint16_t _port, + bool _reliable) { + expire_subscriptions(_address, configuration::port_range_t(_port, _port), + _reliable); +} + +void +routing_manager_impl::expire_subscriptions( + const boost::asio::ip::address &_address, + const configuration::port_range_t& _range, bool _reliable) { + const bool expire_all = (_range.first == ANY_PORT + && _range.second == ANY_PORT); + + std::lock_guard<std::mutex> its_lock(eventgroups_mutex_); + for (const auto &its_service : eventgroups_) { + for (const auto &its_instance : its_service.second) { + for (const auto &its_eventgroup : its_instance.second) { + const auto its_info = its_eventgroup.second; + for (auto its_subscription + : its_info->get_remote_subscriptions()) { + // Note: get_remote_subscription delivers a copied + // set of subscriptions. Thus, its is possible to + // to remove them within the loop. + const auto its_ep_definition = + (_reliable) ? its_subscription->get_reliable() : + its_subscription->get_unreliable(); + + if (its_ep_definition + && its_ep_definition->get_address() == _address + && (expire_all || + (its_ep_definition->get_remote_port() >= _range.first + && its_ep_definition->get_remote_port() <= _range.second))) { + + // TODO: Check whether subscriptions to different hosts are valid. + // IF yes, we probably need to simply reset the corresponding + // endpoint instead of removing the subscription... + VSOMEIP_ERROR << __func__ + << ": removing subscription to " + << std::hex << its_info->get_service() << "." + << std::hex << its_info->get_instance() << "." + << std::hex << its_info->get_eventgroup() + << " from target " + << its_ep_definition->get_address() << ":" + << std::dec << its_ep_definition->get_port() + << " reliable=" << _reliable; + if (expire_all) { + const auto its_ep_definition2 = + (!_reliable) ? its_subscription->get_reliable() : + its_subscription->get_unreliable(); + if (its_ep_definition2) { VSOMEIP_ERROR << __func__ << ": removing subscription to " << std::hex << its_info->get_service() << "." << std::hex << its_info->get_instance() << "." << std::hex << its_info->get_eventgroup() << " from target " - << its_unreliable->get_address().to_string() << ":" - << std::dec << its_unreliable->get_port(); + << its_ep_definition2->get_address() << ":" + << std::dec << its_ep_definition2->get_port() + << " reliable=" << !_reliable; } - - on_remote_unsubscribe(its_subscription); } + on_remote_unsubscribe(its_subscription); } } } @@ -2570,22 +2626,34 @@ void routing_manager_impl::init_routing_info() { = configuration_->get_reliable_port(i.first, i.second); uint16_t its_unreliable_port = configuration_->get_unreliable_port(i.first, i.second); + major_version_t its_major + = configuration_->get_major_version(i.first, i.second); + minor_version_t its_minor + = configuration_->get_minor_version(i.first, i.second); + ttl_t its_ttl + = configuration_->get_ttl(i.first, i.second); if (its_reliable_port != ILLEGAL_PORT || its_unreliable_port != ILLEGAL_PORT) { + VSOMEIP_INFO << "Adding static remote service [" + << std::hex << std::setw(4) << std::setfill('0') + << i.first << "." << i.second + << std::dec << ":" << +its_major << "." << its_minor + << "]"; + add_routing_info(i.first, i.second, - DEFAULT_MAJOR, DEFAULT_MINOR, DEFAULT_TTL, + its_major, its_minor, its_ttl, its_address, its_reliable_port, its_address, its_unreliable_port); if(its_reliable_port != ILLEGAL_PORT) { ep_mgr_impl_->find_or_create_remote_client( - i.first, i.second, true, VSOMEIP_ROUTING_CLIENT); + i.first, i.second, true); } if(its_unreliable_port != ILLEGAL_PORT) { ep_mgr_impl_->find_or_create_remote_client( - i.first, i.second, false, VSOMEIP_ROUTING_CLIENT); + i.first, i.second, false); } } } @@ -2660,6 +2728,7 @@ void routing_manager_impl::on_remote_subscribe( if (its_reliable && its_unreliable) its_warning << "]"; VSOMEIP_WARNING << its_warning.str(); + _callback(_subscription); } } else { // new subscription auto its_id @@ -2810,10 +2879,9 @@ void routing_manager_impl::on_subscribe_ack(client_t _client, } std::shared_ptr<endpoint> routing_manager_impl::find_or_create_remote_client( - service_t _service, instance_t _instance, bool _reliable, - client_t _client) { + service_t _service, instance_t _instance, bool _reliable) { return ep_mgr_impl_->find_or_create_remote_client(_service, - _instance, _reliable, _client); + _instance, _reliable); } void routing_manager_impl::on_subscribe_nack(client_t _client, @@ -3082,7 +3150,7 @@ void routing_manager_impl::log_version_timer_cbk(boost::system::error_code const #ifndef VSOMEIP_VERSION #define VSOMEIP_VERSION "unknown version" #endif - static int counter(0); + static int its_counter(0); static uint32_t its_interval = configuration_->get_log_version_interval(); bool is_diag_mode(false); @@ -3104,11 +3172,11 @@ void routing_manager_impl::log_version_timer_cbk(boost::system::error_code const << ((is_diag_mode == true) ? "diagnosis)" : "default)") << its_last_resume.str(); - counter++; - if (counter == 6) { + its_counter++; + if (its_counter == 6) { ep_mgr_->log_client_states(); ep_mgr_impl_->log_client_states(); - counter = 0; + its_counter = 0; } { @@ -3852,12 +3920,10 @@ void routing_manager_impl::register_routing_state_handler( } void routing_manager_impl::sd_acceptance_enabled( - const boost::asio::ip::address& _address) { - boost::system::error_code ec; - VSOMEIP_INFO << "ipsec-plugin-mgu: expire subscriptions and services: " - << _address.to_string(ec); - expire_subscriptions(_address); - expire_services(_address); + const boost::asio::ip::address& _address, + const configuration::port_range_t& _range, bool _reliable) { + expire_subscriptions(_address, _range, _reliable); + expire_services(_address, _range, _reliable); } void routing_manager_impl::memory_log_timer_cbk( diff --git a/implementation/routing/src/routing_manager_proxy.cpp b/implementation/routing/src/routing_manager_proxy.cpp index 8135c3f..3b95a2d 100644 --- a/implementation/routing/src/routing_manager_proxy.cpp +++ b/implementation/routing/src/routing_manager_proxy.cpp @@ -45,7 +45,6 @@ routing_manager_proxy::routing_manager_proxy(routing_manager_host *_host, sender_(nullptr), receiver_(nullptr), register_application_timer_(io_), - logger_(logger::get()), request_debounce_timer_ (io_), request_debounce_timer_running_(false), client_side_logging_(_client_side_logging), @@ -342,9 +341,35 @@ void routing_manager_proxy::register_event(client_t _client, std::lock_guard<std::mutex> its_lock(state_mutex_); is_first = pending_event_registrations_.find(registration) == pending_event_registrations_.end(); +#ifndef VSOMEIP_ENABLE_COMPAT if (is_first) { pending_event_registrations_.insert(registration); } +#else + bool insert = true; + if (is_first) { + for (auto iter = pending_event_registrations_.begin(); + iter != pending_event_registrations_.end();) { + if (iter->service_ == _service + && iter->instance_ == _instance + && iter->notifier_ == _notifier + && iter->is_provided_ == _is_provided + && iter->type_ == event_type_e::ET_EVENT + && _type == event_type_e::ET_SELECTIVE_EVENT) { + iter = pending_event_registrations_.erase(iter); + iter = pending_event_registrations_.insert(registration).first; + is_first = true; + insert = false; + break; + } else { + iter++; + } + } + if (insert) { + pending_event_registrations_.insert(registration); + } + } +#endif } if (is_first || _is_provided) { routing_manager_base::register_event(_client, @@ -399,17 +424,19 @@ void routing_manager_proxy::unregister_event(client_t _client, } } } - auto it = pending_event_registrations_.begin(); - while (it != pending_event_registrations_.end()) { - if (it->service_ == _service - && it->instance_ == _instance - && it->notifier_ == _notifier) { + + for (auto iter = pending_event_registrations_.begin(); + iter != pending_event_registrations_.end(); ) { + if (iter->service_ == _service + && iter->instance_ == _instance + && iter->notifier_ == _notifier + && iter->is_provided_ == _is_provided) { + pending_event_registrations_.erase(iter); break; + } else { + iter++; } - it++; } - if (it != pending_event_registrations_.end()) - pending_event_registrations_.erase(it); } } @@ -455,7 +482,7 @@ void routing_manager_proxy::subscribe(client_t _client, uid_t _uid, gid_t _gid, std::lock_guard<std::mutex> its_lock(state_mutex_); if (state_ == inner_state_type_e::ST_REGISTERED && is_available(_service, _instance, _major)) { - send_subscribe(_client, _service, _instance, _eventgroup, _major, _event ); + send_subscribe(client_, _service, _instance, _eventgroup, _major, _event ); } subscription_data_t subscription = { _service, _instance, _eventgroup, _major, _event, _uid, _gid}; pending_subscriptions_.insert(subscription); @@ -1548,20 +1575,23 @@ void routing_manager_proxy::on_routing_info(const byte_t *_data, return; } #endif - - // inform host about its own registration state changes - host_->on_state(static_cast<state_type_e>(inner_state_type_e::ST_REGISTERED)); - { std::lock_guard<std::mutex> its_lock(state_mutex_); - boost::system::error_code ec; - register_application_timer_.cancel(ec); - send_registered_ack(); - send_pending_commands(); - state_ = inner_state_type_e::ST_REGISTERED; - // Notify stop() call about clean deregistration - state_condition_.notify_one(); + if (state_ == inner_state_type_e::ST_REGISTERING) { + boost::system::error_code ec; + register_application_timer_.cancel(ec); + send_registered_ack(); + send_pending_commands(); + state_ = inner_state_type_e::ST_REGISTERED; + // Notify stop() call about clean deregistration + state_condition_.notify_one(); + } } + + // inform host about its own registration state changes + if (state_ == inner_state_type_e::ST_REGISTERED) + host_->on_state(static_cast<state_type_e>(inner_state_type_e::ST_REGISTERED)); + } } else if (routing_info_entry == routing_info_entry_e::RIE_DEL_CLIENT) { { @@ -2278,25 +2308,23 @@ routing_manager_proxy::assign_client_timeout_cbk( void routing_manager_proxy::register_application_timeout_cbk( boost::system::error_code const &_error) { - if (!_error) { - bool register_again(false); - { - std::lock_guard<std::mutex> its_lock(state_mutex_); - if (state_ != inner_state_type_e::ST_REGISTERED) { - state_ = inner_state_type_e::ST_DEREGISTERED; - register_again = true; - } - } - if (register_again) { - std::lock_guard<std::mutex> its_lock(sender_mutex_); - VSOMEIP_WARNING << std::hex << "Client 0x" << get_client() - << " register timeout! Trying again..."; - if (sender_) { - sender_->restart(); - } + bool register_again(false); + { + std::lock_guard<std::mutex> its_lock(state_mutex_); + if (!_error && state_ != inner_state_type_e::ST_REGISTERED) { + state_ = inner_state_type_e::ST_DEREGISTERED; + register_again = true; } } + if (register_again) { + std::lock_guard<std::mutex> its_lock(sender_mutex_); + VSOMEIP_WARNING << std::hex << "Client 0x" << get_client() + << " register timeout! Trying again..."; + + if (sender_) + sender_->restart(); + } } void routing_manager_proxy::send_registered_ack() { diff --git a/implementation/routing/src/routing_manager_stub.cpp b/implementation/routing/src/routing_manager_stub.cpp index 65945f7..d7a1dd2 100644 --- a/implementation/routing/src/routing_manager_stub.cpp +++ b/implementation/routing/src/routing_manager_stub.cpp @@ -784,8 +784,8 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, void routing_manager_stub::on_register_application(client_t _client) { auto endpoint = host_->find_local(_client); if (endpoint) { - VSOMEIP_ERROR << "Registering application: " << std::hex << _client - << " failed. It is already registered!"; + VSOMEIP_WARNING << "Reregistering application: " << std::hex << _client + << ". Last registration might have been taken too long."; } else { (void)host_->find_or_create_local(_client); std::lock_guard<std::mutex> its_lock(routing_info_mutex_); |