Fast DDS  Version 3.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
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 <vector>
28
29#include <fastdds/config.hpp>
30#include <fastdds/dds/log/Log.hpp>
31#include <fastdds/fastdds_dll.hpp>
32#include <fastdds/rtps/common/Types.hpp>
33#include <fastdds/utils/IPLocator.hpp>
34
35namespace eprosima {
36namespace fastdds {
37namespace rtps {
38
40#define LOCATOR_INVALID(loc) {loc.kind = LOCATOR_KIND_INVALID; loc.port = LOCATOR_PORT_INVALID; \
41 LOCATOR_ADDRESS_INVALID(loc.address); \
42}
44#define LOCATOR_KIND_INVALID -1
45
47#define LOCATOR_ADDRESS_INVALID(a) {std::memset(a, 0x00, 16 * sizeof(octet));}
48
50#define LOCATOR_PORT_INVALID 0
51
53#define LOCATOR_KIND_RESERVED 0
55#define LOCATOR_KIND_UDPv4 1
57#define LOCATOR_KIND_UDPv6 2
59#define LOCATOR_KIND_TCPv4 4
61#define LOCATOR_KIND_TCPv6 8
63#define LOCATOR_KIND_SHM 16 + FASTDDS_VERSION_MAJOR
64
70class FASTDDS_EXPORTED_API Locator_t
71{
72public:
73
87 int32_t kind;
89 uint32_t port;
91 octet address[16];
92
95 : kind(LOCATOR_KIND_UDPv4)
96 {
97 port = 0;
98 LOCATOR_ADDRESS_INVALID(address);
99 }
100
103 Locator_t&& loc)
104 : kind(loc.kind)
105 {
106 port = loc.port;
107 std::memcpy(address, loc.address, 16 * sizeof(octet));
108 }
109
112 const Locator_t& loc)
113 : kind(loc.kind)
114 {
115 port = loc.port;
116 std::memcpy(address, loc.address, 16 * sizeof(octet));
117 }
118
121 uint32_t portin)
122 : kind(LOCATOR_KIND_UDPv4)
123 {
124 port = portin;
125 LOCATOR_ADDRESS_INVALID(address);
126 }
127
130 int32_t kindin,
131 uint32_t portin)
132 : kind(kindin)
133 {
134 port = portin;
135 LOCATOR_ADDRESS_INVALID(address);
136 }
137
139 Locator_t& operator =(
140 const Locator_t& loc)
141 {
142 kind = loc.kind;
143 port = loc.port;
144 std::memcpy(address, loc.address, 16 * sizeof(octet));
145 return *this;
146 }
147
155 const Locator_t& other)
156 {
157 memcpy(address, other.address, sizeof(octet) * 16);
158 return true;
159 }
160
167 {
168 return address;
169 }
170
178 uint16_t field) const
179 {
180 return address[field];
181 }
182
187 {
188 LOCATOR_ADDRESS_INVALID(address);
189 }
190
191};
192
201 const Locator_t& loc)
202{
203 if (loc.kind == LOCATOR_KIND_UDPv4 || loc.kind == LOCATOR_KIND_TCPv4) // WAN addr in TCPv4 is optional, isn't?
204 {
205 for (uint8_t i = 12; i < 16; ++i)
206 {
207 if (loc.address[i] != 0)
208 {
209 return true;
210 }
211 }
212 }
213 else if (loc.kind == LOCATOR_KIND_UDPv6 || loc.kind == LOCATOR_KIND_TCPv6)
214 {
215 for (uint8_t i = 0; i < 16; ++i)
216 {
217 if (loc.address[i] != 0)
218 {
219 return true;
220 }
221 }
222 }
223 return false;
224}
225
233inline bool IsLocatorValid(
234 const Locator_t& loc)
235{
236 return (0 <= loc.kind);
237}
238
247inline bool operator <(
248 const Locator_t& loc1,
249 const Locator_t& loc2)
250{
251 return memcmp(&loc1, &loc2, sizeof(Locator_t)) < 0;
252}
253
262inline bool operator ==(
263 const Locator_t& loc1,
264 const Locator_t& loc2)
265{
266 if (loc1.kind != loc2.kind)
267 {
268 return false;
269 }
270 if (loc1.port != loc2.port)
271 {
272 return false;
273 }
274 if (!std::equal(loc1.address, loc1.address + 16, loc2.address))
275 {
276 return false;
277 }
278 return true;
279}
280
289inline bool operator !=(
290 const Locator_t& loc1,
291 const Locator_t& loc2)
292{
293 return !(loc1 == loc2);
294}
295
312inline std::ostream& operator <<(
313 std::ostream& output,
314 const Locator_t& loc)
315{
316 // Stream Locator kind
317 switch (loc.kind)
318 {
319 case LOCATOR_KIND_TCPv4:
320 {
321 output << "TCPv4:[";
322 break;
323 }
324 case LOCATOR_KIND_UDPv4:
325 {
326 output << "UDPv4:[";
327 break;
328 }
329 case LOCATOR_KIND_TCPv6:
330 {
331 output << "TCPv6:[";
332 break;
333 }
334 case LOCATOR_KIND_UDPv6:
335 {
336 output << "UDPv6:[";
337 break;
338 }
339 case LOCATOR_KIND_SHM:
340 {
341 output << "SHM:[";
342 break;
343 }
344 default:
345 {
346 output << "Invalid_locator:[_]:0";
347 return output;
348 }
349 }
350
351 // Stream address
352 if (loc.kind == LOCATOR_KIND_UDPv4 || loc.kind == LOCATOR_KIND_TCPv4)
353 {
354 output << IPLocator::toIPv4string(loc);
355 }
356 else if (loc.kind == LOCATOR_KIND_UDPv6 || loc.kind == LOCATOR_KIND_TCPv6)
357 {
358 output << IPLocator::toIPv6string(loc);
359 }
360 else if (loc.kind == LOCATOR_KIND_SHM)
361 {
362 if (loc.address[0] == 'M')
363 {
364 output << "M";
365 }
366 else
367 {
368 output << "_";
369 }
370 }
371
372 // Stream port
373 if (loc.kind == LOCATOR_KIND_TCPv4 || loc.kind == LOCATOR_KIND_TCPv6)
374 {
375 output << "]:" << std::to_string(IPLocator::getPhysicalPort(loc)) << "-" << std::to_string(IPLocator::getLogicalPort(
376 loc));
377 }
378 else
379 {
380 output << "]:" << loc.port;
381 }
382
383 return output;
384}
385
402inline std::istream& operator >>(
403 std::istream& input,
404 Locator_t& loc)
405{
406 std::istream::sentry s(input);
407
408 if (s)
409 {
410 std::ios_base::iostate excp_mask = input.exceptions();
411
412 try
413 {
414 input.exceptions(excp_mask | std::ios_base::failbit | std::ios_base::badbit);
415
416 // Locator info
417 int32_t kind;
418 uint32_t port;
419 std::string address;
420
421 // Deserialization variables
422 std::stringbuf sb_kind;
423 std::stringbuf sb_address;
424 std::string str_kind;
425 char punct;
426
427 // Check the locator kind
428 input.get(sb_kind, ':');
429 str_kind = sb_kind.str();
430
431 if (str_kind == "SHM")
432 {
433 kind = LOCATOR_KIND_SHM;
434 }
435 else if (str_kind == "TCPv4")
436 {
437 kind = LOCATOR_KIND_TCPv4;
438 }
439 else if (str_kind == "TCPv6")
440 {
441 kind = LOCATOR_KIND_TCPv6;
442 }
443 else if (str_kind == "UDPv4")
444 {
445 kind = LOCATOR_KIND_UDPv4;
446 }
447 else if (str_kind == "UDPv6")
448 {
449 kind = LOCATOR_KIND_UDPv6;
450 }
451 else
452 {
453 kind = LOCATOR_KIND_INVALID;
454 loc.kind = LOCATOR_KIND_INVALID;
455 }
456
457 if (kind != LOCATOR_KIND_INVALID)
458 {
459 // Get chars :[
460 input >> punct >> punct;
461
462 // Get address in string
463 input.get(sb_address, ']');
464 address = sb_address.str();
465
466 // check if this is a valid IPv4 or IPv6 and call DNS if not
467 if ((kind == LOCATOR_KIND_UDPv4 || kind == LOCATOR_KIND_TCPv4) &&
468 !IPLocator::isIPv4(address))
469 {
470 auto addresses = IPLocator::resolveNameDNS(address);
471 if (addresses.first.empty())
472 {
473 loc.kind = LOCATOR_KIND_INVALID;
474 EPROSIMA_LOG_WARNING(LOCATOR, "Error deserializing Locator");
475 return input;
476 }
477 address = *addresses.first.begin();
478 }
479 if ((kind == LOCATOR_KIND_UDPv6 || kind == LOCATOR_KIND_TCPv6) &&
480 !IPLocator::isIPv6(address))
481 {
482 auto addresses = IPLocator::resolveNameDNS(address);
483 if (addresses.second.empty())
484 {
485 loc.kind = LOCATOR_KIND_INVALID;
486 EPROSIMA_LOG_WARNING(LOCATOR, "Error deserializing Locator");
487 return input;
488 }
489 address = *addresses.second.begin();
490 }
491
492 // Get char ]:
493 input >> punct >> punct;
494
495 // Get port
496 input >> port;
497
498 IPLocator::createLocator(kind, address, port, loc);
499 }
500 }
501 catch (std::ios_base::failure& )
502 {
503 loc.kind = LOCATOR_KIND_INVALID;
504 EPROSIMA_LOG_WARNING(LOCATOR, "Error deserializing Locator");
505 }
506
507 input.exceptions(excp_mask);
508 }
509 return input;
510}
511
512typedef std::vector<Locator_t>::iterator LocatorListIterator;
513typedef std::vector<Locator_t>::const_iterator LocatorListConstIterator;
514
515} // namespace rtps
516} // namespace fastdds
517} // namespace eprosima
518
519namespace eprosima {
520namespace fastdds {
521namespace rtps {
522
524
525} // namespace rtps
526} // namespace fastdds
527} // namespace eprosima
528
529#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.
static FASTDDS_EXPORTED_API void createLocator(int32_t kindin, const std::string &address, uint32_t portin, Locator_t &locator)
Fills locator with the given parameters.
Class Locator_t, uniquely identifies a communication channel for a particular transport.
Definition Locator.hpp:71
int32_t kind
Specifies the locator type.
Definition Locator.hpp:87
octet address[16]
IP address.
Definition Locator.hpp:91
Locator_t(uint32_t portin)
Port constructor.
Definition Locator.hpp:120
bool set_address(const Locator_t &other)
Set the locator IP address using another locator.
Definition Locator.hpp:154
octet get_address(uint16_t field) const
Getter for a specific field of the locator IP address.
Definition Locator.hpp:177
octet * get_address()
Getter for the locator IP address.
Definition Locator.hpp:166
Locator_t(int32_t kindin, uint32_t portin)
Kind and port constructor.
Definition Locator.hpp:129
uint32_t port
Network port.
Definition Locator.hpp:89
void set_Invalid_Address()
Automatic setter for setting locator IP address to invalid address (0).
Definition Locator.hpp:186
Locator_t(Locator_t &&loc)
Move constructor.
Definition Locator.hpp:102
Locator_t()
Default constructor.
Definition Locator.hpp:94
Locator_t(const Locator_t &loc)
Copy constructor.
Definition Locator.hpp:111
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:117
bool IsLocatorValid(const Locator_t &loc)
Auxiliary method to check that locator kind is not LOCATOR_KIND_INVALID (-1).
Definition Locator.hpp:233
unsigned char octet
Definition Types.hpp:83
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:513
std::vector< Locator_t >::iterator LocatorListIterator
Iterator to iterate over a vector of locators.
Definition Locator.hpp:512
bool IsAddressDefined(const Locator_t &loc)
Auxiliary method to check that IP address is not invalid (0).
Definition Locator.hpp:200
eProsima namespace.