summaryrefslogtreecommitdiff
path: root/implementation/routing/src/routing_manager_stub.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'implementation/routing/src/routing_manager_stub.cpp')
-rw-r--r--implementation/routing/src/routing_manager_stub.cpp2550
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