diff options
Diffstat (limited to 'implementation/configuration')
19 files changed, 1323 insertions, 1835 deletions
diff --git a/implementation/configuration/include/client.hpp b/implementation/configuration/include/client.hpp index 81ed890..7758eca 100644 --- a/implementation/configuration/include/client.hpp +++ b/implementation/configuration/include/client.hpp @@ -3,8 +3,8 @@ // 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/. -#ifndef VSOMEIP_CFG_CLIENT_HPP -#define VSOMEIP_CFG_CLIENT_HPP +#ifndef VSOMEIP_V3_CFG_CLIENT_HPP +#define VSOMEIP_V3_CFG_CLIENT_HPP #include <map> #include <memory> @@ -12,7 +12,7 @@ #include <vsomeip/primitive_types.hpp> -namespace vsomeip { +namespace vsomeip_v3 { namespace cfg { struct client { @@ -29,6 +29,6 @@ struct client { }; } // namespace cfg -} // namespace vsomeip +} // namespace vsomeip_v3 -#endif // VSOMEIP_CFG_CLIENT_HPP +#endif // VSOMEIP_V3_CFG_CLIENT_HPP diff --git a/implementation/configuration/include/configuration.hpp b/implementation/configuration/include/configuration.hpp index 9740a79..aac5422 100644 --- a/implementation/configuration/include/configuration.hpp +++ b/implementation/configuration/include/configuration.hpp @@ -3,13 +3,14 @@ // 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/. -#ifndef VSOMEIP_CONFIGURATION_HPP -#define VSOMEIP_CONFIGURATION_HPP +#ifndef VSOMEIP_V3_CONFIGURATION_HPP +#define VSOMEIP_V3_CONFIGURATION_HPP #include <map> #include <memory> #include <set> #include <string> +#include <chrono> #include <boost/asio/ip/address.hpp> #include <boost/log/trivial.hpp> @@ -19,24 +20,35 @@ #include <vsomeip/plugin.hpp> #include <vsomeip/primitive_types.hpp> -#include "internal.hpp" #include "trace.hpp" #include "../../e2e_protection/include/e2exf/config.hpp" #include "e2e.hpp" -#include "policy.hpp" #include "debounce.hpp" +#ifdef ANDROID +#include "internal_android.hpp" +#else +#include "internal.hpp" +#endif // ANDROID + +#include "../../security/include/policy.hpp" + #define VSOMEIP_CONFIG_PLUGIN_VERSION 1 -namespace vsomeip { +namespace vsomeip_v3 { class event; class configuration { public: - virtual ~configuration() {} + virtual ~configuration() +#ifndef ANDROID + {} +#else + ; +#endif virtual bool load(const std::string &_name) = 0; virtual bool remote_offer_info_add(service_t _service, @@ -55,8 +67,9 @@ public: virtual const boost::asio::ip::address & get_unicast_address() const = 0; virtual const boost::asio::ip::address& get_netmask() const = 0; - virtual unsigned short get_diagnosis_address() const = 0; - virtual std::uint16_t get_diagnosis_mask() const = 0; + virtual const std::string &get_device() const = 0; + virtual diagnosis_t get_diagnosis_address() const = 0; + virtual diagnosis_t get_diagnosis_mask() const = 0; virtual bool is_v4() const = 0; virtual bool is_v6() const = 0; @@ -77,6 +90,17 @@ public: virtual uint16_t get_unreliable_port(service_t _service, instance_t _instance) const = 0; + virtual void get_configured_timing_requests( + service_t _service, std::string _ip_target, + std::uint16_t _port_target, method_t _method, + std::chrono::nanoseconds *_debounce_time, + std::chrono::nanoseconds *_max_retention_time) const = 0; + virtual void get_configured_timing_responses( + service_t _service, std::string _ip_service, + std::uint16_t _port_service, method_t _method, + std::chrono::nanoseconds *_debounce_time, + std::chrono::nanoseconds *_max_retention_time) const = 0; + virtual bool is_someip(service_t _service, instance_t _instance) const = 0; virtual bool get_client_port(service_t _service, instance_t _instance, @@ -103,6 +127,7 @@ public: virtual std::uint32_t get_max_message_size_local() const = 0; virtual std::uint32_t get_max_message_size_reliable(const std::string& _address, std::uint16_t _port) const = 0; + virtual std::uint32_t get_max_message_size_unreliable() const = 0; virtual std::uint32_t get_buffer_shrink_threshold() const = 0; virtual bool supports_selective_broadcasts(boost::asio::ip::address _address) const = 0; @@ -111,7 +136,10 @@ public: virtual bool is_local_service(service_t _service, instance_t _instance) const = 0; - virtual bool is_event_reliable(service_t _service, instance_t _instance, event_t _event) const = 0; + virtual reliability_type_e get_event_reliability( + service_t _service, instance_t _instance, event_t _event) const = 0; + virtual reliability_type_e get_service_reliability( + service_t _service, instance_t _instance) const = 0; // Service Discovery configuration virtual bool is_sd_enabled() const = 0; @@ -120,8 +148,8 @@ public: virtual uint16_t get_sd_port() const = 0; virtual const std::string & get_sd_protocol() const = 0; - virtual int32_t get_sd_initial_delay_min() const = 0; - virtual int32_t get_sd_initial_delay_max() const = 0; + virtual uint32_t get_sd_initial_delay_min() const = 0; + virtual uint32_t get_sd_initial_delay_max() const = 0; virtual int32_t get_sd_repetitions_base_delay() const = 0; virtual uint8_t get_sd_repetitions_max() const = 0; virtual ttl_t get_sd_ttl() const = 0; @@ -144,23 +172,6 @@ public: virtual bool log_version() const = 0; virtual uint32_t get_log_version_interval() const = 0; - // Security - virtual bool is_security_enabled() const = 0; - virtual bool is_client_allowed(client_t _client, service_t _service, - instance_t _instance, method_t _method, bool _is_request_service = false) const = 0; - virtual bool is_offer_allowed(client_t _client, service_t _service, - instance_t _instance) const = 0; - virtual bool check_credentials(client_t _client, - uint32_t _uid, uint32_t _gid) = 0; - virtual bool store_client_to_uid_gid_mapping(client_t _client, uint32_t _uid, uint32_t _gid) = 0; - virtual void store_uid_gid_to_client_mapping(uint32_t _uid, uint32_t _gid, client_t _client) = 0; - - virtual bool get_client_to_uid_gid_mapping(client_t _client, - std::pair<uint32_t, uint32_t> &_uid_gid) = 0; - virtual bool remove_client_to_uid_gid_mapping(client_t _client) = 0; - virtual bool get_uid_gid_to_client_mapping(std::pair<uint32_t, uint32_t> _uid_gid, - std::set<client_t> &_clients) = 0; - // Plugins virtual std::map<plugin_type_e, std::set<std::string>> get_plugins( const std::string &_name) const = 0; @@ -196,37 +207,31 @@ public: virtual std::uint32_t get_max_tcp_restart_aborts() const = 0; virtual std::uint32_t get_max_tcp_connect_time() const = 0; - // Offer acceptance - virtual bool offer_acceptance_required( - const boost::asio::ip::address& _address) const = 0; - virtual void set_offer_acceptance_required( - const boost::asio::ip::address& _address, const std::string& _path, - bool _enable) = 0; - virtual std::map<boost::asio::ip::address, std::string> get_offer_acceptance_required() = 0; - - // Security policy - virtual void update_security_policy(uint32_t _uid, uint32_t _gid, ::std::shared_ptr<policy> _policy) = 0; - virtual bool remove_security_policy(uint32_t _uid, uint32_t _gid) = 0; - - virtual void add_security_credentials(uint32_t _uid, uint32_t _gid, - ::std::shared_ptr<policy> _credentials_policy, client_t _client) = 0; - - virtual bool is_remote_client_allowed() const = 0; - - virtual bool is_policy_update_allowed(uint32_t _uid, std::shared_ptr<policy> &_policy) const = 0; - - virtual bool is_policy_removal_allowed(uint32_t _uid) const = 0; + // SD acceptance + virtual bool sd_acceptance_required(const boost::asio::ip::address& _address, + std::uint16_t _port) const = 0; + virtual void set_sd_acceptance_required( + const boost::asio::ip::address& _address, std::uint16_t _port, + const std::string& _path, bool _enable) = 0; + typedef std::map<std::pair<boost::asio::ip::address, std::uint16_t>, std::string> sd_acceptance_required_map_t; + virtual sd_acceptance_required_map_t get_sd_acceptance_required() = 0; virtual std::uint32_t get_udp_receive_buffer_size() const = 0; - virtual bool is_audit_mode_enabled() const = 0; - virtual bool check_routing_credentials(client_t _client, uint32_t _uid, uint32_t _gid) const = 0; + // SOME/IP-TP + virtual bool tp_segment_messages_client_to_service( + service_t _service, std::string _ip_target, + std::uint16_t _port_target, method_t _method) const = 0; + virtual bool tp_segment_messages_service_to_client( + service_t _service, std::string _ip_service, + std::uint16_t _port_service, method_t _method) const = 0; + // routing shutdown timeout virtual std::uint32_t get_shutdown_timeout() const = 0; }; -} // namespace vsomeip +} // namespace vsomeip_v3 -#endif // VSOMEIP_CONFIGURATION_HPP +#endif // VSOMEIP_V3_CONFIGURATION_HPP diff --git a/implementation/configuration/include/configuration_element.hpp b/implementation/configuration/include/configuration_element.hpp new file mode 100644 index 0000000..7daf9d7 --- /dev/null +++ b/implementation/configuration/include/configuration_element.hpp @@ -0,0 +1,26 @@ +// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// 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/. + +#ifndef VSOMEIP_V3_CONFIGURATION_CONFIGURATION_ELEMENT_HPP_ +#define VSOMEIP_V3_CONFIGURATION_CONFIGURATION_ELEMENT_HPP_ + +#include <string> + +#include <boost/property_tree/ptree.hpp> + +namespace vsomeip_v3 { + +struct configuration_element { + std::string name_; + boost::property_tree::ptree tree_; + + bool operator<(const configuration_element &_other) const { + return (name_ < _other.name_); + } +}; + +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_CONFIGURATION_CONFIGURATION_ELEMENT_HPP_ diff --git a/implementation/configuration/include/configuration_impl.hpp b/implementation/configuration/include/configuration_impl.hpp index 9bf1188..f43a97a 100644 --- a/implementation/configuration/include/configuration_impl.hpp +++ b/implementation/configuration/include/configuration_impl.hpp @@ -3,8 +3,8 @@ // 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/. -#ifndef VSOMEIP_CFG_CONFIGURATION_IMPL_HPP -#define VSOMEIP_CFG_CONFIGURATION_IMPL_HPP +#ifndef VSOMEIP_V3_CFG_CONFIGURATION_IMPL_HPP +#define VSOMEIP_V3_CFG_CONFIGURATION_IMPL_HPP #include <map> #include <memory> @@ -17,14 +17,15 @@ #include "trace.hpp" #include "configuration.hpp" +#include "configuration_element.hpp" #include "watchdog.hpp" #include "service_instance_range.hpp" -#include "policy.hpp" #include "../../e2e_protection/include/e2exf/config.hpp" #include "e2e.hpp" #include "debounce.hpp" +#include "../../security/include/policy.hpp" -namespace vsomeip { +namespace vsomeip_v3 { namespace cfg { struct client; @@ -34,18 +35,8 @@ struct event; struct eventgroup; struct watchdog; -struct element { - std::string name_; - boost::property_tree::ptree tree_; - - bool operator<(const element &_other) const { - return (name_ < _other.name_); - } -}; - class configuration_impl: public configuration, - public plugin_impl<configuration_impl>, public std::enable_shared_from_this<configuration_impl> { public: VSOMEIP_EXPORT configuration_impl(); @@ -71,6 +62,7 @@ public: VSOMEIP_EXPORT const boost::asio::ip::address & get_unicast_address() const; VSOMEIP_EXPORT const boost::asio::ip::address& get_netmask() const; + VSOMEIP_EXPORT const std::string &get_device() const; VSOMEIP_EXPORT unsigned short get_diagnosis_address() const; VSOMEIP_EXPORT std::uint16_t get_diagnosis_mask() const; VSOMEIP_EXPORT bool is_v4() const; @@ -89,6 +81,17 @@ public: VSOMEIP_EXPORT uint16_t get_unreliable_port(service_t _service, instance_t _instance) const; + VSOMEIP_EXPORT void get_configured_timing_requests( + service_t _service, std::string _ip_target, + std::uint16_t _port_target, method_t _method, + std::chrono::nanoseconds *_debounce_time, + std::chrono::nanoseconds *_max_retention_time) const; + VSOMEIP_EXPORT void get_configured_timing_responses( + service_t _service, std::string _ip_service, + std::uint16_t _port_service, method_t _method, + std::chrono::nanoseconds *_debounce_time, + std::chrono::nanoseconds *_max_retention_time) const; + VSOMEIP_EXPORT bool is_someip(service_t _service, instance_t _instance) const; VSOMEIP_EXPORT bool get_client_port(service_t _service, instance_t _instance, @@ -117,6 +120,7 @@ public: VSOMEIP_EXPORT std::uint32_t get_max_message_size_local() const; VSOMEIP_EXPORT std::uint32_t get_max_message_size_reliable(const std::string& _address, std::uint16_t _port) const; + VSOMEIP_EXPORT std::uint32_t get_max_message_size_unreliable() const; VSOMEIP_EXPORT std::uint32_t get_buffer_shrink_threshold() const; VSOMEIP_EXPORT bool supports_selective_broadcasts(boost::asio::ip::address _address) const; @@ -128,7 +132,11 @@ public: VSOMEIP_EXPORT bool is_local_service(service_t _service, instance_t _instance) const; - VSOMEIP_EXPORT bool is_event_reliable(service_t _service, instance_t _instance, event_t _event) const; + VSOMEIP_EXPORT reliability_type_e get_event_reliability( + service_t _service, instance_t _instance, event_t _event) const; + + VSOMEIP_EXPORT reliability_type_e get_service_reliability( + service_t _service, instance_t _instance) const; // Service Discovery configuration VSOMEIP_EXPORT bool is_sd_enabled() const; @@ -137,8 +145,8 @@ public: VSOMEIP_EXPORT uint16_t get_sd_port() const; VSOMEIP_EXPORT const std::string & get_sd_protocol() const; - VSOMEIP_EXPORT int32_t get_sd_initial_delay_min() const; - VSOMEIP_EXPORT int32_t get_sd_initial_delay_max() const; + VSOMEIP_EXPORT uint32_t get_sd_initial_delay_min() const; + VSOMEIP_EXPORT uint32_t get_sd_initial_delay_max() const; VSOMEIP_EXPORT int32_t get_sd_repetitions_base_delay() const; VSOMEIP_EXPORT uint8_t get_sd_repetitions_max() const; VSOMEIP_EXPORT ttl_t get_sd_ttl() const; @@ -156,22 +164,7 @@ public: VSOMEIP_EXPORT std::uint32_t get_permissions_uds() const; VSOMEIP_EXPORT std::uint32_t get_permissions_shm() const; - // Policy - VSOMEIP_EXPORT bool is_security_enabled() const; - VSOMEIP_EXPORT bool is_client_allowed(client_t _client, service_t _service, - instance_t _instance, method_t _method, bool _is_request_service = false) const; - VSOMEIP_EXPORT bool is_offer_allowed(client_t _client, service_t _service, - instance_t _instance) const; - VSOMEIP_EXPORT bool check_credentials(client_t _client, - uint32_t _uid, uint32_t _gid); - - VSOMEIP_EXPORT bool store_client_to_uid_gid_mapping(client_t _client, uint32_t _uid, uint32_t _gid); - VSOMEIP_EXPORT void store_uid_gid_to_client_mapping(uint32_t _uid, uint32_t _gid, client_t _client); - VSOMEIP_EXPORT bool get_client_to_uid_gid_mapping(client_t _client, - std::pair<uint32_t, uint32_t> &_uid_gid); - VSOMEIP_EXPORT bool remove_client_to_uid_gid_mapping(client_t _client); - VSOMEIP_EXPORT bool get_uid_gid_to_client_mapping(std::pair<uint32_t, uint32_t> _uid_gid, - std::set<client_t> &_clients); + VSOMEIP_EXPORT bool check_routing_credentials(client_t _client, uint32_t _uid, uint32_t _gid) const; VSOMEIP_EXPORT std::map<plugin_type_e, std::set<std::string>> get_plugins( const std::string &_name) const; @@ -198,52 +191,59 @@ public: VSOMEIP_EXPORT std::uint32_t get_max_tcp_restart_aborts() const; VSOMEIP_EXPORT std::uint32_t get_max_tcp_connect_time() const; - VSOMEIP_EXPORT bool offer_acceptance_required( - const boost::asio::ip::address& _address) const; - - VSOMEIP_EXPORT void set_offer_acceptance_required( - const boost::asio::ip::address& _address, const std::string& _path, - bool _enable); - VSOMEIP_EXPORT std::map<boost::asio::ip::address, std::string> get_offer_acceptance_required(); - - VSOMEIP_EXPORT void update_security_policy(uint32_t _uid, uint32_t _gid, ::std::shared_ptr<policy> _policy); - VSOMEIP_EXPORT bool remove_security_policy(uint32_t _uid, uint32_t _gid); - - VSOMEIP_EXPORT void add_security_credentials(uint32_t _uid, uint32_t _gid, - ::std::shared_ptr<policy> _credentials_policy, client_t _client); + VSOMEIP_EXPORT bool sd_acceptance_required(const boost::asio::ip::address& _address, + std::uint16_t _port) const; - VSOMEIP_EXPORT bool is_remote_client_allowed() const; - - VSOMEIP_EXPORT bool is_policy_update_allowed(uint32_t _uid, std::shared_ptr<policy> &_policy) const; - - VSOMEIP_EXPORT bool is_policy_removal_allowed(uint32_t _uid) const; + VSOMEIP_EXPORT void set_sd_acceptance_required( + const boost::asio::ip::address& _address, std::uint16_t _port, + const std::string& _path, bool _enable); + VSOMEIP_EXPORT sd_acceptance_required_map_t get_sd_acceptance_required(); VSOMEIP_EXPORT std::uint32_t get_udp_receive_buffer_size() const; - VSOMEIP_EXPORT bool is_audit_mode_enabled() const; + VSOMEIP_EXPORT bool has_overlay(const std::string &_name) const; + VSOMEIP_EXPORT void load_overlay(const std::string &_name); - VSOMEIP_EXPORT bool check_routing_credentials(client_t _client, uint32_t _uid, uint32_t _gid) const; + VSOMEIP_EXPORT bool tp_segment_messages_client_to_service( + service_t _service, std::string _ip_target, + std::uint16_t _port_target, method_t _method) const; + VSOMEIP_EXPORT bool tp_segment_messages_service_to_client( + service_t _service, std::string _ip_service, + std::uint16_t _port_service, method_t _method) const; VSOMEIP_EXPORT std::uint32_t get_shutdown_timeout() const; private: void read_data(const std::set<std::string> &_input, - std::vector<element> &_elements, + std::vector<configuration_element> &_elements, std::set<std::string> &_failed, bool _mandatory_only); - bool load_data(const std::vector<element> &_elements, + bool load_data(const std::vector<configuration_element> &_elements, bool _load_mandatory, bool _load_optional); - bool load_logging(const element &_element, + bool load_logging(const configuration_element &_element, std::set<std::string> &_warnings); - bool load_routing(const element &_element); - bool load_routing_credentials(const element &_element); + bool load_routing(const configuration_element &_element); + bool load_routing_credentials(const configuration_element &_element); - bool load_applications(const element &_element); + bool load_applications(const configuration_element &_element); void load_application_data(const boost::property_tree::ptree &_tree, const std::string &_file_name); - void load_tracing(const element &_element); + std::map<plugin_type_e, std::set<std::string>> load_plugins( + const boost::property_tree::ptree &_tree, + const std::string& _application_name); + + struct plugin_config_data_t { + std::string name_; + std::string type_; + }; + + void add_plugin(std::map<plugin_type_e, std::set<std::string>> &_plugins, + const plugin_config_data_t &_plugin_data, + const std::string& _application_name); + + void load_tracing(const configuration_element &_element); void load_trace_channels(const boost::property_tree::ptree &_tree); void load_trace_channel(const boost::property_tree::ptree &_tree); void load_trace_filters(const boost::property_tree::ptree &_tree); @@ -256,17 +256,19 @@ private: const boost::property_tree::ptree &_data, std::tuple<service_t, instance_t, method_t> &_match); - void load_network(const element &_element); + void load_network(const configuration_element &_element); + void load_device(const configuration_element &_element); - void load_unicast_address(const element &_element); - void load_netmask(const element &_element); - void load_diagnosis_address(const element &_element); - void load_shutdown_timeout(const element &_element); + void load_unicast_address(const configuration_element &_element); + void load_netmask(const configuration_element &_element); + void load_diagnosis_address(const configuration_element &_element); + void load_shutdown_timeout(const configuration_element &_element); - void load_service_discovery(const element &_element); + void load_service_discovery(const configuration_element &_element); void load_delays(const boost::property_tree::ptree &_tree); - void load_services(const element &_element); + void load_npdu_default_timings(const configuration_element &_element); + void load_services(const configuration_element &_element); void load_servicegroup(const boost::property_tree::ptree &_tree); void load_service(const boost::property_tree::ptree &_tree, const std::string &_unicast_address); @@ -275,30 +277,24 @@ private: void load_eventgroup(std::shared_ptr<service> &_service, const boost::property_tree::ptree &_tree); - void load_internal_services(const element &_element); + void load_internal_services(const configuration_element &_element); - void load_clients(const element &_element); + void load_clients(const configuration_element &_element); void load_client(const boost::property_tree::ptree &_tree); std::set<uint16_t> load_client_ports(const boost::property_tree::ptree &_tree); std::pair<uint16_t, uint16_t> load_client_port_range(const boost::property_tree::ptree &_tree); - void load_watchdog(const element &_element); + void load_watchdog(const configuration_element &_element); - void load_payload_sizes(const element &_element); - void load_permissions(const element &_element); - void load_selective_broadcasts_support(const element &_element); - void load_policies(const element &_element); - void load_policy(const boost::property_tree::ptree &_tree); - void load_credential(const boost::property_tree::ptree &_tree, ids_t &_ids); - void load_ranges(const boost::property_tree::ptree &_tree, ranges_t &_range); - void load_instance_ranges(const boost::property_tree::ptree &_tree, ranges_t &_range); + void load_payload_sizes(const configuration_element &_element); + void load_permissions(const configuration_element &_element); - void load_security_update_whitelist(const element &_element); - void load_service_ranges(const boost::property_tree::ptree &_tree, - std::set<std::pair<service_t, service_t>> &_ranges); + void load_security(const configuration_element &_element); - void load_debounce(const element &_element); + void load_selective_broadcasts_support(const configuration_element &_element); + + void load_debounce(const configuration_element &_element); void load_service_debounce(const boost::property_tree::ptree &_tree); void load_events_debounce(const boost::property_tree::ptree &_tree, std::map<event_t, std::shared_ptr<debounce>> &_debounces); @@ -306,15 +302,27 @@ private: std::map<event_t, std::shared_ptr<debounce>> &_debounces); void load_event_debounce_ignore(const boost::property_tree::ptree &_tree, std::map<std::size_t, byte_t> &_ignore); - void load_offer_acceptance_required(const element &_element); - void load_udp_receive_buffer_size(const element &_element); - + void load_sd_acceptance_required(const configuration_element &_element); + void load_udp_receive_buffer_size(const configuration_element &_element); + bool load_npdu_debounce_times_configuration( + const std::shared_ptr<service>& _service, + const boost::property_tree::ptree &_tree); + bool load_npdu_debounce_times_for_service( + const std::shared_ptr<service>& _service, bool _is_request, + const boost::property_tree::ptree &_tree); + void load_someip_tp(const std::shared_ptr<service>& _service, + const boost::property_tree::ptree &_tree); + void load_someip_tp_for_service( + const std::shared_ptr<service>& _service, + const boost::property_tree::ptree &_tree, bool _is_request); servicegroup *find_servicegroup(const std::string &_name) const; std::shared_ptr<client> find_client(service_t _service, instance_t _instance) const; std::shared_ptr<service> find_service(service_t _service, instance_t _instance) const; std::shared_ptr<service> find_service_unlocked(service_t _service, instance_t _instance) const; + service * find_service_by_ip_port(service_t _service, const std::string& _ip, + std::uint16_t _port) const; std::shared_ptr<eventgroup> find_eventgroup(service_t _service, instance_t _instance, eventgroup_t _eventgroup) const; bool find_port(uint16_t &_port, uint16_t _remote, bool _reliable, @@ -323,32 +331,30 @@ private: void set_magic_cookies_unicast_address(); bool is_mandatory(const std::string &_name) const; - bool is_remote(std::shared_ptr<service> _service) const; + bool is_remote(const std::shared_ptr<service>& _service) const; bool is_internal_service(service_t _service, instance_t _instance) const; bool is_in_port_range(uint16_t _port, std::pair<uint16_t, uint16_t> _port_range) const; void set_mandatory(const std::string &_input); void trim(std::string &_s); - void load_e2e(const element &_element); + void load_e2e(const configuration_element &_element); void load_e2e_protected(const boost::property_tree::ptree &_tree); void load_ttl_factors(const boost::property_tree::ptree &_tree, ttl_map_t* _target); - void load_endpoint_queue_sizes(const element &_element); + void load_endpoint_queue_sizes(const configuration_element &_element); - void load_tcp_restart_settings(const element &_element); - - std::shared_ptr<policy> find_client_id_policy(client_t _client) const; + void load_tcp_restart_settings(const configuration_element &_element); private: std::mutex mutex_; - mutable std::mutex ids_mutex_; - mutable std::mutex uid_to_clients_mutex_; + const std::string default_unicast_; bool is_loaded_; bool is_logging_loaded_; + bool is_overlay_; std::set<std::string> mandatory_; @@ -356,8 +362,9 @@ protected: // Configuration data boost::asio::ip::address unicast_; boost::asio::ip::address netmask_; - unsigned short diagnosis_; - std::uint16_t diagnosis_mask_; + std::string device_; + diagnosis_t diagnosis_; + diagnosis_t diagnosis_mask_; bool has_console_log_; bool has_file_log_; @@ -365,8 +372,21 @@ protected: std::string logfile_; boost::log::trivial::severity_level loglevel_; - std::map<std::string, std::tuple<client_t, std::size_t, std::size_t, - size_t, size_t, std::map<plugin_type_e, std::set<std::string>>, int>> applications_; + std::map<std::string, + std::tuple< + client_t, + std::size_t, + std::size_t, + std::size_t, + std::size_t, + std::map< + plugin_type_e, + std::set<std::string> + >, + int, + std::string + > + > applications_; std::set<client_t> client_identifiers_; mutable std::mutex services_mutex_; @@ -374,6 +394,11 @@ protected: std::map<instance_t, std::shared_ptr<service> > > services_; + std::map<std::string, // IP + std::map<std::uint16_t, // port + std::map<service_t, + std::shared_ptr<service>>>> services_by_ip_port_; + std::list< std::shared_ptr<client> > clients_; std::string routing_host_; @@ -383,8 +408,8 @@ protected: std::string sd_multicast_; uint16_t sd_port_; - int32_t sd_initial_delay_min_; - int32_t sd_initial_delay_max_; + uint32_t sd_initial_delay_min_; + uint32_t sd_initial_delay_max_; int32_t sd_repetitions_base_delay_; uint8_t sd_repetitions_max_; ttl_t sd_ttl_; @@ -398,6 +423,7 @@ protected: std::uint32_t max_configured_message_size_; std::uint32_t max_local_message_size_; std::uint32_t max_reliable_message_size_; + std::uint32_t max_unreliable_message_size_; std::uint32_t buffer_shrink_threshold_; std::shared_ptr<trace> trace_; @@ -414,6 +440,7 @@ protected: enum element_type_e { ET_NETWORK, ET_UNICAST, + ET_DEVICE, ET_DIAGNOSIS, ET_DIAGNOSIS_MASK, ET_LOGGING_CONSOLE, @@ -445,32 +472,21 @@ protected: ET_ENDPOINT_QUEUE_LIMIT_LOCAL, ET_TCP_RESTART_ABORTS_MAX, ET_TCP_CONNECT_TIME_MAX, - ET_OFFER_ACCEPTANCE_REQUIRED, + ET_SD_ACCEPTANCE_REQUIRED, ET_NETMASK, ET_UDP_RECEIVE_BUFFER_SIZE, + ET_NPDU_DEFAULT_TIMINGS, + ET_PLUGIN_NAME, + ET_PLUGIN_TYPE, ET_ROUTING_CREDENTIALS, ET_SHUTDOWN_TIMEOUT, - ET_MAX = 38 + ET_MAX = 42 }; bool is_configured_[ET_MAX]; std::uint32_t permissions_shm_; std::uint32_t permissions_uds_; - std::map<std::pair<uint16_t, uint16_t>, std::shared_ptr<policy>> policies_; - std::vector<std::shared_ptr<policy> > any_client_policies_; - - mutable std::mutex policies_mutex_; - mutable std::mutex any_client_policies_mutex_; - std::map<client_t, std::pair<uint32_t, uint32_t> > ids_; - std::map<std::pair<uint32_t, uint32_t>, std::set<client_t> > uid_to_clients_; - - bool policy_enabled_; - bool check_credentials_; - bool check_routing_credentials_; - bool allow_remote_clients_; - bool check_whitelist_; - std::string network_; std::string configuration_path_; @@ -495,27 +511,23 @@ protected: uint32_t tcp_restart_aborts_max_; uint32_t tcp_connect_time_max_; - mutable std::mutex offer_acceptance_required_ips_mutex_; - std::map<boost::asio::ip::address, std::string> offer_acceptance_required_ips_; + mutable std::mutex sd_acceptance_required_ips_mutex_; + sd_acceptance_required_map_t sd_acceptance_required_ips_; bool has_issued_methods_warning_; bool has_issued_clients_warning_; std::uint32_t udp_receive_buffer_size_; - mutable std::mutex service_interface_whitelist_mutex_; - std::set<std::pair<service_t, service_t>> service_interface_whitelist_; - - mutable std::mutex uid_whitelist_mutex_; - ranges_t uid_whitelist_; - - mutable std::mutex routing_credentials_mutex_; - std::pair<uint32_t, uint32_t> routing_credentials_; + std::chrono::nanoseconds npdu_default_debounce_requ_; + std::chrono::nanoseconds npdu_default_debounce_resp_; + std::chrono::nanoseconds npdu_default_max_retention_requ_; + std::chrono::nanoseconds npdu_default_max_retention_resp_; std::uint32_t shutdown_timeout_; }; } // namespace cfg -} // namespace vsomeip +} // namespace vsomeip_v3 -#endif // VSOMEIP_CFG_CONFIGURATION_IMPL_HPP +#endif // VSOMEIP_V3_CFG_CONFIGURATION_IMPL_HPP diff --git a/implementation/configuration/include/configuration_plugin.hpp b/implementation/configuration/include/configuration_plugin.hpp new file mode 100644 index 0000000..cbb4685 --- /dev/null +++ b/implementation/configuration/include/configuration_plugin.hpp @@ -0,0 +1,26 @@ +// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// 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/. + +#ifndef VSOMEIP_V3_CONFIGURATION_PLUGIN_HPP_ +#define VSOMEIP_V3_CONFIGURATION_PLUGIN_HPP_ + +#include <string> +#include <memory> + +#define VSOMEIP_CONFIG_PLUGIN_VERSION 1 + +namespace vsomeip_v3 { + +class configuration; + +class configuration_plugin { +public: + virtual ~configuration_plugin() = default; + virtual std::shared_ptr<configuration> get_configuration(const std::string &_name) = 0; +}; + +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_CONFIGURATION_PLUGIN_HPP_ diff --git a/implementation/configuration/include/configuration_plugin_impl.hpp b/implementation/configuration/include/configuration_plugin_impl.hpp new file mode 100644 index 0000000..fd95628 --- /dev/null +++ b/implementation/configuration/include/configuration_plugin_impl.hpp @@ -0,0 +1,42 @@ +// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// 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/. + +#ifndef VSOMEIP_V3_CONFIGURATION_CONFIGURATION_PLUGIN_IMPL_HPP_ +#define VSOMEIP_V3_CONFIGURATION_CONFIGURATION_PLUGIN_IMPL_HPP_ + +#include <map> +#include <mutex> + +#include <vsomeip/plugin.hpp> + +#include "configuration_plugin.hpp" + +namespace vsomeip_v3 { +namespace cfg { + + class configuration_impl; + +} // namespace cfg + +class configuration_plugin_impl + : public configuration_plugin, + public plugin_impl<configuration_plugin_impl> { +public: + configuration_plugin_impl(); + virtual ~configuration_plugin_impl(); + + std::shared_ptr<configuration> get_configuration(const std::string &_name); + +private: + std::mutex mutex_; + std::shared_ptr<cfg::configuration_impl> default_; +#ifdef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS + std::map<std::string, std::shared_ptr<cfg::configuration_impl> > configurations_; +#endif // VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS +}; + +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_CONFIGURATION_CONFIGURATION_PLUGIN_IMPL_HPP_ diff --git a/implementation/configuration/include/debounce.hpp b/implementation/configuration/include/debounce.hpp index b4ce6d3..dc61514 100644 --- a/implementation/configuration/include/debounce.hpp +++ b/implementation/configuration/include/debounce.hpp @@ -3,12 +3,12 @@ // 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/. -#ifndef VSOMEIP_CFG_DEBOUNCE_HPP -#define VSOMEIP_CFG_DEBOUNCE_HPP +#ifndef VSOMEIP_V3_CFG_DEBOUNCE_HPP +#define VSOMEIP_V3_CFG_DEBOUNCE_HPP #include <map> -namespace vsomeip { +namespace vsomeip_v3 { namespace cfg { // Messages are forwarded either because their value differs from the @@ -34,6 +34,6 @@ struct debounce { }; } // namespace cfg -} // namespace vsomeip +} // namespace vsomeip_v3 -#endif // VSOMEIP_CFG_DEBOUNCE_HPP +#endif // VSOMEIP_V3_CFG_DEBOUNCE_HPP diff --git a/implementation/configuration/include/e2e.hpp b/implementation/configuration/include/e2e.hpp index 94eb33d..8c873c2 100644 --- a/implementation/configuration/include/e2e.hpp +++ b/implementation/configuration/include/e2e.hpp @@ -3,48 +3,37 @@ // 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/. -#ifndef VSOMEIP_CFG_E2E_HPP_ -#define VSOMEIP_CFG_E2E_HPP_ +#ifndef VSOMEIP_V3_CFG_E2E_HPP_ +#define VSOMEIP_V3_CFG_E2E_HPP_ +#include <map> #include <string> #include <vector> #include <vsomeip/primitive_types.hpp> -namespace vsomeip { +namespace vsomeip_v3 { namespace cfg { struct e2e { + typedef std::map<std::string, std::string> custom_parameters_t; e2e() : data_id(0), variant(""), profile(""), service_id(0), - event_id(0), - crc_offset(0), - data_id_mode(0), - data_length(0), - data_id_nibble_offset(0), - counter_offset(0) { + event_id(0) { } - e2e(uint16_t _data_id, std::string _variant, std::string _profile, service_t _service_id, - event_t _event_id,uint16_t _crc_offset, - uint8_t _data_id_mode, uint16_t _data_length, uint16_t _data_id_nibble_offset, uint16_t _counter_offset) : - + event_t _event_id, custom_parameters_t&& _custom_parameters) : data_id(_data_id), variant(_variant), profile(_profile), service_id(_service_id), event_id(_event_id), - crc_offset(_crc_offset), - data_id_mode(_data_id_mode), - data_length(_data_length), - data_id_nibble_offset(_data_id_nibble_offset), - counter_offset(_counter_offset) { - + custom_parameters(_custom_parameters) { } // common config @@ -54,16 +43,11 @@ struct e2e { service_t service_id; event_t event_id; - //profile 1 specific config - // [SWS_E2E_00018] - uint16_t crc_offset; - uint8_t data_id_mode; - uint16_t data_length; - uint16_t data_id_nibble_offset; - uint16_t counter_offset; + // custom parameters + custom_parameters_t custom_parameters; }; } // namespace cfg -} // namespace vsomeip +} // namespace vsomeip_v3 -#endif // VSOMEIP_CFG_E2E_HPP_ +#endif // VSOMEIP_V3_CFG_E2E_HPP_ diff --git a/implementation/configuration/include/event.hpp b/implementation/configuration/include/event.hpp index 499c49a..701ec0c 100644 --- a/implementation/configuration/include/event.hpp +++ b/implementation/configuration/include/event.hpp @@ -3,31 +3,33 @@ // 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/. -#ifndef VSOMEIP_CFG_EVENT_HPP -#define VSOMEIP_CFG_EVENT_HPP +#ifndef VSOMEIP_V3_CFG_EVENT_HPP +#define VSOMEIP_V3_CFG_EVENT_HPP #include <memory> #include <vector> #include <vsomeip/primitive_types.hpp> -namespace vsomeip { +namespace vsomeip_v3 { namespace cfg { struct eventgroup; struct event { - event(event_t _id, bool _is_field, bool _is_reliable) - : id_(_id), is_field_(_is_field), is_reliable_(_is_reliable) { + event(event_t _id, bool _is_field, reliability_type_e _reliability) + : id_(_id), + is_field_(_is_field), + reliability_(_reliability) { } event_t id_; bool is_field_; - bool is_reliable_; + reliability_type_e reliability_; std::vector<std::weak_ptr<eventgroup> > groups_; }; } // namespace cfg -} // namespace vsomeip +} // namespace vsomeip_v3 -#endif // VSOMEIP_CFG_EVENT_HPP +#endif // VSOMEIP_V3_CFG_EVENT_HPP diff --git a/implementation/configuration/include/eventgroup.hpp b/implementation/configuration/include/eventgroup.hpp index c26edc0..1402b51 100644 --- a/implementation/configuration/include/eventgroup.hpp +++ b/implementation/configuration/include/eventgroup.hpp @@ -3,14 +3,14 @@ // 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/. -#ifndef VSOMEIP_CFG_EVENTGROUP_HPP -#define VSOMEIP_CFG_EVENTGROUP_HPP +#ifndef VSOMEIP_V3_CFG_EVENTGROUP_HPP +#define VSOMEIP_V3_CFG_EVENTGROUP_HPP #include <memory> #include <vsomeip/primitive_types.hpp> -namespace vsomeip { +namespace vsomeip_v3 { namespace cfg { struct event; @@ -24,6 +24,6 @@ struct eventgroup { }; } // namespace cfg -} // namespace vsomeip +} // namespace vsomeip_v3 -#endif // VSOMEIP_CFG_EVENTGROUP_HPP +#endif // VSOMEIP_V3_CFG_EVENTGROUP_HPP diff --git a/implementation/configuration/include/internal.hpp.in b/implementation/configuration/include/internal.hpp.in index b1a1372..36a6355 100644 --- a/implementation/configuration/include/internal.hpp.in +++ b/implementation/configuration/include/internal.hpp.in @@ -1,10 +1,10 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // 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/. -#ifndef VSOMEIP_INTERNAL_HPP -#define VSOMEIP_INTERNAL_HPP +#ifndef VSOMEIP_V3_INTERNAL_HPP_ +#define VSOMEIP_V3_INTERNAL_HPP_ #include <cstdint> #include <limits> @@ -13,35 +13,42 @@ #define VSOMEIP_ENV_APPLICATION_NAME "VSOMEIP_APPLICATION_NAME" #define VSOMEIP_ENV_CONFIGURATION "VSOMEIP_CONFIGURATION" #define VSOMEIP_ENV_CONFIGURATION_MODULE "VSOMEIP_CONFIGURATION_MODULE" +#define VSOMEIP_ENV_E2E_PROTECTION_MODULE "VSOMEIP_E2E_PROTECTION_MODULE" #define VSOMEIP_ENV_MANDATORY_CONFIGURATION_FILES "VSOMEIP_MANDATORY_CONFIGURATION_FILES" #define VSOMEIP_ENV_LOAD_PLUGINS "VSOMEIP_LOAD_PLUGINS" #define VSOMEIP_ENV_CLIENTSIDELOGGING "VSOMEIP_CLIENTSIDELOGGING" -#define VSOMEIP_DEFAULT_CONFIGURATION_FILE "/etc/vsomeip.json" +#define VSOMEIP_DEFAULT_CONFIGURATION_FILE "@DEFAULT_CONFIGURATION_FILE@" #define VSOMEIP_LOCAL_CONFIGURATION_FILE "./vsomeip.json" #define VSOMEIP_MANDATORY_CONFIGURATION_FILES "vsomeip_std.json,vsomeip_app.json,vsomeip_plc.json,vsomeip_log.json,vsomeip_security.json,vsomeip_whitelist.json" -#define VSOMEIP_DEFAULT_CONFIGURATION_FOLDER "/etc/vsomeip" +#define VSOMEIP_DEFAULT_CONFIGURATION_FOLDER "@DEFAULT_CONFIGURATION_FOLDER@" #define VSOMEIP_DEBUG_CONFIGURATION_FOLDER "/var/opt/public/sin/vsomeip/" #define VSOMEIP_LOCAL_CONFIGURATION_FOLDER "./vsomeip" -#define VSOMEIP_BASE_PATH "/tmp/" +#define VSOMEIP_BASE_PATH "@VSOMEIP_BASE_PATH@/" -#ifdef WIN32 -#define VSOMEIP_CFG_LIBRARY "vsomeip-cfg.dll" +#ifdef _WIN32 +#define VSOMEIP_CFG_LIBRARY "vsomeip3-cfg.dll" +#else +#define VSOMEIP_CFG_LIBRARY "libvsomeip3-cfg.so.@VSOMEIP_MAJOR_VERSION@" +#endif + +#ifdef _WIN32 +#define VSOMEIP_SD_LIBRARY "vsomeip3-sd.dll" #else -#define VSOMEIP_CFG_LIBRARY "libvsomeip-cfg.so.@VSOMEIP_MAJOR_VERSION@" +#define VSOMEIP_SD_LIBRARY "libvsomeip3-sd.so.@VSOMEIP_MAJOR_VERSION@" #endif -#ifdef WIN32 -#define VSOMEIP_SD_LIBRARY "vsomeip-sd.dll" +#ifdef _WIN32 +#define VSOMEIP_E2E_LIBRARY "vsomeip3-e2e.dll" #else -#define VSOMEIP_SD_LIBRARY "libvsomeip-sd.so.@VSOMEIP_MAJOR_VERSION@" +#define VSOMEIP_E2E_LIBRARY "libvsomeip3-e2e.so.@VSOMEIP_MAJOR_VERSION@" #endif -#define VSOMEIP_ROUTING "@VSOMEIP_ROUTING@" #define VSOMEIP_ROUTING_CLIENT 0 -#define VSOMEIP_ROUTING_INFO_SIZE_INIT 256 + +#define VSOMEIP_CLIENT_UNSET 0xFFFF #ifdef _WIN32 #define VSOMEIP_INTERNAL_BASE_PORT 51234 @@ -57,6 +64,8 @@ #define VSOMEIP_DEFAULT_SHUTDOWN_TIMEOUT 5000 +#define VSOMEIP_DEFAULT_QUEUE_WARN_SIZE 102400 + #define VSOMEIP_MAX_TCP_CONNECT_TIME 5000 #define VSOMEIP_MAX_TCP_RESTART_ABORTS 5 @@ -73,8 +82,6 @@ #define VSOMEIP_MAX_DISPATCHERS 10 #define VSOMEIP_MAX_DISPATCH_TIME 100 -#define VSOMEIP_MAX_DESERIALIZER 5 - #define VSOMEIP_REQUEST_DEBOUNCE_TIME 10 #define VSOMEIP_COMMAND_HEADER_SIZE 7 @@ -85,11 +92,13 @@ #define VSOMEIP_COMMAND_SIZE_POS_MAX 6 #define VSOMEIP_COMMAND_PAYLOAD_POS 7 -#define VSOMEIP_REGISTER_APPLICATION 0x00 -#define VSOMEIP_DEREGISTER_APPLICATION 0x01 -#define VSOMEIP_APPLICATION_LOST 0x02 -#define VSOMEIP_ROUTING_INFO 0x03 -#define VSOMEIP_REGISTERED_ACK 0x04 +#define VSOMEIP_ASSIGN_CLIENT 0x00 +#define VSOMEIP_ASSIGN_CLIENT_ACK 0x01 +#define VSOMEIP_REGISTER_APPLICATION 0x02 +#define VSOMEIP_DEREGISTER_APPLICATION 0x03 +#define VSOMEIP_APPLICATION_LOST 0x04 +#define VSOMEIP_ROUTING_INFO 0x05 +#define VSOMEIP_REGISTERED_ACK 0x06 #define VSOMEIP_PING 0x0E #define VSOMEIP_PONG 0x0F @@ -123,29 +132,27 @@ #define VSOMEIP_UPDATE_SECURITY_CREDENTIALS 0x27 #define VSOMEIP_DISTRIBUTE_SECURITY_POLICIES 0x28 -#define VSOMEIP_SEND_COMMAND_SIZE 14 +#define VSOMEIP_SEND_COMMAND_SIZE 13 #define VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN 7 #define VSOMEIP_SEND_COMMAND_INSTANCE_POS_MAX 8 -#define VSOMEIP_SEND_COMMAND_FLUSH_POS 9 -#define VSOMEIP_SEND_COMMAND_RELIABLE_POS 10 -#define VSOMEIP_SEND_COMMAND_VALID_CRC_POS 11 -#define VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MIN 12 -#define VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MAX 13 -#define VSOMEIP_SEND_COMMAND_PAYLOAD_POS 14 +#define VSOMEIP_SEND_COMMAND_RELIABLE_POS 9 +#define VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS 10 +#define VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MIN 11 +#define VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MAX 12 +#define VSOMEIP_SEND_COMMAND_PAYLOAD_POS 13 +#define VSOMEIP_ASSIGN_CLIENT_ACK_COMMAND_SIZE 9 #define VSOMEIP_OFFER_SERVICE_COMMAND_SIZE 16 -#define VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE 17 +#define VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE 16 #define VSOMEIP_RELEASE_SERVICE_COMMAND_SIZE 11 #define VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE 16 -#define VSOMEIP_SUBSCRIBE_COMMAND_SIZE 19 +#define VSOMEIP_SUBSCRIBE_COMMAND_SIZE 18 #define VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE 19 #define VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE 19 #define VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE 17 #define VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE 15 -#define VSOMEIP_REGISTER_EVENT_COMMAND_SIZE 15 +#define VSOMEIP_REGISTER_EVENT_COMMAND_SIZE 16 #define VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE 14 -#define VSOMEIP_ID_RESPONSE_COMMAND_SIZE 12 -#define VSOMEIP_ID_REQUEST_COMMAND_SIZE 13 #define VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE 8 #define VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE 11 #define VSOMEIP_REMOVE_SECURITY_POLICY_COMMAND_SIZE 19 @@ -170,7 +177,7 @@ #define VSOMEIP_ROUTING_READY_MESSAGE "@VSOMEIP_ROUTING_READY_MESSAGE@" -namespace vsomeip { +namespace vsomeip_v3 { typedef enum { RIE_ADD_CLIENT = 0x0, @@ -184,7 +191,6 @@ struct service_data_t { instance_t instance_; major_version_t major_; minor_version_t minor_; - bool use_exclusive_proxy_; // only used for requests! bool operator<(const service_data_t &_other) const { return (service_ < _other.service_ @@ -199,27 +205,20 @@ typedef enum { IS_SUBSCRIBING } subscription_state_e; -struct configuration_data_t { -#ifndef _WIN32 - volatile char initialized_; - pthread_mutex_t mutex_; - pid_t pid_; -#endif - unsigned short client_base_; - unsigned short max_clients_; - int max_used_client_ids_index_; - unsigned short max_assigned_client_id_; - unsigned short routing_manager_host_; - // array of used client ids here, pointer to it is kept in utility class -}; - const std::uint32_t MESSAGE_SIZE_UNLIMITED = (std::numeric_limits<std::uint32_t>::max)(); const std::uint32_t QUEUE_SIZE_UNLIMITED = (std::numeric_limits<std::uint32_t>::max)(); +#define VSOMEIP_DEFAULT_NPDU_DEBOUNCING_NANO 2 * 1000 * 1000 +#define VSOMEIP_DEFAULT_NPDU_MAXIMUM_RETENTION_NANO 5 * 1000 * 1000 + const std::uint32_t MAX_RECONNECTS_UNLIMITED = (std::numeric_limits<std::uint32_t>::max)(); +const std::uint32_t ANY_UID = 0xFFFFFFFF; +const std::uint32_t ANY_GID = 0xFFFFFFFF; + +typedef std::pair<std::uint32_t, std::uint32_t> credentials_t; -} // namespace vsomeip +} // namespace vsomeip_v3 -#endif // VSOMEIP_INTERNAL_HPP +#endif // VSOMEIP_V3_INTERNAL_HPP_ diff --git a/implementation/configuration/include/internal_android.hpp b/implementation/configuration/include/internal_android.hpp new file mode 100644 index 0000000..9f770ac --- /dev/null +++ b/implementation/configuration/include/internal_android.hpp @@ -0,0 +1,206 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// 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/. + +#ifndef VSOMEIP_V3_INTERNAL_HPP_ +#define VSOMEIP_V3_INTERNAL_HPP_ + +#include <cstdint> +#include <limits> +#include <vsomeip/primitive_types.hpp> + +#define VSOMEIP_ENV_APPLICATION_NAME "VSOMEIP_APPLICATION_NAME" +#define VSOMEIP_ENV_CONFIGURATION "VSOMEIP_CONFIGURATION" +#define VSOMEIP_ENV_CONFIGURATION_MODULE "VSOMEIP_CONFIGURATION_MODULE" +#define VSOMEIP_ENV_E2E_PROTECTION_MODULE "VSOMEIP_E2E_PROTECTION_MODULE" +#define VSOMEIP_ENV_MANDATORY_CONFIGURATION_FILES "VSOMEIP_MANDATORY_CONFIGURATION_FILES" +#define VSOMEIP_ENV_LOAD_PLUGINS "VSOMEIP_LOAD_PLUGINS" +#define VSOMEIP_ENV_CLIENTSIDELOGGING "VSOMEIP_CLIENTSIDELOGGING" + +#define VSOMEIP_DEFAULT_CONFIGURATION_FILE "/etc/vsomeip.json" +#define VSOMEIP_LOCAL_CONFIGURATION_FILE "./vsomeip.json" +#define VSOMEIP_MANDATORY_CONFIGURATION_FILES "vsomeip_std.json,vsomeip_app.json,vsomeip_plc.json,vsomeip_log.json,vsomeip_security.json,vsomeip_whitelist.json" + +#define VSOMEIP_DEFAULT_CONFIGURATION_FOLDER "/etc/vsomeip" +#define VSOMEIP_DEBUG_CONFIGURATION_FOLDER "/var/opt/public/sin/vsomeip/" +#define VSOMEIP_LOCAL_CONFIGURATION_FOLDER "./vsomeip" + +#define VSOMEIP_BASE_PATH "/storage/" + +#define VSOMEIP_CFG_LIBRARY "libvsomeip_cfg.so" + +#define VSOMEIP_SD_LIBRARY "libvsomeip_sd.so" + +#define VSOMEIP_E2E_LIBRARY "libvsomeip-e2e.so.3" + +#define VSOMEIP_ROUTING_CLIENT 0 + +#define VSOMEIP_CLIENT_UNSET 0xFFFF + +#define VSOMEIP_UNICAST_ADDRESS "127.0.0.1" +#define VSOMEIP_NETMASK "255.255.255.0" + +#define VSOMEIP_DEFAULT_CONNECT_TIMEOUT 100 +#define VSOMEIP_MAX_CONNECT_TIMEOUT 1600 +#define VSOMEIP_DEFAULT_FLUSH_TIMEOUT 1000 + +#define VSOMEIP_DEFAULT_SHUTDOWN_TIMEOUT 5000 + +#define VSOMEIP_DEFAULT_QUEUE_WARN_SIZE 102400 + +#define VSOMEIP_MAX_TCP_CONNECT_TIME 5000 +#define VSOMEIP_MAX_TCP_RESTART_ABORTS 5 + +#define VSOMEIP_DEFAULT_BUFFER_SHRINK_THRESHOLD 5 + +#define VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT 5000 +#define VSOMEIP_DEFAULT_MAX_MISSING_PONGS 3 + +#define VSOMEIP_DEFAULT_UDP_RCV_BUFFER_SIZE 1703936 + +#define VSOMEIP_IO_THREAD_COUNT 2 +#define VSOMEIP_IO_THREAD_NICE_LEVEL 255 + +#define VSOMEIP_MAX_DISPATCHERS 10 +#define VSOMEIP_MAX_DISPATCH_TIME 100 + +#define VSOMEIP_MAX_DESERIALIZER 5 + +#define VSOMEIP_REQUEST_DEBOUNCE_TIME 10 + +#define VSOMEIP_COMMAND_HEADER_SIZE 7 + +#define VSOMEIP_COMMAND_TYPE_POS 0 +#define VSOMEIP_COMMAND_CLIENT_POS 1 +#define VSOMEIP_COMMAND_SIZE_POS_MIN 3 +#define VSOMEIP_COMMAND_SIZE_POS_MAX 6 +#define VSOMEIP_COMMAND_PAYLOAD_POS 7 + +#define VSOMEIP_ASSIGN_CLIENT 0x00 +#define VSOMEIP_ASSIGN_CLIENT_ACK 0x01 +#define VSOMEIP_REGISTER_APPLICATION 0x02 +#define VSOMEIP_DEREGISTER_APPLICATION 0x03 +#define VSOMEIP_APPLICATION_LOST 0x04 +#define VSOMEIP_ROUTING_INFO 0x05 +#define VSOMEIP_REGISTERED_ACK 0x06 + +#define VSOMEIP_PING 0x0E +#define VSOMEIP_PONG 0x0F + +#define VSOMEIP_OFFER_SERVICE 0x10 +#define VSOMEIP_STOP_OFFER_SERVICE 0x11 +#define VSOMEIP_SUBSCRIBE 0x12 +#define VSOMEIP_UNSUBSCRIBE 0x13 +#define VSOMEIP_REQUEST_SERVICE 0x14 +#define VSOMEIP_RELEASE_SERVICE 0x15 +#define VSOMEIP_SUBSCRIBE_NACK 0x16 +#define VSOMEIP_SUBSCRIBE_ACK 0x17 + +#define VSOMEIP_SEND 0x18 +#define VSOMEIP_NOTIFY 0x19 +#define VSOMEIP_NOTIFY_ONE 0x1A + +#define VSOMEIP_REGISTER_EVENT 0x1B +#define VSOMEIP_UNREGISTER_EVENT 0x1C +#define VSOMEIP_ID_RESPONSE 0x1D +#define VSOMEIP_ID_REQUEST 0x1E +#define VSOMEIP_OFFERED_SERVICES_REQUEST 0x1F +#define VSOMEIP_OFFERED_SERVICES_RESPONSE 0x20 +#define VSOMEIP_UNSUBSCRIBE_ACK 0x21 +#define VSOMEIP_RESEND_PROVIDED_EVENTS 0x22 + +#define VSOMEIP_UPDATE_SECURITY_POLICY 0x23 +#define VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE 0x24 +#define VSOMEIP_REMOVE_SECURITY_POLICY 0x25 +#define VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE 0x26 +#define VSOMEIP_UPDATE_SECURITY_CREDENTIALS 0x27 +#define VSOMEIP_DISTRIBUTE_SECURITY_POLICIES 0x28 + +#define VSOMEIP_SEND_COMMAND_SIZE 13 +#define VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN 7 +#define VSOMEIP_SEND_COMMAND_INSTANCE_POS_MAX 8 +#define VSOMEIP_SEND_COMMAND_RELIABLE_POS 9 +#define VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS 10 +#define VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MIN 11 +#define VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MAX 12 +#define VSOMEIP_SEND_COMMAND_PAYLOAD_POS 13 + +#define VSOMEIP_ASSIGN_CLIENT_ACK_COMMAND_SIZE 9 +#define VSOMEIP_OFFER_SERVICE_COMMAND_SIZE 16 +#define VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE 16 +#define VSOMEIP_RELEASE_SERVICE_COMMAND_SIZE 11 +#define VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE 16 +#define VSOMEIP_SUBSCRIBE_COMMAND_SIZE 18 +#define VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE 19 +#define VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE 19 +#define VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE 17 +#define VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE 15 +#define VSOMEIP_REGISTER_EVENT_COMMAND_SIZE 16 +#define VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE 14 +#define VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE 8 +#define VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE 11 +#define VSOMEIP_REMOVE_SECURITY_POLICY_COMMAND_SIZE 19 +#define VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE 11 +#define VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE 11 +#define VSOMEIP_PING_COMMAND_SIZE 7 +#define VSOMEIP_PONG_COMMAND_SIZE 7 +#define VSOMEIP_REGISTER_APPLICATION_COMMAND_SIZE 7 +#define VSOMEIP_DEREGISTER_APPLICATION_COMMAND_SIZE 7 +#define VSOMEIP_REGISTERED_ACK_COMMAND_SIZE 7 + +#include <pthread.h> + +#define VSOMEIP_DATA_ID 0x677D +#define VSOMEIP_DIAGNOSIS_ADDRESS 0x01 + +#define VSOMEIP_DEFAULT_SHM_PERMISSION 0666 +#define VSOMEIP_DEFAULT_UDS_PERMISSIONS 0666 + +#define VSOMEIP_ROUTING_READY_MESSAGE "SOME/IP routing ready." + +namespace vsomeip_v3 { + +typedef enum { + RIE_ADD_CLIENT = 0x0, + RIE_ADD_SERVICE_INSTANCE = 0x1, + RIE_DEL_SERVICE_INSTANCE = 0x2, + RIE_DEL_CLIENT = 0x3, +} routing_info_entry_e; + +struct service_data_t { + service_t service_; + instance_t instance_; + major_version_t major_; + minor_version_t minor_; + + bool operator<(const service_data_t &_other) const { + return (service_ < _other.service_ + || (service_ == _other.service_ + && instance_ < _other.instance_)); + } +}; + +typedef enum { + SUBSCRIPTION_ACKNOWLEDGED, + SUBSCRIPTION_NOT_ACKNOWLEDGED, + IS_SUBSCRIBING +} subscription_state_e; + +const std::uint32_t MESSAGE_SIZE_UNLIMITED = (std::numeric_limits<std::uint32_t>::max)(); + +const std::uint32_t QUEUE_SIZE_UNLIMITED = (std::numeric_limits<std::uint32_t>::max)(); + +#define VSOMEIP_DEFAULT_NPDU_DEBOUNCING_NANO 2 * 1000 * 1000 +#define VSOMEIP_DEFAULT_NPDU_MAXIMUM_RETENTION_NANO 5 * 1000 * 1000 + +const std::uint32_t MAX_RECONNECTS_UNLIMITED = (std::numeric_limits<std::uint32_t>::max)(); + +const std::uint32_t ANY_UID = 0xFFFFFFFF; +const std::uint32_t ANY_GID = 0xFFFFFFFF; + +typedef std::pair<std::uint32_t, std::uint32_t> credentials_t; + +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_INTERNAL_HPP_ diff --git a/implementation/configuration/include/policy.hpp b/implementation/configuration/include/policy.hpp deleted file mode 100644 index c8f649e..0000000 --- a/implementation/configuration/include/policy.hpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// 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/. - -#ifndef VSOMEIP_CFG_POLICY_HPP -#define VSOMEIP_CFG_POLICY_HPP - -#include <memory> -#include <set> - -#include <vsomeip/primitive_types.hpp> - -namespace vsomeip { - -typedef std::set<std::pair<uint32_t, uint32_t>> ranges_t; -typedef std::set<std::pair<ranges_t, ranges_t>> ids_t; - -struct policy { - policy() : allow_who_(false), allow_what_(false) {}; - - ids_t ids_; - bool allow_who_; - - std::set<std::pair<service_t, ids_t>> services_; - std::set<std::pair<service_t, ranges_t>> offers_; - bool allow_what_; -}; - -} // namespace vsomeip - -#endif // VSOMEIP_CFG_POLICY_HPP diff --git a/implementation/configuration/include/service.hpp b/implementation/configuration/include/service.hpp index b33cf72..e0e0c72 100644 --- a/implementation/configuration/include/service.hpp +++ b/implementation/configuration/include/service.hpp @@ -3,14 +3,14 @@ // 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/. -#ifndef VSOMEIP_CFG_SERVICE_HPP -#define VSOMEIP_CFG_SERVICE_HPP +#ifndef VSOMEIP_V3_CFG_SERVICE_HPP +#define VSOMEIP_V3_CFG_SERVICE_HPP #include <memory> #include <vsomeip/primitive_types.hpp> -namespace vsomeip { +namespace vsomeip_v3 { namespace cfg { struct event; @@ -30,12 +30,22 @@ struct service { std::string protocol_; + // [0] = debounce_time + // [1] = retention_time + typedef std::map<method_t, std::array<std::chrono::nanoseconds, 2>> npdu_time_configuration_t; + npdu_time_configuration_t debounce_times_requests_; + npdu_time_configuration_t debounce_times_responses_; + std::shared_ptr<servicegroup> group_; std::map<event_t, std::shared_ptr<event> > events_; std::map<eventgroup_t, std::shared_ptr<eventgroup> > eventgroups_; + + // SOME/IP-TP + std::set<method_t> tp_segment_messages_client_to_service_; + std::set<method_t> tp_segment_messages_service_to_client_; }; } // namespace cfg -} // namespace vsomeip +} // namespace vsomeip_v3 -#endif // VSOMEIP_CFG_SERVICE_HPP +#endif // VSOMEIP_V3_CFG_SERVICE_HPP diff --git a/implementation/configuration/include/service_instance_range.hpp b/implementation/configuration/include/service_instance_range.hpp index bf5f415..a585d7a 100644 --- a/implementation/configuration/include/service_instance_range.hpp +++ b/implementation/configuration/include/service_instance_range.hpp @@ -3,12 +3,12 @@ // 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/. -#ifndef VSOMEIP_CFG_SERVICE_INSTANCE_RANGE_HPP -#define VSOMEIP_CFG_SERVICE_INSTANCE_RANGE_HPP +#ifndef VSOMEIP_V3_CFG_SERVICE_INSTANCE_RANGE_HPP +#define VSOMEIP_V3_CFG_SERVICE_INSTANCE_RANGE_HPP #include <vsomeip/primitive_types.hpp> -namespace vsomeip { +namespace vsomeip_v3 { namespace cfg { struct service_instance_range { @@ -18,7 +18,7 @@ struct service_instance_range { instance_t last_instance_; }; -} -} +} // namespace cfg +} // namespace vsomeip_v3 -#endif // VSOMEIP_CFG_SERVICE_INSTANCE_RANGE_HPP +#endif // VSOMEIP_V3_CFG_SERVICE_INSTANCE_RANGE_HPP diff --git a/implementation/configuration/include/trace.hpp b/implementation/configuration/include/trace.hpp index 3d4e1f4..c9eb8cb 100644 --- a/implementation/configuration/include/trace.hpp +++ b/implementation/configuration/include/trace.hpp @@ -3,8 +3,8 @@ // 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/. -#ifndef CFG_TRACE_HPP_ -#define CFG_TRACE_HPP_ +#ifndef VSOMEIP_V3_CFG_TRACE_HPP_ +#define VSOMEIP_V3_CFG_TRACE_HPP_ #include <string> #include <vector> @@ -12,7 +12,7 @@ #include <vsomeip/primitive_types.hpp> #include <vsomeip/trace.hpp> -namespace vsomeip { +namespace vsomeip_v3 { namespace cfg { struct trace_channel { @@ -29,7 +29,7 @@ struct trace_filter { std::vector<trace_channel_t> channels_; bool is_positive_; bool is_range_; - std::vector<vsomeip::trace::match_t> matches_; + std::vector<vsomeip_v3::trace::match_t> matches_; }; struct trace { @@ -48,6 +48,6 @@ struct trace { }; } // namespace cfg -} // namespace vsomeip +} // namespace vsomeip_v3 -#endif // CFG_TRACE_HPP_ +#endif // VSOMEIP_V3_CFG_TRACE_HPP_ diff --git a/implementation/configuration/include/watchdog.hpp b/implementation/configuration/include/watchdog.hpp index 00fdb69..9fe81ff 100644 --- a/implementation/configuration/include/watchdog.hpp +++ b/implementation/configuration/include/watchdog.hpp @@ -2,10 +2,10 @@ // This Source Code Form is subject to the terms of the Mozilla Public // 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/. -#ifndef VSOMEIP_CFG_WATCHDOG_HPP_ -#define VSOMEIP_CFG_WATCHDOG_HPP_ +#ifndef VSOMEIP_V3_CFG_WATCHDOG_HPP_ +#define VSOMEIP_V3_CFG_WATCHDOG_HPP_ -namespace vsomeip { +namespace vsomeip_v3 { namespace cfg { struct watchdog { @@ -21,6 +21,6 @@ struct watchdog { }; } // namespace cfg -} // namespace vsomeip +} // namespace vsomeip_v3 -#endif /* VSOMEIP_CFG_WATCHDOG_HPP_ */ +#endif // VSOMEIP_V3_CFG_WATCHDOG_HPP_ diff --git a/implementation/configuration/src/configuration_impl.cpp b/implementation/configuration/src/configuration_impl.cpp index b574841..7c0cf6a 100644 --- a/implementation/configuration/src/configuration_impl.cpp +++ b/implementation/configuration/src/configuration_impl.cpp @@ -26,22 +26,21 @@ #include "../include/event.hpp" #include "../include/eventgroup.hpp" #include "../include/service.hpp" -#include "../include/internal.hpp" #include "../../logging/include/logger_impl.hpp" #include "../../routing/include/event.hpp" #include "../../service_discovery/include/defines.hpp" #include "../../utility/include/utility.hpp" #include "../../plugin/include/plugin_manager.hpp" +#include "../../security/include/security.hpp" -VSOMEIP_PLUGIN(vsomeip::cfg::configuration_impl) - -namespace vsomeip { +namespace vsomeip_v3 { namespace cfg { configuration_impl::configuration_impl() - : plugin_impl("vsomeip cfg plugin", 1, plugin_type_e::CONFIGURATION_PLUGIN), + : default_unicast_("local"), is_loaded_(false), is_logging_loaded_(false), + is_overlay_(false), diagnosis_(VSOMEIP_DIAGNOSIS_ADDRESS), diagnosis_mask_(0xFF00), has_console_log_(true), @@ -64,6 +63,7 @@ configuration_impl::configuration_impl() 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<trace>()), watchdog_(std::make_shared<watchdog>()), @@ -71,11 +71,6 @@ configuration_impl::configuration_impl() log_version_interval_(10), permissions_shm_(VSOMEIP_DEFAULT_SHM_PERMISSION), permissions_uds_(VSOMEIP_DEFAULT_UDS_PERMISSIONS), - policy_enabled_(false), - check_credentials_(false), - check_routing_credentials_(false), - allow_remote_clients_(true), - check_whitelist_(false), network_("vsomeip"), e2e_enabled_(false), log_memory_(false), @@ -89,6 +84,10 @@ configuration_impl::configuration_impl() 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) { unicast_ = unicast_.from_string(VSOMEIP_UNICAST_ADDRESS); netmask_ = netmask_.from_string(VSOMEIP_NETMASK); @@ -97,14 +96,16 @@ configuration_impl::configuration_impl() } configuration_impl::configuration_impl(const configuration_impl &_other) - : plugin_impl("vsomeip cfg plugin", 1, plugin_type_e::CONFIGURATION_PLUGIN), - std::enable_shared_from_this<configuration_impl>(_other), + : std::enable_shared_from_this<configuration_impl>(_other), + default_unicast_(_other.default_unicast_), is_loaded_(_other.is_loaded_), is_logging_loaded_(_other.is_logging_loaded_), + is_overlay_(_other.is_overlay_), mandatory_(_other.mandatory_), 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_shm_(VSOMEIP_DEFAULT_SHM_PERMISSION), permissions_uds_(VSOMEIP_DEFAULT_UDS_PERMISSIONS), @@ -113,6 +114,10 @@ configuration_impl::configuration_impl(const configuration_impl &_other) 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_) { applications_.insert(_other.applications_.begin(), _other.applications_.end()); @@ -122,6 +127,7 @@ configuration_impl::configuration_impl(const configuration_impl &_other) unicast_ = _other.unicast_; netmask_ = _other.netmask_; + device_ = _other.device_; diagnosis_ = _other.diagnosis_; diagnosis_mask_ = _other.diagnosis_mask_; @@ -161,15 +167,6 @@ configuration_impl::configuration_impl(const configuration_impl &_other) for (auto i = 0; i < ET_MAX; i++) is_configured_[i] = _other.is_configured_[i]; - policies_ = _other.policies_; - any_client_policies_ = _other.any_client_policies_; - ids_ = _other.ids_; - policy_enabled_ = _other.policy_enabled_; - check_credentials_ = _other.check_credentials_; - check_routing_credentials_ = _other.check_routing_credentials_; - allow_remote_clients_ = _other.allow_remote_clients_; - check_whitelist_ = _other.check_whitelist_; - network_ = _other.network_; configuration_path_ = _other.configuration_path_; @@ -187,7 +184,7 @@ configuration_impl::configuration_impl(const configuration_impl &_other) debounces_ = _other.debounces_; endpoint_queue_limits_ = _other.endpoint_queue_limits_; - offer_acceptance_required_ips_ = _other.offer_acceptance_required_ips_; + sd_acceptance_required_ips_ = _other.sd_acceptance_required_ips_; has_issued_methods_warning_ = _other.has_issued_methods_warning_; has_issued_clients_warning_ = _other.has_issued_clients_warning_; @@ -257,8 +254,8 @@ bool configuration_impl::load(const std::string &_name) { 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; + std::vector<configuration_element> its_mandatory_elements; + std::vector<configuration_element> its_optional_elements; // Dummy initialization; maybe we'll find no logging configuration logger_impl::init(shared_from_this()); @@ -299,17 +296,18 @@ bool configuration_impl::load(const std::string &_name) { VSOMEIP_INFO << "Using configuration folder: \"" << i << "\"."; } - if (policy_enabled_ && check_credentials_) - VSOMEIP_INFO << "Security configuration is active."; - - if (policy_enabled_ && !check_credentials_) - VSOMEIP_INFO << "Security configuration is active but in audit mode (allow all)"; - is_loaded_ = true; return is_loaded_; } +bool +configuration_impl::check_routing_credentials( + client_t _client, uint32_t _uid, uint32_t _gid) const { + return (_client != get_id(routing_host_)) || + security::get()->check_routing_credentials(_client, _uid, _gid); +} + bool configuration_impl::remote_offer_info_add(service_t _service, instance_t _instance, std::uint16_t _port, @@ -327,7 +325,7 @@ bool configuration_impl::remote_offer_info_add(service_t _service, _reliable ? its_service->reliable_ = _port : its_service->unreliable_ = _port; - its_service->unicast_address_ = "local"; + its_service->unicast_address_ = default_unicast_; its_service->multicast_address_ = ""; its_service->multicast_port_ = ILLEGAL_PORT; its_service->protocol_ = "someip"; @@ -406,11 +404,11 @@ bool configuration_impl::remote_offer_info_remove(service_t _service, } void configuration_impl::read_data(const std::set<std::string> &_input, - std::vector<element> &_elements, std::set<std::string> &_failed, + std::vector<configuration_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) { + if (is_mandatory(i) == _mandatory_only) { boost::property_tree::ptree its_tree; try { boost::property_tree::json_parser::read_json(i, its_tree); @@ -430,7 +428,7 @@ void configuration_impl::read_data(const std::set<std::string> &_input, j++) { auto its_file_path = j->path(); if (!boost::filesystem::is_directory(its_file_path)) { - std::string its_name = its_file_path.string(); + const std::string& its_name = its_file_path.string(); if (is_mandatory(its_name) == _mandatory_only) { boost::property_tree::ptree its_tree; try { @@ -448,12 +446,12 @@ void configuration_impl::read_data(const std::set<std::string> &_input, } -bool configuration_impl::load_data(const std::vector<element> &_elements, +bool configuration_impl::load_data(const std::vector<configuration_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) + for (const auto& e : _elements) is_logging_loaded_ = load_logging(e, its_warnings) || is_logging_loaded_; @@ -468,7 +466,7 @@ bool configuration_impl::load_data(const std::vector<element> &_elements, bool has_applications(false); if (_load_mandatory) { // Load mandatory configuration data - for (auto e : _elements) { + for (const auto& e : _elements) { has_routing = load_routing(e) || has_routing; has_applications = load_applications(e) || has_applications; load_network(e); @@ -478,19 +476,19 @@ bool configuration_impl::load_data(const std::vector<element> &_elements, load_endpoint_queue_sizes(e); load_tcp_restart_settings(e); load_permissions(e); - load_policies(e); + load_security(e); load_tracing(e); load_udp_receive_buffer_size(e); - load_security_update_whitelist(e); - load_routing_credentials(e); } } if (_load_optional) { - for (auto e : _elements) { + for (const auto& e : _elements) { load_unicast_address(e); load_netmask(e); + load_device(e); load_service_discovery(e); + load_npdu_default_timings(e); load_services(e); load_internal_services(e); load_clients(e); @@ -498,7 +496,7 @@ bool configuration_impl::load_data(const std::vector<element> &_elements, load_selective_broadcasts_support(e); load_e2e(e); load_debounce(e); - load_offer_acceptance_required(e); + load_sd_acceptance_required(e); } } @@ -506,7 +504,7 @@ bool configuration_impl::load_data(const std::vector<element> &_elements, } bool configuration_impl::load_logging( - const element &_element, std::set<std::string> &_warnings) { + const configuration_element &_element, std::set<std::string> &_warnings) { try { auto its_logging = _element.tree_.get_child("logging"); for (auto i = its_logging.begin(); i != its_logging.end(); ++i) { @@ -601,7 +599,8 @@ bool configuration_impl::load_logging( return true; } -bool configuration_impl::load_routing(const element &_element) { +bool +configuration_impl::load_routing(const configuration_element &_element) { try { auto its_routing = _element.tree_.get_child("routing"); if (is_configured_[ET_ROUTING]) { @@ -617,54 +616,9 @@ bool configuration_impl::load_routing(const element &_element) { return true; } -bool configuration_impl::load_routing_credentials(const element &_element) { - try { - auto its_routing_cred = _element.tree_.get_child("routing-credentials"); - if (is_configured_[ET_ROUTING_CREDENTIALS]) { - VSOMEIP_WARNING << "vSomeIP Security: Multiple definitions of routing-credentials." - << " Ignoring definition from " << _element.name_; - } else { - for (auto i = its_routing_cred.begin(); - i != its_routing_cred.end(); - ++i) { - std::string its_key(i->first); - std::string its_value(i->second.data()); - std::stringstream its_converter; - if (its_key == "uid") { - uint32_t its_uid(0); - if (its_value.find("0x") == 0) { - its_converter << std::hex << its_value; - } else { - its_converter << std::dec << its_value; - } - its_converter >> its_uid; - std::lock_guard<std::mutex> its_lock(routing_credentials_mutex_); - std::get<0>(routing_credentials_) = its_uid; - } else if (its_key == "gid") { - uint32_t its_gid(0); - if (its_value.find("0x") == 0) { - its_converter << std::hex << its_value; - } else { - its_converter << std::dec << its_value; - } - its_converter >> its_gid; - std::lock_guard<std::mutex> its_lock(routing_credentials_mutex_); - std::get<1>(routing_credentials_) = its_gid; - } - } - check_routing_credentials_ = true; - is_configured_[ET_ROUTING_CREDENTIALS] = true; - } - } catch (...) { - return false; - } - return true; -} - - -bool configuration_impl::load_applications(const element &_element) { +bool +configuration_impl::load_applications(const configuration_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(); @@ -680,13 +634,14 @@ bool configuration_impl::load_applications(const element &_element) { 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); + client_t its_id(VSOMEIP_CLIENT_UNSET); std::size_t its_max_dispatchers(VSOMEIP_MAX_DISPATCHERS); std::size_t its_max_dispatch_time(VSOMEIP_MAX_DISPATCH_TIME); std::size_t its_io_thread_count(VSOMEIP_IO_THREAD_COUNT); std::size_t its_request_debounce_time(VSOMEIP_REQUEST_DEBOUNCE_TIME); std::map<plugin_type_e, std::set<std::string>> plugins; int its_io_thread_nice_level(VSOMEIP_IO_THREAD_NICE_LEVEL); + std::string its_overlay; for (auto i = _tree.begin(); i != _tree.end(); ++i) { std::string its_key(i->first); std::string its_value(i->second.data()); @@ -727,42 +682,14 @@ void configuration_impl::load_application_data( its_request_debounce_time = 10000; } } else if (its_key == "plugins") { - for (auto l = i->second.begin(); l != i->second.end(); ++l) { - for (auto n = l->second.begin(); n != l->second.end(); ++n) { - std::string its_inner_key(n->first); - std::string its_inner_value(n->second.data()); - #ifdef _WIN32 - std::string library(its_inner_value); - library += ".dll"; - #else - std::string library("lib"); - library += its_inner_value; - library += ".so"; - #endif - if (its_inner_key == "application_plugin") { - #ifndef _WIN32 - library += "."; - library += std::to_string(std::uint32_t(VSOMEIP_APPLICATION_PLUGIN_VERSION)); - #endif - plugins[plugin_type_e::APPLICATION_PLUGIN].insert(library); - } else if (its_inner_key == "configuration_plugin") { - #ifndef _WIN32 - library += "."; - library += std::to_string(std::uint32_t(VSOMEIP_PRE_CONFIGURATION_PLUGIN_VERSION)); - #endif - plugins[plugin_type_e::PRE_CONFIGURATION_PLUGIN].insert(library); - } else { - VSOMEIP_WARNING << "Unknown plug-in type (" - << its_inner_key << ") configured for client: " - << its_name; - } - } - } + plugins = load_plugins(i->second, its_name); + } else if (its_key == "overlay") { + its_overlay = its_value; } } if (its_name != "") { if (applications_.find(its_name) == applications_.end()) { - if (its_id > 0) { + if (its_id != VSOMEIP_CLIENT_UNSET) { if (!is_configured_client_id(its_id)) { client_identifiers_.insert(its_id); } else { @@ -770,13 +697,14 @@ void configuration_impl::load_application_data( << " client identifier " << std::hex << its_id << ". Ignoring the configuration for application " << its_name; - its_id = 0; + its_id = VSOMEIP_CLIENT_UNSET; } } applications_[its_name] = std::make_tuple(its_id, its_max_dispatchers, its_max_dispatch_time, its_io_thread_count, - its_request_debounce_time, plugins, its_io_thread_nice_level); + its_request_debounce_time, plugins, its_io_thread_nice_level, + its_overlay); } else { VSOMEIP_WARNING << "Multiple configurations for application " << its_name << ". Ignoring a configuration from " @@ -785,9 +713,86 @@ void configuration_impl::load_application_data( } } -void configuration_impl::load_tracing(const element &_element) { +std::map<plugin_type_e, std::set<std::string>> configuration_impl::load_plugins( + const boost::property_tree::ptree &_tree, + const std::string& _application_name) { + std::map<plugin_type_e, std::set<std::string>> its_plugins; + std::string its_name(""); + std::string its_type; + for (auto i = _tree.begin(); i != _tree.end(); ++i) { + bool its_configured[ET_MAX] = { 0 }; + for (auto l = i->second.begin(); l != i->second.end(); ++l) { + std::string its_inner_key(l->first); + std::string its_inner_value(l->second.data()); + + if (its_inner_key == "name") { + if (its_configured[ET_PLUGIN_NAME]) { + VSOMEIP_WARNING << "Multiple definitions of plugins.name." + << " Ignoring definition from " << its_inner_value; + } else { + its_name = its_inner_value; + its_configured[ET_PLUGIN_NAME] = true; + } + } else if (its_inner_key == "type") { + if (its_configured[ET_PLUGIN_TYPE]) { + VSOMEIP_WARNING << "Multiple definitions of plugins.type." + << " Ignoring definition from " << its_inner_value; + } else { + its_type = its_inner_value; + its_configured[ET_PLUGIN_TYPE] = true; + } + } else { + //support old config format (type : name) + plugin_config_data_t its_plugin_data = { + its_inner_value, its_inner_key }; + add_plugin(its_plugins, its_plugin_data, _application_name); + } + } + + if (its_configured[ET_PLUGIN_NAME] && its_configured[ET_PLUGIN_TYPE]) { + plugin_config_data_t its_plugin_data = { + its_name, its_type }; + add_plugin(its_plugins, its_plugin_data, _application_name); + } + } + + return its_plugins; +} + +void configuration_impl::add_plugin(std::map<plugin_type_e, std::set<std::string>> &_plugins, + const plugin_config_data_t &_plugin_data, + const std::string& _application_name) { + +#ifdef _WIN32 + std::string its_library(_plugin_data.name_); + its_library += ".dll"; +#else + std::string its_library("lib"); + its_library += _plugin_data.name_; + its_library += ".so"; +#endif + + if (_plugin_data.type_ == "application_plugin") { +#ifndef _WIN32 + its_library += "."; + its_library += (VSOMEIP_APPLICATION_PLUGIN_VERSION + '0'); +#endif + _plugins[plugin_type_e::APPLICATION_PLUGIN].insert(its_library); + } else if (_plugin_data.type_ == "configuration_plugin") { +#ifndef _WIN32 + its_library += "."; + its_library += (VSOMEIP_PRE_CONFIGURATION_PLUGIN_VERSION + '0'); +#endif + _plugins[plugin_type_e::PRE_CONFIGURATION_PLUGIN].insert(its_library); + } else { + VSOMEIP_WARNING << "Unknown plug-in type (" + << _plugin_data.type_ << ") configured for client: " + << _application_name; + } +} + +void configuration_impl::load_tracing(const configuration_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(); @@ -900,7 +905,7 @@ void configuration_impl::load_trace_filter_expressions( std::shared_ptr<trace_filter> &_filter) { if (_criteria == "services") { for (auto i = _tree.begin(); i != _tree.end(); ++i) { - vsomeip::trace::match_t its_match; + vsomeip_v3::trace::match_t its_match; load_trace_filter_match(i->second, its_match); _filter->matches_.push_back(its_match); } @@ -916,7 +921,7 @@ void configuration_impl::load_trace_filter_expressions( } } else if (_criteria == "matches") { for (auto i = _tree.begin(); i != _tree.end(); ++i) { - vsomeip::trace::match_t its_match; + vsomeip_v3::trace::match_t its_match; load_trace_filter_match(i->second, its_match); if (i->first == "from") { _filter->is_range_ = true; @@ -931,11 +936,11 @@ void configuration_impl::load_trace_filter_expressions( void configuration_impl::load_trace_filter_match( const boost::property_tree::ptree &_data, - vsomeip::trace::match_t &_match) { + vsomeip_v3::trace::match_t &_match) { std::stringstream its_converter; if (_data.size() == 0) { - std::string its_value(_data.data()); + const std::string& its_value(_data.data()); service_t its_service(ANY_SERVICE); if (its_value.find("0x") == 0) { its_converter << std::hex << its_value; @@ -997,10 +1002,10 @@ void configuration_impl::load_trace_filter_match( } } -void configuration_impl::load_unicast_address(const element &_element) { +void configuration_impl::load_unicast_address(const configuration_element &_element) { try { std::string its_value = _element.tree_.get<std::string>("unicast"); - if (is_configured_[ET_UNICAST]) { + if (!is_overlay_ && is_configured_[ET_UNICAST]) { VSOMEIP_WARNING << "Multiple definitions for unicast." "Ignoring definition from " << _element.name_; } else { @@ -1012,10 +1017,10 @@ void configuration_impl::load_unicast_address(const element &_element) { } } -void configuration_impl::load_netmask(const element &_element) { +void configuration_impl::load_netmask(const configuration_element &_element) { try { std::string its_value = _element.tree_.get<std::string>("netmask"); - if (is_configured_[ET_NETMASK]) { + if (!is_overlay_ && is_configured_[ET_NETMASK]) { VSOMEIP_WARNING << "Multiple definitions for netmask." "Ignoring definition from " << _element.name_; } else { @@ -1027,10 +1032,25 @@ void configuration_impl::load_netmask(const element &_element) { } } -void configuration_impl::load_network(const element &_element) { +void configuration_impl::load_device(const configuration_element &_element) { + try { + std::string its_value = _element.tree_.get<std::string>("device"); + if (!is_overlay_ && is_configured_[ET_DEVICE]) { + VSOMEIP_WARNING << "Multiple definitions for device." + "Ignoring definition from " << _element.name_; + } else { + device_ = its_value; + is_configured_[ET_DEVICE] = true; + } + } catch (...) { + // intentionally left empty! + } +} + +void configuration_impl::load_network(const configuration_element &_element) { try { std::string its_value(_element.tree_.get<std::string>("network")); - if (is_configured_[ET_NETWORK]) { + if (!is_overlay_ && is_configured_[ET_NETWORK]) { VSOMEIP_WARNING << "Multiple definitions for network." "Ignoring definition from " << _element.name_; } else { @@ -1042,10 +1062,10 @@ void configuration_impl::load_network(const element &_element) { } } -void configuration_impl::load_diagnosis_address(const element &_element) { +void configuration_impl::load_diagnosis_address(const configuration_element &_element) { try { std::string its_value = _element.tree_.get<std::string>("diagnosis"); - if (is_configured_[ET_DIAGNOSIS]) { + if (!is_overlay_ && is_configured_[ET_DIAGNOSIS]) { VSOMEIP_WARNING << "Multiple definitions for diagnosis." "Ignoring definition from " << _element.name_; } else { @@ -1060,7 +1080,7 @@ void configuration_impl::load_diagnosis_address(const element &_element) { is_configured_[ET_DIAGNOSIS] = true; } std::string its_mask = _element.tree_.get<std::string>("diagnosis_mask"); - if (is_configured_[ET_DIAGNOSIS_MASK]) { + if (!is_overlay_ && is_configured_[ET_DIAGNOSIS_MASK]) { VSOMEIP_WARNING << "Multiple definitions for diagnosis_mask." "Ignoring definition from " << _element.name_; } else { @@ -1074,12 +1094,20 @@ void configuration_impl::load_diagnosis_address(const element &_element) { its_converter >> diagnosis_mask_; is_configured_[ET_DIAGNOSIS_MASK] = true; } + if (is_configured_[ET_DIAGNOSIS] && is_configured_[ET_DIAGNOSIS_MASK] + && (static_cast<std::uint16_t>(diagnosis_ << 8) & diagnosis_mask_) + != static_cast<std::uint16_t>(diagnosis_ << 8)) { + VSOMEIP_WARNING << "Diagnosis mask masks bits of diagnosis prefix! " + "Client IDs will start at 0x" << std::hex << + (static_cast<std::uint16_t>(diagnosis_ << 8) & diagnosis_mask_) + << " not at 0x" << static_cast<std::uint16_t>(diagnosis_ << 8); + } } catch (...) { // intentionally left empty } } -void configuration_impl::load_shutdown_timeout(const element &_element) { +void configuration_impl::load_shutdown_timeout(const configuration_element &_element) { const std::string shutdown_timeout("shutdown_timeout"); try { if (_element.tree_.get_child_optional(shutdown_timeout)) { @@ -1105,7 +1133,7 @@ void configuration_impl::load_shutdown_timeout(const element &_element) { } void configuration_impl::load_service_discovery( - const element &_element) { + const configuration_element &_element) { try { auto its_service_discovery = _element.tree_.get_child("service-discovery"); for (auto i = its_service_discovery.begin(); @@ -1114,7 +1142,7 @@ void configuration_impl::load_service_discovery( std::string its_value(i->second.data()); std::stringstream its_converter; if (its_key == "enable") { - if (is_configured_[ET_SERVICE_DISCOVERY_ENABLE]) { + if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_ENABLE]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.enabled." " Ignoring definition from " << _element.name_; } else { @@ -1122,7 +1150,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_ENABLE] = true; } } else if (its_key == "multicast") { - if (is_configured_[ET_SERVICE_DISCOVERY_MULTICAST]) { + if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_MULTICAST]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.multicast." " Ignoring definition from " << _element.name_; } else { @@ -1130,7 +1158,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_MULTICAST] = true; } } else if (its_key == "port") { - if (is_configured_[ET_SERVICE_DISCOVERY_PORT]) { + if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_PORT]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.port." " Ignoring definition from " << _element.name_; } else { @@ -1143,7 +1171,7 @@ void configuration_impl::load_service_discovery( } } } else if (its_key == "protocol") { - if (is_configured_[ET_SERVICE_DISCOVERY_PROTOCOL]) { + if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_PROTOCOL]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.protocol." " Ignoring definition from " << _element.name_; } else { @@ -1151,7 +1179,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_PROTOCOL] = true; } } else if (its_key == "initial_delay_min") { - if (is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MIN]) { + if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MIN]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.initial_delay_min." " Ignoring definition from " << _element.name_; } else { @@ -1160,7 +1188,7 @@ void configuration_impl::load_service_discovery( 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]) { + if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MAX]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.initial_delay_max." " Ignoring definition from " << _element.name_; } else { @@ -1169,7 +1197,7 @@ void configuration_impl::load_service_discovery( 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]) { + if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_REPETITION_BASE_DELAY]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.repetition_base_delay." " Ignoring definition from " << _element.name_; } else { @@ -1178,7 +1206,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_REPETITION_BASE_DELAY] = true; } } else if (its_key == "repetitions_max") { - if (is_configured_[ET_SERVICE_DISCOVERY_REPETITION_MAX]) { + if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_REPETITION_MAX]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.repetition_max." " Ignoring definition from " << _element.name_; } else { @@ -1191,18 +1219,22 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_REPETITION_MAX] = true; } } else if (its_key == "ttl") { - if (is_configured_[ET_SERVICE_DISCOVERY_TTL]) { + if (!is_overlay_ && 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; + if (sd_ttl_ == 0) { + VSOMEIP_WARNING << "TTL=0 is not allowed. Using default (" + << std::dec << VSOMEIP_SD_DEFAULT_TTL << ")"; + 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]) { + if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_CYCLIC_OFFER_DELAY]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.cyclic_offer_delay." " Ignoring definition from " << _element.name_; } else { @@ -1211,7 +1243,7 @@ void configuration_impl::load_service_discovery( 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]) { + if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_REQUEST_RESPONSE_DELAY]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.request_response_delay." " Ignoring definition from " << _element.name_; } else { @@ -1220,7 +1252,7 @@ void configuration_impl::load_service_discovery( 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]) { + if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_OFFER_DEBOUNCE_TIME]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.offer_debounce." " Ignoring definition from " << _element.name_; } else { @@ -1229,7 +1261,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_OFFER_DEBOUNCE_TIME] = true; } } else if (its_key == "ttl_factor_offers") { - if (is_configured_[ET_SERVICE_DISCOVERY_TTL_FACTOR_OFFERS]) { + if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_TTL_FACTOR_OFFERS]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.ttl_factor_offers." " Ignoring definition from " << _element.name_; } else { @@ -1237,7 +1269,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_TTL_FACTOR_OFFERS] = true; } } else if (its_key == "ttl_factor_subscriptions") { - if (is_configured_[ET_SERVICE_DISCOVERY_TTL_FACTOR_SUBSCRIPTIONS]) { + if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_TTL_FACTOR_SUBSCRIPTIONS]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.ttl_factor_subscriptions." " Ignoring definition from " << _element.name_; } else { @@ -1288,12 +1320,51 @@ void configuration_impl::load_delays( } } -void configuration_impl::load_services(const element &_element) { +void configuration_impl::load_npdu_default_timings(const configuration_element &_element) { + const std::string ndt("npdu-default-timings"); + const std::string dreq("debounce-time-request"); + const std::string dres("debounce-time-response"); + const std::string rreq("max-retention-time-request"); + const std::string rresp("max-retention-time-response"); + try { + if (_element.tree_.get_child_optional(ndt)) { + if (!is_overlay_ && is_configured_[ET_NPDU_DEFAULT_TIMINGS]) { + VSOMEIP_WARNING << "Multiple definitions of " << ndt + << " Ignoring definition from " << _element.name_; + } else { + for (const auto& e : _element.tree_.get_child(ndt)) { + std::chrono::nanoseconds its_time(0); + try { + its_time = std::chrono::nanoseconds( + std::strtoull(e.second.data().c_str(), NULL, 10) + * 1000000); + } catch (const std::exception& e) { + continue; + } + if (e.first.data() == dreq) { + npdu_default_debounce_requ_ = its_time; + } else if (e.first.data() == dres) { + npdu_default_debounce_resp_ = its_time; + } else if (e.first.data() == rreq) { + npdu_default_max_retention_requ_ = its_time; + } else if (e.first.data() == rresp) { + npdu_default_max_retention_resp_ = its_time; + } + } + is_configured_[ET_NPDU_DEFAULT_TIMINGS] = true; + } + } + } catch (...) { + // intentionally left empty + } +} + +void configuration_impl::load_services(const configuration_element &_element) { std::lock_guard<std::mutex> its_lock(services_mutex_); 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"); + load_service(i->second, default_unicast_); } catch (...) { try { auto its_servicegroups = _element.tree_.get_child("servicegroups"); @@ -1308,7 +1379,7 @@ void configuration_impl::load_services(const element &_element) { void configuration_impl::load_servicegroup( const boost::property_tree::ptree &_tree) { try { - std::string its_unicast_address("local"); + std::string its_unicast_address(default_unicast_); for (auto i = _tree.begin(); i != _tree.end(); ++i) { std::string its_key(i->first); @@ -1393,6 +1464,10 @@ void configuration_impl::load_service( load_event(its_service, i->second); } else if (its_key == "eventgroups") { load_eventgroup(its_service, i->second); + } else if (its_key == "debounce-times") { + load_npdu_debounce_times_configuration(its_service, i->second); + } else if (its_key == "someip-tp") { + load_someip_tp(its_service, i->second); } else { // Trim "its_value" if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { @@ -1427,6 +1502,40 @@ void configuration_impl::load_service( if (use_magic_cookies) { magic_cookies_[its_service->unicast_address_].insert(its_service->reliable_); } + + if (its_service->unicast_address_ == default_unicast_) { + // local services + if(its_service->reliable_ != ILLEGAL_PORT) { + services_by_ip_port_[unicast_.to_string()] + [its_service->reliable_] + [its_service->service_] = its_service; + } + if (its_service->unreliable_ != ILLEGAL_PORT) { + services_by_ip_port_[unicast_.to_string()] + [its_service->unreliable_] + [its_service->service_] = its_service; + // This is necessary as all udp server endpoints listen on + // INADDR_ANY instead of a specific address + services_by_ip_port_[boost::asio::ip::address_v4::any().to_string()] + [its_service->unreliable_] + [its_service->service_] = its_service; + services_by_ip_port_[boost::asio::ip::address_v6::any().to_string()] + [its_service->unreliable_] + [its_service->service_] = its_service; + } + } else { + // remote services + if (its_service->reliable_ != ILLEGAL_PORT) { + services_by_ip_port_[its_service->unicast_address_] + [its_service->reliable_] + [its_service->service_] = its_service; + } + if (its_service->unreliable_ != ILLEGAL_PORT) { + services_by_ip_port_[its_service->unicast_address_] + [its_service->unreliable_] + [its_service->service_] = its_service; + } + } } } catch (...) { // Intentionally left empty @@ -1439,7 +1548,7 @@ void configuration_impl::load_event( for (auto i = _tree.begin(); i != _tree.end(); ++i) { event_t its_event_id(0); bool its_is_field(false); - bool its_is_reliable(false); + reliability_type_e its_reliability(reliability_type_e::RT_UNKNOWN); for (auto j = i->second.begin(); j != i->second.end(); ++j) { std::string its_key(j->first); @@ -1455,7 +1564,10 @@ void configuration_impl::load_event( } else if (its_key == "is_field") { its_is_field = (its_value == "true"); } else if (its_key == "is_reliable") { - its_is_reliable = (its_value == "true"); + if (its_value == "true") + its_reliability = reliability_type_e::RT_RELIABLE; + else + its_reliability = reliability_type_e::RT_UNRELIABLE; } } @@ -1467,8 +1579,23 @@ void configuration_impl::load_event( << _service->instance_ << "." << its_event_id << "]"; } else { + // If event reliability type was not configured, + if (its_reliability == reliability_type_e::RT_UNKNOWN) { + if (_service->reliable_ != ILLEGAL_PORT) { + its_reliability = reliability_type_e::RT_RELIABLE; + } else if (_service->unreliable_ != ILLEGAL_PORT) { + its_reliability = reliability_type_e::RT_UNRELIABLE; + } + VSOMEIP_WARNING << "Reliability type for event [" + << std::hex << _service->service_ << "." + << _service->instance_ << "." + << its_event_id << "] was not configured Using : " + << ((its_reliability == reliability_type_e::RT_RELIABLE) + ? "RT_RELIABLE" : "RT_UNRELIABLE"); + } + std::shared_ptr<event> its_event = std::make_shared<event>( - its_event_id, its_is_field, its_is_reliable); + its_event_id, its_is_field, its_reliability); _service->events_[its_event_id] = its_event; } } @@ -1534,7 +1661,7 @@ void configuration_impl::load_eventgroup( its_event = find_event->second; } else { its_event = std::make_shared<event>(its_event_id, - false, false); + false, reliability_type_e::RT_UNRELIABLE); } if (its_event) { its_event->groups_.push_back(its_eventgroup); @@ -1552,7 +1679,7 @@ void configuration_impl::load_eventgroup( } } -void configuration_impl::load_internal_services(const element &_element) { +void configuration_impl::load_internal_services(const configuration_element &_element) { try { auto optional = _element.tree_.get_child_optional("internal_services"); if (!optional) { @@ -1623,7 +1750,7 @@ void configuration_impl::load_internal_services(const element &_element) { } } -void configuration_impl::load_clients(const element &_element) { +void configuration_impl::load_clients(const configuration_element &_element) { try { auto its_clients = _element.tree_.get_child("clients"); for (auto i = its_clients.begin(); i != its_clients.end(); ++i) @@ -1731,7 +1858,7 @@ std::pair<uint16_t,uint16_t> configuration_impl::load_client_port_range( return its_port_range; } -void configuration_impl::load_watchdog(const element &_element) { +void configuration_impl::load_watchdog(const configuration_element &_element) { try { auto its_service_discovery = _element.tree_.get_child("watchdog"); for (auto i = its_service_discovery.begin(); @@ -1771,36 +1898,34 @@ void configuration_impl::load_watchdog(const element &_element) { } } -void configuration_impl::load_payload_sizes(const element &_element) { +void configuration_impl::load_payload_sizes(const configuration_element &_element) { const std::string payload_sizes("payload-sizes"); const std::string max_local_payload_size("max-payload-size-local"); const std::string buffer_shrink_threshold("buffer-shrink-threshold"); const std::string max_reliable_payload_size("max-payload-size-reliable"); + const std::string max_unreliable_payload_size("max-payload-size-unreliable"); try { - if (_element.tree_.get_child_optional(max_local_payload_size)) { - auto mpsl = _element.tree_.get_child(max_local_payload_size); - std::string s(mpsl.data()); - try { - // add 16 Byte for the SOME/IP header - max_local_message_size_ = static_cast<std::uint32_t>(std::stoul( - s.c_str(), NULL, 10) + 16); - } catch (const std::exception &e) { - VSOMEIP_ERROR<< __func__ << ": " << max_local_payload_size - << " " << e.what(); - } - } - if (_element.tree_.get_child_optional(max_reliable_payload_size)) { - auto mpsl = _element.tree_.get_child(max_reliable_payload_size); - std::string s(mpsl.data()); - try { - // add 16 Byte for the SOME/IP header - max_reliable_message_size_ = static_cast<std::uint32_t>(std::stoul( - s.c_str(), NULL, 10) + 16); - } catch (const std::exception &e) { - VSOMEIP_ERROR<< __func__ << ": " << max_reliable_payload_size - << " " << e.what(); + for (const auto& s : { max_local_payload_size, + max_reliable_payload_size, max_unreliable_payload_size }) { + if (_element.tree_.get_child_optional(s)) { + const std::string size_str(_element.tree_.get_child(s).data()); + try { + // add 16 Byte for the SOME/IP header + const std::uint32_t its_size = static_cast<std::uint32_t>( + std::stoul(size_str.c_str(), NULL, 10) + 16); + if (s == max_local_payload_size) { + max_local_message_size_ = its_size; + } else if (s == max_reliable_payload_size) { + max_reliable_message_size_ = its_size; + } else if (s == max_unreliable_payload_size) { + max_unreliable_message_size_ = its_size; + } + } catch (const std::exception &e) { + VSOMEIP_ERROR<< __func__ << ": " << s << " " << e.what(); + } } } + if (_element.tree_.get_child_optional(buffer_shrink_threshold)) { auto bst = _element.tree_.get_child(buffer_shrink_threshold); std::string s(bst.data()); @@ -1841,9 +1966,8 @@ void configuration_impl::load_payload_sizes(const element &_element) { 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); + 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(); } @@ -1881,12 +2005,24 @@ void configuration_impl::load_payload_sizes(const element &_element) { << "local message distribution."; max_local_message_size_ = max_reliable_message_size_; } + if (max_local_message_size_ != 0 + && max_unreliable_message_size_ != 0 + && max_unreliable_message_size_ > max_local_message_size_) { + VSOMEIP_WARNING << max_local_payload_size << " (" + << max_local_message_size_ - 16 << ") is configured" + << " smaller than " << max_unreliable_payload_size << " (" + << max_unreliable_message_size_ - 16 << "). " + << max_local_payload_size << " will be increased to " + << max_unreliable_message_size_ - 16 << " to ensure " + << "local message distribution."; + max_local_message_size_ = max_unreliable_message_size_; + } } } catch (...) { } } -void configuration_impl::load_permissions(const element &_element) { +void configuration_impl::load_permissions(const configuration_element &_element) { const std::string file_permissions("file-permissions"); try { if (_element.tree_.get_child_optional(file_permissions)) { @@ -1911,644 +2047,34 @@ void configuration_impl::load_permissions(const element &_element) { } } -void configuration_impl::load_selective_broadcasts_support(const element &_element) { +void configuration_impl::load_security(const configuration_element &_element) { + security::get()->load(_element); +} + +void configuration_impl::load_selective_broadcasts_support(const configuration_element &_element) { try { 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); std::string its_value(i->second.data()); - std::stringstream its_converter; - if (its_key == "address") { - supported_selective_addresses.insert(its_value); - } + supported_selective_addresses.insert(its_value); } } catch (...) { } } - - -void configuration_impl::load_policies(const element &_element) { -#ifdef _WIN32 - return; -#endif - try { - 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 { - check_credentials_ = false; - } - } else if (its_security->first == "allow_remote_clients") { - if (its_security->second.data() == "true") { - allow_remote_clients_ = true; - } else { - allow_remote_clients_ = false; - } - } else 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); - } - } - } - } catch (...) { - } -} - -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 has_been_inserted(false); - 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(ILLEGAL_CLIENT); - client_t lastClient(ILLEGAL_CLIENT); - for (auto n = i->second.begin(); - n != i->second.end(); ++n) { - if (n->first == "first") { - std::stringstream its_converter; - std::string value = n->second.data(); - its_converter << std::hex << value; - 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; - } - } - if (firstClient < lastClient && lastClient != ANY_CLIENT) { - uint32_t overrides(0); - for (client_t c = firstClient; c <= lastClient; ++c) { - if (find_client_id_policy(c)) { - overrides++; - } - } - if (overrides) { - VSOMEIP_WARNING << std::hex << "Security configuration: " - << "for client range 0x" << firstClient - << " - 0x" << lastClient - << " will be ignored as it would override an already existing policy of " - << std::dec << overrides << " clients!"; - } else { - std::lock_guard<std::mutex> its_lock(policies_mutex_); - policies_[std::make_pair(firstClient, lastClient)] = policy; - } - has_been_inserted = true; - } 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 (find_client_id_policy(client)) { - VSOMEIP_WARNING << std::hex << "Security configuration for client " - << client - << " will be ignored as it would overwrite an already existing policy!"; - } else { - std::lock_guard<std::mutex> its_lock(policies_mutex_); - policies_[std::make_pair(client, client)] = policy; - } - has_been_inserted= true; - } - } - } else if (i->first == "credentials") { - std::pair<uint32_t, uint32_t> its_uid_range, its_gid_range; - ranges_t its_uid_ranges, its_gid_ranges; - - bool has_uid(false), has_gid(false); - bool has_uid_range(false), has_gid_range(false); - for (auto n = i->second.begin(); - n != i->second.end(); ++n) { - std::string its_key(n->first); - std::string its_value(n->second.data()); - if (its_key == "uid") { - if(n->second.data().empty()) { - load_ranges(n->second, its_uid_ranges); - has_uid_range = true; - } else { - if (its_value != "any") { - uint32_t its_uid; - std::stringstream its_converter; - its_converter << std::dec << its_value; - its_converter >> its_uid; - std::get<0>(its_uid_range) = its_uid; - std::get<1>(its_uid_range) = its_uid; - } else { - std::get<0>(its_uid_range) = 0; - std::get<1>(its_uid_range) = 0xFFFFFFFF; - } - has_uid = true; - } - } else if (its_key == "gid") { - if(n->second.data().empty()) { - load_ranges(n->second, its_gid_ranges); - has_gid_range = true; - } else { - if (its_value != "any") { - uint32_t its_gid; - std::stringstream its_converter; - its_converter << std::dec << its_value; - its_converter >> its_gid; - std::get<0>(its_gid_range) = its_gid; - std::get<1>(its_gid_range) = its_gid; - } else { - std::get<0>(its_gid_range) = 0; - std::get<1>(its_gid_range) = 0xFFFFFFFF; - } - has_gid = true; - } - } else if (its_key == "allow" || its_key == "deny") { - policy->allow_who_ = (its_key == "allow"); - load_credential(n->second, policy->ids_); - } - } - - if (has_uid && has_gid) { - std::set<std::pair<uint32_t, uint32_t>> its_uids, its_gids; - - its_uids.insert(its_uid_range); - its_gids.insert(its_gid_range); - - policy->allow_who_ = true; - policy->ids_.insert(std::make_pair(its_uids, its_gids)); - } - if (has_uid_range && has_gid_range) { - policy->allow_who_ = true; - policy->ids_.insert(std::make_pair(its_uid_ranges, its_gid_ranges)); - } - } else if (i->first == "allow") { - if (allow_deny_set) { - VSOMEIP_WARNING << "vSomeIP Security: Security configuration: \"allow\" tag overrides " - << "already set \"deny\" tag. " - << "Either \"deny\" or \"allow\" is allowed."; - } - allow_deny_set = true; - policy->allow_what_ = 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; - ids_t its_instance_method_ranges; - 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") { // legacy definition for instances - ranges_t its_instance_ranges; - ranges_t its_method_ranges; - std::string value = k->second.data(); - if (value != "any") { - its_converter << std::hex << value; - its_converter >> instance; - if (instance != 0x0) { - its_instance_ranges.insert(std::make_pair(instance, instance)); - its_method_ranges.insert(std::make_pair(0x01, 0xFFFF)); - } - } else { - its_instance_ranges.insert(std::make_pair(0x01, 0xFFFF)); - its_method_ranges.insert(std::make_pair(0x01, 0xFFFF)); - } - its_instance_method_ranges.insert(std::make_pair(its_instance_ranges, its_method_ranges)); - } else if (k->first == "instances") { // new instances definition - for (auto p = k->second.begin(); p != k->second.end(); ++p) { - ranges_t its_instance_ranges; - ranges_t its_method_ranges; - for (auto m = p->second.begin(); m != p->second.end(); ++m) { - if (m->first == "ids") { - load_instance_ranges(m->second, its_instance_ranges); - } else if (m->first == "methods") { - load_instance_ranges(m->second, its_method_ranges); - } - if (!its_instance_ranges.empty() && !its_method_ranges.empty()) { - its_instance_method_ranges.insert(std::make_pair(its_instance_ranges, its_method_ranges)); - } - } - } - if (its_instance_method_ranges.empty()) { - ranges_t its_legacy_instance_ranges; - ranges_t its_legacy_method_ranges; - its_legacy_method_ranges.insert(std::make_pair(0x01, 0xFFFF)); - // try to only load instance ranges with any method to be allowed - load_instance_ranges(k->second, its_legacy_instance_ranges); - if (!its_legacy_instance_ranges.empty() && !its_legacy_method_ranges.empty()) { - its_instance_method_ranges.insert(std::make_pair(its_legacy_instance_ranges, - its_legacy_method_ranges)); - } - } - } - } - if (service != 0x0 && !its_instance_method_ranges.empty()) { - policy->services_.insert( - std::make_pair(service, its_instance_method_ranges)); - } - } - } else if (l->first == "offers") { - for (auto n = l->second.begin(); n != l->second.end(); ++n) { - service_t service = 0x0; - instance_t instance = 0x0; - ranges_t its_instance_ranges; - 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") { // legacy definition for instances - std::string value = k->second.data(); - if (value != "any") { - its_converter << std::hex << value; - its_converter >> instance; - if (instance != 0x0) { - its_instance_ranges.insert(std::make_pair(instance, instance)); - } - } else { - its_instance_ranges.insert(std::make_pair(0x01, 0xFFFF)); - } - } else if (k->first == "instances") { // new instances definition - load_instance_ranges(k->second, its_instance_ranges); - } - } - if (service != 0x0 && !its_instance_ranges.empty()) { - policy->offers_.insert( - std::make_pair(service, its_instance_ranges)); - } - } - } - } - } else if (i->first == "deny") { - if (allow_deny_set) { - VSOMEIP_WARNING << "vSomeIP Security: Security configuration: \"deny\" tag overrides " - << "already set \"allow\" tag. " - << "Either \"deny\" or \"allow\" is allowed."; - } - allow_deny_set = true; - policy->allow_what_ = 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; - ids_t its_instance_method_ranges; - 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") { // legacy definition for instances - ranges_t its_instance_ranges; - ranges_t its_method_ranges; - std::string value = k->second.data(); - if (value != "any") { - its_converter << std::hex << value; - its_converter >> instance; - if (instance != 0x0) { - its_instance_ranges.insert(std::make_pair(instance, instance)); - its_method_ranges.insert(std::make_pair(0x01, 0xFFFF)); - } - } else { - its_instance_ranges.insert(std::make_pair(0x01, 0xFFFF)); - its_method_ranges.insert(std::make_pair(0x01, 0xFFFF)); - } - its_instance_method_ranges.insert(std::make_pair(its_instance_ranges, its_method_ranges)); - } else if (k->first == "instances") { // new instances definition - for (auto p = k->second.begin(); p != k->second.end(); ++p) { - ranges_t its_instance_ranges; - ranges_t its_method_ranges; - for (auto m = p->second.begin(); m != p->second.end(); ++m) { - if (m->first == "ids") { - load_instance_ranges(m->second, its_instance_ranges); - } else if (m->first == "methods") { - load_instance_ranges(m->second, its_method_ranges); - } - if (!its_instance_ranges.empty() && !its_method_ranges.empty()) { - its_instance_method_ranges.insert(std::make_pair(its_instance_ranges, its_method_ranges)); - } - } - } - if (its_instance_method_ranges.empty()) { - ranges_t its_legacy_instance_ranges; - ranges_t its_legacy_method_ranges; - its_legacy_method_ranges.insert(std::make_pair(0x01, 0xFFFF)); - // try to only load instance ranges with any method to be allowed - load_instance_ranges(k->second, its_legacy_instance_ranges); - if (!its_legacy_instance_ranges.empty() && !its_legacy_method_ranges.empty()) { - its_instance_method_ranges.insert(std::make_pair(its_legacy_instance_ranges, - its_legacy_method_ranges)); - } - } - } - } - if (service != 0x0 && !its_instance_method_ranges.empty()) { - policy->services_.insert( - std::make_pair(service, its_instance_method_ranges)); - } - } - } - if (l->first == "offers") { - for (auto n = l->second.begin(); n != l->second.end(); ++n) { - service_t service = 0x0; - instance_t instance = 0x0; - ranges_t its_instance_ranges; - 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") { // legacy definition for instances - std::string value = k->second.data(); - if (value != "any") { - its_converter << std::hex << value; - its_converter >> instance; - if (instance != 0x0) { - its_instance_ranges.insert(std::make_pair(instance, instance)); - } - } else { - its_instance_ranges.insert(std::make_pair(0x01, 0xFFFF)); - } - } else if (k->first == "instances") { // new instances definition - load_instance_ranges(k->second, its_instance_ranges); - } - } - if (service != 0x0 && !its_instance_ranges.empty()) { - policy->offers_.insert( - std::make_pair(service, its_instance_ranges)); - } - } - } - } - } - } - - if (!has_been_inserted) { - std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_); - any_client_policies_.push_back(policy); - } -} - -void configuration_impl::load_credential( - const boost::property_tree::ptree &_tree, ids_t &_ids) { - for (auto i = _tree.begin(); i != _tree.end(); ++i) { - ranges_t its_uid_ranges, its_gid_ranges; - for (auto j = i->second.begin(); j != i->second.end(); ++j) { - std::string its_key(j->first); - if (its_key == "uid") { - load_ranges(j->second, its_uid_ranges); - } else if (its_key == "gid") { - load_ranges(j->second, its_gid_ranges); - } else { - VSOMEIP_WARNING << "vSomeIP Security: Security configuration: " - << "Malformed credential (contains illegal key \"" - << its_key << "\""; - } - } - - _ids.insert(std::make_pair(its_uid_ranges, its_gid_ranges)); - } -} - -void configuration_impl::load_security_update_whitelist(const element &_element) { -#ifdef _WIN32 - return; -#endif - try { - auto optional = _element.tree_.get_child_optional("security-update-whitelist"); - if (!optional) { - return; - } - auto found_whitelist = _element.tree_.get_child("security-update-whitelist"); - for (auto its_whitelist = found_whitelist.begin(); - its_whitelist != found_whitelist.end(); ++its_whitelist) { - - if (its_whitelist->first == "uids") { - { - std::lock_guard<std::mutex> its_lock(uid_whitelist_mutex_); - load_ranges(its_whitelist->second, uid_whitelist_); - } - } else if (its_whitelist->first == "services") { - { - std::lock_guard<std::mutex> its_lock(service_interface_whitelist_mutex_); - load_service_ranges(its_whitelist->second, service_interface_whitelist_); - } - } else if (its_whitelist->first == "check-whitelist") { - if (its_whitelist->second.data() == "true") { - check_whitelist_ = true; - } else { - check_whitelist_ = false; - } - } - } - } catch (...) { - } -} - -void configuration_impl::load_ranges( - const boost::property_tree::ptree &_tree, ranges_t &_range) { - ranges_t its_ranges; - for (auto i = _tree.begin(); i != _tree.end(); ++i) { - auto its_data = i->second; - if (!its_data.data().empty()) { - uint32_t its_id; - std::stringstream its_converter; - its_converter << std::dec << its_data.data(); - its_converter >> its_id; - its_ranges.insert(std::make_pair(its_id, its_id)); - } else { - uint32_t its_first, its_last; - bool has_first(false), has_last(false); - for (auto j = its_data.begin(); j != its_data.end(); ++j) { - std::string its_key(j->first); - std::string its_value(j->second.data()); - if (its_key == "first") { - if (its_value == "max") { - its_first = 0xFFFFFFFF; - } else { - std::stringstream its_converter; - its_converter << std::dec << j->second.data(); - its_converter >> its_first; - } - has_first = true; - } else if (its_key == "last") { - if (its_value == "max") { - its_last = 0xFFFFFFFF; - } else { - std::stringstream its_converter; - its_converter << std::dec << j->second.data(); - its_converter >> its_last; - } - has_last = true; - } else { - VSOMEIP_WARNING << "vSomeIP Security: Security configuration: " - << " Malformed range. Contains illegal key (" - << its_key << ")"; - } - } - - if (has_first && has_last) { - its_ranges.insert(std::make_pair(its_first, its_last)); - } - } - } - - _range = its_ranges; -} - -void configuration_impl::load_instance_ranges( - const boost::property_tree::ptree &_tree, ranges_t &_range) { - ranges_t its_ranges; - std::string key(_tree.data()); - if (key == "any") { - its_ranges.insert(std::make_pair(0x01, 0xFFFF)); - _range = its_ranges; - return; - } - for (auto i = _tree.begin(); i != _tree.end(); ++i) { - auto its_data = i->second; - if (!its_data.data().empty()) { - uint32_t its_id = 0x0; - std::stringstream its_converter; - its_converter << std::hex << its_data.data(); - its_converter >> its_id; - if (its_id != 0x0) { - its_ranges.insert(std::make_pair(its_id, its_id)); - } - } else { - uint32_t its_first, its_last; - bool has_first(false), has_last(false); - for (auto j = its_data.begin(); j != its_data.end(); ++j) { - std::string its_key(j->first); - std::string its_value(j->second.data()); - if (its_key == "first") { - if (its_value == "max") { - its_first = 0xFFFF; - } else { - std::stringstream its_converter; - its_converter << std::hex << j->second.data(); - its_converter >> its_first; - } - has_first = true; - } else if (its_key == "last") { - if (its_value == "max") { - its_last = 0xFFFF; - } else { - std::stringstream its_converter; - its_converter << std::hex << j->second.data(); - its_converter >> its_last; - } - has_last = true; - } else { - VSOMEIP_WARNING << "vSomeIP Security: Security configuration: " - << " Malformed range. Contains illegal key (" - << its_key << ")"; - } - } - - if (has_first && has_last) { - if( its_last > its_first) { - its_ranges.insert(std::make_pair(its_first, its_last)); - } - } - } - } - - _range = its_ranges; -} - -void configuration_impl::load_service_ranges( - const boost::property_tree::ptree &_tree, std::set<std::pair<service_t, service_t>> &_ranges) { - std::set<std::pair<service_t, service_t>> its_ranges; - std::string key(_tree.data()); - if (key == "any") { - its_ranges.insert(std::make_pair(0x01, 0xFFFF)); - _ranges = its_ranges; - return; - } - for (auto i = _tree.begin(); i != _tree.end(); ++i) { - auto its_data = i->second; - if (!its_data.data().empty()) { - service_t its_id = 0x0; - std::stringstream its_converter; - its_converter << std::hex << its_data.data(); - its_converter >> its_id; - if (its_id != 0x0) { - its_ranges.insert(std::make_pair(its_id, its_id)); - } - } else { - service_t its_first, its_last; - bool has_first(false), has_last(false); - for (auto j = its_data.begin(); j != its_data.end(); ++j) { - std::string its_key(j->first); - std::string its_value(j->second.data()); - if (its_key == "first") { - if (its_value == "max") { - its_first = 0xFFFF; - } else { - std::stringstream its_converter; - its_converter << std::hex << j->second.data(); - its_converter >> its_first; - } - has_first = true; - } else if (its_key == "last") { - if (its_value == "max") { - its_last = 0xFFFF; - } else { - std::stringstream its_converter; - its_converter << std::hex << j->second.data(); - its_converter >> its_last; - } - has_last = true; - } else { - VSOMEIP_WARNING << "vSomeIP Security: Security interface whitelist configuration: " - << " Malformed range. Contains illegal key (" - << its_key << ")"; - } - } - - if (has_first && has_last) { - if( its_last >= its_first) { - its_ranges.insert(std::make_pair(its_first, its_last)); - } - } - } - } - - _ranges = its_ranges; -} - /////////////////////////////////////////////////////////////////////////////// // 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"); + its_magic_cookies_.erase(default_unicast_); //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()); + its_magic_cookies_[get_unicast_address().to_string()].insert( + magic_cookies_[default_unicast_].begin(), + magic_cookies_[default_unicast_].end()); magic_cookies_.clear(); magic_cookies_ = its_magic_cookies_; } @@ -2592,11 +2118,15 @@ const boost::asio::ip::address& configuration_impl::get_netmask() const { return netmask_; } -unsigned short configuration_impl::get_diagnosis_address() const { +const std::string &configuration_impl::get_device() const { + return device_; +} + +diagnosis_t configuration_impl::get_diagnosis_address() const { return diagnosis_; } -std::uint16_t configuration_impl::get_diagnosis_mask() const { +diagnosis_t configuration_impl::get_diagnosis_mask() const { return diagnosis_mask_; } @@ -2636,7 +2166,7 @@ std::string configuration_impl::get_unicast_address(service_t _service, its_unicast_address = its_service->unicast_address_; } - if (its_unicast_address == "local" || its_unicast_address == "") { + if (its_unicast_address == default_unicast_ || its_unicast_address == "") { its_unicast_address = get_unicast_address().to_string(); } return its_unicast_address; @@ -2664,6 +2194,50 @@ uint16_t configuration_impl::get_unreliable_port(service_t _service, return its_unreliable; } +void configuration_impl::get_configured_timing_requests( + service_t _service, std::string _ip_target, + std::uint16_t _port_target, method_t _method, + std::chrono::nanoseconds *_debounce_time, + std::chrono::nanoseconds *_max_retention_time) const { + if (_debounce_time == nullptr || _max_retention_time == nullptr) { + return; + } + service *its_service = find_service_by_ip_port(_service, _ip_target, + _port_target); + if (its_service) { + auto find_method = its_service->debounce_times_requests_.find(_method); + if (find_method != its_service->debounce_times_requests_.end()) { + *_debounce_time = find_method->second[0]; + *_max_retention_time = find_method->second[1]; + return; + } + } + *_debounce_time = npdu_default_debounce_requ_; + *_max_retention_time = npdu_default_max_retention_requ_; +} + +void configuration_impl::get_configured_timing_responses( + service_t _service, std::string _ip_service, + std::uint16_t _port_service, method_t _method, + std::chrono::nanoseconds *_debounce_time, + std::chrono::nanoseconds *_max_retention_time) const { + if (_debounce_time == nullptr || _max_retention_time == nullptr) { + return; + } + service *its_service = find_service_by_ip_port(_service, _ip_service, + _port_service); + if (its_service) { + auto find_method = its_service->debounce_times_responses_.find(_method); + if (find_method != its_service->debounce_times_responses_.end()) { + *_debounce_time = find_method->second[0]; + *_max_retention_time = find_method->second[1]; + return; + } + } + *_debounce_time = npdu_default_debounce_resp_; + *_max_retention_time = npdu_default_max_retention_resp_; +} + bool configuration_impl::is_someip(service_t _service, instance_t _instance) const { auto its_service = find_service(_service, _instance); @@ -2708,6 +2282,7 @@ bool configuration_impl::get_client_port( if (!is_configured) { // Neither specific not generic configurarion available, // use dynamic port configuration! + _client_port = 0; return true; } @@ -2739,7 +2314,7 @@ const std::string & configuration_impl::get_routing_host() const { } client_t configuration_impl::get_id(const std::string &_name) const { - client_t its_client = 0; + client_t its_client(VSOMEIP_CLIENT_UNSET); auto found_application = applications_.find(_name); if (found_application != applications_.end()) { @@ -2813,8 +2388,8 @@ std::set<std::pair<service_t, instance_t> > configuration_impl::get_remote_services() const { std::lock_guard<std::mutex> its_lock(services_mutex_); std::set<std::pair<service_t, instance_t> > its_remote_services; - for (auto i : services_) { - for (auto j : i.second) { + for (const auto& i : services_) { + for (const auto& j : i.second) { if (is_remote(j.second)) { its_remote_services.insert(std::make_pair(i.first, j.first)); } @@ -2825,7 +2400,7 @@ configuration_impl::get_remote_services() const { bool configuration_impl::is_mandatory(const std::string &_name) const { std::set<std::string> its_candidates; - for (auto m : mandatory_) { + for (const auto& m : mandatory_) { if (m.size() <= _name.size()) { its_candidates.insert(m); } @@ -2834,7 +2409,7 @@ bool configuration_impl::is_mandatory(const std::string &_name) const { if (its_candidates.empty()) return false; - for (auto c : its_candidates) { + for (const auto& c : its_candidates) { if (std::equal(c.rbegin(), c.rend(), _name.rbegin())) { return true; } @@ -2879,8 +2454,8 @@ void configuration_impl::trim(std::string &_s) { ); } -bool configuration_impl::is_remote(std::shared_ptr<service> _service) const { - return (_service->unicast_address_ != "local" && +bool configuration_impl::is_remote(const std::shared_ptr<service>& _service) const { + return (_service->unicast_address_ != default_unicast_ && _service->unicast_address_ != "" && _service->unicast_address_ != unicast_.to_string() && _service->unicast_address_ != VSOMEIP_UNICAST_ADDRESS); @@ -2945,23 +2520,39 @@ bool configuration_impl::find_port(uint16_t &_port, uint16_t _remote, bool _reli return is_configured; } -bool configuration_impl::is_event_reliable(service_t _service, +reliability_type_e +configuration_impl::get_event_reliability(service_t _service, instance_t _instance, event_t _event) const { std::lock_guard<std::mutex> its_lock(services_mutex_); - bool is_reliable(false); + reliability_type_e its_reliability(reliability_type_e::RT_UNKNOWN); auto its_service = find_service_unlocked(_service, _instance); if (its_service) { auto its_event = its_service->events_.find(_event); if (its_event != its_service->events_.end()) { - return its_event->second->is_reliable_; - } else { - if (its_service->reliable_ != ILLEGAL_PORT && - its_service->unreliable_ == ILLEGAL_PORT) { - is_reliable = true; + its_reliability = its_event->second->reliability_; + } + } + return its_reliability; +} + +reliability_type_e +configuration_impl::get_service_reliability(service_t _service, + instance_t _instance) const { + std::lock_guard<std::mutex> its_lock(services_mutex_); + reliability_type_e its_reliability(reliability_type_e::RT_UNKNOWN); + auto its_service = find_service_unlocked(_service, _instance); + if (its_service) { + if (its_service->reliable_ != ILLEGAL_PORT) { + if (its_service->unreliable_ != ILLEGAL_PORT) { + its_reliability = reliability_type_e::RT_BOTH; + } else { + its_reliability = reliability_type_e::RT_RELIABLE; } + } else { + its_reliability = reliability_type_e::RT_UNRELIABLE; } } - return is_reliable; + return its_reliability; } std::shared_ptr<service> configuration_impl::find_service(service_t _service, @@ -2983,6 +2574,22 @@ std::shared_ptr<service> configuration_impl::find_service_unlocked(service_t _se return its_service; } +service* configuration_impl::find_service_by_ip_port( + service_t _service, const std::string& _ip, std::uint16_t _port) const { + service *its_service(0); + auto find_ip = services_by_ip_port_.find(_ip); + if(find_ip != services_by_ip_port_.end()) { + auto find_port = find_ip->second.find(_port); + if(find_port != find_ip->second.end()) { + auto find_service = find_port->second.find(_service); + if(find_service != find_port->second.end()) { + its_service = find_service->second.get(); + } + } + } + return its_service; +} + std::shared_ptr<eventgroup> configuration_impl::find_eventgroup( service_t _service, instance_t _instance, eventgroup_t _eventgroup) const { @@ -3036,6 +2643,11 @@ std::uint32_t configuration_impl::get_max_message_size_reliable( VSOMEIP_MAX_TCP_MESSAGE_SIZE) : max_reliable_message_size_; } +std::uint32_t configuration_impl::get_max_message_size_unreliable() const { + return (max_unreliable_message_size_ == 0) ? + MESSAGE_SIZE_UNLIMITED : max_unreliable_message_size_; +} + std::uint32_t configuration_impl::get_buffer_shrink_threshold() const { return buffer_shrink_threshold_; } @@ -3087,11 +2699,11 @@ const std::string & configuration_impl::get_sd_protocol() const { return sd_protocol_; } -int32_t configuration_impl::get_sd_initial_delay_min() const { +uint32_t configuration_impl::get_sd_initial_delay_min() const { return sd_initial_delay_min_; } -int32_t configuration_impl::get_sd_initial_delay_max() const { +uint32_t configuration_impl::get_sd_initial_delay_max() const { return sd_initial_delay_max_; } @@ -3144,420 +2756,6 @@ 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::is_audit_mode_enabled() const { - return check_credentials_; -} - -bool configuration_impl::check_credentials(client_t _client, uint32_t _uid, - uint32_t _gid) { - if (!policy_enabled_) { - return true; - } - - std::vector<std::shared_ptr<policy> > its_policies; - bool has_id(false); - auto found_policy = find_client_id_policy(_client); - if (found_policy) { - its_policies.push_back(found_policy); - } else { - std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_); - its_policies = any_client_policies_; - } - - for (const auto &p : its_policies) { - for (auto its_credential : p->ids_) { - bool has_uid(false), has_gid(false); - for (auto its_range : std::get<0>(its_credential)) { - if (std::get<0>(its_range) <= _uid && _uid <= std::get<1>(its_range)) { - has_uid = true; - break; - } - } - for (auto its_range : std::get<1>(its_credential)) { - if (std::get<0>(its_range) <= _gid && _gid <= std::get<1>(its_range)) { - has_gid = true; - break; - } - } - - if (has_uid && has_gid) { - has_id = true; - break; - } - } - - if ((has_id && p->allow_who_) || (!has_id && !p->allow_who_)) { - if (!store_client_to_uid_gid_mapping(_client,_uid, _gid)) { - std::string security_mode_text = "!"; - if (!check_credentials_) { - security_mode_text = " but will be allowed due to audit mode is active!"; - } - - VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client - << " with UID/GID=" << std::dec << _uid << "/" << _gid - << " : Check credentials failed as existing credentials would be overwritten" - << security_mode_text; - - return !check_credentials_; - } - store_uid_gid_to_client_mapping(_uid, _gid, _client); - return true; - } - } - - std::string security_mode_text = " ~> Skip!"; - if (!check_credentials_) { - security_mode_text = " but will be allowed due to audit mode is active!"; - } - VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client - << " with UID/GID=" << std::dec << _uid << "/" << _gid - << " : Check credentials failed" << security_mode_text; - - - return !check_credentials_; -} - -bool configuration_impl::is_client_allowed(client_t _client, service_t _service, - instance_t _instance, method_t _method, bool _is_request_service) const { - if (!policy_enabled_) { - return true; - } - - uint32_t its_uid(0xffffffff), its_gid(0xffffffff); - bool must_apply(true); - std::vector<std::shared_ptr<policy> > its_policies; - auto found_policy = find_client_id_policy(_client); - if (found_policy) - its_policies.push_back(found_policy); - else { - must_apply = false; - { - std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_); - its_policies = any_client_policies_; - } - - std::lock_guard<std::mutex> its_lock(ids_mutex_); - auto found_id = ids_.find(_client); - if (found_id != ids_.end()) { - its_uid = found_id->second.first; - its_gid = found_id->second.second; - } else { - std::string security_mode_text = " ~> Skip!"; - if (!check_credentials_) { - security_mode_text = " but will be allowed due to audit mode is active!"; - } - VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client - << " : Cannot determine uid/gid. Therefore it isn't allowed to communicate to service/instance " - << _service << "/" << _instance - << security_mode_text; - - return !check_credentials_; - } - } - - for (const auto &p : its_policies) { - bool has_uid(false), has_gid(false), has_service(false), has_instance_id(false), has_method_id(false); - if (must_apply) { - has_uid = has_gid = p->allow_who_; - } else { - for (auto its_credential : p->ids_) { - has_uid = has_gid = false; - for (auto its_range : std::get<0>(its_credential)) { - if (std::get<0>(its_range) <= its_uid && its_uid <= std::get<1>(its_range)) { - has_uid = true; - break; - } - } - for (auto its_range : std::get<1>(its_credential)) { - if (std::get<0>(its_range) <= its_gid && its_gid <= std::get<1>(its_range)) { - has_gid = true; - break; - } - } - - if (has_uid && has_gid) - break; - } - } - - for (auto its_offer : p->services_) { - if (std::get<0>(its_offer) == _service) { - for (auto its_ids : std::get<1>(its_offer)) { - has_service = has_instance_id = has_method_id = false; - for (auto its_instance_range : std::get<0>(its_ids)) { - if (std::get<0>(its_instance_range) <= _instance && _instance <= std::get<1>(its_instance_range)) { - has_instance_id = true; - break; - } - } - if (!_is_request_service) { - for (auto its_method_range : std::get<1>(its_ids)) { - if (std::get<0>(its_method_range) <= _method && _method <= std::get<1>(its_method_range)) { - has_method_id = true; - break; - } - } - } else { - // handle VSOMEIP_REQUEST_SERVICE - has_method_id = true; - } - - if (has_instance_id && has_method_id) { - has_service = true; - break; - } - } - if (has_service) - break; - } - } - - if ((has_uid && has_gid && p->allow_who_) || ((!has_uid || !has_gid) && !p->allow_who_)) { - if (p->allow_what_) { - // allow policy - if (has_service) { - return true; - } - } else { - // deny policy - // allow client if the service / instance / !ANY_METHOD was not found - if ((!has_service && (_method != ANY_METHOD)) - // allow client if the service / instance / ANY_METHOD was not found - // and it is a "deny nothing" policy - || (!has_service && (_method == ANY_METHOD) && p->services_.empty())) { - return true; - } - } - } - } - - std::string security_mode_text = " ~> Skip!"; - if (!check_credentials_) { - security_mode_text = " but will be allowed due to audit mode is active!"; - } - - VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client - << " with UID/GID=" << std::dec << its_uid << "/" << its_gid - << " : Isn't allowed to communicate with service/instance/(method / event) " << std::hex - << _service << "/" << _instance << "/" << _method - << security_mode_text; - - return !check_credentials_; -} - -bool configuration_impl::is_offer_allowed(client_t _client, service_t _service, - instance_t _instance) const { - if (!policy_enabled_) { - return true; - } - - uint32_t its_uid(0xffffffff), its_gid(0xffffffff); - bool must_apply(true); - std::vector<std::shared_ptr<policy> > its_policies; - auto found_policy = find_client_id_policy(_client); - if (found_policy) - its_policies.push_back(found_policy); - else { - must_apply = false; - { - std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_); - its_policies = any_client_policies_; - } - - std::lock_guard<std::mutex> its_lock(ids_mutex_); - auto found_id = ids_.find(_client); - if (found_id != ids_.end()) { - its_uid = found_id->second.first; - its_gid = found_id->second.second; - } else { - std::string audit_mode_text = " ~> Skip offer!"; - if (!check_credentials_) { - audit_mode_text = " but will be allowed due to audit mode is active!"; - } - - VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client - << " : Cannot determine uid/gid. Therefore it isn't allowed to offer service/instance " - << _service << "/" << _instance << audit_mode_text; - - return !check_credentials_; - } - } - - for (const auto &p : its_policies) { - bool has_uid(false), has_gid(false), has_offer(false); - if (must_apply) { - has_uid = has_gid = p->allow_who_; - } else { - for (auto its_credential : p->ids_) { - has_uid = has_gid = false; - for (auto its_range : std::get<0>(its_credential)) { - if (std::get<0>(its_range) <= its_uid && its_uid <= std::get<1>(its_range)) { - has_uid = true; - break; - } - } - for (auto its_range : std::get<1>(its_credential)) { - if (std::get<0>(its_range) <= its_gid && its_gid <= std::get<1>(its_range)) { - has_gid = true; - break; - } - } - - if (has_uid && has_gid) - break; - } - } - - for (auto its_offer : p->offers_) { - has_offer = false; - if (std::get<0>(its_offer) == _service) { - for (auto its_instance_range : std::get<1>(its_offer)) { - if (std::get<0>(its_instance_range) <= _instance && _instance <= std::get<1>(its_instance_range)) { - has_offer = true; - break; - } - } - if (has_offer) - break; - } - } - - if ((has_uid && has_gid && p->allow_who_) || ((!has_uid || !has_gid) && !p->allow_who_)) { - if (p->allow_what_ == has_offer) { - return true; - } - } - } - - std::string security_mode_text = " ~> Skip offer!"; - if (!check_credentials_) { - security_mode_text = " but will be allowed due to audit mode is active!"; - } - - VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client - << " with UID/GID=" << std::dec << its_uid << "/" << its_gid - << " isn't allowed to offer service/instance " << std::hex - << _service << "/" << _instance - << security_mode_text; - - - return !check_credentials_; -} - -bool configuration_impl::store_client_to_uid_gid_mapping(client_t _client, - uint32_t _uid, uint32_t _gid) { - { - // store the client -> (uid, gid) mapping - std::lock_guard<std::mutex> its_lock(ids_mutex_); - auto found_client = ids_.find(_client); - if (found_client != ids_.end()) { - if (found_client->second != std::make_pair(_uid, _gid)) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" - << std::hex << _client << " with UID/GID=" - << std::dec << _uid << "/" << _gid << " : Overwriting existing credentials UID/GID=" - << std::dec << std::get<0>(found_client->second) << "/" - << std::get<1>(found_client->second); - found_client->second = std::make_pair(_uid, _gid); - return true; - } - } else { - ids_[_client] = std::make_pair(_uid, _gid); - } - return true; - } -} - -bool configuration_impl::get_client_to_uid_gid_mapping(client_t _client, std::pair<uint32_t, uint32_t> &_uid_gid) { - { - // get the UID / GID of the client - std::lock_guard<std::mutex> its_lock(ids_mutex_); - if (ids_.find(_client) != ids_.end()) { - _uid_gid = ids_[_client]; - return true; - } - return false; - } -} - -bool configuration_impl::remove_client_to_uid_gid_mapping(client_t _client) { - std::pair<uint32_t, uint32_t> its_uid_gid; - bool client_removed(false); - bool uid_gid_removed(false); - { - std::lock_guard<std::mutex> its_lock(ids_mutex_); - auto found_client = ids_.find(_client); - if (found_client != ids_.end()) { - its_uid_gid = found_client->second; - ids_.erase(found_client); - client_removed = true; - } - } - { - std::lock_guard<std::mutex> its_lock(uid_to_clients_mutex_); - if (client_removed) { - auto found_uid_gid = uid_to_clients_.find(its_uid_gid); - if (found_uid_gid != uid_to_clients_.end()) { - auto its_client = found_uid_gid->second.find(_client); - if (its_client != found_uid_gid->second.end()) { - found_uid_gid->second.erase(its_client); - if (found_uid_gid->second.empty()) { - uid_to_clients_.erase(found_uid_gid); - } - uid_gid_removed = true; - } - } - } else { - for (auto its_uid_gid = uid_to_clients_.begin(); - its_uid_gid != uid_to_clients_.end(); ++its_uid_gid) { - auto its_client = its_uid_gid->second.find(_client); - if (its_client != its_uid_gid->second.end()) { - its_uid_gid->second.erase(its_client); - if (its_uid_gid->second.empty()) { - uid_to_clients_.erase(its_uid_gid); - } - uid_gid_removed = true; - break; - } - } - } - } - return (client_removed && uid_gid_removed); -} - -void configuration_impl::store_uid_gid_to_client_mapping(uint32_t _uid, uint32_t _gid, - client_t _client) { - { - // store the uid gid to clients mapping - std::lock_guard<std::mutex> its_lock(uid_to_clients_mutex_); - std::set<client_t> mapped_clients; - if (uid_to_clients_.find(std::make_pair(_uid, _gid)) != uid_to_clients_.end()) { - mapped_clients = uid_to_clients_[std::make_pair(_uid, _gid)]; - mapped_clients.insert(_client); - uid_to_clients_[std::make_pair(_uid, _gid)] = mapped_clients; - } else { - mapped_clients.insert(_client); - uid_to_clients_[std::make_pair(_uid, _gid)] = mapped_clients; - } - } -} - -bool configuration_impl::get_uid_gid_to_client_mapping(std::pair<uint32_t, uint32_t> _uid_gid, - std::set<client_t> &_clients) { - { - // get the clients corresponding to uid, gid - std::lock_guard<std::mutex> its_lock(uid_to_clients_mutex_); - if (uid_to_clients_.find(_uid_gid) != uid_to_clients_.end()) { - _clients = uid_to_clients_[_uid_gid]; - return true; - } - return false; - } -} - std::map<plugin_type_e, std::set<std::string>> configuration_impl::get_plugins( const std::string &_name) const { std::map<plugin_type_e, std::set<std::string>> result; @@ -3578,7 +2776,7 @@ bool configuration_impl::is_e2e_enabled() const { return e2e_enabled_; } -void configuration_impl::load_e2e(const element &_element) { +void configuration_impl::load_e2e(const configuration_element &_element) { #ifdef _WIN32 return; #endif @@ -3614,15 +2812,10 @@ void configuration_impl::load_e2e_protected(const boost::property_tree::ptree &_ service_t service_id(0); event_t event_id(0); - uint16_t crc_offset(0); - uint8_t data_id_mode(0); - uint16_t data_length(0); - uint16_t data_id_nibble_offset(12); // data id nibble behind 4 bit counter value - uint16_t counter_offset(8); // counter field behind CRC8 + e2e::custom_parameters_t custom_parameters; for (auto l = _tree.begin(); l != _tree.end(); ++l) { std::stringstream its_converter; - uint16_t tmp; if (l->first == "data_id" && data_id == 0) { std::string value = l->second.data(); if (value.size() > 1 && value[0] == '0' && value[1] == 'x') { @@ -3655,28 +2848,8 @@ void configuration_impl::load_e2e_protected(const boost::property_tree::ptree &_ std::string value = l->second.data(); its_converter << value; its_converter >> profile; - } else if (l->first == "crc_offset") { - std::string value = l->second.data(); - its_converter << value; - its_converter >> crc_offset; - } else if (l->first == "counter_offset") { - std::string value = l->second.data(); - its_converter << value; - its_converter >> counter_offset; - } else if (l->first == "data_id_mode") { - std::string value = l->second.data(); - its_converter << value; - its_converter >> tmp; - data_id_mode = static_cast<uint8_t>(tmp); - } else if (l->first == "data_id_nibble_offset") { - std::string value = l->second.data(); - its_converter << value; - its_converter >> data_id_nibble_offset; - } - else if (l->first == "data_length") { - std::string value = l->second.data(); - its_converter << value; - its_converter >> data_length; + } else { + custom_parameters[l->first.data()] = l->second.data(); } } e2e_configuration_[std::make_pair(service_id, event_id)] = std::make_shared<cfg::e2e>( @@ -3685,11 +2858,7 @@ void configuration_impl::load_e2e_protected(const boost::property_tree::ptree &_ profile, service_id, event_id, - crc_offset, - data_id_mode, - data_length, - data_id_nibble_offset, - counter_offset + std::move(custom_parameters) ); } @@ -3780,7 +2949,8 @@ configuration_impl::get_endpoint_queue_limit_local() const { return endpoint_queue_limit_local_; } -void configuration_impl::load_endpoint_queue_sizes(const element &_element) { +void +configuration_impl::load_endpoint_queue_sizes(const configuration_element &_element) { const std::string endpoint_queue_limits("endpoint-queue-limits"); const std::string endpoint_queue_limit_external("endpoint-queue-limit-external"); const std::string endpoint_queue_limit_local("endpoint-queue-limit-local"); @@ -3838,13 +3008,13 @@ void configuration_impl::load_endpoint_queue_sizes(const element &_element) { const std::string port("port"); const std::string queue_size_limit("queue-size-limit"); - for (const auto i : _element.tree_.get_child(endpoint_queue_limits)) { + for (const auto& i : _element.tree_.get_child(endpoint_queue_limits)) { 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 (const auto j : i.second.get_child(ports)) { + for (const auto& j : i.second.get_child(ports)) { if (!j.second.get_child_optional(port) || !j.second.get_child_optional(queue_size_limit)) { @@ -3878,7 +3048,8 @@ void configuration_impl::load_endpoint_queue_sizes(const element &_element) { } } -void configuration_impl::load_debounce(const element &_element) { +void +configuration_impl::load_debounce(const configuration_element &_element) { try { auto its_debounce = _element.tree_.get_child("debounce"); for (auto i = its_debounce.begin(); i != its_debounce.end(); ++i) { @@ -3888,8 +3059,8 @@ void configuration_impl::load_debounce(const element &_element) { } } -void configuration_impl::load_service_debounce( - const boost::property_tree::ptree &_tree) { +void +configuration_impl::load_service_debounce(const boost::property_tree::ptree &_tree) { service_t its_service(0); instance_t its_instance(0); std::map<event_t, std::shared_ptr<debounce>> its_debounces; @@ -4034,25 +3205,146 @@ void configuration_impl::load_event_debounce_ignore( } } -void configuration_impl::load_offer_acceptance_required( - const element &_element) { - const std::string oar("offer_acceptance_required"); +void +configuration_impl::load_sd_acceptance_required( + const configuration_element &_element) { + const std::string sar("sd_acceptance_required"); try { - std::lock_guard<std::mutex> its_lock(offer_acceptance_required_ips_mutex_); - if (_element.tree_.get_child_optional(oar)) { - if (is_configured_[ET_OFFER_ACCEPTANCE_REQUIRED]) { - VSOMEIP_WARNING << "Multiple definitions of " << oar + std::lock_guard<std::mutex> its_lock(sd_acceptance_required_ips_mutex_); + if (_element.tree_.get_child_optional(sar)) { + if (is_configured_[ET_SD_ACCEPTANCE_REQUIRED]) { + VSOMEIP_WARNING << "Multiple definitions of " << sar << " Ignoring definition from " << _element.name_; } else { - for (const auto& ipe : _element.tree_.get_child(oar)) { + for (const auto& ipe : _element.tree_.get_child(sar)) { boost::system::error_code ec; boost::asio::ip::address its_address = boost::asio::ip::address::from_string(ipe.first.data(), ec); if (!its_address.is_unspecified()) { - offer_acceptance_required_ips_[its_address] = ipe.second.data(); + sd_acceptance_required_ips_[{its_address, ANY_PORT}] = ipe.second.data(); } } - is_configured_[ET_OFFER_ACCEPTANCE_REQUIRED] = true; + is_configured_[ET_SD_ACCEPTANCE_REQUIRED] = true; + } + } + } catch (...) { + // intentionally left empty + } +} + +bool configuration_impl::load_npdu_debounce_times_configuration( + const std::shared_ptr<service>& _service, + const boost::property_tree::ptree &_tree) { + bool is_loaded(true); + try { + for (const auto& i : _tree) { + const std::string its_key(i.first); + if (its_key == "requests") { + if (!load_npdu_debounce_times_for_service(_service, true, i.second)) { + is_loaded = false; + } + } else if (its_key == "responses") { + if (!load_npdu_debounce_times_for_service(_service, false, i.second)) { + is_loaded = false; + } + } + } + } catch (...) { + is_loaded = false; + } + return is_loaded; +} + +bool configuration_impl::load_npdu_debounce_times_for_service( + const std::shared_ptr<service>& _service, bool _is_request, + const boost::property_tree::ptree &_tree) { + const std::string dtime("debounce-time"); + const std::string rtime("maximum-retention-time"); + + bool is_loaded(true); + try { + std::stringstream its_converter; + for (const auto& i : _tree) { + const std::string its_method_str(i.first.data()); + if (its_method_str.size()) { + method_t its_method = 0xFFFF; + if (its_method_str.size() > 1 && its_method_str[0] == '0' + && its_method_str[1] == 'x') { + its_converter << std::hex << its_method_str; + } else { + its_converter << std::dec << its_method_str; + } + its_converter >> its_method; + its_converter.str(""); + its_converter.clear(); + + std::chrono::nanoseconds its_debounce_time( + npdu_default_debounce_requ_); + std::chrono::nanoseconds its_retention_time( + npdu_default_max_retention_requ_); + for (const auto& j : i.second) { + const std::string& key = j.first; + const std::uint64_t value = std::strtoull( + j.second.data().c_str(), + NULL, 10) * 1000000; + if (key == dtime) { + its_debounce_time = std::chrono::nanoseconds(value); + } else if (key == rtime) { + its_retention_time = std::chrono::nanoseconds(value); + } + } + if (_is_request) { + _service->debounce_times_requests_[its_method] + = {its_debounce_time, its_retention_time}; + } else { + _service->debounce_times_responses_[its_method] + = { its_debounce_time, its_retention_time}; + } + } + } + } catch (...) { + is_loaded = false; + } + return is_loaded; +} + +void configuration_impl::load_someip_tp( + const std::shared_ptr<service>& _service, + const boost::property_tree::ptree &_tree) { + try { + for (const auto& i : _tree) { + const std::string its_key(i.first); + if (its_key == "client-to-service") { + load_someip_tp_for_service(_service, i.second, true); + } else if (its_key == "service-to-client") { + load_someip_tp_for_service(_service, i.second, false); + } + } + } catch (...) { + // intentionally left empty + } +} + +void configuration_impl::load_someip_tp_for_service( + const std::shared_ptr<service>& _service, + const boost::property_tree::ptree &_tree, bool _is_request) { + try { + std::stringstream its_converter; + for (const auto& method : _tree) { + method_t its_method = 0xFFFF; + const std::string its_value(method.second.data()); + 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_method; + its_converter.str(""); + its_converter.clear(); + if (_is_request) { + _service->tp_segment_messages_client_to_service_.insert(its_method); + } else { + _service->tp_segment_messages_service_to_client_.insert(its_method); } } } catch (...) { @@ -4060,7 +3352,8 @@ void configuration_impl::load_offer_acceptance_required( } } -void configuration_impl::load_udp_receive_buffer_size(const element &_element) { +void +configuration_impl::load_udp_receive_buffer_size(const configuration_element &_element) { const std::string urbs("udp-receive-buffer-size"); try { if (_element.tree_.get_child_optional(urbs)) { @@ -4098,7 +3391,8 @@ std::shared_ptr<debounce> configuration_impl::get_debounce( return nullptr; } -void configuration_impl::load_tcp_restart_settings(const element &_element) { +void +configuration_impl::load_tcp_restart_settings(const configuration_element &_element) { const std::string tcp_restart_aborts_max("tcp-restart-aborts-max"); const std::string tcp_connect_time_max("tcp-connect-time-max"); @@ -4154,240 +3448,102 @@ std::uint32_t configuration_impl::get_max_tcp_connect_time() const { return tcp_connect_time_max_; } -bool configuration_impl::offer_acceptance_required( - const boost::asio::ip::address& _address) const { - std::lock_guard<std::mutex> its_lock(offer_acceptance_required_ips_mutex_); - return offer_acceptance_required_ips_.find(_address) - != offer_acceptance_required_ips_.end(); +bool configuration_impl::sd_acceptance_required( + const boost::asio::ip::address& _address, std::uint16_t _port) const { + std::lock_guard<std::mutex> its_lock(sd_acceptance_required_ips_mutex_); + return sd_acceptance_required_ips_.find({_address, _port}) + != sd_acceptance_required_ips_.end(); } -void configuration_impl::set_offer_acceptance_required( - const boost::asio::ip::address& _address, const std::string& _path, - bool _enable) { - std::lock_guard<std::mutex> its_lock(offer_acceptance_required_ips_mutex_); +void configuration_impl::set_sd_acceptance_required( + const boost::asio::ip::address& _address, std::uint16_t _port, + const std::string& _path, bool _enable) { + std::lock_guard<std::mutex> its_lock(sd_acceptance_required_ips_mutex_); if (_enable) { - const auto found_address = offer_acceptance_required_ips_.find(_address); - if (found_address != offer_acceptance_required_ips_.end()) { + const auto found_address = sd_acceptance_required_ips_.find({_address, _port}); + if (found_address != sd_acceptance_required_ips_.end()) { boost::system::error_code ec; VSOMEIP_WARNING << __func__ << " configuration for: " - << found_address->first.to_string(ec) << " -> " - << found_address->second << " already configured." + << found_address->first.first.to_string(ec) << ":" + << std::dec << _port << " -> " + << found_address->first.second << " already configured." << " Won't update with: "<< _path; } else { - offer_acceptance_required_ips_[_address] = _path; + sd_acceptance_required_ips_[{_address, _port}] = _path; } } else { - offer_acceptance_required_ips_.erase(_address); + sd_acceptance_required_ips_.erase({_address, _port}); } } -std::map<boost::asio::ip::address, std::string> -configuration_impl::get_offer_acceptance_required() { - std::lock_guard<std::mutex> its_lock(offer_acceptance_required_ips_mutex_); - return offer_acceptance_required_ips_; +configuration::sd_acceptance_required_map_t configuration_impl::get_sd_acceptance_required() { + std::lock_guard<std::mutex> its_lock(sd_acceptance_required_ips_mutex_); + return sd_acceptance_required_ips_; } std::uint32_t configuration_impl::get_udp_receive_buffer_size() const { return udp_receive_buffer_size_; } -std::shared_ptr<policy> configuration_impl::find_client_id_policy(client_t _client) const { - std::lock_guard<std::mutex> its_lock(policies_mutex_); - for (auto client_id_pair : policies_) { - if (std::get<0>(client_id_pair.first) <= _client - && _client <= std::get<1>(client_id_pair.first)) { - return client_id_pair.second; - } - } - return nullptr; -} - -bool configuration_impl::remove_security_policy(uint32_t _uid, uint32_t _gid) { - std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_); - bool was_removed(false); - if (!any_client_policies_.empty()) { - std::vector<std::shared_ptr<policy>>::iterator p_it = any_client_policies_.begin(); - while (p_it != any_client_policies_.end()) { - bool has_uid(false), has_gid(false); - for (auto its_credential : p_it->get()->ids_) { - has_uid = has_gid = false; - for (auto its_range : std::get<0>(its_credential)) { - if (std::get<0>(its_range) <= _uid && _uid <= std::get<1>(its_range)) { - has_uid = true; - break; - } - } - for (auto its_range : std::get<1>(its_credential)) { - if (std::get<0>(its_range) <= _gid && _gid <= std::get<1>(its_range)) { - has_gid = true; - break; - } - } - // only remove "credentials allow" policies to prevent removal of - // blacklist configured in file - if (has_uid && has_gid && p_it->get()->allow_who_) { - was_removed = true; - break; - } - } - if (was_removed) { - p_it = any_client_policies_.erase(p_it); - break; - } else { - ++p_it; - } - } +bool configuration_impl::tp_segment_messages_client_to_service( + service_t _service, std::string _ip_target, std::uint16_t _port_target, + method_t _method) const { + bool ret(false); + const service* const its_service = find_service_by_ip_port(_service, + _ip_target, _port_target); + if (its_service) { + ret = (its_service->tp_segment_messages_client_to_service_.find(_method) + != its_service->tp_segment_messages_client_to_service_.end()); } - return was_removed; -} - -void configuration_impl::update_security_policy(uint32_t _uid, uint32_t _gid, ::std::shared_ptr<policy> _policy) { - remove_security_policy(_uid, _gid); - std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_); - any_client_policies_.push_back(_policy); + return ret; } -void configuration_impl::add_security_credentials(uint32_t _uid, uint32_t _gid, - ::std::shared_ptr<policy> _credentials_policy, client_t _client) { - - bool was_found(false); - std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_); - for (auto its_policy : any_client_policies_) { - bool has_uid(false), has_gid(false); - for (auto its_credential : its_policy->ids_) { - has_uid = has_gid = false; - for (auto its_range : std::get<0>(its_credential)) { - if (std::get<0>(its_range) <= _uid && _uid <= std::get<1>(its_range)) { - has_uid = true; - break; - } - } - for (auto its_range : std::get<1>(its_credential)) { - if (std::get<0>(its_range) <= _gid && _gid <= std::get<1>(its_range)) { - has_gid = true; - break; - } - } - if (has_uid && has_gid && its_policy->allow_who_) { - was_found = true; - break; - } - } - if (was_found) { - break; - } - } - // Do not add the new (credentials-only-policy) if a allow credentials policy with same credentials was found - if (!was_found) { - any_client_policies_.push_back(_credentials_policy); - VSOMEIP_INFO << __func__ << " Added security credentials at client: 0x" - << std::hex << _client << std::dec << " with UID: " << _uid << " GID: " << _gid; +bool configuration_impl::tp_segment_messages_service_to_client( + service_t _service, std::string _ip_service, + std::uint16_t _port_service, method_t _method) const { + bool ret(false); + const service* const its_service = find_service_by_ip_port(_service, + _ip_service, _port_service); + if (its_service) { + ret = (its_service->tp_segment_messages_service_to_client_.find(_method) + != its_service->tp_segment_messages_service_to_client_.end()); } + return ret; } -bool configuration_impl::is_remote_client_allowed() const { - if (!check_credentials_) { - return true; - } - return allow_remote_clients_; +#ifdef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS +bool +configuration_impl::has_overlay(const std::string &_name) const { + auto its_application = applications_.find(_name); + return (its_application != applications_.end() + && !std::get<7>(its_application->second).empty()); } -bool configuration_impl::is_policy_update_allowed(uint32_t _uid, std::shared_ptr<policy> &_policy) const { - bool uid_allowed(false); - { - std::lock_guard<std::mutex> its_lock(uid_whitelist_mutex_); - for (auto its_uid_range : uid_whitelist_) { - if (std::get<0>(its_uid_range) <= _uid && _uid <= std::get<1>(its_uid_range)) { - uid_allowed = true; - break; - } - } - } - - if (uid_allowed) { - std::lock_guard<std::mutex> its_lock(service_interface_whitelist_mutex_); - for (auto its_request : _policy->services_) { - auto its_requested_service = std::get<0>(its_request); - bool has_service(false); - for (auto its_service_range : service_interface_whitelist_) { - if (std::get<0>(its_service_range) <= its_requested_service - && its_requested_service <= std::get<1>(its_service_range)) { - has_service = true; - break; - } - } - if (!has_service) { - if (!check_whitelist_) { - VSOMEIP_INFO << "vSomeIP Security: Policy update requesting service ID: " - << std::hex << its_requested_service - << " is not allowed, but will be allowed due to whitelist audit mode is active!"; - } else { - VSOMEIP_WARNING << "vSomeIP Security: Policy update requesting service ID: " - << std::hex << its_requested_service - << " is not allowed! -> ignore update"; - } - return !check_whitelist_; - } - } - return true; - } else { - if (!check_whitelist_) { - VSOMEIP_INFO << "vSomeIP Security: Policy update for UID: " << std::dec << _uid - << " is not allowed, but will be allowed due to whitelist audit mode is active!"; - } else { - VSOMEIP_WARNING << "vSomeIP Security: Policy update for UID: " << std::dec << _uid - << " is not allowed! -> ignore update"; - } - return !check_whitelist_; - } -} +void +configuration_impl::load_overlay(const std::string &_name) { + std::set<std::string> its_input; + std::vector<element> its_elements; + std::set<std::string> its_failed; -bool configuration_impl::is_policy_removal_allowed(uint32_t _uid) const { - std::lock_guard<std::mutex> its_lock(uid_whitelist_mutex_); - for (auto its_uid_range : uid_whitelist_) { - if (std::get<0>(its_uid_range) <= _uid && _uid <= std::get<1>(its_uid_range)) { - return true; - } - } + auto its_application = applications_.find(_name); + if (its_application != applications_.end()) { + std::string its_overlay(std::get<7>(its_application->second)); - if (!check_whitelist_) { - VSOMEIP_INFO << "vSomeIP Security: Policy removal for UID: " << std::dec << _uid - << " is not allowed, but will be allowed due to whitelist audit mode is active!"; - } else { - VSOMEIP_WARNING << "vSomeIP Security: Policy removal for UID: " << std::dec << _uid - << " is not allowed! -> ignore removal"; - } - return !check_whitelist_; -} + its_input.insert(its_overlay); + read_data(its_input, its_elements, its_failed, false); -bool configuration_impl::check_routing_credentials(client_t _client, uint32_t _uid, uint32_t _gid) const { - if (_client != get_id(routing_host_)) { - return true; - } else { - std::lock_guard<std::mutex> its_lock(routing_credentials_mutex_); - if ( std::get<0>(routing_credentials_) == _uid - && std::get<1>(routing_credentials_) == _gid) { - return true; - } - } + for (const auto f : its_failed) + VSOMEIP_ERROR << "Reading configuration data from " << f << " failed!"; - std::string security_mode_text = "!"; - if (!check_routing_credentials_) { - security_mode_text = " but will be allowed due to audit mode is active!"; + is_overlay_ = true; + load_data(its_elements, true, true); } - VSOMEIP_INFO << "vSomeIP Security: Client 0x" - << std::hex << _client << " and UID/GID=" << std::dec << _uid - << "/" << _gid << " : Check routing credentials failed as " - << "configured routing manager credentials " - << "do not match with routing manager credentials" - << security_mode_text; - - return !check_routing_credentials_; } +#endif // VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS std::uint32_t configuration_impl::get_shutdown_timeout() const { return shutdown_timeout_; } } // namespace config -} // namespace vsomeip +} // namespace vsomeip_v3 diff --git a/implementation/configuration/src/configuration_plugin_impl.cpp b/implementation/configuration/src/configuration_plugin_impl.cpp new file mode 100644 index 0000000..df175f3 --- /dev/null +++ b/implementation/configuration/src/configuration_plugin_impl.cpp @@ -0,0 +1,52 @@ +// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// 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 <vsomeip/internal/logger.hpp> + +#include "../include/configuration_plugin_impl.hpp" +#include "../include/configuration_impl.hpp" + +VSOMEIP_PLUGIN(vsomeip_v3::configuration_plugin_impl) + +namespace vsomeip_v3 { + +configuration_plugin_impl::configuration_plugin_impl() + : plugin_impl("vsomeip-configuration-plugin", + VSOMEIP_CONFIG_PLUGIN_VERSION, + plugin_type_e::CONFIGURATION_PLUGIN) { +} + +configuration_plugin_impl::~configuration_plugin_impl() { +} + +std::shared_ptr<configuration> +configuration_plugin_impl::get_configuration(const std::string &_name) { + std::lock_guard<std::mutex> its_lock(mutex_); + if (!default_) { + default_ = std::make_shared<cfg::configuration_impl>(); + default_->load(_name); + } + +#ifdef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS + auto its_configuration(default_); + if (its_configuration->has_overlay(_name)) { + VSOMEIP_INFO << "Loading configuration overlay for \"" << _name << "\""; + auto its_iterator = configurations_.find(_name); + if (its_iterator != configurations_.end()) { + its_configuration = its_iterator->second; + } else { + its_configuration = std::make_shared<cfg::configuration_impl>( + *(its_configuration.get())); + its_configuration->load_overlay(_name); + configurations_[_name] = its_configuration; + } + } + return its_configuration; +#else + return default_; +#endif // VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS +} + +} // namespace vsomeip_v3 |