From 93b775701ea876e6f81e678d7761a7dfddad499e Mon Sep 17 00:00:00 2001 From: Lutz Bichler Date: Tue, 5 Nov 2024 11:33:33 +0100 Subject: [PATCH] Allow to configure the initial routing state Summary Allow to configure the initial routing state to allow suspended startup Details Add a configuration parameter service-discovery.initial_state to allow the configuration of the behavior on startup. Additionally, ensure that new endpoints that are created while the routing is suspended are not started. This will happen on the next resume. --- documentation/vsomeipUserGuide.md | 5 + .../configuration/include/configuration.hpp | 1 + .../include/configuration_impl.hpp | 6 +- .../configuration/src/configuration_impl.cpp | 167 ++++++++---------- .../endpoints/src/endpoint_manager_impl.cpp | 65 +++---- .../routing/src/routing_manager_base.cpp | 14 +- .../routing/src/routing_manager_impl.cpp | 5 +- 7 files changed, 133 insertions(+), 130 deletions(-) diff --git a/documentation/vsomeipUserGuide.md b/documentation/vsomeipUserGuide.md index e2a3cc0df..55064a611 100644 --- a/documentation/vsomeipUserGuide.md +++ b/documentation/vsomeipUserGuide.md @@ -1067,6 +1067,11 @@ Configuration file element explanation: Specifies whether the Service Discovery is enabled (valid values: _true_, _false_). The default value is _true_. + * `initial_state` + + Specifies the initial Service Discovery state after startup + (valid values: _unknown_, _suspended_, _resumed_). The default value is _unknown_. + * `multicast` The multicast address which the messages of the Service Discovery will be sent diff --git a/implementation/configuration/include/configuration.hpp b/implementation/configuration/include/configuration.hpp index 15fbc9c7d..dc445b4c2 100644 --- a/implementation/configuration/include/configuration.hpp +++ b/implementation/configuration/include/configuration.hpp @@ -96,6 +96,7 @@ class configuration { uid_t _uid, gid_t _gid) const = 0; virtual bool is_local_routing() const = 0; + virtual routing_state_e get_initial_routing_state() const = 0; virtual std::string get_unicast_address(service_t _service, instance_t _instance) const = 0; diff --git a/implementation/configuration/include/configuration_impl.hpp b/implementation/configuration/include/configuration_impl.hpp index d9ed9cbc0..da8cf2e74 100644 --- a/implementation/configuration/include/configuration_impl.hpp +++ b/implementation/configuration/include/configuration_impl.hpp @@ -126,6 +126,7 @@ class configuration_impl: VSOMEIP_EXPORT bool is_routing_enabled() const; VSOMEIP_EXPORT bool is_local_routing() const; + VSOMEIP_EXPORT routing_state_e get_initial_routing_state() const; VSOMEIP_EXPORT const std::string &get_routing_host_name() const; VSOMEIP_EXPORT const boost::asio::ip::address &get_routing_host_address() const; @@ -606,7 +607,8 @@ class configuration_impl: ET_PARTITIONS, ET_SECURITY_AUDIT_MODE, ET_SECURITY_REMOTE_ACCESS, - ET_MAX = 46 + ET_INITIAL_ROUTING_STATE, + ET_MAX = 47 }; bool is_configured_[ET_MAX]; @@ -683,6 +685,8 @@ class configuration_impl: std::atomic_bool is_security_external_; std::atomic_bool is_security_audit_; std::atomic_bool is_remote_access_allowed_; + + routing_state_e initial_routing_state_; }; } // namespace cfg diff --git a/implementation/configuration/src/configuration_impl.cpp b/implementation/configuration/src/configuration_impl.cpp index 4e8215100..84a3308ab 100644 --- a/implementation/configuration/src/configuration_impl.cpp +++ b/implementation/configuration/src/configuration_impl.cpp @@ -44,69 +44,45 @@ namespace vsomeip_v3 { namespace cfg { -configuration_impl::configuration_impl(const std::string &_path) - : default_unicast_("local"), - is_loaded_(false), - is_logging_loaded_(false), - prefix_(VSOMEIP_PREFIX), - diagnosis_(VSOMEIP_DIAGNOSIS_ADDRESS), - diagnosis_mask_(0xFF00), - has_console_log_(true), - has_file_log_(false), - has_dlt_log_(false), - logfile_("/tmp/vsomeip.log"), - loglevel_(vsomeip_v3::logger::level_e::LL_INFO), - is_sd_enabled_(VSOMEIP_SD_DEFAULT_ENABLED), - sd_protocol_(VSOMEIP_SD_DEFAULT_PROTOCOL), - sd_multicast_(VSOMEIP_SD_DEFAULT_MULTICAST), - sd_port_(VSOMEIP_SD_DEFAULT_PORT), - sd_initial_delay_min_(VSOMEIP_SD_DEFAULT_INITIAL_DELAY_MIN), - sd_initial_delay_max_(VSOMEIP_SD_DEFAULT_INITIAL_DELAY_MAX), - sd_repetitions_base_delay_(VSOMEIP_SD_DEFAULT_REPETITIONS_BASE_DELAY), - sd_repetitions_max_(VSOMEIP_SD_DEFAULT_REPETITIONS_MAX), - sd_ttl_(VSOMEIP_SD_DEFAULT_TTL), - sd_cyclic_offer_delay_(VSOMEIP_SD_DEFAULT_CYCLIC_OFFER_DELAY), - sd_request_response_delay_(VSOMEIP_SD_DEFAULT_REQUEST_RESPONSE_DELAY), - sd_offer_debounce_time_(VSOMEIP_SD_DEFAULT_OFFER_DEBOUNCE_TIME), - sd_find_debounce_time_(VSOMEIP_SD_DEFAULT_FIND_DEBOUNCE_TIME), - max_configured_message_size_(0), - max_local_message_size_(0), - max_reliable_message_size_(0), - max_unreliable_message_size_(0), - buffer_shrink_threshold_(VSOMEIP_DEFAULT_BUFFER_SHRINK_THRESHOLD), - trace_(std::make_shared()), - watchdog_(std::make_shared()), - log_version_(true), - log_version_interval_(10), - permissions_uds_(VSOMEIP_DEFAULT_UDS_PERMISSIONS), - network_("vsomeip"), - e2e_enabled_(false), - log_memory_(false), - log_memory_interval_(0), - log_status_(false), - log_status_interval_(0), - endpoint_queue_limit_external_(QUEUE_SIZE_UNLIMITED), - endpoint_queue_limit_local_(QUEUE_SIZE_UNLIMITED), - tcp_restart_aborts_max_(VSOMEIP_MAX_TCP_RESTART_ABORTS), - tcp_connect_time_max_(VSOMEIP_MAX_TCP_CONNECT_TIME), - has_issued_methods_warning_(false), - has_issued_clients_warning_(false), - udp_receive_buffer_size_(VSOMEIP_DEFAULT_UDP_RCV_BUFFER_SIZE), - npdu_default_debounce_requ_(VSOMEIP_DEFAULT_NPDU_DEBOUNCING_NANO), - npdu_default_debounce_resp_(VSOMEIP_DEFAULT_NPDU_DEBOUNCING_NANO), - npdu_default_max_retention_requ_(VSOMEIP_DEFAULT_NPDU_MAXIMUM_RETENTION_NANO), - npdu_default_max_retention_resp_(VSOMEIP_DEFAULT_NPDU_MAXIMUM_RETENTION_NANO), - shutdown_timeout_(VSOMEIP_DEFAULT_SHUTDOWN_TIMEOUT), - log_statistics_(true), - statistics_interval_(VSOMEIP_DEFAULT_STATISTICS_INTERVAL), - statistics_min_freq_(VSOMEIP_DEFAULT_STATISTICS_MIN_FREQ), - statistics_max_messages_(VSOMEIP_DEFAULT_STATISTICS_MAX_MSG), - max_remote_subscribers_(VSOMEIP_DEFAULT_MAX_REMOTE_SUBSCRIBERS), - path_(_path), - is_security_enabled_(false), - is_security_external_(false), - is_security_audit_(false), - is_remote_access_allowed_(true) { +configuration_impl::configuration_impl(const std::string& _path) : + default_unicast_ {"local"}, is_loaded_ {false}, is_logging_loaded_ {false}, + prefix_ {VSOMEIP_PREFIX}, diagnosis_ {VSOMEIP_DIAGNOSIS_ADDRESS}, diagnosis_mask_ {0xFF00}, + has_console_log_ {true}, has_file_log_ {false}, has_dlt_log_ {false}, + logfile_ {"/tmp/vsomeip.log"}, loglevel_ {vsomeip_v3::logger::level_e::LL_INFO}, + is_sd_enabled_ {VSOMEIP_SD_DEFAULT_ENABLED}, sd_protocol_ {VSOMEIP_SD_DEFAULT_PROTOCOL}, + sd_multicast_ {VSOMEIP_SD_DEFAULT_MULTICAST}, sd_port_ {VSOMEIP_SD_DEFAULT_PORT}, + sd_initial_delay_min_ {VSOMEIP_SD_DEFAULT_INITIAL_DELAY_MIN}, + sd_initial_delay_max_ {VSOMEIP_SD_DEFAULT_INITIAL_DELAY_MAX}, + sd_repetitions_base_delay_ {VSOMEIP_SD_DEFAULT_REPETITIONS_BASE_DELAY}, + sd_repetitions_max_ {VSOMEIP_SD_DEFAULT_REPETITIONS_MAX}, sd_ttl_ {VSOMEIP_SD_DEFAULT_TTL}, + sd_cyclic_offer_delay_ {VSOMEIP_SD_DEFAULT_CYCLIC_OFFER_DELAY}, + sd_request_response_delay_ {VSOMEIP_SD_DEFAULT_REQUEST_RESPONSE_DELAY}, + sd_offer_debounce_time_ {VSOMEIP_SD_DEFAULT_OFFER_DEBOUNCE_TIME}, + sd_find_debounce_time_ {VSOMEIP_SD_DEFAULT_FIND_DEBOUNCE_TIME}, + max_configured_message_size_ {0}, max_local_message_size_ {0}, max_reliable_message_size_ {0}, + max_unreliable_message_size_ {0}, + buffer_shrink_threshold_ {VSOMEIP_DEFAULT_BUFFER_SHRINK_THRESHOLD}, + trace_ {std::make_shared()}, watchdog_ {std::make_shared()}, + log_version_ {true}, log_version_interval_ {10}, + permissions_uds_ {VSOMEIP_DEFAULT_UDS_PERMISSIONS}, network_ {"vsomeip"}, e2e_enabled_ {false}, + log_memory_ {false}, log_memory_interval_ {0}, log_status_ {false}, log_status_interval_ {0}, + endpoint_queue_limit_external_ {QUEUE_SIZE_UNLIMITED}, + endpoint_queue_limit_local_ {QUEUE_SIZE_UNLIMITED}, + tcp_restart_aborts_max_ {VSOMEIP_MAX_TCP_RESTART_ABORTS}, + tcp_connect_time_max_ {VSOMEIP_MAX_TCP_CONNECT_TIME}, has_issued_methods_warning_ {false}, + has_issued_clients_warning_ {false}, + udp_receive_buffer_size_ {VSOMEIP_DEFAULT_UDP_RCV_BUFFER_SIZE}, + npdu_default_debounce_requ_ {VSOMEIP_DEFAULT_NPDU_DEBOUNCING_NANO}, + npdu_default_debounce_resp_ {VSOMEIP_DEFAULT_NPDU_DEBOUNCING_NANO}, + npdu_default_max_retention_requ_ {VSOMEIP_DEFAULT_NPDU_MAXIMUM_RETENTION_NANO}, + npdu_default_max_retention_resp_ {VSOMEIP_DEFAULT_NPDU_MAXIMUM_RETENTION_NANO}, + shutdown_timeout_ {VSOMEIP_DEFAULT_SHUTDOWN_TIMEOUT}, log_statistics_ {true}, + statistics_interval_ {VSOMEIP_DEFAULT_STATISTICS_INTERVAL}, + statistics_min_freq_ {VSOMEIP_DEFAULT_STATISTICS_MIN_FREQ}, + statistics_max_messages_ {VSOMEIP_DEFAULT_STATISTICS_MAX_MSG}, + max_remote_subscribers_ {VSOMEIP_DEFAULT_MAX_REMOTE_SUBSCRIBERS}, path_ {_path}, + is_security_enabled_ {false}, is_security_external_ {false}, is_security_audit_ {false}, + is_remote_access_allowed_ {true}, initial_routing_state_ {routing_state_e::RS_UNKNOWN} { policy_manager_ = std::make_shared(); security_ = std::make_shared(policy_manager_); @@ -123,32 +99,29 @@ configuration_impl::configuration_impl(const std::string &_path) #endif } -configuration_impl::configuration_impl(const configuration_impl &_other) - : std::enable_shared_from_this(_other), - default_unicast_(_other.default_unicast_), - is_loaded_(_other.is_loaded_), - is_logging_loaded_(_other.is_logging_loaded_), - mandatory_(_other.mandatory_), - has_console_log_(_other.has_console_log_.load()), - has_file_log_(_other.has_file_log_.load()), - has_dlt_log_(_other.has_dlt_log_.load()), - max_configured_message_size_(_other.max_configured_message_size_), - max_local_message_size_(_other.max_local_message_size_), - max_reliable_message_size_(_other.max_reliable_message_size_), - max_unreliable_message_size_(_other.max_unreliable_message_size_), - buffer_shrink_threshold_(_other.buffer_shrink_threshold_), - permissions_uds_(VSOMEIP_DEFAULT_UDS_PERMISSIONS), - endpoint_queue_limit_external_(_other.endpoint_queue_limit_external_), - endpoint_queue_limit_local_(_other.endpoint_queue_limit_local_), - tcp_restart_aborts_max_(_other.tcp_restart_aborts_max_), - tcp_connect_time_max_(_other.tcp_connect_time_max_), - udp_receive_buffer_size_(_other.udp_receive_buffer_size_), - npdu_default_debounce_requ_(_other.npdu_default_debounce_requ_), - npdu_default_debounce_resp_(_other.npdu_default_debounce_resp_), - npdu_default_max_retention_requ_(_other.npdu_default_max_retention_requ_), - npdu_default_max_retention_resp_(_other.npdu_default_max_retention_resp_), - shutdown_timeout_(_other.shutdown_timeout_), - path_(_other.path_) { +configuration_impl::configuration_impl(const configuration_impl& _other) : + std::enable_shared_from_this(_other), + default_unicast_ {_other.default_unicast_}, is_loaded_ {_other.is_loaded_}, + is_logging_loaded_ {_other.is_logging_loaded_}, mandatory_ {_other.mandatory_}, + has_console_log_ {_other.has_console_log_.load()}, has_file_log_ {_other.has_file_log_.load()}, + has_dlt_log_ {_other.has_dlt_log_.load()}, + max_configured_message_size_ {_other.max_configured_message_size_}, + max_local_message_size_ {_other.max_local_message_size_}, + max_reliable_message_size_ {_other.max_reliable_message_size_}, + max_unreliable_message_size_ {_other.max_unreliable_message_size_}, + buffer_shrink_threshold_ {_other.buffer_shrink_threshold_}, + permissions_uds_ {VSOMEIP_DEFAULT_UDS_PERMISSIONS}, + endpoint_queue_limit_external_ {_other.endpoint_queue_limit_external_}, + endpoint_queue_limit_local_ {_other.endpoint_queue_limit_local_}, + tcp_restart_aborts_max_ {_other.tcp_restart_aborts_max_}, + tcp_connect_time_max_ {_other.tcp_connect_time_max_}, + udp_receive_buffer_size_ {_other.udp_receive_buffer_size_}, + npdu_default_debounce_requ_ {_other.npdu_default_debounce_requ_}, + npdu_default_debounce_resp_ {_other.npdu_default_debounce_resp_}, + npdu_default_max_retention_requ_ {_other.npdu_default_max_retention_requ_}, + npdu_default_max_retention_resp_ {_other.npdu_default_max_retention_resp_}, + shutdown_timeout_ {_other.shutdown_timeout_}, path_ {_other.path_}, + initial_routing_state_ {_other.initial_routing_state_} { applications_.insert(_other.applications_.begin(), _other.applications_.end()); client_identifiers_ = _other.client_identifiers_; @@ -1877,6 +1850,18 @@ void configuration_impl::load_service_discovery( } is_configured_[ET_MAX_REMOTE_SUBSCRIBERS] = true; } + } else if (its_key == "initial_state") { + if (is_configured_[ET_INITIAL_ROUTING_STATE]) { + VSOMEIP_WARNING << "Multiple definitions for service_discovery.initial_state." + " Ignoring definition from " + << _element.name_; + } else { + if (its_value == "suspended") { + initial_routing_state_ = routing_state_e::RS_SUSPENDED; + } else if (its_value == "resumed") { + initial_routing_state_ = routing_state_e::RS_RESUMED; + } + } } } } catch (...) { @@ -5065,5 +5050,9 @@ std::shared_ptr configuration_impl::get_security() const { return security_; } +routing_state_e configuration_impl::get_initial_routing_state() const { + return initial_routing_state_; +} + } // namespace cfg } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/endpoint_manager_impl.cpp b/implementation/endpoints/src/endpoint_manager_impl.cpp index a8e30cde3..e269806e4 100644 --- a/implementation/endpoints/src/endpoint_manager_impl.cpp +++ b/implementation/endpoints/src/endpoint_manager_impl.cpp @@ -34,12 +34,11 @@ namespace vsomeip_v3 { -endpoint_manager_impl::endpoint_manager_impl( - routing_manager_base* const _rm, boost::asio::io_context &_io, - const std::shared_ptr& _configuration) : - endpoint_manager_base(_rm, _io, _configuration), - is_processing_options_(true), - options_thread_(std::bind(&endpoint_manager_impl::process_multicast_options, this)) { +endpoint_manager_impl::endpoint_manager_impl(routing_manager_base* const _rm, + boost::asio::io_context& _io, + const std::shared_ptr& _configuration) : + endpoint_manager_base(_rm, _io, _configuration), is_processing_options_(true), + options_thread_(std::bind(&endpoint_manager_impl::process_multicast_options, this)) { local_port_ = port_t(_configuration->get_routing_host_port() + 1); if (!is_local_routing_) { @@ -71,8 +70,8 @@ std::shared_ptr endpoint_manager_impl::find_or_create_remote_client( start_endpoint = true; } } - if (start_endpoint && its_endpoint - && configuration_->is_someip(_service, _instance)) { + if (start_endpoint && its_endpoint && configuration_->is_someip(_service, _instance) + && rm_->get_routing_state() != routing_state_e::RS_SUSPENDED) { its_endpoint->start(); } return its_endpoint; @@ -97,11 +96,13 @@ void endpoint_manager_impl::find_or_create_remote_client( start_unreliable_endpoint = true; } } - const bool is_someip = configuration_->is_someip(_service, _instance); - if (start_reliable_endpoint && its_reliable_endpoint && is_someip) { + const bool is_someip {configuration_->is_someip(_service, _instance)}; + const bool is_suspended {rm_->get_routing_state() == routing_state_e::RS_SUSPENDED}; + + if (start_reliable_endpoint && its_reliable_endpoint && is_someip && !is_suspended) { its_reliable_endpoint->start(); } - if (start_unreliable_endpoint && its_unreliable_endpoint && is_someip) { + if (start_unreliable_endpoint && its_unreliable_endpoint && is_someip && !is_suspended) { its_unreliable_endpoint->start(); } } @@ -288,7 +289,9 @@ endpoint_manager_impl::create_server_endpoint(uint16_t _port, bool _reliable, bo if (its_server_endpoint) { server_endpoints_[_port][_reliable] = its_server_endpoint; - its_server_endpoint->start(); + if (rm_->get_routing_state() != routing_state_e::RS_SUSPENDED) { + its_server_endpoint->start(); + } } else { VSOMEIP_ERROR << __func__ << " Server endpoint creation failed." @@ -1403,14 +1406,13 @@ void endpoint_manager_impl::suspend() { // stop client endpoints std::set> its_suspended_client_endpoints; - for (auto& its_address : its_client_endpoints) { - for (auto& its_port : its_address.second) { - for (auto& its_protocol : its_port.second) { - for (auto& its_partition : its_protocol.second) { - its_partition.second->stop(); - + for (const auto& [its_address, ports] : its_client_endpoints) { + for (const auto& [its_port, protocols] : ports) { + for (const auto& [its_protocol, partitions] : protocols) { + for (const auto& [its_partition, its_endpoint] : partitions) { + its_endpoint->stop(); auto its_client_endpoint { - std::dynamic_pointer_cast(its_partition.second)}; + std::dynamic_pointer_cast(its_endpoint)}; if (its_client_endpoint) { its_suspended_client_endpoints.insert(its_client_endpoint); } @@ -1420,9 +1422,9 @@ void endpoint_manager_impl::suspend() { } // start server endpoints - for (auto& its_port : its_server_endpoints) { - for (auto& its_protocol : its_port.second) { - its_protocol.second->stop(); + for (const auto& [its_port, protocols] : its_server_endpoints) { + for (const auto& [its_protocol, its_endpoint] : protocols) { + its_endpoint->stop(); } } // check that the clients are established again @@ -1471,22 +1473,21 @@ void endpoint_manager_impl::resume() { } // start server endpoints - for (const auto& its_port : server_endpoints_) { - for (const auto& its_protocol : its_port.second) { - its_protocol.second->restart(); + for (const auto& [its_port, protocols] : its_server_endpoints) { + for (const auto& [its_protocol, its_endpoint] : protocols) { + its_endpoint->restart(); } } // start client endpoints std::set> its_resumed_client_endpoints; - for (const auto& its_address : client_endpoints_) { - for (const auto& its_port : its_address.second) { - for (const auto& its_protocol : its_port.second) { - for (const auto& its_partition : its_protocol.second) { - its_partition.second->restart(); - + for (const auto& [its_address, ports] : its_client_endpoints) { + for (const auto& [its_port, protocols] : ports) { + for (const auto& [its_protocol, partitions] : protocols) { + for (const auto& [its_partition, its_endpoint] : partitions) { + its_endpoint->restart(); auto its_client_endpoint { - std::dynamic_pointer_cast(its_partition.second)}; + std::dynamic_pointer_cast(its_endpoint)}; if (its_client_endpoint) { its_resumed_client_endpoints.insert(its_client_endpoint); } diff --git a/implementation/routing/src/routing_manager_base.cpp b/implementation/routing/src/routing_manager_base.cpp index 28005b8e9..52eebe4c6 100644 --- a/implementation/routing/src/routing_manager_base.cpp +++ b/implementation/routing/src/routing_manager_base.cpp @@ -21,16 +21,16 @@ namespace vsomeip_v3 { -routing_manager_base::routing_manager_base(routing_manager_host *_host) : - host_(_host), - io_(host_->get_io()), - configuration_(host_->get_configuration()), - debounce_timer(host_->get_io()), - routing_state_(routing_state_e::RS_UNKNOWN) +routing_manager_base::routing_manager_base(routing_manager_host* _host) : + host_(_host), io_(host_->get_io()), configuration_(host_->get_configuration()), + debounce_timer(host_->get_io()) #ifdef USE_DLT - , tc_(trace::connector_impl::get()) + , + tc_(trace::connector_impl::get()) #endif { + routing_state_ = configuration_->get_initial_routing_state(); + const std::size_t its_max = configuration_->get_io_thread_count(host_->get_name()); const uint32_t its_buffer_shrink_threshold = configuration_->get_buffer_shrink_threshold(); diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp index 9ddac3d85..aed605e51 100644 --- a/implementation/routing/src/routing_manager_impl.cpp +++ b/implementation/routing/src/routing_manager_impl.cpp @@ -4025,8 +4025,11 @@ void routing_manager_impl::start_ip_routing() { if (routing_ready_handler_) { routing_ready_handler_(); } + if (discovery_) { - discovery_->start(); + if (routing_state_ != routing_state_e::RS_SUSPENDED) { + discovery_->start(); + } } else { init_routing_info(); }