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