1 // Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
2 // This Source Code Form is subject to the terms of the Mozilla Public
3 // License, v. 2.0. If a copy of the MPL was not distributed with this
4 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
6 #include <chrono>
7 #include <functional>
8 #include <iomanip>
9 #include <forward_list>
10
11 #include <boost/system/error_code.hpp>
12
13 #include <vsomeip/constants.hpp>
14 #include <vsomeip/primitive_types.hpp>
15 #include <vsomeip/runtime.hpp>
16 #include <vsomeip/error.hpp>
17 #include <vsomeip/internal/logger.hpp>
18
19 #include "../include/routing_manager_stub.hpp"
20 #include "../include/routing_manager_stub_host.hpp"
21 #include "../include/remote_subscription.hpp"
22 #include "../../configuration/include/configuration.hpp"
23 #include "../../security/include/security.hpp"
24
25 #include "../../endpoints/include/local_server_endpoint_impl.hpp"
26 #include "../../endpoints/include/endpoint_manager_impl.hpp"
27 #include "../../utility/include/byteorder.hpp"
28 #include "../../utility/include/utility.hpp"
29 #include "../implementation/message/include/payload_impl.hpp"
30
31 namespace vsomeip_v3 {
32
33 const std::vector<byte_t> routing_manager_stub::its_ping_(
34 { VSOMEIP_PING, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
35
routing_manager_stub(routing_manager_stub_host * _host,const std::shared_ptr<configuration> & _configuration)36 routing_manager_stub::routing_manager_stub(
37 routing_manager_stub_host *_host,
38 const std::shared_ptr<configuration>& _configuration) :
39 host_(_host),
40 io_(_host->get_io()),
41 watchdog_timer_(_host->get_io()),
42 client_id_timer_(_host->get_io()),
43 endpoint_(nullptr),
44 local_receiver_(nullptr),
45 configuration_(_configuration),
46 is_socket_activated_(false),
47 client_registration_running_(false),
48 max_local_message_size_(configuration_->get_max_message_size_local()),
49 configured_watchdog_timeout_(configuration_->get_watchdog_timeout()),
50 pinged_clients_timer_(io_),
51 pending_security_update_id_(0) {
52 }
53
~routing_manager_stub()54 routing_manager_stub::~routing_manager_stub() {
55 }
56
init()57 void routing_manager_stub::init() {
58 init_routing_endpoint();
59 }
60
start()61 void routing_manager_stub::start() {
62 {
63 std::lock_guard<std::mutex> its_lock(used_client_ids_mutex_);
64 used_client_ids_ = utility::get_used_client_ids();
65 // Wait VSOMEIP_MAX_CONNECT_TIMEOUT * 2 and expect after that time
66 // that all client_ids are used have to be connected to the routing.
67 // Otherwise they can be marked as "erroneous client".
68 client_id_timer_.expires_from_now(std::chrono::milliseconds(VSOMEIP_MAX_CONNECT_TIMEOUT * 2));
69 client_id_timer_.async_wait(
70 std::bind(
71 &routing_manager_stub::on_client_id_timer_expired,
72 std::dynamic_pointer_cast<routing_manager_stub>(shared_from_this()),
73 std::placeholders::_1));
74 }
75
76 if (!endpoint_) {
77 // application has been stopped and started again
78 init_routing_endpoint();
79 }
80 if (endpoint_) {
81 endpoint_->start();
82 }
83
84 client_registration_running_ = true;
85 client_registration_thread_ = std::make_shared<std::thread>(
86 std::bind(&routing_manager_stub::client_registration_func, this));
87
88 if (configuration_->is_watchdog_enabled()) {
89 VSOMEIP_INFO << "Watchdog is enabled : Timeout in ms = "
90 << configuration_->get_watchdog_timeout()
91 << " : Allowed missing pongs = "
92 << configuration_->get_allowed_missing_pongs()
93 << ".";
94 start_watchdog();
95 } else {
96 VSOMEIP_INFO << "Watchdog is disabled!";
97 }
98
99 {
100 std::lock_guard<std::mutex> its_lock(routing_info_mutex_);
101 routing_info_[host_->get_client()].first = 0;
102 }
103 }
104
stop()105 void routing_manager_stub::stop() {
106 {
107 std::lock_guard<std::mutex> its_lock(client_registration_mutex_);
108 client_registration_running_ = false;
109 client_registration_condition_.notify_one();
110 }
111 if (client_registration_thread_->joinable()) {
112 client_registration_thread_->join();
113 }
114
115 {
116 std::lock_guard<std::mutex> its_lock(watchdog_timer_mutex_);
117 watchdog_timer_.cancel();
118 }
119
120 {
121 std::lock_guard<std::mutex> its_lock(used_client_ids_mutex_);
122 client_id_timer_.cancel();
123 }
124
125 if( !is_socket_activated_) {
126 endpoint_->stop();
127 endpoint_ = nullptr;
128 std::stringstream its_endpoint_path;
129 its_endpoint_path << utility::get_base_path(configuration_) << std::hex
130 << VSOMEIP_ROUTING_CLIENT;
131 #ifdef _WIN32
132 ::_unlink(its_endpoint_path.str().c_str());
133 #else
134 if (-1 == ::unlink(its_endpoint_path.str().c_str())) {
135 VSOMEIP_ERROR << "routing_manager_stub::stop() unlink failed ("
136 << its_endpoint_path.str() << "): "<< std::strerror(errno);
137 }
138 #endif
139 }
140
141 if(local_receiver_) {
142 local_receiver_->stop();
143 local_receiver_ = nullptr;
144 std::stringstream its_local_receiver_path;
145 its_local_receiver_path << utility::get_base_path(configuration_)
146 << std::hex << host_->get_client();
147 #ifdef _WIN32
148 ::_unlink(its_local_receiver_path.str().c_str());
149 #else
150 if (-1 == ::unlink(its_local_receiver_path.str().c_str())) {
151 VSOMEIP_ERROR << "routing_manager_stub::stop() unlink (local receiver) failed ("
152 << its_local_receiver_path.str() << "): "<< std::strerror(errno);
153 }
154 #endif
155 }
156 }
157
on_message(const byte_t * _data,length_t _size,endpoint * _receiver,const boost::asio::ip::address & _destination,client_t _bound_client,credentials_t _credentials,const boost::asio::ip::address & _remote_address,std::uint16_t _remote_port)158 void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
159 endpoint *_receiver, const boost::asio::ip::address &_destination,
160 client_t _bound_client,
161 credentials_t _credentials,
162 const boost::asio::ip::address &_remote_address,
163 std::uint16_t _remote_port) {
164 (void)_receiver;
165 (void)_destination;
166 (void)_remote_address;
167 (void) _remote_port;
168 #if 0
169 std::stringstream msg;
170 msg << "rms::on_message: ";
171 for (length_t i = 0; i < _size; ++i)
172 msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
173 VSOMEIP_INFO << msg.str();
174 #endif
175
176 std::uint32_t its_sender_uid = std::get<0>(_credentials);
177 std::uint32_t its_sender_gid = std::get<1>(_credentials);
178
179 if (VSOMEIP_COMMAND_SIZE_POS_MAX < _size) {
180 byte_t its_command;
181 client_t its_client;
182 std::string its_client_endpoint;
183 service_t its_service;
184 instance_t its_instance;
185 method_t its_method;
186 eventgroup_t its_eventgroup;
187 event_t its_notifier;
188 event_type_e its_event_type;
189 bool is_provided(false);
190 major_version_t its_major;
191 minor_version_t its_minor;
192 std::shared_ptr<payload> its_payload;
193 const byte_t *its_data;
194 uint32_t its_size;
195 bool its_reliable(false);
196 client_t its_client_from_header;
197 client_t its_target_client;
198 client_t its_subscriber;
199 uint8_t its_check_status(0);
200 std::uint16_t its_subscription_id(PENDING_SUBSCRIPTION_ID);
201 offer_type_e its_offer_type;
202
203 its_command = _data[VSOMEIP_COMMAND_TYPE_POS];
204 std::memcpy(&its_client, &_data[VSOMEIP_COMMAND_CLIENT_POS],
205 sizeof(its_client));
206
207 if (security::get()->is_enabled() && _bound_client != its_client) {
208 VSOMEIP_WARNING << "vSomeIP Security: routing_manager_stub::on_message: "
209 << "Routing Manager received a message from client "
210 << std::hex << std::setw(4) << std::setfill('0')
211 << its_client << " with command " << (uint32_t)its_command
212 << " which doesn't match the bound client "
213 << std::setw(4) << std::setfill('0') << _bound_client
214 << " ~> skip message!";
215 return;
216 }
217
218 std::memcpy(&its_size, &_data[VSOMEIP_COMMAND_SIZE_POS_MIN],
219 sizeof(its_size));
220
221 if (its_size <= _size - VSOMEIP_COMMAND_HEADER_SIZE) {
222 switch (its_command) {
223 case VSOMEIP_REGISTER_APPLICATION:
224 if (_size != VSOMEIP_REGISTER_APPLICATION_COMMAND_SIZE) {
225 VSOMEIP_WARNING << "Received a REGISTER_APPLICATION command with wrong size ~> skip!";
226 break;
227 }
228 update_registration(its_client, registration_type_e::REGISTER);
229 break;
230
231 case VSOMEIP_DEREGISTER_APPLICATION:
232 if (_size != VSOMEIP_DEREGISTER_APPLICATION_COMMAND_SIZE) {
233 VSOMEIP_WARNING << "Received a DEREGISTER_APPLICATION command with wrong size ~> skip!";
234 break;
235 }
236 update_registration(its_client, registration_type_e::DEREGISTER);
237 break;
238
239 case VSOMEIP_PONG:
240 if (_size != VSOMEIP_PONG_COMMAND_SIZE) {
241 VSOMEIP_WARNING << "Received a PONG command with wrong size ~> skip!";
242 break;
243 }
244 on_pong(its_client);
245 VSOMEIP_TRACE << "PONG("
246 << std::hex << std::setw(4) << std::setfill('0') << its_client << ")";
247 break;
248
249 case VSOMEIP_OFFER_SERVICE:
250 if (_size != VSOMEIP_OFFER_SERVICE_COMMAND_SIZE) {
251 VSOMEIP_WARNING << "Received a OFFER_SERVICE command with wrong size ~> skip!";
252 break;
253 }
254
255 std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
256 sizeof(its_service));
257 std::memcpy(&its_instance,
258 &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
259 sizeof(its_instance));
260 std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
261 sizeof(its_major));
262 std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5],
263 sizeof(its_minor));
264
265 if (security::get()->is_offer_allowed(its_sender_uid, its_sender_gid,
266 its_client, its_service, its_instance)) {
267 host_->offer_service(its_client, its_service, its_instance,
268 its_major, its_minor);
269 } else {
270 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client
271 << " : routing_manager_stub::on_message: isn't allowed to offer "
272 << "the following service/instance " << its_service << "/" << its_instance
273 << " ~> Skip offer!";
274 }
275 break;
276
277 case VSOMEIP_STOP_OFFER_SERVICE:
278 if (_size != VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE) {
279 VSOMEIP_WARNING << "Received a STOP_OFFER_SERVICE command with wrong size ~> skip!";
280 break;
281 }
282 std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
283 sizeof(its_service));
284 std::memcpy(&its_instance,
285 &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
286 sizeof(its_instance));
287
288 std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
289 sizeof(its_major));
290 std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5],
291 sizeof(its_minor));
292
293 host_->stop_offer_service(its_client, its_service, its_instance, its_major, its_minor);
294 break;
295
296 case VSOMEIP_SUBSCRIBE:
297 if (_size != VSOMEIP_SUBSCRIBE_COMMAND_SIZE) {
298 VSOMEIP_WARNING << "Received a SUBSCRIBE command with wrong size ~> skip!";
299 break;
300 }
301 std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
302 sizeof(its_service));
303 std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
304 sizeof(its_instance));
305 std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
306 sizeof(its_eventgroup));
307 std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
308 sizeof(its_major));
309 std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7],
310 sizeof(its_notifier));
311
312 if (its_notifier == ANY_EVENT) {
313 if (host_->is_subscribe_to_any_event_allowed(_credentials, its_client, its_service,
314 its_instance, its_eventgroup)) {
315 host_->subscribe(its_client, its_sender_uid, its_sender_gid, its_service, its_instance,
316 its_eventgroup, its_major, its_notifier);
317 } else {
318 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client
319 << " : routing_manager_stub::on_message: "
320 << " subscribes to service/instance/event "
321 << its_service << "/" << its_instance << "/ANY_EVENT"
322 << " which violates the security policy ~> Skip subscribe!";
323 }
324 } else {
325 if (security::get()->is_client_allowed(its_sender_uid, its_sender_gid,
326 its_client, its_service, its_instance, its_notifier)) {
327 host_->subscribe(its_client, its_sender_uid, its_sender_gid, its_service, its_instance,
328 its_eventgroup, its_major, its_notifier);
329 } else {
330 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client
331 << " : routing_manager_stub::on_message: "
332 << " subscribes to service/instance/event "
333 << its_service << "/" << its_instance << "/" << its_notifier
334 << " which violates the security policy ~> Skip subscribe!";
335 }
336 }
337 break;
338
339 case VSOMEIP_UNSUBSCRIBE:
340 if (_size != VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE) {
341 VSOMEIP_WARNING << "Received a UNSUBSCRIBE command with wrong size ~> skip!";
342 break;
343 }
344 std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
345 sizeof(its_service));
346 std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
347 sizeof(its_instance));
348 std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
349 sizeof(its_eventgroup));
350 std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
351 sizeof(its_notifier));
352
353 host_->unsubscribe(its_client, its_sender_uid, its_sender_gid, its_service,
354 its_instance, its_eventgroup, its_notifier);
355 break;
356
357 case VSOMEIP_SUBSCRIBE_ACK:
358 if (_size != VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE) {
359 VSOMEIP_WARNING << "Received a SUBSCRIBE_ACK command with wrong size ~> skip!";
360 break;
361 }
362 std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
363 sizeof(its_service));
364 std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
365 sizeof(its_instance));
366 std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
367 sizeof(its_eventgroup));
368 std::memcpy(&its_subscriber, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
369 sizeof(its_subscriber));
370 std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8],
371 sizeof(its_notifier));
372 std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 10],
373 sizeof(its_subscription_id));
374 host_->on_subscribe_ack(its_subscriber, its_service,
375 its_instance, its_eventgroup, its_notifier, its_subscription_id);
376 VSOMEIP_INFO << "SUBSCRIBE ACK("
377 << std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
378 << std::hex << std::setw(4) << std::setfill('0') << its_service << "."
379 << std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
380 << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "."
381 << std::hex << std::setw(4) << std::setfill('0') << its_notifier << "]";
382 break;
383
384 case VSOMEIP_SUBSCRIBE_NACK:
385 if (_size != VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE) {
386 VSOMEIP_WARNING << "Received a SUBSCRIBE_NACK command with wrong size ~> skip!";
387 break;
388 }
389 std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
390 sizeof(its_service));
391 std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
392 sizeof(its_instance));
393 std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
394 sizeof(its_eventgroup));
395 std::memcpy(&its_subscriber, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
396 sizeof(its_subscriber));
397 std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8],
398 sizeof(its_notifier));
399 std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 10],
400 sizeof(its_subscription_id));
401 host_->on_subscribe_nack(its_subscriber, its_service,
402 its_instance, its_eventgroup, its_notifier,
403 its_subscription_id, false);
404 VSOMEIP_INFO << "SUBSCRIBE NACK("
405 << std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
406 << std::hex << std::setw(4) << std::setfill('0') << its_service << "."
407 << std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
408 << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "."
409 << std::hex << std::setw(4) << std::setfill('0') << its_notifier << "]";
410 break;
411 case VSOMEIP_UNSUBSCRIBE_ACK:
412 if (_size != VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE) {
413 VSOMEIP_WARNING << "Received a VSOMEIP_UNSUBSCRIBE_ACK command with wrong size ~> skip!";
414 break;
415 }
416 std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
417 sizeof(its_service));
418 std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
419 sizeof(its_instance));
420 std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
421 sizeof(its_eventgroup));
422 std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
423 sizeof(its_subscription_id));
424 host_->on_unsubscribe_ack(its_client, its_service,
425 its_instance, its_eventgroup, its_subscription_id);
426 VSOMEIP_INFO << "UNSUBSCRIBE ACK("
427 << std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
428 << std::hex << std::setw(4) << std::setfill('0') << its_service << "."
429 << std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
430 << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "]";
431 break;
432 case VSOMEIP_SEND: {
433 if (_size < VSOMEIP_SEND_COMMAND_SIZE + VSOMEIP_FULL_HEADER_SIZE) {
434 VSOMEIP_WARNING << "Received a SEND command with too small size ~> skip!";
435 break;
436 }
437 its_data = &_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS];
438 its_service = VSOMEIP_BYTES_TO_WORD(
439 its_data[VSOMEIP_SERVICE_POS_MIN],
440 its_data[VSOMEIP_SERVICE_POS_MAX]);
441 its_client_from_header = VSOMEIP_BYTES_TO_WORD(
442 its_data[VSOMEIP_CLIENT_POS_MIN],
443 its_data[VSOMEIP_CLIENT_POS_MAX]);
444 its_method = VSOMEIP_BYTES_TO_WORD(
445 its_data[VSOMEIP_METHOD_POS_MIN],
446 its_data[VSOMEIP_METHOD_POS_MAX]);
447 std::memcpy(&its_instance, &_data[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN],
448 sizeof(its_instance));
449 std::memcpy(&its_reliable, &_data[VSOMEIP_SEND_COMMAND_RELIABLE_POS],
450 sizeof(its_reliable));
451 std::memcpy(&its_check_status, &_data[VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS],
452 sizeof(its_check_status));
453
454 // Allow response messages from local proxies as answer to remote requests
455 // but check requests sent by local proxies to remote against policy.
456 if (utility::is_request(its_data[VSOMEIP_MESSAGE_TYPE_POS])) {
457 if (!security::get()->is_client_allowed(its_sender_uid, its_sender_gid,
458 its_client_from_header, its_service, its_instance, its_method)) {
459 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client_from_header
460 << " : routing_manager_stub::on_message: "
461 << " isn't allowed to send a request to service/instance/method "
462 << its_service << "/" << its_instance << "/" << its_method
463 << " ~> Skip message!";
464 return;
465 }
466 }
467 // reduce by size of instance, flush, reliable, client and is_valid_crc flag
468 const std::uint32_t its_message_size = its_size -
469 (VSOMEIP_SEND_COMMAND_SIZE - VSOMEIP_COMMAND_HEADER_SIZE);
470 if (its_message_size !=
471 VSOMEIP_BYTES_TO_LONG(_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN],
472 _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 1],
473 _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 2],
474 _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 3])
475 + VSOMEIP_SOMEIP_HEADER_SIZE) {
476 VSOMEIP_WARNING << "Received a SEND command containing message with invalid size -> skip!";
477 break;
478 }
479 host_->on_message(its_service, its_instance, its_data, its_message_size,
480 its_reliable, _bound_client, _credentials, its_check_status, false);
481 break;
482 }
483 case VSOMEIP_NOTIFY: {
484 if (_size < VSOMEIP_SEND_COMMAND_SIZE + VSOMEIP_FULL_HEADER_SIZE) {
485 VSOMEIP_WARNING << "Received a NOTIFY command with too small size ~> skip!";
486 break;
487 }
488 its_data = &_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS];
489 its_service = VSOMEIP_BYTES_TO_WORD(
490 its_data[VSOMEIP_SERVICE_POS_MIN],
491 its_data[VSOMEIP_SERVICE_POS_MAX]);
492 std::memcpy(&its_instance, &_data[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN],
493 sizeof(its_instance));
494 // reduce by size of instance, flush, reliable, is_valid_crc flag and target client
495 const std::uint32_t its_message_size = its_size -
496 (VSOMEIP_SEND_COMMAND_SIZE - VSOMEIP_COMMAND_HEADER_SIZE);
497 if (its_message_size !=
498 VSOMEIP_BYTES_TO_LONG(_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN],
499 _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 1],
500 _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 2],
501 _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 3])
502 + VSOMEIP_SOMEIP_HEADER_SIZE) {
503 VSOMEIP_WARNING << "Received a NOTIFY command containing message with invalid size -> skip!";
504 break;
505 }
506 host_->on_notification(VSOMEIP_ROUTING_CLIENT, its_service, its_instance, its_data, its_message_size);
507 break;
508 }
509 case VSOMEIP_NOTIFY_ONE: {
510 if (_size < VSOMEIP_SEND_COMMAND_SIZE + VSOMEIP_FULL_HEADER_SIZE) {
511 VSOMEIP_WARNING << "Received a NOTIFY_ONE command with too small size ~> skip!";
512 break;
513 }
514 its_data = &_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS];
515 its_service = VSOMEIP_BYTES_TO_WORD(
516 its_data[VSOMEIP_SERVICE_POS_MIN],
517 its_data[VSOMEIP_SERVICE_POS_MAX]);
518 std::memcpy(&its_instance, &_data[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN],
519 sizeof(its_instance));
520 std::memcpy(&its_target_client, &_data[VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MIN],
521 sizeof(client_t));
522 // reduce by size of instance, flush, reliable flag, is_valid_crc and target client
523 const std::uint32_t its_message_size = its_size -
524 (VSOMEIP_SEND_COMMAND_SIZE - VSOMEIP_COMMAND_HEADER_SIZE);
525 if (its_message_size !=
526 VSOMEIP_BYTES_TO_LONG(_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN],
527 _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 1],
528 _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 2],
529 _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 3])
530 + VSOMEIP_SOMEIP_HEADER_SIZE) {
531 VSOMEIP_WARNING << "Received a NOTIFY_ONE command containing message with invalid size -> skip!";
532 break;
533 }
534 host_->on_notification(its_target_client, its_service, its_instance,
535 its_data, its_message_size, true);
536 break;
537 }
538 case VSOMEIP_REQUEST_SERVICE:
539 {
540 uint32_t entry_size = (sizeof(service_t) + sizeof(instance_t)
541 + sizeof(major_version_t) + sizeof(minor_version_t));
542 if (its_size % entry_size > 0) {
543 VSOMEIP_WARNING << "Received a REQUEST_SERVICE command with invalid size -> skip!";
544 break;
545 }
546 uint32_t request_count(its_size / entry_size);
547 std::set<service_data_t> requests;
548 for (uint32_t i = 0; i < request_count; ++i) {
549 service_t its_service;
550 instance_t its_instance;
551 major_version_t its_major;
552 minor_version_t its_minor;
553 std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + (i * entry_size)],
554 sizeof(its_service));
555 std::memcpy(&its_instance,
556 &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2 + (i * entry_size)],
557 sizeof(its_instance));
558 std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4 + (i * entry_size)],
559 sizeof(its_major));
560 std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5 + (i * entry_size)],
561 sizeof(its_minor));
562 if (security::get()->is_client_allowed(its_sender_uid, its_sender_gid,
563 its_client, its_service, its_instance, 0x00, true)) {
564 host_->request_service(its_client, its_service, its_instance,
565 its_major, its_minor );
566 service_data_t request = {
567 its_service, its_instance,
568 its_major, its_minor
569 };
570 requests.insert(request);
571 } else {
572 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex
573 << its_client << " : routing_manager_stub::on_message: "
574 << "requests service/instance "
575 << its_service << "/" << its_instance
576 << " which violates the security policy ~> Skip request!";
577 }
578 }
579 if (security::get()->is_enabled()) {
580 handle_credentials(its_client, requests);
581 }
582 handle_requests(its_client, requests);
583 break;
584 }
585
586 case VSOMEIP_RELEASE_SERVICE:
587 if (_size != VSOMEIP_RELEASE_SERVICE_COMMAND_SIZE) {
588 VSOMEIP_WARNING << "Received a RELEASE_SERVICE command with wrong size ~> skip!";
589 break;
590 }
591 std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
592 sizeof(its_service));
593 std::memcpy(&its_instance,
594 &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
595 sizeof(its_instance));
596
597 host_->release_service(its_client, its_service, its_instance);
598 break;
599
600 case VSOMEIP_REGISTER_EVENT: {
601 if (_size < VSOMEIP_REGISTER_EVENT_COMMAND_SIZE) {
602 VSOMEIP_WARNING << "Received a REGISTER_EVENT command with wrong size ~> skip!";
603 break;
604 }
605
606 std::set<eventgroup_t> its_eventgroups;
607 reliability_type_e its_reliability = reliability_type_e::RT_UNKNOWN;
608
609 std::memcpy(&its_service,
610 &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
611 sizeof(its_service));
612 std::memcpy(&its_instance,
613 &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
614 sizeof(its_instance));
615 std::memcpy(&its_notifier,
616 &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
617 sizeof(its_notifier));
618 std::memcpy(&its_event_type,
619 &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
620 sizeof(its_event_type));
621 std::memcpy(&is_provided,
622 &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7],
623 sizeof(is_provided));
624 std::memcpy(&its_reliability,
625 &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8],
626 sizeof(its_reliability));
627 if (is_provided
628 && !configuration_->is_offered_remote(its_service,
629 its_instance)) {
630 break;
631 }
632 for (std::size_t i = 9; i+1 < its_size; i++) {
633 std::memcpy(&its_eventgroup,
634 &_data[VSOMEIP_COMMAND_PAYLOAD_POS + i],
635 sizeof(its_eventgroup));
636 its_eventgroups.insert(its_eventgroup);
637 }
638 host_->register_shadow_event(its_client,
639 its_service, its_instance,
640 its_notifier, its_eventgroups, its_event_type,
641 its_reliability,
642 is_provided);
643 VSOMEIP_INFO << "REGISTER EVENT("
644 << std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
645 << std::hex << std::setw(4) << std::setfill('0') << its_service << "."
646 << std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
647 << std::hex << std::setw(4) << std::setfill('0') << its_notifier
648 << ":is_provider=" << is_provided << ":reliability="
649 << (std::uint32_t)(its_reliability) << "]";
650 break;
651 }
652 case VSOMEIP_UNREGISTER_EVENT:
653 if (_size != VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE) {
654 VSOMEIP_WARNING << "Received a UNREGISTER_EVENT command with wrong size ~> skip!";
655 break;
656 }
657 std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
658 sizeof(its_service));
659 std::memcpy(&its_instance,
660 &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
661 sizeof(its_instance));
662 std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
663 sizeof(its_notifier));
664 std::memcpy(&is_provided,
665 &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
666 sizeof(is_provided));
667 if (is_provided
668 && !configuration_->is_offered_remote(its_service,
669 its_instance)) {
670 break;
671 }
672 host_->unregister_shadow_event(its_client, its_service, its_instance,
673 its_notifier, is_provided);
674 VSOMEIP_INFO << "UNREGISTER EVENT("
675 << std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
676 << std::hex << std::setw(4) << std::setfill('0') << its_service << "."
677 << std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
678 << std::hex << std::setw(4) << std::setfill('0') << its_notifier
679 << ":is_provider=" << is_provided << "]";
680 break;
681
682 case VSOMEIP_REGISTERED_ACK:
683 if (_size != VSOMEIP_REGISTERED_ACK_COMMAND_SIZE) {
684 VSOMEIP_WARNING << "Received a REGISTERED_ACK command with wrong size ~> skip!";
685 break;
686 }
687 VSOMEIP_INFO << "REGISTERED_ACK("
688 << std::hex << std::setw(4) << std::setfill('0') << its_client << ")";
689 break;
690 case VSOMEIP_OFFERED_SERVICES_REQUEST: {
691 if (_size != VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE) {
692 VSOMEIP_WARNING << "Received a VSOMEIP_OFFERED_SERVICES_REQUEST command with wrong size ~> skip!";
693 break;
694 }
695
696 std::memcpy(&its_offer_type, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
697 sizeof(its_offer_type));
698
699 std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
700 create_offered_services_info(its_client);
701
702 for (const auto& found_client : routing_info_) {
703 // skip services which are offered on remote hosts
704 if (found_client.first != VSOMEIP_ROUTING_CLIENT) {
705 for (const auto &its_service : found_client.second.second) {
706 for (const auto &its_instance : its_service.second) {
707 uint16_t its_reliable_port = configuration_->get_reliable_port(its_service.first,
708 its_instance.first);
709 uint16_t its_unreliable_port = configuration_->get_unreliable_port(
710 its_service.first, its_instance.first);
711
712 if (its_offer_type == offer_type_e::OT_LOCAL) {
713 if (its_reliable_port == ILLEGAL_PORT
714 && its_unreliable_port == ILLEGAL_PORT) {
715 insert_offered_services_info(its_client,
716 routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE,
717 its_service.first, its_instance.first,
718 its_instance.second.first, its_instance.second.second);
719 }
720 }
721 else if (its_offer_type == offer_type_e::OT_REMOTE) {
722 if (its_reliable_port != ILLEGAL_PORT
723 || its_unreliable_port != ILLEGAL_PORT) {
724 insert_offered_services_info(its_client,
725 routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE,
726 its_service.first, its_instance.first,
727 its_instance.second.first, its_instance.second.second);
728 }
729 } else if (its_offer_type == offer_type_e::OT_ALL) {
730 insert_offered_services_info(its_client,
731 routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE,
732 its_service.first, its_instance.first,
733 its_instance.second.first, its_instance.second.second);
734 }
735 }
736 }
737 }
738 }
739 send_offered_services_info(its_client);
740 break;
741 }
742 case VSOMEIP_RESEND_PROVIDED_EVENTS: {
743 if (_size != VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE) {
744 VSOMEIP_WARNING << "Received a RESEND_PROVIDED_EVENTS command with wrong size ~> skip!";
745 break;
746 }
747 pending_remote_offer_id_t its_pending_remote_offer_id(0);
748 std::memcpy(&its_pending_remote_offer_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
749 sizeof(pending_remote_offer_id_t));
750 host_->on_resend_provided_events_response(its_pending_remote_offer_id);
751 VSOMEIP_INFO << "RESEND_PROVIDED_EVENTS("
752 << std::hex << std::setw(4) << std::setfill('0') << its_client << ")";
753 break;
754 }
755 case VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE: {
756 if (_size != VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE) {
757 VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE "
758 << "command with wrong size ~> skip!";
759 break;
760 }
761 pending_security_update_id_t its_pending_security_update_id(0);
762 std::memcpy(&its_pending_security_update_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
763 sizeof(pending_security_update_id_t));
764
765 on_security_update_response(its_pending_security_update_id ,its_client);
766 break;
767 }
768 case VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE: {
769 if (_size != VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE) {
770 VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE "
771 << "command with wrong size ~> skip!";
772 break;
773 }
774 pending_security_update_id_t its_pending_security_update_id(0);
775 std::memcpy(&its_pending_security_update_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
776 sizeof(pending_security_update_id_t));
777
778 on_security_update_response(its_pending_security_update_id ,its_client);
779 break;
780 }
781 }
782 }
783 }
784 }
785
on_register_application(client_t _client)786 void routing_manager_stub::on_register_application(client_t _client) {
787 auto endpoint = host_->find_local(_client);
788 if (endpoint) {
789 VSOMEIP_WARNING << "Reregistering application: " << std::hex << _client
790 << ". Last registration might have been taken too long.";
791 } else {
792 endpoint = host_->find_or_create_local(_client);
793 {
794 std::lock_guard<std::mutex> its_lock(routing_info_mutex_);
795 routing_info_[_client].first = 0;
796 }
797
798 std::pair<uid_t, gid_t> its_uid_gid;
799 std::set<std::shared_ptr<policy> > its_policies;
800
801 security::get()->get_client_to_uid_gid_mapping(_client, its_uid_gid);
802 get_requester_policies(its_uid_gid.first, its_uid_gid.second, its_policies);
803
804 if (!its_policies.empty())
805 send_requester_policies({ _client }, its_policies);
806 }
807 }
808
on_deregister_application(client_t _client)809 void routing_manager_stub::on_deregister_application(client_t _client) {
810 std::vector<
811 std::tuple<service_t, instance_t,
812 major_version_t, minor_version_t>> services_to_report;
813 {
814 std::lock_guard<std::mutex> its_lock(routing_info_mutex_);
815 auto its_info = routing_info_.find(_client);
816 if (its_info != routing_info_.end()) {
817 for (const auto &its_service : its_info->second.second) {
818 for (const auto &its_instance : its_service.second) {
819 const auto its_version = its_instance.second;
820 services_to_report.push_back(
821 std::make_tuple(its_service.first,
822 its_instance.first, its_version.first,
823 its_version.second));
824 }
825 }
826 }
827 routing_info_.erase(_client);
828 }
829 for (const auto &s : services_to_report) {
830 host_->on_availability(std::get<0>(s), std::get<1>(s), false,
831 std::get<2>(s), std::get<3>(s));
832 host_->on_stop_offer_service(_client, std::get<0>(s), std::get<1>(s),
833 std::get<2>(s), std::get<3>(s));
834 }
835 }
836
client_registration_func(void)837 void routing_manager_stub::client_registration_func(void) {
838 #ifndef _WIN32
839 {
840 std::stringstream s;
841 s << std::hex << std::setw(4) << std::setfill('0')
842 << host_->get_client() << "_client_reg";
843 pthread_setname_np(pthread_self(),s.str().c_str());
844 }
845 #endif
846 std::unique_lock<std::mutex> its_lock(client_registration_mutex_);
847 while (client_registration_running_) {
848 while (!pending_client_registrations_.size() && client_registration_running_) {
849 client_registration_condition_.wait(its_lock);
850 }
851
852 std::map<client_t, std::vector<registration_type_e>> its_registrations(
853 pending_client_registrations_);
854 pending_client_registrations_.clear();
855 its_lock.unlock();
856
857 for (const auto& r : its_registrations) {
858 for (auto b : r.second) {
859 if (b == registration_type_e::REGISTER) {
860 on_register_application(r.first);
861 } else {
862 on_deregister_application(r.first);
863 }
864 // Inform (de)registered client. All others will be informed after
865 // the client acknowledged its registered state!
866 // Don't inform client if we deregister because of an client
867 // endpoint error to avoid writing in an already closed socket
868 if (b != registration_type_e::DEREGISTER_ON_ERROR) {
869 std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
870 create_client_routing_info(r.first);
871 insert_client_routing_info(r.first,
872 b == registration_type_e::REGISTER ?
873 routing_info_entry_e::RIE_ADD_CLIENT :
874 routing_info_entry_e::RIE_DEL_CLIENT,
875 r.first);
876 // distribute updated security config to new clients
877 if (b == registration_type_e::REGISTER) {
878 send_cached_security_policies(r.first);
879 }
880 send_client_routing_info(r.first);
881 }
882 if (b != registration_type_e::REGISTER) {
883 {
884 std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
885 auto its_connection = connection_matrix_.find(r.first);
886 if (its_connection != connection_matrix_.end()) {
887 for (auto its_client : its_connection->second) {
888 if (its_client != r.first &&
889 its_client != VSOMEIP_ROUTING_CLIENT &&
890 its_client != get_client()) {
891 create_client_routing_info(its_client);
892 insert_client_routing_info(its_client,
893 routing_info_entry_e::RIE_DEL_CLIENT, r.first);
894 send_client_routing_info(its_client);
895 }
896 }
897 connection_matrix_.erase(r.first);
898 }
899 for (const auto& its_client : connection_matrix_) {
900 connection_matrix_[its_client.first].erase(r.first);
901 }
902 service_requests_.erase(r.first);
903 }
904 // Don't remove client ID to UID maping as same client
905 // could have passed its credentials again
906 host_->remove_local(r.first, false);
907 utility::release_client_id(r.first);
908 }
909 }
910 }
911 its_lock.lock();
912 }
913 }
914
init_routing_endpoint()915 void routing_manager_stub::init_routing_endpoint() {
916 endpoint_ = host_->get_endpoint_manager()->create_local_server(
917 &is_socket_activated_, shared_from_this());
918 }
919
on_offer_service(client_t _client,service_t _service,instance_t _instance,major_version_t _major,minor_version_t _minor)920 void routing_manager_stub::on_offer_service(client_t _client,
921 service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) {
922 if (_client == host_->get_client()) {
923 create_local_receiver();
924 }
925
926 std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
927 routing_info_[_client].second[_service][_instance] = std::make_pair(_major, _minor);
928 if (security::get()->is_enabled()) {
929 distribute_credentials(_client, _service, _instance);
930 }
931 inform_requesters(_client, _service, _instance, _major, _minor,
932 routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, true);
933 }
934
on_stop_offer_service(client_t _client,service_t _service,instance_t _instance,major_version_t _major,minor_version_t _minor)935 void routing_manager_stub::on_stop_offer_service(client_t _client,
936 service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) {
937 std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
938 auto found_client = routing_info_.find(_client);
939 if (found_client != routing_info_.end()) {
940 auto found_service = found_client->second.second.find(_service);
941 if (found_service != found_client->second.second.end()) {
942 auto found_instance = found_service->second.find(_instance);
943 if (found_instance != found_service->second.end()) {
944 auto found_version = found_instance->second;
945 if( _major == found_version.first && _minor == found_version.second) {
946 found_service->second.erase(_instance);
947 if (0 == found_service->second.size()) {
948 found_client->second.second.erase(_service);
949 }
950 inform_provider(_client, _service, _instance, _major, _minor,
951 routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE);
952 inform_requesters(_client, _service, _instance, _major, _minor,
953 routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE, false);
954 } else if( _major == DEFAULT_MAJOR && _minor == DEFAULT_MINOR) {
955 found_service->second.erase(_instance);
956 if (0 == found_service->second.size()) {
957 found_client->second.second.erase(_service);
958 }
959 inform_provider(_client, _service, _instance, _major, _minor,
960 routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE);
961 inform_requesters(_client, _service, _instance, _major, _minor,
962 routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE, false);
963 }
964 }
965 }
966 }
967 }
968
create_client_routing_info(const client_t _target)969 void routing_manager_stub::create_client_routing_info(const client_t _target) {
970 std::vector<byte_t> its_command;
971 its_command.push_back(VSOMEIP_ROUTING_INFO);
972
973 // Sender client
974 client_t client = get_client();
975 for (uint32_t i = 0; i < sizeof(client_t); ++i) {
976 its_command.push_back(
977 reinterpret_cast<const byte_t*>(&client)[i]);
978 }
979
980 // Overall size placeholder
981 byte_t size_placeholder = 0x0;
982 for (uint32_t i = 0; i < sizeof(uint32_t); ++i) {
983 its_command.push_back(size_placeholder);
984 }
985
986 client_routing_info_[_target] = its_command;
987 }
988
create_client_credentials_info(const client_t _target)989 void routing_manager_stub::create_client_credentials_info(const client_t _target) {
990 std::vector<byte_t> its_command;
991 its_command.push_back(VSOMEIP_UPDATE_SECURITY_CREDENTIALS);
992
993 // Sender client
994 client_t client = get_client();
995 for (uint32_t i = 0; i < sizeof(client_t); ++i) {
996 its_command.push_back(
997 reinterpret_cast<const byte_t*>(&client)[i]);
998 }
999
1000 // Overall size placeholder
1001 byte_t size_placeholder = 0x0;
1002 for (uint32_t i = 0; i < sizeof(uint32_t); ++i) {
1003 its_command.push_back(size_placeholder);
1004 }
1005
1006 client_credentials_info_[_target] = its_command;
1007 }
1008
insert_client_credentials_info(client_t _target,std::set<std::pair<uint32_t,uint32_t>> _credentials)1009 void routing_manager_stub::insert_client_credentials_info(client_t _target, std::set<std::pair<uint32_t, uint32_t>> _credentials) {
1010 if (client_credentials_info_.find(_target) == client_credentials_info_.end()) {
1011 return;
1012 }
1013
1014 auto its_command = client_credentials_info_[_target];
1015
1016 // insert uid / gid credential pairs
1017 for (auto its_credentials : _credentials) {
1018 //uid
1019 for (uint32_t i = 0; i < sizeof(uint32_t); ++i) {
1020 its_command.push_back(
1021 reinterpret_cast<const byte_t*>(&std::get<0>(its_credentials))[i]);
1022 }
1023 //gid
1024 for (uint32_t i = 0; i < sizeof(uint32_t); ++i) {
1025 its_command.push_back(
1026 reinterpret_cast<const byte_t*>(&std::get<1>(its_credentials))[i]);
1027 }
1028 }
1029
1030 client_credentials_info_[_target] = its_command;
1031 }
1032
send_client_credentials_info(const client_t _target)1033 void routing_manager_stub::send_client_credentials_info(const client_t _target) {
1034 if (client_credentials_info_.find(_target) == client_credentials_info_.end()) {
1035 return;
1036 }
1037
1038 std::shared_ptr<endpoint> its_endpoint = host_->find_local(_target);
1039 if (its_endpoint) {
1040 auto its_command = client_credentials_info_[_target];
1041
1042 // File overall size
1043 std::size_t its_size = its_command.size() - VSOMEIP_COMMAND_PAYLOAD_POS;
1044 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, sizeof(uint32_t));
1045 its_size += VSOMEIP_COMMAND_PAYLOAD_POS;
1046
1047 #if 0
1048 std::stringstream msg;
1049 msg << "rms::send_credentials_info to (" << std::hex << _target << "): ";
1050 for (uint32_t i = 0; i < its_size; ++i)
1051 msg << std::hex << std::setw(2) << std::setfill('0') << (int)its_command[i] << " ";
1052 VSOMEIP_INFO << msg.str();
1053 #endif
1054
1055 // Send routing info or error!
1056 if(its_command.size() <= max_local_message_size_
1057 || VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) {
1058 its_endpoint->send(&its_command[0], uint32_t(its_size));
1059 } else {
1060 VSOMEIP_ERROR << "Credentials info exceeds maximum message size: Can't send!";
1061 }
1062
1063 client_credentials_info_.erase(_target);
1064 } else {
1065 VSOMEIP_ERROR << "Send credentials info to client 0x" << std::hex << _target
1066 << " failed: No valid endpoint!";
1067 }
1068 }
1069
create_offered_services_info(const client_t _target)1070 void routing_manager_stub::create_offered_services_info(const client_t _target) {
1071 std::vector<byte_t> its_command;
1072 its_command.push_back(VSOMEIP_OFFERED_SERVICES_RESPONSE);
1073
1074 // Sender client
1075 client_t client = get_client();
1076 for (uint32_t i = 0; i < sizeof(client_t); ++i) {
1077 its_command.push_back(
1078 reinterpret_cast<const byte_t*>(&client)[i]);
1079 }
1080
1081 // Overall size placeholder
1082 byte_t size_placeholder = 0x0;
1083 for (uint32_t i = 0; i < sizeof(uint32_t); ++i) {
1084 its_command.push_back(size_placeholder);
1085 }
1086
1087 offered_services_info_[_target] = its_command;
1088 }
1089
1090
send_client_routing_info(const client_t _target)1091 void routing_manager_stub::send_client_routing_info(const client_t _target) {
1092 if (client_routing_info_.find(_target) == client_routing_info_.end()) {
1093 return;
1094 }
1095 std::shared_ptr<endpoint> its_endpoint = host_->find_local(_target);
1096 if (its_endpoint) {
1097 auto its_command = client_routing_info_[_target];
1098
1099 // File overall size
1100 std::size_t its_size = its_command.size() - VSOMEIP_COMMAND_PAYLOAD_POS;
1101 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, sizeof(uint32_t));
1102 its_size += VSOMEIP_COMMAND_PAYLOAD_POS;
1103
1104 #if 0
1105 std::stringstream msg;
1106 msg << "rms::send_routing_info to (" << std::hex << _target << "): ";
1107 for (uint32_t i = 0; i < its_size; ++i)
1108 msg << std::hex << std::setw(2) << std::setfill('0') << (int)its_command[i] << " ";
1109 VSOMEIP_INFO << msg.str();
1110 #endif
1111
1112 // Send routing info or error!
1113 if(its_command.size() <= max_local_message_size_
1114 || VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) {
1115 its_endpoint->send(&its_command[0], uint32_t(its_size));
1116 } else {
1117 VSOMEIP_ERROR << "Routing info exceeds maximum message size: Can't send!";
1118 }
1119
1120 client_routing_info_.erase(_target);
1121 } else {
1122 VSOMEIP_ERROR << "Send routing info to client 0x" << std::hex << _target
1123 << " failed: No valid endpoint!";
1124 }
1125 }
1126
1127
send_offered_services_info(const client_t _target)1128 void routing_manager_stub::send_offered_services_info(const client_t _target) {
1129 if (offered_services_info_.find(_target) == offered_services_info_.end()) {
1130 return;
1131 }
1132 std::shared_ptr<endpoint> its_endpoint = host_->find_local(_target);
1133 if (its_endpoint) {
1134 auto its_command = offered_services_info_[_target];
1135
1136 // File overall size
1137 std::size_t its_size = its_command.size() - VSOMEIP_COMMAND_PAYLOAD_POS;
1138 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, sizeof(uint32_t));
1139 its_size += VSOMEIP_COMMAND_PAYLOAD_POS;
1140
1141 #if 0
1142 std::stringstream msg;
1143 msg << "rms::send_offered_services_info to (" << std::hex << _target << "): ";
1144 for (uint32_t i = 0; i < its_size; ++i)
1145 msg << std::hex << std::setw(2) << std::setfill('0') << (int)its_command[i] << " ";
1146 VSOMEIP_INFO << msg.str();
1147 #endif
1148
1149 // Send routing info or error!
1150 if(its_command.size() <= max_local_message_size_
1151 || VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) {
1152 its_endpoint->send(&its_command[0], uint32_t(its_size));
1153 } else {
1154 VSOMEIP_ERROR << "Offered services info exceeds maximum message size: Can't send!";
1155 }
1156
1157 offered_services_info_.erase(_target);
1158 } else {
1159 VSOMEIP_ERROR << "Send offered services info to client 0x" << std::hex << _target
1160 << " failed: No valid endpoint!";
1161 }
1162 }
1163
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)1164 void routing_manager_stub::insert_client_routing_info(client_t _target,
1165 routing_info_entry_e _entry,
1166 client_t _client, service_t _service,
1167 instance_t _instance,
1168 major_version_t _major,
1169 minor_version_t _minor) {
1170
1171 if (client_routing_info_.find(_target) == client_routing_info_.end()) {
1172 return;
1173 }
1174
1175 connection_matrix_[_target].insert(_client);
1176
1177 auto its_command = client_routing_info_[_target];
1178
1179 // Routing Info State Change
1180 for (uint32_t i = 0; i < sizeof(routing_info_entry_e); ++i) {
1181 its_command.push_back(
1182 reinterpret_cast<const byte_t*>(&_entry)[i]);
1183 }
1184
1185 std::size_t its_size_pos = its_command.size();
1186 std::size_t its_entry_size = its_command.size();
1187
1188 // Client size placeholder
1189 byte_t placeholder = 0x0;
1190 for (uint32_t i = 0; i < sizeof(uint32_t); ++i) {
1191 its_command.push_back(placeholder);
1192 }
1193 // Client
1194 for (uint32_t i = 0; i < sizeof(client_t); ++i) {
1195 its_command.push_back(
1196 reinterpret_cast<const byte_t*>(&_client)[i]);
1197 }
1198
1199 if (_entry == routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE ||
1200 _entry == routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE) {
1201 //Service
1202 uint32_t its_service_entry_size = uint32_t(sizeof(service_t)
1203 + sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t));
1204 for (uint32_t i = 0; i < sizeof(its_service_entry_size); ++i) {
1205 its_command.push_back(
1206 reinterpret_cast<const byte_t*>(&its_service_entry_size)[i]);
1207 }
1208 for (uint32_t i = 0; i < sizeof(service_t); ++i) {
1209 its_command.push_back(
1210 reinterpret_cast<const byte_t*>(&_service)[i]);
1211 }
1212 // Instance
1213 for (uint32_t i = 0; i < sizeof(instance_t); ++i) {
1214 its_command.push_back(
1215 reinterpret_cast<const byte_t*>(&_instance)[i]);
1216 }
1217 // Major version
1218 for (uint32_t i = 0; i < sizeof(major_version_t); ++i) {
1219 its_command.push_back(
1220 reinterpret_cast<const byte_t*>(&_major)[i]);
1221 }
1222 // Minor version
1223 for (uint32_t i = 0; i < sizeof(minor_version_t); ++i) {
1224 its_command.push_back(
1225 reinterpret_cast<const byte_t*>(&_minor)[i]);
1226 }
1227 }
1228
1229 // File client size
1230 its_entry_size = its_command.size() - its_entry_size - uint32_t(sizeof(uint32_t));
1231 std::memcpy(&its_command[its_size_pos], &its_entry_size, sizeof(uint32_t));
1232
1233 client_routing_info_[_target] = its_command;
1234 }
1235
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)1236 void routing_manager_stub::insert_offered_services_info(client_t _target,
1237 routing_info_entry_e _entry,
1238 service_t _service,
1239 instance_t _instance,
1240 major_version_t _major,
1241 minor_version_t _minor) {
1242
1243 if (offered_services_info_.find(_target) == offered_services_info_.end()) {
1244 return;
1245 }
1246
1247 auto its_command = offered_services_info_[_target];
1248
1249 // Routing Info State Change
1250 for (uint32_t i = 0; i < sizeof(routing_info_entry_e); ++i) {
1251 its_command.push_back(
1252 reinterpret_cast<const byte_t*>(&_entry)[i]);
1253 }
1254
1255 // entry size
1256 uint32_t its_service_entry_size = uint32_t(sizeof(service_t)
1257 + sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t));
1258 for (uint32_t i = 0; i < sizeof(its_service_entry_size); ++i) {
1259 its_command.push_back(
1260 reinterpret_cast<const byte_t*>(&its_service_entry_size)[i]);
1261 }
1262 //Service
1263 for (uint32_t i = 0; i < sizeof(service_t); ++i) {
1264 its_command.push_back(
1265 reinterpret_cast<const byte_t*>(&_service)[i]);
1266 }
1267 // Instance
1268 for (uint32_t i = 0; i < sizeof(instance_t); ++i) {
1269 its_command.push_back(
1270 reinterpret_cast<const byte_t*>(&_instance)[i]);
1271 }
1272 // Major version
1273 for (uint32_t i = 0; i < sizeof(major_version_t); ++i) {
1274 its_command.push_back(
1275 reinterpret_cast<const byte_t*>(&_major)[i]);
1276 }
1277 // Minor version
1278 for (uint32_t i = 0; i < sizeof(minor_version_t); ++i) {
1279 its_command.push_back(
1280 reinterpret_cast<const byte_t*>(&_minor)[i]);
1281 }
1282
1283 offered_services_info_[_target] = its_command;
1284 }
1285
distribute_credentials(client_t _hoster,service_t _service,instance_t _instance)1286 void routing_manager_stub::distribute_credentials(client_t _hoster, service_t _service, instance_t _instance) {
1287 std::set<std::pair<uint32_t, uint32_t>> its_credentials;
1288 std::set<client_t> its_requesting_clients;
1289 // search for clients which shall receive the credentials
1290 for (auto its_requesting_client : service_requests_) {
1291 auto its_service = its_requesting_client.second.find(_service);
1292 if (its_service != its_requesting_client.second.end()) {
1293 if (its_service->second.find(_instance) != its_service->second.end()
1294 || its_service->second.find(ANY_INSTANCE) != its_service->second.end()) {
1295 its_requesting_clients.insert(its_requesting_client.first);
1296 }
1297 }
1298 }
1299
1300 // search for UID / GID linked with the client ID that offers the requested services
1301 std::pair<uint32_t, uint32_t> its_uid_gid;
1302 if (security::get()->get_client_to_uid_gid_mapping(_hoster, its_uid_gid)) {
1303 its_credentials.insert(its_uid_gid);
1304 for (auto its_requesting_client : its_requesting_clients) {
1305 std::pair<uint32_t, uint32_t> its_requester_uid_gid;
1306 if (security::get()->get_client_to_uid_gid_mapping(its_requesting_client, its_requester_uid_gid)) {
1307 if (its_uid_gid != its_requester_uid_gid) {
1308 create_client_credentials_info(its_requesting_client);
1309 insert_client_credentials_info(its_requesting_client, its_credentials);
1310 send_client_credentials_info(its_requesting_client);
1311 }
1312 }
1313 }
1314 }
1315 }
1316
inform_provider(client_t _hoster,service_t _service,instance_t _instance,major_version_t _major,minor_version_t _minor,routing_info_entry_e _entry)1317 void routing_manager_stub::inform_provider(client_t _hoster, service_t _service,
1318 instance_t _instance, major_version_t _major, minor_version_t _minor,
1319 routing_info_entry_e _entry) {
1320
1321 if (_hoster != VSOMEIP_ROUTING_CLIENT
1322 && _hoster != host_->get_client()) {
1323 create_client_routing_info(_hoster);
1324 insert_client_routing_info(_hoster, _entry, _hoster,
1325 _service, _instance, _major, _minor);
1326 send_client_routing_info(_hoster);
1327 }
1328 };
1329
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)1330 void routing_manager_stub::inform_requesters(client_t _hoster, service_t _service,
1331 instance_t _instance, major_version_t _major, minor_version_t _minor,
1332 routing_info_entry_e _entry, bool _inform_service) {
1333 for (auto its_client : service_requests_) {
1334 auto its_service = its_client.second.find(_service);
1335 if (its_service != its_client.second.end()) {
1336 if (its_service->second.find(_instance) != its_service->second.end()
1337 || its_service->second.find(ANY_INSTANCE) != its_service->second.end()) {
1338 if (_inform_service) {
1339 if (_hoster != VSOMEIP_ROUTING_CLIENT &&
1340 _hoster != host_->get_client()) {
1341 if (!is_already_connected(_hoster, its_client.first)) {
1342 create_client_routing_info(_hoster);
1343 insert_client_routing_info(_hoster,
1344 routing_info_entry_e::RIE_ADD_CLIENT,
1345 its_client.first);
1346 send_client_routing_info(_hoster);
1347 }
1348 }
1349 }
1350 if (its_client.first != VSOMEIP_ROUTING_CLIENT &&
1351 its_client.first != get_client()) {
1352 create_client_routing_info(its_client.first);
1353 insert_client_routing_info(its_client.first, _entry, _hoster,
1354 _service, _instance, _major, _minor);
1355 send_client_routing_info(its_client.first);
1356 }
1357 }
1358 }
1359 }
1360 }
1361
is_already_connected(client_t _source,client_t _sink)1362 bool routing_manager_stub::is_already_connected(client_t _source, client_t _sink) {
1363 return connection_matrix_[_source].find(_sink) != connection_matrix_[_source].end();
1364 }
1365
broadcast(const std::vector<byte_t> & _command) const1366 void routing_manager_stub::broadcast(const std::vector<byte_t> &_command) const {
1367 std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
1368 for (const auto& a : routing_info_) {
1369 if (a.first != VSOMEIP_ROUTING_CLIENT && a.first != host_->get_client()) {
1370 std::shared_ptr<endpoint> its_endpoint
1371 = host_->find_local(a.first);
1372 if (its_endpoint) {
1373 its_endpoint->send(&_command[0], uint32_t(_command.size()));
1374 }
1375 }
1376 }
1377 }
1378
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)1379 bool routing_manager_stub::send_subscribe(const std::shared_ptr<endpoint>& _target,
1380 client_t _client, service_t _service, instance_t _instance,
1381 eventgroup_t _eventgroup, major_version_t _major,
1382 event_t _event, remote_subscription_id_t _id) {
1383 if (_target) {
1384 byte_t its_command[VSOMEIP_SUBSCRIBE_COMMAND_SIZE];
1385 uint32_t its_size = VSOMEIP_SUBSCRIBE_COMMAND_SIZE
1386 - VSOMEIP_COMMAND_HEADER_SIZE;
1387 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE;
1388 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client,
1389 sizeof(_client));
1390 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
1391 sizeof(its_size));
1392 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
1393 sizeof(_service));
1394 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
1395 sizeof(_instance));
1396 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup,
1397 sizeof(_eventgroup));
1398 its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6] = _major;
1399 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 7], &_event,
1400 sizeof(_event));
1401 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 9], &_id,
1402 sizeof(_id));
1403
1404 return _target->send(its_command, sizeof(its_command));
1405 } else {
1406 VSOMEIP_WARNING << __func__ << " Couldn't send subscription to local client ["
1407 << std::hex << std::setw(4) << std::setfill('0') << _service << "."
1408 << std::hex << std::setw(4) << std::setfill('0') << _instance << "."
1409 << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "."
1410 << std::hex << std::setw(4) << std::setfill('0') << _event << "]"
1411 << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0')
1412 << _client;
1413 return false;
1414 }
1415 }
1416
send_unsubscribe(const std::shared_ptr<endpoint> & _target,client_t _client,service_t _service,instance_t _instance,eventgroup_t _eventgroup,event_t _event,remote_subscription_id_t _id)1417 bool routing_manager_stub::send_unsubscribe(
1418 const std::shared_ptr<endpoint>& _target,
1419 client_t _client, service_t _service, instance_t _instance,
1420 eventgroup_t _eventgroup, event_t _event,
1421 remote_subscription_id_t _id) {
1422 if (_target) {
1423 byte_t its_command[VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE];
1424 uint32_t its_size = VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE
1425 - VSOMEIP_COMMAND_HEADER_SIZE;
1426 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UNSUBSCRIBE;
1427 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client,
1428 sizeof(_client));
1429 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
1430 sizeof(its_size));
1431 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
1432 sizeof(_service));
1433 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
1434 sizeof(_instance));
1435 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup,
1436 sizeof(_eventgroup));
1437 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_event,
1438 sizeof(_event));
1439 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_id,
1440 sizeof(_id));
1441
1442 return _target->send(its_command, sizeof(its_command));
1443 } else {
1444 VSOMEIP_WARNING << __func__ << " Couldn't send unsubscription to local client ["
1445 << std::hex << std::setw(4) << std::setfill('0') << _service << "."
1446 << std::hex << std::setw(4) << std::setfill('0') << _instance << "."
1447 << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "."
1448 << std::hex << std::setw(4) << std::setfill('0') << _event << "]"
1449 << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0')
1450 << _client;
1451 return false;
1452 }
1453 }
1454
send_expired_subscription(const std::shared_ptr<endpoint> & _target,client_t _client,service_t _service,instance_t _instance,eventgroup_t _eventgroup,event_t _event,remote_subscription_id_t _id)1455 bool routing_manager_stub::send_expired_subscription(
1456 const std::shared_ptr<endpoint>& _target,
1457 client_t _client, service_t _service, instance_t _instance,
1458 eventgroup_t _eventgroup, event_t _event,
1459 remote_subscription_id_t _id) {
1460 if (_target) {
1461 byte_t its_command[VSOMEIP_EXPIRED_SUBSCRIPTION_COMMAND_SIZE];
1462 uint32_t its_size = VSOMEIP_EXPIRED_SUBSCRIPTION_COMMAND_SIZE
1463 - VSOMEIP_COMMAND_HEADER_SIZE;
1464 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_EXPIRED_SUBSCRIPTION;
1465 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client,
1466 sizeof(_client));
1467 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
1468 sizeof(its_size));
1469 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
1470 sizeof(_service));
1471 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
1472 sizeof(_instance));
1473 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup,
1474 sizeof(_eventgroup));
1475 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_event,
1476 sizeof(_event));
1477 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_id,
1478 sizeof(_id));
1479
1480 return _target->send(its_command, sizeof(its_command));
1481 } else {
1482 VSOMEIP_WARNING << __func__ << " Couldn't send expired subscription to local client ["
1483 << std::hex << std::setw(4) << std::setfill('0') << _service << "."
1484 << std::hex << std::setw(4) << std::setfill('0') << _instance << "."
1485 << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "."
1486 << std::hex << std::setw(4) << std::setfill('0') << _event << "]"
1487 << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0')
1488 << _client;
1489 return false;
1490 }
1491 }
1492
send_subscribe_ack(client_t _client,service_t _service,instance_t _instance,eventgroup_t _eventgroup,event_t _event)1493 void routing_manager_stub::send_subscribe_ack(client_t _client, service_t _service,
1494 instance_t _instance, eventgroup_t _eventgroup, event_t _event) {
1495
1496 std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client);
1497 if (its_endpoint) {
1498 byte_t its_command[VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE];
1499 uint32_t its_size = VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE
1500 - VSOMEIP_COMMAND_HEADER_SIZE;
1501
1502 client_t this_client = get_client();
1503 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE_ACK;
1504 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &this_client,
1505 sizeof(this_client));
1506 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
1507 sizeof(its_size));
1508 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
1509 sizeof(_service));
1510 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
1511 sizeof(_instance));
1512 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup,
1513 sizeof(_eventgroup));
1514 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_client,
1515 sizeof(_client));
1516 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_event,
1517 sizeof(_event));
1518 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10],
1519 &PENDING_SUBSCRIPTION_ID, sizeof(PENDING_SUBSCRIPTION_ID));
1520
1521 its_endpoint->send(&its_command[0], sizeof(its_command));
1522 }
1523 }
1524
send_subscribe_nack(client_t _client,service_t _service,instance_t _instance,eventgroup_t _eventgroup,event_t _event)1525 void routing_manager_stub::send_subscribe_nack(client_t _client, service_t _service,
1526 instance_t _instance, eventgroup_t _eventgroup, event_t _event) {
1527
1528 std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client);
1529 if (its_endpoint) {
1530 byte_t its_command[VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE];
1531 uint32_t its_size = VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE
1532 - VSOMEIP_COMMAND_HEADER_SIZE;
1533
1534 client_t this_client = get_client();
1535 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE_NACK;
1536 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &this_client,
1537 sizeof(this_client));
1538 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
1539 sizeof(its_size));
1540 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
1541 sizeof(_service));
1542 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
1543 sizeof(_instance));
1544 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup,
1545 sizeof(_eventgroup));
1546 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_client,
1547 sizeof(_client));
1548 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_event,
1549 sizeof(_event));
1550 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10],
1551 &PENDING_SUBSCRIPTION_ID, sizeof(PENDING_SUBSCRIPTION_ID));
1552
1553 its_endpoint->send(&its_command[0], sizeof(its_command));
1554 }
1555 }
1556
contained_in_routing_info(client_t _client,service_t _service,instance_t _instance,major_version_t _major,minor_version_t _minor) const1557 bool routing_manager_stub::contained_in_routing_info(
1558 client_t _client, service_t _service, instance_t _instance,
1559 major_version_t _major, minor_version_t _minor) const {
1560 std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
1561 auto found_client = routing_info_.find(_client);
1562 if (found_client != routing_info_.end()) {
1563 auto found_service = found_client->second.second.find(_service);
1564 if (found_service != found_client->second.second.end()) {
1565 auto found_instance = found_service->second.find(_instance);
1566 if (found_instance != found_service->second.end()) {
1567 if (found_instance->second.first == _major
1568 && found_instance->second.second == _minor) {
1569 return true;
1570 }
1571 }
1572 }
1573 }
1574 return false;
1575 }
1576
1577 // Watchdog
broadcast_ping() const1578 void routing_manager_stub::broadcast_ping() const {
1579 broadcast(its_ping_);
1580 }
1581
on_pong(client_t _client)1582 void routing_manager_stub::on_pong(client_t _client) {
1583 {
1584 std::lock_guard<std::mutex> its_lock(routing_info_mutex_);
1585 auto found_info = routing_info_.find(_client);
1586 if (found_info != routing_info_.end()) {
1587 found_info->second.first = 0;
1588 } else {
1589 VSOMEIP_ERROR << "Received PONG from unregistered application: "
1590 << std::hex << std::setw(4) << std::setfill('0') << _client;
1591 }
1592 }
1593 remove_from_pinged_clients(_client);
1594 host_->on_pong(_client);
1595 }
1596
start_watchdog()1597 void routing_manager_stub::start_watchdog() {
1598
1599 auto its_callback =
1600 [this](boost::system::error_code const &_error) {
1601 if (!_error)
1602 check_watchdog();
1603 };
1604 {
1605 std::lock_guard<std::mutex> its_lock(watchdog_timer_mutex_);
1606 // Divide / 2 as start and check sleep each
1607 watchdog_timer_.expires_from_now(
1608 std::chrono::milliseconds(
1609 configuration_->get_watchdog_timeout() / 2));
1610
1611 watchdog_timer_.async_wait(its_callback);
1612 }
1613 }
1614
check_watchdog()1615 void routing_manager_stub::check_watchdog() {
1616 {
1617 std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
1618 for (auto i = routing_info_.begin(); i != routing_info_.end(); ++i) {
1619 i->second.first++;
1620 }
1621 }
1622 broadcast_ping();
1623
1624
1625 auto its_callback = [this](boost::system::error_code const &_error) {
1626 (void)_error;
1627 std::list< client_t > lost;
1628 {
1629 std::lock_guard<std::mutex> its_lock(routing_info_mutex_);
1630 for (const auto& i : routing_info_) {
1631 if (i.first > 0 && i.first != host_->get_client()) {
1632 if (i.second.first > configuration_->get_allowed_missing_pongs()) {
1633 VSOMEIP_WARNING << "Lost contact to application " << std::hex << (int)i.first;
1634 lost.push_back(i.first);
1635 }
1636 }
1637 }
1638 }
1639 for (auto i : lost) {
1640 host_->handle_client_error(i);
1641 }
1642 start_watchdog();
1643 };
1644 {
1645 std::lock_guard<std::mutex> its_lock(watchdog_timer_mutex_);
1646 watchdog_timer_.expires_from_now(
1647 std::chrono::milliseconds(
1648 configuration_->get_watchdog_timeout() / 2));
1649 watchdog_timer_.async_wait(its_callback);
1650 }
1651 }
1652
create_local_receiver()1653 void routing_manager_stub::create_local_receiver() {
1654 std::lock_guard<std::mutex> its_lock(local_receiver_mutex_);
1655
1656 if (local_receiver_) {
1657 return;
1658 }
1659 #ifndef _WIN32
1660 else if (!security::get()->check_credentials(get_client(), getuid(), getgid())) {
1661 VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client()
1662 << " : routing_manager_stub::create_local_receiver: isn't allowed"
1663 << " to create a server endpoint due to credential check failed!";
1664 return;
1665 }
1666 #endif
1667 local_receiver_ = std::static_pointer_cast<endpoint_manager_base>(
1668 host_->get_endpoint_manager())->create_local_server(shared_from_this());
1669 local_receiver_->start();
1670 }
1671
send_ping(client_t _client)1672 bool routing_manager_stub::send_ping(client_t _client) {
1673 std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client);
1674 if (!its_endpoint) {
1675 return false;
1676 }
1677
1678 {
1679 std::lock_guard<std::mutex> its_lock(pinged_clients_mutex_);
1680
1681 if (pinged_clients_.find(_client) != pinged_clients_.end()) {
1682 // client was already pinged: don't ping again and wait for answer
1683 // or timeout of previous ping.
1684 return true;
1685 }
1686
1687 boost::system::error_code ec;
1688 pinged_clients_timer_.cancel(ec);
1689 if (ec) {
1690 VSOMEIP_ERROR << "routing_manager_stub::send_ping cancellation of "
1691 "timer failed: " << ec.message();
1692 }
1693 const std::chrono::steady_clock::time_point now(
1694 std::chrono::steady_clock::now());
1695
1696 std::chrono::milliseconds next_timeout(configured_watchdog_timeout_);
1697 for (const auto &tp : pinged_clients_) {
1698 const std::chrono::milliseconds its_clients_timeout =
1699 std::chrono::duration_cast<std::chrono::milliseconds>(
1700 now - tp.second);
1701 if (next_timeout > its_clients_timeout) {
1702 next_timeout = its_clients_timeout;
1703 }
1704 }
1705
1706 pinged_clients_[_client] = now;
1707
1708 ec.clear();
1709 pinged_clients_timer_.expires_from_now(next_timeout, ec);
1710 if (ec) {
1711 VSOMEIP_ERROR<< "routing_manager_stub::send_ping setting "
1712 "expiry time of timer failed: " << ec.message();
1713 }
1714 pinged_clients_timer_.async_wait(
1715 std::bind(&routing_manager_stub::on_ping_timer_expired, this,
1716 std::placeholders::_1));
1717 return its_endpoint->send(&its_ping_[0], uint32_t(its_ping_.size()));
1718 }
1719 }
1720
on_ping_timer_expired(boost::system::error_code const & _error)1721 void routing_manager_stub::on_ping_timer_expired(
1722 boost::system::error_code const &_error) {
1723 if(_error) {
1724 return;
1725 }
1726 std::forward_list<client_t> timed_out_clients;
1727 std::chrono::milliseconds next_timeout(configured_watchdog_timeout_);
1728 bool pinged_clients_remaining(false);
1729
1730 {
1731 // remove timed out clients
1732 std::lock_guard<std::mutex> its_lock(pinged_clients_mutex_);
1733 const std::chrono::steady_clock::time_point now(
1734 std::chrono::steady_clock::now());
1735
1736 for (auto client_iter = pinged_clients_.begin();
1737 client_iter != pinged_clients_.end(); ) {
1738 if ((now - client_iter->second) >= configured_watchdog_timeout_) {
1739 timed_out_clients.push_front(client_iter->first);
1740 client_iter = pinged_clients_.erase(client_iter);
1741 } else {
1742 ++client_iter;
1743 }
1744 }
1745 pinged_clients_remaining = (pinged_clients_.size() > 0);
1746
1747 if(pinged_clients_remaining) {
1748 // find out next timeout
1749 for (const auto &tp : pinged_clients_) {
1750 const std::chrono::milliseconds its_clients_timeout =
1751 std::chrono::duration_cast<std::chrono::milliseconds>(
1752 now - tp.second);
1753 if (next_timeout > its_clients_timeout) {
1754 next_timeout = its_clients_timeout;
1755 }
1756 }
1757 }
1758 }
1759
1760 for (const client_t client : timed_out_clients) {
1761 // Client did not respond to ping. Report client_error in order to
1762 // accept pending offers trying to replace the offers of the client
1763 // that seems to be gone.
1764 host_->handle_client_error(client);
1765 }
1766 if (pinged_clients_remaining) {
1767 boost::system::error_code ec;
1768 pinged_clients_timer_.expires_from_now(next_timeout, ec);
1769 if (ec) {
1770 VSOMEIP_ERROR<< "routing_manager_stub::on_ping_timer_expired "
1771 "setting expiry time of timer failed: " << ec.message();
1772 }
1773 pinged_clients_timer_.async_wait(
1774 std::bind(&routing_manager_stub::on_ping_timer_expired, this,
1775 std::placeholders::_1));
1776 }
1777 }
1778
remove_from_pinged_clients(client_t _client)1779 void routing_manager_stub::remove_from_pinged_clients(client_t _client) {
1780 std::lock_guard<std::mutex> its_lock(pinged_clients_mutex_);
1781 if (!pinged_clients_.size()) {
1782 return;
1783 }
1784 boost::system::error_code ec;
1785 pinged_clients_timer_.cancel(ec);
1786 if (ec) {
1787 VSOMEIP_ERROR << "routing_manager_stub::remove_from_pinged_clients "
1788 "cancellation of timer failed: " << ec.message();
1789 }
1790 pinged_clients_.erase(_client);
1791
1792 if (!pinged_clients_.size()) {
1793 return;
1794 }
1795 const std::chrono::steady_clock::time_point now(
1796 std::chrono::steady_clock::now());
1797 std::chrono::milliseconds next_timeout(configured_watchdog_timeout_);
1798 // find out next timeout
1799 for (const auto &tp : pinged_clients_) {
1800 const std::chrono::milliseconds its_clients_timeout =
1801 std::chrono::duration_cast<std::chrono::milliseconds>(
1802 now - tp.second);
1803 if (next_timeout > its_clients_timeout) {
1804 next_timeout = its_clients_timeout;
1805 }
1806 }
1807 ec.clear();
1808 pinged_clients_timer_.expires_from_now(next_timeout, ec);
1809 if (ec) {
1810 VSOMEIP_ERROR<< "routing_manager_stub::remove_from_pinged_clients "
1811 "setting expiry time of timer failed: " << ec.message();
1812 }
1813 pinged_clients_timer_.async_wait(
1814 std::bind(&routing_manager_stub::on_ping_timer_expired, this,
1815 std::placeholders::_1));
1816 }
1817
is_registered(client_t _client) const1818 bool routing_manager_stub::is_registered(client_t _client) const {
1819 std::lock_guard<std::mutex> its_lock(routing_info_mutex_);
1820 return (routing_info_.find(_client) != routing_info_.end());
1821 }
1822
update_registration(client_t _client,registration_type_e _type)1823 void routing_manager_stub::update_registration(client_t _client,
1824 registration_type_e _type) {
1825
1826 VSOMEIP_INFO << "Application/Client "
1827 << std::hex << std::setw(4) << std::setfill('0') << _client
1828 << " is "
1829 << (_type == registration_type_e::REGISTER ?
1830 "registering." : "deregistering.");
1831
1832 if (_type != registration_type_e::REGISTER) {
1833 security::get()->remove_client_to_uid_gid_mapping(_client);
1834 }
1835
1836 if (_type == registration_type_e::DEREGISTER) {
1837 // If we receive a DEREGISTER client command
1838 // the endpoint error handler is not longer needed
1839 // as the client is going down anyways.
1840
1841 // Normally the handler is removed in "remove_local"
1842 // anyways, but as some time takes place until
1843 // the client DEREGISTER command is consumed
1844 // and therefore "remove_local" is finally called
1845 // it was possible the same client registers itself
1846 // again in very short time and then could "overtake"
1847 // the occurring error in the endpoint and was then
1848 // erroneously unregistered even that error has
1849 // nothing to do with the newly registered client.
1850
1851 auto its_endpoint = host_->find_local(_client);
1852 if (its_endpoint) {
1853 its_endpoint->register_error_handler(nullptr);
1854 }
1855 }
1856
1857 std::lock_guard<std::mutex> its_lock(client_registration_mutex_);
1858 pending_client_registrations_[_client].push_back(_type);
1859 client_registration_condition_.notify_one();
1860
1861 if (_type != registration_type_e::REGISTER) {
1862 std::lock_guard<std::mutex> its_lock(used_client_ids_mutex_);
1863 used_client_ids_.erase(_client);
1864 }
1865 }
1866
get_client() const1867 client_t routing_manager_stub::get_client() const {
1868 return host_->get_client();
1869 }
1870
handle_credentials(const client_t _client,std::set<service_data_t> & _requests)1871 void routing_manager_stub::handle_credentials(const client_t _client, std::set<service_data_t>& _requests) {
1872 if (!_requests.size()) {
1873 return;
1874 }
1875
1876 std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
1877 std::set<std::pair<uint32_t, uint32_t>> its_credentials;
1878 std::pair<uint32_t, uint32_t> its_requester_uid_gid;
1879 if (security::get()->get_client_to_uid_gid_mapping(_client, its_requester_uid_gid)) {
1880 // determine credentials of offering clients using current routing info
1881 std::set<client_t> its_offering_clients;
1882
1883 // search in local clients for the offering client
1884 for (auto request : _requests) {
1885 std::set<client_t> its_clients;
1886 its_clients = host_->find_local_clients(request.service_, request.instance_);
1887 for (auto its_client : its_clients) {
1888 its_offering_clients.insert(its_client);
1889 }
1890 }
1891
1892 // search for UID / GID linked with the client ID that offers the requested services
1893 for (auto its_offering_client : its_offering_clients) {
1894 std::pair<uint32_t, uint32_t> its_uid_gid;
1895 if (security::get()->get_client_to_uid_gid_mapping(its_offering_client, its_uid_gid)) {
1896 if (its_uid_gid != its_requester_uid_gid) {
1897 its_credentials.insert(std::make_pair(std::get<0>(its_uid_gid), std::get<1>(its_uid_gid)));
1898 }
1899 }
1900 }
1901
1902 // send credentials to clients
1903 if (!its_credentials.empty()) {
1904 create_client_credentials_info(_client);
1905 insert_client_credentials_info(_client, its_credentials);
1906 send_client_credentials_info(_client);
1907 }
1908 }
1909 }
1910
handle_requests(const client_t _client,std::set<service_data_t> & _requests)1911 void routing_manager_stub::handle_requests(const client_t _client, std::set<service_data_t>& _requests) {
1912 if (!_requests.size()) {
1913 return;
1914 }
1915 bool service_available(false);
1916 std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
1917 create_client_routing_info(_client);
1918 for (auto request : _requests) {
1919 service_requests_[_client][request.service_][request.instance_]
1920 = std::make_pair(request.major_, request.minor_);
1921 if (request.instance_ == ANY_INSTANCE) {
1922 std::set<client_t> its_clients = host_->find_local_clients(request.service_, request.instance_);
1923 // insert VSOMEIP_ROUTING_CLIENT to check wether service is remotely offered
1924 its_clients.insert(VSOMEIP_ROUTING_CLIENT);
1925 for (const client_t c : its_clients) {
1926 if (c != VSOMEIP_ROUTING_CLIENT &&
1927 c != host_->get_client()) {
1928 if (!is_already_connected(c, _client)) {
1929 if (_client == c) {
1930 service_available = true;
1931 insert_client_routing_info(c,
1932 routing_info_entry_e::RIE_ADD_CLIENT, _client);
1933 } else {
1934 create_client_routing_info(c);
1935 insert_client_routing_info(c,
1936 routing_info_entry_e::RIE_ADD_CLIENT, _client);
1937 send_client_routing_info(c);
1938 }
1939 }
1940 }
1941 if (_client != VSOMEIP_ROUTING_CLIENT &&
1942 _client != host_->get_client()) {
1943 const auto found_client = routing_info_.find(c);
1944 if (found_client != routing_info_.end()) {
1945 const auto found_service = found_client->second.second.find(request.service_);
1946 if (found_service != found_client->second.second.end()) {
1947 for (auto instance : found_service->second) {
1948 service_available = true;
1949 insert_client_routing_info(_client,
1950 routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE,
1951 c, request.service_, instance.first,
1952 instance.second.first, instance.second.second);
1953 }
1954 }
1955 }
1956 }
1957 }
1958 } else {
1959 const client_t c = host_->find_local_client(request.service_, request.instance_);
1960 const auto found_client = routing_info_.find(c);
1961 if (found_client != routing_info_.end()) {
1962 const auto found_service = found_client->second.second.find(request.service_);
1963 if (found_service != found_client->second.second.end()) {
1964 const auto found_instance = found_service->second.find(request.instance_);
1965 if (found_instance != found_service->second.end()) {
1966 if (c != VSOMEIP_ROUTING_CLIENT &&
1967 c != host_->get_client()) {
1968 if (!is_already_connected(c, _client)) {
1969 if (_client == c) {
1970 service_available = true;
1971 insert_client_routing_info(c,
1972 routing_info_entry_e::RIE_ADD_CLIENT, _client);
1973 } else {
1974 create_client_routing_info(c);
1975 insert_client_routing_info(c,
1976 routing_info_entry_e::RIE_ADD_CLIENT, _client);
1977 send_client_routing_info(c);
1978 }
1979 }
1980 }
1981 if (_client != VSOMEIP_ROUTING_CLIENT &&
1982 _client != host_->get_client()) {
1983 service_available = true;
1984 insert_client_routing_info(_client,
1985 routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE,
1986 c, request.service_, request.instance_,
1987 found_instance->second.first,
1988 found_instance->second.second);
1989 }
1990 }
1991 }
1992 }
1993 }
1994 }
1995 if (service_available) {
1996 send_client_routing_info(_client);
1997 }
1998 }
1999
on_client_id_timer_expired(boost::system::error_code const & _error)2000 void routing_manager_stub::on_client_id_timer_expired(boost::system::error_code const &_error) {
2001 std::set<client_t> used_client_ids;
2002 {
2003 std::lock_guard<std::mutex> its_lock(used_client_ids_mutex_);
2004 used_client_ids = used_client_ids_;
2005 used_client_ids_.clear();
2006 }
2007
2008 std::set<client_t> erroneous_clients;
2009 if (!_error) {
2010 std::lock_guard<std::mutex> its_lock(routing_info_mutex_);
2011 for (auto client : used_client_ids) {
2012 if (client != VSOMEIP_ROUTING_CLIENT && client != get_client()) {
2013 if (routing_info_.find(client) == routing_info_.end()) {
2014 erroneous_clients.insert(client);
2015 }
2016 }
2017 }
2018 }
2019 for (auto client : erroneous_clients) {
2020 VSOMEIP_WARNING << "Releasing client identifier "
2021 << std::hex << std::setw(4) << std::setfill('0') << client << ". "
2022 << "Its corresponding application went offline while no "
2023 << "routing manager was running.";
2024 host_->handle_client_error(client);
2025 }
2026 }
2027
print_endpoint_status() const2028 void routing_manager_stub::print_endpoint_status() const {
2029 if (local_receiver_) {
2030 local_receiver_->print_status();
2031 }
2032 if (endpoint_) {
2033 endpoint_->print_status();
2034 }
2035 }
2036
send_provided_event_resend_request(client_t _client,pending_remote_offer_id_t _id)2037 bool routing_manager_stub::send_provided_event_resend_request(client_t _client,
2038 pending_remote_offer_id_t _id) {
2039 std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client);
2040 if (its_endpoint) {
2041 byte_t its_command[VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE];
2042 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_RESEND_PROVIDED_EVENTS;
2043 const client_t routing_client(VSOMEIP_ROUTING_CLIENT);
2044 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &routing_client,
2045 sizeof(routing_client));
2046 std::uint32_t its_size = sizeof(pending_remote_offer_id_t);
2047 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
2048 sizeof(its_size));
2049 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_id,
2050 sizeof(pending_remote_offer_id_t));
2051 return its_endpoint->send(its_command, sizeof(its_command));
2052 } else {
2053 VSOMEIP_WARNING << __func__ << " Couldn't send provided event resend "
2054 "request to local client: 0x"
2055 << std::hex << std::setw(4) << std::setfill('0') << _client;
2056 return false;
2057 }
2058 }
2059
is_policy_cached(uint32_t _uid)2060 bool routing_manager_stub::is_policy_cached(uint32_t _uid) {
2061 {
2062 std::lock_guard<std::mutex> its_lock(updated_security_policies_mutex_);
2063 if (updated_security_policies_.find(_uid)
2064 != updated_security_policies_.end()) {
2065 VSOMEIP_INFO << __func__ << " Policy for UID: " << std::dec
2066 << _uid << " was already updated before!";
2067 return true;
2068 } else {
2069 return false;
2070 }
2071 }
2072 }
2073
policy_cache_add(uint32_t _uid,const std::shared_ptr<payload> & _payload)2074 void routing_manager_stub::policy_cache_add(uint32_t _uid, const std::shared_ptr<payload>& _payload) {
2075 // cache security policy payload for later distribution to new registering clients
2076 {
2077 std::lock_guard<std::mutex> its_lock(updated_security_policies_mutex_);
2078 updated_security_policies_[_uid] = _payload;
2079 }
2080 }
2081
policy_cache_remove(uint32_t _uid)2082 void routing_manager_stub::policy_cache_remove(uint32_t _uid) {
2083 {
2084 std::lock_guard<std::mutex> its_lock(updated_security_policies_mutex_);
2085 updated_security_policies_.erase(_uid);
2086 }
2087 }
2088
send_update_security_policy_request(client_t _client,pending_security_update_id_t _update_id,uint32_t _uid,const std::shared_ptr<payload> & _payload)2089 bool routing_manager_stub::send_update_security_policy_request(client_t _client, pending_security_update_id_t _update_id,
2090 uint32_t _uid, const std::shared_ptr<payload>& _payload) {
2091 (void)_uid;
2092 std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client);
2093 if (its_endpoint) {
2094 std::vector<byte_t> its_command;
2095 // command
2096 its_command.push_back(VSOMEIP_UPDATE_SECURITY_POLICY);
2097
2098 // client ID
2099 for (uint32_t i = 0; i < sizeof(client_t); ++i) {
2100 its_command.push_back(
2101 reinterpret_cast<const byte_t*>(&_client)[i]);
2102 }
2103 // security update id length + payload length including gid and uid
2104 std::uint32_t its_size = uint32_t(sizeof(pending_security_update_id_t) + _payload->get_length());
2105 for (uint32_t i = 0; i < sizeof(its_size); ++i) {
2106 its_command.push_back(
2107 reinterpret_cast<const byte_t*>(&its_size)[i]);
2108 }
2109 // ID of update request
2110 for (uint32_t i = 0; i < sizeof(pending_security_update_id_t); ++i) {
2111 its_command.push_back(
2112 reinterpret_cast<const byte_t*>(&_update_id)[i]);
2113 }
2114 // payload
2115 for (uint32_t i = 0; i < _payload->get_length(); ++i) {
2116 its_command.push_back(_payload->get_data()[i]);
2117 }
2118
2119 return its_endpoint->send(its_command.data(), uint32_t(its_command.size()));
2120 } else {
2121 return false;
2122 }
2123 }
2124
send_cached_security_policies(client_t _client)2125 bool routing_manager_stub::send_cached_security_policies(client_t _client) {
2126 std::vector<byte_t> its_command;
2127 std::size_t its_size(0);
2128
2129 std::lock_guard<std::mutex> its_lock(updated_security_policies_mutex_);
2130 uint32_t its_policy_count = uint32_t(updated_security_policies_.size());
2131
2132 if (!its_policy_count) {
2133 return true;
2134 }
2135
2136 VSOMEIP_INFO << __func__ << " Distributing ["
2137 << std::dec << its_policy_count
2138 << "] security policy updates to registering client: "
2139 << std::hex << _client;
2140
2141 // command
2142 its_command.push_back(VSOMEIP_DISTRIBUTE_SECURITY_POLICIES);
2143
2144 // client ID
2145 client_t its_client = get_client();
2146 for (uint32_t i = 0; i < sizeof(client_t); ++i) {
2147 its_command.push_back(
2148 reinterpret_cast<const byte_t*>(&its_client)[i]);
2149 }
2150
2151 //overall size (placeholder
2152 for (uint32_t i = 0; i < sizeof(uint32_t); ++i) {
2153 its_command.push_back(0x00);
2154 }
2155
2156 // number of policies contained in message
2157 for (uint32_t i = 0; i < sizeof(its_policy_count); ++i) {
2158 its_command.push_back(
2159 reinterpret_cast<const byte_t*>(&its_policy_count)[i]);
2160 }
2161
2162 for (const auto& its_uid_gid : updated_security_policies_) {
2163 // policy payload length including gid and uid
2164 std::uint32_t its_length = uint32_t(its_uid_gid.second->get_length());
2165 for (uint32_t i = 0; i < sizeof(its_length); ++i) {
2166 its_command.push_back(
2167 reinterpret_cast<const byte_t*>(&its_length)[i]);
2168 }
2169 // payload
2170 its_command.insert(its_command.end(), its_uid_gid.second->get_data(),
2171 its_uid_gid.second->get_data() + its_uid_gid.second->get_length());
2172 }
2173 // File overall size
2174 its_size = its_command.size() - VSOMEIP_COMMAND_PAYLOAD_POS;
2175 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, sizeof(uint32_t));
2176
2177 std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client);
2178 if (its_endpoint) {
2179 return its_endpoint->send(its_command.data(), uint32_t(its_command.size()));
2180 } else {
2181 VSOMEIP_WARNING << __func__ << " Couldn't send cached security policies "
2182 " to registering client: 0x"
2183 << std::hex << std::setw(4) << std::setfill('0') << _client;
2184 return false;
2185 }
2186 }
2187
send_remove_security_policy_request(client_t _client,pending_security_update_id_t _update_id,uint32_t _uid,uint32_t _gid)2188 bool routing_manager_stub::send_remove_security_policy_request( client_t _client, pending_security_update_id_t _update_id,
2189 uint32_t _uid, uint32_t _gid) {
2190 std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client);
2191 if (its_endpoint) {
2192 byte_t its_command[VSOMEIP_REMOVE_SECURITY_POLICY_COMMAND_SIZE];
2193 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_REMOVE_SECURITY_POLICY;
2194 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client,
2195 sizeof(client_t));
2196 std::uint32_t its_size = sizeof(_update_id) + sizeof(_uid) + sizeof(_gid);
2197 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
2198 sizeof(its_size));
2199 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_update_id,
2200 sizeof(uint32_t));
2201 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_uid,
2202 sizeof(uint32_t));
2203 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_gid,
2204 sizeof(uint32_t));
2205 return its_endpoint->send(its_command, sizeof(its_command));
2206 } else {
2207 return false;
2208 }
2209 }
2210
2211 bool
add_requester_policies(uid_t _uid,gid_t _gid,const std::set<std::shared_ptr<policy>> & _policies)2212 routing_manager_stub::add_requester_policies(uid_t _uid, gid_t _gid,
2213 const std::set<std::shared_ptr<policy> > &_policies) {
2214
2215 std::lock_guard<std::mutex> its_lock(requester_policies_mutex_);
2216 auto found_uid = requester_policies_.find(_uid);
2217 if (found_uid != requester_policies_.end()) {
2218 auto found_gid = found_uid->second.find(_gid);
2219 if (found_gid != found_uid->second.end()) {
2220 found_gid->second.insert(_policies.begin(), _policies.end());
2221 } else {
2222 found_uid->second.insert(std::make_pair(_gid, _policies));
2223 }
2224 } else {
2225 requester_policies_[_uid][_gid] = _policies;
2226 }
2227
2228 // Check whether clients with uid/gid are already registered.
2229 // If yes, update their policy
2230 std::unordered_set<client_t> its_clients;
2231 security::get()->get_clients(_uid, _gid, its_clients);
2232
2233 if (!its_clients.empty())
2234 return send_requester_policies(its_clients, _policies);
2235
2236 return (true);
2237 }
2238
2239 void
remove_requester_policies(uid_t _uid,gid_t _gid)2240 routing_manager_stub::remove_requester_policies(uid_t _uid, gid_t _gid) {
2241
2242 std::lock_guard<std::mutex> its_lock(requester_policies_mutex_);
2243 auto found_uid = requester_policies_.find(_uid);
2244 if (found_uid != requester_policies_.end()) {
2245 found_uid->second.erase(_gid);
2246 if (found_uid->second.empty())
2247 requester_policies_.erase(_uid);
2248 }
2249 }
2250
2251 void
get_requester_policies(uid_t _uid,gid_t _gid,std::set<std::shared_ptr<policy>> & _policies) const2252 routing_manager_stub::get_requester_policies(uid_t _uid, gid_t _gid,
2253 std::set<std::shared_ptr<policy> > &_policies) const {
2254
2255 std::lock_guard<std::mutex> its_lock(requester_policies_mutex_);
2256 auto found_uid = requester_policies_.find(_uid);
2257 if (found_uid != requester_policies_.end()) {
2258 auto found_gid = found_uid->second.find(_gid);
2259 if (found_gid != found_uid->second.end())
2260 _policies = found_gid->second;
2261 }
2262 }
2263
2264 void
add_pending_security_update_handler(pending_security_update_id_t _id,security_update_handler_t _handler)2265 routing_manager_stub::add_pending_security_update_handler(
2266 pending_security_update_id_t _id, security_update_handler_t _handler) {
2267
2268 std::lock_guard<std::recursive_mutex> its_lock(security_update_handlers_mutex_);
2269 security_update_handlers_[_id] = _handler;
2270 }
2271
2272 void
add_pending_security_update_timer(pending_security_update_id_t _id)2273 routing_manager_stub::add_pending_security_update_timer(
2274 pending_security_update_id_t _id) {
2275
2276 std::shared_ptr<boost::asio::steady_timer> its_timer
2277 = std::make_shared<boost::asio::steady_timer>(io_);
2278
2279 boost::system::error_code ec;
2280 its_timer->expires_from_now(std::chrono::milliseconds(3000), ec);
2281 if (!ec) {
2282 its_timer->async_wait(
2283 std::bind(
2284 &routing_manager_stub::on_security_update_timeout,
2285 shared_from_this(),
2286 std::placeholders::_1, _id, its_timer));
2287 } else {
2288 VSOMEIP_ERROR << __func__
2289 << "[" << std::dec << _id << "]: timer creation: "
2290 << ec.message();
2291 }
2292 std::lock_guard<std::mutex> its_lock(security_update_timers_mutex_);
2293 security_update_timers_[_id] = its_timer;
2294 }
2295
2296 bool
send_requester_policies(const std::unordered_set<client_t> & _clients,const std::set<std::shared_ptr<policy>> & _policies)2297 routing_manager_stub::send_requester_policies(const std::unordered_set<client_t> &_clients,
2298 const std::set<std::shared_ptr<policy> > &_policies) {
2299
2300 pending_security_update_id_t its_policy_id;
2301
2302 // serialize the policies and send them...
2303 for (const auto &p : _policies) {
2304 std::vector<byte_t> its_policy_data;
2305 if (p->serialize(its_policy_data)) {
2306 std::vector<byte_t> its_message;
2307 its_message.push_back(VSOMEIP_UPDATE_SECURITY_POLICY_INT);
2308 its_message.push_back(0);
2309 its_message.push_back(0);
2310
2311 uint32_t its_policy_size = static_cast<uint32_t>(its_policy_data.size() + sizeof(uint32_t));
2312 its_message.push_back(VSOMEIP_LONG_BYTE0(its_policy_size));
2313 its_message.push_back(VSOMEIP_LONG_BYTE1(its_policy_size));
2314 its_message.push_back(VSOMEIP_LONG_BYTE2(its_policy_size));
2315 its_message.push_back(VSOMEIP_LONG_BYTE3(its_policy_size));
2316
2317 its_policy_id = pending_security_update_add(_clients);
2318 its_message.push_back(VSOMEIP_LONG_BYTE0(its_policy_id));
2319 its_message.push_back(VSOMEIP_LONG_BYTE1(its_policy_id));
2320 its_message.push_back(VSOMEIP_LONG_BYTE2(its_policy_id));
2321 its_message.push_back(VSOMEIP_LONG_BYTE3(its_policy_id));
2322
2323 its_message.insert(its_message.end(), its_policy_data.begin(), its_policy_data.end());
2324
2325 for (const auto& c : _clients) {
2326 std::shared_ptr<endpoint> its_endpoint = host_->find_local(c);
2327 if (its_endpoint)
2328 its_endpoint->send(&its_message[0], static_cast<uint32_t>(its_message.size()));
2329 }
2330 }
2331 }
2332
2333 return (true);
2334 }
2335
on_security_update_timeout(const boost::system::error_code & _error,pending_security_update_id_t _id,std::shared_ptr<boost::asio::steady_timer> _timer)2336 void routing_manager_stub::on_security_update_timeout(
2337 const boost::system::error_code& _error,
2338 pending_security_update_id_t _id,
2339 std::shared_ptr<boost::asio::steady_timer> _timer) {
2340 (void)_timer;
2341 if (_error) {
2342 // timer was cancelled
2343 return;
2344 }
2345 security_update_state_e its_state = security_update_state_e::SU_UNKNOWN_USER_ID;
2346 std::unordered_set<client_t> its_missing_clients = pending_security_update_get(_id);
2347 {
2348 // erase timer
2349 std::lock_guard<std::mutex> its_lock(security_update_timers_mutex_);
2350 security_update_timers_.erase(_id);
2351 }
2352 {
2353 // print missing responses and check if some clients did not respond because they already disconnected
2354 if (!its_missing_clients.empty()) {
2355 for (auto its_client : its_missing_clients) {
2356 VSOMEIP_INFO << __func__ << ": Client 0x" << std::hex << its_client
2357 << " did not respond to the policy update / removal with ID: 0x" << std::hex << _id;
2358 if (!host_->find_local(its_client)) {
2359 VSOMEIP_INFO << __func__ << ": Client 0x" << std::hex << its_client
2360 << " is not connected anymore, do not expect answer for policy update / removal with ID: 0x"
2361 << std::hex << _id;
2362 pending_security_update_remove(_id, its_client);
2363 }
2364 }
2365 }
2366
2367 its_missing_clients = pending_security_update_get(_id);
2368 if (its_missing_clients.empty()) {
2369 VSOMEIP_INFO << __func__ << ": Received all responses for "
2370 "security update/removal ID: 0x" << std::hex << _id;
2371 its_state = security_update_state_e::SU_SUCCESS;
2372 }
2373 {
2374 // erase pending security update
2375 std::lock_guard<std::mutex> its_lock(pending_security_updates_mutex_);
2376 pending_security_updates_.erase(_id);
2377 }
2378
2379 // call handler with error on timeout or with SUCCESS if missing clients are not connected
2380 std::lock_guard<std::recursive_mutex> its_lock(security_update_handlers_mutex_);
2381 const auto found_handler = security_update_handlers_.find(_id);
2382 if (found_handler != security_update_handlers_.end()) {
2383 found_handler->second(its_state);
2384 security_update_handlers_.erase(found_handler);
2385 } else {
2386 VSOMEIP_WARNING << __func__ << ": Callback not found for security update / removal with ID: 0x"
2387 << std::hex << _id;
2388 }
2389 }
2390 }
2391
update_security_policy_configuration(uint32_t _uid,uint32_t _gid,const std::shared_ptr<policy> & _policy,const std::shared_ptr<payload> & _payload,const security_update_handler_t & _handler)2392 bool routing_manager_stub::update_security_policy_configuration(
2393 uint32_t _uid, uint32_t _gid,
2394 const std::shared_ptr<policy> &_policy,
2395 const std::shared_ptr<payload> &_payload,
2396 const security_update_handler_t &_handler) {
2397
2398 bool ret(true);
2399
2400 // cache security policy payload for later distribution to new registering clients
2401 policy_cache_add(_uid, _payload);
2402
2403 // update security policy from configuration
2404 security::get()->update_security_policy(_uid, _gid, _policy);
2405
2406 // Build requester policies for the services offered by the new policy
2407 std::set<std::shared_ptr<policy> > its_requesters;
2408 security::get()->get_requester_policies(_policy, its_requesters);
2409
2410 // and add them to the requester policy cache
2411 add_requester_policies(_uid, _gid, its_requesters);
2412
2413 // determine currently connected clients
2414 std::unordered_set<client_t> its_clients_to_inform;
2415 auto its_epm = host_->get_endpoint_manager();
2416 if (its_epm)
2417 its_clients_to_inform = its_epm->get_connected_clients();
2418
2419 // add handler
2420 pending_security_update_id_t its_id;
2421 if (!its_clients_to_inform.empty()) {
2422 its_id = pending_security_update_add(its_clients_to_inform);
2423
2424 add_pending_security_update_handler(its_id, _handler);
2425 add_pending_security_update_timer(its_id);
2426
2427 // trigger all currently connected clients to update the security policy
2428 uint32_t sent_counter(0);
2429 uint32_t its_tranche =
2430 uint32_t(its_clients_to_inform.size() >= 10 ? (its_clients_to_inform.size() / 10) : 1);
2431 VSOMEIP_INFO << __func__ << ": Informing [" << std::dec << its_clients_to_inform.size()
2432 << "] currently connected clients about policy update for UID: "
2433 << std::dec << _uid << " with update ID: 0x" << std::hex << its_id;
2434 for (auto its_client : its_clients_to_inform) {
2435 if (!send_update_security_policy_request(its_client, its_id, _uid, _payload)) {
2436 VSOMEIP_INFO << __func__ << ": Couldn't send update security policy "
2437 << "request to client 0x" << std::hex << std::setw(4)
2438 << std::setfill('0') << its_client << " policy UID: "
2439 << std::hex << std::setw(4) << std::setfill('0') << _uid << " GID: "
2440 << std::hex << std::setw(4) << std::setfill('0') << _gid
2441 << " with update ID: 0x" << std::hex << its_id
2442 << " as client already disconnected";
2443 // remove client from expected answer list
2444 pending_security_update_remove(its_id, its_client);
2445 }
2446 sent_counter++;
2447 // Prevent burst
2448 if (sent_counter % its_tranche == 0) {
2449 std::this_thread::sleep_for(std::chrono::milliseconds(10));
2450 }
2451 }
2452 } else {
2453 // if routing manager has no client call the handler directly
2454 _handler(security_update_state_e::SU_SUCCESS);
2455 }
2456
2457 return ret;
2458 }
2459
remove_security_policy_configuration(uint32_t _uid,uint32_t _gid,const security_update_handler_t & _handler)2460 bool routing_manager_stub::remove_security_policy_configuration(
2461 uint32_t _uid, uint32_t _gid, const security_update_handler_t &_handler) {
2462
2463 bool ret(true);
2464
2465 // remove security policy from configuration (only if there was a updateACL call before)
2466 if (is_policy_cached(_uid)) {
2467 if (!security::get()->remove_security_policy(_uid, _gid)) {
2468 _handler(security_update_state_e::SU_UNKNOWN_USER_ID);
2469 ret = false;
2470 } else {
2471 // remove policy from cache to prevent sending it to registering clients
2472 policy_cache_remove(_uid);
2473
2474 // add handler
2475 pending_security_update_id_t its_id;
2476
2477 // determine currently connected clients
2478 std::unordered_set<client_t> its_clients_to_inform;
2479 auto its_epm = host_->get_endpoint_manager();
2480 if (its_epm)
2481 its_clients_to_inform = its_epm->get_connected_clients();
2482
2483 if (!its_clients_to_inform.empty()) {
2484 its_id = pending_security_update_add(its_clients_to_inform);
2485
2486 add_pending_security_update_handler(its_id, _handler);
2487 add_pending_security_update_timer(its_id);
2488
2489 // trigger all clients to remove the security policy
2490 uint32_t sent_counter(0);
2491 uint32_t its_tranche =
2492 uint32_t(its_clients_to_inform.size() >= 10 ? (its_clients_to_inform.size() / 10) : 1);
2493 VSOMEIP_INFO << __func__ << ": Informing [" << std::dec << its_clients_to_inform.size()
2494 << "] currently connected clients about policy removal for UID: "
2495 << std::dec << _uid << " with update ID: " << its_id;
2496 for (auto its_client : its_clients_to_inform) {
2497 if (!send_remove_security_policy_request(its_client, its_id, _uid, _gid)) {
2498 VSOMEIP_INFO << __func__ << ": Couldn't send remove security policy "
2499 << "request to client 0x" << std::hex << std::setw(4)
2500 << std::setfill('0') << its_client << " policy UID: "
2501 << std::hex << std::setw(4) << std::setfill('0') << _uid << " GID: "
2502 << std::hex << std::setw(4) << std::setfill('0') << _gid
2503 << " with update ID: 0x" << std::hex << its_id
2504 << " as client already disconnected";
2505 // remove client from expected answer list
2506 pending_security_update_remove(its_id, its_client);
2507 }
2508 sent_counter++;
2509 // Prevent burst
2510 if (sent_counter % its_tranche == 0) {
2511 std::this_thread::sleep_for(std::chrono::milliseconds(10));
2512 }
2513 }
2514 } else {
2515 // if routing manager has no client call the handler directly
2516 _handler(security_update_state_e::SU_SUCCESS);
2517 }
2518 }
2519 }
2520 else {
2521 _handler(security_update_state_e::SU_UNKNOWN_USER_ID);
2522 ret = false;
2523 }
2524 return ret;
2525 }
2526
pending_security_update_add(const std::unordered_set<client_t> & _clients)2527 pending_security_update_id_t routing_manager_stub::pending_security_update_add(
2528 const std::unordered_set<client_t>& _clients) {
2529 std::lock_guard<std::mutex> its_lock(pending_security_updates_mutex_);
2530 if (++pending_security_update_id_ == 0) {
2531 pending_security_update_id_++;
2532 }
2533 pending_security_updates_[pending_security_update_id_] = _clients;
2534
2535 return pending_security_update_id_;
2536 }
2537
pending_security_update_get(pending_security_update_id_t _id)2538 std::unordered_set<client_t> routing_manager_stub::pending_security_update_get(
2539 pending_security_update_id_t _id) {
2540 std::lock_guard<std::mutex> its_lock(pending_security_updates_mutex_);
2541 std::unordered_set<client_t> its_missing_clients;
2542 auto found_si = pending_security_updates_.find(_id);
2543 if (found_si != pending_security_updates_.end()) {
2544 its_missing_clients = pending_security_updates_[_id];
2545 }
2546 return its_missing_clients;
2547 }
2548
pending_security_update_remove(pending_security_update_id_t _id,client_t _client)2549 bool routing_manager_stub::pending_security_update_remove(
2550 pending_security_update_id_t _id, client_t _client) {
2551 std::lock_guard<std::mutex> its_lock(pending_security_updates_mutex_);
2552 auto found_si = pending_security_updates_.find(_id);
2553 if (found_si != pending_security_updates_.end()) {
2554 if (found_si->second.erase(_client)) {
2555 return true;
2556 }
2557 }
2558 return false;
2559 }
2560
is_pending_security_update_finished(pending_security_update_id_t _id)2561 bool routing_manager_stub::is_pending_security_update_finished(
2562 pending_security_update_id_t _id) {
2563 std::lock_guard<std::mutex> its_lock(pending_security_updates_mutex_);
2564 bool ret(false);
2565 auto found_si = pending_security_updates_.find(_id);
2566 if (found_si != pending_security_updates_.end()) {
2567 if (!found_si->second.size()) {
2568 ret = true;
2569 }
2570 }
2571 if (ret) {
2572 pending_security_updates_.erase(_id);
2573 }
2574 return ret;
2575 }
2576
on_security_update_response(pending_security_update_id_t _id,client_t _client)2577 void routing_manager_stub::on_security_update_response(
2578 pending_security_update_id_t _id, client_t _client) {
2579 if (pending_security_update_remove(_id, _client)) {
2580 if (is_pending_security_update_finished(_id)) {
2581 // cancel timeout timer
2582 {
2583 std::lock_guard<std::mutex> its_lock(security_update_timers_mutex_);
2584 auto found_timer = security_update_timers_.find(_id);
2585 if (found_timer != security_update_timers_.end()) {
2586 boost::system::error_code ec;
2587 found_timer->second->cancel(ec);
2588 security_update_timers_.erase(found_timer);
2589 } else {
2590 VSOMEIP_WARNING << __func__ << ": Received all responses "
2591 "for security update/removal ID: 0x"
2592 << std::hex << _id << " but timeout already happened";
2593 }
2594 }
2595
2596 // call handler
2597 {
2598 std::lock_guard<std::recursive_mutex> its_lock(security_update_handlers_mutex_);
2599 auto found_handler = security_update_handlers_.find(_id);
2600 if (found_handler != security_update_handlers_.end()) {
2601 found_handler->second(security_update_state_e::SU_SUCCESS);
2602 security_update_handlers_.erase(found_handler);
2603 VSOMEIP_INFO << __func__ << ": Received all responses for "
2604 "security update/removal ID: 0x" << std::hex << _id;
2605 } else {
2606 VSOMEIP_WARNING << __func__ << ": Received all responses "
2607 "for security update/removal ID: 0x"
2608 << std::hex << _id << " but didn't find handler";
2609 }
2610 }
2611 }
2612 }
2613 }
2614
send_suspend() const2615 void routing_manager_stub::send_suspend() const {
2616
2617 static const std::vector<byte_t> its_suspend(
2618 { VSOMEIP_SUSPEND, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
2619
2620 broadcast(its_suspend);
2621 }
2622
2623 } // namespace vsomeip_v3
2624