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 <climits>
7 #include <iomanip>
8 #include <mutex>
9 #include <unordered_set>
10 #include <future>
11 #include <forward_list>
12
13 #include <vsomeip/constants.hpp>
14 #include <vsomeip/runtime.hpp>
15 #include <vsomeip/internal/logger.hpp>
16
17 #include "../include/event.hpp"
18 #include "../include/routing_manager_host.hpp"
19 #include "../include/routing_manager_proxy.hpp"
20 #include "../../configuration/include/configuration.hpp"
21 #include "../../security/include/policy.hpp"
22 #include "../../security/include/security_impl.hpp"
23
24 #include "../../endpoints/include/local_client_endpoint_impl.hpp"
25 #include "../../endpoints/include/local_server_endpoint_impl.hpp"
26 #include "../../message/include/deserializer.hpp"
27 #include "../../message/include/message_impl.hpp"
28 #include "../../message/include/serializer.hpp"
29 #include "../../service_discovery/include/runtime.hpp"
30 #include "../../utility/include/byteorder.hpp"
31 #include "../../utility/include/utility.hpp"
32 #ifdef USE_DLT
33 #include "../../tracing/include/connector_impl.hpp"
34 #endif
35
36 namespace vsomeip_v3 {
37
routing_manager_proxy(routing_manager_host * _host,bool _client_side_logging,const std::set<std::tuple<service_t,instance_t>> & _client_side_logging_filter)38 routing_manager_proxy::routing_manager_proxy(routing_manager_host *_host,
39 bool _client_side_logging,
40 const std::set<std::tuple<service_t, instance_t> > & _client_side_logging_filter) :
41 routing_manager_base(_host),
42 is_connected_(false),
43 is_started_(false),
44 state_(inner_state_type_e::ST_DEREGISTERED),
45 sender_(nullptr),
46 receiver_(nullptr),
47 register_application_timer_(io_),
48 request_debounce_timer_ (io_),
49 request_debounce_timer_running_(false),
50 client_side_logging_(_client_side_logging),
51 client_side_logging_filter_(_client_side_logging_filter)
52 {
53 }
54
~routing_manager_proxy()55 routing_manager_proxy::~routing_manager_proxy() {
56 }
57
init()58 void routing_manager_proxy::init() {
59 routing_manager_base::init(std::make_shared<endpoint_manager_base>(this, io_, configuration_));
60 {
61 std::lock_guard<std::mutex> its_lock(sender_mutex_);
62 sender_ = ep_mgr_->create_local(VSOMEIP_ROUTING_CLIENT);
63 }
64 }
65
start()66 void routing_manager_proxy::start() {
67 is_started_ = true;
68 {
69 std::lock_guard<std::mutex> its_lock(sender_mutex_);
70 if (!sender_) {
71 // application has been stopped and started again
72 sender_ = ep_mgr_->create_local(VSOMEIP_ROUTING_CLIENT);
73 }
74 if (sender_) {
75 sender_->start();
76 }
77 }
78 }
79
stop()80 void routing_manager_proxy::stop() {
81 std::unique_lock<std::mutex> its_lock(state_mutex_);
82 if (state_ == inner_state_type_e::ST_REGISTERING) {
83 register_application_timer_.cancel();
84 }
85
86 const std::chrono::milliseconds its_timeout(configuration_->get_shutdown_timeout());
87 while (state_ == inner_state_type_e::ST_REGISTERING) {
88 std::cv_status status = state_condition_.wait_for(its_lock, its_timeout);
89 if (status == std::cv_status::timeout) {
90 VSOMEIP_WARNING << std::hex << client_ << " registering timeout on stop";
91 break;
92 }
93 }
94
95 if (state_ == inner_state_type_e::ST_REGISTERED) {
96 deregister_application();
97 // Waiting de-register acknowledge to synchronize shutdown
98 while (state_ == inner_state_type_e::ST_REGISTERED) {
99 std::cv_status status = state_condition_.wait_for(its_lock, its_timeout);
100 if (status == std::cv_status::timeout) {
101 VSOMEIP_WARNING << std::hex << client_ << " couldn't deregister application - timeout";
102 break;
103 }
104 }
105 }
106 is_started_ = false;
107 its_lock.unlock();
108
109 {
110 std::lock_guard<std::mutex> its_lock(request_timer_mutex_);
111 request_debounce_timer_.cancel();
112 }
113
114 if (receiver_) {
115 receiver_->stop();
116 }
117 receiver_ = nullptr;
118
119 {
120 std::lock_guard<std::mutex> its_lock(sender_mutex_);
121 if (sender_) {
122 sender_->stop();
123 }
124 // delete the sender
125 sender_ = nullptr;
126 }
127
128 for (const auto& client : ep_mgr_->get_connected_clients()) {
129 if (client != VSOMEIP_ROUTING_CLIENT) {
130 remove_local(client, true);
131 }
132 }
133
134 std::stringstream its_client;
135 its_client << utility::get_base_path(configuration_) << std::hex << client_;
136 #ifdef _WIN32
137 ::_unlink(its_client.str().c_str());
138 #else
139 if (-1 == ::unlink(its_client.str().c_str())) {
140 VSOMEIP_ERROR<< "routing_manager_proxy::stop unlink failed ("
141 << its_client.str() << "): "<< std::strerror(errno);
142 }
143 #endif
144 }
145
get_configuration() const146 std::shared_ptr<configuration> routing_manager_proxy::get_configuration() const {
147 return host_->get_configuration();
148 }
149
offer_service(client_t _client,service_t _service,instance_t _instance,major_version_t _major,minor_version_t _minor)150 bool routing_manager_proxy::offer_service(client_t _client,
151 service_t _service, instance_t _instance,
152 major_version_t _major, minor_version_t _minor) {
153
154 if(!routing_manager_base::offer_service(_client, _service, _instance, _major, _minor)) {
155 VSOMEIP_WARNING << "routing_manager_proxy::offer_service,"
156 << "routing_manager_base::offer_service returned false";
157 return false;
158 }
159 {
160 std::lock_guard<std::mutex> its_lock(state_mutex_);
161 if (state_ == inner_state_type_e::ST_REGISTERED) {
162 send_offer_service(_client, _service, _instance, _major, _minor);
163 }
164 service_data_t offer = { _service, _instance, _major, _minor };
165 pending_offers_.insert(offer);
166 }
167 return true;
168 }
169
send_offer_service(client_t _client,service_t _service,instance_t _instance,major_version_t _major,minor_version_t _minor)170 void routing_manager_proxy::send_offer_service(client_t _client,
171 service_t _service, instance_t _instance,
172 major_version_t _major, minor_version_t _minor) {
173 (void)_client;
174
175 byte_t its_command[VSOMEIP_OFFER_SERVICE_COMMAND_SIZE];
176 uint32_t its_size = VSOMEIP_OFFER_SERVICE_COMMAND_SIZE
177 - VSOMEIP_COMMAND_HEADER_SIZE;
178
179 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_OFFER_SERVICE;
180 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
181 sizeof(client_));
182 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
183 sizeof(its_size));
184 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
185 sizeof(_service));
186 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
187 sizeof(_instance));
188 its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4] = _major;
189 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5], &_minor,
190 sizeof(_minor));
191
192 {
193 std::lock_guard<std::mutex> its_lock(sender_mutex_);
194 if (sender_) {
195 sender_->send(its_command, sizeof(its_command));
196 }
197 }
198 }
199
stop_offer_service(client_t _client,service_t _service,instance_t _instance,major_version_t _major,minor_version_t _minor)200 void routing_manager_proxy::stop_offer_service(client_t _client,
201 service_t _service, instance_t _instance,
202 major_version_t _major, minor_version_t _minor) {
203
204 (void)_client;
205
206 {
207 // Hold the mutex to ensure no placeholder event is created inbetween.
208 std::lock_guard<std::mutex> its_lock(stop_mutex_);
209
210 routing_manager_base::stop_offer_service(_client, _service, _instance, _major, _minor);
211 clear_remote_subscriber_count(_service, _instance);
212
213 // Note: The last argument does not matter here as a proxy
214 // does not manage endpoints to the external network.
215 clear_service_info(_service, _instance, false);
216 }
217
218 {
219 std::lock_guard<std::mutex> its_lock(state_mutex_);
220 if (state_ == inner_state_type_e::ST_REGISTERED) {
221 byte_t its_command[VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE];
222 uint32_t its_size = VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE
223 - VSOMEIP_COMMAND_HEADER_SIZE;
224
225 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_STOP_OFFER_SERVICE;
226 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
227 sizeof(client_));
228 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
229 sizeof(its_size));
230 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
231 sizeof(_service));
232 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
233 sizeof(_instance));
234 its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4] = _major;
235 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5], &_minor,
236 sizeof(_minor));
237
238 {
239 std::lock_guard<std::mutex> its_lock(sender_mutex_);
240 if (sender_) {
241 sender_->send(its_command, sizeof(its_command));
242 }
243 }
244 }
245 auto it = pending_offers_.begin();
246 while (it != pending_offers_.end()) {
247 if (it->service_ == _service
248 && it->instance_ == _instance) {
249 break;
250 }
251 it++;
252 }
253 if (it != pending_offers_.end()) pending_offers_.erase(it);
254 }
255 }
256
request_service(client_t _client,service_t _service,instance_t _instance,major_version_t _major,minor_version_t _minor)257 void routing_manager_proxy::request_service(client_t _client,
258 service_t _service, instance_t _instance,
259 major_version_t _major, minor_version_t _minor) {
260 routing_manager_base::request_service(_client,
261 _service, _instance, _major, _minor);
262 {
263 std::lock_guard<std::mutex> its_lock(state_mutex_);
264 size_t request_debouncing_time = configuration_->get_request_debouncing(host_->get_name());
265 service_data_t request = { _service, _instance, _major, _minor };
266 if (!request_debouncing_time) {
267 if (state_ == inner_state_type_e::ST_REGISTERED) {
268 std::set<service_data_t> requests;
269 requests.insert(request);
270 send_request_services(requests);
271 }
272 requests_.insert(request);
273 } else {
274 requests_to_debounce_.insert(request);
275 std::lock_guard<std::mutex> its_lock(request_timer_mutex_);
276 if (!request_debounce_timer_running_) {
277 request_debounce_timer_running_ = true;
278 request_debounce_timer_.expires_from_now(std::chrono::milliseconds(request_debouncing_time));
279 request_debounce_timer_.async_wait(
280 std::bind(
281 &routing_manager_proxy::request_debounce_timeout_cbk,
282 std::dynamic_pointer_cast<routing_manager_proxy>(shared_from_this()),
283 std::placeholders::_1));
284 }
285 }
286 }
287 }
288
release_service(client_t _client,service_t _service,instance_t _instance)289 void routing_manager_proxy::release_service(client_t _client,
290 service_t _service, instance_t _instance) {
291 routing_manager_base::release_service(_client, _service, _instance);
292 {
293 std::lock_guard<std::mutex> its_lock(state_mutex_);
294 remove_pending_subscription(_service, _instance, 0xFFFF, ANY_EVENT);
295
296 auto it = requests_to_debounce_.begin();
297 while (it != requests_to_debounce_.end()) {
298 if (it->service_ == _service
299 && it->instance_ == _instance) {
300 break;
301 }
302 it++;
303 }
304 if (it != requests_to_debounce_.end()) {
305 requests_to_debounce_.erase(it);
306 } else if (state_ == inner_state_type_e::ST_REGISTERED) {
307 send_release_service(_client, _service, _instance);
308 }
309
310 {
311 auto it = requests_.begin();
312 while (it != requests_.end()) {
313 if (it->service_ == _service
314 && it->instance_ == _instance) {
315 break;
316 }
317 it++;
318 }
319 if (it != requests_.end()) requests_.erase(it);
320 }
321 }
322 }
323
register_event(client_t _client,service_t _service,instance_t _instance,event_t _notifier,const std::set<eventgroup_t> & _eventgroups,const event_type_e _type,reliability_type_e _reliability,std::chrono::milliseconds _cycle,bool _change_resets_cycle,bool _update_on_change,epsilon_change_func_t _epsilon_change_func,bool _is_provided,bool _is_shadow,bool _is_cache_placeholder)324 void routing_manager_proxy::register_event(client_t _client,
325 service_t _service, instance_t _instance,
326 event_t _notifier,
327 const std::set<eventgroup_t> &_eventgroups, const event_type_e _type,
328 reliability_type_e _reliability,
329 std::chrono::milliseconds _cycle, bool _change_resets_cycle,
330 bool _update_on_change, epsilon_change_func_t _epsilon_change_func,
331 bool _is_provided, bool _is_shadow, bool _is_cache_placeholder) {
332 (void)_is_shadow;
333 (void)_is_cache_placeholder;
334
335 const event_data_t registration = {
336 _service,
337 _instance,
338 _notifier,
339 _type,
340 _reliability,
341 _is_provided,
342 _eventgroups
343 };
344 bool is_first(false);
345 {
346 std::lock_guard<std::mutex> its_lock(state_mutex_);
347 is_first = pending_event_registrations_.find(registration)
348 == pending_event_registrations_.end();
349 #ifndef VSOMEIP_ENABLE_COMPAT
350 if (is_first) {
351 pending_event_registrations_.insert(registration);
352 }
353 #else
354 bool insert = true;
355 if (is_first) {
356 for (auto iter = pending_event_registrations_.begin();
357 iter != pending_event_registrations_.end();) {
358 if (iter->service_ == _service
359 && iter->instance_ == _instance
360 && iter->notifier_ == _notifier
361 && iter->is_provided_ == _is_provided
362 && iter->type_ == event_type_e::ET_EVENT
363 && _type == event_type_e::ET_SELECTIVE_EVENT) {
364 iter = pending_event_registrations_.erase(iter);
365 iter = pending_event_registrations_.insert(registration).first;
366 is_first = true;
367 insert = false;
368 break;
369 } else {
370 iter++;
371 }
372 }
373 if (insert) {
374 pending_event_registrations_.insert(registration);
375 }
376 }
377 #endif
378 }
379 if (is_first || _is_provided) {
380 routing_manager_base::register_event(_client,
381 _service, _instance,
382 _notifier,
383 _eventgroups, _type, _reliability,
384 _cycle, _change_resets_cycle, _update_on_change,
385 _epsilon_change_func,
386 _is_provided);
387 }
388 {
389 std::lock_guard<std::mutex> its_lock(state_mutex_);
390 if (state_ == inner_state_type_e::ST_REGISTERED && is_first) {
391 send_register_event(client_, _service, _instance,
392 _notifier, _eventgroups, _type, _reliability, _is_provided);
393 }
394 }
395 }
396
unregister_event(client_t _client,service_t _service,instance_t _instance,event_t _notifier,bool _is_provided)397 void routing_manager_proxy::unregister_event(client_t _client,
398 service_t _service, instance_t _instance, event_t _notifier,
399 bool _is_provided) {
400
401 routing_manager_base::unregister_event(_client, _service, _instance,
402 _notifier, _is_provided);
403
404 {
405 std::lock_guard<std::mutex> its_lock(state_mutex_);
406 if (state_ == inner_state_type_e::ST_REGISTERED) {
407 byte_t its_command[VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE];
408 uint32_t its_size = VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE
409 - VSOMEIP_COMMAND_HEADER_SIZE;
410
411 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UNREGISTER_EVENT;
412 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
413 sizeof(client_));
414 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
415 sizeof(its_size));
416 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
417 sizeof(_service));
418 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
419 sizeof(_instance));
420 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_notifier,
421 sizeof(_notifier));
422 its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6]
423 = static_cast<byte_t>(_is_provided);
424
425 {
426 std::lock_guard<std::mutex> its_lock(sender_mutex_);
427 if (sender_) {
428 sender_->send(its_command, sizeof(its_command));
429 }
430 }
431 }
432
433 for (auto iter = pending_event_registrations_.begin();
434 iter != pending_event_registrations_.end(); ) {
435 if (iter->service_ == _service
436 && iter->instance_ == _instance
437 && iter->notifier_ == _notifier
438 && iter->is_provided_ == _is_provided) {
439 pending_event_registrations_.erase(iter);
440 break;
441 } else {
442 iter++;
443 }
444 }
445 }
446 }
447
is_field(service_t _service,instance_t _instance,event_t _event) const448 bool routing_manager_proxy::is_field(service_t _service, instance_t _instance,
449 event_t _event) const {
450 auto event = find_event(_service, _instance, _event);
451 if (event && event->is_field()) {
452 return true;
453 }
454 return false;
455 }
456
subscribe(client_t _client,uid_t _uid,gid_t _gid,service_t _service,instance_t _instance,eventgroup_t _eventgroup,major_version_t _major,event_t _event)457 void routing_manager_proxy::subscribe(client_t _client, uid_t _uid, gid_t _gid, service_t _service,
458 instance_t _instance, eventgroup_t _eventgroup, major_version_t _major,
459 event_t _event) {
460 (void)_uid;
461 (void)_gid;
462 {
463 credentials_t its_credentials = std::make_pair(own_uid_, own_gid_);
464 if (_event == ANY_EVENT) {
465 if (!is_subscribe_to_any_event_allowed(its_credentials, _client, _service, _instance, _eventgroup)) {
466 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << _client
467 << " : routing_manager_proxy::subscribe: "
468 << " isn't allowed to subscribe to service/instance/event "
469 << _service << "/" << _instance << "/ANY_EVENT"
470 << " which violates the security policy ~> Skip subscribe!";
471 return;
472 }
473 } else {
474 auto its_security = security_impl::get();
475 if (!its_security)
476 return;
477 if (!its_security->is_client_allowed(own_uid_, own_gid_,
478 _client, _service, _instance, _event)) {
479 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << _client
480 << " : routing_manager_proxy::subscribe: "
481 << " isn't allowed to subscribe to service/instance/event "
482 << _service << "/" << _instance
483 << "/" << _event;
484 return;
485 }
486 }
487
488 std::lock_guard<std::mutex> its_lock(state_mutex_);
489 if (state_ == inner_state_type_e::ST_REGISTERED && is_available(_service, _instance, _major)) {
490 send_subscribe(client_, _service, _instance, _eventgroup, _major, _event );
491 }
492 subscription_data_t subscription = { _service, _instance, _eventgroup, _major, _event, _uid, _gid};
493 pending_subscriptions_.insert(subscription);
494 }
495 }
496
send_subscribe(client_t _client,service_t _service,instance_t _instance,eventgroup_t _eventgroup,major_version_t _major,event_t _event)497 void routing_manager_proxy::send_subscribe(client_t _client, service_t _service,
498 instance_t _instance, eventgroup_t _eventgroup, major_version_t _major,
499 event_t _event) {
500 (void)_client;
501
502 byte_t its_command[VSOMEIP_SUBSCRIBE_COMMAND_SIZE];
503 uint32_t its_size = VSOMEIP_SUBSCRIBE_COMMAND_SIZE
504 - VSOMEIP_COMMAND_HEADER_SIZE;
505
506 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE;
507 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client,
508 sizeof(_client));
509 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
510 sizeof(its_size));
511 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
512 sizeof(_service));
513 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
514 sizeof(_instance));
515 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup,
516 sizeof(_eventgroup));
517 its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6] = _major;
518 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 7], &_event,
519 sizeof(_event));
520 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 9],
521 &PENDING_SUBSCRIPTION_ID, sizeof(PENDING_SUBSCRIPTION_ID));
522
523 client_t target_client = find_local_client(_service, _instance);
524 if (target_client != VSOMEIP_ROUTING_CLIENT) {
525 auto its_target = ep_mgr_->find_or_create_local(target_client);
526 its_target->send(its_command, sizeof(its_command));
527 } else {
528 std::lock_guard<std::mutex> its_lock(sender_mutex_);
529 if (sender_) {
530 sender_->send(its_command, sizeof(its_command));
531 }
532 }
533 }
534
send_subscribe_nack(client_t _subscriber,service_t _service,instance_t _instance,eventgroup_t _eventgroup,event_t _event,remote_subscription_id_t _id)535 void routing_manager_proxy::send_subscribe_nack(client_t _subscriber,
536 service_t _service, instance_t _instance, eventgroup_t _eventgroup,
537 event_t _event, remote_subscription_id_t _id) {
538 byte_t its_command[VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE];
539 uint32_t its_size = VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE
540 - VSOMEIP_COMMAND_HEADER_SIZE;
541
542 client_t its_client = get_client();
543 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE_NACK;
544 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &its_client,
545 sizeof(its_client));
546 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
547 sizeof(its_size));
548 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
549 sizeof(_service));
550 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
551 sizeof(_instance));
552 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup,
553 sizeof(_eventgroup));
554 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_subscriber,
555 sizeof(_subscriber));
556 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_event,
557 sizeof(_event));
558 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10], &_id,
559 sizeof(_id));
560
561 if (_subscriber != VSOMEIP_ROUTING_CLIENT
562 && _id == PENDING_SUBSCRIPTION_ID) {
563 auto its_target = ep_mgr_->find_local(_subscriber);
564 if (its_target) {
565 its_target->send(its_command, sizeof(its_command));
566 return;
567 }
568 }
569 {
570 std::lock_guard<std::mutex> its_lock(sender_mutex_);
571 if (sender_) {
572 sender_->send(its_command, sizeof(its_command));
573 }
574 }
575 }
576
send_subscribe_ack(client_t _subscriber,service_t _service,instance_t _instance,eventgroup_t _eventgroup,event_t _event,remote_subscription_id_t _id)577 void routing_manager_proxy::send_subscribe_ack(client_t _subscriber,
578 service_t _service, instance_t _instance, eventgroup_t _eventgroup,
579 event_t _event, remote_subscription_id_t _id) {
580 byte_t its_command[VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE];
581 uint32_t its_size = VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE
582 - VSOMEIP_COMMAND_HEADER_SIZE;
583
584 client_t its_client = get_client();
585 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE_ACK;
586 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &its_client,
587 sizeof(its_client));
588 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
589 sizeof(its_size));
590 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
591 sizeof(_service));
592 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
593 sizeof(_instance));
594 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup,
595 sizeof(_eventgroup));
596 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_subscriber,
597 sizeof(_subscriber));
598 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_event,
599 sizeof(_event));
600 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10], &_id,
601 sizeof(_id));
602
603 if (_subscriber != VSOMEIP_ROUTING_CLIENT
604 && _id == PENDING_SUBSCRIPTION_ID) {
605 auto its_target = ep_mgr_->find_local(_subscriber);
606 if (its_target) {
607 its_target->send(its_command, sizeof(its_command));
608 return;
609 }
610 }
611 {
612 std::lock_guard<std::mutex> its_lock(sender_mutex_);
613 if (sender_) {
614 sender_->send(its_command, sizeof(its_command));
615 }
616 }
617 }
618
unsubscribe(client_t _client,uid_t _uid,gid_t _gid,service_t _service,instance_t _instance,eventgroup_t _eventgroup,event_t _event)619 void routing_manager_proxy::unsubscribe(client_t _client, uid_t _uid, gid_t _gid,
620 service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) {
621 (void)_client;
622 (void)_uid;
623 (void)_gid;
624 {
625 std::lock_guard<std::mutex> its_lock(state_mutex_);
626 remove_pending_subscription(_service, _instance, _eventgroup, _event);
627
628 if (state_ == inner_state_type_e::ST_REGISTERED) {
629 byte_t its_command[VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE];
630 uint32_t its_size = VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE
631 - VSOMEIP_COMMAND_HEADER_SIZE;
632
633 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UNSUBSCRIBE;
634 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client,
635 sizeof(_client));
636 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
637 sizeof(its_size));
638 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
639 sizeof(_service));
640 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
641 sizeof(_instance));
642 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup,
643 sizeof(_eventgroup));
644 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_event,
645 sizeof(_event));
646 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8],
647 &PENDING_SUBSCRIPTION_ID, sizeof(PENDING_SUBSCRIPTION_ID));
648
649 auto its_target = ep_mgr_->find_local(_service, _instance);
650 if (its_target) {
651 its_target->send(its_command, sizeof(its_command));
652 } else {
653 std::lock_guard<std::mutex> its_lock(sender_mutex_);
654 if (sender_) {
655 sender_->send(its_command, sizeof(its_command));
656 }
657 }
658 }
659 }
660 }
661
send(client_t _client,const byte_t * _data,length_t _size,instance_t _instance,bool _reliable,client_t _bound_client,credentials_t _credentials,uint8_t _status_check,bool _sent_from_remote)662 bool routing_manager_proxy::send(client_t _client, const byte_t *_data,
663 length_t _size, instance_t _instance,
664 bool _reliable,
665 client_t _bound_client,
666 credentials_t _credentials,
667 uint8_t _status_check,
668 bool _sent_from_remote) {
669 (void)_client;
670 (void)_bound_client;
671 (void)_credentials;
672 (void)_sent_from_remote;
673 bool is_sent(false);
674 bool has_remote_subscribers(false);
675 {
676 std::lock_guard<std::mutex> its_lock(state_mutex_);
677 if (state_ != inner_state_type_e::ST_REGISTERED) {
678 return false;
679 }
680 }
681 if (client_side_logging_) {
682 if (_size > VSOMEIP_MESSAGE_TYPE_POS) {
683 service_t its_service = VSOMEIP_BYTES_TO_WORD(
684 _data[VSOMEIP_SERVICE_POS_MIN],
685 _data[VSOMEIP_SERVICE_POS_MAX]);
686 if (client_side_logging_filter_.empty()
687 || (1 == client_side_logging_filter_.count(std::make_tuple(its_service, ANY_INSTANCE)))
688 || (1 == client_side_logging_filter_.count(std::make_tuple(its_service, _instance)))) {
689 method_t its_method = VSOMEIP_BYTES_TO_WORD(
690 _data[VSOMEIP_METHOD_POS_MIN],
691 _data[VSOMEIP_METHOD_POS_MAX]);
692 session_t its_session = VSOMEIP_BYTES_TO_WORD(
693 _data[VSOMEIP_SESSION_POS_MIN],
694 _data[VSOMEIP_SESSION_POS_MAX]);
695 client_t its_client = VSOMEIP_BYTES_TO_WORD(
696 _data[VSOMEIP_CLIENT_POS_MIN],
697 _data[VSOMEIP_CLIENT_POS_MAX]);
698 VSOMEIP_INFO << "routing_manager_proxy::send: ("
699 << std::hex << std::setw(4) << std::setfill('0') << client_ <<"): ["
700 << std::hex << std::setw(4) << std::setfill('0') << its_service << "."
701 << std::hex << std::setw(4) << std::setfill('0') << _instance << "."
702 << std::hex << std::setw(4) << std::setfill('0') << its_method << ":"
703 << std::hex << std::setw(4) << std::setfill('0') << its_session << ":"
704 << std::hex << std::setw(4) << std::setfill('0') << its_client << "] "
705 << "type=" << std::hex << static_cast<std::uint32_t>(_data[VSOMEIP_MESSAGE_TYPE_POS])
706 << " thread=" << std::hex << std::this_thread::get_id();
707 }
708 } else {
709 VSOMEIP_ERROR << "routing_manager_proxy::send: ("
710 << std::hex << std::setw(4) << std::setfill('0') << client_
711 <<"): message too short to log: " << std::dec << _size;
712 }
713 }
714 if (_size > VSOMEIP_MESSAGE_TYPE_POS) {
715 std::shared_ptr<endpoint> its_target;
716 if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
717 // Request
718 service_t its_service = VSOMEIP_BYTES_TO_WORD(
719 _data[VSOMEIP_SERVICE_POS_MIN],
720 _data[VSOMEIP_SERVICE_POS_MAX]);
721 client_t its_client = find_local_client(its_service, _instance);
722 if (its_client != VSOMEIP_ROUTING_CLIENT) {
723 if (is_client_known(its_client)) {
724 its_target = ep_mgr_->find_or_create_local(its_client);
725 }
726 }
727 } else if (!utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
728 // Response
729 client_t its_client = VSOMEIP_BYTES_TO_WORD(
730 _data[VSOMEIP_CLIENT_POS_MIN],
731 _data[VSOMEIP_CLIENT_POS_MAX]);
732 if (its_client != VSOMEIP_ROUTING_CLIENT) {
733 if (is_client_known(its_client)) {
734 its_target = ep_mgr_->find_or_create_local(its_client);
735 }
736 }
737 } else if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]) &&
738 _client == VSOMEIP_ROUTING_CLIENT) {
739 // notify
740 has_remote_subscribers = send_local_notification(get_client(), _data, _size,
741 _instance, _reliable, _status_check);
742 } else if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]) &&
743 _client != VSOMEIP_ROUTING_CLIENT) {
744 // notify_one
745 its_target = ep_mgr_->find_local(_client);
746 if (its_target) {
747 #ifdef USE_DLT
748 const uint16_t its_data_size
749 = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size);
750
751 trace::header its_header;
752 if (its_header.prepare(nullptr, true, _instance))
753 tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE,
754 _data, its_data_size);
755 #endif
756 return send_local(its_target, get_client(), _data, _size,
757 _instance, _reliable, VSOMEIP_SEND, _status_check);
758 }
759 }
760 // If no direct endpoint could be found
761 // or for notifications ~> route to routing_manager_stub
762 #ifdef USE_DLT
763 bool message_to_stub(false);
764 #endif
765 if (!its_target) {
766 std::lock_guard<std::mutex> its_lock(sender_mutex_);
767 if (sender_) {
768 its_target = sender_;
769 #ifdef USE_DLT
770 message_to_stub = true;
771 #endif
772 } else {
773 return false;
774 }
775 }
776
777 bool send(true);
778 uint8_t command = VSOMEIP_SEND;
779
780 if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
781 if (_client != VSOMEIP_ROUTING_CLIENT) {
782 command = VSOMEIP_NOTIFY_ONE;
783 } else {
784 command = VSOMEIP_NOTIFY;
785 // Do we need to deliver a notification to the routing manager?
786 // Only for services which already have remote clients subscribed to
787 send = has_remote_subscribers;
788 }
789 }
790 #ifdef USE_DLT
791 else if (!message_to_stub) {
792 const uint16_t its_data_size
793 = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size);
794
795 trace::header its_header;
796 if (its_header.prepare(nullptr, true, _instance))
797 tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE,
798 _data, its_data_size);
799 }
800 #endif
801 if (send) {
802 is_sent = send_local(its_target,
803 (command == VSOMEIP_NOTIFY_ONE ? _client : get_client()),
804 _data, _size, _instance, _reliable, command, _status_check);
805 }
806 }
807 return (is_sent);
808 }
809
send_to(const client_t _client,const std::shared_ptr<endpoint_definition> & _target,std::shared_ptr<message> _message)810 bool routing_manager_proxy::send_to(const client_t _client,
811 const std::shared_ptr<endpoint_definition> &_target,
812 std::shared_ptr<message> _message) {
813 (void)_client;
814 (void)_target;
815 (void)_message;
816 return (false);
817 }
818
send_to(const std::shared_ptr<endpoint_definition> & _target,const byte_t * _data,uint32_t _size,instance_t _instance)819 bool routing_manager_proxy::send_to(
820 const std::shared_ptr<endpoint_definition> &_target,
821 const byte_t *_data, uint32_t _size, instance_t _instance) {
822 (void)_target;
823 (void)_data;
824 (void)_size;
825 (void)_instance;
826 return (false);
827 }
828
on_connect(const std::shared_ptr<endpoint> & _endpoint)829 void routing_manager_proxy::on_connect(const std::shared_ptr<endpoint>& _endpoint) {
830 _endpoint->set_connected(true);
831 _endpoint->set_established(true);
832 {
833 std::lock_guard<std::mutex> its_lock(sender_mutex_);
834 if (_endpoint != sender_) {
835 return;
836 }
837 }
838 is_connected_ = true;
839 assign_client();
840 }
841
on_disconnect(const std::shared_ptr<endpoint> & _endpoint)842 void routing_manager_proxy::on_disconnect(const std::shared_ptr<endpoint>& _endpoint) {
843
844 bool is_disconnected((_endpoint == sender_));
845 if (is_disconnected) {
846 {
847 std::lock_guard<std::mutex> its_lock(sender_mutex_);
848 is_connected_ = false;
849 }
850
851 VSOMEIP_INFO << "routing_manager_proxy::on_disconnect: Client 0x" << std::hex
852 << get_client() << " calling host_->on_state "
853 << "with DEREGISTERED";
854 host_->on_state(state_type_e::ST_DEREGISTERED);
855 }
856 }
857
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)858 void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
859 endpoint *_receiver, const boost::asio::ip::address &_destination,
860 client_t _bound_client,
861 credentials_t _credentials,
862 const boost::asio::ip::address &_remote_address,
863 std::uint16_t _remote_port) {
864 (void)_receiver;
865 (void)_destination;
866 (void)_remote_address;
867 (void)_remote_port;
868 #if 0
869 std::stringstream msg;
870 msg << "rmp::on_message: ";
871 for (length_t i = 0; i < _size; ++i)
872 msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
873 VSOMEIP_INFO << msg.str();
874 #endif
875 byte_t its_command;
876 client_t its_client;
877 length_t its_length;
878 service_t its_service;
879 instance_t its_instance;
880 eventgroup_t its_eventgroup;
881 event_t its_event;
882 major_version_t its_major;
883 client_t routing_host_id = configuration_->get_id(configuration_->get_routing_host());
884 client_t its_subscriber;
885 remote_subscription_id_t its_subscription_id(PENDING_SUBSCRIPTION_ID);
886 std::uint32_t its_remote_subscriber_count(0);
887 bool is_internal_policy_update(false);
888
889 std::uint32_t its_sender_uid = std::get<0>(_credentials);
890 std::uint32_t its_sender_gid = std::get<1>(_credentials);
891
892 auto its_security = security_impl::get();
893 if (!its_security)
894 return;
895
896 if (_size > VSOMEIP_COMMAND_SIZE_POS_MAX) {
897 its_command = _data[VSOMEIP_COMMAND_TYPE_POS];
898 std::memcpy(&its_client, &_data[VSOMEIP_COMMAND_CLIENT_POS],
899 sizeof(its_client));
900 std::memcpy(&its_length, &_data[VSOMEIP_COMMAND_SIZE_POS_MIN],
901 sizeof(its_length));
902
903 bool message_from_routing(false);
904 if (its_security->is_enabled()) {
905 // if security is enabled, client ID of routing must be configured
906 // and credential passing is active. Otherwise bound client is zero by default
907 message_from_routing = (_bound_client == routing_host_id);
908 } else {
909 message_from_routing = (its_client == routing_host_id);
910 }
911
912 if (its_security->is_enabled() && !message_from_routing &&
913 _bound_client != its_client) {
914 VSOMEIP_WARNING << std::hex << "Client " << std::setw(4) << std::setfill('0') << get_client()
915 << " received a message with command " << (uint32_t)its_command
916 << " from " << std::setw(4) << std::setfill('0')
917 << its_client << " which doesn't match the bound client "
918 << std::setw(4) << std::setfill('0') << _bound_client
919 << " ~> skip message!";
920 return;
921 }
922
923 switch (its_command) {
924 case VSOMEIP_SEND: {
925 if (_size < VSOMEIP_SEND_COMMAND_SIZE + VSOMEIP_FULL_HEADER_SIZE) {
926 VSOMEIP_WARNING << "Received a SEND command with too small size -> skip!";
927 break;
928 }
929 instance_t its_instance;
930 bool its_reliable;
931 uint8_t its_check_status;
932 std::memcpy(&its_instance,&_data[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN],
933 sizeof(instance_t));
934 std::memcpy(&its_reliable, &_data[VSOMEIP_SEND_COMMAND_RELIABLE_POS],
935 sizeof(its_reliable));
936 std::memcpy(&its_check_status, &_data[VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS],
937 sizeof(its_check_status));
938
939 // reduce by size of instance, flush, reliable, client and is_valid_crc flag
940 const std::uint32_t its_message_size = its_length -
941 (VSOMEIP_SEND_COMMAND_SIZE - VSOMEIP_COMMAND_HEADER_SIZE);
942
943 if (its_message_size !=
944 VSOMEIP_BYTES_TO_LONG(_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN],
945 _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 1],
946 _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 2],
947 _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 3])
948 + VSOMEIP_SOMEIP_HEADER_SIZE) {
949 VSOMEIP_WARNING << "Received a SEND command containing message with invalid size -> skip!";
950 break;
951 }
952
953 auto a_deserializer = get_deserializer();
954 a_deserializer->set_data(&_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS],
955 its_message_size);
956 std::shared_ptr<message_impl> its_message(a_deserializer->deserialize_message());
957 a_deserializer->reset();
958 put_deserializer(a_deserializer);
959
960 if (its_message) {
961 its_message->set_instance(its_instance);
962 its_message->set_reliable(its_reliable);
963 its_message->set_check_result(its_check_status);
964 its_message->set_uid(std::get<0>(_credentials));
965 its_message->set_gid(std::get<1>(_credentials));
966
967 if (!message_from_routing) {
968 if (utility::is_notification(its_message->get_message_type())) {
969 if (!is_response_allowed(_bound_client, its_message->get_service(),
970 its_message->get_instance(), its_message->get_method())) {
971 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
972 << " : routing_manager_proxy::on_message: "
973 << " received a notification from client 0x" << _bound_client
974 << " which does not offer service/instance/event "
975 << its_message->get_service() << "/" << its_message->get_instance()
976 << "/" << its_message->get_method()
977 << " ~> Skip message!";
978 return;
979 } else {
980 if (!its_security->is_client_allowed(own_uid_, own_gid_,
981 get_client(), its_message->get_service(),
982 its_message->get_instance(), its_message->get_method())) {
983 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
984 << " : routing_manager_proxy::on_message: "
985 << " isn't allowed to receive a notification from service/instance/event "
986 << its_message->get_service() << "/" << its_message->get_instance()
987 << "/" << its_message->get_method()
988 << " respectively from client 0x" << _bound_client
989 << " ~> Skip message!";
990 return;
991 }
992 cache_event_payload(its_message);
993 }
994 } else if (utility::is_request(its_message->get_message_type())) {
995 if (its_security->is_enabled()
996 && its_message->get_client() != _bound_client) {
997 VSOMEIP_WARNING << std::hex << "vSomeIP Security: Client 0x" << std::setw(4) << std::setfill('0') << get_client()
998 << " received a request from client 0x" << std::setw(4) << std::setfill('0')
999 << its_message->get_client() << " to service/instance/method "
1000 << its_message->get_service() << "/" << its_message->get_instance()
1001 << "/" << its_message->get_method() << " which doesn't match the bound client 0x"
1002 << std::setw(4) << std::setfill('0') << _bound_client
1003 << " ~> skip message!";
1004 return;
1005 }
1006
1007 if (!its_security->is_client_allowed(its_sender_uid, its_sender_gid,
1008 its_message->get_client(), its_message->get_service(),
1009 its_message->get_instance(), its_message->get_method())) {
1010 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_message->get_client()
1011 << " : routing_manager_proxy::on_message: "
1012 << "isn't allowed to send a request to service/instance/method "
1013 << its_message->get_service() << "/" << its_message->get_instance()
1014 << "/" << its_message->get_method()
1015 << " ~> Skip message!";
1016 return;
1017 }
1018 } else { // response
1019 if (!is_response_allowed(_bound_client, its_message->get_service(),
1020 its_message->get_instance(), its_message->get_method())) {
1021 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
1022 << " : routing_manager_proxy::on_message: "
1023 << " received a response from client 0x" << _bound_client
1024 << " which does not offer service/instance/method "
1025 << its_message->get_service() << "/" << its_message->get_instance()
1026 << "/" << its_message->get_method()
1027 << " ~> Skip message!";
1028 return;
1029 } else {
1030 if (!its_security->is_client_allowed(own_uid_, own_gid_,
1031 get_client(), its_message->get_service(),
1032 its_message->get_instance(), its_message->get_method())) {
1033 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
1034 << " : routing_manager_proxy::on_message: "
1035 << " isn't allowed to receive a response from service/instance/method "
1036 << its_message->get_service() << "/" << its_message->get_instance()
1037 << "/" << its_message->get_method()
1038 << " respectively from client 0x" << _bound_client
1039 << " ~> Skip message!";
1040 return;
1041 }
1042 }
1043 }
1044 } else {
1045 if (!its_security->is_remote_client_allowed()) {
1046 // if the message is from routing manager, check if
1047 // policy allows remote requests.
1048 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
1049 << " : routing_manager_proxy::on_message: "
1050 << std::hex << "Security: Remote clients via routing manager with client ID 0x" << its_client
1051 << " are not allowed to communicate with service/instance/method "
1052 << its_message->get_service() << "/" << its_message->get_instance()
1053 << "/" << its_message->get_method()
1054 << " respectively with client 0x" << get_client()
1055 << " ~> Skip message!";
1056 return;
1057 } else if (utility::is_notification(its_message->get_message_type())) {
1058 // As subscription is sent on eventgroup level, incoming remote event ID's
1059 // need to be checked as well if remote clients are allowed
1060 // and the local policy only allows specific events in the eventgroup to be received.
1061 if (!its_security->is_client_allowed(own_uid_, own_gid_,
1062 get_client(), its_message->get_service(),
1063 its_message->get_instance(), its_message->get_method())) {
1064 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
1065 << " : routing_manager_proxy::on_message: "
1066 << " isn't allowed to receive a notification from service/instance/event "
1067 << its_message->get_service() << "/" << its_message->get_instance()
1068 << "/" << its_message->get_method()
1069 << " respectively from remote clients via routing manager with client ID 0x"
1070 << routing_host_id
1071 << " ~> Skip message!";
1072 return;
1073 }
1074 cache_event_payload(its_message);
1075 }
1076 }
1077 #ifdef USE_DLT
1078 if (client_side_logging_
1079 && (client_side_logging_filter_.empty()
1080 || (1 == client_side_logging_filter_.count(std::make_tuple(its_message->get_service(), ANY_INSTANCE)))
1081 || (1 == client_side_logging_filter_.count(std::make_tuple(its_message->get_service(), its_message->get_instance()))))) {
1082 trace::header its_header;
1083 if (its_header.prepare(nullptr, false, its_instance))
1084 tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE,
1085 &_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS],
1086 static_cast<std::uint16_t>(its_message_size));
1087 }
1088 #endif
1089
1090 host_->on_message(std::move(its_message));
1091 } else {
1092 VSOMEIP_ERROR << "Routing proxy: on_message: "
1093 << "SomeIP-Header deserialization failed!";
1094 }
1095 break;
1096 }
1097
1098 case VSOMEIP_ASSIGN_CLIENT_ACK: {
1099 if (_size != VSOMEIP_ASSIGN_CLIENT_ACK_COMMAND_SIZE) {
1100 VSOMEIP_WARNING << "Received a VSOMEIP_ASSIGN_CLIENT_ACK command with wrong size ~> skip!";
1101 break;
1102 }
1103 client_t its_assigned_client(VSOMEIP_CLIENT_UNSET);
1104 std::memcpy(&its_assigned_client,
1105 &_data[VSOMEIP_COMMAND_PAYLOAD_POS], sizeof(client_));
1106 on_client_assign_ack(its_assigned_client);
1107 break;
1108 }
1109 case VSOMEIP_ROUTING_INFO:
1110 if (_size - VSOMEIP_COMMAND_HEADER_SIZE != its_length) {
1111 VSOMEIP_WARNING << "Received a ROUTING_INFO command with invalid size -> skip!";
1112 break;
1113 }
1114 if (!its_security->is_enabled() || message_from_routing) {
1115 on_routing_info(&_data[VSOMEIP_COMMAND_PAYLOAD_POS], its_length);
1116 } else {
1117 VSOMEIP_WARNING << "routing_manager_proxy::on_message: "
1118 << std::hex << "Security: Client 0x" << get_client()
1119 << " received an routing info from a client which isn't the routing manager"
1120 << " : Skip message!";
1121 }
1122 break;
1123
1124 case VSOMEIP_PING:
1125 if (_size != VSOMEIP_PING_COMMAND_SIZE) {
1126 VSOMEIP_WARNING << "Received a PING command with wrong size ~> skip!";
1127 break;
1128 }
1129 send_pong();
1130 VSOMEIP_TRACE << "PING("
1131 << std::hex << std::setw(4) << std::setfill('0') << client_ << ")";
1132 break;
1133
1134 case VSOMEIP_SUBSCRIBE:
1135 if (_size != VSOMEIP_SUBSCRIBE_COMMAND_SIZE) {
1136 VSOMEIP_WARNING << "Received a SUBSCRIBE command with wrong size ~> skip!";
1137 break;
1138 }
1139 std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
1140 sizeof(its_service));
1141 std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
1142 sizeof(its_instance));
1143 std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
1144 sizeof(its_eventgroup));
1145 std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
1146 sizeof(its_major));
1147 std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7],
1148 sizeof(its_event));
1149 std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 9],
1150 sizeof(its_subscription_id));
1151 {
1152 std::unique_lock<std::recursive_mutex> its_lock(incoming_subscriptions_mutex_);
1153 if (its_subscription_id != PENDING_SUBSCRIPTION_ID) {
1154 its_lock.unlock();
1155 #ifdef VSOMEIP_ENABLE_COMPAT
1156 routing_manager_base::set_incoming_subscription_state(its_client, its_service,
1157 its_instance, its_eventgroup, its_event, subscription_state_e::IS_SUBSCRIBING);
1158 #endif
1159 // Remote subscriber: Notify routing manager initially + count subscribes
1160 auto self = shared_from_this();
1161 host_->on_subscription(its_service, its_instance, its_eventgroup,
1162 its_client, its_sender_uid, its_sender_gid, true,
1163 [this, self, its_client, its_service, its_instance,
1164 its_eventgroup, its_event, its_subscription_id, its_major]
1165 (const bool _subscription_accepted){
1166 std::uint32_t its_count = 0;
1167 if(_subscription_accepted) {
1168 send_subscribe_ack(its_client, its_service, its_instance,
1169 its_eventgroup, its_event, its_subscription_id);
1170 std::set<event_t> its_already_subscribed_events;
1171 bool inserted = insert_subscription(its_service, its_instance, its_eventgroup,
1172 its_event, VSOMEIP_ROUTING_CLIENT, &its_already_subscribed_events);
1173 if (inserted) {
1174 notify_remote_initially(its_service, its_instance, its_eventgroup,
1175 its_already_subscribed_events);
1176 }
1177 #ifdef VSOMEIP_ENABLE_COMPAT
1178 send_pending_notify_ones(its_service, its_instance, its_eventgroup, its_client, true);
1179 #endif
1180 its_count = get_remote_subscriber_count(its_service, its_instance, its_eventgroup, true);
1181 } else {
1182 send_subscribe_nack(its_client, its_service, its_instance,
1183 its_eventgroup, its_event, its_subscription_id);
1184 }
1185 VSOMEIP_INFO << "SUBSCRIBE("
1186 << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): ["
1187 << std::hex << std::setw(4) << std::setfill('0') << its_service << "."
1188 << std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
1189 << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << ":"
1190 << std::hex << std::setw(4) << std::setfill('0') << its_event << ":"
1191 << std::dec << (uint16_t)its_major << "] "
1192 << (bool)(its_subscription_id != PENDING_SUBSCRIPTION_ID) << " "
1193 << (_subscription_accepted ? std::to_string(its_count) : "-")
1194 << (_subscription_accepted ? " ACCEPTED" : " NOT ACCEPTED");
1195 #ifdef VSOMEIP_ENABLE_COMPAT
1196 routing_manager_base::erase_incoming_subscription_state(its_client, its_service,
1197 its_instance, its_eventgroup, its_event);
1198 #endif
1199 });
1200 } else if (is_client_known(its_client)) {
1201 its_lock.unlock();
1202 if (!message_from_routing) {
1203 if (its_event == ANY_EVENT) {
1204 if (!is_subscribe_to_any_event_allowed(_credentials, its_client, its_service, its_instance, its_eventgroup)) {
1205 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client
1206 << " : routing_manager_proxy::on_message: "
1207 << " isn't allowed to subscribe to service/instance/event "
1208 << its_service << "/" << its_instance << "/ANY_EVENT"
1209 << " which violates the security policy ~> Skip subscribe!";
1210 return;
1211 }
1212 } else {
1213 if (!its_security->is_client_allowed(its_sender_uid, its_sender_gid,
1214 its_client, its_service, its_instance, its_event)) {
1215 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client
1216 << " : routing_manager_proxy::on_message: "
1217 << " subscribes to service/instance/event "
1218 << its_service << "/" << its_instance << "/" << its_event
1219 << " which violates the security policy ~> Skip subscribe!";
1220 return;
1221 }
1222 }
1223 } else {
1224 if (!its_security->is_remote_client_allowed()) {
1225 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client
1226 << " : routing_manager_proxy::on_message: "
1227 << std::hex << "Routing manager with client ID 0x"
1228 << its_client
1229 << " isn't allowed to subscribe to service/instance/event "
1230 << its_service << "/" << its_instance
1231 << "/" << its_event
1232 << " respectively to client 0x" << get_client()
1233 << " ~> Skip Subscribe!";
1234 return;
1235 }
1236 }
1237
1238 // Local & already known subscriber: create endpoint + send (N)ACK + insert subscription
1239 #ifdef VSOMEIP_ENABLE_COMPAT
1240 routing_manager_base::set_incoming_subscription_state(its_client, its_service,
1241 its_instance, its_eventgroup, its_event, subscription_state_e::IS_SUBSCRIBING);
1242 #endif
1243 (void) ep_mgr_->find_or_create_local(its_client);
1244 auto self = shared_from_this();
1245 host_->on_subscription(its_service, its_instance,
1246 its_eventgroup, its_client, its_sender_uid, its_sender_gid, true,
1247 [this, self, its_client, its_sender_uid, its_sender_gid, its_service,
1248 its_instance, its_eventgroup, its_event, its_major]
1249 (const bool _subscription_accepted) {
1250 if (!_subscription_accepted) {
1251 send_subscribe_nack(its_client, its_service, its_instance,
1252 its_eventgroup, its_event, PENDING_SUBSCRIPTION_ID);
1253 } else {
1254 send_subscribe_ack(its_client, its_service, its_instance,
1255 its_eventgroup, its_event, PENDING_SUBSCRIPTION_ID);
1256 routing_manager_base::subscribe(its_client, its_sender_uid, its_sender_gid,
1257 its_service, its_instance, its_eventgroup, its_major, its_event);
1258 #ifdef VSOMEIP_ENABLE_COMPAT
1259 send_pending_notify_ones(its_service, its_instance, its_eventgroup, its_client);
1260 #endif
1261 }
1262 #ifdef VSOMEIP_ENABLE_COMPAT
1263 routing_manager_base::erase_incoming_subscription_state(its_client, its_service,
1264 its_instance, its_eventgroup, its_event);
1265 #endif
1266 });
1267 } else {
1268 // Local & not yet known subscriber ~> set pending until subscriber gets known!
1269 subscription_data_t subscription = { its_service, its_instance,
1270 its_eventgroup, its_major, its_event, its_sender_uid, its_sender_gid };
1271 pending_incoming_subscripitons_[its_client].insert(subscription);
1272 }
1273 }
1274 if (its_subscription_id == PENDING_SUBSCRIPTION_ID) { // local subscription
1275 VSOMEIP_INFO << "SUBSCRIBE("
1276 << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): ["
1277 << std::hex << std::setw(4) << std::setfill('0') << its_service << "."
1278 << std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
1279 << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << ":"
1280 << std::hex << std::setw(4) << std::setfill('0') << its_event << ":"
1281 << std::dec << (uint16_t)its_major << "]";
1282 }
1283 break;
1284
1285 case VSOMEIP_UNSUBSCRIBE:
1286 if (_size != VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE) {
1287 VSOMEIP_WARNING << "Received an UNSUBSCRIBE command with wrong size ~> skip!";
1288 break;
1289 }
1290 std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
1291 sizeof(its_service));
1292 std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
1293 sizeof(its_instance));
1294 std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
1295 sizeof(its_eventgroup));
1296 std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
1297 sizeof(its_event));
1298 std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8],
1299 sizeof(its_subscription_id));
1300 host_->on_subscription(its_service, its_instance, its_eventgroup, its_client, its_sender_uid, its_sender_gid, false, [](const bool _subscription_accepted){ (void)_subscription_accepted; });
1301 if (its_subscription_id == PENDING_SUBSCRIPTION_ID) {
1302 // Local subscriber: withdraw subscription
1303 routing_manager_base::unsubscribe(its_client, its_sender_uid, its_sender_gid, its_service, its_instance, its_eventgroup, its_event);
1304 } else {
1305 // Remote subscriber: withdraw subscription only if no more remote subscriber exists
1306 its_remote_subscriber_count = get_remote_subscriber_count(its_service,
1307 its_instance, its_eventgroup, false);
1308 if (!its_remote_subscriber_count) {
1309 routing_manager_base::unsubscribe(VSOMEIP_ROUTING_CLIENT, ANY_UID, ANY_GID, its_service,
1310 its_instance, its_eventgroup, its_event);
1311 }
1312 send_unsubscribe_ack(its_service, its_instance, its_eventgroup,
1313 its_subscription_id);
1314 }
1315 VSOMEIP_INFO << "UNSUBSCRIBE("
1316 << std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
1317 << std::hex << std::setw(4) << std::setfill('0') << its_service << "."
1318 << std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
1319 << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "."
1320 << std::hex << std::setw(4) << std::setfill('0') << its_event << "] "
1321 << (bool)(its_subscription_id != PENDING_SUBSCRIPTION_ID) << " "
1322 << std::dec << its_remote_subscriber_count;
1323 break;
1324
1325 case VSOMEIP_EXPIRED_SUBSCRIPTION:
1326 if (_size != VSOMEIP_EXPIRED_SUBSCRIPTION_COMMAND_SIZE) {
1327 VSOMEIP_WARNING << "Received an VSOMEIP_EXPIRED_SUBSCRIPTION command with wrong size ~> skip!";
1328 break;
1329 }
1330 std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
1331 sizeof(its_service));
1332 std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
1333 sizeof(its_instance));
1334 std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
1335 sizeof(its_eventgroup));
1336 std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
1337 sizeof(its_event));
1338 std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8],
1339 sizeof(its_subscription_id));
1340 host_->on_subscription(its_service, its_instance, its_eventgroup, its_client, its_sender_uid, its_sender_gid, false, [](const bool _subscription_accepted){ (void)_subscription_accepted; });
1341 if (its_subscription_id == PENDING_SUBSCRIPTION_ID) {
1342 // Local subscriber: withdraw subscription
1343 routing_manager_base::unsubscribe(its_client, its_sender_uid, its_sender_gid, its_service, its_instance, its_eventgroup, its_event);
1344 } else {
1345 // Remote subscriber: withdraw subscription only if no more remote subscriber exists
1346 its_remote_subscriber_count = get_remote_subscriber_count(its_service,
1347 its_instance, its_eventgroup, false);
1348 if (!its_remote_subscriber_count) {
1349 routing_manager_base::unsubscribe(VSOMEIP_ROUTING_CLIENT, ANY_UID, ANY_GID, its_service,
1350 its_instance, its_eventgroup, its_event);
1351 }
1352 }
1353 VSOMEIP_INFO << "UNSUBSCRIBE EXPIRED SUBSCRIPTION("
1354 << std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
1355 << std::hex << std::setw(4) << std::setfill('0') << its_service << "."
1356 << std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
1357 << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "."
1358 << std::hex << std::setw(4) << std::setfill('0') << its_event << "] "
1359 << (bool)(its_subscription_id != PENDING_SUBSCRIPTION_ID) << " "
1360 << std::dec << its_remote_subscriber_count;
1361 break;
1362
1363 case VSOMEIP_SUBSCRIBE_NACK:
1364 if (_size != VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE) {
1365 VSOMEIP_WARNING << "Received a VSOMEIP_SUBSCRIBE_NACK command with wrong size ~> skip!";
1366 break;
1367 }
1368 std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
1369 sizeof(its_service));
1370 std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
1371 sizeof(its_instance));
1372 std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
1373 sizeof(its_eventgroup));
1374 std::memcpy(&its_subscriber, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
1375 sizeof(its_subscriber));
1376 std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8],
1377 sizeof(its_event));
1378
1379 on_subscribe_nack(its_subscriber, its_service, its_instance, its_eventgroup, its_event);
1380 VSOMEIP_INFO << "SUBSCRIBE NACK("
1381 << std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
1382 << std::hex << std::setw(4) << std::setfill('0') << its_service << "."
1383 << std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
1384 << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "."
1385 << std::hex << std::setw(4) << std::setfill('0') << its_event << "]";
1386 break;
1387
1388 case VSOMEIP_SUBSCRIBE_ACK:
1389 if (_size != VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE) {
1390 VSOMEIP_WARNING << "Received a VSOMEIP_SUBSCRIBE_ACK command with wrong size ~> skip!";
1391 break;
1392 }
1393 std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
1394 sizeof(its_service));
1395 std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
1396 sizeof(its_instance));
1397 std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
1398 sizeof(its_eventgroup));
1399 std::memcpy(&its_subscriber, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
1400 sizeof(its_subscriber));
1401 std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8],
1402 sizeof(its_event));
1403
1404 on_subscribe_ack(its_subscriber, its_service, its_instance, its_eventgroup, its_event);
1405 VSOMEIP_INFO << "SUBSCRIBE ACK("
1406 << std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
1407 << std::hex << std::setw(4) << std::setfill('0') << its_service << "."
1408 << std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
1409 << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "."
1410 << std::hex << std::setw(4) << std::setfill('0') << its_event << "]";
1411 break;
1412
1413 case VSOMEIP_OFFERED_SERVICES_RESPONSE:
1414 if (_size - VSOMEIP_COMMAND_HEADER_SIZE != its_length) {
1415 VSOMEIP_WARNING << "Received a VSOMEIP_OFFERED_SERVICES_RESPONSE command with invalid size -> skip!";
1416 break;
1417 }
1418 if (!its_security->is_enabled() || message_from_routing) {
1419 on_offered_services_info(&_data[VSOMEIP_COMMAND_PAYLOAD_POS], its_length);
1420 } else {
1421 VSOMEIP_WARNING << std::hex << "Security: Client 0x" << get_client()
1422 << " received an offered services info from a client which isn't the routing manager"
1423 << " : Skip message!";
1424 }
1425 break;
1426 case VSOMEIP_RESEND_PROVIDED_EVENTS: {
1427 if (_size != VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE) {
1428 VSOMEIP_WARNING << "Received a RESEND_PROVIDED_EVENTS command with wrong size ~> skip!";
1429 break;
1430 }
1431 pending_remote_offer_id_t its_pending_remote_offer_id(0);
1432 std::memcpy(&its_pending_remote_offer_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
1433 sizeof(pending_remote_offer_id_t));
1434 resend_provided_event_registrations();
1435 send_resend_provided_event_response(its_pending_remote_offer_id);
1436 VSOMEIP_INFO << "RESEND_PROVIDED_EVENTS("
1437 << std::hex << std::setw(4) << std::setfill('0')
1438 << its_client << ")";
1439 break;
1440 }
1441 case VSOMEIP_UPDATE_SECURITY_POLICY_INT:
1442 is_internal_policy_update = true;
1443 /* Fallthrough */
1444 case VSOMEIP_UPDATE_SECURITY_POLICY: {
1445 if (_size < VSOMEIP_COMMAND_HEADER_SIZE + sizeof(pending_security_update_id_t) ||
1446 _size - VSOMEIP_COMMAND_HEADER_SIZE != its_length) {
1447 VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_UPDATE_SECURITY_POLICY command with wrong size -> skip!";
1448 break;
1449 }
1450 if (!its_security->is_enabled() || message_from_routing) {
1451 pending_security_update_id_t its_update_id(0);
1452
1453 std::memcpy(&its_update_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
1454 sizeof(pending_security_update_id_t));
1455
1456 std::shared_ptr<policy> its_policy(std::make_shared<policy>());
1457 const byte_t *its_policy_data = _data + (VSOMEIP_COMMAND_PAYLOAD_POS +
1458 sizeof(pending_security_update_id_t));
1459
1460 uint32_t its_policy_size = uint32_t(_size - (VSOMEIP_COMMAND_PAYLOAD_POS
1461 + sizeof(pending_security_update_id_t)));
1462
1463 bool is_valid = its_policy->deserialize(its_policy_data, its_policy_size);
1464 if (is_valid) {
1465 uint32_t its_uid;
1466 uint32_t its_gid;
1467 is_valid = its_policy->get_uid_gid(its_uid, its_gid);
1468 if (is_valid) {
1469 if (is_internal_policy_update
1470 || its_security->is_policy_update_allowed(its_uid, its_policy)) {
1471 its_security->update_security_policy(its_uid, its_gid, its_policy);
1472 send_update_security_policy_response(its_update_id);
1473 }
1474 } else {
1475 VSOMEIP_ERROR << "vSomeIP Security: Policy has no valid uid/gid!";
1476 }
1477 } else {
1478 VSOMEIP_ERROR << "vSomeIP Security: Policy deserialization failed!";
1479 }
1480 } else {
1481 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
1482 << " : routing_manager_proxy::on_message: "
1483 << " received a security policy update from a client which isn't the routing manager"
1484 << " : Skip message!";
1485 }
1486 break;
1487 }
1488 case VSOMEIP_REMOVE_SECURITY_POLICY: {
1489 if (_size != VSOMEIP_REMOVE_SECURITY_POLICY_COMMAND_SIZE) {
1490 VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_REMOVE_SECURITY_POLICY command with wrong size ~> skip!";
1491 break;
1492 }
1493 if (!its_security->is_enabled() || message_from_routing) {
1494 pending_security_update_id_t its_update_id(0);
1495 uint32_t its_uid(ANY_UID);
1496 uint32_t its_gid(ANY_GID);
1497
1498 std::memcpy(&its_update_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
1499 sizeof(pending_security_update_id_t));
1500 std::memcpy(&its_uid, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
1501 sizeof(uint32_t));
1502 std::memcpy(&its_gid, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8],
1503 sizeof(uint32_t));
1504 if (its_security->is_policy_removal_allowed(its_uid)) {
1505 its_security->remove_security_policy(its_uid, its_gid);
1506 send_remove_security_policy_response(its_update_id);
1507 }
1508 } else {
1509 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
1510 << " : routing_manager_proxy::on_message: "
1511 << "received a security policy removal from a client which isn't the routing manager"
1512 << " : Skip message!";
1513 }
1514 break;
1515 }
1516 case VSOMEIP_DISTRIBUTE_SECURITY_POLICIES: {
1517 if (_size < VSOMEIP_COMMAND_HEADER_SIZE ||
1518 _size - VSOMEIP_COMMAND_HEADER_SIZE != its_length) {
1519 VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_DISTRIBUTE_SECURITY_POLICIES command with wrong size -> skip!";
1520 break;
1521 }
1522 if (!its_security->is_enabled() || message_from_routing) {
1523 uint32_t its_policy_count(0);
1524 uint32_t its_policy_size(0);
1525 const byte_t* buffer_ptr = 0;
1526
1527 if (VSOMEIP_COMMAND_PAYLOAD_POS + sizeof(uint32_t) * 2 <= _size) {
1528 std::memcpy(&its_policy_count, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
1529 sizeof(uint32_t));
1530
1531 // skip policy count field
1532 buffer_ptr = _data + (VSOMEIP_COMMAND_PAYLOAD_POS +
1533 sizeof(uint32_t));
1534
1535 for (uint32_t i = 0; i < its_policy_count; i++) {
1536 uint32_t its_uid(0);
1537 uint32_t its_gid(0);
1538 std::shared_ptr<policy> its_policy(std::make_shared<policy>());
1539 // length field of next (UID/GID + policy)
1540 if (buffer_ptr + sizeof(uint32_t) <= _data + _size) {
1541 std::memcpy(&its_policy_size, buffer_ptr,
1542 sizeof(uint32_t));
1543 buffer_ptr += sizeof(uint32_t);
1544
1545 if (buffer_ptr + its_policy_size <= _data + _size) {
1546 if (its_security->parse_policy(buffer_ptr, its_policy_size, its_uid, its_gid, its_policy)) {
1547 if (its_security->is_policy_update_allowed(its_uid, its_policy)) {
1548 its_security->update_security_policy(its_uid, its_gid, its_policy);
1549 }
1550 } else {
1551 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() << " could not parse policy!";
1552 }
1553 }
1554 }
1555 }
1556 }
1557 } else {
1558 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
1559 << " : routing_manager_proxy::on_message: "
1560 << " received a security policy distribution command from a client which isn't the routing manager"
1561 << " : Skip message!";
1562 }
1563 break;
1564 }
1565 case VSOMEIP_UPDATE_SECURITY_CREDENTIALS: {
1566 if (_size < VSOMEIP_COMMAND_HEADER_SIZE ||
1567 _size - VSOMEIP_COMMAND_HEADER_SIZE != its_length) {
1568 VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_UPDATE_SECURITY_CREDENTIALS command with wrong size -> skip!";
1569 break;
1570 }
1571 if (!its_security->is_enabled() || message_from_routing) {
1572 on_update_security_credentials(&_data[VSOMEIP_COMMAND_PAYLOAD_POS], its_length);
1573 } else {
1574 VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
1575 << " : routing_manager_proxy::on_message: "
1576 << "received a security credential update from a client which isn't the routing manager"
1577 << " : Skip message!";
1578 }
1579 break;
1580 }
1581
1582 case VSOMEIP_SUSPEND:
1583 on_suspend(); // cleanup remote subscribers
1584 break;
1585
1586 default:
1587 break;
1588 }
1589 }
1590 }
1591
on_routing_info(const byte_t * _data,uint32_t _size)1592 void routing_manager_proxy::on_routing_info(const byte_t *_data,
1593 uint32_t _size) {
1594 #if 0
1595 std::stringstream msg;
1596 msg << "rmp::on_routing_info(" << std::hex << client_ << "): ";
1597 for (uint32_t i = 0; i < _size; ++i)
1598 msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
1599 VSOMEIP_INFO << msg.str();
1600 #endif
1601 auto its_security = security_impl::get();
1602 if (!its_security)
1603 return;
1604
1605 uint32_t i = 0;
1606 while (i + sizeof(uint32_t) + sizeof(routing_info_entry_e) <= _size) {
1607 routing_info_entry_e routing_info_entry;
1608 std::memcpy(&routing_info_entry, &_data[i], sizeof(routing_info_entry_e));
1609 i += uint32_t(sizeof(routing_info_entry_e));
1610
1611 uint32_t its_client_size;
1612 std::memcpy(&its_client_size, &_data[i], sizeof(uint32_t));
1613 i += uint32_t(sizeof(uint32_t));
1614
1615 if (its_client_size + i > _size) {
1616 VSOMEIP_WARNING << "Client 0x" << std::hex << get_client() << " : "
1617 << "Processing of routing info failed due to bad length fields!";
1618 return;
1619 }
1620
1621 if (i + sizeof(client_t) <= _size) {
1622 client_t its_client;
1623 std::memcpy(&its_client, &_data[i], sizeof(client_t));
1624 i += uint32_t(sizeof(client_t));
1625
1626 if (routing_info_entry == routing_info_entry_e::RIE_ADD_CLIENT) {
1627 {
1628 std::lock_guard<std::mutex> its_lock(known_clients_mutex_);
1629 known_clients_.insert(its_client);
1630 }
1631 if (its_client == get_client()) {
1632 VSOMEIP_INFO << std::hex << "Application/Client " << get_client()
1633 << " (" << host_->get_name() << ") is registered.";
1634
1635 #ifndef _WIN32
1636 if (!its_security->check_credentials(get_client(), own_uid_, own_gid_)) {
1637 VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client()
1638 << " : routing_manager_proxy::on_routing_info: RIE_ADD_CLIENT: isn't allowed"
1639 << " to use the server endpoint due to credential check failed!";
1640 deregister_application();
1641 host_->on_state(static_cast<state_type_e>(inner_state_type_e::ST_DEREGISTERED));
1642 return;
1643 }
1644 #endif
1645 {
1646 std::lock_guard<std::mutex> its_lock(state_mutex_);
1647 if (state_ == inner_state_type_e::ST_REGISTERING) {
1648 boost::system::error_code ec;
1649 register_application_timer_.cancel(ec);
1650 send_registered_ack();
1651 send_pending_commands();
1652 state_ = inner_state_type_e::ST_REGISTERED;
1653 // Notify stop() call about clean deregistration
1654 state_condition_.notify_one();
1655 }
1656 }
1657
1658 // inform host about its own registration state changes
1659 if (state_ == inner_state_type_e::ST_REGISTERED)
1660 host_->on_state(static_cast<state_type_e>(inner_state_type_e::ST_REGISTERED));
1661
1662 }
1663 } else if (routing_info_entry == routing_info_entry_e::RIE_DEL_CLIENT) {
1664 {
1665 std::lock_guard<std::mutex> its_lock(known_clients_mutex_);
1666 known_clients_.erase(its_client);
1667 }
1668 if (its_client == get_client()) {
1669 its_security->remove_client_to_uid_gid_mapping(its_client);
1670 VSOMEIP_INFO << std::hex << "Application/Client " << get_client()
1671 << " (" << host_->get_name() << ") is deregistered.";
1672
1673 // inform host about its own registration state changes
1674 host_->on_state(static_cast<state_type_e>(inner_state_type_e::ST_DEREGISTERED));
1675
1676 {
1677 std::lock_guard<std::mutex> its_lock(state_mutex_);
1678 state_ = inner_state_type_e::ST_DEREGISTERED;
1679 // Notify stop() call about clean deregistration
1680 state_condition_.notify_one();
1681 }
1682 } else if (its_client != VSOMEIP_ROUTING_CLIENT) {
1683 remove_local(its_client, true);
1684 }
1685 }
1686
1687 uint32_t j = 0;
1688 while (j + sizeof(uint32_t) <= its_client_size) {
1689 uint32_t its_services_size;
1690 std::memcpy(&its_services_size, &_data[i + j], sizeof(uint32_t));
1691 j += uint32_t(sizeof(uint32_t));
1692
1693 if (its_services_size >= sizeof(service_t) + sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t)) {
1694 its_services_size -= uint32_t(sizeof(service_t));
1695
1696 service_t its_service;
1697 std::memcpy(&its_service, &_data[i + j], sizeof(service_t));
1698 j += uint32_t(sizeof(service_t));
1699
1700 while (its_services_size >= sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t)) {
1701 instance_t its_instance;
1702 std::memcpy(&its_instance, &_data[i + j], sizeof(instance_t));
1703 j += uint32_t(sizeof(instance_t));
1704
1705 major_version_t its_major;
1706 std::memcpy(&its_major, &_data[i + j], sizeof(major_version_t));
1707 j += uint32_t(sizeof(major_version_t));
1708
1709 minor_version_t its_minor;
1710 std::memcpy(&its_minor, &_data[i + j], sizeof(minor_version_t));
1711 j += uint32_t(sizeof(minor_version_t));
1712
1713 if (routing_info_entry == routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE) {
1714 if (get_routing_state() == routing_state_e::RS_SUSPENDED) {
1715 VSOMEIP_INFO << "rmp::" <<__func__ << " We are in suspended mode, the service will not be added!";
1716 return;
1717 }
1718 {
1719 std::lock_guard<std::mutex> its_lock(known_clients_mutex_);
1720 known_clients_.insert(its_client);
1721 }
1722 {
1723 std::lock_guard<std::mutex> its_lock(local_services_mutex_);
1724 local_services_[its_service][its_instance] = std::make_tuple(its_major, its_minor, its_client);
1725 }
1726 {
1727 std::lock_guard<std::mutex> its_lock(state_mutex_);
1728 send_pending_subscriptions(its_service, its_instance, its_major);
1729 }
1730 host_->on_availability(its_service, its_instance, true, its_major, its_minor);
1731 VSOMEIP_INFO << "ON_AVAILABLE("
1732 << std::hex << std::setw(4) << std::setfill('0') << get_client() <<"): ["
1733 << std::hex << std::setw(4) << std::setfill('0') << its_service << "."
1734 << std::hex << std::setw(4) << std::setfill('0') << its_instance
1735 << ":" << std::dec << int(its_major) << "." << std::dec << its_minor << "]";
1736 } else if (routing_info_entry == routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE) {
1737 {
1738 std::lock_guard<std::mutex> its_lock(local_services_mutex_);
1739 auto found_service = local_services_.find(its_service);
1740 if (found_service != local_services_.end()) {
1741 found_service->second.erase(its_instance);
1742 // move previously offering client to history
1743 local_services_history_[its_service][its_instance].insert(its_client);
1744 if (found_service->second.size() == 0) {
1745 local_services_.erase(its_service);
1746 }
1747 }
1748 }
1749 on_stop_offer_service(its_service, its_instance, its_major, its_minor);
1750 host_->on_availability(its_service, its_instance, false, its_major, its_minor);
1751 VSOMEIP_INFO << "ON_UNAVAILABLE("
1752 << std::hex << std::setw(4) << std::setfill('0') << get_client() <<"): ["
1753 << std::hex << std::setw(4) << std::setfill('0') << its_service << "."
1754 << std::hex << std::setw(4) << std::setfill('0') << its_instance
1755 << ":" << std::dec << int(its_major) << "." << std::dec << its_minor << "]";
1756
1757 if (its_client == get_client()) {
1758 VSOMEIP_INFO << __func__
1759 << ": Clearing subscriptions for service ["
1760 << std::hex << std::setw(4) << std::setfill('0') << its_service << "."
1761 << std::hex << std::setw(4) << std::setfill('0') << its_instance << "]";
1762 unsubscribe_all(its_service, its_instance);
1763 }
1764 }
1765
1766 its_services_size -= uint32_t(sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t) );
1767 }
1768 }
1769 }
1770
1771 i += j;
1772 }
1773 }
1774 {
1775 struct subscription_info {
1776 service_t service_id_;
1777 instance_t instance_id_;
1778 eventgroup_t eventgroup_id_;
1779 client_t client_id_;
1780 major_version_t major_;
1781 event_t event_;
1782 uid_t uid_;
1783 gid_t gid_;
1784 };
1785 std::lock_guard<std::recursive_mutex> its_lock(incoming_subscriptions_mutex_);
1786 std::forward_list<struct subscription_info> subscription_actions;
1787 if (pending_incoming_subscripitons_.size()) {
1788 {
1789 std::lock_guard<std::mutex> its_lock(known_clients_mutex_);
1790 for (const client_t client : known_clients_) {
1791 auto its_client = pending_incoming_subscripitons_.find(client);
1792 if (its_client != pending_incoming_subscripitons_.end()) {
1793 for (const auto& subscription : its_client->second) {
1794 subscription_actions.push_front(
1795 { subscription.service_, subscription.instance_,
1796 subscription.eventgroup_, client,
1797 subscription.major_, subscription.event_,
1798 subscription.uid_, subscription.gid_ });
1799 }
1800 }
1801 }
1802 }
1803 for (const subscription_info &si : subscription_actions) {
1804 #ifdef VSOMEIP_ENABLE_COMPAT
1805 routing_manager_base::set_incoming_subscription_state(si.client_id_, si.service_id_, si.instance_id_,
1806 si.eventgroup_id_, si.event_, subscription_state_e::IS_SUBSCRIBING);
1807 #endif
1808 (void) ep_mgr_->find_or_create_local(si.client_id_);
1809 auto self = shared_from_this();
1810 host_->on_subscription(
1811 si.service_id_, si.instance_id_, si.eventgroup_id_,
1812 si.client_id_, si.uid_, si.gid_, true,
1813 [this, self, si](const bool _subscription_accepted) {
1814 if (!_subscription_accepted) {
1815 send_subscribe_nack(si.client_id_, si.service_id_,
1816 si.instance_id_, si.eventgroup_id_, si.event_, PENDING_SUBSCRIPTION_ID);
1817 } else {
1818 send_subscribe_ack(si.client_id_, si.service_id_,
1819 si.instance_id_, si.eventgroup_id_, si.event_, PENDING_SUBSCRIPTION_ID);
1820 routing_manager_base::subscribe(si.client_id_, si.uid_, si.gid_,
1821 si.service_id_, si.instance_id_, si.eventgroup_id_,
1822 si.major_, si.event_);
1823 #ifdef VSOMEIP_ENABLE_COMPAT
1824 send_pending_notify_ones(si.service_id_,
1825 si.instance_id_, si.eventgroup_id_, si.client_id_);
1826 #endif
1827 }
1828 #ifdef VSOMEIP_ENABLE_COMPAT
1829 routing_manager_base::erase_incoming_subscription_state(si.client_id_, si.service_id_,
1830 si.instance_id_, si.eventgroup_id_, si.event_);
1831 #endif
1832 {
1833 std::lock_guard<std::recursive_mutex> its_lock2(incoming_subscriptions_mutex_);
1834 pending_incoming_subscripitons_.erase(si.client_id_);
1835 }
1836 });
1837 }
1838 }
1839 }
1840 }
1841
on_offered_services_info(const byte_t * _data,uint32_t _size)1842 void routing_manager_proxy::on_offered_services_info(const byte_t *_data,
1843 uint32_t _size) {
1844 #if 0
1845 std::stringstream msg;
1846 msg << "rmp::on_offered_services_info(" << std::hex << client_ << "): ";
1847 for (uint32_t i = 0; i < _size; ++i)
1848 msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
1849 VSOMEIP_INFO << msg.str();
1850 #endif
1851
1852 std::vector<std::pair<service_t, instance_t>> its_offered_services_info;
1853
1854 uint32_t i = 0;
1855 while (i + sizeof(uint32_t) + sizeof(routing_info_entry_e) <= _size) {
1856 routing_info_entry_e routing_info_entry;
1857 std::memcpy(&routing_info_entry, &_data[i], sizeof(routing_info_entry_e));
1858 i += uint32_t(sizeof(routing_info_entry_e));
1859
1860 uint32_t its_service_entry_size;
1861 std::memcpy(&its_service_entry_size, &_data[i], sizeof(uint32_t));
1862 i += uint32_t(sizeof(uint32_t));
1863
1864 if (its_service_entry_size + i > _size) {
1865 VSOMEIP_WARNING << "Client 0x" << std::hex << get_client() << " : "
1866 << "Processing of offered services info failed due to bad length fields!";
1867 return;
1868 }
1869
1870 if (its_service_entry_size >= sizeof(service_t) + sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t)) {
1871 service_t its_service;
1872 std::memcpy(&its_service, &_data[i], sizeof(service_t));
1873 i += uint32_t(sizeof(service_t));
1874
1875 instance_t its_instance;
1876 std::memcpy(&its_instance, &_data[i], sizeof(instance_t));
1877 i += uint32_t(sizeof(instance_t));
1878
1879 major_version_t its_major;
1880 std::memcpy(&its_major, &_data[i], sizeof(major_version_t));
1881 i += uint32_t(sizeof(major_version_t));
1882
1883 minor_version_t its_minor;
1884 std::memcpy(&its_minor, &_data[i], sizeof(minor_version_t));
1885 i += uint32_t(sizeof(minor_version_t));
1886
1887 its_offered_services_info.push_back(std::make_pair(its_service, its_instance));
1888 }
1889 }
1890 host_->on_offered_services_info(its_offered_services_info);
1891 }
1892
reconnect(const std::unordered_set<client_t> & _clients)1893 void routing_manager_proxy::reconnect(const std::unordered_set<client_t> &_clients) {
1894 auto its_security = security_impl::get();
1895 if (!its_security)
1896 return;
1897
1898 // inform host about its own registration state changes
1899 host_->on_state(static_cast<state_type_e>(inner_state_type_e::ST_DEREGISTERED));
1900
1901 {
1902 std::lock_guard<std::mutex> its_lock(state_mutex_);
1903 state_ = inner_state_type_e::ST_DEREGISTERED;
1904 // Notify stop() call about clean deregistration
1905 state_condition_.notify_one();
1906 }
1907
1908
1909 // Remove all local connections/endpoints
1910 for (const auto& its_client : _clients) {
1911 if (its_client != VSOMEIP_ROUTING_CLIENT) {
1912 remove_local(its_client, true);
1913 }
1914 }
1915
1916 VSOMEIP_INFO << std::hex << "Application/Client " << get_client()
1917 <<": Reconnecting to routing manager.";
1918
1919 #ifndef _WIN32
1920 if (!its_security->check_credentials(get_client(), own_uid_, own_gid_)) {
1921 VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client()
1922 << " : routing_manager_proxy::reconnect: isn't allowed"
1923 << " to use the server endpoint due to credential check failed!";
1924 std::lock_guard<std::mutex> its_lock(sender_mutex_);
1925 if (sender_) {
1926 sender_->stop();
1927 }
1928 return;
1929 }
1930 #endif
1931
1932 std::lock_guard<std::mutex> its_lock(sender_mutex_);
1933 if (sender_) {
1934 sender_->restart();
1935 }
1936 }
1937
assign_client()1938 void routing_manager_proxy::assign_client() {
1939 std::vector<byte_t> its_command;
1940
1941 std::string its_name(host_->get_name());
1942 uint32_t its_size(static_cast<uint32_t>(its_name.size()));
1943 its_command.resize(7 + its_name.size());
1944
1945 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_ASSIGN_CLIENT;
1946 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
1947 sizeof(client_));
1948 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
1949 sizeof(its_size));
1950 if (0 < its_name.size())
1951 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], its_name.c_str(),
1952 its_name.size());
1953
1954 std::lock_guard<std::mutex> its_state_lock(state_mutex_);
1955 if (is_connected_) {
1956 std::lock_guard<std::mutex> its_lock(sender_mutex_);
1957 if (sender_) {
1958 if (state_ != inner_state_type_e::ST_DEREGISTERED)
1959 return;
1960 state_ = inner_state_type_e::ST_ASSIGNING;
1961
1962 sender_->send(&its_command[0], static_cast<uint32_t>(its_command.size()));
1963
1964 boost::system::error_code ec;
1965 register_application_timer_.cancel(ec);
1966 register_application_timer_.expires_from_now(std::chrono::milliseconds(10000));
1967 register_application_timer_.async_wait(
1968 std::bind(
1969 &routing_manager_proxy::assign_client_timeout_cbk,
1970 std::dynamic_pointer_cast<routing_manager_proxy>(shared_from_this()),
1971 std::placeholders::_1));
1972 }
1973 }
1974 }
1975
register_application()1976 void routing_manager_proxy::register_application() {
1977 byte_t its_command[] = {
1978 VSOMEIP_REGISTER_APPLICATION, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1979
1980 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
1981 sizeof(client_));
1982
1983 if (is_connected_) {
1984 std::lock_guard<std::mutex> its_lock(sender_mutex_);
1985 if (sender_) {
1986 state_ = inner_state_type_e::ST_REGISTERING;
1987 sender_->send(its_command, sizeof(its_command));
1988
1989 register_application_timer_.cancel();
1990 register_application_timer_.expires_from_now(std::chrono::milliseconds(1000));
1991 register_application_timer_.async_wait(
1992 std::bind(
1993 &routing_manager_proxy::register_application_timeout_cbk,
1994 std::dynamic_pointer_cast<routing_manager_proxy>(shared_from_this()),
1995 std::placeholders::_1));
1996 }
1997 }
1998 }
1999
deregister_application()2000 void routing_manager_proxy::deregister_application() {
2001 std::vector<byte_t> its_command(VSOMEIP_COMMAND_HEADER_SIZE, 0);
2002 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_DEREGISTER_APPLICATION;
2003 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
2004 sizeof(client_));
2005 if (is_connected_)
2006 {
2007 std::lock_guard<std::mutex> its_lock(sender_mutex_);
2008 if (sender_) {
2009 sender_->send(&its_command[0], uint32_t(its_command.size()));
2010 }
2011 }
2012 }
2013
send_pong() const2014 void routing_manager_proxy::send_pong() const {
2015 byte_t its_pong[] = {
2016 VSOMEIP_PONG, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
2017
2018 std::memcpy(&its_pong[VSOMEIP_COMMAND_CLIENT_POS], &client_,
2019 sizeof(client_t));
2020
2021 if (is_connected_) {
2022 std::lock_guard<std::mutex> its_lock(sender_mutex_);
2023 if (sender_) {
2024 sender_->send(its_pong, sizeof(its_pong));
2025 }
2026 }
2027 }
2028
send_request_services(std::set<service_data_t> & _requests)2029 void routing_manager_proxy::send_request_services(std::set<service_data_t>& _requests) {
2030 if (!_requests.size()) {
2031 return;
2032 }
2033 size_t its_size = (VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE
2034 - VSOMEIP_COMMAND_HEADER_SIZE) * _requests.size();
2035 if (its_size > (std::numeric_limits<std::uint32_t>::max)()) {
2036 VSOMEIP_ERROR<< "routing_manager_proxy::send_request_services too many"
2037 << " requests (" << std::dec << its_size << "), returning.";
2038 return;
2039 }
2040
2041 std::vector<byte_t> its_command(its_size + VSOMEIP_COMMAND_HEADER_SIZE);
2042 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_REQUEST_SERVICE;
2043 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS],
2044 &client_, sizeof(client_));
2045 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN],
2046 &its_size, sizeof(std::uint32_t));
2047
2048 uint32_t entry_size = (sizeof(service_t) + sizeof(instance_t)
2049 + sizeof(major_version_t) + sizeof(minor_version_t));
2050
2051 unsigned int i = 0;
2052 for (auto its_service : _requests) {
2053 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + (i * entry_size)],
2054 &its_service.service_, sizeof(its_service.service_));
2055 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2 + (i * entry_size)],
2056 &its_service.instance_, sizeof(its_service.instance_));
2057 its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4 + (i * entry_size)] = its_service.major_;
2058 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5 + (i * entry_size)],
2059 &its_service.minor_, sizeof(its_service.minor_));
2060 ++i;
2061 }
2062
2063 {
2064 std::lock_guard<std::mutex> its_lock(sender_mutex_);
2065 if (sender_) {
2066 sender_->send(&its_command[0],
2067 static_cast<std::uint32_t>(its_size + VSOMEIP_COMMAND_HEADER_SIZE));
2068 }
2069 }
2070 }
2071
send_release_service(client_t _client,service_t _service,instance_t _instance)2072 void routing_manager_proxy::send_release_service(client_t _client, service_t _service,
2073 instance_t _instance) {
2074 (void)_client;
2075 byte_t its_command[VSOMEIP_RELEASE_SERVICE_COMMAND_SIZE];
2076 uint32_t its_size = VSOMEIP_RELEASE_SERVICE_COMMAND_SIZE
2077 - VSOMEIP_COMMAND_HEADER_SIZE;
2078
2079 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_RELEASE_SERVICE;
2080 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
2081 sizeof(client_));
2082 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
2083 sizeof(its_size));
2084 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
2085 sizeof(_service));
2086 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
2087 sizeof(_instance));
2088
2089 {
2090 std::lock_guard<std::mutex> its_lock(sender_mutex_);
2091 if (sender_) {
2092 sender_->send(its_command, sizeof(its_command));
2093 }
2094 }
2095 }
2096
send_register_event(client_t _client,service_t _service,instance_t _instance,event_t _notifier,const std::set<eventgroup_t> & _eventgroups,const event_type_e _type,reliability_type_e _reliability,bool _is_provided)2097 void routing_manager_proxy::send_register_event(client_t _client,
2098 service_t _service, instance_t _instance,
2099 event_t _notifier,
2100 const std::set<eventgroup_t> &_eventgroups, const event_type_e _type,
2101 reliability_type_e _reliability,
2102 bool _is_provided) {
2103
2104 std::size_t its_eventgroups_size = (_eventgroups.size() * sizeof(eventgroup_t)) +
2105 VSOMEIP_REGISTER_EVENT_COMMAND_SIZE;
2106 if (its_eventgroups_size > (std::numeric_limits<std::uint32_t>::max)()) {
2107 VSOMEIP_ERROR<< "routing_manager_proxy::send_register_event too many"
2108 << " eventgroups (" << std::dec << its_eventgroups_size << "), returning.";
2109 return;
2110 }
2111 byte_t *its_command = new byte_t[its_eventgroups_size];
2112 uint32_t its_size = static_cast<std::uint32_t>(its_eventgroups_size)
2113 - VSOMEIP_COMMAND_HEADER_SIZE;
2114
2115 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_REGISTER_EVENT;
2116 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
2117 sizeof(_client));
2118 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
2119 sizeof(its_size));
2120 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
2121 sizeof(_service));
2122 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
2123 sizeof(_instance));
2124 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_notifier,
2125 sizeof(_notifier));
2126 its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6]
2127 = static_cast<byte_t>(_type);
2128 its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 7]
2129 = static_cast<byte_t>(_is_provided);
2130 its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8]
2131 = static_cast<byte_t>(_reliability);
2132
2133 std::size_t i = 9;
2134 for (auto eg : _eventgroups) {
2135 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + i], &eg,
2136 sizeof(eventgroup_t));
2137 i += sizeof(eventgroup_t);
2138 }
2139
2140 {
2141 std::lock_guard<std::mutex> its_lock(sender_mutex_);
2142 if (sender_) {
2143 sender_->send(its_command, static_cast<std::uint32_t>(its_eventgroups_size));
2144 }
2145 }
2146
2147 if (_is_provided) {
2148 VSOMEIP_INFO << "REGISTER EVENT("
2149 << std::hex << std::setw(4) << std::setfill('0') << client_ << "): ["
2150 << std::hex << std::setw(4) << std::setfill('0') << _service << "."
2151 << std::hex << std::setw(4) << std::setfill('0') << _instance << "."
2152 << std::hex << std::setw(4) << std::setfill('0') << _notifier
2153 << ":is_provider=" << _is_provided << "]";
2154 }
2155
2156 delete[] its_command;
2157 }
2158
on_subscribe_ack(client_t _client,service_t _service,instance_t _instance,eventgroup_t _eventgroup,event_t _event)2159 void routing_manager_proxy::on_subscribe_ack(client_t _client,
2160 service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) {
2161 (void)_client;
2162 #if 0
2163 VSOMEIP_ERROR << "routing_manager_proxy::" << __func__
2164 << "(" << std::hex << host_->get_client() << "):"
2165 << "event="
2166 << std::hex << _service << "."
2167 << std::hex << _instance << "."
2168 << std::hex << _eventgroup << "."
2169 << std::hex << _event;
2170 #endif
2171 if (_event == ANY_EVENT) {
2172 auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup);
2173 if (its_eventgroup) {
2174 for (const auto& its_event : its_eventgroup->get_events()) {
2175 host_->on_subscription_status(_service, _instance, _eventgroup, its_event->get_event(), 0x0 /*OK*/);
2176 }
2177 }
2178 } else {
2179 host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x0 /*OK*/);
2180 }
2181 }
2182
on_subscribe_nack(client_t _client,service_t _service,instance_t _instance,eventgroup_t _eventgroup,event_t _event)2183 void routing_manager_proxy::on_subscribe_nack(client_t _client,
2184 service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) {
2185 (void)_client;
2186 if (_event == ANY_EVENT) {
2187 auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup);
2188 if (its_eventgroup) {
2189 for (const auto& its_event : its_eventgroup->get_events()) {
2190 host_->on_subscription_status(_service, _instance, _eventgroup, its_event->get_event(), 0x7 /*Rejected*/);
2191 }
2192 }
2193 } else {
2194 host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x7 /*Rejected*/);
2195 }
2196 }
2197
cache_event_payload(const std::shared_ptr<message> & _message)2198 void routing_manager_proxy::cache_event_payload(
2199 const std::shared_ptr<message> &_message) {
2200 const service_t its_service(_message->get_service());
2201 const instance_t its_instance(_message->get_instance());
2202 const method_t its_method(_message->get_method());
2203 std::shared_ptr<event> its_event = find_event(its_service, its_instance, its_method);
2204 if (its_event) {
2205 if (its_event->is_field()) {
2206 its_event->set_payload_dont_notify(_message->get_payload());
2207 }
2208 } else {
2209 // we received a event which was not yet requested
2210 std::set<eventgroup_t> its_eventgroups;
2211 // create a placeholder field until someone requests this event with
2212 // full information like eventgroup, field or not etc.
2213 routing_manager_base::register_event(host_->get_client(),
2214 its_service, its_instance,
2215 its_method,
2216 its_eventgroups, event_type_e::ET_UNKNOWN,
2217 reliability_type_e::RT_UNKNOWN,
2218 std::chrono::milliseconds::zero(), false, true,
2219 nullptr,
2220 false, false, true);
2221 std::shared_ptr<event> its_event = find_event(its_service, its_instance, its_method);
2222 if (its_event) {
2223 its_event->set_payload_dont_notify(_message->get_payload());
2224 }
2225 }
2226
2227 }
2228
on_stop_offer_service(service_t _service,instance_t _instance,major_version_t _major,minor_version_t _minor)2229 void routing_manager_proxy::on_stop_offer_service(service_t _service,
2230 instance_t _instance,
2231 major_version_t _major,
2232 minor_version_t _minor) {
2233 (void) _major;
2234 (void) _minor;
2235 std::map<event_t, std::shared_ptr<event> > events;
2236 {
2237 std::lock_guard<std::mutex> its_lock(events_mutex_);
2238 auto its_events_service = events_.find(_service);
2239 if (its_events_service != events_.end()) {
2240 auto its_events_instance = its_events_service->second.find(_instance);
2241 if (its_events_instance != its_events_service->second.end()) {
2242 for (auto &e : its_events_instance->second)
2243 events[e.first] = e.second;
2244 }
2245 }
2246 }
2247 for (auto &e : events) {
2248 e.second->unset_payload();
2249 }
2250 }
2251
send_pending_commands()2252 void routing_manager_proxy::send_pending_commands() {
2253 for (auto &po : pending_offers_)
2254 send_offer_service(client_,
2255 po.service_, po.instance_,
2256 po.major_, po.minor_);
2257
2258 for (auto &per : pending_event_registrations_)
2259 send_register_event(client_,
2260 per.service_, per.instance_,
2261 per.notifier_,
2262 per.eventgroups_, per.type_, per.reliability_,
2263 per.is_provided_);
2264
2265 send_request_services(requests_);
2266 }
2267
init_receiver()2268 void routing_manager_proxy::init_receiver() {
2269 #ifndef _WIN32
2270 auto its_security = security_impl::get();
2271 if (!its_security)
2272 return;
2273
2274 its_security->store_client_to_uid_gid_mapping(get_client(), own_uid_, own_gid_);
2275 its_security->store_uid_gid_to_client_mapping(own_uid_, own_gid_, get_client());
2276 #endif
2277 receiver_ = ep_mgr_->create_local_server(shared_from_this());
2278 }
2279
notify_remote_initially(service_t _service,instance_t _instance,eventgroup_t _eventgroup,const std::set<event_t> & _events_to_exclude)2280 void routing_manager_proxy::notify_remote_initially(service_t _service, instance_t _instance,
2281 eventgroup_t _eventgroup, const std::set<event_t> &_events_to_exclude) {
2282 auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup);
2283 if (its_eventgroup) {
2284 auto service_info = find_service(_service, _instance);
2285 for (const auto &e : its_eventgroup->get_events()) {
2286 if (e->is_field() && e->is_set()
2287 && _events_to_exclude.find(e->get_event())
2288 == _events_to_exclude.end()) {
2289 std::shared_ptr<message> its_notification
2290 = runtime::get()->create_notification();
2291 its_notification->set_service(_service);
2292 its_notification->set_instance(_instance);
2293 its_notification->set_method(e->get_event());
2294 its_notification->set_payload(e->get_payload());
2295 if (service_info) {
2296 its_notification->set_interface_version(service_info->get_major());
2297 }
2298
2299 std::shared_ptr<serializer> its_serializer(get_serializer());
2300 if (its_serializer->serialize(its_notification.get())) {
2301 {
2302 std::lock_guard<std::mutex> its_lock(sender_mutex_);
2303 if (sender_) {
2304 send_local(sender_, VSOMEIP_ROUTING_CLIENT, its_serializer->get_data(),
2305 its_serializer->get_size(), _instance, false, VSOMEIP_NOTIFY);
2306 }
2307 }
2308 its_serializer->reset();
2309 put_serializer(its_serializer);
2310 } else {
2311 VSOMEIP_ERROR << "Failed to serialize message. Check message size!";
2312 }
2313 }
2314 }
2315 }
2316
2317 }
2318
get_remote_subscriber_count(service_t _service,instance_t _instance,eventgroup_t _eventgroup,bool _increment)2319 uint32_t routing_manager_proxy::get_remote_subscriber_count(service_t _service,
2320 instance_t _instance, eventgroup_t _eventgroup, bool _increment) {
2321 std::lock_guard<std::mutex> its_lock(remote_subscriber_count_mutex_);
2322 uint32_t count (0);
2323 bool found(false);
2324 auto found_service = remote_subscriber_count_.find(_service);
2325 if (found_service != remote_subscriber_count_.end()) {
2326 auto found_instance = found_service->second.find(_instance);
2327 if (found_instance != found_service->second.end()) {
2328 auto found_group = found_instance->second.find(_eventgroup);
2329 if (found_group != found_instance->second.end()) {
2330 found = true;
2331 if (_increment) {
2332 found_group->second = found_group->second + 1;
2333 } else {
2334 if (found_group->second > 0) {
2335 found_group->second = found_group->second - 1;
2336 }
2337 }
2338 count = found_group->second;
2339 }
2340 }
2341 }
2342 if (!found) {
2343 if (_increment) {
2344 remote_subscriber_count_[_service][_instance][_eventgroup] = 1;
2345 count = 1;
2346 }
2347 }
2348 return count;
2349 }
2350
clear_remote_subscriber_count(service_t _service,instance_t _instance)2351 void routing_manager_proxy::clear_remote_subscriber_count(
2352 service_t _service, instance_t _instance) {
2353 std::lock_guard<std::mutex> its_lock(remote_subscriber_count_mutex_);
2354 auto found_service = remote_subscriber_count_.find(_service);
2355 if (found_service != remote_subscriber_count_.end()) {
2356 if (found_service->second.erase(_instance)) {
2357 if (!found_service->second.size()) {
2358 remote_subscriber_count_.erase(found_service);
2359 }
2360 }
2361 }
2362 }
2363
2364 void
assign_client_timeout_cbk(boost::system::error_code const & _error)2365 routing_manager_proxy::assign_client_timeout_cbk(
2366 boost::system::error_code const &_error) {
2367 if (!_error) {
2368 bool register_again(false);
2369 {
2370 std::lock_guard<std::mutex> its_lock(state_mutex_);
2371 if (state_ != inner_state_type_e::ST_REGISTERED) {
2372 state_ = inner_state_type_e::ST_DEREGISTERED;
2373 register_again = true;
2374 }
2375 }
2376 if (register_again) {
2377 std::lock_guard<std::mutex> its_lock(sender_mutex_);
2378 VSOMEIP_WARNING << std::hex << "Client 0x" << get_client()
2379 << " request client timeout! Trying again...";
2380
2381 if (sender_) {
2382 sender_->restart();
2383 }
2384 }
2385 }
2386 }
2387
register_application_timeout_cbk(boost::system::error_code const & _error)2388 void routing_manager_proxy::register_application_timeout_cbk(
2389 boost::system::error_code const &_error) {
2390
2391 bool register_again(false);
2392 {
2393 std::lock_guard<std::mutex> its_lock(state_mutex_);
2394 if (!_error && state_ != inner_state_type_e::ST_REGISTERED) {
2395 state_ = inner_state_type_e::ST_DEREGISTERED;
2396 register_again = true;
2397 }
2398 }
2399 if (register_again) {
2400 std::lock_guard<std::mutex> its_lock(sender_mutex_);
2401 VSOMEIP_WARNING << std::hex << "Client 0x" << get_client()
2402 << " register timeout! Trying again...";
2403
2404 if (sender_)
2405 sender_->restart();
2406 }
2407 }
2408
send_registered_ack()2409 void routing_manager_proxy::send_registered_ack() {
2410 byte_t its_command[VSOMEIP_COMMAND_HEADER_SIZE] = {
2411 VSOMEIP_REGISTERED_ACK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
2412 client_t client = get_client();
2413 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client,
2414 sizeof(client));
2415 {
2416 std::lock_guard<std::mutex> its_lock(sender_mutex_);
2417 if (sender_) {
2418 sender_->send(its_command, VSOMEIP_COMMAND_HEADER_SIZE);
2419 }
2420 }
2421 }
2422
is_client_known(client_t _client)2423 bool routing_manager_proxy::is_client_known(client_t _client) {
2424 std::lock_guard<std::mutex> its_lock(known_clients_mutex_);
2425 return (known_clients_.find(_client) != known_clients_.end());
2426 }
2427
create_placeholder_event_and_subscribe(service_t _service,instance_t _instance,eventgroup_t _eventgroup,event_t _notifier,client_t _client)2428 bool routing_manager_proxy::create_placeholder_event_and_subscribe(
2429 service_t _service, instance_t _instance,
2430 eventgroup_t _eventgroup, event_t _notifier, client_t _client) {
2431
2432 std::lock_guard<std::mutex> its_lock(stop_mutex_);
2433
2434 bool is_inserted(false);
2435
2436 if (find_service(_service, _instance)) {
2437 // We received an event for an existing service which was not yet
2438 // requested/offered. Create a placeholder field until someone
2439 // requests/offers this event with full information like eventgroup,
2440 // field/event, etc.
2441 std::set<eventgroup_t> its_eventgroups({ _eventgroup });
2442 // routing_manager_proxy: Always register with own client id and shadow = false
2443 routing_manager_base::register_event(host_->get_client(),
2444 _service, _instance, _notifier,
2445 its_eventgroups, event_type_e::ET_UNKNOWN, reliability_type_e::RT_UNKNOWN,
2446 std::chrono::milliseconds::zero(), false, true, nullptr, false, false,
2447 true);
2448
2449 std::shared_ptr<event> its_event = find_event(_service, _instance, _notifier);
2450 if (its_event) {
2451 is_inserted = its_event->add_subscriber(_eventgroup, _client, false);
2452 }
2453 }
2454
2455 return is_inserted;
2456 }
2457
request_debounce_timeout_cbk(boost::system::error_code const & _error)2458 void routing_manager_proxy::request_debounce_timeout_cbk(
2459 boost::system::error_code const &_error) {
2460 std::lock_guard<std::mutex> its_lock(state_mutex_);
2461 if (!_error) {
2462 if (requests_to_debounce_.size()) {
2463 if (state_ == inner_state_type_e::ST_REGISTERED) {
2464 send_request_services(requests_to_debounce_);
2465 requests_.insert(requests_to_debounce_.begin(),
2466 requests_to_debounce_.end());
2467 requests_to_debounce_.clear();
2468 } else {
2469 {
2470 std::lock_guard<std::mutex> its_lock(request_timer_mutex_);
2471 request_debounce_timer_running_ = true;
2472 request_debounce_timer_.expires_from_now(std::chrono::milliseconds(
2473 configuration_->get_request_debouncing(host_->get_name())));
2474 request_debounce_timer_.async_wait(
2475 std::bind(
2476 &routing_manager_proxy::request_debounce_timeout_cbk,
2477 std::dynamic_pointer_cast<routing_manager_proxy>(shared_from_this()),
2478 std::placeholders::_1));
2479 return;
2480 }
2481 }
2482 }
2483 }
2484 {
2485 std::lock_guard<std::mutex> its_lock(request_timer_mutex_);
2486 request_debounce_timer_running_ = false;
2487 }
2488 }
2489
register_client_error_handler(client_t _client,const std::shared_ptr<endpoint> & _endpoint)2490 void routing_manager_proxy::register_client_error_handler(client_t _client,
2491 const std::shared_ptr<endpoint> &_endpoint) {
2492 _endpoint->register_error_handler(
2493 std::bind(&routing_manager_proxy::handle_client_error, this, _client));
2494 }
2495
handle_client_error(client_t _client)2496 void routing_manager_proxy::handle_client_error(client_t _client) {
2497 if (_client != VSOMEIP_ROUTING_CLIENT) {
2498 VSOMEIP_INFO << "Client 0x" << std::hex << get_client()
2499 << " handles a client error(" << std::hex << _client << ")";
2500 remove_local(_client, true);
2501 } else {
2502 bool should_reconnect(true);
2503 {
2504 std::unique_lock<std::mutex> its_lock(state_mutex_);
2505 should_reconnect = is_started_;
2506 }
2507 if (should_reconnect) {
2508 std::unordered_set<client_t> its_known_clients;
2509 {
2510 std::lock_guard<std::mutex> its_lock(known_clients_mutex_);
2511 its_known_clients = known_clients_;
2512 }
2513 reconnect(its_known_clients);
2514 }
2515 }
2516 }
2517
send_get_offered_services_info(client_t _client,offer_type_e _offer_type)2518 void routing_manager_proxy::send_get_offered_services_info(client_t _client, offer_type_e _offer_type) {
2519 (void)_client;
2520
2521 byte_t its_command[VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE];
2522 uint32_t its_size = VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE
2523 - VSOMEIP_COMMAND_HEADER_SIZE;
2524
2525 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_OFFERED_SERVICES_REQUEST;
2526 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client,
2527 sizeof(_client));
2528 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
2529 sizeof(its_size));
2530 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_offer_type,
2531 sizeof(_offer_type));
2532
2533 std::lock_guard<std::mutex> its_lock(sender_mutex_);
2534 if (sender_) {
2535 sender_->send(its_command, sizeof(its_command));
2536 }
2537 }
2538
send_unsubscribe_ack(service_t _service,instance_t _instance,eventgroup_t _eventgroup,remote_subscription_id_t _id)2539 void routing_manager_proxy::send_unsubscribe_ack(
2540 service_t _service, instance_t _instance, eventgroup_t _eventgroup,
2541 remote_subscription_id_t _id) {
2542 byte_t its_command[VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE];
2543 const std::uint32_t its_size = VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE
2544 - VSOMEIP_COMMAND_HEADER_SIZE;
2545
2546 const client_t its_client = get_client();
2547 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UNSUBSCRIBE_ACK;
2548 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &its_client,
2549 sizeof(its_client));
2550 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
2551 sizeof(its_size));
2552 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
2553 sizeof(_service));
2554 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
2555 sizeof(_instance));
2556 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup,
2557 sizeof(_eventgroup));
2558 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_id,
2559 sizeof(_id));
2560
2561 {
2562 std::lock_guard<std::mutex> its_lock(sender_mutex_);
2563 if (sender_) {
2564 sender_->send(its_command, sizeof(its_command));
2565 }
2566 }
2567 }
2568
resend_provided_event_registrations()2569 void routing_manager_proxy::resend_provided_event_registrations() {
2570 std::lock_guard<std::mutex> its_lock(state_mutex_);
2571 for (const event_data_t& ed : pending_event_registrations_) {
2572 if (ed.is_provided_) {
2573 send_register_event(client_, ed.service_, ed.instance_,
2574 ed.notifier_, ed.eventgroups_, ed.type_, ed.reliability_,
2575 ed.is_provided_);
2576 }
2577 }
2578 }
2579
send_resend_provided_event_response(pending_remote_offer_id_t _id)2580 void routing_manager_proxy::send_resend_provided_event_response(pending_remote_offer_id_t _id) {
2581 byte_t its_command[VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE];
2582 const std::uint32_t its_size = VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE
2583 - VSOMEIP_COMMAND_HEADER_SIZE;
2584
2585 const client_t its_client = get_client();
2586 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_RESEND_PROVIDED_EVENTS;
2587 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &its_client,
2588 sizeof(its_client));
2589 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
2590 sizeof(its_size));
2591 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_id,
2592 sizeof(pending_remote_offer_id_t));
2593 {
2594 std::lock_guard<std::mutex> its_lock(sender_mutex_);
2595 if (sender_) {
2596 sender_->send(its_command, sizeof(its_command));
2597 }
2598 }
2599 }
2600
send_update_security_policy_response(pending_security_update_id_t _update_id)2601 void routing_manager_proxy::send_update_security_policy_response(pending_security_update_id_t _update_id) {
2602 byte_t its_command[VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE];
2603 const std::uint32_t its_size = VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE
2604 - VSOMEIP_COMMAND_HEADER_SIZE;
2605
2606 const client_t its_client = get_client();
2607 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE;
2608 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &its_client,
2609 sizeof(its_client));
2610 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
2611 sizeof(its_size));
2612 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_update_id,
2613 sizeof(pending_security_update_id_t));
2614 {
2615 std::lock_guard<std::mutex> its_lock(sender_mutex_);
2616 if (sender_) {
2617 sender_->send(its_command, sizeof(its_command));
2618 }
2619 }
2620 }
2621
send_remove_security_policy_response(pending_security_update_id_t _update_id)2622 void routing_manager_proxy::send_remove_security_policy_response(pending_security_update_id_t _update_id) {
2623 byte_t its_command[VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE];
2624 const std::uint32_t its_size = VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE
2625 - VSOMEIP_COMMAND_HEADER_SIZE;
2626
2627 const client_t its_client = get_client();
2628 its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE;
2629 std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &its_client,
2630 sizeof(its_client));
2631 std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
2632 sizeof(its_size));
2633 std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_update_id,
2634 sizeof(pending_security_update_id_t));
2635 {
2636 std::lock_guard<std::mutex> its_lock(sender_mutex_);
2637 if (sender_) {
2638 sender_->send(its_command, sizeof(its_command));
2639 }
2640 }
2641 }
2642
on_update_security_credentials(const byte_t * _data,uint32_t _size)2643 void routing_manager_proxy::on_update_security_credentials(const byte_t *_data, uint32_t _size) {
2644 auto its_security = security_impl::get();
2645 if (!its_security)
2646 return;
2647
2648 uint32_t i = 0;
2649 while ( (i + sizeof(uint32_t) + sizeof(uint32_t)) <= _size) {
2650 std::shared_ptr<policy> its_policy(std::make_shared<policy>());
2651
2652 boost::icl::interval_set<uint32_t> its_gid_set;
2653 uint32_t its_uid, its_gid;
2654
2655 std::memcpy(&its_uid, &_data[i], sizeof(uint32_t));
2656 i += uint32_t(sizeof(uint32_t));
2657 std::memcpy(&its_gid, &_data[i], sizeof(uint32_t));
2658 i += uint32_t(sizeof(uint32_t));
2659
2660 its_gid_set.insert(its_gid);
2661
2662 its_policy->credentials_ += std::make_pair(
2663 boost::icl::interval<uid_t>::closed(its_uid, its_uid), its_gid_set);
2664 its_policy->allow_who_ = true;
2665 its_policy->allow_what_ = true;
2666
2667 its_security->add_security_credentials(its_uid, its_gid, its_policy, get_client());
2668 }
2669 }
2670
on_client_assign_ack(const client_t & _client)2671 void routing_manager_proxy::on_client_assign_ack(const client_t &_client) {
2672 std::lock_guard<std::mutex> its_lock(state_mutex_);
2673 if (state_ == inner_state_type_e::ST_ASSIGNING) {
2674 if (_client != VSOMEIP_CLIENT_UNSET) {
2675 state_ = inner_state_type_e::ST_ASSIGNED;
2676
2677 boost::system::error_code ec;
2678 register_application_timer_.cancel(ec);
2679 host_->set_client(_client);
2680 client_ = _client;
2681
2682 if (is_started_) {
2683 init_receiver();
2684 if (receiver_) {
2685 receiver_->start();
2686
2687 VSOMEIP_INFO << std::hex << "Client " << client_
2688 << " (" << host_->get_name()
2689 << ") successfully connected to routing ~> registering..";
2690 register_application();
2691 } else {
2692 state_ = inner_state_type_e::ST_DEREGISTERED;
2693
2694 host_->set_client(VSOMEIP_CLIENT_UNSET);
2695 client_ = VSOMEIP_CLIENT_UNSET;
2696
2697 sender_->restart();
2698 }
2699 }
2700 } else {
2701 VSOMEIP_ERROR << "Didn't receive valid clientID! Won't register application.";
2702 }
2703 } else {
2704 VSOMEIP_WARNING << "Client " << std::hex << client_
2705 << " received another client identifier ("
2706 << std::hex << _client
2707 << "). Ignoring it. ("
2708 << (int)state_ << ")";
2709 }
2710 }
2711
on_suspend()2712 void routing_manager_proxy::on_suspend() {
2713
2714 VSOMEIP_INFO << __func__ << ": Application "
2715 << std::hex << std::setw(4) << std::setfill('0')
2716 << host_->get_client();
2717
2718 std::lock_guard<std::mutex> its_lock(remote_subscriber_count_mutex_);
2719
2720 // Unsubscribe everything that is left over.
2721 for (const auto &s : remote_subscriber_count_) {
2722 for (const auto &i : s.second) {
2723 for (const auto e : i.second)
2724 routing_manager_base::unsubscribe(
2725 VSOMEIP_ROUTING_CLIENT, ANY_UID, ANY_GID,
2726 s.first, i.first, e.first, ANY_EVENT);
2727 }
2728 }
2729
2730 // Remove all entries.
2731 remote_subscriber_count_.clear();
2732 }
2733
2734 } // namespace vsomeip_v3
2735