diff options
Diffstat (limited to 'implementation/routing/src/routing_manager_stub.cpp')
-rw-r--r-- | implementation/routing/src/routing_manager_stub.cpp | 2550 |
1 files changed, 1276 insertions, 1274 deletions
diff --git a/implementation/routing/src/routing_manager_stub.cpp b/implementation/routing/src/routing_manager_stub.cpp index 406b0d9..16ad36d 100644 --- a/implementation/routing/src/routing_manager_stub.cpp +++ b/implementation/routing/src/routing_manager_stub.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 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/. @@ -11,28 +11,56 @@ #include <boost/system/error_code.hpp> #include <vsomeip/constants.hpp> +#include <vsomeip/error.hpp> +#include <vsomeip/payload.hpp> #include <vsomeip/primitive_types.hpp> #include <vsomeip/runtime.hpp> -#include <vsomeip/error.hpp> +#include <vsomeip/structured_types.hpp> #include <vsomeip/internal/logger.hpp> #include "../include/routing_manager_stub.hpp" #include "../include/routing_manager_stub_host.hpp" #include "../include/remote_subscription.hpp" #include "../../configuration/include/configuration.hpp" -#include "../../security/include/security.hpp" - -#include "../../endpoints/include/local_server_endpoint_impl.hpp" #include "../../endpoints/include/endpoint_manager_impl.hpp" +#include "../../endpoints/include/netlink_connector.hpp" +#include "../../protocol/include/deregister_application_command.hpp" +#include "../../protocol/include/distribute_security_policies_command.hpp" +#include "../../protocol/include/dummy_command.hpp" +#include "../../protocol/include/expire_command.hpp" +#include "../../protocol/include/offer_service_command.hpp" +#include "../../protocol/include/offered_services_request_command.hpp" +#include "../../protocol/include/offered_services_response_command.hpp" +#include "../../protocol/include/ping_command.hpp" +#include "../../protocol/include/pong_command.hpp" +#include "../../protocol/include/register_application_command.hpp" +#include "../../protocol/include/register_events_command.hpp" +#include "../../protocol/include/registered_ack_command.hpp" +#include "../../protocol/include/release_service_command.hpp" +#include "../../protocol/include/remove_security_policy_command.hpp" +#include "../../protocol/include/remove_security_policy_response_command.hpp" +#include "../../protocol/include/request_service_command.hpp" +#include "../../protocol/include/resend_provided_events_command.hpp" +#include "../../protocol/include/routing_info_command.hpp" +#include "../../protocol/include/send_command.hpp" +#include "../../protocol/include/stop_offer_service_command.hpp" +#include "../../protocol/include/subscribe_ack_command.hpp" +#include "../../protocol/include/subscribe_command.hpp" +#include "../../protocol/include/subscribe_nack_command.hpp" +#include "../../protocol/include/suspend_command.hpp" +#include "../../protocol/include/unregister_event_command.hpp" +#include "../../protocol/include/unsubscribe_ack_command.hpp" +#include "../../protocol/include/unsubscribe_command.hpp" +#include "../../protocol/include/update_security_credentials_command.hpp" +#include "../../protocol/include/update_security_policy_command.hpp" +#include "../../protocol/include/update_security_policy_response_command.hpp" +#include "../../security/include/policy_manager_impl.hpp" +#include "../../security/include/security.hpp" #include "../../utility/include/byteorder.hpp" #include "../../utility/include/utility.hpp" -#include "../implementation/message/include/payload_impl.hpp" namespace vsomeip_v3 { -const std::vector<byte_t> routing_manager_stub::its_ping_( - { VSOMEIP_PING, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); - routing_manager_stub::routing_manager_stub( routing_manager_stub_host *_host, const std::shared_ptr<configuration>& _configuration) : @@ -40,7 +68,7 @@ routing_manager_stub::routing_manager_stub( io_(_host->get_io()), watchdog_timer_(_host->get_io()), client_id_timer_(_host->get_io()), - endpoint_(nullptr), + root_(nullptr), local_receiver_(nullptr), configuration_(_configuration), is_socket_activated_(false), @@ -48,20 +76,31 @@ routing_manager_stub::routing_manager_stub( max_local_message_size_(configuration_->get_max_message_size_local()), configured_watchdog_timeout_(configuration_->get_watchdog_timeout()), pinged_clients_timer_(io_), - pending_security_update_id_(0) { + pending_security_update_id_(0) +#if defined(__linux__) || defined(ANDROID) + , is_local_link_available_(false) +#endif +{ } routing_manager_stub::~routing_manager_stub() { } void routing_manager_stub::init() { + init_routing_endpoint(); + + std::string its_env; + char its_hostname[1024]; + if (gethostname(its_hostname, sizeof(its_hostname)) == 0) + its_env = its_hostname; + host_->set_client_host(its_env); } void routing_manager_stub::start() { { std::lock_guard<std::mutex> its_lock(used_client_ids_mutex_); - used_client_ids_ = utility::get_used_client_ids(); + used_client_ids_ = utility::get_used_client_ids(configuration_->get_network()); // Wait VSOMEIP_MAX_CONNECT_TIMEOUT * 2 and expect after that time // that all client_ids are used have to be connected to the routing. // Otherwise they can be marked as "erroneous client". @@ -73,12 +112,23 @@ void routing_manager_stub::start() { std::placeholders::_1)); } - if (!endpoint_) { - // application has been stopped and started again - init_routing_endpoint(); - } - if (endpoint_) { - endpoint_->start(); +#if defined(__linux__) || defined(ANDROID) + if (configuration_->is_local_routing()) { +#else + { +#endif // __linux__ || ANDROID + if (!root_) { + // application has been stopped and started again + init_routing_endpoint(); + } + if (root_) { + root_->start(); + } +#if defined(__linux__) || defined(ANDROID) + } else { + if (local_link_connector_) + local_link_connector_->start(); +#endif } client_registration_running_ = true; @@ -122,47 +172,60 @@ void routing_manager_stub::stop() { client_id_timer_.cancel(); } - if( !is_socket_activated_) { - endpoint_->stop(); - endpoint_ = nullptr; - std::stringstream its_endpoint_path; - its_endpoint_path << utility::get_base_path(configuration_) << std::hex - << VSOMEIP_ROUTING_CLIENT; -#ifdef _WIN32 - ::_unlink(its_endpoint_path.str().c_str()); -#else - if (-1 == ::unlink(its_endpoint_path.str().c_str())) { - VSOMEIP_ERROR << "routing_manager_stub::stop() unlink failed (" - << its_endpoint_path.str() << "): "<< std::strerror(errno); + bool is_local_routing(configuration_->is_local_routing()); + +#if defined(__linux__) || defined(ANDROID) + if (local_link_connector_) + local_link_connector_->stop(); +#endif // __linux__ || ANDROID + + if (!is_socket_activated_) { + root_->stop(); + root_ = nullptr; + + if (is_local_routing) { + std::stringstream its_endpoint_path; + its_endpoint_path << utility::get_base_path(configuration_->get_network()) + << std::hex << VSOMEIP_ROUTING_CLIENT; + #ifdef _WIN32 + ::_unlink(its_endpoint_path.str().c_str()); + #else + if (-1 == ::unlink(its_endpoint_path.str().c_str())) { + VSOMEIP_ERROR << "routing_manager_stub::stop() unlink failed (" + << its_endpoint_path.str() << "): "<< std::strerror(errno); + } + #endif } -#endif } - if(local_receiver_) { + if (local_receiver_) { local_receiver_->stop(); local_receiver_ = nullptr; - std::stringstream its_local_receiver_path; - its_local_receiver_path << utility::get_base_path(configuration_) - << std::hex << host_->get_client(); + + if (is_local_routing) { + std::stringstream its_local_receiver_path; + its_local_receiver_path << utility::get_base_path(configuration_->get_network()) + << std::hex << host_->get_client(); #ifdef _WIN32 - ::_unlink(its_local_receiver_path.str().c_str()); + ::_unlink(its_local_receiver_path.str().c_str()); #else - if (-1 == ::unlink(its_local_receiver_path.str().c_str())) { - VSOMEIP_ERROR << "routing_manager_stub::stop() unlink (local receiver) failed (" - << its_local_receiver_path.str() << "): "<< std::strerror(errno); - } + if (-1 == ::unlink(its_local_receiver_path.str().c_str())) { + VSOMEIP_ERROR << "routing_manager_stub::stop() unlink (local receiver) failed (" + << its_local_receiver_path.str() << "): "<< std::strerror(errno); + } #endif + } } } void routing_manager_stub::on_message(const byte_t *_data, length_t _size, - endpoint *_receiver, const boost::asio::ip::address &_destination, - client_t _bound_client, - credentials_t _credentials, + endpoint *_receiver, bool _is_multicast, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, const boost::asio::ip::address &_remote_address, std::uint16_t _remote_port) { + (void)_receiver; - (void)_destination; + (void)_is_multicast; (void)_remote_address; (void) _remote_port; #if 0 @@ -173,97 +236,118 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, VSOMEIP_INFO << msg.str(); #endif - std::uint32_t its_sender_uid = std::get<0>(_credentials); - std::uint32_t its_sender_gid = std::get<1>(_credentials); - - if (VSOMEIP_COMMAND_SIZE_POS_MAX < _size) { - byte_t its_command; - client_t its_client; - std::string its_client_endpoint; - service_t its_service; - instance_t its_instance; - method_t its_method; - eventgroup_t its_eventgroup; - event_t its_notifier; - event_type_e its_event_type; - bool is_provided(false); - major_version_t its_major; - minor_version_t its_minor; - std::shared_ptr<payload> its_payload; - const byte_t *its_data; - uint32_t its_size; - bool its_reliable(false); - client_t its_client_from_header; - client_t its_target_client; - client_t its_subscriber; - uint8_t its_check_status(0); - std::uint16_t its_subscription_id(PENDING_SUBSCRIPTION_ID); - offer_type_e its_offer_type; - - its_command = _data[VSOMEIP_COMMAND_TYPE_POS]; - std::memcpy(&its_client, &_data[VSOMEIP_COMMAND_CLIENT_POS], - sizeof(its_client)); - - if (security::get()->is_enabled() && _bound_client != its_client) { - VSOMEIP_WARNING << "vSomeIP Security: routing_manager_stub::on_message: " - << "Routing Manager received a message from client " - << std::hex << std::setw(4) << std::setfill('0') - << its_client << " with command " << (uint32_t)its_command - << " which doesn't match the bound client " - << std::setw(4) << std::setfill('0') << _bound_client - << " ~> skip message!"; - return; - } + client_t its_client; + protocol::id_e its_id; + std::string its_client_endpoint; + service_t its_service; + instance_t its_instance; + method_t its_method; + eventgroup_t its_eventgroup; + event_t its_notifier; + major_version_t its_major; + minor_version_t its_minor; + std::shared_ptr<payload> its_payload; + bool is_reliable(false); + client_t its_subscriber; + uint8_t its_check_status(0); + std::uint16_t its_subscription_id(PENDING_SUBSCRIPTION_ID); + port_t its_port(ILLEGAL_PORT); + + std::vector<byte_t> its_buffer(_data, _data + _size); + protocol::error_e its_error; + + // Use dummy command to deserialize id and client. + protocol::dummy_command its_base_command; + its_base_command.deserialize(its_buffer, its_error); + if (its_error != protocol::error_e::ERROR_OK) { - std::memcpy(&its_size, &_data[VSOMEIP_COMMAND_SIZE_POS_MIN], - sizeof(its_size)); + VSOMEIP_ERROR << __func__ + << ": deserialization of command and client identifier failed (" + << std::dec << static_cast<int>(its_error) + << ")"; + return; + } - if (its_size <= _size - VSOMEIP_COMMAND_HEADER_SIZE) { - switch (its_command) { - case VSOMEIP_REGISTER_APPLICATION: - if (_size != VSOMEIP_REGISTER_APPLICATION_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a REGISTER_APPLICATION command with wrong size ~> skip!"; - break; - } - update_registration(its_client, registration_type_e::REGISTER); - break; + its_client = its_base_command.get_client(); + its_id = its_base_command.get_id(); - case VSOMEIP_DEREGISTER_APPLICATION: - if (_size != VSOMEIP_DEREGISTER_APPLICATION_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a DEREGISTER_APPLICATION command with wrong size ~> skip!"; - break; - } - update_registration(its_client, registration_type_e::DEREGISTER); - break; + if (configuration_->is_security_enabled() + && configuration_->is_local_routing() + && _bound_client != its_client) { + VSOMEIP_WARNING << "vSomeIP Security: routing_manager_stub::on_message: " + << "Routing Manager received a message from client " + << std::hex << std::setw(4) << std::setfill('0') + << its_client << " with command " << (uint32_t)its_id + << " which doesn't match the bound client " + << std::setw(4) << std::setfill('0') << _bound_client + << " ~> skip message!"; + return; + } - case VSOMEIP_PONG: - if (_size != VSOMEIP_PONG_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a PONG command with wrong size ~> skip!"; - break; - } + switch (its_id) { + + case protocol::id_e::REGISTER_APPLICATION_ID: + { + protocol::register_application_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) + update_registration(its_command.get_client(), + registration_type_e::REGISTER, + _remote_address, its_command.get_port()); + else + VSOMEIP_ERROR << __func__ + << ": deserializing register application failed (" + << std::dec << static_cast<int>(its_error) << ")"; + + break; + } + + case protocol::id_e::DEREGISTER_APPLICATION_ID: + { + protocol::deregister_application_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) + update_registration(its_command.get_client(), + registration_type_e::DEREGISTER, + _remote_address, its_port); + else + VSOMEIP_ERROR << __func__ + << ": deserializing register application failed (" + << std::dec << static_cast<int>(its_error) << ")"; + + break; + } + + case protocol::id_e::PONG_ID: + { + protocol::pong_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { on_pong(its_client); VSOMEIP_TRACE << "PONG(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << ")"; - break; - - case VSOMEIP_OFFER_SERVICE: - if (_size != VSOMEIP_OFFER_SERVICE_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a OFFER_SERVICE command with wrong size ~> skip!"; - break; - } + << std::hex << std::setw(4) << std::setfill('0') + << its_client << ")"; + } else + VSOMEIP_ERROR << __func__ + << ": deserializing pong failed (" + << std::dec << static_cast<int>(its_error) << ")"; + break; + } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_major)); - std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5], - sizeof(its_minor)); - - if (security::get()->is_offer_allowed(its_sender_uid, its_sender_gid, - its_client, its_service, its_instance)) { + case protocol::id_e::OFFER_SERVICE_ID: + { + protocol::offer_service_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_major = its_command.get_major(); + its_minor = its_command.get_minor(); + + if (VSOMEIP_SEC_OK == security::is_client_allowed_to_offer( + _sec_client, its_service, its_instance)) { host_->offer_service(its_client, its_service, its_instance, its_major, its_minor); } else { @@ -272,48 +356,54 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, << "the following service/instance " << its_service << "/" << its_instance << " ~> Skip offer!"; } - break; + } else + VSOMEIP_ERROR << __func__ + << ": deserializing offer service failed (" + << std::dec << static_cast<int>(its_error) << ")"; + break; + } - case VSOMEIP_STOP_OFFER_SERVICE: - if (_size != VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a STOP_OFFER_SERVICE command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - - std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_major)); - std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5], - sizeof(its_minor)); - - host_->stop_offer_service(its_client, its_service, its_instance, its_major, its_minor); - break; - - case VSOMEIP_SUBSCRIBE: - if (_size != VSOMEIP_SUBSCRIBE_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a SUBSCRIBE command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_major)); - std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7], - sizeof(its_notifier)); + case protocol::id_e::STOP_OFFER_SERVICE_ID: + { + protocol::stop_offer_service_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_major = its_command.get_major(); + its_minor = its_command.get_minor(); + + host_->stop_offer_service(its_client, + its_service, its_instance, + its_major, its_minor); + } else + VSOMEIP_ERROR << __func__ + << ": deserializing stop offer service failed (" + << std::dec << static_cast<int>(its_error) << ")"; + break; + } + + case protocol::id_e::SUBSCRIBE_ID: + { + protocol::subscribe_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_eventgroup = its_command.get_eventgroup(); + its_major = its_command.get_major(); + its_notifier = its_command.get_event(); + auto its_filter = its_command.get_filter(); if (its_notifier == ANY_EVENT) { - if (host_->is_subscribe_to_any_event_allowed(_credentials, its_client, its_service, + if (host_->is_subscribe_to_any_event_allowed(_sec_client, its_client, its_service, its_instance, its_eventgroup)) { - host_->subscribe(its_client, its_sender_uid, its_sender_gid, its_service, its_instance, - its_eventgroup, its_major, its_notifier); + host_->subscribe(its_client, _sec_client, its_service, its_instance, + its_eventgroup, its_major, its_notifier, its_filter); } else { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client << " : routing_manager_stub::on_message: " @@ -322,10 +412,10 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, << " which violates the security policy ~> Skip subscribe!"; } } else { - if (security::get()->is_client_allowed(its_sender_uid, its_sender_gid, - its_client, its_service, its_instance, its_notifier)) { - host_->subscribe(its_client, its_sender_uid, its_sender_gid, its_service, its_instance, - its_eventgroup, its_major, its_notifier); + if (VSOMEIP_SEC_OK == security::is_client_allowed_to_access_member( + _sec_client, its_service, its_instance, its_notifier)) { + host_->subscribe(its_client, _sec_client, its_service, its_instance, + its_eventgroup, its_major, its_notifier, its_filter); } else { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client << " : routing_manager_stub::on_message: " @@ -334,456 +424,397 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, << " which violates the security policy ~> Skip subscribe!"; } } - break; + } else + VSOMEIP_ERROR << __func__ + << ": deserializing subscribe failed (" + << std::dec << static_cast<int>(its_error) << ")"; + break; + } + + case protocol::id_e::UNSUBSCRIBE_ID: + { + protocol::unsubscribe_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_eventgroup = its_command.get_eventgroup(); + its_notifier = its_command.get_event(); + + host_->unsubscribe(its_client, _sec_client, + its_service, its_instance, its_eventgroup, its_notifier); + } else + VSOMEIP_ERROR << __func__ + << ": deserializing unsubscribe failed (" + << std::dec << static_cast<int>(its_error) << ")"; + break; + } + + case protocol::id_e::SUBSCRIBE_ACK_ID: + { + protocol::subscribe_ack_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_eventgroup = its_command.get_eventgroup(); + its_subscriber = its_command.get_subscriber(); + its_notifier = its_command.get_event(); + its_subscription_id = its_command.get_pending_id(); - case VSOMEIP_UNSUBSCRIBE: - if (_size != VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a UNSUBSCRIBE command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_notifier)); - - host_->unsubscribe(its_client, its_sender_uid, its_sender_gid, its_service, - its_instance, its_eventgroup, its_notifier); - break; - - case VSOMEIP_SUBSCRIBE_ACK: - if (_size != VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a SUBSCRIBE_ACK command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_subscriber, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_subscriber)); - std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - sizeof(its_notifier)); - std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 10], - sizeof(its_subscription_id)); host_->on_subscribe_ack(its_subscriber, its_service, its_instance, its_eventgroup, its_notifier, its_subscription_id); + VSOMEIP_INFO << "SUBSCRIBE ACK(" << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" << std::hex << std::setw(4) << std::setfill('0') << its_service << "." << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." << std::hex << std::setw(4) << std::setfill('0') << its_notifier << "]"; - break; + } else + VSOMEIP_ERROR << __func__ + << ": deserializing subscribe ack failed (" + << std::dec << static_cast<int>(its_error) << ")"; + + break; + } + + case protocol::id_e::SUBSCRIBE_NACK_ID: + { + protocol::subscribe_nack_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_eventgroup = its_command.get_eventgroup(); + its_subscriber = its_command.get_subscriber(); + its_notifier = its_command.get_event(); + its_subscription_id = its_command.get_pending_id(); - case VSOMEIP_SUBSCRIBE_NACK: - if (_size != VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a SUBSCRIBE_NACK command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_subscriber, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_subscriber)); - std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - sizeof(its_notifier)); - std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 10], - sizeof(its_subscription_id)); host_->on_subscribe_nack(its_subscriber, its_service, - its_instance, its_eventgroup, its_notifier, - its_subscription_id, false); + its_instance, its_eventgroup, its_notifier, its_subscription_id); + VSOMEIP_INFO << "SUBSCRIBE NACK(" << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" << std::hex << std::setw(4) << std::setfill('0') << its_service << "." << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." << std::hex << std::setw(4) << std::setfill('0') << its_notifier << "]"; - break; - case VSOMEIP_UNSUBSCRIBE_ACK: - if (_size != VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a VSOMEIP_UNSUBSCRIBE_ACK command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_subscription_id)); + } else + VSOMEIP_ERROR << __func__ + << ": deserializing subscribe nack failed (" + << std::dec << static_cast<int>(its_error) << ")"; + + break; + } + + case protocol::id_e::UNSUBSCRIBE_ACK_ID: + { + protocol::unsubscribe_ack_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_eventgroup = its_command.get_eventgroup(); + its_subscription_id = its_command.get_pending_id(); + host_->on_unsubscribe_ack(its_client, its_service, its_instance, its_eventgroup, its_subscription_id); + VSOMEIP_INFO << "UNSUBSCRIBE ACK(" << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" << std::hex << std::setw(4) << std::setfill('0') << its_service << "." << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "]"; - break; - case VSOMEIP_SEND: { - if (_size < VSOMEIP_SEND_COMMAND_SIZE + VSOMEIP_FULL_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a SEND command with too small size ~> skip!"; - break; - } - its_data = &_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS]; - its_service = VSOMEIP_BYTES_TO_WORD( - its_data[VSOMEIP_SERVICE_POS_MIN], - its_data[VSOMEIP_SERVICE_POS_MAX]); - its_client_from_header = VSOMEIP_BYTES_TO_WORD( - its_data[VSOMEIP_CLIENT_POS_MIN], - its_data[VSOMEIP_CLIENT_POS_MAX]); - its_method = VSOMEIP_BYTES_TO_WORD( - its_data[VSOMEIP_METHOD_POS_MIN], - its_data[VSOMEIP_METHOD_POS_MAX]); - std::memcpy(&its_instance, &_data[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN], - sizeof(its_instance)); - std::memcpy(&its_reliable, &_data[VSOMEIP_SEND_COMMAND_RELIABLE_POS], - sizeof(its_reliable)); - std::memcpy(&its_check_status, &_data[VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS], - sizeof(its_check_status)); - - // Allow response messages from local proxies as answer to remote requests - // but check requests sent by local proxies to remote against policy. - if (utility::is_request(its_data[VSOMEIP_MESSAGE_TYPE_POS])) { - if (!security::get()->is_client_allowed(its_sender_uid, its_sender_gid, - its_client_from_header, its_service, its_instance, its_method)) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client_from_header - << " : routing_manager_stub::on_message: " - << " isn't allowed to send a request to service/instance/method " - << its_service << "/" << its_instance << "/" << its_method - << " ~> Skip message!"; - return; - } - } - // reduce by size of instance, flush, reliable, client and is_valid_crc flag - const std::uint32_t its_message_size = its_size - - (VSOMEIP_SEND_COMMAND_SIZE - VSOMEIP_COMMAND_HEADER_SIZE); - if (its_message_size != - VSOMEIP_BYTES_TO_LONG(_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 1], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 2], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 3]) - + VSOMEIP_SOMEIP_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a SEND command containing message with invalid size -> skip!"; - break; - } - host_->on_message(its_service, its_instance, its_data, its_message_size, - its_reliable, _bound_client, _credentials, its_check_status, false); - break; - } - case VSOMEIP_NOTIFY: { - if (_size < VSOMEIP_SEND_COMMAND_SIZE + VSOMEIP_FULL_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a NOTIFY command with too small size ~> skip!"; - break; - } - its_data = &_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS]; - its_service = VSOMEIP_BYTES_TO_WORD( - its_data[VSOMEIP_SERVICE_POS_MIN], - its_data[VSOMEIP_SERVICE_POS_MAX]); - std::memcpy(&its_instance, &_data[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN], - sizeof(its_instance)); - // reduce by size of instance, flush, reliable, is_valid_crc flag and target client - const std::uint32_t its_message_size = its_size - - (VSOMEIP_SEND_COMMAND_SIZE - VSOMEIP_COMMAND_HEADER_SIZE); - if (its_message_size != - VSOMEIP_BYTES_TO_LONG(_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 1], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 2], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 3]) - + VSOMEIP_SOMEIP_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a NOTIFY command containing message with invalid size -> skip!"; - break; - } - host_->on_notification(VSOMEIP_ROUTING_CLIENT, its_service, its_instance, its_data, its_message_size); - break; - } - case VSOMEIP_NOTIFY_ONE: { - if (_size < VSOMEIP_SEND_COMMAND_SIZE + VSOMEIP_FULL_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a NOTIFY_ONE command with too small size ~> skip!"; - break; - } - its_data = &_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS]; - its_service = VSOMEIP_BYTES_TO_WORD( - its_data[VSOMEIP_SERVICE_POS_MIN], - its_data[VSOMEIP_SERVICE_POS_MAX]); - std::memcpy(&its_instance, &_data[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN], - sizeof(its_instance)); - std::memcpy(&its_target_client, &_data[VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MIN], - sizeof(client_t)); - // reduce by size of instance, flush, reliable flag, is_valid_crc and target client - const std::uint32_t its_message_size = its_size - - (VSOMEIP_SEND_COMMAND_SIZE - VSOMEIP_COMMAND_HEADER_SIZE); - if (its_message_size != - VSOMEIP_BYTES_TO_LONG(_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 1], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 2], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 3]) - + VSOMEIP_SOMEIP_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a NOTIFY_ONE command containing message with invalid size -> skip!"; - break; - } - host_->on_notification(its_target_client, its_service, its_instance, - its_data, its_message_size, true); - break; - } - case VSOMEIP_REQUEST_SERVICE: - { - uint32_t entry_size = (sizeof(service_t) + sizeof(instance_t) - + sizeof(major_version_t) + sizeof(minor_version_t)); - if (its_size % entry_size > 0) { - VSOMEIP_WARNING << "Received a REQUEST_SERVICE command with invalid size -> skip!"; - break; - } - uint32_t request_count(its_size / entry_size); - std::set<service_data_t> requests; - for (uint32_t i = 0; i < request_count; ++i) { - service_t its_service; - instance_t its_instance; - major_version_t its_major; - minor_version_t its_minor; - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + (i * entry_size)], - sizeof(its_service)); - std::memcpy(&its_instance, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2 + (i * entry_size)], - sizeof(its_instance)); - std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4 + (i * entry_size)], - sizeof(its_major)); - std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5 + (i * entry_size)], - sizeof(its_minor)); - if (security::get()->is_client_allowed(its_sender_uid, its_sender_gid, - its_client, its_service, its_instance, 0x00, true)) { - host_->request_service(its_client, its_service, its_instance, - its_major, its_minor ); - service_data_t request = { - its_service, its_instance, - its_major, its_minor - }; - requests.insert(request); - } else { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex - << its_client << " : routing_manager_stub::on_message: " - << "requests service/instance " - << its_service << "/" << its_instance - << " which violates the security policy ~> Skip request!"; + } else + VSOMEIP_ERROR << __func__ + << ": deserializing unsubscribe ack failed (" + << std::dec << static_cast<int>(its_error) << ")"; + break; + } + + case protocol::id_e::SEND_ID: + { + protocol::send_command its_command(its_id); + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + auto its_message_data(its_command.get_message()); + if (its_message_data.size() > VSOMEIP_MESSAGE_TYPE_POS) { + + its_service = VSOMEIP_BYTES_TO_WORD( + its_message_data[VSOMEIP_SERVICE_POS_MIN], + its_message_data[VSOMEIP_SERVICE_POS_MAX]); + its_method = VSOMEIP_BYTES_TO_WORD( + its_message_data[VSOMEIP_METHOD_POS_MIN], + its_message_data[VSOMEIP_METHOD_POS_MAX]); + its_client = VSOMEIP_BYTES_TO_WORD( + its_message_data[VSOMEIP_CLIENT_POS_MIN], + its_message_data[VSOMEIP_CLIENT_POS_MAX]); + + its_instance = its_command.get_instance(); + is_reliable = its_command.is_reliable(); + its_check_status = its_command.get_status(); + + // Allow response messages from local proxies as answer to remote requests + // but check requests sent by local proxies to remote against policy. + if (utility::is_request(its_message_data[VSOMEIP_MESSAGE_TYPE_POS])) { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member( + _sec_client, its_service, its_instance, its_method)) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client + << " : routing_manager_stub::on_message: " + << " isn't allowed to send a request to service/instance/method " + << its_service << "/" << its_instance << "/" << its_method + << " ~> Skip message!"; + return; } } - if (security::get()->is_enabled()) { - handle_credentials(its_client, requests); + // reduce by size of instance, flush, reliable, client and is_valid_crc flag + auto its_contained_size = VSOMEIP_BYTES_TO_LONG( + its_message_data[VSOMEIP_LENGTH_POS_MIN], + its_message_data[VSOMEIP_LENGTH_POS_MIN+1], + its_message_data[VSOMEIP_LENGTH_POS_MIN+2], + its_message_data[VSOMEIP_LENGTH_POS_MIN+3]); + if (its_message_data.size() != its_contained_size + VSOMEIP_SOMEIP_HEADER_SIZE) { + VSOMEIP_WARNING << "Received a SEND command containing message with invalid size -> skip!"; + break; } - handle_requests(its_client, requests); - break; + host_->on_message(its_service, its_instance, + &its_message_data[0], length_t(its_message_data.size()), + is_reliable, _bound_client, _sec_client, its_check_status, false); } + } + break; + } - case VSOMEIP_RELEASE_SERVICE: - if (_size != VSOMEIP_RELEASE_SERVICE_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a RELEASE_SERVICE command with wrong size ~> skip!"; + case protocol::id_e::NOTIFY_ID: + case protocol::id_e::NOTIFY_ONE_ID: + { + protocol::send_command its_command(its_id); + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + auto its_message_data(its_command.get_message()); + if (its_message_data.size() > VSOMEIP_MESSAGE_TYPE_POS) { + + its_client = its_command.get_target(); + its_service = VSOMEIP_BYTES_TO_WORD( + its_message_data[VSOMEIP_SERVICE_POS_MIN], + its_message_data[VSOMEIP_SERVICE_POS_MAX]); + its_instance = its_command.get_instance(); + + auto its_contained_size = VSOMEIP_BYTES_TO_LONG( + its_message_data[VSOMEIP_LENGTH_POS_MIN], + its_message_data[VSOMEIP_LENGTH_POS_MIN+1], + its_message_data[VSOMEIP_LENGTH_POS_MIN+2], + its_message_data[VSOMEIP_LENGTH_POS_MIN+3]); + if (its_message_data.size() != its_contained_size + VSOMEIP_SOMEIP_HEADER_SIZE) { + VSOMEIP_WARNING << "Received a NOTIFY command containing message with invalid size -> skip!"; break; } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - host_->release_service(its_client, its_service, its_instance); + host_->on_notification(its_client, its_service, its_instance, + &its_message_data[0], length_t(its_message_data.size()), + its_id == protocol::id_e::NOTIFY_ONE_ID); break; + } + } + break; + } - case VSOMEIP_REGISTER_EVENT: { - if (_size < VSOMEIP_REGISTER_EVENT_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a REGISTER_EVENT command with wrong size ~> skip!"; - break; + case protocol::id_e::REQUEST_SERVICE_ID: + { + protocol::request_service_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + its_client = its_command.get_client(); + auto its_requests = its_command.get_services(); + + std::set<protocol::service> its_allowed_requests; + for (const auto &r : its_requests) { + if (VSOMEIP_SEC_OK == security::is_client_allowed_to_request( + _sec_client, r.service_, r.instance_)) { + host_->request_service(its_client, + r.service_, r.instance_, r.major_, r.minor_); + its_allowed_requests.insert(r); } + } + if (configuration_->is_security_enabled()) { + handle_credentials(its_client, its_allowed_requests); + } + handle_requests(its_client, its_allowed_requests); + } else + VSOMEIP_ERROR << __func__ << ": request service deserialization failed (" + << std::dec << static_cast<int>(its_error) << ")"; - std::set<eventgroup_t> its_eventgroups; - reliability_type_e its_reliability = reliability_type_e::RT_UNKNOWN; - - std::memcpy(&its_service, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_notifier, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_notifier)); - std::memcpy(&its_event_type, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_event_type)); - std::memcpy(&is_provided, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7], - sizeof(is_provided)); - std::memcpy(&its_reliability, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - sizeof(its_reliability)); - if (is_provided - && !configuration_->is_offered_remote(its_service, - its_instance)) { - break; + break; + } + + case protocol::id_e::RELEASE_SERVICE_ID: + { + protocol::release_service_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + host_->release_service(its_command.get_client(), + its_command.get_service(), its_command.get_instance()); + } else + VSOMEIP_ERROR << __func__ << ": release service deserialization failed (" + << std::dec << static_cast<int>(its_error) << ")"; + break; + } + + case protocol::id_e::REGISTER_EVENT_ID: + { + protocol::register_events_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + for(std::size_t i = 0; i < its_command.get_num_registrations(); i++) { + protocol::register_event register_event; + if (!its_command.get_registration_at(i, register_event)) { + continue; } - for (std::size_t i = 9; i+1 < its_size; i++) { - std::memcpy(&its_eventgroup, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + i], - sizeof(its_eventgroup)); - its_eventgroups.insert(its_eventgroup); + + its_service = register_event.get_service(); + its_instance = register_event.get_instance(); + + if (register_event.is_provided() + && !configuration_->is_offered_remote(its_service, its_instance)) { + continue; } + host_->register_shadow_event(its_client, its_service, its_instance, - its_notifier, its_eventgroups, its_event_type, - its_reliability, - is_provided); + register_event.get_event(), register_event.get_eventgroups(), + register_event.get_event_type(), register_event.get_reliability(), + register_event.is_provided(), register_event.is_cyclic()); + VSOMEIP_INFO << "REGISTER EVENT(" << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_notifier - << ":is_provider=" << is_provided << ":reliability=" - << (std::uint32_t)(its_reliability) << "]"; - break; + << std::hex << std::setw(4) << std::setfill('0') << its_instance + << ":eventtype=" << std::dec << (int)register_event.get_event_type() + << ":is_provided=" << std::boolalpha << register_event.is_provided() + << ":reliable=" << std::dec << (int)register_event.get_reliability() << "]"; } - case VSOMEIP_UNREGISTER_EVENT: - if (_size != VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a UNREGISTER_EVENT command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_notifier)); - std::memcpy(&is_provided, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(is_provided)); - if (is_provided - && !configuration_->is_offered_remote(its_service, - its_instance)) { - break; - } - host_->unregister_shadow_event(its_client, its_service, its_instance, - its_notifier, is_provided); - VSOMEIP_INFO << "UNREGISTER EVENT(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_notifier - << ":is_provider=" << is_provided << "]"; - break; - case VSOMEIP_REGISTERED_ACK: - if (_size != VSOMEIP_REGISTERED_ACK_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a REGISTERED_ACK command with wrong size ~> skip!"; - break; - } - VSOMEIP_INFO << "REGISTERED_ACK(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << ")"; - break; - case VSOMEIP_OFFERED_SERVICES_REQUEST: { - if (_size != VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a VSOMEIP_OFFERED_SERVICES_REQUEST command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_offer_type, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_offer_type)); + } else + VSOMEIP_ERROR << __func__ << ": register event deserialization failed (" + << std::dec << static_cast<int>(its_error) << ")"; + break; + } - std::lock_guard<std::mutex> its_guard(routing_info_mutex_); - create_offered_services_info(its_client); - - for (const auto& found_client : routing_info_) { - // skip services which are offered on remote hosts - if (found_client.first != VSOMEIP_ROUTING_CLIENT) { - for (const auto &its_service : found_client.second.second) { - for (const auto &its_instance : its_service.second) { - uint16_t its_reliable_port = configuration_->get_reliable_port(its_service.first, - its_instance.first); - uint16_t its_unreliable_port = configuration_->get_unreliable_port( - its_service.first, its_instance.first); - - if (its_offer_type == offer_type_e::OT_LOCAL) { - if (its_reliable_port == ILLEGAL_PORT - && its_unreliable_port == ILLEGAL_PORT) { - insert_offered_services_info(its_client, - routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, - its_service.first, its_instance.first, - its_instance.second.first, its_instance.second.second); - } - } - else if (its_offer_type == offer_type_e::OT_REMOTE) { - if (its_reliable_port != ILLEGAL_PORT - || its_unreliable_port != ILLEGAL_PORT) { - insert_offered_services_info(its_client, - routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, - its_service.first, its_instance.first, - its_instance.second.first, its_instance.second.second); - } - } else if (its_offer_type == offer_type_e::OT_ALL) { - insert_offered_services_info(its_client, - routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, - its_service.first, its_instance.first, - its_instance.second.first, its_instance.second.second); - } - } - } - } - } - send_offered_services_info(its_client); - break; - } - case VSOMEIP_RESEND_PROVIDED_EVENTS: { - if (_size != VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a RESEND_PROVIDED_EVENTS command with wrong size ~> skip!"; - break; - } - pending_remote_offer_id_t its_pending_remote_offer_id(0); - std::memcpy(&its_pending_remote_offer_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(pending_remote_offer_id_t)); - host_->on_resend_provided_events_response(its_pending_remote_offer_id); - VSOMEIP_INFO << "RESEND_PROVIDED_EVENTS(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << ")"; - break; - } - case VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE: { - if (_size != VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE) { - VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE " - << "command with wrong size ~> skip!"; - break; - } - pending_security_update_id_t its_pending_security_update_id(0); - std::memcpy(&its_pending_security_update_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(pending_security_update_id_t)); + case protocol::id_e::UNREGISTER_EVENT_ID: + { + protocol::unregister_event_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + host_->unregister_shadow_event(its_command.get_client(), + its_command.get_service(), its_command.get_instance(), + its_command.get_event(), its_command.is_provided()); + + VSOMEIP_INFO << "UNREGISTER EVENT(" + << std::hex << std::setw(4) << std::setfill('0') << its_command.get_client() << "): [" + << std::hex << std::setw(4) << std::setfill('0') << its_command.get_service() << "." + << std::hex << std::setw(4) << std::setfill('0') << its_command.get_instance() << "." + << std::hex << std::setw(4) << std::setfill('0') << its_command.get_event() + << ":is_provider=" << std::boolalpha << its_command.is_provided() << "]"; + } else + VSOMEIP_ERROR << __func__ << ": unregister event deserialization failed (" + << std::dec << static_cast<int>(its_error) << ")"; + break; + } - on_security_update_response(its_pending_security_update_id ,its_client); - break; - } - case VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE: { - if (_size != VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE) { - VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE " - << "command with wrong size ~> skip!"; - break; - } - pending_security_update_id_t its_pending_security_update_id(0); - std::memcpy(&its_pending_security_update_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(pending_security_update_id_t)); + case protocol::id_e::REGISTERED_ACK_ID: + { + protocol::registered_ack_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + VSOMEIP_INFO << "REGISTERED_ACK(" + << std::hex << std::setw(4) << std::setfill('0') + << its_command.get_client() << ")"; + } else + VSOMEIP_ERROR << __func__ << ": registered ack deserialization failed (" + << std::dec << static_cast<int>(its_error) << ")"; + break; + } - on_security_update_response(its_pending_security_update_id ,its_client); - break; - } - } + case protocol::id_e::OFFERED_SERVICES_REQUEST_ID: + { + protocol::offered_services_request_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + on_offered_service_request(its_command.get_client(), its_command.get_offer_type()); + } else + VSOMEIP_ERROR << __func__ << ": offer service request deserialization failed (" + << std::dec << static_cast<int>(its_error) << ")"; + break; + } + + case protocol::id_e::RESEND_PROVIDED_EVENTS_ID: + { + protocol::resend_provided_events_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + host_->on_resend_provided_events_response(its_command.get_remote_offer_id()); + VSOMEIP_INFO << "RESEND_PROVIDED_EVENTS(" + << std::hex << std::setw(4) << std::setfill('0') << its_client << ")"; + } else + VSOMEIP_ERROR << __func__ << ": resend provided events deserialization failed (" + << std::dec << static_cast<int>(its_error) << ")"; + break; + } +#ifndef VSOMEIP_DISABLE_SECURITY + case protocol::id_e::UPDATE_SECURITY_POLICY_RESPONSE_ID: + { + protocol::update_security_policy_response_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + on_security_update_response(its_command.get_update_id(), its_client); + } else + VSOMEIP_ERROR << __func__ << ": update security policy deserialization failed (" + << std::dec << static_cast<int>(its_error) << ")"; + break; + } + + case protocol::id_e::REMOVE_SECURITY_POLICY_RESPONSE_ID: + { + protocol::remove_security_policy_response_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + on_security_update_response(its_command.get_update_id(), its_client); + } else + VSOMEIP_ERROR << __func__ << ": update security policy deserialization failed (" + << std::dec << static_cast<int>(its_error) << ")"; + break; } +#endif // !VSOMEIP_DISABLE_SECURITY + default: + VSOMEIP_WARNING << __func__ << ": Received an unhandled command (" + << std::dec << static_cast<int>(its_id) << ")"; } } +void routing_manager_stub::add_known_client(client_t _client, const std::string &_client_host) { + host_->add_known_client(_client, _client_host); +} + void routing_manager_stub::on_register_application(client_t _client) { + auto endpoint = host_->find_local(_client); if (endpoint) { VSOMEIP_WARNING << "Reregistering application: " << std::hex << _client @@ -794,15 +825,21 @@ void routing_manager_stub::on_register_application(client_t _client) { std::lock_guard<std::mutex> its_lock(routing_info_mutex_); routing_info_[_client].first = 0; } +#ifndef VSOMEIP_DISABLE_SECURITY + if (configuration_->is_local_routing()) { + vsomeip_sec_client_t its_sec_client; + std::set<std::shared_ptr<policy> > its_policies; + + policy_manager_impl::get()->get_client_to_sec_client_mapping(_client, its_sec_client); + if (its_sec_client.client_type == VSOMEIP_CLIENT_UDS) { + get_requester_policies(its_sec_client.client.uds_client.user, + its_sec_client.client.uds_client.group, its_policies); + } - std::pair<uid_t, gid_t> its_uid_gid; - std::set<std::shared_ptr<policy> > its_policies; - - security::get()->get_client_to_uid_gid_mapping(_client, its_uid_gid); - get_requester_policies(its_uid_gid.first, its_uid_gid.second, its_policies); - - if (!its_policies.empty()) - send_requester_policies({ _client }, its_policies); + if (!its_policies.empty()) + send_requester_policies({ _client }, its_policies); + } +#endif // !VSOMEIP_DISABLE_SECURITY } } @@ -827,15 +864,59 @@ void routing_manager_stub::on_deregister_application(client_t _client) { routing_info_.erase(_client); } for (const auto &s : services_to_report) { - host_->on_availability(std::get<0>(s), std::get<1>(s), false, + host_->on_availability(std::get<0>(s), std::get<1>(s), + availability_state_e::AS_UNAVAILABLE, std::get<2>(s), std::get<3>(s)); host_->on_stop_offer_service(_client, std::get<0>(s), std::get<1>(s), std::get<2>(s), std::get<3>(s)); } } +void +routing_manager_stub::on_offered_service_request(client_t _client, + offer_type_e _offer_type) { + + protocol::offered_services_response_command its_command; + its_command.set_client(_client); + + for (const auto& found_client : routing_info_) { + // skip services which are offered on remote hosts + if (found_client.first != VSOMEIP_ROUTING_CLIENT) { + for (const auto &s : found_client.second.second) { + for (const auto &i : s.second) { + uint16_t its_reliable_port + = configuration_->get_reliable_port(s.first, i.first); + uint16_t its_unreliable_port + = configuration_->get_unreliable_port(s.first, i.first); + bool has_port = (its_reliable_port != ILLEGAL_PORT + || its_unreliable_port != ILLEGAL_PORT); + + if (_offer_type == offer_type_e::OT_ALL + || (_offer_type == offer_type_e::OT_LOCAL && !has_port) + || (_offer_type == offer_type_e::OT_REMOTE && has_port)) { + + protocol::service its_service(s.first, i.first, + i.second.first, i.second.second); + its_command.add_service(its_service); + } + } + } + } + } + + std::vector<byte_t> its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client); + if (its_endpoint) + its_endpoint->send(&its_buffer[0], uint32_t(its_buffer.size())); + } +} + void routing_manager_stub::client_registration_func(void) { -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) { std::stringstream s; s << std::hex << std::setw(4) << std::setfill('0') @@ -845,9 +926,9 @@ void routing_manager_stub::client_registration_func(void) { #endif std::unique_lock<std::mutex> its_lock(client_registration_mutex_); while (client_registration_running_) { - while (!pending_client_registrations_.size() && client_registration_running_) { - client_registration_condition_.wait(its_lock); - } + client_registration_condition_.wait(its_lock, [this] { + return pending_client_registrations_.size() || !client_registration_running_; + }); std::map<client_t, std::vector<registration_type_e>> its_registrations( pending_client_registrations_); @@ -867,44 +948,53 @@ void routing_manager_stub::client_registration_func(void) { // endpoint error to avoid writing in an already closed socket if (b != registration_type_e::DEREGISTER_ON_ERROR) { std::lock_guard<std::mutex> its_guard(routing_info_mutex_); - create_client_routing_info(r.first); - insert_client_routing_info(r.first, - b == registration_type_e::REGISTER ? - routing_info_entry_e::RIE_ADD_CLIENT : - routing_info_entry_e::RIE_DEL_CLIENT, - r.first); - // distribute updated security config to new clients + add_connection(r.first, r.first); + protocol::routing_info_entry its_entry; + its_entry.set_client(r.first); if (b == registration_type_e::REGISTER) { + boost::asio::ip::address its_address; + port_t its_port; + + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_ADD_CLIENT); + if (host_->get_guest(r.first, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } +#ifndef VSOMEIP_DISABLE_SECURITY + // distribute updated security config to new clients send_cached_security_policies(r.first); +#endif // !VSOMEIP_DISABLE_SECURITY + } else { + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_DELETE_CLIENT); } - send_client_routing_info(r.first); + send_client_routing_info(r.first, its_entry); } if (b != registration_type_e::REGISTER) { { std::lock_guard<std::mutex> its_guard(routing_info_mutex_); - auto its_connection = connection_matrix_.find(r.first); - if (its_connection != connection_matrix_.end()) { - for (auto its_client : its_connection->second) { + auto find_connections = connection_matrix_.find(r.first); + if (find_connections != connection_matrix_.end()) { + for (auto its_client : find_connections->second) { if (its_client != r.first && its_client != VSOMEIP_ROUTING_CLIENT && its_client != get_client()) { - create_client_routing_info(its_client); - insert_client_routing_info(its_client, - routing_info_entry_e::RIE_DEL_CLIENT, r.first); - send_client_routing_info(its_client); + protocol::routing_info_entry its_entry; + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_DELETE_CLIENT); + its_entry.set_client(r.first); + send_client_routing_info(its_client, its_entry); } } - connection_matrix_.erase(r.first); + remove_source(r.first); } - for (const auto& its_client : connection_matrix_) { - connection_matrix_[its_client.first].erase(r.first); + for (const auto &its_connections : connection_matrix_) { + remove_connection(its_connections.first, r.first); } service_requests_.erase(r.first); } // Don't remove client ID to UID maping as same client // could have passed its credentials again host_->remove_local(r.first, false); - utility::release_client_id(r.first); + utility::release_client_id(configuration_->get_network(), r.first); } } } @@ -913,9 +1003,75 @@ void routing_manager_stub::client_registration_func(void) { } void routing_manager_stub::init_routing_endpoint() { - endpoint_ = host_->get_endpoint_manager()->create_local_server( - &is_socket_activated_, shared_from_this()); + +#if defined(__linux__) || defined(ANDROID) + if (configuration_->is_local_routing()) { +#else + { +#endif // __linux__ || ANDROID + bool is_successful = host_->get_endpoint_manager()->create_routing_root( + root_, is_socket_activated_, shared_from_this()); + + if (!is_successful) { + VSOMEIP_WARNING << "Routing root creating (partially) failed. Please check your configuration."; + } +#if defined(__linux__) || defined(ANDROID) + } else { + auto its_host_address = configuration_->get_routing_host_address(); + local_link_connector_ = std::make_shared<netlink_connector>( + io_, its_host_address, boost::asio::ip::address(), false); // routing host doesn't need link up + if (local_link_connector_) { + local_link_connector_->register_net_if_changes_handler( + std::bind(&routing_manager_stub::on_net_state_change, + this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + } +#endif // __linux__ || ANDROID + } +} + +#if defined(__linux__) || defined(ANDROID) +void +routing_manager_stub::on_net_state_change( + bool _is_interface, const std::string &_name, bool _is_available) { + + VSOMEIP_INFO << __func__ + << "("<< std::hex << std::this_thread::get_id() << "): " + << std::boolalpha << _is_interface << " " + << _name << " " + << std::boolalpha << _is_available; + + if (_is_interface) { + if (_is_available) { + if (!is_local_link_available_) { + is_local_link_available_ = true; + if (!root_) + (void)host_->get_endpoint_manager()->create_routing_root( + root_, is_socket_activated_, shared_from_this()); + if (root_) { + VSOMEIP_INFO << __func__ + << ": Starting routing root."; + root_->start(); + } else + VSOMEIP_WARNING << "Routing root creating (partially) failed. " + "Please check your configuration."; + } + } else { + if (is_local_link_available_) { + + VSOMEIP_INFO << __func__ + << ": Stopping routing root."; + root_->stop(); + + routing_info_.clear(); + host_->clear_local_services(); + + is_local_link_available_ = false; + } + } + } } +#endif // __linux__ || ANDROID void routing_manager_stub::on_offer_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) { @@ -925,11 +1081,11 @@ void routing_manager_stub::on_offer_service(client_t _client, std::lock_guard<std::mutex> its_guard(routing_info_mutex_); routing_info_[_client].second[_service][_instance] = std::make_pair(_major, _minor); - if (security::get()->is_enabled()) { + if (configuration_->is_security_enabled()) { distribute_credentials(_client, _service, _instance); } inform_requesters(_client, _service, _instance, _major, _minor, - routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, true); + protocol::routing_info_entry_type_e::RIE_ADD_SERVICE_INSTANCE, true); } void routing_manager_stub::on_stop_offer_service(client_t _client, @@ -947,102 +1103,29 @@ void routing_manager_stub::on_stop_offer_service(client_t _client, if (0 == found_service->second.size()) { found_client->second.second.erase(_service); } - inform_provider(_client, _service, _instance, _major, _minor, - routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE); inform_requesters(_client, _service, _instance, _major, _minor, - routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE, false); + protocol::routing_info_entry_type_e::RIE_DELETE_SERVICE_INSTANCE, false); } else if( _major == DEFAULT_MAJOR && _minor == DEFAULT_MINOR) { found_service->second.erase(_instance); if (0 == found_service->second.size()) { found_client->second.second.erase(_service); } - inform_provider(_client, _service, _instance, _major, _minor, - routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE); inform_requesters(_client, _service, _instance, _major, _minor, - routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE, false); + protocol::routing_info_entry_type_e::RIE_DELETE_SERVICE_INSTANCE, false); } } } } } -void routing_manager_stub::create_client_routing_info(const client_t _target) { - std::vector<byte_t> its_command; - its_command.push_back(VSOMEIP_ROUTING_INFO); - - // Sender client - client_t client = get_client(); - for (uint32_t i = 0; i < sizeof(client_t); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&client)[i]); - } - - // Overall size placeholder - byte_t size_placeholder = 0x0; - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back(size_placeholder); - } - - client_routing_info_[_target] = its_command; -} - -void routing_manager_stub::create_client_credentials_info(const client_t _target) { - std::vector<byte_t> its_command; - its_command.push_back(VSOMEIP_UPDATE_SECURITY_CREDENTIALS); - - // Sender client - client_t client = get_client(); - for (uint32_t i = 0; i < sizeof(client_t); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&client)[i]); - } - - // Overall size placeholder - byte_t size_placeholder = 0x0; - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back(size_placeholder); - } - - client_credentials_info_[_target] = its_command; -} - -void routing_manager_stub::insert_client_credentials_info(client_t _target, std::set<std::pair<uint32_t, uint32_t>> _credentials) { - if (client_credentials_info_.find(_target) == client_credentials_info_.end()) { - return; - } - - auto its_command = client_credentials_info_[_target]; - - // insert uid / gid credential pairs - for (auto its_credentials : _credentials) { - //uid - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&std::get<0>(its_credentials))[i]); - } - //gid - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&std::get<1>(its_credentials))[i]); - } - } - - client_credentials_info_[_target] = its_command; -} - -void routing_manager_stub::send_client_credentials_info(const client_t _target) { - if (client_credentials_info_.find(_target) == client_credentials_info_.end()) { - return; - } +void routing_manager_stub::send_client_credentials(const client_t _target, + std::set<std::pair<uint32_t, uint32_t>> &_credentials) { std::shared_ptr<endpoint> its_endpoint = host_->find_local(_target); if (its_endpoint) { - auto its_command = client_credentials_info_[_target]; - - // File overall size - std::size_t its_size = its_command.size() - VSOMEIP_COMMAND_PAYLOAD_POS; - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, sizeof(uint32_t)); - its_size += VSOMEIP_COMMAND_PAYLOAD_POS; + protocol::update_security_credentials_command its_command; + its_command.set_client(_target); + its_command.set_credentials(_credentials); #if 0 std::stringstream msg; @@ -1052,235 +1135,66 @@ void routing_manager_stub::send_client_credentials_info(const client_t _target) VSOMEIP_INFO << msg.str(); #endif - // Send routing info or error! - if(its_command.size() <= max_local_message_size_ - || VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) { - its_endpoint->send(&its_command[0], uint32_t(its_size)); - } else { - VSOMEIP_ERROR << "Credentials info exceeds maximum message size: Can't send!"; - } - - client_credentials_info_.erase(_target); - } else { - VSOMEIP_ERROR << "Send credentials info to client 0x" << std::hex << _target - << " failed: No valid endpoint!"; - } -} - -void routing_manager_stub::create_offered_services_info(const client_t _target) { - std::vector<byte_t> its_command; - its_command.push_back(VSOMEIP_OFFERED_SERVICES_RESPONSE); - - // Sender client - client_t client = get_client(); - for (uint32_t i = 0; i < sizeof(client_t); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&client)[i]); - } - - // Overall size placeholder - byte_t size_placeholder = 0x0; - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back(size_placeholder); - } - - offered_services_info_[_target] = its_command; -} - - -void routing_manager_stub::send_client_routing_info(const client_t _target) { - if (client_routing_info_.find(_target) == client_routing_info_.end()) { - return; - } - std::shared_ptr<endpoint> its_endpoint = host_->find_local(_target); - if (its_endpoint) { - auto its_command = client_routing_info_[_target]; - - // File overall size - std::size_t its_size = its_command.size() - VSOMEIP_COMMAND_PAYLOAD_POS; - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, sizeof(uint32_t)); - its_size += VSOMEIP_COMMAND_PAYLOAD_POS; - -#if 0 - std::stringstream msg; - msg << "rms::send_routing_info to (" << std::hex << _target << "): "; - for (uint32_t i = 0; i < its_size; ++i) - msg << std::hex << std::setw(2) << std::setfill('0') << (int)its_command[i] << " "; - VSOMEIP_INFO << msg.str(); -#endif - - // Send routing info or error! - if(its_command.size() <= max_local_message_size_ - || VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) { - its_endpoint->send(&its_command[0], uint32_t(its_size)); - } else { - VSOMEIP_ERROR << "Routing info exceeds maximum message size: Can't send!"; - } - - client_routing_info_.erase(_target); - } else { - VSOMEIP_ERROR << "Send routing info to client 0x" << std::hex << _target - << " failed: No valid endpoint!"; - } -} - - -void routing_manager_stub::send_offered_services_info(const client_t _target) { - if (offered_services_info_.find(_target) == offered_services_info_.end()) { - return; - } - std::shared_ptr<endpoint> its_endpoint = host_->find_local(_target); - if (its_endpoint) { - auto its_command = offered_services_info_[_target]; - - // File overall size - std::size_t its_size = its_command.size() - VSOMEIP_COMMAND_PAYLOAD_POS; - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, sizeof(uint32_t)); - its_size += VSOMEIP_COMMAND_PAYLOAD_POS; - -#if 0 - std::stringstream msg; - msg << "rms::send_offered_services_info to (" << std::hex << _target << "): "; - for (uint32_t i = 0; i < its_size; ++i) - msg << std::hex << std::setw(2) << std::setfill('0') << (int)its_command[i] << " "; - VSOMEIP_INFO << msg.str(); -#endif - - // Send routing info or error! - if(its_command.size() <= max_local_message_size_ - || VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) { - its_endpoint->send(&its_command[0], uint32_t(its_size)); - } else { - VSOMEIP_ERROR << "Offered services info exceeds maximum message size: Can't send!"; - } - - offered_services_info_.erase(_target); - } else { - VSOMEIP_ERROR << "Send offered services info to client 0x" << std::hex << _target - << " failed: No valid endpoint!"; - } + std::vector<byte_t> its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + if(its_buffer.size() <= max_local_message_size_ + || VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) { + its_endpoint->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": Credentials info exceeds maximum message size: Can't send!"; + + } else + VSOMEIP_ERROR << __func__ + << ": update security credentials command serialization failed (" + << static_cast<int>(its_error) + << ")"; + } else + VSOMEIP_ERROR << __func__ + << ": Sending credentials to client [" + << std::hex << std::setw(4) << std::setfill('0') + << _target + << "] failed"; } -void routing_manager_stub::insert_client_routing_info(client_t _target, - routing_info_entry_e _entry, - client_t _client, service_t _service, - instance_t _instance, - major_version_t _major, - minor_version_t _minor) { - - if (client_routing_info_.find(_target) == client_routing_info_.end()) { - return; - } - - connection_matrix_[_target].insert(_client); - - auto its_command = client_routing_info_[_target]; - - // Routing Info State Change - for (uint32_t i = 0; i < sizeof(routing_info_entry_e); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&_entry)[i]); - } - - std::size_t its_size_pos = its_command.size(); - std::size_t its_entry_size = its_command.size(); - - // Client size placeholder - byte_t placeholder = 0x0; - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back(placeholder); - } - // Client - for (uint32_t i = 0; i < sizeof(client_t); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&_client)[i]); - } - - if (_entry == routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE || - _entry == routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE) { - //Service - uint32_t its_service_entry_size = uint32_t(sizeof(service_t) - + sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t)); - for (uint32_t i = 0; i < sizeof(its_service_entry_size); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&its_service_entry_size)[i]); - } - for (uint32_t i = 0; i < sizeof(service_t); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&_service)[i]); - } - // Instance - for (uint32_t i = 0; i < sizeof(instance_t); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&_instance)[i]); - } - // Major version - for (uint32_t i = 0; i < sizeof(major_version_t); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&_major)[i]); - } - // Minor version - for (uint32_t i = 0; i < sizeof(minor_version_t); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&_minor)[i]); - } - } - - // File client size - its_entry_size = its_command.size() - its_entry_size - uint32_t(sizeof(uint32_t)); - std::memcpy(&its_command[its_size_pos], &its_entry_size, sizeof(uint32_t)); +void routing_manager_stub::send_client_routing_info(const client_t _target, + protocol::routing_info_entry &_entry) { - client_routing_info_[_target] = its_command; + std::vector<protocol::routing_info_entry> its_entries; + its_entries.emplace_back(_entry); + send_client_routing_info(_target, std::move(its_entries)); } -void routing_manager_stub::insert_offered_services_info(client_t _target, - routing_info_entry_e _entry, - service_t _service, - instance_t _instance, - major_version_t _major, - minor_version_t _minor) { +void routing_manager_stub::send_client_routing_info(const client_t _target, + std::vector<protocol::routing_info_entry> &&_entries) { - if (offered_services_info_.find(_target) == offered_services_info_.end()) { - return; - } + auto its_target_endpoint = host_->find_local(_target); + if (its_target_endpoint) { - auto its_command = offered_services_info_[_target]; + protocol::routing_info_command its_command; + its_command.set_client(get_client()); + its_command.set_entries(std::move(_entries)); - // Routing Info State Change - for (uint32_t i = 0; i < sizeof(routing_info_entry_e); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&_entry)[i]); - } + std::vector<byte_t> its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); - // entry size - uint32_t its_service_entry_size = uint32_t(sizeof(service_t) - + sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t)); - for (uint32_t i = 0; i < sizeof(its_service_entry_size); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&its_service_entry_size)[i]); - } - //Service - for (uint32_t i = 0; i < sizeof(service_t); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&_service)[i]); - } - // Instance - for (uint32_t i = 0; i < sizeof(instance_t); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&_instance)[i]); - } - // Major version - for (uint32_t i = 0; i < sizeof(major_version_t); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&_major)[i]); - } - // Minor version - for (uint32_t i = 0; i < sizeof(minor_version_t); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&_minor)[i]); - } - - offered_services_info_[_target] = its_command; + if (its_error == protocol::error_e::ERROR_OK) { + its_target_endpoint->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": routing info command serialization failed (" + << static_cast<int>(its_error) + << ")"; + } else + VSOMEIP_ERROR << __func__ + << ": Sending routing info to client [" + << std::hex << std::setw(4) << std::setfill('0') + << _target + << "] failed"; } void routing_manager_stub::distribute_credentials(client_t _hoster, service_t _service, instance_t _instance) { @@ -1298,38 +1212,30 @@ void routing_manager_stub::distribute_credentials(client_t _hoster, service_t _s } // search for UID / GID linked with the client ID that offers the requested services - std::pair<uint32_t, uint32_t> its_uid_gid; - if (security::get()->get_client_to_uid_gid_mapping(_hoster, its_uid_gid)) { + vsomeip_sec_client_t its_sec_client; + if (policy_manager_impl::get()->get_client_to_sec_client_mapping(_hoster, its_sec_client)) { + std::pair<uint32_t, uint32_t> its_uid_gid; + its_uid_gid.first = its_sec_client.client.uds_client.user; + its_uid_gid.second = its_sec_client.client.uds_client.group; its_credentials.insert(its_uid_gid); for (auto its_requesting_client : its_requesting_clients) { - std::pair<uint32_t, uint32_t> its_requester_uid_gid; - if (security::get()->get_client_to_uid_gid_mapping(its_requesting_client, its_requester_uid_gid)) { - if (its_uid_gid != its_requester_uid_gid) { - create_client_credentials_info(its_requesting_client); - insert_client_credentials_info(its_requesting_client, its_credentials); - send_client_credentials_info(its_requesting_client); - } + vsomeip_sec_client_t its_requester_sec_client; + if (policy_manager_impl::get()->get_client_to_sec_client_mapping( + its_requesting_client, its_requester_sec_client)) { + if (!utility::compare(its_sec_client, its_requester_sec_client)) + send_client_credentials(its_requesting_client, its_credentials); } } } } -void routing_manager_stub::inform_provider(client_t _hoster, service_t _service, +void routing_manager_stub::inform_requesters(client_t _hoster, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, - routing_info_entry_e _entry) { + protocol::routing_info_entry_type_e _type, bool _inform_service) { - if (_hoster != VSOMEIP_ROUTING_CLIENT - && _hoster != host_->get_client()) { - create_client_routing_info(_hoster); - insert_client_routing_info(_hoster, _entry, _hoster, - _service, _instance, _major, _minor); - send_client_routing_info(_hoster); - } -}; + boost::asio::ip::address its_address; + port_t its_port; -void routing_manager_stub::inform_requesters(client_t _hoster, service_t _service, - instance_t _instance, major_version_t _major, minor_version_t _minor, - routing_info_entry_e _entry, bool _inform_service) { for (auto its_client : service_requests_) { auto its_service = its_client.second.find(_service); if (its_service != its_client.second.end()) { @@ -1338,31 +1244,39 @@ void routing_manager_stub::inform_requesters(client_t _hoster, service_t _servic if (_inform_service) { if (_hoster != VSOMEIP_ROUTING_CLIENT && _hoster != host_->get_client()) { - if (!is_already_connected(_hoster, its_client.first)) { - create_client_routing_info(_hoster); - insert_client_routing_info(_hoster, - routing_info_entry_e::RIE_ADD_CLIENT, - its_client.first); - send_client_routing_info(_hoster); + if (!is_connected(_hoster, its_client.first)) { + add_connection(_hoster, its_client.first); + protocol::routing_info_entry its_entry; + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_ADD_CLIENT); + its_entry.set_client(its_client.first); + if (host_->get_guest(its_client.first, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } + send_client_routing_info(_hoster, its_entry); } } } if (its_client.first != VSOMEIP_ROUTING_CLIENT && its_client.first != get_client()) { - create_client_routing_info(its_client.first); - insert_client_routing_info(its_client.first, _entry, _hoster, - _service, _instance, _major, _minor); - send_client_routing_info(its_client.first); + add_connection(its_client.first, _hoster); + protocol::routing_info_entry its_entry; + its_entry.set_type(_type); + its_entry.set_client(_hoster); + if ((_type == protocol::routing_info_entry_type_e::RIE_ADD_CLIENT + || _type == protocol::routing_info_entry_type_e::RIE_ADD_SERVICE_INSTANCE) + && host_->get_guest(_hoster, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } + its_entry.add_service({ _service, _instance, _major, _minor} ); + send_client_routing_info(its_client.first, its_entry); } } } } } -bool routing_manager_stub::is_already_connected(client_t _source, client_t _sink) { - return connection_matrix_[_source].find(_sink) != connection_matrix_[_source].end(); -} - void routing_manager_stub::broadcast(const std::vector<byte_t> &_command) const { std::lock_guard<std::mutex> its_guard(routing_info_mutex_); for (const auto& a : routing_info_) { @@ -1376,42 +1290,50 @@ void routing_manager_stub::broadcast(const std::vector<byte_t> &_command) const } } -bool routing_manager_stub::send_subscribe(const std::shared_ptr<endpoint>& _target, - client_t _client, service_t _service, instance_t _instance, +bool routing_manager_stub::send_subscribe( + const std::shared_ptr<endpoint>& _target, client_t _client, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, - event_t _event, remote_subscription_id_t _id) { + event_t _event, const std::shared_ptr<debounce_filter_t> &_filter, + remote_subscription_id_t _id) { + + bool has_sent(false); + if (_target) { - byte_t its_command[VSOMEIP_SUBSCRIBE_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_SUBSCRIBE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6] = _major; - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 7], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 9], &_id, - sizeof(_id)); - - return _target->send(its_command, sizeof(its_command)); + + protocol::subscribe_command its_command; + its_command.set_client(_client); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_major(_major); + its_command.set_event(_event); + its_command.set_filter(_filter); + its_command.set_pending_id(_id); + + std::vector<byte_t> its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + has_sent = _target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": subscribe command serialization failed (" + << std::dec << int(its_error) << ")"; + } else { - VSOMEIP_WARNING << __func__ << " Couldn't send subscription to local client [" - << std::hex << std::setw(4) << std::setfill('0') << _service << "." - << std::hex << std::setw(4) << std::setfill('0') << _instance << "." - << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "." - << std::hex << std::setw(4) << std::setfill('0') << _event << "]" - << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0') - << _client; - return false; + VSOMEIP_WARNING << __func__ + << " Couldn't send subscription to local client [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "." + << std::hex << std::setw(4) << std::setfill('0') << _event << "]" + << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0') + << _client; } + + return (has_sent); } bool routing_manager_stub::send_unsubscribe( @@ -1419,37 +1341,41 @@ bool routing_manager_stub::send_unsubscribe( client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, remote_subscription_id_t _id) { + + bool has_sent(false); + if (_target) { - byte_t its_command[VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UNSUBSCRIBE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_id, - sizeof(_id)); - - return _target->send(its_command, sizeof(its_command)); + + protocol::unsubscribe_command its_command; + its_command.set_client(_client); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_event(_event); + its_command.set_pending_id(_id); + + std::vector<byte_t> its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + has_sent = _target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": unsubscribe command serialization failed (" + << std::dec << int(its_error) << ")"; } else { - VSOMEIP_WARNING << __func__ << " Couldn't send unsubscription to local client [" - << std::hex << std::setw(4) << std::setfill('0') << _service << "." - << std::hex << std::setw(4) << std::setfill('0') << _instance << "." - << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "." - << std::hex << std::setw(4) << std::setfill('0') << _event << "]" - << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0') - << _client; - return false; + VSOMEIP_WARNING << __func__ + << " Couldn't send unsubscription to local client [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "." + << std::hex << std::setw(4) << std::setfill('0') << _event << "]" + << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0') + << _client; } + + return (has_sent); } bool routing_manager_stub::send_expired_subscription( @@ -1457,100 +1383,94 @@ bool routing_manager_stub::send_expired_subscription( client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, remote_subscription_id_t _id) { + + bool has_sent(false); + if (_target) { - byte_t its_command[VSOMEIP_EXPIRED_SUBSCRIPTION_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_EXPIRED_SUBSCRIPTION_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_EXPIRED_SUBSCRIPTION; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_id, - sizeof(_id)); - - return _target->send(its_command, sizeof(its_command)); + + protocol::expire_command its_command; + its_command.set_client(_client); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_event(_event); + its_command.set_pending_id(_id); + + std::vector<byte_t> its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + has_sent = _target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": unsubscribe command serialization failed (" + << std::dec << int(its_error) << ")"; } else { - VSOMEIP_WARNING << __func__ << " Couldn't send expired subscription to local client [" - << std::hex << std::setw(4) << std::setfill('0') << _service << "." - << std::hex << std::setw(4) << std::setfill('0') << _instance << "." - << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "." - << std::hex << std::setw(4) << std::setfill('0') << _event << "]" - << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0') - << _client; - return false; + VSOMEIP_WARNING << __func__ + << " Couldn't send expired subscription to local client [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "." + << std::hex << std::setw(4) << std::setfill('0') << _event << "]" + << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0') + << _client; } + + return (has_sent); } void routing_manager_stub::send_subscribe_ack(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { - std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client); - if (its_endpoint) { - byte_t its_command[VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - client_t this_client = get_client(); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE_ACK; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &this_client, - sizeof(this_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10], - &PENDING_SUBSCRIPTION_ID, sizeof(PENDING_SUBSCRIPTION_ID)); - - its_endpoint->send(&its_command[0], sizeof(its_command)); + std::shared_ptr<endpoint> its_target = host_->find_local(_client); + if (its_target) { + + protocol::subscribe_ack_command its_command; + its_command.set_client(get_client()); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_subscriber(_client); + its_command.set_event(_event); + + std::vector<byte_t> its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + (void)its_target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": subscribe ack command serialization failed (" + << std::dec << int(its_error) << ")"; } } void routing_manager_stub::send_subscribe_nack(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { - std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client); - if (its_endpoint) { - byte_t its_command[VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - client_t this_client = get_client(); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE_NACK; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &this_client, - sizeof(this_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10], - &PENDING_SUBSCRIPTION_ID, sizeof(PENDING_SUBSCRIPTION_ID)); - - its_endpoint->send(&its_command[0], sizeof(its_command)); + std::shared_ptr<endpoint> its_target = host_->find_local(_client); + if (its_target) { + + protocol::subscribe_nack_command its_command; + its_command.set_client(get_client()); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_subscriber(_client); + its_command.set_event(_event); + + std::vector<byte_t> its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + (void)its_target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": subscribe ack command serialization failed (" + << std::dec << int(its_error) << ")"; } } @@ -1576,7 +1496,19 @@ bool routing_manager_stub::contained_in_routing_info( // Watchdog void routing_manager_stub::broadcast_ping() const { - broadcast(its_ping_); + + protocol::ping_command its_command; + + std::vector<byte_t> its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) + broadcast(its_buffer); + else + VSOMEIP_ERROR << __func__ + << ": ping command serialization failed (" + << std::dec << int(its_error) << ")"; } void routing_manager_stub::on_pong(client_t _client) { @@ -1656,8 +1588,8 @@ void routing_manager_stub::create_local_receiver() { if (local_receiver_) { return; } -#ifndef _WIN32 - else if (!security::get()->check_credentials(get_client(), getuid(), getgid())) { +#if defined(__linux__) || defined(ANDROID) + else if (!policy_manager_impl::get()->check_credentials(get_client(), host_->get_sec_client())) { VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client() << " : routing_manager_stub::create_local_receiver: isn't allowed" << " to create a server endpoint due to credential check failed!"; @@ -1666,56 +1598,71 @@ void routing_manager_stub::create_local_receiver() { #endif local_receiver_ = std::static_pointer_cast<endpoint_manager_base>( host_->get_endpoint_manager())->create_local_server(shared_from_this()); - local_receiver_->start(); + + if (local_receiver_) + local_receiver_->start(); } bool routing_manager_stub::send_ping(client_t _client) { - std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client); - if (!its_endpoint) { - return false; - } - { + bool has_sent(false); + + std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client); + if (its_endpoint) { std::lock_guard<std::mutex> its_lock(pinged_clients_mutex_); if (pinged_clients_.find(_client) != pinged_clients_.end()) { // client was already pinged: don't ping again and wait for answer // or timeout of previous ping. - return true; - } - - boost::system::error_code ec; - pinged_clients_timer_.cancel(ec); - if (ec) { - VSOMEIP_ERROR << "routing_manager_stub::send_ping cancellation of " - "timer failed: " << ec.message(); - } - const std::chrono::steady_clock::time_point now( - std::chrono::steady_clock::now()); + has_sent = true; + } else { + boost::system::error_code ec; + pinged_clients_timer_.cancel(ec); + if (ec) { + VSOMEIP_ERROR << "routing_manager_stub::send_ping cancellation of " + "timer failed: " << ec.message(); + } + const std::chrono::steady_clock::time_point now( + std::chrono::steady_clock::now()); - std::chrono::milliseconds next_timeout(configured_watchdog_timeout_); - for (const auto &tp : pinged_clients_) { - const std::chrono::milliseconds its_clients_timeout = - std::chrono::duration_cast<std::chrono::milliseconds>( - now - tp.second); - if (next_timeout > its_clients_timeout) { - next_timeout = its_clients_timeout; + std::chrono::milliseconds next_timeout(configured_watchdog_timeout_); + for (const auto &tp : pinged_clients_) { + const std::chrono::milliseconds its_clients_timeout = + std::chrono::duration_cast<std::chrono::milliseconds>( + now - tp.second); + if (next_timeout > its_clients_timeout) { + next_timeout = its_clients_timeout; + } } - } - pinged_clients_[_client] = now; + pinged_clients_[_client] = now; - ec.clear(); - pinged_clients_timer_.expires_from_now(next_timeout, ec); - if (ec) { - VSOMEIP_ERROR<< "routing_manager_stub::send_ping setting " - "expiry time of timer failed: " << ec.message(); + ec.clear(); + pinged_clients_timer_.expires_from_now(next_timeout, ec); + if (ec) { + VSOMEIP_ERROR << "routing_manager_stub::send_ping setting " + "expiry time of timer failed: " << ec.message(); + } + pinged_clients_timer_.async_wait( + std::bind(&routing_manager_stub::on_ping_timer_expired, this, + std::placeholders::_1)); + + protocol::ping_command its_command; + + std::vector<byte_t> its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) + has_sent = its_endpoint->send(&its_buffer[0], uint32_t(its_buffer.size())); + else + VSOMEIP_ERROR << __func__ + << ": ping command serialization failed (" + << std::dec << int(its_error) << ")"; } - pinged_clients_timer_.async_wait( - std::bind(&routing_manager_stub::on_ping_timer_expired, this, - std::placeholders::_1)); - return its_endpoint->send(&its_ping_[0], uint32_t(its_ping_.size())); } + + return (has_sent); } void routing_manager_stub::on_ping_timer_expired( @@ -1821,19 +1768,33 @@ bool routing_manager_stub::is_registered(client_t _client) const { } void routing_manager_stub::update_registration(client_t _client, - registration_type_e _type) { + registration_type_e _type, + const boost::asio::ip::address &_address, port_t _port) { + + std::stringstream its_client; + its_client << std::hex << std::setw(4) << std::setfill('0') + << _client; + + if (_port > 0 && _port < ILLEGAL_PORT) { + its_client << " @ " << _address.to_string() << ":" << std::dec << _port; + } VSOMEIP_INFO << "Application/Client " - << std::hex << std::setw(4) << std::setfill('0') << _client + << its_client.str() << " is " << (_type == registration_type_e::REGISTER ? "registering." : "deregistering."); if (_type != registration_type_e::REGISTER) { - security::get()->remove_client_to_uid_gid_mapping(_client); + policy_manager_impl::get()->remove_client_to_sec_client_mapping(_client); + } else { + if (_port > 0 && _port < ILLEGAL_PORT) + host_->add_guest(_client, _address, _port); } if (_type == registration_type_e::DEREGISTER) { + host_->remove_guest(_client); + // If we receive a DEREGISTER client command // the endpoint error handler is not longer needed // as the client is going down anyways. @@ -1868,15 +1829,15 @@ client_t routing_manager_stub::get_client() const { return host_->get_client(); } -void routing_manager_stub::handle_credentials(const client_t _client, std::set<service_data_t>& _requests) { +void routing_manager_stub::handle_credentials(const client_t _client, std::set<protocol::service> &_requests) { if (!_requests.size()) { return; } std::lock_guard<std::mutex> its_guard(routing_info_mutex_); std::set<std::pair<uint32_t, uint32_t>> its_credentials; - std::pair<uint32_t, uint32_t> its_requester_uid_gid; - if (security::get()->get_client_to_uid_gid_mapping(_client, its_requester_uid_gid)) { + vsomeip_sec_client_t its_requester_sec_client; + if (policy_manager_impl::get()->get_client_to_sec_client_mapping(_client, its_requester_sec_client)) { // determine credentials of offering clients using current routing info std::set<client_t> its_offering_clients; @@ -1891,65 +1852,79 @@ void routing_manager_stub::handle_credentials(const client_t _client, std::set<s // search for UID / GID linked with the client ID that offers the requested services for (auto its_offering_client : its_offering_clients) { - std::pair<uint32_t, uint32_t> its_uid_gid; - if (security::get()->get_client_to_uid_gid_mapping(its_offering_client, its_uid_gid)) { - if (its_uid_gid != its_requester_uid_gid) { - its_credentials.insert(std::make_pair(std::get<0>(its_uid_gid), std::get<1>(its_uid_gid))); + vsomeip_sec_client_t its_sec_client; + if (policy_manager_impl::get()->get_client_to_sec_client_mapping(its_offering_client, its_sec_client)) { + if (its_sec_client.client_type == VSOMEIP_CLIENT_UDS + && !utility::compare(its_sec_client, its_requester_sec_client)) { + + its_credentials.insert(std::make_pair( + its_sec_client.client.uds_client.user, its_sec_client.client.uds_client.group)); } } } // send credentials to clients - if (!its_credentials.empty()) { - create_client_credentials_info(_client); - insert_client_credentials_info(_client, its_credentials); - send_client_credentials_info(_client); - } + if (!its_credentials.empty()) + send_client_credentials(_client, its_credentials); } } -void routing_manager_stub::handle_requests(const client_t _client, std::set<service_data_t>& _requests) { - if (!_requests.size()) { +void routing_manager_stub::handle_requests(const client_t _client, std::set<protocol::service> &_requests) { + + if (_requests.empty()) return; - } - bool service_available(false); + + boost::asio::ip::address its_address; + port_t its_port; + + std::vector<protocol::routing_info_entry> its_entries; std::lock_guard<std::mutex> its_guard(routing_info_mutex_); - create_client_routing_info(_client); + for (auto request : _requests) { service_requests_[_client][request.service_][request.instance_] - = std::make_pair(request.major_, request.minor_); + = std::make_pair(request.major_, request.minor_); if (request.instance_ == ANY_INSTANCE) { std::set<client_t> its_clients = host_->find_local_clients(request.service_, request.instance_); - // insert VSOMEIP_ROUTING_CLIENT to check wether service is remotely offered + // insert VSOMEIP_ROUTING_CLIENT to check whether service is remotely offered its_clients.insert(VSOMEIP_ROUTING_CLIENT); for (const client_t c : its_clients) { if (c != VSOMEIP_ROUTING_CLIENT && c != host_->get_client()) { - if (!is_already_connected(c, _client)) { + if (!is_connected(c, _client)) { + add_connection(c, _client); + + protocol::routing_info_entry its_entry; + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_ADD_CLIENT); + its_entry.set_client(_client); + if (host_->get_guest(_client, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } if (_client == c) { - service_available = true; - insert_client_routing_info(c, - routing_info_entry_e::RIE_ADD_CLIENT, _client); + its_entries.emplace_back(its_entry); } else { - create_client_routing_info(c); - insert_client_routing_info(c, - routing_info_entry_e::RIE_ADD_CLIENT, _client); - send_client_routing_info(c); + send_client_routing_info(c, its_entry); } } } - if (_client != VSOMEIP_ROUTING_CLIENT && - _client != host_->get_client()) { + if (_client != VSOMEIP_ROUTING_CLIENT && _client != host_->get_client()) { const auto found_client = routing_info_.find(c); if (found_client != routing_info_.end()) { const auto found_service = found_client->second.second.find(request.service_); if (found_service != found_client->second.second.end()) { for (auto instance : found_service->second) { - service_available = true; - insert_client_routing_info(_client, - routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, - c, request.service_, instance.first, - instance.second.first, instance.second.second); + add_connection(_client, c); + + protocol::routing_info_entry its_entry; + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_ADD_SERVICE_INSTANCE); + its_entry.set_client(c); + if (host_->get_guest(c, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } + its_entry.add_service({ request.service_, instance.first, + instance.second.first, instance.second.second }); + its_entries.emplace_back(its_entry); } } } @@ -1963,38 +1938,46 @@ void routing_manager_stub::handle_requests(const client_t _client, std::set<serv if (found_service != found_client->second.second.end()) { const auto found_instance = found_service->second.find(request.instance_); if (found_instance != found_service->second.end()) { - if (c != VSOMEIP_ROUTING_CLIENT && - c != host_->get_client()) { - if (!is_already_connected(c, _client)) { + if (c != VSOMEIP_ROUTING_CLIENT && c != host_->get_client()) { + if (!is_connected(c, _client)) { + add_connection(c, _client); + + protocol::routing_info_entry its_entry; + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_ADD_CLIENT); + its_entry.set_client(_client); + if (host_->get_guest(_client, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } if (_client == c) { - service_available = true; - insert_client_routing_info(c, - routing_info_entry_e::RIE_ADD_CLIENT, _client); + its_entries.emplace_back(its_entry); } else { - create_client_routing_info(c); - insert_client_routing_info(c, - routing_info_entry_e::RIE_ADD_CLIENT, _client); - send_client_routing_info(c); + send_client_routing_info(c, its_entry); } } } - if (_client != VSOMEIP_ROUTING_CLIENT && - _client != host_->get_client()) { - service_available = true; - insert_client_routing_info(_client, - routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, - c, request.service_, request.instance_, - found_instance->second.first, - found_instance->second.second); + if (_client != VSOMEIP_ROUTING_CLIENT && _client != host_->get_client()) { + add_connection(_client, c); + + protocol::routing_info_entry its_entry; + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_ADD_SERVICE_INSTANCE); + its_entry.set_client(c); + if (host_->get_guest(c, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } + its_entry.add_service({ request.service_, request.instance_, + found_instance->second.first, found_instance->second.second }); + its_entries.emplace_back(its_entry); } } } } } } - if (service_available) { - send_client_routing_info(_client); - } + + if (!its_entries.empty()) + send_client_routing_info(_client, std::move(its_entries)); } void routing_manager_stub::on_client_id_timer_expired(boost::system::error_code const &_error) { @@ -2029,34 +2012,37 @@ void routing_manager_stub::print_endpoint_status() const { if (local_receiver_) { local_receiver_->print_status(); } - if (endpoint_) { - endpoint_->print_status(); + if (root_) { + root_->print_status(); } } -bool routing_manager_stub::send_provided_event_resend_request(client_t _client, - pending_remote_offer_id_t _id) { +bool routing_manager_stub::send_provided_event_resend_request( + client_t _client, pending_remote_offer_id_t _id) { + std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client); if (its_endpoint) { - byte_t its_command[VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE]; - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_RESEND_PROVIDED_EVENTS; - const client_t routing_client(VSOMEIP_ROUTING_CLIENT); - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &routing_client, - sizeof(routing_client)); - std::uint32_t its_size = sizeof(pending_remote_offer_id_t); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_id, - sizeof(pending_remote_offer_id_t)); - return its_endpoint->send(its_command, sizeof(its_command)); + + protocol::resend_provided_events_command its_command; + its_command.set_client(VSOMEIP_ROUTING_CLIENT); + its_command.set_remote_offer_id(_id); + + std::vector<byte_t> its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) + return (its_endpoint->send(&its_buffer[0], uint32_t(its_buffer.size()))); } else { VSOMEIP_WARNING << __func__ << " Couldn't send provided event resend " "request to local client: 0x" << std::hex << std::setw(4) << std::setfill('0') << _client; - return false; } + + return (false); } +#ifndef VSOMEIP_DISABLE_SECURITY bool routing_manager_stub::is_policy_cached(uint32_t _uid) { { std::lock_guard<std::mutex> its_lock(updated_security_policies_mutex_); @@ -2089,11 +2075,16 @@ void routing_manager_stub::policy_cache_remove(uint32_t _uid) { bool routing_manager_stub::send_update_security_policy_request(client_t _client, pending_security_update_id_t _update_id, uint32_t _uid, const std::shared_ptr<payload>& _payload) { (void)_uid; + std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client); if (its_endpoint) { std::vector<byte_t> its_command; // command - its_command.push_back(VSOMEIP_UPDATE_SECURITY_POLICY); + its_command.push_back(byte_t(protocol::id_e::UPDATE_SECURITY_POLICY_ID)); + + // version + its_command.push_back(0x00); + its_command.push_back(0x00); // client ID for (uint32_t i = 0; i < sizeof(client_t); ++i) { @@ -2123,89 +2114,74 @@ bool routing_manager_stub::send_update_security_policy_request(client_t _client, } bool routing_manager_stub::send_cached_security_policies(client_t _client) { - std::vector<byte_t> its_command; - std::size_t its_size(0); - std::lock_guard<std::mutex> its_lock(updated_security_policies_mutex_); - uint32_t its_policy_count = uint32_t(updated_security_policies_.size()); + std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client); + if (its_endpoint) { - if (!its_policy_count) { - return true; - } - VSOMEIP_INFO << __func__ << " Distributing [" - << std::dec << its_policy_count - << "] security policy updates to registering client: " - << std::hex << _client; + std::lock_guard<std::mutex> its_lock(updated_security_policies_mutex_); + if (!updated_security_policies_.empty()) { - // command - its_command.push_back(VSOMEIP_DISTRIBUTE_SECURITY_POLICIES); + VSOMEIP_INFO << __func__ << " Distributing [" + << std::dec << updated_security_policies_.size() + << "] security policy updates to registering client: " + << std::hex << _client; - // client ID - client_t its_client = get_client(); - for (uint32_t i = 0; i < sizeof(client_t); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&its_client)[i]); - } + protocol::distribute_security_policies_command its_command; + its_command.set_client(get_client()); + its_command.set_payloads(updated_security_policies_); - //overall size (placeholder - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back(0x00); - } + std::vector<byte_t> its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); - // number of policies contained in message - for (uint32_t i = 0; i < sizeof(its_policy_count); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&its_policy_count)[i]); - } + if (its_error == protocol::error_e::ERROR_OK) + return its_endpoint->send(its_buffer.data(), uint32_t(its_buffer.size())); - for (const auto& its_uid_gid : updated_security_policies_) { - // policy payload length including gid and uid - std::uint32_t its_length = uint32_t(its_uid_gid.second->get_length()); - for (uint32_t i = 0; i < sizeof(its_length); ++i) { - its_command.push_back( - reinterpret_cast<const byte_t*>(&its_length)[i]); + VSOMEIP_ERROR << __func__ + << ": serializing distribute security policies (" + << static_cast<int>(its_error) + << ")"; } - // payload - its_command.insert(its_command.end(), its_uid_gid.second->get_data(), - its_uid_gid.second->get_data() + its_uid_gid.second->get_length()); - } - // File overall size - its_size = its_command.size() - VSOMEIP_COMMAND_PAYLOAD_POS; - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, sizeof(uint32_t)); + } else + VSOMEIP_WARNING << __func__ + << ": could not send cached security policies to registering client: 0x" + << std::hex << std::setw(4) << std::setfill('0') << _client; + + return (false); +} + +bool routing_manager_stub::send_remove_security_policy_request( + client_t _client, pending_security_update_id_t _update_id, + uint32_t _uid, uint32_t _gid) { + + protocol::remove_security_policy_command its_command; + its_command.set_client(_client); + its_command.set_update_id(_update_id); + its_command.set_uid(_uid); + its_command.set_gid(_gid); + + std::vector<byte_t> its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client); + if (its_endpoint) + return (its_endpoint->send(&its_buffer[0], uint32_t(its_buffer.size()))); + else + VSOMEIP_ERROR << __func__ + << ": cannot find local client endpoint for client " + << std::hex << std::setw(4) << std::setfill('0') + << _client; + } else + VSOMEIP_ERROR << __func__ + << ": remove security policy command serialization failed (" + << std::dec << static_cast<int>(its_error) + << ")"; - std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client); - if (its_endpoint) { - return its_endpoint->send(its_command.data(), uint32_t(its_command.size())); - } else { - VSOMEIP_WARNING << __func__ << " Couldn't send cached security policies " - " to registering client: 0x" - << std::hex << std::setw(4) << std::setfill('0') << _client; - return false; - } -} + return (false); -bool routing_manager_stub::send_remove_security_policy_request( client_t _client, pending_security_update_id_t _update_id, - uint32_t _uid, uint32_t _gid) { - std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client); - if (its_endpoint) { - byte_t its_command[VSOMEIP_REMOVE_SECURITY_POLICY_COMMAND_SIZE]; - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_REMOVE_SECURITY_POLICY; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, - sizeof(client_t)); - std::uint32_t its_size = sizeof(_update_id) + sizeof(_uid) + sizeof(_gid); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_update_id, - sizeof(uint32_t)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_uid, - sizeof(uint32_t)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_gid, - sizeof(uint32_t)); - return its_endpoint->send(its_command, sizeof(its_command)); - } else { - return false; - } } bool @@ -2219,7 +2195,7 @@ routing_manager_stub::add_requester_policies(uid_t _uid, gid_t _gid, if (found_gid != found_uid->second.end()) { found_gid->second.insert(_policies.begin(), _policies.end()); } else { - found_uid->second.insert(std::make_pair(_gid, _policies)); + found_uid->second[_gid] = _policies; } } else { requester_policies_[_uid][_gid] = _policies; @@ -2228,7 +2204,7 @@ routing_manager_stub::add_requester_policies(uid_t _uid, gid_t _gid, // Check whether clients with uid/gid are already registered. // If yes, update their policy std::unordered_set<client_t> its_clients; - security::get()->get_clients(_uid, _gid, its_clients); + policy_manager_impl::get()->get_clients(_uid, _gid, its_clients); if (!its_clients.empty()) return send_requester_policies(its_clients, _policies); @@ -2263,7 +2239,7 @@ routing_manager_stub::get_requester_policies(uid_t _uid, gid_t _gid, void routing_manager_stub::add_pending_security_update_handler( - pending_security_update_id_t _id, security_update_handler_t _handler) { + pending_security_update_id_t _id, const security_update_handler_t &_handler) { std::lock_guard<std::recursive_mutex> its_lock(security_update_handlers_mutex_); security_update_handlers_[_id] = _handler; @@ -2304,7 +2280,13 @@ routing_manager_stub::send_requester_policies(const std::unordered_set<client_t> std::vector<byte_t> its_policy_data; if (p->serialize(its_policy_data)) { std::vector<byte_t> its_message; - its_message.push_back(VSOMEIP_UPDATE_SECURITY_POLICY_INT); + its_message.push_back(byte_t(protocol::id_e::UPDATE_SECURITY_POLICY_INT_ID)); + + // version + its_message.push_back(0); + its_message.push_back(0); + + // client identifier its_message.push_back(0); its_message.push_back(0); @@ -2322,7 +2304,7 @@ routing_manager_stub::send_requester_policies(const std::unordered_set<client_t> its_message.insert(its_message.end(), its_policy_data.begin(), its_policy_data.end()); - for (const auto& c : _clients) { + for (const auto c : _clients) { std::shared_ptr<endpoint> its_endpoint = host_->find_local(c); if (its_endpoint) its_endpoint->send(&its_message[0], static_cast<uint32_t>(its_message.size())); @@ -2401,11 +2383,11 @@ bool routing_manager_stub::update_security_policy_configuration( policy_cache_add(_uid, _payload); // update security policy from configuration - security::get()->update_security_policy(_uid, _gid, _policy); + policy_manager_impl::get()->update_security_policy(_uid, _gid, _policy); // Build requester policies for the services offered by the new policy std::set<std::shared_ptr<policy> > its_requesters; - security::get()->get_requester_policies(_policy, its_requesters); + policy_manager_impl::get()->get_requester_policies(_policy, its_requesters); // and add them to the requester policy cache add_requester_policies(_uid, _gid, its_requesters); @@ -2464,7 +2446,7 @@ bool routing_manager_stub::remove_security_policy_configuration( // remove security policy from configuration (only if there was a updateACL call before) if (is_policy_cached(_uid)) { - if (!security::get()->remove_security_policy(_uid, _gid)) { + if (!policy_manager_impl::get()->remove_security_policy(_uid, _gid)) { _handler(security_update_state_e::SU_UNKNOWN_USER_ID); ret = false; } else { @@ -2611,13 +2593,33 @@ void routing_manager_stub::on_security_update_response( } } } +#endif // !VSOMEIP_DISABLE_SECURITY void routing_manager_stub::send_suspend() const { - static const std::vector<byte_t> its_suspend( - { VSOMEIP_SUSPEND, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); + protocol::suspend_command its_command; + + std::vector<byte_t> its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); - broadcast(its_suspend); + if (its_error == protocol::error_e::ERROR_OK) + broadcast(its_buffer); + else + VSOMEIP_ERROR << __func__ + << ": suspend command serialization failed (" + << std::dec << int(its_error) << ")"; +} + +void +routing_manager_stub::remove_subscriptions(port_t _local_port, + const boost::asio::ip::address &_remote_address, + port_t _remote_port) { + + (void)_local_port; + (void)_remote_address; + (void)_remote_port; + // dummy method to implement routing_host interface } } // namespace vsomeip_v3 |