Fast DDS  Version 3.6.1.0
Fast DDS
Loading...
Searching...
No Matches
Locator.hpp
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
18
19#ifndef FASTDDS_RTPS_COMMON__LOCATOR_HPP
20#define FASTDDS_RTPS_COMMON__LOCATOR_HPP
21
22#include <algorithm>
23#include <cstdint>
24#include <cstring>
25#include <iomanip>
26#include <sstream>
27#include <string>
28#include <vector>
29
30#include <fastdds/config.hpp>
31#include <fastdds/dds/log/Log.hpp>
32#include <fastdds/fastdds_dll.hpp>
33#include <fastdds/rtps/common/Types.hpp>
34#include <fastdds/utils/IPLocator.hpp>
35
36namespace eprosima {
37namespace fastdds {
38namespace rtps {
39
41#define LOCATOR_INVALID(loc) {loc.kind = LOCATOR_KIND_INVALID; loc.port = LOCATOR_PORT_INVALID; \
42 LOCATOR_ADDRESS_INVALID(loc.address); \
43}
45#define LOCATOR_KIND_INVALID -1
46
48#define LOCATOR_ADDRESS_INVALID(a) {std::memset(a, 0x00, 16 * sizeof(octet));}
49
51#define LOCATOR_PORT_INVALID 0
52
54#define LOCATOR_KIND_RESERVED 0
56#define LOCATOR_KIND_UDPv4 1
58#define LOCATOR_KIND_UDPv6 2
60#define LOCATOR_KIND_TCPv4 4
62#define LOCATOR_KIND_TCPv6 8
64#define LOCATOR_KIND_SHM 16 + FASTDDS_VERSION_MAJOR
66#define LOCATOR_KIND_ETHERNET 0x02000000
67
73class FASTDDS_EXPORTED_API Locator_t
74{
75public:
76
92 int32_t kind;
94 uint32_t port;
97
100 : kind(LOCATOR_KIND_UDPv4)
101 {
102 port = 0;
103 LOCATOR_ADDRESS_INVALID(address);
104 }
105
108 Locator_t&& loc)
109 : kind(loc.kind)
110 {
111 port = loc.port;
112 std::memcpy(address, loc.address, 16 * sizeof(octet));
113 }
114
117 const Locator_t& loc)
118 : kind(loc.kind)
119 {
120 port = loc.port;
121 std::memcpy(address, loc.address, 16 * sizeof(octet));
122 }
123
126 uint32_t portin)
127 : kind(LOCATOR_KIND_UDPv4)
128 {
129 port = portin;
130 LOCATOR_ADDRESS_INVALID(address);
131 }
132
135 int32_t kindin,
136 uint32_t portin)
137 : kind(kindin)
138 {
139 port = portin;
140 LOCATOR_ADDRESS_INVALID(address);
141 }
142
144 Locator_t& operator =(
145 const Locator_t& loc)
146 {
147 kind = loc.kind;
148 port = loc.port;
149 std::memcpy(address, loc.address, 16 * sizeof(octet));
150 return *this;
151 }
152
160 const Locator_t& other)
161 {
162 memcpy(address, other.address, sizeof(octet) * 16);
163 return true;
164 }
165
172 {
173 return address;
174 }
175
183 uint16_t field) const
184 {
185 return address[field];
186 }
187
192 {
193 LOCATOR_ADDRESS_INVALID(address);
194 }
195
205 int32_t kind,
206 const std::string& address,
207 uint32_t port);
208
209};
210
219 const Locator_t& loc)
220{
221 if (loc.kind == LOCATOR_KIND_UDPv4 || loc.kind == LOCATOR_KIND_TCPv4) // WAN addr in TCPv4 is optional, isn't?
222 {
223 for (uint8_t i = 12; i < 16; ++i)
224 {
225 if (loc.address[i] != 0)
226 {
227 return true;
228 }
229 }
230 }
231 else if (loc.kind == LOCATOR_KIND_UDPv6 || loc.kind == LOCATOR_KIND_TCPv6 ||
232 loc.kind == LOCATOR_KIND_SHM || loc.kind == LOCATOR_KIND_ETHERNET)
233 {
234 for (uint8_t i = 0; i < 16; ++i)
235 {
236 if (loc.address[i] != 0)
237 {
238 return true;
239 }
240 }
241 }
242 return false;
243}
244
252inline bool IsLocatorValid(
253 const Locator_t& loc)
254{
255 return (0 <= loc.kind);
256}
257
266inline bool operator <(
267 const Locator_t& loc1,
268 const Locator_t& loc2)
269{
270 return memcmp(&loc1, &loc2, sizeof(Locator_t)) < 0;
271}
272
281inline bool operator ==(
282 const Locator_t& loc1,
283 const Locator_t& loc2)
284{
285 if (loc1.kind != loc2.kind)
286 {
287 return false;
288 }
289 if (loc1.port != loc2.port)
290 {
291 return false;
292 }
293 if (!std::equal(loc1.address, loc1.address + 16, loc2.address))
294 {
295 return false;
296 }
297 return true;
298}
299
308inline bool operator !=(
309 const Locator_t& loc1,
310 const Locator_t& loc2)
311{
312 return !(loc1 == loc2);
313}
314
332inline std::ostream& operator <<(
333 std::ostream& output,
334 const Locator_t& loc)
335{
336 // Stream Locator kind
337 switch (loc.kind)
338 {
339 case LOCATOR_KIND_TCPv4:
340 {
341 output << "TCPv4:[";
342 break;
343 }
344 case LOCATOR_KIND_UDPv4:
345 {
346 output << "UDPv4:[";
347 break;
348 }
349 case LOCATOR_KIND_TCPv6:
350 {
351 output << "TCPv6:[";
352 break;
353 }
354 case LOCATOR_KIND_UDPv6:
355 {
356 output << "UDPv6:[";
357 break;
358 }
359 case LOCATOR_KIND_SHM:
360 {
361 output << "SHM:[";
362 break;
363 }
364 case LOCATOR_KIND_ETHERNET:
365 {
366 output << "ETH:[";
367 break;
368 }
369 default:
370 {
371 output << "Invalid_locator:[_]:0";
372 return output;
373 }
374 }
375
376 // Stream address
377 switch (loc.kind)
378 {
379 case LOCATOR_KIND_UDPv4:
380 case LOCATOR_KIND_TCPv4:
381 output << IPLocator::toIPv4string(loc);
382 break;
383
384 case LOCATOR_KIND_UDPv6:
385 case LOCATOR_KIND_TCPv6:
386 output << IPLocator::toIPv6string(loc);
387 break;
388
389 case LOCATOR_KIND_ETHERNET:
390 output << std::hex << std::setfill('0') << std::setw(2) << (int)loc.address[10];
391 for (int i = 1; i < 6; ++i)
392 {
393 output << ":" << std::hex << std::setfill('0') << std::setw(2) << (int)loc.address[10 + i];
394 }
395 break;
396
397 case LOCATOR_KIND_SHM:
398 if (loc.address[0] == 'M')
399 {
400 output << "M";
401 }
402 else
403 {
404 output << "_";
405 }
406 break;
407 }
408
409 // Stream port
410 if (loc.kind == LOCATOR_KIND_TCPv4 || loc.kind == LOCATOR_KIND_TCPv6)
411 {
412 output << "]:" << std::to_string(IPLocator::getPhysicalPort(loc)) << "-"
413 << std::to_string(IPLocator::getLogicalPort(
414 loc));
415 }
416 else
417 {
418 output << "]:" << loc.port;
419 }
420
421 return output;
422}
423
441inline std::istream& operator >>(
442 std::istream& input,
443 Locator_t& loc)
444{
445 std::istream::sentry s(input);
446
447 if (s)
448 {
449 std::ios_base::iostate excp_mask = input.exceptions();
450
451 try
452 {
453 input.exceptions(excp_mask | std::ios_base::failbit | std::ios_base::badbit);
454
455 // Locator info
456 int32_t kind;
457 uint32_t port;
458 std::string address;
459
460 // Deserialization variables
461 std::stringbuf sb_kind;
462 std::stringbuf sb_address;
463 std::string str_kind;
464 char punct;
465
466 // Check the locator kind
467 input.get(sb_kind, ':');
468 str_kind = sb_kind.str();
469
470 if (str_kind == "SHM")
471 {
472 kind = LOCATOR_KIND_SHM;
473 }
474 else if (str_kind == "ETH")
475 {
476 kind = LOCATOR_KIND_ETHERNET;
477 }
478 else if (str_kind == "TCPv4")
479 {
480 kind = LOCATOR_KIND_TCPv4;
481 }
482 else if (str_kind == "TCPv6")
483 {
484 kind = LOCATOR_KIND_TCPv6;
485 }
486 else if (str_kind == "UDPv4")
487 {
488 kind = LOCATOR_KIND_UDPv4;
489 }
490 else if (str_kind == "UDPv6")
491 {
492 kind = LOCATOR_KIND_UDPv6;
493 }
494 else
495 {
496 kind = LOCATOR_KIND_INVALID;
497 loc.kind = LOCATOR_KIND_INVALID;
498 }
499
500 if (kind != LOCATOR_KIND_INVALID)
501 {
502 // Get chars :[
503 input >> punct >> punct;
504
505 // Get address in string
506 input.get(sb_address, ']');
507 address = sb_address.str();
508
509 // check if this is a valid IPv4 or IPv6 and call DNS if not
510 if ((kind == LOCATOR_KIND_UDPv4 || kind == LOCATOR_KIND_TCPv4) &&
511 !IPLocator::isIPv4(address))
512 {
513 auto addresses = IPLocator::resolveNameDNS(address);
514 if (addresses.first.empty())
515 {
516 loc.kind = LOCATOR_KIND_INVALID;
517 EPROSIMA_LOG_WARNING(LOCATOR, "Error deserializing Locator");
518 return input;
519 }
520 address = *addresses.first.begin();
521 }
522 if ((kind == LOCATOR_KIND_UDPv6 || kind == LOCATOR_KIND_TCPv6) &&
523 !IPLocator::isIPv6(address))
524 {
525 auto addresses = IPLocator::resolveNameDNS(address);
526 if (addresses.second.empty())
527 {
528 loc.kind = LOCATOR_KIND_INVALID;
529 EPROSIMA_LOG_WARNING(LOCATOR, "Error deserializing Locator");
530 return input;
531 }
532 address = *addresses.second.begin();
533 }
534 if ((kind == LOCATOR_KIND_SHM) && (address != "M") && (address != "_"))
535 {
536 loc.kind = LOCATOR_KIND_INVALID;
537 EPROSIMA_LOG_WARNING(LOCATOR, "Error deserializing Locator");
538 return input;
539 }
540
541 // Get char ]:
542 input >> punct >> punct;
543
544 // Get port
545 input >> port;
546
547 loc = Locator_t::create_locator(kind, address, port);
548 }
549 }
550 catch (std::ios_base::failure& )
551 {
552 loc.kind = LOCATOR_KIND_INVALID;
553 EPROSIMA_LOG_WARNING(LOCATOR, "Error deserializing Locator");
554 }
555
556 input.exceptions(excp_mask);
557 }
558 return input;
559}
560
561typedef std::vector<Locator_t>::iterator LocatorListIterator;
562typedef std::vector<Locator_t>::const_iterator LocatorListConstIterator;
563
564} // namespace rtps
565} // namespace fastdds
566} // namespace eprosima
567
568namespace eprosima {
569namespace fastdds {
570namespace rtps {
571
573
574} // namespace rtps
575} // namespace fastdds
576} // namespace eprosima
577
578#endif // FASTDDS_RTPS_COMMON__LOCATOR_HPP
static FASTDDS_EXPORTED_API bool isIPv4(const std::string &address)
Check whether a string contains an IPv4 format.
static FASTDDS_EXPORTED_API std::pair< std::set< std::string >, std::set< std::string > > resolveNameDNS(const std::string &address_name)
Resolve an address name by a DNS request and return the IP that this address references by a DNS serv...
static FASTDDS_EXPORTED_API uint16_t getLogicalPort(const Locator_t &locator)
Gets locator's logical port (as in RTCP protocol).
static FASTDDS_EXPORTED_API bool isIPv6(const std::string &address)
Check whether a string contains an IPv6 format.
static FASTDDS_EXPORTED_API uint16_t getPhysicalPort(const Locator_t &locator)
Gets locator's physical port (as in RTCP protocol).
static FASTDDS_EXPORTED_API std::string toIPv6string(const Locator_t &locator)
Returns a string representation of the locator's IPv6 following RFC 5952 recommendation.
static FASTDDS_EXPORTED_API std::string toIPv4string(const Locator_t &locator)
Returns a string representation of the locator's IPv4.
Class Locator_t, uniquely identifies a communication channel for a particular transport.
Definition Locator.hpp:74
int32_t kind
Specifies the locator type.
Definition Locator.hpp:92
octet address[16]
IP address.
Definition Locator.hpp:96
Locator_t(uint32_t portin)
Port constructor.
Definition Locator.hpp:125
bool set_address(const Locator_t &other)
Set the locator IP address using another locator.
Definition Locator.hpp:159
octet get_address(uint16_t field) const
Getter for a specific field of the locator IP address.
Definition Locator.hpp:182
octet * get_address()
Getter for the locator IP address.
Definition Locator.hpp:171
Locator_t(int32_t kindin, uint32_t portin)
Kind and port constructor.
Definition Locator.hpp:134
static Locator_t create_locator(int32_t kind, const std::string &address, uint32_t port)
Create a locator with the given parameters.
uint32_t port
Network port.
Definition Locator.hpp:94
void set_Invalid_Address()
Automatic setter for setting locator IP address to invalid address (0).
Definition Locator.hpp:191
Locator_t(Locator_t &&loc)
Move constructor.
Definition Locator.hpp:107
Locator_t()
Default constructor.
Definition Locator.hpp:99
Locator_t(const Locator_t &loc)
Copy constructor.
Definition Locator.hpp:116
Contains the RTPS protocol implementation.
std::istream & operator>>(std::istream &input, EntityId_t &enP)
Definition EntityId_t.hpp:289
bool operator==(const BuiltinTransportsOptions &bto1, const BuiltinTransportsOptions &bto2)
Equal to operator.
Definition BuiltinTransports.hpp:79
std::ostream & operator<<(std::ostream &output, BuiltinTransports transports)
Definition BuiltinTransports.hpp:118
bool IsLocatorValid(const Locator_t &loc)
Auxiliary method to check that locator kind is not LOCATOR_KIND_INVALID (-1).
Definition Locator.hpp:252
bool operator!=(const EntityId_t &id1, const EntityId_t &id2)
Guid prefix comparison operator.
Definition EntityId_t.hpp:267
bool operator<(const GUID_t &g1, const GUID_t &g2)
Definition Guid.hpp:192
std::vector< Locator_t >::const_iterator LocatorListConstIterator
Constant iterator to iterate over a vector of locators.
Definition Locator.hpp:562
uint8_t octet
Definition Types.hpp:83
std::vector< Locator_t >::iterator LocatorListIterator
Iterator to iterate over a vector of locators.
Definition Locator.hpp:561
eprosima::fastdds::rtps::Locator_t Locator
Definition Locator.hpp:572
bool IsAddressDefined(const Locator_t &loc)
Auxiliary method to check that IP address is not invalid (0).
Definition Locator.hpp:218
eProsima namespace.