/src/Fast-DDS/src/cpp/rtps/messages/MessageReceiver.cpp
Line | Count | Source |
1 | | // Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | /** |
16 | | * @file MessageReceiver.cpp |
17 | | * |
18 | | */ |
19 | | |
20 | | #include <cassert> |
21 | | #include <limits> |
22 | | #include <thread> |
23 | | |
24 | | #include <fastdds/rtps/common/EntityId_t.hpp> |
25 | | #include <fastdds/rtps/common/Guid.hpp> |
26 | | |
27 | | #include <fastdds/core/policy/ParameterList.hpp> |
28 | | #include <fastdds/dds/log/Log.hpp> |
29 | | #include <fastdds/rtps/reader/RTPSReader.hpp> |
30 | | #include <fastdds/rtps/writer/RTPSWriter.hpp> |
31 | | |
32 | | #include <rtps/messages/MessageReceiver.h> |
33 | | #include <rtps/participant/RTPSParticipantImpl.hpp> |
34 | | #include <rtps/reader/BaseReader.hpp> |
35 | | #include <rtps/writer/BaseWriter.hpp> |
36 | | #include <statistics/rtps/messages/RTPSStatisticsMessages.hpp> |
37 | | #include <statistics/rtps/StatisticsBase.hpp> |
38 | | #include <utils/shared_mutex.hpp> |
39 | | |
40 | 921 | #define INFO_SRC_SUBMSG_LENGTH 20 |
41 | | |
42 | | #define IDSTRING "(ID:" << std::this_thread::get_id() << ") " << |
43 | | |
44 | | using ParameterList = eprosima::fastdds::dds::ParameterList; |
45 | | |
46 | | namespace eprosima { |
47 | | namespace fastdds { |
48 | | namespace rtps { |
49 | | |
50 | | MessageReceiver::MessageReceiver( |
51 | | RTPSParticipantImpl* participant, |
52 | | uint32_t rec_buffer_size) |
53 | 1.73k | : mtx_() |
54 | 1.73k | , associated_writers_() |
55 | 1.73k | , associated_readers_() |
56 | | #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
57 | | , participant_(participant) |
58 | | #endif // if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
59 | 1.73k | , source_version_(c_ProtocolVersion) |
60 | 1.73k | , source_vendor_id_(c_VendorId_Unknown) |
61 | 1.73k | , source_guid_prefix_(c_GuidPrefix_Unknown) |
62 | 1.73k | , dest_guid_prefix_(c_GuidPrefix_Unknown) |
63 | 1.73k | , have_timestamp_(false) |
64 | 1.73k | , timestamp_(dds::c_TimeInvalid) |
65 | | #if HAVE_SECURITY |
66 | | , crypto_msg_(participant->is_secure() ? rec_buffer_size : 0) |
67 | | , crypto_submsg_(participant->is_secure() ? rec_buffer_size : 0) |
68 | | , crypto_payload_(participant->is_secure() ? rec_buffer_size : 0) |
69 | | #endif // if HAVE_SECURITY |
70 | 1.73k | { |
71 | 1.73k | static_cast<void>(participant); |
72 | 1.73k | (void)rec_buffer_size; |
73 | 1.73k | EPROSIMA_LOG_INFO(RTPS_MSG_IN, "Created with CDRMessage of size: " << rec_buffer_size); |
74 | | |
75 | | #if HAVE_SECURITY && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
76 | | if (participant->is_secure()) |
77 | | { |
78 | | process_data_message_function_ = std::bind( |
79 | | &MessageReceiver::process_data_message_with_security, |
80 | | this, |
81 | | std::placeholders::_1, |
82 | | std::placeholders::_2, |
83 | | std::placeholders::_3); |
84 | | |
85 | | process_data_fragment_message_function_ = std::bind( |
86 | | &MessageReceiver::process_data_fragment_message_with_security, |
87 | | this, |
88 | | std::placeholders::_1, |
89 | | std::placeholders::_2, |
90 | | std::placeholders::_3, |
91 | | std::placeholders::_4, |
92 | | std::placeholders::_5, |
93 | | std::placeholders::_6); |
94 | | } |
95 | | else |
96 | | { |
97 | | #endif // if HAVE_SECURITY && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
98 | 1.73k | process_data_message_function_ = std::bind( |
99 | 1.73k | &MessageReceiver::process_data_message_without_security, |
100 | 1.73k | this, |
101 | 1.73k | std::placeholders::_1, |
102 | 1.73k | std::placeholders::_2, |
103 | 1.73k | std::placeholders::_3); |
104 | | |
105 | 1.73k | process_data_fragment_message_function_ = std::bind( |
106 | 1.73k | &MessageReceiver::process_data_fragment_message_without_security, |
107 | 1.73k | this, |
108 | 1.73k | std::placeholders::_1, |
109 | 1.73k | std::placeholders::_2, |
110 | 1.73k | std::placeholders::_3, |
111 | 1.73k | std::placeholders::_4, |
112 | 1.73k | std::placeholders::_5, |
113 | 1.73k | std::placeholders::_6); |
114 | | #if HAVE_SECURITY && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
115 | | } |
116 | | |
117 | | #endif // if HAVE_SECURITY && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
118 | 1.73k | } |
119 | | |
120 | | MessageReceiver::~MessageReceiver() |
121 | 1.73k | { |
122 | 1.73k | EPROSIMA_LOG_INFO(RTPS_MSG_IN, ""); |
123 | 1.73k | assert(associated_writers_.empty()); |
124 | 1.73k | assert(associated_readers_.empty()); |
125 | 1.73k | } |
126 | | |
127 | | #if HAVE_SECURITY && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
128 | | void MessageReceiver::process_data_message_with_security( |
129 | | const EntityId_t& reader_id, |
130 | | CacheChange_t& change, |
131 | | bool was_decoded) |
132 | | { |
133 | | auto process_message = [was_decoded, &change, this](BaseReader* reader) |
134 | | { |
135 | | if (!was_decoded && reader->getAttributes().security_attributes().is_submessage_protected) |
136 | | { |
137 | | return; |
138 | | } |
139 | | |
140 | | if (!reader->getAttributes().security_attributes().is_payload_protected) |
141 | | { |
142 | | reader->process_data_msg(&change); |
143 | | return; |
144 | | } |
145 | | |
146 | | if (!reader->matched_writer_is_matched(change.writerGUID)) |
147 | | { |
148 | | return; |
149 | | } |
150 | | |
151 | | if (!participant_->security_manager().decode_serialized_payload(change.serializedPayload, |
152 | | crypto_payload_, reader->getGuid(), change.writerGUID)) |
153 | | { |
154 | | return; |
155 | | } |
156 | | |
157 | | std::swap(change.serializedPayload.data, crypto_payload_.data); |
158 | | std::swap(change.serializedPayload.length, crypto_payload_.length); |
159 | | |
160 | | octet* original_payload_data = change.serializedPayload.data; |
161 | | uint32_t original_payload_length {change.serializedPayload.length}; |
162 | | reader->process_data_msg(&change); |
163 | | IPayloadPool* payload_pool = change.serializedPayload.payload_owner; |
164 | | if (payload_pool) |
165 | | { |
166 | | payload_pool->release_payload(change.serializedPayload); |
167 | | change.serializedPayload.data = original_payload_data; |
168 | | change.serializedPayload.length = original_payload_length; |
169 | | } |
170 | | std::swap(change.serializedPayload.data, crypto_payload_.data); |
171 | | std::swap(change.serializedPayload.length, crypto_payload_.length); |
172 | | }; |
173 | | |
174 | | findAllReaders(reader_id, process_message); |
175 | | } |
176 | | |
177 | | void MessageReceiver::process_data_fragment_message_with_security( |
178 | | const EntityId_t& reader_id, |
179 | | CacheChange_t& change, |
180 | | uint32_t sample_size, |
181 | | uint32_t fragment_starting_num, |
182 | | uint16_t fragments_in_submessage, |
183 | | bool was_decoded) |
184 | | { |
185 | | auto process_message = [was_decoded, &change, sample_size, fragment_starting_num, fragments_in_submessage, this]( |
186 | | BaseReader* reader) |
187 | | { |
188 | | if (!was_decoded && reader->getAttributes().security_attributes().is_submessage_protected) |
189 | | { |
190 | | return; |
191 | | } |
192 | | |
193 | | if (!reader->getAttributes().security_attributes().is_payload_protected) |
194 | | { |
195 | | reader->process_data_frag_msg(&change, sample_size, fragment_starting_num, fragments_in_submessage); |
196 | | return; |
197 | | } |
198 | | |
199 | | if (!reader->matched_writer_is_matched(change.writerGUID)) |
200 | | { |
201 | | return; |
202 | | } |
203 | | |
204 | | if (!participant_->security_manager().decode_serialized_payload(change.serializedPayload, |
205 | | crypto_payload_, reader->getGuid(), change.writerGUID)) |
206 | | { |
207 | | return; |
208 | | } |
209 | | |
210 | | std::swap(change.serializedPayload.data, crypto_payload_.data); |
211 | | std::swap(change.serializedPayload.length, crypto_payload_.length); |
212 | | reader->process_data_frag_msg(&change, sample_size, fragment_starting_num, fragments_in_submessage); |
213 | | std::swap(change.serializedPayload.data, crypto_payload_.data); |
214 | | std::swap(change.serializedPayload.length, crypto_payload_.length); |
215 | | }; |
216 | | |
217 | | findAllReaders(reader_id, process_message); |
218 | | } |
219 | | |
220 | | #endif // if HAVE_SECURITY && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
221 | | |
222 | | void MessageReceiver::process_data_message_without_security( |
223 | | const EntityId_t& reader_id, |
224 | | CacheChange_t& change, |
225 | | bool /*was_decoded*/) |
226 | 0 | { |
227 | 0 | auto process_message = [&change](BaseReader* reader) |
228 | 0 | { |
229 | 0 | reader->process_data_msg(&change); |
230 | 0 | }; |
231 | |
|
232 | 0 | findAllReaders(reader_id, process_message); |
233 | 0 | } |
234 | | |
235 | | void MessageReceiver::process_data_fragment_message_without_security( |
236 | | const EntityId_t& reader_id, |
237 | | CacheChange_t& change, |
238 | | uint32_t sample_size, |
239 | | uint32_t fragment_starting_num, |
240 | | uint16_t fragments_in_submessage, |
241 | | bool /*was_decoded*/) |
242 | 0 | { |
243 | 0 | auto process_message = [&change, sample_size, fragment_starting_num, fragments_in_submessage]( |
244 | 0 | BaseReader* reader) |
245 | 0 | { |
246 | 0 | reader->process_data_frag_msg(&change, sample_size, fragment_starting_num, fragments_in_submessage); |
247 | 0 | }; |
248 | |
|
249 | 0 | findAllReaders(reader_id, process_message); |
250 | 0 | } |
251 | | |
252 | | void MessageReceiver::associateEndpoint( |
253 | | Endpoint* to_add) |
254 | 0 | { |
255 | 0 | std::lock_guard<eprosima::shared_mutex> guard(mtx_); |
256 | 0 | if (to_add->getAttributes().endpointKind == WRITER) |
257 | 0 | { |
258 | 0 | const auto writer = BaseWriter::downcast(to_add); |
259 | 0 | for (const auto& it : associated_writers_) |
260 | 0 | { |
261 | 0 | if (it == writer) |
262 | 0 | { |
263 | 0 | return; |
264 | 0 | } |
265 | 0 | } |
266 | | |
267 | 0 | associated_writers_.push_back(writer); |
268 | 0 | } |
269 | 0 | else |
270 | 0 | { |
271 | 0 | const auto reader = BaseReader::downcast(to_add); |
272 | 0 | const auto entityId = reader->getGuid().entityId; |
273 | | // search for set of readers by entity ID |
274 | 0 | const auto readers = associated_readers_.find(entityId); |
275 | 0 | if (readers == associated_readers_.end()) |
276 | 0 | { |
277 | 0 | auto vec = std::vector<BaseReader*>(); |
278 | 0 | vec.push_back(reader); |
279 | 0 | associated_readers_.emplace(entityId, vec); |
280 | 0 | } |
281 | 0 | else |
282 | 0 | { |
283 | 0 | for (const auto& it : readers->second) |
284 | 0 | { |
285 | 0 | if (it == reader) |
286 | 0 | { |
287 | 0 | return; |
288 | 0 | } |
289 | 0 | } |
290 | | |
291 | 0 | readers->second.push_back(reader); |
292 | 0 | } |
293 | 0 | } |
294 | 0 | } |
295 | | |
296 | | void MessageReceiver::removeEndpoint( |
297 | | Endpoint* to_remove) |
298 | 0 | { |
299 | 0 | std::lock_guard<eprosima::shared_mutex> guard(mtx_); |
300 | |
|
301 | 0 | if (to_remove->getAttributes().endpointKind == WRITER) |
302 | 0 | { |
303 | 0 | auto* var = dynamic_cast<BaseWriter*>(to_remove); |
304 | 0 | for (auto it = associated_writers_.begin(); it != associated_writers_.end(); ++it) |
305 | 0 | { |
306 | 0 | if (*it == var) |
307 | 0 | { |
308 | 0 | associated_writers_.erase(it); |
309 | 0 | break; |
310 | 0 | } |
311 | 0 | } |
312 | 0 | } |
313 | 0 | else |
314 | 0 | { |
315 | 0 | auto readers = associated_readers_.find(to_remove->getGuid().entityId); |
316 | 0 | if (readers != associated_readers_.end()) |
317 | 0 | { |
318 | 0 | auto* var = BaseReader::downcast(to_remove); |
319 | 0 | for (auto it = readers->second.begin(); it != readers->second.end(); ++it) |
320 | 0 | { |
321 | 0 | if (*it == var) |
322 | 0 | { |
323 | 0 | readers->second.erase(it); |
324 | 0 | if (readers->second.empty()) |
325 | 0 | { |
326 | 0 | associated_readers_.erase(readers); |
327 | 0 | } |
328 | 0 | break; |
329 | 0 | } |
330 | 0 | } |
331 | 0 | } |
332 | 0 | } |
333 | 0 | } |
334 | | |
335 | | void MessageReceiver::reset() |
336 | 1.73k | { |
337 | 1.73k | source_version_ = c_ProtocolVersion; |
338 | 1.73k | source_vendor_id_ = c_VendorId_Unknown; |
339 | 1.73k | source_guid_prefix_ = c_GuidPrefix_Unknown; |
340 | 1.73k | dest_guid_prefix_ = c_GuidPrefix_Unknown; |
341 | 1.73k | have_timestamp_ = false; |
342 | 1.73k | timestamp_ = dds::c_TimeInvalid; |
343 | 1.73k | } |
344 | | |
345 | | void MessageReceiver::processCDRMsg( |
346 | | const Locator_t& source_locator, |
347 | | const Locator_t& reception_locator, |
348 | | CDRMessage_t* msg) |
349 | 1.73k | { |
350 | 1.73k | if (msg->length < RTPSMESSAGE_HEADER_SIZE) |
351 | 0 | { |
352 | 0 | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, IDSTRING "Received message too short, ignoring"); |
353 | 0 | return; |
354 | 0 | } |
355 | | |
356 | 1.73k | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
357 | 1.73k | GuidPrefix_t participantGuidPrefix; |
358 | | #else |
359 | | GuidPrefix_t participantGuidPrefix {participant_->getGuid().guidPrefix}; |
360 | | #endif // ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
361 | | |
362 | | #if HAVE_SECURITY && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
363 | | security::SecurityManager& security = participant_->security_manager(); |
364 | | CDRMessage_t* auxiliary_buffer = &crypto_msg_; |
365 | | int decode_ret {0}; |
366 | | #endif // if HAVE_SECURITY && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
367 | | |
368 | 1.73k | bool ignore_submessages {false}; |
369 | | |
370 | 1.73k | { |
371 | 1.73k | std::lock_guard<eprosima::shared_mutex> guard(mtx_); |
372 | | |
373 | 1.73k | reset(); |
374 | | |
375 | 1.73k | dest_guid_prefix_ = participantGuidPrefix; |
376 | | |
377 | 1.73k | msg->pos = 0; //Start reading at 0 |
378 | | |
379 | | //Once everything is set, the reading begins: |
380 | 1.73k | if (!checkRTPSHeader(msg)) |
381 | 66 | { |
382 | 66 | return; |
383 | 66 | } |
384 | | |
385 | | #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
386 | | ignore_submessages = participant_->is_participant_ignored(source_guid_prefix_); |
387 | | #endif // if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
388 | | |
389 | 1.67k | if (!ignore_submessages) |
390 | 1.67k | { |
391 | 1.67k | notify_network_statistics(source_locator, reception_locator, msg); |
392 | 1.67k | } |
393 | | |
394 | | #if HAVE_SECURITY && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
395 | | decode_ret = security.decode_rtps_message(*msg, *auxiliary_buffer, source_guid_prefix_); |
396 | | |
397 | | if (decode_ret < 0) |
398 | | { |
399 | | return; |
400 | | } |
401 | | |
402 | | if (decode_ret == 0) |
403 | | { |
404 | | // The original CDRMessage buffer (msg) now points to the proprietary temporary buffer crypto_msg_. |
405 | | // The auxiliary buffer now points to the propietary temporary buffer crypto_submsg_. |
406 | | // This way each decoded sub-message will be processed using the crypto_submsg_ buffer. |
407 | | msg = auxiliary_buffer; |
408 | | auxiliary_buffer = &crypto_submsg_; |
409 | | } |
410 | | #endif // if HAVE_SECURITY && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
411 | 1.67k | } |
412 | | |
413 | | // Loop until there are no more submessages |
414 | | // Each submessage processing method choses the lock kind required |
415 | 0 | bool valid; |
416 | 1.67k | SubmessageHeader_t submsgh; //Current submessage header |
417 | | |
418 | 21.4k | while (msg->pos < msg->length)// end of the message |
419 | 21.2k | { |
420 | 21.2k | CDRMessage_t* submessage = msg; |
421 | | |
422 | 21.2k | bool current_message_was_decoded {false}; |
423 | | |
424 | | #if HAVE_SECURITY && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
425 | | decode_ret = security.decode_rtps_submessage(*msg, *auxiliary_buffer, source_guid_prefix_); |
426 | | |
427 | | if (decode_ret < 0) |
428 | | { |
429 | | return; |
430 | | } |
431 | | |
432 | | if (decode_ret == 0) |
433 | | { |
434 | | current_message_was_decoded = true; |
435 | | submessage = auxiliary_buffer; |
436 | | } |
437 | | #endif // if HAVE_SECURITY && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
438 | | |
439 | | //First 4 bytes must contain: ID | flags | octets to next header |
440 | 21.2k | if (!readSubmessageHeader(submessage, &submsgh)) |
441 | 270 | { |
442 | 270 | return; |
443 | 270 | } |
444 | | |
445 | 20.9k | valid = true; |
446 | 20.9k | uint32_t next_msg_pos {submessage->pos}; |
447 | 20.9k | next_msg_pos += (submsgh.submessageLength + 3u) & ~3u; |
448 | | |
449 | | // We ignore submessage if the source participant is to be ignored, unless the submessage king is INFO_SRC |
450 | | // which triggers a reevaluation of the flag. |
451 | 20.9k | bool ignore_current_submessage = ignore_submessages && submsgh.submessageId != INFO_SRC; |
452 | | |
453 | 20.9k | if (!ignore_current_submessage) |
454 | 20.9k | { |
455 | 20.9k | switch (submsgh.submessageId) |
456 | 20.9k | { |
457 | 277 | case DATA: |
458 | 277 | { |
459 | 277 | if (dest_guid_prefix_ != participantGuidPrefix) |
460 | 251 | { |
461 | 251 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Data Submsg ignored, DST is another RTPSParticipant"); |
462 | 251 | } |
463 | 26 | else |
464 | 26 | { |
465 | 26 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Data Submsg received, processing."); |
466 | 26 | EntityId_t writerId {c_EntityId_Unknown}; |
467 | 26 | valid = proc_Submsg_Data(submessage, &submsgh, writerId, current_message_was_decoded); |
468 | | #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
469 | | if (valid && writerId == c_EntityId_SPDPWriter) |
470 | | { |
471 | | ignore_submessages = participant_->is_participant_ignored(source_guid_prefix_); |
472 | | } |
473 | | #endif // if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
474 | | |
475 | 26 | } |
476 | 277 | break; |
477 | 0 | } |
478 | 236 | case DATA_FRAG: |
479 | 236 | if (dest_guid_prefix_ != participantGuidPrefix) |
480 | 209 | { |
481 | 209 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, |
482 | 209 | IDSTRING "DataFrag Submsg ignored, DST is another RTPSParticipant"); |
483 | 209 | } |
484 | 27 | else |
485 | 27 | { |
486 | 27 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "DataFrag Submsg received, processing."); |
487 | 27 | valid = proc_Submsg_DataFrag(submessage, &submsgh, current_message_was_decoded); |
488 | 27 | } |
489 | 236 | break; |
490 | 6.16k | case GAP: |
491 | 6.16k | { |
492 | 6.16k | if (dest_guid_prefix_ != participantGuidPrefix) |
493 | 269 | { |
494 | 269 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, |
495 | 269 | IDSTRING "Gap Submsg ignored, DST is another RTPSParticipant..."); |
496 | 269 | } |
497 | 5.89k | else |
498 | 5.89k | { |
499 | 5.89k | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Gap Submsg received, processing..."); |
500 | 5.89k | valid = proc_Submsg_Gap(submessage, &submsgh, current_message_was_decoded); |
501 | 5.89k | } |
502 | 6.16k | break; |
503 | 0 | } |
504 | 534 | case ACKNACK: |
505 | 534 | { |
506 | 534 | if (dest_guid_prefix_ != participantGuidPrefix) |
507 | 204 | { |
508 | 204 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, |
509 | 204 | IDSTRING "Acknack Submsg ignored, DST is another RTPSParticipant..."); |
510 | 204 | } |
511 | 330 | else |
512 | 330 | { |
513 | 330 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Acknack Submsg received, processing..."); |
514 | 330 | valid = proc_Submsg_Acknack(submessage, &submsgh, current_message_was_decoded); |
515 | 330 | } |
516 | 534 | break; |
517 | 0 | } |
518 | 341 | case NACK_FRAG: |
519 | 341 | { |
520 | 341 | if (dest_guid_prefix_ != participantGuidPrefix) |
521 | 204 | { |
522 | 204 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, |
523 | 204 | IDSTRING "NackFrag Submsg ignored, DST is another RTPSParticipant..."); |
524 | 204 | } |
525 | 137 | else |
526 | 137 | { |
527 | 137 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "NackFrag Submsg received, processing..."); |
528 | 137 | valid = proc_Submsg_NackFrag(submessage, &submsgh, current_message_was_decoded); |
529 | 137 | } |
530 | 341 | break; |
531 | 0 | } |
532 | 3.31k | case HEARTBEAT: |
533 | 3.31k | { |
534 | 3.31k | if (dest_guid_prefix_ != participantGuidPrefix) |
535 | 211 | { |
536 | 211 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "HB Submsg ignored, DST is another RTPSParticipant..."); |
537 | 211 | } |
538 | 3.10k | else |
539 | 3.10k | { |
540 | 3.10k | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Heartbeat Submsg received, processing..."); |
541 | 3.10k | valid = proc_Submsg_Heartbeat(submessage, &submsgh, current_message_was_decoded); |
542 | 3.10k | } |
543 | 3.31k | break; |
544 | 0 | } |
545 | 94 | case HEARTBEAT_FRAG: |
546 | 94 | { |
547 | 94 | if (dest_guid_prefix_ != participantGuidPrefix) |
548 | 10 | { |
549 | 10 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, |
550 | 10 | IDSTRING "HBFrag Submsg ignored, DST is another RTPSParticipant..."); |
551 | 10 | } |
552 | 84 | else |
553 | 84 | { |
554 | 84 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "HeartbeatFrag Submsg received, processing..."); |
555 | 84 | valid = proc_Submsg_HeartbeatFrag(submessage, &submsgh, current_message_was_decoded); |
556 | 84 | } |
557 | 94 | break; |
558 | 0 | } |
559 | 1.31k | case PAD: |
560 | 1.31k | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, IDSTRING "PAD messages not yet implemented, ignoring"); |
561 | 1.31k | break; |
562 | 1.56k | case INFO_DST: |
563 | 1.56k | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "InfoDST message received, processing..."); |
564 | 1.56k | valid = proc_Submsg_InfoDST(submessage, &submsgh); |
565 | 1.56k | break; |
566 | 921 | case INFO_SRC: |
567 | 921 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "InfoSRC message received, processing..."); |
568 | 921 | valid = proc_Submsg_InfoSRC(submessage, &submsgh); |
569 | | #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
570 | | ignore_submessages = participant_->is_participant_ignored(source_guid_prefix_); |
571 | | #endif // if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
572 | 921 | break; |
573 | 5.00k | case INFO_TS: |
574 | 5.00k | { |
575 | 5.00k | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "InfoTS Submsg received, processing..."); |
576 | 5.00k | valid = proc_Submsg_InfoTS(submessage, &submsgh); |
577 | 5.00k | break; |
578 | 0 | } |
579 | 1 | case INFO_REPLY: |
580 | 1 | break; |
581 | 1 | case INFO_REPLY_IP4: |
582 | 1 | break; |
583 | 1.20k | default: |
584 | 1.20k | break; |
585 | 20.9k | } |
586 | 20.9k | } |
587 | 20.9k | if (!valid || submsgh.is_last) |
588 | 1.17k | { |
589 | 1.17k | break; |
590 | 1.17k | } |
591 | | |
592 | 19.8k | submessage->pos = next_msg_pos; |
593 | 19.8k | } |
594 | | |
595 | | #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
596 | | participant_->assert_remote_participant_liveliness(source_guid_prefix_); |
597 | | #endif // if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
598 | 1.67k | } |
599 | | |
600 | | bool MessageReceiver::checkRTPSHeader( |
601 | | CDRMessage_t* msg) |
602 | 1.73k | { |
603 | | //check and proccess the RTPS Header |
604 | 1.73k | if (msg->buffer[0] != 'R' || msg->buffer[1] != 'T' || |
605 | 1.71k | msg->buffer[2] != 'P' || msg->buffer[3] != 'S') |
606 | 51 | { |
607 | 51 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Msg received with no RTPS in header, ignoring..."); |
608 | 51 | return false; |
609 | 51 | } |
610 | | |
611 | 1.68k | msg->pos += 4; |
612 | | |
613 | | //CHECK AND SET protocol version |
614 | 1.68k | if (msg->buffer[msg->pos] == c_ProtocolVersion.m_major) |
615 | 1.67k | { |
616 | 1.67k | source_version_.m_major = msg->buffer[msg->pos]; |
617 | 1.67k | msg->pos++; |
618 | 1.67k | source_version_.m_minor = msg->buffer[msg->pos]; |
619 | 1.67k | msg->pos++; |
620 | 1.67k | } |
621 | 15 | else |
622 | 15 | { |
623 | 15 | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, IDSTRING "Major RTPS Version not supported"); |
624 | 15 | return false; |
625 | 15 | } |
626 | | |
627 | | //Set source vendor id |
628 | 1.67k | source_vendor_id_[0] = msg->buffer[msg->pos]; |
629 | 1.67k | msg->pos++; |
630 | 1.67k | source_vendor_id_[1] = msg->buffer[msg->pos]; |
631 | 1.67k | msg->pos++; |
632 | | //set source guid prefix |
633 | 1.67k | CDRMessage::readData(msg, source_guid_prefix_.value, GuidPrefix_t::size); |
634 | 1.67k | have_timestamp_ = false; |
635 | 1.67k | return true; |
636 | 1.68k | } |
637 | | |
638 | | bool MessageReceiver::readSubmessageHeader( |
639 | | CDRMessage_t* msg, |
640 | | SubmessageHeader_t* smh) const |
641 | 31.3k | { |
642 | 31.3k | if (msg->length - msg->pos < 4) |
643 | 92 | { |
644 | 92 | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, IDSTRING "SubmessageHeader too short"); |
645 | 92 | return false; |
646 | 92 | } |
647 | | |
648 | 31.2k | smh->submessageId = msg->buffer[msg->pos]; |
649 | 31.2k | msg->pos++; |
650 | 31.2k | smh->flags = msg->buffer[msg->pos]; |
651 | 31.2k | msg->pos++; |
652 | | |
653 | | //Set endianness of message |
654 | 31.2k | msg->msg_endian = (smh->flags & BIT(0)) != 0 ? LITTLEEND : BIGEND; |
655 | 31.2k | uint16_t length {0}; |
656 | 31.2k | CDRMessage::readUInt16(msg, &length); |
657 | 31.2k | if (msg->pos + length > msg->length) |
658 | 312 | { |
659 | 312 | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, IDSTRING "SubMsg of invalid length (" << length |
660 | 312 | << |
661 | 312 | ") with current msg position/length (" << msg->pos << "/" << msg->length << ")"); |
662 | 312 | return false; |
663 | 312 | } |
664 | | |
665 | 30.9k | if ((length == 0) && (smh->submessageId != INFO_TS) && (smh->submessageId != PAD)) |
666 | 705 | { |
667 | | // THIS IS THE LAST SUBMESSAGE |
668 | 705 | smh->submessageLength = msg->length - msg->pos; |
669 | 705 | smh->is_last = true; |
670 | 705 | } |
671 | 30.2k | else |
672 | 30.2k | { |
673 | 30.2k | smh->submessageLength = length; |
674 | 30.2k | smh->is_last = false; |
675 | 30.2k | } |
676 | | |
677 | 30.9k | return true; |
678 | 31.2k | } |
679 | | |
680 | | bool MessageReceiver::willAReaderAcceptMsgDirectedTo( |
681 | | const EntityId_t& readerID, |
682 | | BaseReader*& first_reader) const |
683 | 28 | { |
684 | 28 | first_reader = nullptr; |
685 | 28 | if (associated_readers_.empty()) |
686 | 28 | { |
687 | 28 | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, IDSTRING "Data received when NO readers are listening"); |
688 | 28 | return false; |
689 | 28 | } |
690 | | |
691 | 0 | if (readerID != c_EntityId_Unknown) |
692 | 0 | { |
693 | 0 | const auto readers = associated_readers_.find(readerID); |
694 | 0 | if (readers != associated_readers_.end()) |
695 | 0 | { |
696 | 0 | first_reader = readers->second.front(); |
697 | 0 | return true; |
698 | 0 | } |
699 | 0 | } |
700 | 0 | else |
701 | 0 | { |
702 | 0 | for (const auto& readers : associated_readers_) |
703 | 0 | { |
704 | 0 | if (0 < readers.second.size()) |
705 | 0 | { |
706 | 0 | first_reader = readers.second.front(); |
707 | 0 | return true; |
708 | 0 | } |
709 | 0 | } |
710 | 0 | } |
711 | | |
712 | 0 | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, IDSTRING "No Reader accepts this message (directed to: " << readerID << ")"); |
713 | 0 | return false; |
714 | 0 | } |
715 | | |
716 | | template<typename Functor> |
717 | | void MessageReceiver::findAllReaders( |
718 | | const EntityId_t& readerID, |
719 | | const Functor& callback) const |
720 | 8.58k | { |
721 | 8.58k | if (readerID != c_EntityId_Unknown) |
722 | 5.88k | { |
723 | 5.88k | const auto readers = associated_readers_.find(readerID); |
724 | 5.88k | if (readers != associated_readers_.end()) |
725 | 0 | { |
726 | 0 | for (const auto& it : readers->second) |
727 | 0 | { |
728 | 0 | callback(it); |
729 | 0 | } |
730 | 0 | } |
731 | 5.88k | } |
732 | 2.69k | else |
733 | 2.69k | { |
734 | 2.69k | for (const auto& readers : associated_readers_) |
735 | 0 | { |
736 | 0 | for (const auto& it : readers.second) |
737 | 0 | { |
738 | 0 | callback(it); |
739 | 0 | } |
740 | 0 | } |
741 | 2.69k | } |
742 | 8.58k | } Unexecuted instantiation: MessageReceiver.cpp:void eprosima::fastdds::rtps::MessageReceiver::findAllReaders<eprosima::fastdds::rtps::MessageReceiver::process_data_message_without_security(eprosima::fastdds::rtps::EntityId_t const&, eprosima::fastdds::rtps::CacheChange_t&, bool)::$_0>(eprosima::fastdds::rtps::EntityId_t const&, eprosima::fastdds::rtps::MessageReceiver::process_data_message_without_security(eprosima::fastdds::rtps::EntityId_t const&, eprosima::fastdds::rtps::CacheChange_t&, bool)::$_0 const&) const Unexecuted instantiation: MessageReceiver.cpp:void eprosima::fastdds::rtps::MessageReceiver::findAllReaders<eprosima::fastdds::rtps::MessageReceiver::process_data_fragment_message_without_security(eprosima::fastdds::rtps::EntityId_t const&, eprosima::fastdds::rtps::CacheChange_t&, unsigned int, unsigned int, unsigned short, bool)::$_0>(eprosima::fastdds::rtps::EntityId_t const&, eprosima::fastdds::rtps::MessageReceiver::process_data_fragment_message_without_security(eprosima::fastdds::rtps::EntityId_t const&, eprosima::fastdds::rtps::CacheChange_t&, unsigned int, unsigned int, unsigned short, bool)::$_0 const&) const MessageReceiver.cpp:void eprosima::fastdds::rtps::MessageReceiver::findAllReaders<eprosima::fastdds::rtps::MessageReceiver::proc_Submsg_Heartbeat(eprosima::fastdds::rtps::CDRMessage_t*, eprosima::fastdds::rtps::SubmessageHeader_t*, bool) const::$_0>(eprosima::fastdds::rtps::EntityId_t const&, eprosima::fastdds::rtps::MessageReceiver::proc_Submsg_Heartbeat(eprosima::fastdds::rtps::CDRMessage_t*, eprosima::fastdds::rtps::SubmessageHeader_t*, bool) const::$_0 const&) const Line | Count | Source | 720 | 2.80k | { | 721 | 2.80k | if (readerID != c_EntityId_Unknown) | 722 | 1.37k | { | 723 | 1.37k | const auto readers = associated_readers_.find(readerID); | 724 | 1.37k | if (readers != associated_readers_.end()) | 725 | 0 | { | 726 | 0 | for (const auto& it : readers->second) | 727 | 0 | { | 728 | 0 | callback(it); | 729 | 0 | } | 730 | 0 | } | 731 | 1.37k | } | 732 | 1.43k | else | 733 | 1.43k | { | 734 | 1.43k | for (const auto& readers : associated_readers_) | 735 | 0 | { | 736 | 0 | for (const auto& it : readers.second) | 737 | 0 | { | 738 | 0 | callback(it); | 739 | 0 | } | 740 | 0 | } | 741 | 1.43k | } | 742 | 2.80k | } |
MessageReceiver.cpp:void eprosima::fastdds::rtps::MessageReceiver::findAllReaders<eprosima::fastdds::rtps::MessageReceiver::proc_Submsg_Gap(eprosima::fastdds::rtps::CDRMessage_t*, eprosima::fastdds::rtps::SubmessageHeader_t*, bool) const::$_0>(eprosima::fastdds::rtps::EntityId_t const&, eprosima::fastdds::rtps::MessageReceiver::proc_Submsg_Gap(eprosima::fastdds::rtps::CDRMessage_t*, eprosima::fastdds::rtps::SubmessageHeader_t*, bool) const::$_0 const&) const Line | Count | Source | 720 | 5.77k | { | 721 | 5.77k | if (readerID != c_EntityId_Unknown) | 722 | 4.51k | { | 723 | 4.51k | const auto readers = associated_readers_.find(readerID); | 724 | 4.51k | if (readers != associated_readers_.end()) | 725 | 0 | { | 726 | 0 | for (const auto& it : readers->second) | 727 | 0 | { | 728 | 0 | callback(it); | 729 | 0 | } | 730 | 0 | } | 731 | 4.51k | } | 732 | 1.26k | else | 733 | 1.26k | { | 734 | 1.26k | for (const auto& readers : associated_readers_) | 735 | 0 | { | 736 | 0 | for (const auto& it : readers.second) | 737 | 0 | { | 738 | 0 | callback(it); | 739 | 0 | } | 740 | 0 | } | 741 | 1.26k | } | 742 | 5.77k | } |
|
743 | | |
744 | | bool MessageReceiver::proc_Submsg_Data( |
745 | | CDRMessage_t* msg, |
746 | | SubmessageHeader_t* smh, |
747 | | EntityId_t& writerID, |
748 | | bool was_decoded) const |
749 | 26 | { |
750 | 26 | eprosima::shared_lock<eprosima::shared_mutex> guard(mtx_); |
751 | | |
752 | | //READ and PROCESS |
753 | 26 | if (smh->submessageLength < RTPSMESSAGE_DATA_MIN_LENGTH) |
754 | 9 | { |
755 | 9 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Too short submessage received, ignoring"); |
756 | 9 | return false; |
757 | 9 | } |
758 | | //Fill flags bool values |
759 | 17 | bool endiannessFlag {(smh->flags & BIT(0)) != 0}; |
760 | 17 | bool inlineQosFlag {(smh->flags & BIT(1)) != 0}; |
761 | 17 | bool dataFlag {(smh->flags & BIT(2)) != 0}; |
762 | 17 | bool keyFlag {(smh->flags & BIT(3)) != 0}; |
763 | 17 | if (keyFlag && dataFlag) |
764 | 5 | { |
765 | 5 | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, IDSTRING "Message received with Data and Key Flag set, ignoring"); |
766 | 5 | return false; |
767 | 5 | } |
768 | | |
769 | | //Assign message endianness |
770 | 12 | if (endiannessFlag) |
771 | 7 | { |
772 | 7 | msg->msg_endian = LITTLEEND; |
773 | 7 | } |
774 | 5 | else |
775 | 5 | { |
776 | 5 | msg->msg_endian = BIGEND; |
777 | 5 | } |
778 | | |
779 | | //Extra flags don't matter now. Avoid those bytes |
780 | 12 | msg->pos += 2; |
781 | | |
782 | 12 | bool valid {true}; |
783 | 12 | uint16_t octetsToInlineQos {0}; |
784 | 12 | valid &= CDRMessage::readUInt16(msg, &octetsToInlineQos); //it should be 16 in this implementation |
785 | | |
786 | | //reader and writer ID |
787 | 12 | BaseReader* first_reader = nullptr; |
788 | 12 | EntityId_t readerID; |
789 | 12 | valid &= CDRMessage::readEntityId(msg, &readerID); |
790 | | |
791 | | //WE KNOW THE READER THAT THE MESSAGE IS DIRECTED TO SO WE LOOK FOR IT: |
792 | 12 | if (!willAReaderAcceptMsgDirectedTo(readerID, first_reader)) |
793 | 12 | { |
794 | 12 | return false; |
795 | 12 | } |
796 | | |
797 | | //FOUND THE READER. |
798 | | //We ask the reader for a cachechange to store the information. |
799 | 0 | CacheChange_t ch; |
800 | 0 | ch.kind = ALIVE; |
801 | 0 | ch.writerGUID.guidPrefix = source_guid_prefix_; |
802 | 0 | valid &= CDRMessage::readEntityId(msg, &ch.writerGUID.entityId); |
803 | |
|
804 | 0 | writerID = ch.writerGUID.entityId; |
805 | | |
806 | | //Get sequence number |
807 | 0 | valid &= CDRMessage::readSequenceNumber(msg, &ch.sequenceNumber); |
808 | |
|
809 | 0 | if (!valid) |
810 | 0 | { |
811 | 0 | return false; |
812 | 0 | } |
813 | | |
814 | 0 | if (ch.sequenceNumber <= SequenceNumber_t()) |
815 | 0 | { |
816 | 0 | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, IDSTRING "Invalid message received, bad sequence Number"); |
817 | 0 | return false; |
818 | 0 | } |
819 | | |
820 | | // Get the vendor id |
821 | 0 | ch.vendor_id = source_vendor_id_; |
822 | | |
823 | | //Jump ahead if more parameters are before inlineQos (not in this version, maybe if further minor versions.) |
824 | 0 | if (octetsToInlineQos > RTPSMESSAGE_OCTETSTOINLINEQOS_DATASUBMSG) |
825 | 0 | { |
826 | 0 | msg->pos += (octetsToInlineQos - RTPSMESSAGE_OCTETSTOINLINEQOS_DATASUBMSG); |
827 | 0 | if (msg->pos > msg->length) |
828 | 0 | { |
829 | 0 | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, |
830 | 0 | IDSTRING "Invalid jump through msg, msg->pos " << msg->pos << " > msg->length " << msg->length); |
831 | 0 | return false; |
832 | 0 | } |
833 | 0 | } |
834 | | |
835 | 0 | uint32_t inlineQosSize {0}; |
836 | |
|
837 | 0 | if (inlineQosFlag) |
838 | 0 | { |
839 | 0 | if (!ParameterList::updateCacheChangeFromInlineQos(ch, msg, inlineQosSize)) |
840 | 0 | { |
841 | 0 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "SubMessage Data ERROR, Inline Qos ParameterList error"); |
842 | 0 | return false; |
843 | 0 | } |
844 | 0 | ch.inline_qos.data = &msg->buffer[msg->pos - inlineQosSize]; |
845 | 0 | ch.inline_qos.max_size = inlineQosSize; |
846 | 0 | ch.inline_qos.length = inlineQosSize; |
847 | 0 | ch.inline_qos.encapsulation = endiannessFlag ? PL_CDR_LE : PL_CDR_BE; |
848 | 0 | ch.inline_qos.pos = 0; |
849 | 0 | } |
850 | | |
851 | 0 | if (dataFlag || keyFlag) |
852 | 0 | { |
853 | 0 | uint32_t payload_size; |
854 | 0 | const uint32_t submsg_no_payload_size = |
855 | 0 | RTPSMESSAGE_DATA_EXTRA_INLINEQOS_SIZE + octetsToInlineQos + inlineQosSize; |
856 | | |
857 | | // Prevent integer overflow of variable payload_size |
858 | 0 | if (smh->submessageLength < submsg_no_payload_size) |
859 | 0 | { |
860 | 0 | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, IDSTRING "Serialized Payload avoided overflow " |
861 | 0 | "(" << smh->submessageLength << "/" << submsg_no_payload_size << ")"); |
862 | 0 | ch.serializedPayload.data = nullptr; |
863 | 0 | ch.inline_qos.data = nullptr; |
864 | 0 | return false; |
865 | 0 | } |
866 | | |
867 | 0 | payload_size = smh->submessageLength - submsg_no_payload_size; |
868 | 0 | uint32_t next_pos {msg->pos + payload_size}; |
869 | 0 | if (msg->length >= next_pos && payload_size > 0) |
870 | 0 | { |
871 | 0 | ch.serializedPayload.data = &msg->buffer[msg->pos]; |
872 | 0 | ch.serializedPayload.length = payload_size; |
873 | 0 | ch.serializedPayload.max_size = payload_size; |
874 | 0 | ch.serializedPayload.is_serialized_key = keyFlag; |
875 | 0 | msg->pos = next_pos; |
876 | 0 | } |
877 | 0 | else |
878 | 0 | { |
879 | 0 | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, |
880 | 0 | IDSTRING "Serialized Payload value invalid or larger than maximum allowed size" |
881 | 0 | "(" << payload_size << "/" << (msg->length - msg->pos) << ")"); |
882 | 0 | ch.serializedPayload.data = nullptr; |
883 | 0 | ch.inline_qos.data = nullptr; |
884 | 0 | return false; |
885 | 0 | } |
886 | 0 | } |
887 | | |
888 | | // Set sourcetimestamp |
889 | 0 | if (have_timestamp_) |
890 | 0 | { |
891 | 0 | ch.sourceTimestamp = timestamp_; |
892 | 0 | } |
893 | |
|
894 | 0 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "from Writer " << ch.writerGUID << "; possible Reader entities: " |
895 | 0 | << associated_readers_.size()); |
896 | | |
897 | | //Look for the correct reader to add the change |
898 | 0 | process_data_message_function_(readerID, ch, was_decoded); |
899 | |
|
900 | 0 | IPayloadPool* payload_pool = ch.serializedPayload.payload_owner; |
901 | 0 | if (payload_pool) |
902 | 0 | { |
903 | 0 | payload_pool->release_payload(ch.serializedPayload); |
904 | 0 | } |
905 | | |
906 | | //TODO(Ricardo) If an exception is thrown (ex, by fastcdr), these lines are not executed -> segmentation fault |
907 | 0 | ch.serializedPayload.data = nullptr; |
908 | 0 | ch.inline_qos.data = nullptr; |
909 | |
|
910 | 0 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Sub Message DATA processed"); |
911 | 0 | return true; |
912 | 0 | } |
913 | | |
914 | | bool MessageReceiver::proc_Submsg_DataFrag( |
915 | | CDRMessage_t* msg, |
916 | | SubmessageHeader_t* smh, |
917 | | bool was_decoded) const |
918 | 27 | { |
919 | 27 | eprosima::shared_lock<eprosima::shared_mutex> guard(mtx_); |
920 | | |
921 | | //READ and PROCESS |
922 | 27 | if (smh->submessageLength < RTPSMESSAGE_DATA_MIN_LENGTH) |
923 | 11 | { |
924 | 11 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Too short submessage received, ignoring"); |
925 | 11 | return false; |
926 | 11 | } |
927 | | |
928 | | //Fill flags bool values |
929 | 16 | bool endiannessFlag {(smh->flags & BIT(0)) != 0}; |
930 | 16 | bool inlineQosFlag {(smh->flags & BIT(1)) != 0}; |
931 | 16 | bool keyFlag {(smh->flags & BIT(2)) != 0}; |
932 | | |
933 | | //Assign message endianness |
934 | 16 | if (endiannessFlag) |
935 | 7 | { |
936 | 7 | msg->msg_endian = LITTLEEND; |
937 | 7 | } |
938 | 9 | else |
939 | 9 | { |
940 | 9 | msg->msg_endian = BIGEND; |
941 | 9 | } |
942 | | |
943 | | //Extra flags don't matter now. Avoid those bytes |
944 | 16 | msg->pos += 2; |
945 | | |
946 | 16 | bool valid {true}; |
947 | 16 | uint16_t octetsToInlineQos {0}; |
948 | 16 | valid &= CDRMessage::readUInt16(msg, &octetsToInlineQos); //it should be 16 in this implementation |
949 | | |
950 | | //reader and writer ID |
951 | 16 | BaseReader* first_reader = nullptr; |
952 | 16 | EntityId_t readerID; |
953 | 16 | valid &= CDRMessage::readEntityId(msg, &readerID); |
954 | | |
955 | | //WE KNOW THE READER THAT THE MESSAGE IS DIRECTED TO SO WE LOOK FOR IT: |
956 | 16 | if (!willAReaderAcceptMsgDirectedTo(readerID, first_reader)) |
957 | 16 | { |
958 | 16 | return false; |
959 | 16 | } |
960 | | |
961 | | //FOUND THE READER. |
962 | | //We ask the reader for a cachechange to store the information. |
963 | 0 | CacheChange_t ch; |
964 | 0 | ch.kind = ALIVE; |
965 | 0 | ch.writerGUID.guidPrefix = source_guid_prefix_; |
966 | 0 | valid &= CDRMessage::readEntityId(msg, &ch.writerGUID.entityId); |
967 | | |
968 | | //Get sequence number |
969 | 0 | valid &= CDRMessage::readSequenceNumber(msg, &ch.sequenceNumber); |
970 | |
|
971 | 0 | if (ch.sequenceNumber <= SequenceNumber_t()) |
972 | 0 | { |
973 | 0 | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, IDSTRING "Invalid message received, bad sequence Number"); |
974 | 0 | return false; |
975 | 0 | } |
976 | | |
977 | | // Get the vendor id |
978 | 0 | ch.vendor_id = source_vendor_id_; |
979 | | |
980 | | // READ FRAGMENT NUMBER |
981 | 0 | uint32_t fragmentStartingNum {0}; |
982 | 0 | valid &= CDRMessage::readUInt32(msg, &fragmentStartingNum); |
983 | | |
984 | | // READ FRAGMENTSINSUBMESSAGE |
985 | 0 | uint16_t fragmentsInSubmessage {0}; |
986 | 0 | valid &= CDRMessage::readUInt16(msg, &fragmentsInSubmessage); |
987 | | |
988 | | // READ FRAGMENTSIZE |
989 | 0 | uint16_t fragmentSize {0}; |
990 | 0 | valid &= CDRMessage::readUInt16(msg, &fragmentSize); |
991 | | |
992 | | // READ SAMPLESIZE |
993 | 0 | uint32_t sampleSize {0}; |
994 | 0 | valid &= CDRMessage::readUInt32(msg, &sampleSize); |
995 | |
|
996 | 0 | if (!valid) |
997 | 0 | { |
998 | 0 | return false; |
999 | 0 | } |
1000 | | |
1001 | | //Jump ahead if more parameters are before inlineQos (not in this version, maybe if further minor versions.) |
1002 | 0 | if (octetsToInlineQos > RTPSMESSAGE_OCTETSTOINLINEQOS_DATAFRAGSUBMSG) |
1003 | 0 | { |
1004 | 0 | msg->pos += (octetsToInlineQos - RTPSMESSAGE_OCTETSTOINLINEQOS_DATAFRAGSUBMSG); |
1005 | 0 | if (msg->pos > msg->length) |
1006 | 0 | { |
1007 | 0 | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, |
1008 | 0 | IDSTRING "Invalid jump through msg, msg->pos " << msg->pos << " > msg->length " << msg->length); |
1009 | 0 | return false; |
1010 | 0 | } |
1011 | 0 | } |
1012 | | |
1013 | 0 | uint32_t inlineQosSize {0}; |
1014 | |
|
1015 | 0 | if (inlineQosFlag) |
1016 | 0 | { |
1017 | 0 | if (!ParameterList::updateCacheChangeFromInlineQos(ch, msg, inlineQosSize)) |
1018 | 0 | { |
1019 | 0 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "SubMessage Data ERROR, Inline Qos ParameterList error"); |
1020 | 0 | return false; |
1021 | 0 | } |
1022 | 0 | ch.inline_qos.data = &msg->buffer[msg->pos - inlineQosSize]; |
1023 | 0 | ch.inline_qos.max_size = inlineQosSize; |
1024 | 0 | ch.inline_qos.length = inlineQosSize; |
1025 | 0 | ch.inline_qos.encapsulation = endiannessFlag ? PL_CDR_LE : PL_CDR_BE; |
1026 | 0 | ch.inline_qos.pos = 0; |
1027 | 0 | } |
1028 | | |
1029 | 0 | uint32_t payload_size; |
1030 | 0 | const uint32_t submsg_no_payload_size = RTPSMESSAGE_DATA_EXTRA_INLINEQOS_SIZE + octetsToInlineQos + inlineQosSize; |
1031 | 0 | if (smh->submessageLength < submsg_no_payload_size) |
1032 | 0 | { |
1033 | 0 | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, IDSTRING "Serialized Payload avoided underflow " |
1034 | 0 | "(" << smh->submessageLength << "/" << submsg_no_payload_size << ")"); |
1035 | 0 | ch.serializedPayload.data = nullptr; |
1036 | 0 | ch.inline_qos.data = nullptr; |
1037 | 0 | return false; |
1038 | 0 | } |
1039 | 0 | payload_size = smh->submessageLength - submsg_no_payload_size; |
1040 | | |
1041 | | // Validations??? XXX TODO |
1042 | |
|
1043 | 0 | uint32_t next_pos {msg->pos + payload_size}; |
1044 | 0 | if (msg->length >= next_pos && payload_size > 0) |
1045 | 0 | { |
1046 | 0 | ch.serializedPayload.data = &msg->buffer[msg->pos]; |
1047 | 0 | ch.serializedPayload.length = payload_size; |
1048 | 0 | ch.serializedPayload.max_size = payload_size; |
1049 | 0 | ch.serializedPayload.is_serialized_key = keyFlag; |
1050 | 0 | ch.setFragmentSize(fragmentSize); |
1051 | |
|
1052 | 0 | msg->pos = next_pos; |
1053 | 0 | } |
1054 | 0 | else |
1055 | 0 | { |
1056 | 0 | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, |
1057 | 0 | IDSTRING "Serialized Payload value invalid or larger than maximum allowed size " |
1058 | 0 | "(" << payload_size << "/" << (msg->length - msg->pos) << ")"); |
1059 | 0 | ch.serializedPayload.data = nullptr; |
1060 | 0 | ch.inline_qos.data = nullptr; |
1061 | 0 | return false; |
1062 | 0 | } |
1063 | | |
1064 | | // Set sourcetimestamp |
1065 | 0 | if (have_timestamp_) |
1066 | 0 | { |
1067 | 0 | ch.sourceTimestamp = timestamp_; |
1068 | 0 | } |
1069 | |
|
1070 | 0 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "from Writer " << ch.writerGUID << "; possible Reader entities: " |
1071 | 0 | << associated_readers_.size()); |
1072 | 0 | process_data_fragment_message_function_(readerID, ch, sampleSize, fragmentStartingNum, fragmentsInSubmessage, |
1073 | 0 | was_decoded); |
1074 | 0 | ch.serializedPayload.data = nullptr; |
1075 | 0 | ch.inline_qos.data = nullptr; |
1076 | |
|
1077 | 0 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Sub Message DATA_FRAG processed"); |
1078 | |
|
1079 | 0 | return true; |
1080 | 0 | } |
1081 | | |
1082 | | bool MessageReceiver::proc_Submsg_Heartbeat( |
1083 | | CDRMessage_t* msg, |
1084 | | SubmessageHeader_t* smh, |
1085 | | bool was_decoded) const |
1086 | 3.10k | { |
1087 | 3.10k | eprosima::shared_lock<eprosima::shared_mutex> guard(mtx_); |
1088 | | |
1089 | 3.10k | bool endiannessFlag {(smh->flags & BIT(0)) != 0}; |
1090 | 3.10k | bool finalFlag {(smh->flags & BIT(1)) != 0}; |
1091 | 3.10k | bool livelinessFlag {(smh->flags & BIT(2)) != 0}; |
1092 | | //Assign message endianness |
1093 | 3.10k | if (endiannessFlag) |
1094 | 1.03k | { |
1095 | 1.03k | msg->msg_endian = LITTLEEND; |
1096 | 1.03k | } |
1097 | 2.06k | else |
1098 | 2.06k | { |
1099 | 2.06k | msg->msg_endian = BIGEND; |
1100 | 2.06k | } |
1101 | | |
1102 | 3.10k | GUID_t readerGUID; |
1103 | 3.10k | GUID_t writerGUID; |
1104 | 3.10k | readerGUID.guidPrefix = dest_guid_prefix_; |
1105 | 3.10k | CDRMessage::readEntityId(msg, &readerGUID.entityId); |
1106 | 3.10k | writerGUID.guidPrefix = source_guid_prefix_; |
1107 | 3.10k | CDRMessage::readEntityId(msg, &writerGUID.entityId); |
1108 | 3.10k | SequenceNumber_t firstSN; |
1109 | 3.10k | SequenceNumber_t lastSN; |
1110 | 3.10k | CDRMessage::readSequenceNumber(msg, &firstSN); |
1111 | 3.10k | CDRMessage::readSequenceNumber(msg, &lastSN); |
1112 | | |
1113 | 3.10k | SequenceNumber_t zeroSN; |
1114 | 3.10k | if (firstSN <= zeroSN) |
1115 | 56 | { |
1116 | 56 | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, IDSTRING "Invalid Heartbeat received (" << firstSN << " <= 0), ignoring"); |
1117 | 56 | return false; |
1118 | 56 | } |
1119 | 3.04k | if (lastSN < firstSN && lastSN != firstSN - 1) |
1120 | 208 | { |
1121 | 208 | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, IDSTRING "Invalid Heartbeat received (" << firstSN << ") - (" |
1122 | 208 | << lastSN << "), ignoring"); |
1123 | 208 | return false; |
1124 | 208 | } |
1125 | 2.83k | uint32_t HBCount {0}; |
1126 | 2.83k | if (!CDRMessage::readUInt32(msg, &HBCount)) |
1127 | 32 | { |
1128 | 32 | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, IDSTRING "Unable to read heartbeat count from heartbeat message"); |
1129 | 32 | return false; |
1130 | 32 | } |
1131 | | |
1132 | | //Look for the correct reader and writers: |
1133 | 2.80k | findAllReaders(readerGUID.entityId, |
1134 | 2.80k | [was_decoded, &writerGUID, &HBCount, &firstSN, &lastSN, finalFlag, livelinessFlag, this]( |
1135 | 2.80k | BaseReader* reader) |
1136 | 2.80k | { |
1137 | | // Only used when HAVE_SECURITY is defined |
1138 | 0 | static_cast<void>(was_decoded); |
1139 | | #if HAVE_SECURITY |
1140 | | if (was_decoded || !reader->getAttributes().security_attributes().is_submessage_protected) |
1141 | | #endif // HAVE_SECURITY |
1142 | 0 | { |
1143 | 0 | reader->process_heartbeat_msg(writerGUID, HBCount, firstSN, lastSN, finalFlag, livelinessFlag, |
1144 | 0 | source_vendor_id_); |
1145 | 0 | } |
1146 | 0 | }); |
1147 | | |
1148 | 2.80k | return true; |
1149 | 2.83k | } |
1150 | | |
1151 | | bool MessageReceiver::proc_Submsg_Acknack( |
1152 | | CDRMessage_t* msg, |
1153 | | SubmessageHeader_t* smh, |
1154 | | bool was_decoded) const |
1155 | 330 | { |
1156 | | // Only used when HAVE_SECURITY is defined |
1157 | 330 | static_cast<void>(was_decoded); |
1158 | | |
1159 | 330 | eprosima::shared_lock<eprosima::shared_mutex> guard(mtx_); |
1160 | | |
1161 | 330 | bool endiannessFlag {(smh->flags & BIT(0)) != 0}; |
1162 | 330 | bool finalFlag {(smh->flags & BIT(1)) != 0}; |
1163 | | //Assign message endianness |
1164 | 330 | if (endiannessFlag) |
1165 | 95 | { |
1166 | 95 | msg->msg_endian = LITTLEEND; |
1167 | 95 | } |
1168 | 235 | else |
1169 | 235 | { |
1170 | 235 | msg->msg_endian = BIGEND; |
1171 | 235 | } |
1172 | 330 | GUID_t readerGUID; |
1173 | 330 | GUID_t writerGUID; |
1174 | 330 | readerGUID.guidPrefix = source_guid_prefix_; |
1175 | 330 | CDRMessage::readEntityId(msg, &readerGUID.entityId); |
1176 | 330 | writerGUID.guidPrefix = dest_guid_prefix_; |
1177 | 330 | CDRMessage::readEntityId(msg, &writerGUID.entityId); |
1178 | | |
1179 | 330 | SequenceNumberSet_t SNSet = CDRMessage::readSequenceNumberSet(msg); |
1180 | 330 | uint32_t Ackcount {0}; |
1181 | 330 | if (!CDRMessage::readUInt32(msg, &Ackcount)) |
1182 | 311 | { |
1183 | 311 | EPROSIMA_LOG_WARNING(RTPS_MSG_IN, IDSTRING "Unable to read ackcount from message"); |
1184 | 311 | return false; |
1185 | 311 | } |
1186 | | |
1187 | | //Look for the correct writer to use the acknack |
1188 | 19 | for (BaseWriter* it : associated_writers_) |
1189 | 0 | { |
1190 | | #if HAVE_SECURITY |
1191 | | if (was_decoded || !it->getAttributes().security_attributes().is_submessage_protected) |
1192 | | #endif // HAVE_SECURITY |
1193 | 0 | { |
1194 | 0 | bool result; |
1195 | 0 | if (it->process_acknack(writerGUID, readerGUID, Ackcount, SNSet, finalFlag, result, source_vendor_id_)) |
1196 | 0 | { |
1197 | 0 | if (!result) |
1198 | 0 | { |
1199 | 0 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Acknack msg to NOT stateful writer "); |
1200 | 0 | } |
1201 | 0 | return result; |
1202 | 0 | } |
1203 | 0 | } |
1204 | 0 | } |
1205 | 19 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Acknack msg to UNKNOWN writer (I looked through " |
1206 | 19 | << associated_writers_.size() << " writers in this ListenResource)"); |
1207 | 19 | return false; |
1208 | 19 | } |
1209 | | |
1210 | | bool MessageReceiver::proc_Submsg_Gap( |
1211 | | CDRMessage_t* msg, |
1212 | | SubmessageHeader_t* smh, |
1213 | | bool was_decoded) const |
1214 | 5.89k | { |
1215 | 5.89k | eprosima::shared_lock<eprosima::shared_mutex> guard(mtx_); |
1216 | | |
1217 | 5.89k | bool endiannessFlag {(smh->flags & BIT(0)) != 0}; |
1218 | | //Assign message endianness |
1219 | 5.89k | if (endiannessFlag) |
1220 | 3.12k | { |
1221 | 3.12k | msg->msg_endian = LITTLEEND; |
1222 | 3.12k | } |
1223 | 2.77k | else |
1224 | 2.77k | { |
1225 | 2.77k | msg->msg_endian = BIGEND; |
1226 | 2.77k | } |
1227 | | |
1228 | 5.89k | GUID_t writerGUID; |
1229 | 5.89k | GUID_t readerGUID; |
1230 | 5.89k | readerGUID.guidPrefix = dest_guid_prefix_; |
1231 | 5.89k | CDRMessage::readEntityId(msg, &readerGUID.entityId); |
1232 | 5.89k | writerGUID.guidPrefix = source_guid_prefix_; |
1233 | 5.89k | CDRMessage::readEntityId(msg, &writerGUID.entityId); |
1234 | 5.89k | SequenceNumber_t gapStart; |
1235 | 5.89k | CDRMessage::readSequenceNumber(msg, &gapStart); |
1236 | 5.89k | SequenceNumberSet_t gapList = CDRMessage::readSequenceNumberSet(msg); |
1237 | 5.89k | if (gapStart <= SequenceNumber_t(0, 0)) |
1238 | 120 | { |
1239 | 120 | return false; |
1240 | 120 | } |
1241 | | |
1242 | 5.77k | findAllReaders(readerGUID.entityId, |
1243 | 5.77k | [was_decoded, &writerGUID, &gapStart, &gapList, this](BaseReader* reader) |
1244 | 5.77k | { |
1245 | | // Only used when HAVE_SECURITY is defined |
1246 | 0 | static_cast<void>(was_decoded); |
1247 | | #if HAVE_SECURITY |
1248 | | if (was_decoded || !reader->getAttributes().security_attributes().is_submessage_protected) |
1249 | | #endif // HAVE_SECURITY |
1250 | 0 | { |
1251 | 0 | reader->process_gap_msg(writerGUID, gapStart, gapList, source_vendor_id_); |
1252 | 0 | } |
1253 | 0 | }); |
1254 | | |
1255 | 5.77k | return true; |
1256 | 5.89k | } |
1257 | | |
1258 | | bool MessageReceiver::proc_Submsg_InfoTS( |
1259 | | CDRMessage_t* msg, |
1260 | | SubmessageHeader_t* smh) |
1261 | 5.00k | { |
1262 | 5.00k | std::lock_guard<eprosima::shared_mutex> guard(mtx_); |
1263 | | |
1264 | 5.00k | bool endiannessFlag {(smh->flags & BIT(0)) != 0}; |
1265 | 5.00k | bool timeFlag {(smh->flags & BIT(1)) != 0}; |
1266 | | //Assign message endianness |
1267 | 5.00k | if (endiannessFlag) |
1268 | 2.56k | { |
1269 | 2.56k | msg->msg_endian = LITTLEEND; |
1270 | 2.56k | } |
1271 | 2.44k | else |
1272 | 2.44k | { |
1273 | 2.44k | msg->msg_endian = BIGEND; |
1274 | 2.44k | } |
1275 | 5.00k | if (!timeFlag) |
1276 | 3.82k | { |
1277 | 3.82k | have_timestamp_ = true; |
1278 | 3.82k | CDRMessage::readTimestamp(msg, ×tamp_); |
1279 | 3.82k | } |
1280 | 1.18k | else |
1281 | 1.18k | { |
1282 | 1.18k | have_timestamp_ = false; |
1283 | 1.18k | } |
1284 | | |
1285 | 5.00k | return true; |
1286 | 5.00k | } |
1287 | | |
1288 | | bool MessageReceiver::proc_Submsg_InfoDST( |
1289 | | CDRMessage_t* msg, |
1290 | | SubmessageHeader_t* smh) |
1291 | 1.56k | { |
1292 | 1.56k | std::lock_guard<eprosima::shared_mutex> guard(mtx_); |
1293 | | |
1294 | 1.56k | bool endiannessFlag {(smh->flags & BIT(0)) != 0u}; |
1295 | | //bool timeFlag = smh->flags & BIT(1) ? true : false; |
1296 | | //Assign message endianness |
1297 | 1.56k | if (endiannessFlag) |
1298 | 819 | { |
1299 | 819 | msg->msg_endian = LITTLEEND; |
1300 | 819 | } |
1301 | 750 | else |
1302 | 750 | { |
1303 | 750 | msg->msg_endian = BIGEND; |
1304 | 750 | } |
1305 | 1.56k | GuidPrefix_t guidP; |
1306 | 1.56k | CDRMessage::readData(msg, guidP.value, GuidPrefix_t::size); |
1307 | 1.56k | if (guidP != c_GuidPrefix_Unknown) |
1308 | 1.31k | { |
1309 | 1.31k | dest_guid_prefix_ = guidP; |
1310 | 1.31k | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "DST RTPSParticipant is now: " << dest_guid_prefix_); |
1311 | 1.31k | } |
1312 | 1.56k | return true; |
1313 | 1.56k | } |
1314 | | |
1315 | | bool MessageReceiver::proc_Submsg_InfoSRC( |
1316 | | CDRMessage_t* msg, |
1317 | | SubmessageHeader_t* smh) |
1318 | 921 | { |
1319 | 921 | std::lock_guard<eprosima::shared_mutex> guard(mtx_); |
1320 | | |
1321 | 921 | bool endiannessFlag {(smh->flags & BIT(0)) != 0}; |
1322 | | //bool timeFlag = smh->flags & BIT(1) ? true : false; |
1323 | | //Assign message endianness |
1324 | 921 | if (endiannessFlag) |
1325 | 373 | { |
1326 | 373 | msg->msg_endian = LITTLEEND; |
1327 | 373 | } |
1328 | 548 | else |
1329 | 548 | { |
1330 | 548 | msg->msg_endian = BIGEND; |
1331 | 548 | } |
1332 | 921 | if (smh->submessageLength == INFO_SRC_SUBMSG_LENGTH) |
1333 | 883 | { |
1334 | | //AVOID FIRST 4 BYTES: |
1335 | 883 | msg->pos += 4; |
1336 | 883 | CDRMessage::readOctet(msg, &source_version_.m_major); |
1337 | 883 | CDRMessage::readOctet(msg, &source_version_.m_minor); |
1338 | 883 | CDRMessage::readData(msg, &source_vendor_id_[0], 2); |
1339 | 883 | CDRMessage::readData(msg, source_guid_prefix_.value, GuidPrefix_t::size); |
1340 | 883 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "SRC RTPSParticipant is now: " << source_guid_prefix_); |
1341 | 883 | return true; |
1342 | 883 | } |
1343 | 38 | return false; |
1344 | 921 | } |
1345 | | |
1346 | | bool MessageReceiver::proc_Submsg_NackFrag( |
1347 | | CDRMessage_t* msg, |
1348 | | SubmessageHeader_t* smh, |
1349 | | bool was_decoded) const |
1350 | 137 | { |
1351 | | // Only used when HAVE_SECURITY is defined |
1352 | 137 | static_cast<void>(was_decoded); |
1353 | | |
1354 | 137 | eprosima::shared_lock<eprosima::shared_mutex> guard(mtx_); |
1355 | | |
1356 | 137 | bool endiannessFlag {(smh->flags & BIT(0)) != 0}; |
1357 | | //Assign message endianness |
1358 | 137 | if (endiannessFlag) |
1359 | 57 | { |
1360 | 57 | msg->msg_endian = LITTLEEND; |
1361 | 57 | } |
1362 | 80 | else |
1363 | 80 | { |
1364 | 80 | msg->msg_endian = BIGEND; |
1365 | 80 | } |
1366 | | |
1367 | 137 | GUID_t readerGUID; |
1368 | 137 | GUID_t writerGUID; |
1369 | 137 | readerGUID.guidPrefix = source_guid_prefix_; |
1370 | 137 | CDRMessage::readEntityId(msg, &readerGUID.entityId); |
1371 | 137 | writerGUID.guidPrefix = dest_guid_prefix_; |
1372 | 137 | CDRMessage::readEntityId(msg, &writerGUID.entityId); |
1373 | | |
1374 | 137 | SequenceNumber_t writerSN; |
1375 | 137 | CDRMessage::readSequenceNumber(msg, &writerSN); |
1376 | | |
1377 | 137 | FragmentNumberSet_t fnState; |
1378 | 137 | CDRMessage::readFragmentNumberSet(msg, &fnState); |
1379 | | |
1380 | 137 | uint32_t Ackcount {0}; |
1381 | 137 | if (!CDRMessage::readUInt32(msg, &Ackcount)) |
1382 | 117 | { |
1383 | 117 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Unable to read ackcount from message"); |
1384 | 117 | return false; |
1385 | 117 | } |
1386 | | |
1387 | | //Look for the correct writer to use the acknack |
1388 | 20 | for (BaseWriter* it : associated_writers_) |
1389 | 0 | { |
1390 | | #if HAVE_SECURITY |
1391 | | if (was_decoded || !it->getAttributes().security_attributes().is_submessage_protected) |
1392 | | #endif // HAVE_SECURITY |
1393 | 0 | { |
1394 | 0 | bool result; |
1395 | 0 | if (it->process_nack_frag(writerGUID, readerGUID, Ackcount, writerSN, fnState, result, source_vendor_id_)) |
1396 | 0 | { |
1397 | 0 | if (!result) |
1398 | 0 | { |
1399 | 0 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Acknack msg to NOT stateful writer "); |
1400 | 0 | } |
1401 | 0 | return result; |
1402 | 0 | } |
1403 | 0 | } |
1404 | 0 | } |
1405 | 20 | EPROSIMA_LOG_INFO(RTPS_MSG_IN, IDSTRING "Acknack msg to UNKNOWN writer (I looked through " |
1406 | 20 | << associated_writers_.size() << " writers in this ListenResource)"); |
1407 | 20 | return false; |
1408 | 20 | } |
1409 | | |
1410 | | bool MessageReceiver::proc_Submsg_HeartbeatFrag( |
1411 | | CDRMessage_t* msg, |
1412 | | SubmessageHeader_t* smh, |
1413 | | bool was_decoded) const |
1414 | 84 | { |
1415 | | // TODO: Add support for HEARTBEAT_FRAG submessage |
1416 | 84 | static_cast<void>(msg); |
1417 | 84 | static_cast<void>(smh); |
1418 | 84 | static_cast<void>(was_decoded); |
1419 | | |
1420 | 84 | return true; |
1421 | 84 | } |
1422 | | |
1423 | | void MessageReceiver::notify_network_statistics( |
1424 | | const Locator_t& source_locator, |
1425 | | const Locator_t& reception_locator, |
1426 | | CDRMessage_t* msg) const |
1427 | 1.67k | { |
1428 | 1.67k | static_cast<void>(source_locator); |
1429 | 1.67k | static_cast<void>(reception_locator); |
1430 | 1.67k | static_cast<void>(msg); |
1431 | | |
1432 | 1.67k | #ifdef FASTDDS_STATISTICS |
1433 | 1.67k | using namespace eprosima::fastdds::statistics; |
1434 | 1.67k | using namespace eprosima::fastdds::statistics::rtps; |
1435 | | |
1436 | 1.67k | if ((c_VendorId_eProsima != source_vendor_id_) || |
1437 | 343 | (LOCATOR_KIND_SHM == source_locator.kind)) |
1438 | 1.32k | { |
1439 | 1.32k | return; |
1440 | 1.32k | } |
1441 | | |
1442 | | // Keep track of current position, so we can restore it later. |
1443 | 343 | uint32_t initial_pos {msg->pos}; |
1444 | 343 | uint32_t msg_length {msg->length}; |
1445 | 10.1k | while (msg->pos < msg_length) |
1446 | 10.0k | { |
1447 | 10.0k | SubmessageHeader_t header; |
1448 | 10.0k | if (!readSubmessageHeader(msg, &header)) |
1449 | 134 | { |
1450 | 134 | break; |
1451 | 134 | } |
1452 | | |
1453 | 9.95k | if (FASTDDS_STATISTICS_NETWORK_SUBMESSAGE == header.submessageId) |
1454 | 89 | { |
1455 | | // Check submessage validity |
1456 | 89 | if ((statistics_submessage_data_length != header.submessageLength) || |
1457 | 70 | ((msg->pos + header.submessageLength) > msg_length)) |
1458 | 19 | { |
1459 | 19 | break; |
1460 | 19 | } |
1461 | | |
1462 | 70 | StatisticsSubmessageData data; |
1463 | 70 | read_statistics_submessage(msg, data); |
1464 | | #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
1465 | | participant_->on_network_statistics( |
1466 | | source_guid_prefix_, source_locator, reception_locator, data, msg_length); |
1467 | | #endif // if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) |
1468 | 70 | break; |
1469 | 89 | } |
1470 | | |
1471 | 9.86k | if (header.is_last) |
1472 | 64 | { |
1473 | 64 | break; |
1474 | 64 | } |
1475 | 9.80k | msg->pos += (header.submessageLength + 3u) & ~3u; |
1476 | 9.80k | } |
1477 | | |
1478 | 343 | msg->pos = initial_pos; |
1479 | 343 | #endif // FASTDDS_STATISTICS |
1480 | 343 | } |
1481 | | |
1482 | | } /* namespace rtps */ |
1483 | | } /* namespace fastdds */ |
1484 | | } /* namespace eprosima */ |