23 #if !defined (__ACE_INLINE__) 34 (outCdr << value.
addr_.c_str());
70 bool prefer_loopback,
bool allow_ipv4_fallback)
73 for (
size_t i = 0; i < addr_count; ++i) {
74 if (addr == addr_array[i]) {
88 if (fullname.length() == 0) {
91 OpenDDS::DCPS::HostnameInfoVector nonFQDN;
101 } guardObject(addr_array);
103 if (result != 0 || addr_count < 1) {
105 ACE_TEXT(
"(%P|%t) ERROR: get_fully_qualified_hostname: Unable to probe network. %p\n"),
106 ACE_TEXT(
"ACE::get_ip_interfaces")));
109 for (
size_t i = 0; i < addr_count; i++) {
115 size_t index_last_non_ipv6 = 0;
116 for (
size_t i = 0; i < addr_count; i++) {
117 if (addr_array[i].get_type() == AF_INET6) {
118 if (i == index_last_non_ipv6) {
119 ++index_last_non_ipv6;
121 std::swap(addr_array[i], addr_array[index_last_non_ipv6]);
122 ++index_last_non_ipv6;
127 for (
size_t i = 0; i < addr_count; i++) {
132 VDBG_LVL((
LM_DEBUG,
"(%P|%t) get_fully_qualified_hostname: Considering fqdn %C\n", hostname), 4);
134 if (!addr_array[i].is_loopback() &&
ACE_OS::strchr(hostname,
'.') != 0 &&
136 VDBG_LVL((
LM_DEBUG,
"(%P|%t) get_fully_qualified_hostname: Found fqdn %C from %C\n", hostname,
LogAddr(addr_array[i]).c_str()), 2);
137 selected_address = addr_array[i];
140 *addr = selected_address;
144 VDBG_LVL((
LM_DEBUG,
"(%P|%t) get_fully_qualified_hostname: IP interface %C maps to hostname %C\n",
145 LogAddr(addr_array[i]).c_str(), hostname), 2);
155 nonFQDN.push_back(info);
162 OpenDDS::DCPS::HostnameInfoVector::iterator itBegin = nonFQDN.begin();
163 OpenDDS::DCPS::HostnameInfoVector::iterator itEnd = nonFQDN.end();
165 for (OpenDDS::DCPS::HostnameInfoVector::iterator it = itBegin; it != itEnd; ++it) {
167 ACE_DEBUG((
LM_WARNING,
"(%P|%t) WARNING: get_fully_qualified_hostname: Could not find FQDN. Using " 168 "\"%C\" as fully qualified hostname, please " 169 "correct system configuration.\n", it->hostname_.c_str()));
170 selected_address = addr_array[it->index_];
171 fullname = it->hostname_;
173 *addr = selected_address;
181 for (
size_t i = 0; i < addr_count; ++i) {
182 if (!addr_array[i].is_loopback()) {
185 ACE_DEBUG((
LM_WARNING,
"(%P|%t) WARNING: get_fully_qualified_hostname: Could not find FQDN. Using " 186 "\"%C\" as fully qualified hostname, please " 187 "correct system configuration.\n", addr_str));
188 selected_address = addr_array[i];
191 *addr = selected_address;
198 if (itBegin != itEnd) {
199 ACE_DEBUG((
LM_WARNING,
"(%P|%t) WARNING: get_fully_qualified_hostname: Could not find FQDN. Using " 200 "\"%C\" as fully qualified hostname, please " 201 "correct system configuration.\n", itBegin->hostname_.c_str()));
202 selected_address = addr_array[itBegin->index_];
203 fullname = itBegin->hostname_;
205 *addr = selected_address;
210 #ifdef OPENDDS_SAFETY_PROFILE 214 static const char local[] = {1, 0, 0, 127};
220 "(%P|%t) ERROR: get_fully_qualified_hostname: Failed to discover the fully qualified hostname\n"));
225 *addr = selected_address;
234 size_t endpoint_count = 0;
237 #ifdef OPENDDS_SAFETY_PROFILE 249 } guardObject(if_addrs);
253 #if defined (ACE_HAS_IPV6) 255 size_t ipv4_lo_cnt = 0;
257 bool ipv6_non_ll =
false;
259 for (
size_t j = 0; j < if_cnt; ++j) {
262 if (if_addrs[j].is_loopback())
264 #if defined (ACE_HAS_IPV6) 267 if (if_addrs[j].get_type() != AF_INET6 ||
268 if_addrs[j].is_ipv4_mapped_ipv6()) {
270 if (if_addrs[j].is_loopback())
272 }
else if (!if_addrs[j].is_linklocal() &&
273 !if_addrs[j].is_loopback()) {
275 }
else if (if_addrs[j].is_linklocal()) {
283 #if defined (ACE_HAS_IPV6) 290 ignore_lo = ipv4_cnt != ipv4_lo_cnt;
292 ignore_lo = if_cnt != lo_cnt;
296 size_t if_ok_cnt = if_cnt;
298 if_ok_cnt = ipv4_cnt;
299 lo_cnt = ipv4_lo_cnt;
307 if (!ipv4_only && !ipv6_non_ll)
308 lo_cnt = ipv4_lo_cnt;
311 endpoint_count = if_ok_cnt - ipv6_ll;
313 endpoint_count = if_ok_cnt - ipv6_ll - lo_cnt;
319 ignore_lo = if_cnt != lo_cnt;
321 endpoint_count = if_cnt;
323 endpoint_count = if_cnt - lo_cnt;
325 if (endpoint_count == 0) {
327 ACE_TEXT(
"(%P|%t) get_interface_addrs() - ")
328 ACE_TEXT(
"found no usable addresses\n")), 2);
331 for (
size_t i = 0; i < if_cnt; ++i) {
333 if (ipv4_only && (if_addrs[i].get_type() !=
AF_INET))
335 #if defined (ACE_HAS_IPV6) 339 if_addrs[i].is_loopback() &&
342 if_addrs[i].get_type() != AF_INET6))
346 if (ipv6_non_ll && if_addrs[i].is_linklocal())
351 if (ignore_lo && if_addrs[i].is_loopback())
354 addrs.push_back(if_addrs[i]);
359 size_t index_last_non_ipv6 = 0;
360 for (
size_t i = 0; i < addrs.size(); i++) {
361 if (addrs.at(i).
get_type() == AF_INET6) {
362 if (i == index_last_non_ipv6) {
363 ++index_last_non_ipv6;
366 std::swap(addrs.at(i), addrs.at(index_last_non_ipv6));
367 ++index_last_non_ipv6;
372 #ifdef OPENDDS_SAFETY_PROFILE 377 static const char local[] = { 1, 0, 0, 127 };
379 addrs.push_back(addr);
384 "(%P|%t) ERROR: failed to find usable interface address\n"));
392 const void* ttlp = &ttl;
393 #if defined(ACE_LINUX) || defined(__linux__) || defined(ACE_HAS_MAC_OSX) 400 #if defined (ACE_HAS_IPV6) 404 "ACE_SOCK_Dgram::get_local_addr %p\n",
ACE_TEXT(
"")));
406 if (local_addr.
get_type () == AF_INET6) {
410 static_cast<const char*>(ttlp),
415 ACE_TEXT(
"failed to set IPV6 TTL: %d %p\n"),
417 ACE_TEXT(
"ACE_OS::setsockopt(TTL)")),
425 static_cast<const char*>(ttlp),
430 ACE_TEXT(
"failed to set TTL: %d %p\n"),
432 ACE_TEXT(
"ACE_OS::setsockopt(TTL)")),
440 #if defined (ACE_HAS_IPV6) && defined (IPV6_V6ONLY) 445 protocol_family = local_address.
get_type();
446 }
else if (protocol_family ==
PF_UNSPEC) {
455 if (socket.
get_handle() == ACE_INVALID_HANDLE) {
458 ACE_TEXT(
"open_appropriate_socket_type: ")
459 ACE_TEXT(
"failed to set socket handle\n")),
461 }
else if (protocol_family !=
PF_UNIX &&
470 ACE_TEXT(
"open_appropriate_socket_type: ")
471 ACE_TEXT(
"failed to set socket SO_REUSEADDR option\n")),
476 if (protocol_family == PF_INET6 &&
481 sizeof(ipv6_only))) {
484 ACE_TEXT(
"open_appropriate_socket_type: ")
485 ACE_TEXT(
"failed to set IPV6_V6ONLY to 0: %p\n"),
486 ACE_TEXT(
"ACE_OS::setsockopt(IPV6_V6ONLY)")),
492 if (protocol_family ==
PF_INET || protocol_family == PF_INET6) {
495 protocol_family) == -1) {
500 reinterpret_cast<sockaddr *
> (local_address.
get_addr()),
508 "failed to bind address to socket\n"), 2);
512 *proto_family = protocol_family;
519 return socket.
open(local_address) == 0;
526 #if !(ACE_MAJOR_VERSION < 6 || (ACE_MAJOR_VERSION == 6 && (ACE_MINOR_VERSION < 3 || (ACE_MINOR_VERSION == 3 && ACE_MICRO_VERSION < 1)))) 532 addresses.push_back(temp);
533 }
while (copy.
next());
536 ACE_UNUSED_ARG(prefer_loopback);
538 #endif // !(ACE_MAJOR_VERSION < 6 || (ACE_MAJOR_VERSION == 6 && (ACE_MINOR_VERSION < 3 || (ACE_MINOR_VERSION == 3 && ACE_MICRO_VERSION < 1)))) 543 template <
typename T>
547 for (
typename T::const_iterator it = addrs.begin(); it != addrs.end(); ++it) {
549 VDBG((
LM_DEBUG,
"(%P|%t) tie_breaker - Choosing Address %C\n",
556 return *addrs.begin();
568 #endif // ACE_HAS_IPV6 574 if (it->get_type() == AF_INET6 && !it->is_multicast()) {
575 if (it->is_loopback()) {
576 VDBG((
LM_DEBUG,
"(%P|%t) choose_single_coherent_address(list) - " 577 "Considering Address %C - ADDING TO IPv6 LOOPBACK LIST\n",
LogAddr(*it).
c_str()));
578 set6_loopback.insert(*it);
579 }
else if (it->is_ipv4_mapped_ipv6() || it->is_ipv4_compat_ipv6()) {
581 VDBG((
LM_DEBUG,
"(%P|%t) choose_single_coherent_address(list) - " 582 "Considering Address %C - ADDING TO IPv6 MAPPED / COMPATIBLE IPv4 LIST\n",
LogAddr(*it).
c_str()));
583 set6_mapped_v4.insert(*it);
584 #endif // ! IPV6_V6ONLY 585 }
else if (it->is_linklocal()) {
586 VDBG((
LM_DEBUG,
"(%P|%t) choose_single_coherent_address(list) - " 587 "Considering Address %C - ADDING TO IPv6 LINK-LOCAL LIST\n",
LogAddr(*it).
c_str()));
588 set6_linklocal.insert(*it);
590 VDBG((
LM_DEBUG,
"(%P|%t) choose_single_coherent_address(list) - " 591 "Considering Address %C - ADDING TO IPv6 NORMAL LIST\n",
LogAddr(*it).
c_str()));
595 #endif // ACE_HAS_IPV6 596 if (it->get_type() ==
AF_INET && !it->is_multicast()) {
597 if (it->is_loopback()) {
598 VDBG((
LM_DEBUG,
"(%P|%t) choose_single_coherent_address(list) - " 599 "Considering Address %C - ADDING TO IPv4 LOOPBACK LIST\n",
LogAddr(*it).
c_str()));
600 set4_loopback.insert(*it);
602 VDBG((
LM_DEBUG,
"(%P|%t) choose_single_coherent_address(list) - " 603 "Considering Address %C - ADDING TO IPv4 NORMAL LIST\n",
LogAddr(*it).
c_str()));
610 if (prefer_loopback && !set6_loopback.empty()) {
611 return tie_breaker(set6_loopback, name);
613 #endif // ACE_HAS_IPV6 615 if (prefer_loopback && !set4_loopback.empty()) {
616 return tie_breaker(set4_loopback, name);
620 if (prefer_loopback && !set6_linklocal.empty()) {
621 return tie_breaker(set6_linklocal, name);
624 return tie_breaker(set6, name);
626 if (!set6_mapped_v4.empty()) {
627 return tie_breaker(set6_mapped_v4, name);
629 #endif // ACE_HAS_IPV6 632 return tie_breaker(set4, name);
636 if (!set6_linklocal.empty()) {
637 return tie_breaker(set6_linklocal, name);
639 if (!set6_loopback.empty()) {
640 return tie_breaker(set6_loopback, name);
642 #endif // ACE_HAS_IPV6 644 if (!set4_loopback.empty()) {
645 return tie_breaker(set4_loopback, name);
648 if (!addresses.empty()) {
649 return tie_breaker(addresses, name);
659 if (address.empty()) {
664 unsigned short port_number = 0;
667 const String::size_type openb = address.find_first_of(
'[');
668 const String::size_type closeb = address.find_first_of(
']', openb);
669 const String::size_type last_double = address.rfind(
"::", closeb);
670 const String::size_type port_div = closeb != String::npos ?
671 address.find_first_of(
':', closeb + 1u) :
672 (last_double != String::npos ?
673 address.find_first_of(
':', last_double + 2u) :
674 address.find_last_of(
':'));
676 const String::size_type port_div = address.find_last_of(
':');
679 if (port_div != String::npos) {
681 if (openb != String::npos && closeb != String::npos) {
682 host_name_str = address.substr(openb + 1u, closeb - 1u - openb);
686 host_name_str = address.substr(0, port_div);
688 port_number =
static_cast<unsigned short>(std::strtoul(address.substr(port_div + 1u).c_str(), 0, 10));
691 if (openb != String::npos && closeb != String::npos) {
692 host_name_str = address.substr(openb + 1u, closeb - 1u - openb);
696 host_name_str = address;
700 if (host_name_str.empty()) {
704 const char* host_name = host_name_str.c_str();
717 #if defined ACE_HAS_IPV6 && defined ACE_USES_IPV4_IPV6_MIGRATION 725 address_family = AF_INET6;
729 #ifdef ACE_HAS_SOCKADDR_IN6_SIN6_LEN 738 ACE_UNUSED_ARG(allow_ipv4_fallback);
743 #ifdef ACE_HAS_SOCKADDR_IN_SIN_LEN 753 std::memset(&hints, 0,
sizeof hints);
754 hints.ai_family = address_family;
760 #if defined ACE_HAS_IPV6 && !defined IPV6_V6ONLY 764 #if defined ACE_HAS_IPV6 && defined AI_ALL 767 hints.ai_flags |= AI_ALL;
782 VDBG((
LM_WARNING,
"(%P|%t) WARNING: choose_single_coherent_address: Call to getaddrinfo for hostname %C returned error: %d\n", host_name, error));
786 struct AddrInfoGuard {
787 AddrInfoGuard(addrinfo* ptr) : ptr_(ptr) {}
791 addrinfo*
const ptr_;
798 typedef std::pair<SystemTimePoint, OPENDDS_SET(ACE_INET_Addr)> AddrCachePair;
800 static AddrCacheMap addr_cache_map_;
803 for (AddrCacheMap::iterator it = addr_cache_map_.begin(); it != addr_cache_map_.end(); ) {
805 addr_cache_map_.erase(it++);
810 AddrCacheMap::iterator it = addr_cache_map_.find(host_name);
811 if (it != addr_cache_map_.end()) {
812 addresses.insert(addresses.end(), it->second.second.begin(), it->second.second.end());
813 it->second.first = now;
817 for (addrinfo* curr = res; curr; curr = curr->ai_next) {
818 if (curr->ai_family !=
AF_INET && curr->ai_family != AF_INET6) {
822 std::memset(&addr, 0,
sizeof addr);
823 std::memcpy(&addr, curr->ai_addr, curr->ai_addrlen);
825 if (curr->ai_family == AF_INET6) {
826 addr.in6_.sin6_port =
ACE_NTOHS(port_number);
829 addr.in4_.sin_port =
ACE_NTOHS(port_number);;
836 addresses.push_back(temp);
838 if (it != addr_cache_map_.end()) {
839 it->second.second.insert(temp);
843 addr_cache_map_[host_name] = make_pair(now, my_set);
861 switch (locator.
kind) {
873 #if !defined (ACE_HAS_IPV6) || !defined (IPV6_V6ONLY) 879 #
if defined (ACE_HAS_IPV6) && defined (IPV6_V6ONLY)
903 const sockaddr_in* in =
static_cast<const sockaddr_in*
>(raw);
904 std::memset(&locator.
address[0], 0, 12);
905 std::memcpy(&locator.
address[12], &in->sin_addr, 4);
912 const sockaddr_in6* in =
static_cast<const sockaddr_in6*
>(raw);
913 std::memcpy(&locator.
address[0], &in->sin6_addr, 16);
919 std::memset(&locator.
address[0], 0, 16);
const char * get_host_addr(char *addr, int addr_size) const
#define ACE_BEGIN_VERSIONED_NAMESPACE_DECL
void swap(MessageBlock &lhs, MessageBlock &rhs)
int setsockopt(ACE_HANDLE handle, int level, int optname, const char *optval, int optlen)
const LogLevel::Value value
const long LOCATOR_KIND_INVALID
bool good_bit(void) const
String addr_
The address in string format. e.g. ip:port, hostname:port.
#define OpenDDS_Dcps_Export
int strncmp(const char *s, const char *t, size_t len)
int locator_to_address(ACE_INET_Addr &dest, const DCPS::Locator_t &locator, bool map)
#define ACE_CDR_BYTE_ORDER
int set_option(int level, int option, void *optval, int optlen) const
ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_CDR::Boolean operator<<(ACE_OutputCDR &outCdr, OpenDDS::DCPS::NetworkResource &value)
Marshal into a buffer.
int inet_pton(int family, const char *strptr, void *addrptr)
OpenDDS_Dcps_Export void address_to_locator(Locator_t &locator, const ACE_INET_Addr &addr)
ACE_HANDLE socket(int protocol_family, int type, int proto)
static TimePoint_T< SystemClock > now()
int getaddrinfo(const char *name, const char *service, const addrinfo *hints, addrinfo **result)
bool verify_hostname(const String &hostname, ACE_INET_Addr *addr_array, size_t addr_count, bool prefer_loopback, bool allow_ipv4_fallback)
const char * strchr(const char *s, int c)
ACE_CDR::Boolean operator>>(ACE_InputCDR &inCdr, OpenDDS::DCPS::NetworkResource &value)
Demarshal from a buffer.
bool set_socket_multicast_ttl(const ACE_SOCK_Dgram &socket, const unsigned char &ttl)
static const String host(const ACE_INET_Addr &addr)
int hostname(char name[], size_t maxnamelen)
int get_fqdn(ACE_INET_Addr const &addr, char hostname[], size_t len)
ACE_INET_Addr choose_single_coherent_address(const ACE_INET_Addr &address, bool prefer_loopback)
int get_ip_interfaces(size_t &count, ACE_INET_Addr *&addr_array)
virtual void * get_addr(void) const
void set_handle(ACE_HANDLE handle)
int set_address(const char *ip_addr, int len, int encode=1, int map=0)
Defines a wrapper around address info which is used for advertise.
void get_interface_addrs(OPENDDS_VECTOR(ACE_INET_Addr)&addrs)
const char * c_str() const
#define ACE_END_VERSIONED_NAMESPACE_DECL
int get_local_addr(ACE_Addr &) const
int bind(ACE_HANDLE s, struct sockaddr *name, int namelen)
ACE_HANDLE get_handle(void) const
const long LOCATOR_KIND_UDPv6
void freeaddrinfo(addrinfo *result)
static const ACE_Addr sap_any
bool open_appropriate_socket_type(ACE_SOCK_Dgram &socket, const ACE_INET_Addr &local_address, int *proto_family)
u_short get_port_number(void) const
virtual void set_addr(const void *, int len)
DDS::ReturnCode_t copy(DDS::DynamicData_ptr dest, DDS::DynamicData_ptr src)
#define VDBG_LVL(DBG_ARGS, LEVEL)
int get_addr_size(void) const
int bind_port(ACE_HANDLE handle, ACE_UINT32 ip_addr=INADDR_ANY, int address_family=AF_UNSPEC)
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
int open(const ACE_Addr &local, int protocol_family=ACE_PROTOCOL_FAMILY_INET, int protocol=0, int reuse_addr=0, int ipv6_only=0)
void set_port_number(u_short, int encode=1)
String get_fully_qualified_hostname(ACE_INET_Addr *addr)
const long LOCATOR_KIND_UDPv4
#define ACE_ERROR_RETURN(X, Y)
typedef OPENDDS_VECTOR(ActionConnectionRecord) ConnectionRecords
static const String ip(const ACE_INET_Addr &addr)
#define ACE_PROTOCOL_FAMILY_INET
unsigned long inet_addr(const char *name)
The Internal API and Implementation of OpenDDS.
bool is_loopback(void) const
typedef OPENDDS_MAP(OPENDDS_STRING, OPENDDS_STRING) ValueMap
Helper types and functions for config file parsing.
DDS::OctetArray16 address
void reset_byte_order(int byte_order)
typedef OPENDDS_SET(NetworkAddress) AddrSet