diff options
author | Jürgen Gehring <Juergen.Gehring@bmw.de> | 2016-11-04 09:26:06 -0700 |
---|---|---|
committer | Jürgen Gehring <Juergen.Gehring@bmw.de> | 2016-11-04 09:26:06 -0700 |
commit | 30b6688d9f77d40352cc3cec99052e0946a8affc (patch) | |
tree | 52d7f9332f709917bb287db61505000e18eeeefd /implementation/configuration/src/configuration_impl.cpp | |
parent | 7bb933404f4ee0be3add0c506b53e1c1f7274869 (diff) | |
download | vSomeIP-30b6688d9f77d40352cc3cec99052e0946a8affc.tar.gz |
vSomeIP 2.5.02.5.0
Diffstat (limited to 'implementation/configuration/src/configuration_impl.cpp')
-rw-r--r-- | implementation/configuration/src/configuration_impl.cpp | 1871 |
1 files changed, 1167 insertions, 704 deletions
diff --git a/implementation/configuration/src/configuration_impl.cpp b/implementation/configuration/src/configuration_impl.cpp index ef5b706..c4fefb9 100644 --- a/implementation/configuration/src/configuration_impl.cpp +++ b/implementation/configuration/src/configuration_impl.cpp @@ -3,7 +3,9 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. +#include <cctype> #include <fstream> +#include <functional> #include <set> #include <sstream> @@ -30,128 +32,53 @@ namespace vsomeip { namespace cfg { -std::shared_ptr<configuration_impl> configuration_impl::the_configuration; -std::mutex configuration_impl::mutex_; - -std::shared_ptr<configuration> configuration_impl::get( - const std::set<std::string> &_input) { - std::shared_ptr<configuration> its_configuration; - std::lock_guard<std::mutex> its_lock(mutex_); - - std::set<std::string> failed_files; - static bool has_reading_failed(false); - - if (!the_configuration) { - std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); - - the_configuration = std::make_shared<configuration_impl>(); - std::vector<element> its_configuration_elements; - - // Load logger configuration first - for (auto i : _input) { - if (utility::is_file(i)) { - boost::property_tree::ptree its_tree; - try { - boost::property_tree::json_parser::read_json(i, its_tree); - its_configuration_elements.push_back({ i, its_tree }); - } - catch (boost::property_tree::json_parser_error &e) { -#ifdef WIN32 - e; // silence MSVC warining C4101 -#endif - failed_files.insert(i); - } - } else if (utility::is_folder(i)) { - boost::filesystem::path its_path(i); - for (auto j = boost::filesystem::directory_iterator(its_path); - j != boost::filesystem::directory_iterator(); - j++) { - auto its_file_path = j->path(); - if (!boost::filesystem::is_directory(its_file_path)) { - std::string its_name = its_file_path.string(); - boost::property_tree::ptree its_tree; - try { - boost::property_tree::json_parser::read_json(its_name, its_tree); - its_configuration_elements.push_back({its_name, its_tree}); - } - catch (...) { - failed_files.insert(its_name); - } - } - } - } - } - - // Load log configuration - the_configuration->load_log(its_configuration_elements); - - // Check whether reading of configuration file(s) succeeded. - if (!failed_files.empty()) { - has_reading_failed = true; - for (auto its_failed : failed_files) - VSOMEIP_ERROR << "Reading of configuration file \"" - << its_failed << "\" failed."; - } else { - // Load other configuration parts - std::sort(its_configuration_elements.begin(), - its_configuration_elements.end()); - for (auto e : its_configuration_elements) - the_configuration->load(e); - // set global unicast address for all services with magic cookies enabled - the_configuration->set_magic_cookies_unicast_address(); - } - std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); - VSOMEIP_DEBUG << "Parsed vSomeIP configuration in " - << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() - << "ms"; - } - - // There is only one attempt to read the configuration file(s). - // If it has failed, we must not return the configuration object. - if (has_reading_failed) - return nullptr; - - return the_configuration; -} - -void configuration_impl::reset() { - the_configuration.reset(); -} - -configuration_impl::configuration_impl() : - diagnosis_(VSOMEIP_DIAGNOSIS_ADDRESS), - has_console_log_(true), - has_file_log_(false), - has_dlt_log_(false), - logfile_("/tmp/vsomeip.log"), - loglevel_(boost::log::trivial::severity_level::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), - max_configured_message_size_(0), - trace_(std::make_shared<trace>()), - watchdog_(std::make_shared<watchdog>()), - log_version_(true), - log_version_interval_(10), - permissions_shm_(VSOMEIP_DEFAULT_SHM_PERMISSION), - umask_(VSOMEIP_DEFAULT_UMASK_LOCAL_ENDPOINTS) { +std::shared_ptr<configuration> configuration_impl::get() { + return std::make_shared<configuration_impl>(); +} + +configuration_impl::configuration_impl() + : is_loaded_(false), + is_logging_loaded_(false), + diagnosis_(VSOMEIP_DIAGNOSIS_ADDRESS), + has_console_log_(true), + has_file_log_(false), + has_dlt_log_(false), + logfile_("/tmp/vsomeip.log"), + loglevel_(boost::log::trivial::severity_level::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), + max_configured_message_size_(0), + trace_(std::make_shared<trace>()), + watchdog_(std::make_shared<watchdog>()), + log_version_(true), + log_version_interval_(10), + permissions_shm_(VSOMEIP_DEFAULT_SHM_PERMISSION), + umask_(VSOMEIP_DEFAULT_UMASK_LOCAL_ENDPOINTS), + policy_enabled_(false), + check_credentials_(false) { unicast_ = unicast_.from_string(VSOMEIP_UNICAST_ADDRESS); for (auto i = 0; i < ET_MAX; i++) is_configured_[i] = false; } -configuration_impl::configuration_impl(const configuration_impl &_other) : - max_configured_message_size_(0), - permissions_shm_(VSOMEIP_DEFAULT_SHM_PERMISSION), - umask_(VSOMEIP_DEFAULT_UMASK_LOCAL_ENDPOINTS) { +configuration_impl::configuration_impl(const configuration_impl &_other) + : std::enable_shared_from_this<configuration_impl>(_other), + is_loaded_(_other.is_loaded_), + is_logging_loaded_(_other.is_logging_loaded_), + mandatory_(_other.mandatory_), + max_configured_message_size_(0), + permissions_shm_(VSOMEIP_DEFAULT_SHM_PERMISSION), + umask_(VSOMEIP_DEFAULT_UMASK_LOCAL_ENDPOINTS) { applications_.insert(_other.applications_.begin(), _other.applications_.end()); services_.insert(_other.services_.begin(), _other.services_.end()); @@ -180,57 +107,216 @@ configuration_impl::configuration_impl(const configuration_impl &_other) : sd_ttl_ = _other.sd_ttl_; sd_cyclic_offer_delay_= _other.sd_cyclic_offer_delay_; sd_request_response_delay_= _other.sd_request_response_delay_; + sd_offer_debounce_time_ = _other.sd_offer_debounce_time_; trace_ = std::make_shared<trace>(*_other.trace_.get()); watchdog_ = std::make_shared<watchdog>(*_other.watchdog_.get()); + log_version_ = _other.log_version_; + log_version_interval_ = _other.log_version_interval_; magic_cookies_.insert(_other.magic_cookies_.begin(), _other.magic_cookies_.end()); for (auto i = 0; i < ET_MAX; i++) is_configured_[i] = _other.is_configured_[i]; + + policy_enabled_ = _other.policy_enabled_; + check_credentials_ = _other.check_credentials_; } configuration_impl::~configuration_impl() { } -void configuration_impl::load(const element &_element) { - try { - // Read the configuration data - get_someip_configuration(_element); - get_services_configuration(_element.tree_); - get_clients_configuration(_element.tree_); - get_payload_sizes_configuration(_element.tree_); - get_routing_configuration(_element); - get_permission_configuration(_element); - get_service_discovery_configuration(_element); - get_applications_configuration(_element); - get_trace_configuration(_element); - get_supports_selective_broadcasts(_element.tree_); - get_watchdog_configuration(_element); - get_internal_services(_element.tree_); - } catch (std::exception &e) { -#ifdef WIN32 - e; // silence MSVC warning C4101 -#endif +bool configuration_impl::load(const std::string &_name) { + std::lock_guard<std::mutex> its_lock(mutex_); + if (is_loaded_) + return true; + + // Predefine file / folder + std::string its_file(VSOMEIP_DEFAULT_CONFIGURATION_FILE); // configuration file + std::string its_folder(VSOMEIP_DEFAULT_CONFIGURATION_FOLDER); // configuration folder + + // Override with local file / folder (if existing) + std::string its_local_file(VSOMEIP_LOCAL_CONFIGURATION_FILE); + if (utility::is_file(its_local_file)) { + its_file = its_local_file; + } + + std::string its_local_folder(VSOMEIP_LOCAL_CONFIGURATION_FOLDER); + if (utility::is_folder(its_local_folder)) { + its_folder = its_local_folder; + } + + // Finally, override with path from environment (if existing) + const char *its_env = getenv(VSOMEIP_ENV_CONFIGURATION); + if (nullptr != its_env) { + if (utility::is_file(its_env)) { + its_file = its_env; + its_folder = ""; + } else if (utility::is_folder(its_env)) { + its_folder = its_env; + its_file = ""; + } + } + + std::set<std::string> its_input; + if (its_file != "") { + its_input.insert(its_file); + } + if (its_folder != "") { + its_input.insert(its_folder); + } + + // Determine standard configuration file + its_env = getenv(VSOMEIP_ENV_MANDATORY_CONFIGURATION_FILES); + if (nullptr != its_env) { + std::string its_temp(its_env); + set_mandatory(its_temp); + } else { + set_mandatory(VSOMEIP_MANDATORY_CONFIGURATION_FILES); + } + + // Start reading + std::set<std::string> its_failed; + + std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); + std::vector<element> its_mandatory_elements; + std::vector<element> its_optional_elements; + + // Dummy initialization; maybe we'll find no logging configuration + logger_impl::init(shared_from_this()); + + // Look for the standard configuration file + read_data(its_input, its_mandatory_elements, its_failed, true); + load_data(its_mandatory_elements, true, false); + + // If the configuration is incomplete, this is the routing manager configuration or + // the routing is yet unknown, read the full set of configuration files + if (its_mandatory_elements.empty() || + _name == get_routing_host() || + "" == get_routing_host()) { + read_data(its_input, its_optional_elements, its_failed, false); + load_data(its_mandatory_elements, false, true); + load_data(its_optional_elements, true, true); + } + + // Tell, if reading of configuration file(s) failed. + // (This may file if the logger configuration is incomplete/missing). + for (auto f : its_failed) + VSOMEIP_WARNING << "Reading of configuration file \"" + << f << "\" failed. Configuration may be incomplete."; + + // set global unicast address for all services with magic cookies enabled + set_magic_cookies_unicast_address(); + + std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); + VSOMEIP_DEBUG << "Parsed vsomeip configuration in " + << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() + << "ms"; + + if (utility::is_file(its_file)) + VSOMEIP_INFO << "Using configuration file: \"" << its_file << "\"."; + + if (utility::is_folder(its_folder)) + VSOMEIP_INFO << "Using configuration folder: \"" << its_folder << "\"."; + + if (policy_enabled_ && check_credentials_) + VSOMEIP_INFO << "Security configuration is active."; + + is_loaded_ = true; + + return is_loaded_; +} + +void configuration_impl::read_data(const std::set<std::string> &_input, + std::vector<element> &_elements, std::set<std::string> &_failed, + bool _mandatory_only) { + for (auto i : _input) { + if (utility::is_file(i)) { + if (is_mandatory(i) != _mandatory_only) { + boost::property_tree::ptree its_tree; + try { + boost::property_tree::json_parser::read_json(i, its_tree); + _elements.push_back({ i, its_tree }); + } + catch (boost::property_tree::json_parser_error &e) { + #ifdef WIN32 + e; // silence MSVC warning C4101 + #endif + _failed.insert(i); + } + } + } else if (utility::is_folder(i)) { + boost::filesystem::path its_path(i); + for (auto j = boost::filesystem::directory_iterator(its_path); + j != boost::filesystem::directory_iterator(); + j++) { + auto its_file_path = j->path(); + if (!boost::filesystem::is_directory(its_file_path)) { + std::string its_name = its_file_path.string(); + if (is_mandatory(its_name) == _mandatory_only) { + boost::property_tree::ptree its_tree; + try { + boost::property_tree::json_parser::read_json(its_name, its_tree); + _elements.push_back({its_name, its_tree}); + } + catch (...) { + _failed.insert(its_name); + } + } + } + } + } } } -void configuration_impl::load_log(const std::vector<element> &_elements) { + +bool configuration_impl::load_data(const std::vector<element> &_elements, + bool _load_mandatory, bool _load_optional) { + // Load logging configuration data std::set<std::string> its_warnings; + if (!is_logging_loaded_) { + for (auto e : _elements) + is_logging_loaded_ + = load_logging(e, its_warnings) || is_logging_loaded_; + + if (is_logging_loaded_) { + logger_impl::init(shared_from_this()); + for (auto w : its_warnings) + VSOMEIP_WARNING << w; + } + } - // Read the logger configuration(s) - for (auto e : _elements) - get_logging_configuration(e, its_warnings); + bool has_routing(false); + bool has_applications(false); + if (_load_mandatory) { + // Load mandatory configuration data + for (auto e : _elements) { + has_routing = load_routing(e) || has_routing; + has_applications = load_applications(e) || has_applications; + load_diagnosis_address(e); + load_payload_sizes(e); + load_permissions(e); + load_policies(e); + load_tracing(e); + } + } - // Initialize logger - logger_impl::init(the_configuration); + if (_load_optional) { + for (auto e : _elements) { + load_unicast_address(e); + load_service_discovery(e); + load_services(e); + load_internal_services(e); + load_clients(e); + load_watchdog(e); + load_selective_broadcasts_support(e); + } + } - // Print warnings after(!) logger initialization - for (auto w : its_warnings) - VSOMEIP_WARNING << w; + return is_logging_loaded_ && has_routing && has_applications; } -void configuration_impl::get_logging_configuration( +bool configuration_impl::load_logging( const element &_element, std::set<std::string> &_warnings) { try { auto its_logging = _element.tree_.get_child("logging"); @@ -307,165 +393,383 @@ void configuration_impl::get_logging_configuration( } } } catch (...) { + return false; } + return true; } -void configuration_impl::get_someip_configuration( - const element &_element) { +bool configuration_impl::load_routing(const element &_element) { try { - if (is_configured_[ET_UNICAST]) { - VSOMEIP_WARNING << "Multiple definitions for unicast." - "Ignoring definition from " << _element.name_; + auto its_routing = _element.tree_.get_child("routing"); + if (is_configured_[ET_ROUTING]) { + VSOMEIP_WARNING << "Multiple definitions of routing." + << " Ignoring definition from " << _element.name_; } else { - std::string its_value = _element.tree_.get<std::string>("unicast"); - unicast_ = unicast_.from_string(its_value); - is_configured_[ET_UNICAST] = true; + routing_host_ = its_routing.data(); + is_configured_[ET_ROUTING] = true; } } catch (...) { + return false; } + return true; +} + +bool configuration_impl::load_applications(const element &_element) { try { - if (is_configured_[ET_DIAGNOSIS]) { - VSOMEIP_WARNING << "Multiple definitions for diagnosis." - "Ignoring definition from " << _element.name_; - } else { - std::string its_value = _element.tree_.get<std::string>("diagnosis"); - std::stringstream its_converter; + std::stringstream its_converter; + auto its_applications = _element.tree_.get_child("applications"); + for (auto i = its_applications.begin(); + i != its_applications.end(); + ++i) { + load_application_data(i->second, _element.name_); + } + } catch (...) { + return false; + } + return true; +} +void configuration_impl::load_application_data( + const boost::property_tree::ptree &_tree, const std::string &_file_name) { + std::string its_name(""); + client_t its_id(0); + std::size_t its_max_dispatchers(VSOMEIP_MAX_DISPATCHERS); + std::size_t its_max_dispatch_time(VSOMEIP_MAX_DISPATCH_TIME); + for (auto i = _tree.begin(); i != _tree.end(); ++i) { + std::string its_key(i->first); + std::string its_value(i->second.data()); + std::stringstream its_converter; + if (its_key == "name") { + its_name = its_value; + } else if (its_key == "id") { if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { its_converter << std::hex << its_value; } else { its_converter << std::dec << its_value; } - its_converter >> diagnosis_; - is_configured_[ET_DIAGNOSIS] = true; + its_converter >> its_id; + } else if (its_key == "max_dispatchers") { + its_converter << std::dec << its_value; + its_converter >> its_max_dispatchers; + } else if (its_key == "max_dispatch_time") { + its_converter << std::dec << its_value; + its_converter >> its_max_dispatch_time; + } + } + if (its_name != "" && its_id != 0) { + if (applications_.find(its_name) == applications_.end()) { + if (!is_configured_client_id(its_id)) { + applications_[its_name] + = std::make_tuple(its_id, its_max_dispatchers, its_max_dispatch_time); + client_identifiers_.insert(its_id); + } else { + VSOMEIP_WARNING << "Multiple configurations for application " + << its_name << ". Ignoring a configuration from " + << _file_name; + } + } else { + VSOMEIP_WARNING << "Multiple configurations for application " + << its_name << ". Ignoring a configuration from " + << _file_name; + } + } +} + +void configuration_impl::load_tracing(const element &_element) { + try { + std::stringstream its_converter; + auto its_trace_configuration = _element.tree_.get_child("tracing"); + for(auto i = its_trace_configuration.begin(); + i != its_trace_configuration.end(); + ++i) { + std::string its_key(i->first); + std::string its_value(i->second.data()); + if(its_key == "enable") { + if (is_configured_[ET_TRACING_ENABLE]) { + VSOMEIP_WARNING << "Multiple definitions of tracing.enable." + << " Ignoring definition from " << _element.name_; + } else { + trace_->is_enabled_ = (its_value == "true"); + is_configured_[ET_TRACING_ENABLE] = true; + } + } else if (its_key == "sd_enable") { + if (is_configured_[ET_TRACING_SD_ENABLE]) { + VSOMEIP_WARNING << "Multiple definitions of tracing.sd_enable." + << " Ignoring definition from " << _element.name_; + } else { + trace_->is_sd_enabled_ = (its_value == "true"); + is_configured_[ET_TRACING_SD_ENABLE] = true; + } + } else if(its_key == "channels") { + load_trace_channels(i->second); + } else if(its_key == "filters") { + load_trace_filters(i->second); + } } } catch (...) { + // intentionally left empty } } -void configuration_impl::get_services_configuration( +void configuration_impl::load_trace_channels( const boost::property_tree::ptree &_tree) { try { - auto its_services = _tree.get_child("services"); - for (auto i = its_services.begin(); i != its_services.end(); ++i) - get_service_configuration(i->second, "local"); - } catch (...) { - try { - auto its_servicegroups = _tree.get_child("servicegroups"); - for (auto i = its_servicegroups.begin(); i != its_servicegroups.end(); ++i) - get_servicegroup_configuration(i->second); - } catch (...) { - // intentionally left empty! + for(auto i = _tree.begin(); i != _tree.end(); ++i) { + if(i == _tree.begin()) + trace_->channels_.clear(); + load_trace_channel(i->second); } + } catch (...) { + // intentionally left empty } } -void configuration_impl::set_magic_cookies_unicast_address() { - // get services with static routing that have magic cookies enabled - std::map<std::string, std::set<uint16_t> > its_magic_cookies_ = magic_cookies_; - its_magic_cookies_.erase("local"); - - //set unicast address of host for all services without static routing - its_magic_cookies_[get_unicast_address().to_string()].insert(magic_cookies_["local"].begin(), - magic_cookies_["local"].end()); - magic_cookies_.clear(); - magic_cookies_ = its_magic_cookies_; +void configuration_impl::load_trace_channel( + const boost::property_tree::ptree &_tree) { + std::shared_ptr<trace_channel> its_channel = std::make_shared<trace_channel>(); + for(auto i = _tree.begin(); i != _tree.end(); ++i) { + std::string its_key = i->first; + std::string its_value = i->second.data(); + if(its_key == "name") { + its_channel->name_ = its_value; + } else if(its_key == "id") { + its_channel->id_ = its_value; + } + } + trace_->channels_.push_back(its_channel); } - -void configuration_impl::get_clients_configuration( +void configuration_impl::load_trace_filters( const boost::property_tree::ptree &_tree) { try { - auto its_clients = _tree.get_child("clients"); - for (auto i = its_clients.begin(); i != its_clients.end(); ++i) - get_client_configuration(i->second); + for(auto i = _tree.begin(); i != _tree.end(); ++i) { + load_trace_filter(i->second); + } } catch (...) { - // intentionally left empty! + // intentionally left empty } } -void configuration_impl::get_payload_sizes_configuration( +void configuration_impl::load_trace_filter( const boost::property_tree::ptree &_tree) { - const std::string payload_sizes("payload-sizes"); - try { - if (_tree.get_child_optional(payload_sizes)) { - const std::string unicast("unicast"); - const std::string ports("ports"); - const std::string port("port"); - const std::string max_payload_size("max-payload-size"); - auto its_ps = _tree.get_child(payload_sizes); - for (auto i = its_ps.begin(); i != its_ps.end(); ++i) { - if (!i->second.get_child_optional(unicast) - || !i->second.get_child_optional(ports)) { - continue; - } - std::string its_unicast(i->second.get_child(unicast).data()); - for (auto j = i->second.get_child(ports).begin(); - j != i->second.get_child(ports).end(); ++j) { - - if (!j->second.get_child_optional(port) - || !j->second.get_child_optional(max_payload_size)) { - continue; - } - - std::uint16_t its_port = ILLEGAL_PORT; - std::uint32_t its_message_size = 0; - - try { - std::string p(j->second.get_child(port).data()); - its_port = static_cast<std::uint16_t>(std::stoul(p.c_str(), - NULL, 10)); - std::string s(j->second.get_child(max_payload_size).data()); - // add 16 Byte for the SOME/IP header - its_message_size = static_cast<std::uint32_t>(std::stoul( - s.c_str(), - NULL, 10) + 16); - } catch (const std::exception &e) { - VSOMEIP_ERROR << __func__ << ":" << e.what(); - } + std::shared_ptr<trace_filter_rule> its_filter_rule = std::make_shared<trace_filter_rule>(); + for(auto i = _tree.begin(); i != _tree.end(); ++i) { + std::string its_key = i->first; + std::string its_value = i->second.data(); + if(its_key == "channel") { + its_filter_rule->channel_ = its_value; + } else { + load_trace_filter_expressions(i->second, its_key, its_filter_rule); + } + } + trace_->filter_rules_.push_back(its_filter_rule); +} - if (its_port == ILLEGAL_PORT || its_message_size == 0) { - continue; - } - if(max_configured_message_size_ < its_message_size) { - max_configured_message_size_ = its_message_size; - } +void configuration_impl::load_trace_filter_expressions( + const boost::property_tree::ptree &_tree, + std::string &_criteria, + std::shared_ptr<trace_filter_rule> &_filter_rule) { + for(auto i = _tree.begin(); i != _tree.end(); ++i) { + std::string its_value = i->second.data(); + std::stringstream its_converter; - message_sizes_[its_unicast][its_port] = its_message_size; - } + if(_criteria == "services") { + service_t its_id = NO_TRACE_FILTER_EXPRESSION; + if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { + its_converter << std::hex << its_value; + } else { + its_converter << std::dec << its_value; } + its_converter >> its_id; + _filter_rule->services_.push_back(its_id); + } else if(_criteria == "methods") { + method_t its_id = NO_TRACE_FILTER_EXPRESSION; + if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { + its_converter << std::hex << its_value; + } else { + its_converter << std::dec << its_value; + } + its_converter >> its_id; + _filter_rule->methods_.push_back(its_id); + } else if(_criteria == "clients") { + client_t its_id = NO_TRACE_FILTER_EXPRESSION; + if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { + its_converter << std::hex << its_value; + } else { + its_converter << std::dec << its_value; + } + its_converter >> its_id; + _filter_rule->clients_.push_back(its_id); + } + } +} + +void configuration_impl::load_unicast_address(const element &_element) { + try { + std::string its_value = _element.tree_.get<std::string>("unicast"); + if (is_configured_[ET_UNICAST]) { + VSOMEIP_WARNING << "Multiple definitions for unicast." + "Ignoring definition from " << _element.name_; + } else { + unicast_ = unicast_.from_string(its_value); + is_configured_[ET_UNICAST] = true; } } catch (...) { + // intentionally left empty! } } -void configuration_impl::get_servicegroup_configuration( - const boost::property_tree::ptree &_tree) { +void configuration_impl::load_diagnosis_address(const element &_element) { try { - std::string its_unicast_address("local"); + std::string its_value = _element.tree_.get<std::string>("diagnosis"); + if (is_configured_[ET_DIAGNOSIS]) { + VSOMEIP_WARNING << "Multiple definitions for diagnosis." + "Ignoring definition from " << _element.name_; + } else { + std::stringstream its_converter; - for (auto i = _tree.begin(); i != _tree.end(); ++i) { - std::string its_key(i->first); - if (its_key == "unicast") { - its_unicast_address = i->second.data(); - break; + if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { + its_converter << std::hex << its_value; + } else { + its_converter << std::dec << its_value; } + its_converter >> diagnosis_; + is_configured_[ET_DIAGNOSIS] = true; } + } catch (...) { + // intentionally left empty + } +} - for (auto i = _tree.begin(); i != _tree.end(); ++i) { +void configuration_impl::load_service_discovery( + const element &_element) { + try { + auto its_service_discovery = _element.tree_.get_child("service-discovery"); + for (auto i = its_service_discovery.begin(); + i != its_service_discovery.end(); ++i) { std::string its_key(i->first); - if (its_key == "delays") { - get_delays_configuration(i->second); - } else if (its_key == "services") { - for (auto j = i->second.begin(); j != i->second.end(); ++j) - get_service_configuration(j->second, its_unicast_address); + std::string its_value(i->second.data()); + std::stringstream its_converter; + if (its_key == "enable") { + if (is_configured_[ET_SERVICE_DISCOVERY_ENABLE]) { + VSOMEIP_WARNING << "Multiple definitions for service_discovery.enabled." + " Ignoring definition from " << _element.name_; + } else { + is_sd_enabled_ = (its_value == "true"); + is_configured_[ET_SERVICE_DISCOVERY_ENABLE] = true; + } + } else if (its_key == "multicast") { + if (is_configured_[ET_SERVICE_DISCOVERY_MULTICAST]) { + VSOMEIP_WARNING << "Multiple definitions for service_discovery.multicast." + " Ignoring definition from " << _element.name_; + } else { + sd_multicast_ = its_value; + is_configured_[ET_SERVICE_DISCOVERY_MULTICAST] = true; + } + } else if (its_key == "port") { + if (is_configured_[ET_SERVICE_DISCOVERY_PORT]) { + VSOMEIP_WARNING << "Multiple definitions for service_discovery.port." + " Ignoring definition from " << _element.name_; + } else { + its_converter << its_value; + its_converter >> sd_port_; + if (!sd_port_) { + sd_port_ = VSOMEIP_SD_DEFAULT_PORT; + } else { + is_configured_[ET_SERVICE_DISCOVERY_PORT] = true; + } + } + } else if (its_key == "protocol") { + if (is_configured_[ET_SERVICE_DISCOVERY_PROTOCOL]) { + VSOMEIP_WARNING << "Multiple definitions for service_discovery.protocol." + " Ignoring definition from " << _element.name_; + } else { + sd_protocol_ = its_value; + is_configured_[ET_SERVICE_DISCOVERY_PROTOCOL] = true; + } + } else if (its_key == "initial_delay_min") { + if (is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MIN]) { + VSOMEIP_WARNING << "Multiple definitions for service_discovery.initial_delay_min." + " Ignoring definition from " << _element.name_; + } else { + its_converter << its_value; + its_converter >> sd_initial_delay_min_; + is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MIN] = true; + } + } else if (its_key == "initial_delay_max") { + if (is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MAX]) { + VSOMEIP_WARNING << "Multiple definitions for service_discovery.initial_delay_max." + " Ignoring definition from " << _element.name_; + } else { + its_converter << its_value; + its_converter >> sd_initial_delay_max_; + is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MAX] = true; + } + } else if (its_key == "repetitions_base_delay") { + if (is_configured_[ET_SERVICE_DISCOVERY_REPETITION_BASE_DELAY]) { + VSOMEIP_WARNING << "Multiple definitions for service_discovery.repetition_base_delay." + " Ignoring definition from " << _element.name_; + } else { + its_converter << its_value; + its_converter >> sd_repetitions_base_delay_; + is_configured_[ET_SERVICE_DISCOVERY_REPETITION_BASE_DELAY] = true; + } + } else if (its_key == "repetitions_max") { + if (is_configured_[ET_SERVICE_DISCOVERY_REPETITION_MAX]) { + VSOMEIP_WARNING << "Multiple definitions for service_discovery.repetition_max." + " Ignoring definition from " << _element.name_; + } else { + int tmp; + its_converter << its_value; + its_converter >> tmp; + sd_repetitions_max_ = (uint8_t)tmp; + is_configured_[ET_SERVICE_DISCOVERY_REPETITION_MAX] = true; + } + } else if (its_key == "ttl") { + if (is_configured_[ET_SERVICE_DISCOVERY_TTL]) { + VSOMEIP_WARNING << "Multiple definitions for service_discovery.ttl." + " Ignoring definition from " << _element.name_; + } else { + its_converter << its_value; + its_converter >> sd_ttl_; + // We do _not_ accept 0 as this would mean "STOP OFFER" + if (sd_ttl_ == 0) sd_ttl_ = VSOMEIP_SD_DEFAULT_TTL; + else is_configured_[ET_SERVICE_DISCOVERY_TTL] = true; + } + } else if (its_key == "cyclic_offer_delay") { + if (is_configured_[ET_SERVICE_DISCOVERY_CYCLIC_OFFER_DELAY]) { + VSOMEIP_WARNING << "Multiple definitions for service_discovery.cyclic_offer_delay." + " Ignoring definition from " << _element.name_; + } else { + its_converter << its_value; + its_converter >> sd_cyclic_offer_delay_; + is_configured_[ET_SERVICE_DISCOVERY_CYCLIC_OFFER_DELAY] = true; + } + } else if (its_key == "request_response_delay") { + if (is_configured_[ET_SERVICE_DISCOVERY_REQUEST_RESPONSE_DELAY]) { + VSOMEIP_WARNING << "Multiple definitions for service_discovery.request_response_delay." + " Ignoring definition from " << _element.name_; + } else { + its_converter << its_value; + its_converter >> sd_request_response_delay_; + is_configured_[ET_SERVICE_DISCOVERY_REQUEST_RESPONSE_DELAY] = true; + } + } else if (its_key == "offer_debounce_time") { + if (is_configured_[ET_SERVICE_DISCOVERY_OFFER_DEBOUNCE_TIME]) { + VSOMEIP_WARNING << "Multiple definitions for service_discovery.offer_debounce." + " Ignoring definition from " << _element.name_; + } else { + its_converter << its_value; + its_converter >> sd_offer_debounce_time_; + is_configured_[ET_SERVICE_DISCOVERY_OFFER_DEBOUNCE_TIME] = true; + } } } } catch (...) { } } -void configuration_impl::get_delays_configuration( +void configuration_impl::load_delays( const boost::property_tree::ptree &_tree) { try { std::stringstream its_converter; @@ -488,6 +792,9 @@ void configuration_impl::get_delays_configuration( } else if (its_key == "cyclic-request") { its_converter << std::dec << i->second.data(); its_converter >> sd_request_response_delay_; + } else if (its_key == "ttl") { + its_converter << std::dec << i->second.data(); + its_converter >> sd_ttl_; } its_converter.str(""); its_converter.clear(); @@ -496,7 +803,50 @@ void configuration_impl::get_delays_configuration( } } -void configuration_impl::get_service_configuration( +void configuration_impl::load_services(const element &_element) { + try { + auto its_services = _element.tree_.get_child("services"); + for (auto i = its_services.begin(); i != its_services.end(); ++i) + load_service(i->second, "local"); + } catch (...) { + try { + auto its_servicegroups = _element.tree_.get_child("servicegroups"); + for (auto i = its_servicegroups.begin(); i != its_servicegroups.end(); ++i) + load_servicegroup(i->second); + } catch (...) { + // intentionally left empty + } + } +} + +void configuration_impl::load_servicegroup( + const boost::property_tree::ptree &_tree) { + try { + std::string its_unicast_address("local"); + + for (auto i = _tree.begin(); i != _tree.end(); ++i) { + std::string its_key(i->first); + if (its_key == "unicast") { + its_unicast_address = i->second.data(); + break; + } + } + + for (auto i = _tree.begin(); i != _tree.end(); ++i) { + std::string its_key(i->first); + if (its_key == "delays") { + load_delays(i->second); + } else if (its_key == "services") { + for (auto j = i->second.begin(); j != i->second.end(); ++j) + load_service(j->second, its_unicast_address); + } + } + } catch (...) { + // Intentionally left empty + } +} + +void configuration_impl::load_service( const boost::property_tree::ptree &_tree, const std::string &_unicast_address) { try { @@ -554,9 +904,9 @@ void configuration_impl::get_service_configuration( } else if (its_key == "protocol") { its_service->protocol_ = its_value; } else if (its_key == "events") { - get_event_configuration(its_service, i->second); + load_event(its_service, i->second); } else if (its_key == "eventgroups") { - get_eventgroup_configuration(its_service, i->second); + load_eventgroup(its_service, i->second); } else { // Trim "its_value" if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { @@ -593,80 +943,11 @@ void configuration_impl::get_service_configuration( } } } catch (...) { + // Intentionally left empty } } -void configuration_impl::get_client_configuration( - const boost::property_tree::ptree &_tree) { - try { - bool is_loaded(true); - - std::shared_ptr<client> its_client(std::make_shared<client>()); - - for (auto i = _tree.begin(); i != _tree.end(); ++i) { - std::string its_key(i->first); - std::string its_value(i->second.data()); - std::stringstream its_converter; - - if (its_key == "reliable") { - its_client->ports_[true] = get_client_port_configuration(i->second); - } else if (its_key == "unreliable") { - its_client->ports_[false] = get_client_port_configuration(i->second); - } else { - // Trim "its_value" - if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { - its_converter << std::hex << its_value; - } else { - its_converter << std::dec << its_value; - } - - if (its_key == "service") { - its_converter >> its_client->service_; - } else if (its_key == "instance") { - its_converter >> its_client->instance_; - } - } - } - - auto found_service = clients_.find(its_client->service_); - if (found_service != clients_.end()) { - auto found_instance = found_service->second.find( - its_client->instance_); - if (found_instance != found_service->second.end()) { - VSOMEIP_ERROR << "Multiple client configurations for service [" - << std::hex << its_client->service_ << "." - << its_client->instance_ << "]"; - is_loaded = false; - } - } - - if (is_loaded) { - clients_[its_client->service_][its_client->instance_] = its_client; - } - } catch (...) { - } -} - -std::set<uint16_t> configuration_impl::get_client_port_configuration( - const boost::property_tree::ptree &_tree) { - std::set<uint16_t> its_ports; - for (auto i = _tree.begin(); i != _tree.end(); ++i) { - std::string its_value(i->second.data()); - uint16_t its_port_value; - - std::stringstream its_converter; - if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { - its_converter << std::hex << its_value; - } else { - its_converter << std::dec << its_value; - } - its_converter >> its_port_value; - its_ports.insert(its_port_value); - } - return its_ports; -} - -void configuration_impl::get_event_configuration( +void configuration_impl::load_event( std::shared_ptr<service> &_service, const boost::property_tree::ptree &_tree) { for (auto i = _tree.begin(); i != _tree.end(); ++i) { @@ -708,7 +989,7 @@ void configuration_impl::get_event_configuration( } } -void configuration_impl::get_eventgroup_configuration( +void configuration_impl::load_eventgroup( std::shared_ptr<service> &_service, const boost::property_tree::ptree &_tree) { for (auto i = _tree.begin(); i != _tree.end(); ++i) { @@ -782,360 +1063,281 @@ void configuration_impl::get_eventgroup_configuration( } } -void configuration_impl::get_routing_configuration(const element &_element) { +void configuration_impl::load_internal_services(const element &_element) { try { - if (is_configured_[ET_ROUTING]) { - VSOMEIP_WARNING << "Multiple definitions of routing." - << " Ignoring definition from " << _element.name_; - } else { - auto its_routing = _element.tree_.get_child("routing"); - routing_host_ = its_routing.data(); - is_configured_[ET_ROUTING] = true; + auto optional = _element.tree_.get_child_optional("internal_services"); + if (!optional) { + return; + } + auto its_internal_services = _element.tree_.get_child("internal_services"); + for (auto found_range = its_internal_services.begin(); + found_range != its_internal_services.end(); ++found_range) { + service_instance_range range; + range.first_service_ = 0x0; + range.last_service_ = 0x0; + range.first_instance_ = 0x0; + range.last_instance_ = 0xffff; + for (auto i = found_range->second.begin(); + i != found_range->second.end(); ++i) { + if (i->first == "first") { + if (i->second.size() == 0) { + std::stringstream its_converter; + std::string value = i->second.data(); + its_converter << std::hex << value; + its_converter >> range.first_service_; + } + for (auto n = i->second.begin(); + n != i->second.end(); ++n) { + if (n->first == "service") { + std::stringstream its_converter; + std::string value = n->second.data(); + its_converter << std::hex << value; + its_converter >> range.first_service_; + } else if (n->first == "instance") { + std::stringstream its_converter; + std::string value = n->second.data(); + its_converter << std::hex << value; + its_converter >> range.first_instance_; + } + } + } else if (i->first == "last") { + if (i->second.size() == 0) { + std::stringstream its_converter; + std::string value = i->second.data(); + its_converter << std::hex << value; + its_converter >> range.last_service_; + } + for (auto n = i->second.begin(); + n != i->second.end(); ++n) { + if (n->first == "service") { + std::stringstream its_converter; + std::string value = n->second.data(); + its_converter << std::hex << value; + its_converter >> range.last_service_; + } else if (n->first == "instance") { + std::stringstream its_converter; + std::string value = n->second.data(); + its_converter << std::hex << value; + its_converter >> range.last_instance_; + } + } + } + } + if (range.last_service_ >= range.first_service_) { + if (range.last_instance_ >= range.first_instance_) { + internal_service_ranges_.push_back(range); + } + } } } catch (...) { + VSOMEIP_ERROR << "Error parsing internal service range configuration!"; } } -void configuration_impl::get_permission_configuration(const element &_element) { - const std::string file_permissions("file-permissions"); +void configuration_impl::load_clients(const element &_element) { try { - if (_element.tree_.get_child_optional(file_permissions)) { - auto its_permissions = _element.tree_.get_child(file_permissions); - for (auto i = its_permissions.begin(); i != its_permissions.end(); - ++i) { - std::string its_key(i->first); - std::stringstream its_converter; - if (its_key == "permissions-shm") { - std::string its_value(i->second.data()); - its_converter << std::oct << its_value; - its_converter >> permissions_shm_; - } else if (its_key == "umask") { - std::string its_value(i->second.data()); - its_converter << std::oct << its_value; - its_converter >> umask_; - } - } - } + auto its_clients = _element.tree_.get_child("clients"); + for (auto i = its_clients.begin(); i != its_clients.end(); ++i) + load_client(i->second); } catch (...) { + // intentionally left empty! } } -std::uint32_t configuration_impl::get_umask() const { - return umask_; -} +void configuration_impl::load_client(const boost::property_tree::ptree &_tree) { + try { + bool is_loaded(true); -std::uint32_t configuration_impl::get_permissions_shm() const { - return permissions_shm_; -} + std::shared_ptr<client> its_client(std::make_shared<client>()); -void configuration_impl::get_service_discovery_configuration( - const element &_element) { - try { - auto its_service_discovery = _element.tree_.get_child("service-discovery"); - for (auto i = its_service_discovery.begin(); - i != its_service_discovery.end(); ++i) { + for (auto i = _tree.begin(); i != _tree.end(); ++i) { std::string its_key(i->first); std::string its_value(i->second.data()); std::stringstream its_converter; - if (its_key == "enable") { - if (is_configured_[ET_SERVICE_DISCOVERY_ENABLE]) { - VSOMEIP_WARNING << "Multiple definitions for service_discovery.enabled." - " Ignoring definition from " << _element.name_; - } else { - is_sd_enabled_ = (its_value == "true"); - is_configured_[ET_SERVICE_DISCOVERY_ENABLE] = true; - } - } else if (its_key == "multicast") { - if (is_configured_[ET_SERVICE_DISCOVERY_MULTICAST]) { - VSOMEIP_WARNING << "Multiple definitions for service_discovery.multicast." - " Ignoring definition from " << _element.name_; - } else { - sd_multicast_ = its_value; - is_configured_[ET_SERVICE_DISCOVERY_MULTICAST] = true; - } - } else if (its_key == "port") { - if (is_configured_[ET_SERVICE_DISCOVERY_PORT]) { - VSOMEIP_WARNING << "Multiple definitions for service_discovery.port." - " Ignoring definition from " << _element.name_; - } else { - its_converter << its_value; - its_converter >> sd_port_; - if (!sd_port_) { - sd_port_ = VSOMEIP_SD_DEFAULT_PORT; - } else { - is_configured_[ET_SERVICE_DISCOVERY_PORT] = true; - } - } - } else if (its_key == "protocol") { - if (is_configured_[ET_SERVICE_DISCOVERY_PROTOCOL]) { - VSOMEIP_WARNING << "Multiple definitions for service_discovery.protocol." - " Ignoring definition from " << _element.name_; - } else { - sd_protocol_ = its_value; - is_configured_[ET_SERVICE_DISCOVERY_PROTOCOL] = true; - } - } else if (its_key == "initial_delay_min") { - if (is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MIN]) { - VSOMEIP_WARNING << "Multiple definitions for service_discovery.initial_delay_min." - " Ignoring definition from " << _element.name_; - } else { - its_converter << its_value; - its_converter >> sd_initial_delay_min_; - is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MIN] = true; - } - } else if (its_key == "initial_delay_max") { - if (is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MAX]) { - VSOMEIP_WARNING << "Multiple definitions for service_discovery.initial_delay_max." - " Ignoring definition from " << _element.name_; - } else { - its_converter << its_value; - its_converter >> sd_initial_delay_max_; - is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MAX] = true; - } - } else if (its_key == "repetitions_base_delay") { - if (is_configured_[ET_SERVICE_DISCOVERY_REPETITION_BASE_DELAY]) { - VSOMEIP_WARNING << "Multiple definitions for service_discovery.repetition_base_delay." - " Ignoring definition from " << _element.name_; - } else { - its_converter << its_value; - its_converter >> sd_repetitions_base_delay_; - is_configured_[ET_SERVICE_DISCOVERY_REPETITION_BASE_DELAY] = true; - } - } else if (its_key == "repetitions_max") { - if (is_configured_[ET_SERVICE_DISCOVERY_REPETITION_MAX]) { - VSOMEIP_WARNING << "Multiple definitions for service_discovery.repetition_max." - " Ignoring definition from " << _element.name_; - } else { - int tmp; - its_converter << its_value; - its_converter >> tmp; - sd_repetitions_max_ = (uint8_t)tmp; - is_configured_[ET_SERVICE_DISCOVERY_REPETITION_MAX] = true; - } - } else if (its_key == "ttl") { - if (is_configured_[ET_SERVICE_DISCOVERY_TTL]) { - VSOMEIP_WARNING << "Multiple definitions for service_discovery.ttl." - " Ignoring definition from " << _element.name_; - } else { - its_converter << its_value; - its_converter >> sd_ttl_; - // We do _not_ accept 0 as this would mean "STOP OFFER" - if (sd_ttl_ == 0) sd_ttl_ = VSOMEIP_SD_DEFAULT_TTL; - else is_configured_[ET_SERVICE_DISCOVERY_TTL] = true; - } - } else if (its_key == "cyclic_offer_delay") { - if (is_configured_[ET_SERVICE_DISCOVERY_CYCLIC_OFFER_DELAY]) { - VSOMEIP_WARNING << "Multiple definitions for service_discovery.cyclic_offer_delay." - " Ignoring definition from " << _element.name_; + + if (its_key == "reliable") { + its_client->ports_[true] = load_client_ports(i->second); + } else if (its_key == "unreliable") { + its_client->ports_[false] = load_client_ports(i->second); + } else { + // Trim "its_value" + if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { + its_converter << std::hex << its_value; } else { - its_converter << its_value; - its_converter >> sd_cyclic_offer_delay_; - is_configured_[ET_SERVICE_DISCOVERY_CYCLIC_OFFER_DELAY] = true; + its_converter << std::dec << its_value; } - } else if (its_key == "request_response_delay") { - if (is_configured_[ET_SERVICE_DISCOVERY_REQUEST_RESPONSE_DELAY]) { - VSOMEIP_WARNING << "Multiple definitions for service_discovery.request_response_delay." - " Ignoring definition from " << _element.name_; - } else { - its_converter << its_value; - its_converter >> sd_request_response_delay_; - is_configured_[ET_SERVICE_DISCOVERY_REQUEST_RESPONSE_DELAY] = true; + + if (its_key == "service") { + its_converter >> its_client->service_; + } else if (its_key == "instance") { + its_converter >> its_client->instance_; } } } - } catch (...) { - } -} -void configuration_impl::get_applications_configuration( - const element &_element) { - try { - std::stringstream its_converter; - auto its_applications = _element.tree_.get_child("applications"); - for (auto i = its_applications.begin(); - i != its_applications.end(); - ++i) { - get_application_configuration(i->second, _element.name_); + auto found_service = clients_.find(its_client->service_); + if (found_service != clients_.end()) { + auto found_instance = found_service->second.find( + its_client->instance_); + if (found_instance != found_service->second.end()) { + VSOMEIP_ERROR << "Multiple client configurations for service [" + << std::hex << its_client->service_ << "." + << its_client->instance_ << "]"; + is_loaded = false; + } + } + + if (is_loaded) { + clients_[its_client->service_][its_client->instance_] = its_client; } } catch (...) { } } -void configuration_impl::get_application_configuration( - const boost::property_tree::ptree &_tree, const std::string &_file_name) { - std::string its_name(""); - client_t its_id(0); - std::size_t its_max_dispatchers(VSOMEIP_MAX_DISPATCHERS); - std::size_t its_max_dispatch_time(VSOMEIP_MAX_DISPATCH_TIME); +std::set<uint16_t> configuration_impl::load_client_ports( + const boost::property_tree::ptree &_tree) { + std::set<uint16_t> its_ports; for (auto i = _tree.begin(); i != _tree.end(); ++i) { - std::string its_key(i->first); std::string its_value(i->second.data()); + uint16_t its_port_value; + std::stringstream its_converter; - if (its_key == "name") { - its_name = its_value; - } else if (its_key == "id") { - if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { - its_converter << std::hex << its_value; - } else { - its_converter << std::dec << its_value; - } - its_converter >> its_id; - } else if (its_key == "max_dispatchers") { - its_converter << std::dec << its_value; - its_converter >> its_max_dispatchers; - } else if (its_key == "max_dispatch_time") { - its_converter << std::dec << its_value; - its_converter >> its_max_dispatch_time; - } - } - if (its_name != "" && its_id != 0) { - if (applications_.find(its_name) == applications_.end()) { - if (!is_configured_client_id(its_id)) { - applications_[its_name] - = std::make_tuple(its_id, its_max_dispatchers, its_max_dispatch_time); - client_identifiers_.insert(its_id); - } else { - VSOMEIP_WARNING << "Multiple configurations for application " - << its_name << ". Ignoring a configuration from " - << _file_name; - } + if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { + its_converter << std::hex << its_value; } else { - VSOMEIP_WARNING << "Multiple configurations for application " - << its_name << ". Ignoring a configuration from " - << _file_name; + its_converter << std::dec << its_value; } + its_converter >> its_port_value; + its_ports.insert(its_port_value); } + return its_ports; } -void configuration_impl::get_trace_configuration(const element &_element) { +void configuration_impl::load_watchdog(const element &_element) { + watchdog_->is_enabeled_ = false; + watchdog_->timeout_in_ms_ = VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT; + watchdog_->missing_pongs_allowed_ = VSOMEIP_DEFAULT_MAX_MISSING_PONGS; try { - std::stringstream its_converter; - auto its_trace_configuration = _element.tree_.get_child("tracing"); - for(auto i = its_trace_configuration.begin(); - i != its_trace_configuration.end(); - ++i) { + auto its_service_discovery = _element.tree_.get_child("watchdog"); + for (auto i = its_service_discovery.begin(); + i != its_service_discovery.end(); ++i) { std::string its_key(i->first); std::string its_value(i->second.data()); - if(its_key == "enable") { - if (is_configured_[ET_TRACING_ENABLE]) { - VSOMEIP_WARNING << "Multiple definitions of tracing.enable." - << " Ignoring definition from " << _element.name_; + std::stringstream its_converter; + if (its_key == "enable") { + if (is_configured_[ET_WATCHDOG_ENABLE]) { + VSOMEIP_WARNING << "Multiple definitions of watchdog.enable." + " Ignoring definition from " << _element.name_; } else { - trace_->is_enabled_ = (its_value == "true"); - is_configured_[ET_TRACING_ENABLE] = true; + watchdog_->is_enabeled_ = (its_value == "true"); + is_configured_[ET_WATCHDOG_ENABLE] = true; } - } else if (its_key == "sd_enable") { - if (is_configured_[ET_TRACING_SD_ENABLE]) { - VSOMEIP_WARNING << "Multiple definitions of tracing.sd_enable." - << " Ignoring definition from " << _element.name_; + } else if (its_key == "timeout") { + if (is_configured_[ET_WATCHDOG_TIMEOUT]) { + VSOMEIP_WARNING << "Multiple definitions of watchdog.timeout." + " Ignoring definition from " << _element.name_; } else { - trace_->is_sd_enabled_ = (its_value == "true"); - is_configured_[ET_TRACING_SD_ENABLE] = true; + its_converter << std::dec << its_value; + its_converter >> watchdog_->timeout_in_ms_; + is_configured_[ET_WATCHDOG_TIMEOUT] = true; + } + } else if (its_key == "allowed_missing_pongs") { + if (is_configured_[ET_WATCHDOG_ALLOWED_MISSING_PONGS]) { + VSOMEIP_WARNING << "Multiple definitions of watchdog.allowed_missing_pongs." + " Ignoring definition from " << _element.name_; + } else { + its_converter << std::dec << its_value; + its_converter >> watchdog_->missing_pongs_allowed_; + is_configured_[ET_WATCHDOG_ALLOWED_MISSING_PONGS] = true; } - } else if(its_key == "channels") { - get_trace_channels_configuration(i->second); - } else if(its_key == "filters") { - get_trace_filters_configuration(i->second); } } } catch (...) { } } -void configuration_impl::get_trace_channels_configuration( - const boost::property_tree::ptree &_tree) { +void configuration_impl::load_payload_sizes(const element &_element) { + const std::string payload_sizes("payload-sizes"); try { - for(auto i = _tree.begin(); i != _tree.end(); ++i) { - if(i == _tree.begin()) - trace_->channels_.clear(); - get_trace_channel_configuration(i->second); - } - } catch (...) { - } -} + if (_element.tree_.get_child_optional(payload_sizes)) { + const std::string unicast("unicast"); + const std::string ports("ports"); + const std::string port("port"); + const std::string max_payload_size("max-payload-size"); + auto its_ps = _element.tree_.get_child(payload_sizes); + for (auto i = its_ps.begin(); i != its_ps.end(); ++i) { + if (!i->second.get_child_optional(unicast) + || !i->second.get_child_optional(ports)) { + continue; + } + std::string its_unicast(i->second.get_child(unicast).data()); + for (auto j = i->second.get_child(ports).begin(); + j != i->second.get_child(ports).end(); ++j) { -void configuration_impl::get_trace_channel_configuration( - const boost::property_tree::ptree &_tree) { - std::shared_ptr<trace_channel> its_channel = std::make_shared<trace_channel>(); - for(auto i = _tree.begin(); i != _tree.end(); ++i) { - std::string its_key = i->first; - std::string its_value = i->second.data(); - if(its_key == "name") { - its_channel->name_ = its_value; - } else if(its_key == "id") { - its_channel->id_ = its_value; - } - } - trace_->channels_.push_back(its_channel); -} + if (!j->second.get_child_optional(port) + || !j->second.get_child_optional(max_payload_size)) { + continue; + } -void configuration_impl::get_trace_filters_configuration( - const boost::property_tree::ptree &_tree) { - try { - for(auto i = _tree.begin(); i != _tree.end(); ++i) { - get_trace_filter_configuration(i->second); - } - } catch (...) { - } -} + std::uint16_t its_port = ILLEGAL_PORT; + std::uint32_t its_message_size = 0; -void configuration_impl::get_trace_filter_configuration( - const boost::property_tree::ptree &_tree) { - std::shared_ptr<trace_filter_rule> its_filter_rule = std::make_shared<trace_filter_rule>(); - for(auto i = _tree.begin(); i != _tree.end(); ++i) { - std::string its_key = i->first; - std::string its_value = i->second.data(); - if(its_key == "channel") { - its_filter_rule->channel_ = its_value; - } else { - get_trace_filter_expressions(i->second, its_key, its_filter_rule); + try { + std::string p(j->second.get_child(port).data()); + its_port = static_cast<std::uint16_t>(std::stoul(p.c_str(), + NULL, 10)); + std::string s(j->second.get_child(max_payload_size).data()); + // add 16 Byte for the SOME/IP header + its_message_size = static_cast<std::uint32_t>(std::stoul( + s.c_str(), + NULL, 10) + 16); + } catch (const std::exception &e) { + VSOMEIP_ERROR << __func__ << ":" << e.what(); + } + + if (its_port == ILLEGAL_PORT || its_message_size == 0) { + continue; + } + if(max_configured_message_size_ < its_message_size) { + max_configured_message_size_ = its_message_size; + } + + message_sizes_[its_unicast][its_port] = its_message_size; + } + } } + } catch (...) { } - trace_->filter_rules_.push_back(its_filter_rule); } -void configuration_impl::get_trace_filter_expressions( - const boost::property_tree::ptree &_tree, - std::string &_criteria, - std::shared_ptr<trace_filter_rule> &_filter_rule) { - for(auto i = _tree.begin(); i != _tree.end(); ++i) { - std::string its_value = i->second.data(); - std::stringstream its_converter; +void configuration_impl::load_permissions(const element &_element) { + const std::string file_permissions("file-permissions"); + try { + if (_element.tree_.get_child_optional(file_permissions)) { + auto its_permissions = _element.tree_.get_child(file_permissions); + for (auto i = its_permissions.begin(); i != its_permissions.end(); + ++i) { + std::string its_key(i->first); + std::stringstream its_converter; + if (its_key == "permissions-shm") { + std::string its_value(i->second.data()); + its_converter << std::oct << its_value; + its_converter >> permissions_shm_; + } else if (its_key == "umask") { + std::string its_value(i->second.data()); + its_converter << std::oct << its_value; + its_converter >> umask_; - if(_criteria == "services") { - service_t its_id = NO_TRACE_FILTER_EXPRESSION; - if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { - its_converter << std::hex << its_value; - } else { - its_converter << std::dec << its_value; - } - its_converter >> its_id; - _filter_rule->services_.push_back(its_id); - } else if(_criteria == "methods") { - method_t its_id = NO_TRACE_FILTER_EXPRESSION; - if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { - its_converter << std::hex << its_value; - } else { - its_converter << std::dec << its_value; - } - its_converter >> its_id; - _filter_rule->methods_.push_back(its_id); - } else if(_criteria == "clients") { - client_t its_id = NO_TRACE_FILTER_EXPRESSION; - if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { - its_converter << std::hex << its_value; - } else { - its_converter << std::dec << its_value; + } } - its_converter >> its_id; - _filter_rule->clients_.push_back(its_id); } + } catch (...) { } } -void configuration_impl::get_supports_selective_broadcasts(const boost::property_tree::ptree &_tree) { +void configuration_impl::load_selective_broadcasts_support(const element &_element) { try { - auto its_service_discovery = _tree.get_child("supports_selective_broadcasts"); + auto its_service_discovery = _element.tree_.get_child("supports_selective_broadcasts"); for (auto i = its_service_discovery.begin(); i != its_service_discovery.end(); ++i) { std::string its_key(i->first); @@ -1149,42 +1351,32 @@ void configuration_impl::get_supports_selective_broadcasts(const boost::property } } -void configuration_impl::get_watchdog_configuration(const element &_element) { - watchdog_->is_enabeled_ = false; - watchdog_->timeout_in_ms_ = VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT; - watchdog_->missing_pongs_allowed_ = VSOMEIP_DEFAULT_MAX_MISSING_PONGS; + + +void configuration_impl::load_policies(const element &_element) { +#ifdef WIN32 + return; +#endif try { - auto its_service_discovery = _element.tree_.get_child("watchdog"); - for (auto i = its_service_discovery.begin(); - i != its_service_discovery.end(); ++i) { - std::string its_key(i->first); - std::string its_value(i->second.data()); - std::stringstream its_converter; - if (its_key == "enable") { - if (is_configured_[ET_WATCHDOG_ENABLE]) { - VSOMEIP_WARNING << "Multiple definitions of watchdog.enable." - " Ignoring definition from " << _element.name_; - } else { - watchdog_->is_enabeled_ = (its_value == "true"); - is_configured_[ET_WATCHDOG_ENABLE] = true; - } - } else if (its_key == "timeout") { - if (is_configured_[ET_WATCHDOG_TIMEOUT]) { - VSOMEIP_WARNING << "Multiple definitions of watchdog.timeout." - " Ignoring definition from " << _element.name_; + auto optional = _element.tree_.get_child_optional("security"); + if (!optional) { + return; + } + policy_enabled_ = true; + auto found_policy = _element.tree_.get_child("security"); + for (auto its_security = found_policy.begin(); + its_security != found_policy.end(); ++its_security) { + if (its_security->first == "check_credentials") { + if (its_security->second.data() == "true") { + check_credentials_ = true; } else { - its_converter << std::dec << its_value; - its_converter >> watchdog_->timeout_in_ms_; - is_configured_[ET_WATCHDOG_TIMEOUT] = true; + check_credentials_ = false; } - } else if (its_key == "allowed_missing_pongs") { - if (is_configured_[ET_WATCHDOG_ALLOWED_MISSING_PONGS]) { - VSOMEIP_WARNING << "Multiple definitions of watchdog.allowed_missing_pongs." - " Ignoring definition from " << _element.name_; - } else { - its_converter << std::dec << its_value; - its_converter >> watchdog_->missing_pongs_allowed_; - is_configured_[ET_WATCHDOG_ALLOWED_MISSING_PONGS] = true; + } + if (its_security->first == "policies") { + for (auto its_policy = its_security->second.begin(); + its_policy != its_security->second.end(); ++its_policy) { + load_policy(its_policy->second); } } } @@ -1192,78 +1384,209 @@ void configuration_impl::get_watchdog_configuration(const element &_element) { } } -void configuration_impl::get_internal_services( - const boost::property_tree::ptree &_tree) { - try { - auto optional = _tree.get_child_optional("internal_services"); - if (!optional) { - return; - } - auto its_internal_services = _tree.get_child("internal_services"); - for (auto found_range = its_internal_services.begin(); - found_range != its_internal_services.end(); ++found_range) { - service_instance_range range; - range.first_service_ = 0x0; - range.last_service_ = 0x0; - range.first_instance_ = 0x0; - range.last_instance_ = 0xffff; - for (auto i = found_range->second.begin(); - i != found_range->second.end(); ++i) { - if (i->first == "first") { - if (i->second.size() == 0) { +void configuration_impl::load_policy(const boost::property_tree::ptree &_tree) { + client_t client = 0x0; + std::shared_ptr<policy> policy(std::make_shared<policy>()); + bool allow_deny_set(false); + for (auto i = _tree.begin(); i != _tree.end(); ++i) { + if (i->first == "client") { + std::string value = i->second.data(); + if (value == "") { + client_t firstClient, lastClient; + for (auto n = i->second.begin(); + n != i->second.end(); ++n) { + if (n->first == "first") { std::stringstream its_converter; - std::string value = i->second.data(); + std::string value = n->second.data(); its_converter << std::hex << value; - its_converter >> range.first_service_; + its_converter >> firstClient; + } else if (n->first == "last") { + std::stringstream its_converter; + std::string value = n->second.data(); + its_converter << std::hex << value; + its_converter >> lastClient; } - for (auto n = i->second.begin(); - n != i->second.end(); ++n) { - if (n->first == "service") { - std::stringstream its_converter; - std::string value = n->second.data(); - its_converter << std::hex << value; - its_converter >> range.first_service_; - } else if (n->first == "instance") { - std::stringstream its_converter; - std::string value = n->second.data(); - its_converter << std::hex << value; - its_converter >> range.first_instance_; + } + if (firstClient < lastClient) { + uint32_t overrides(0); + for (client_t c = firstClient; c <= lastClient; ++c) { + if (policies_.find(c) != policies_.end()) { + overrides++; + } + policies_[c] = policy; + if (c == 0xffff) { + break; } } - } else if (i->first == "last") { - if (i->second.size() == 0) { - std::stringstream its_converter; - std::string value = i->second.data(); - its_converter << std::hex << value; - its_converter >> range.last_service_; + if (overrides) { + VSOMEIP_WARNING << std::hex << "Security configuration: " + << "Client range 0x" << firstClient + << " - 0x" << lastClient << " overrides policy of " + << std::dec << overrides << " clients"; } - for (auto n = i->second.begin(); - n != i->second.end(); ++n) { - if (n->first == "service") { + } else { + VSOMEIP_WARNING << std::hex << "Security configuration: " + << "Client range have to be ascending, \"first\"=0x" + << firstClient << " : \"last\"=0x" << lastClient + << " ~> Skip policy."; + } + } else { + std::stringstream its_converter; + its_converter << std::hex << value; + its_converter >> client; + if (client != 0x0) { + if (policies_.find(client) != policies_.end()) { + VSOMEIP_WARNING << std::hex << "Security configuration: " + << "Overriding policy for client 0x" << client << "."; + } + policies_[client] = policy; + } + } + } else if (i->first == "credentials") { + uint32_t uid = 0x0; + uint32_t gid = 0x0; + for (auto n = i->second.begin(); + n != i->second.end(); ++n) { + if (n->first == "uid") { + std::stringstream its_converter; + std::string value = n->second.data(); + its_converter << std::dec << value; + its_converter >> uid; + } else if (n->first == "gid") { + std::stringstream its_converter; + std::string value = n->second.data(); + its_converter << std::dec << value; + its_converter >> gid; + } + } + policy->uid_ = uid; + policy->gid_ = gid; + } else if (i->first == "allow") { + if (allow_deny_set) { + VSOMEIP_WARNING << "Security configuration: \"allow\" tag overrides " + << "already set \"deny\" tag. " + << "Either \"deny\" or \"allow\" is allowed."; + } + allow_deny_set = true; + policy->allow_ = true; + for (auto l = i->second.begin(); l != i->second.end(); ++l) { + if (l->first == "requests") { + for (auto n = l->second.begin(); n != l->second.end(); ++n) { + service_t service = 0x0; + instance_t instance = 0x0; + for (auto k = n->second.begin(); k != n->second.end(); ++k) { std::stringstream its_converter; - std::string value = n->second.data(); - its_converter << std::hex << value; - its_converter >> range.last_service_; - } else if (n->first == "instance") { + if (k->first == "service") { + std::string value = k->second.data(); + its_converter << std::hex << value; + its_converter >> service; + } else if (k->first == "instance") { + std::string value = k->second.data(); + its_converter << std::hex << value; + its_converter >> instance; + } + } + if (service != 0x0 && instance != 0x0) { + policy->allowed_services_.insert( + std::make_pair(service, instance)); + } + } + } else if (l->first == "offers") { + for (auto n = l->second.begin(); n != l->second.end(); ++n) { + service_t service = 0x0; + instance_t instance = 0x0; + for (auto k = n->second.begin(); k != n->second.end(); ++k) { std::stringstream its_converter; - std::string value = n->second.data(); - its_converter << std::hex << value; - its_converter >> range.last_instance_; + if (k->first == "service") { + std::string value = k->second.data(); + its_converter << std::hex << value; + its_converter >> service; + } else if (k->first == "instance") { + std::string value = k->second.data(); + its_converter << std::hex << value; + its_converter >> instance; + } + } + if (service != 0x0 && instance != 0x0) { + policy->allowed_offers_.insert( + std::make_pair(service, instance)); } } } } - if (range.last_service_ >= range.first_service_) { - if (range.last_instance_ >= range.first_instance_) { - internal_service_ranges_.push_back(range); + } else if (i->first == "deny") { + if (allow_deny_set) { + VSOMEIP_WARNING << "Security configuration: \"deny\" tag overrides " + << "already set \"allow\" tag. " + << "Either \"deny\" or \"allow\" is allowed."; + } + allow_deny_set = true; + policy->allow_ = false; + for (auto l = i->second.begin(); l != i->second.end(); ++l) { + if (l->first == "requests") { + for (auto n = l->second.begin(); n != l->second.end(); ++n) { + service_t service = 0x0; + instance_t instance = 0x0; + for (auto k = n->second.begin(); k != n->second.end(); ++k) { + std::stringstream its_converter; + if (k->first == "service") { + std::string value = k->second.data(); + its_converter << std::hex << value; + its_converter >> service; + } else if (k->first == "instance") { + std::string value = k->second.data(); + its_converter << std::hex << value; + its_converter >> instance; + } + } + if (service != 0x0 && instance != 0x0) { + policy->denied_services_.insert( + std::make_pair(service, instance)); + } + } + } + if (l->first == "offers") { + for (auto n = l->second.begin(); n != l->second.end(); ++n) { + service_t service = 0x0; + instance_t instance = 0x0; + for (auto k = n->second.begin(); k != n->second.end(); ++k) { + std::stringstream its_converter; + if (k->first == "service") { + std::string value = k->second.data(); + its_converter << std::hex << value; + its_converter >> service; + } else if (k->first == "instance") { + std::string value = k->second.data(); + its_converter << std::hex << value; + its_converter >> instance; + } + } + if (service != 0x0 && instance != 0x0) { + policy->denied_offers_.insert( + std::make_pair(service, instance)); + } + } } } } - } catch (...) { - VSOMEIP_ERROR << "Error parsing internal service range configuration!"; } } +/////////////////////////////////////////////////////////////////////////////// +// Internal helper +/////////////////////////////////////////////////////////////////////////////// +void configuration_impl::set_magic_cookies_unicast_address() { + // get services with static routing that have magic cookies enabled + std::map<std::string, std::set<uint16_t> > its_magic_cookies_ = magic_cookies_; + its_magic_cookies_.erase("local"); + + //set unicast address of host for all services without static routing + its_magic_cookies_[get_unicast_address().to_string()].insert(magic_cookies_["local"].begin(), + magic_cookies_["local"].end()); + magic_cookies_.clear(); + magic_cookies_ = its_magic_cookies_; +} + bool configuration_impl::is_internal_service(service_t _service, instance_t _instance) const { @@ -1278,7 +1601,9 @@ bool configuration_impl::is_internal_service(service_t _service, return false; } +/////////////////////////////////////////////////////////////////////////////// // Public interface +/////////////////////////////////////////////////////////////////////////////// const boost::asio::ip::address & configuration_impl::get_unicast_address() const { return unicast_; } @@ -1453,6 +1778,62 @@ configuration_impl::get_remote_services() const { return its_remote_services; } +bool configuration_impl::is_mandatory(const std::string &_name) const { + std::set<std::string> its_candidates; + for (auto m : mandatory_) { + if (m.size() <= _name.size()) { + its_candidates.insert(m); + } + } + + if (its_candidates.empty()) + return false; + + for (auto c : its_candidates) { + if (std::equal(c.rbegin(), c.rend(), _name.rbegin())) { + return true; + } + } + + return false; +} + +void configuration_impl::set_mandatory(const std::string &_input) { + if (_input.length() > 0) { + auto found_separator = _input.find(','); + std::string its_mandatory_file = _input.substr(0, found_separator); + trim(its_mandatory_file); + mandatory_.insert(its_mandatory_file); + while (found_separator != std::string::npos) { + auto last_separator = found_separator+1; + found_separator = _input.find(',', last_separator); + its_mandatory_file + = _input.substr(last_separator, found_separator - last_separator); + trim(its_mandatory_file); + mandatory_.insert(its_mandatory_file); + } + } +} + +void configuration_impl::trim(std::string &_s) { + _s.erase( + _s.begin(), + std::find_if( + _s.begin(), + _s.end(), + std::not1(std::ptr_fun(isspace)) + ) + ); + + _s.erase( + std::find_if( + _s.rbegin(), + _s.rend(), + std::not1(std::ptr_fun(isspace))).base(), + _s.end() + ); +} + bool configuration_impl::is_remote(std::shared_ptr<service> _service) const { return (_service->unicast_address_ != "local" && _service->unicast_address_ != "" && @@ -1540,7 +1921,7 @@ std::uint32_t configuration_impl::get_max_message_size_local() const { // to the routing_manager stub return std::uint32_t(its_max_message_size + VSOMEIP_COMMAND_HEADER_SIZE + sizeof(instance_t) - + sizeof(bool) + sizeof(bool)); + + sizeof(bool) + sizeof(bool) + sizeof(client_t)); } std::uint32_t configuration_impl::get_message_size_reliable( @@ -1630,6 +2011,10 @@ int32_t configuration_impl::get_sd_request_response_delay() const { return sd_request_response_delay_; } +std::uint32_t configuration_impl::get_sd_offer_debounce_time() const { + return sd_offer_debounce_time_; +} + // Trace configuration std::shared_ptr<cfg::trace> configuration_impl::get_trace() const { return trace_; @@ -1647,7 +2032,85 @@ uint32_t configuration_impl::get_watchdog_timeout() const { uint32_t configuration_impl::get_allowed_missing_pongs() const { return watchdog_->missing_pongs_allowed_; } +std::uint32_t configuration_impl::get_umask() const { + return umask_; +} +std::uint32_t configuration_impl::get_permissions_shm() const { + return permissions_shm_; +} + +bool configuration_impl::is_security_enabled() const { + return policy_enabled_; +} + +bool configuration_impl::check_credentials(client_t _client, uint32_t _uid, + uint32_t _gid) const { + if (!policy_enabled_) { + return true; + } + auto its_client = policies_.find(_client); + if (its_client != policies_.end()) { + if (its_client->second->uid_ == _uid && its_client->second->gid_ == _gid) { + return true; + } + } + return !check_credentials_; +} + +bool configuration_impl::is_client_allowed(client_t _client, service_t _service, + instance_t _instance) const { + if (!policy_enabled_) { + return true; + } + auto its_client = policies_.find(_client); + if (its_client == policies_.end()) { + return !check_credentials_; + } + + if (!its_client->second->allow_) { + auto its_denied_service = its_client->second->denied_services_.find( + std::make_pair(_service, _instance)); + if (its_denied_service == its_client->second->denied_services_.end()) { + return true; + } + } else { + auto its_allowed_service = its_client->second->allowed_services_.find( + std::make_pair(_service, _instance)); + if (its_allowed_service != its_client->second->allowed_services_.end()) { + return true; + } + } + + return !check_credentials_; +} + +bool configuration_impl::is_offer_allowed(client_t _client, service_t _service, + instance_t _instance) const { + if (!policy_enabled_) { + return true; + } + auto its_client = policies_.find(_client); + if (its_client == policies_.end()) { + return !check_credentials_; + } + + if (!its_client->second->allow_) { + auto its_denied_service = its_client->second->denied_offers_.find( + std::make_pair(_service, _instance)); + if (its_denied_service == its_client->second->denied_offers_.end()) { + return true; + } + } else { + auto its_allowed_service = its_client->second->allowed_offers_.find( + std::make_pair(_service, _instance)); + if (its_allowed_service != its_client->second->allowed_offers_.end()) { + return true; + } + } + + return !check_credentials_; +} } // namespace config } // namespace vsomeip |