00001
00002
00003
00004
00005
00006
00007
00008 #include "DCPS/DdsDcps_pch.h"
00009 #include "NetworkAddress.h"
00010 #include "ace/OS_NS_netdb.h"
00011 #include "ace/Sock_Connect.h"
00012 #include "ace/OS_NS_sys_socket.h"
00013
00014 #if !defined (__ACE_INLINE__)
00015 # include "NetworkAddress.inl"
00016 #endif
00017
00018 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00019
00020 ACE_CDR::Boolean
00021 operator<< (ACE_OutputCDR& outCdr, OpenDDS::DCPS::NetworkAddress& value)
00022 {
00023 return (outCdr << ACE_OutputCDR::from_boolean(ACE_CDR_BYTE_ORDER)) &&
00024 (outCdr << ACE_OutputCDR::from_octet(value.reserved_)) &&
00025 (outCdr << value.addr_.c_str());
00026 }
00027
00028 ACE_CDR::Boolean
00029 operator>> (ACE_InputCDR& inCdr, OpenDDS::DCPS::NetworkAddress& value)
00030 {
00031 CORBA::Boolean byte_order;
00032
00033 if (!(inCdr >> ACE_InputCDR::to_boolean(byte_order)))
00034 return false;
00035
00036 inCdr.reset_byte_order(byte_order);
00037
00038 if (!(inCdr >> ACE_InputCDR::to_octet(value.reserved_)))
00039 return false;
00040
00041 char* buf = 0;
00042
00043 if (!(inCdr >> buf))
00044 return false;
00045
00046 value.addr_ = buf;
00047
00048 delete[] buf;
00049
00050 return inCdr.good_bit();
00051 }
00052
00053 ACE_END_VERSIONED_NAMESPACE_DECL
00054
00055 OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
00056
00057 namespace OpenDDS {
00058 namespace DCPS {
00059
00060 OPENDDS_STRING get_fully_qualified_hostname(ACE_INET_Addr* addr)
00061 {
00062
00063
00064 static OPENDDS_STRING fullname;
00065 static ACE_INET_Addr selected_address;
00066
00067 if (fullname.length() == 0) {
00068 size_t addr_count;
00069 ACE_INET_Addr *addr_array = 0;
00070 OpenDDS::DCPS::HostnameInfoVector nonFQDN;
00071
00072 int result = ACE::get_ip_interfaces(addr_count, addr_array);
00073
00074 struct Array_Guard {
00075 Array_Guard(ACE_INET_Addr *ptr) : ptr_(ptr) {}
00076 ~Array_Guard() {
00077 delete [] ptr_;
00078 }
00079 ACE_INET_Addr* const ptr_;
00080 } guardObject(addr_array);
00081
00082 if (result != 0 || addr_count < 1) {
00083 ACE_ERROR((LM_ERROR,
00084 ACE_TEXT("(%P|%t) ERROR: Unable to probe network. %p\n"),
00085 ACE_TEXT("ACE::get_ip_interfaces")));
00086
00087 } else {
00088 #ifdef ACE_HAS_IPV6
00089
00090 size_t index_last_non_ipv6 = 0;
00091 for (size_t i = 0; i < addr_count; i++) {
00092 if (addr_array[i].get_type() == AF_INET6) {
00093 if (i == index_last_non_ipv6) {
00094 ++index_last_non_ipv6;
00095 } else {
00096 std::swap(addr_array[i], addr_array[index_last_non_ipv6]);
00097 ++index_last_non_ipv6;
00098 }
00099 }
00100 }
00101 #endif
00102 for (size_t i = 0; i < addr_count; i++) {
00103 char hostname[MAXHOSTNAMELEN+1] = "";
00104
00105
00106
00107 if (ACE::get_fqdn(addr_array[i], hostname, MAXHOSTNAMELEN+1) == 0) {
00108 if (addr_array[i].is_loopback() == false && ACE_OS::strchr(hostname, '.') != 0) {
00109 VDBG_LVL((LM_DEBUG, "(%P|%t) found fqdn %C from %C:%d\n",
00110 hostname, addr_array[i].get_host_addr(), addr_array[i].get_port_number()), 2);
00111 selected_address = addr_array[i];
00112 fullname = hostname;
00113 if (addr) {
00114 *addr = selected_address;
00115 }
00116 return fullname;
00117
00118 } else {
00119 VDBG_LVL((LM_DEBUG, "(%P|%t) ip interface %C:%d maps to hostname %C\n",
00120 addr_array[i].get_host_addr(), addr_array[i].get_port_number(), hostname), 2);
00121
00122 if (ACE_OS::strncmp(hostname, "localhost", 9) == 0) {
00123 addr_array[i].get_host_addr(hostname, MAXHOSTNAMELEN);
00124 }
00125
00126 OpenDDS::DCPS::HostnameInfo info;
00127 info.index_ = i;
00128 info.hostname_ = hostname;
00129 nonFQDN.push_back(info);
00130 }
00131 }
00132 }
00133 }
00134
00135 OpenDDS::DCPS::HostnameInfoVector::iterator itBegin = nonFQDN.begin();
00136 OpenDDS::DCPS::HostnameInfoVector::iterator itEnd = nonFQDN.end();
00137
00138 for (OpenDDS::DCPS::HostnameInfoVector::iterator it = itBegin; it != itEnd; ++it) {
00139 if (addr_array[it->index_].is_loopback() == false) {
00140 ACE_DEBUG((LM_WARNING, "(%P|%t) WARNING: Could not find FQDN. Using "
00141 "\"%C\" as fully qualified hostname, please "
00142 "correct system configuration.\n", it->hostname_.c_str()));
00143 selected_address = addr_array[it->index_];
00144 fullname = it->hostname_;
00145 if (addr) {
00146 *addr = selected_address;
00147 }
00148 return fullname;
00149 }
00150 }
00151
00152 if (itBegin != itEnd) {
00153 ACE_DEBUG((LM_WARNING, "(%P|%t) WARNING: Could not find FQDN. Using "
00154 "\"%C\" as fully qualified hostname, please "
00155 "correct system configuration.\n", itBegin->hostname_.c_str()));
00156 selected_address = addr_array[itBegin->index_];
00157 fullname = itBegin->hostname_;
00158 if (addr) {
00159 *addr = selected_address;
00160 }
00161 return fullname;
00162 }
00163
00164 #ifdef OPENDDS_SAFETY_PROFILE
00165
00166
00167 if (addr) {
00168 static const char local[] = {1, 0, 0, 127};
00169 addr->set_address(local, sizeof local);
00170 }
00171 return "localhost";
00172 #else
00173 ACE_ERROR((LM_ERROR,
00174 "(%P|%t) ERROR: failed to discover the fully qualified hostname\n"));
00175 #endif
00176 }
00177
00178 if (addr) {
00179 *addr = selected_address;
00180 }
00181 return fullname;
00182 }
00183
00184 void get_interface_addrs(OPENDDS_VECTOR(ACE_INET_Addr)& addrs)
00185 {
00186 ACE_INET_Addr *if_addrs = 0;
00187 size_t if_cnt = 0;
00188 size_t endpoint_count = 0;
00189
00190 int result =
00191 #ifdef OPENDDS_SAFETY_PROFILE
00192 -1;
00193 #else
00194 ACE::get_ip_interfaces(if_cnt, if_addrs);
00195 #endif
00196
00197 struct Array_Guard {
00198 Array_Guard(ACE_INET_Addr *ptr) : ptr_(ptr) {}
00199 ~Array_Guard() {
00200 delete[] ptr_;
00201 }
00202 ACE_INET_Addr* const ptr_;
00203 } guardObject(if_addrs);
00204
00205 if (!result) {
00206 size_t lo_cnt = 0;
00207 #if defined (ACE_HAS_IPV6)
00208 size_t ipv4_cnt = 0;
00209 size_t ipv4_lo_cnt = 0;
00210 size_t ipv6_ll = 0;
00211 bool ipv6_non_ll = false;
00212 #endif
00213 for (size_t j = 0; j < if_cnt; ++j) {
00214
00215
00216 if (if_addrs[j].is_loopback())
00217 ++lo_cnt;
00218 #if defined (ACE_HAS_IPV6)
00219
00220
00221 if (if_addrs[j].get_type() != AF_INET6 ||
00222 if_addrs[j].is_ipv4_mapped_ipv6()) {
00223 ++ipv4_cnt;
00224 if (if_addrs[j].is_loopback())
00225 ++ipv4_lo_cnt;
00226 } else if (!if_addrs[j].is_linklocal() &&
00227 !if_addrs[j].is_loopback()) {
00228 ipv6_non_ll = true;
00229 } else if (if_addrs[j].is_linklocal()) {
00230 ++ipv6_ll;
00231 }
00232 #endif
00233 }
00234
00235 bool ipv4_only = ACE_INET_Addr().get_type() == AF_INET;
00236
00237 #if defined (ACE_HAS_IPV6)
00238
00239
00240
00241
00242 bool ignore_lo;
00243 if (ipv4_only) {
00244 ignore_lo = ipv4_cnt != ipv4_lo_cnt;
00245 } else {
00246 ignore_lo = if_cnt != lo_cnt;
00247 }
00248
00249
00250 size_t if_ok_cnt = if_cnt;
00251 if (ipv4_only) {
00252 if_ok_cnt = ipv4_cnt;
00253 lo_cnt = ipv4_lo_cnt;
00254 ipv6_ll = 0;
00255 }
00256
00257
00258
00259
00260
00261 if (!ipv4_only && !ipv6_non_ll)
00262 lo_cnt = ipv4_lo_cnt;
00263
00264 if (!ignore_lo)
00265 endpoint_count = if_ok_cnt - ipv6_ll;
00266 else
00267 endpoint_count = if_ok_cnt - ipv6_ll - lo_cnt;
00268 #else
00269
00270
00271
00272 bool ignore_lo;
00273 ignore_lo = if_cnt != lo_cnt;
00274 if (!ignore_lo)
00275 endpoint_count = if_cnt;
00276 else
00277 endpoint_count = if_cnt - lo_cnt;
00278 #endif
00279 if (endpoint_count == 0) {
00280 VDBG_LVL((LM_DEBUG,
00281 ACE_TEXT("(%P|%t) get_interface_addrs() - ")
00282 ACE_TEXT("found no usable addresses\n")), 2);
00283 }
00284
00285 for (size_t i = 0; i < if_cnt; ++i) {
00286
00287 if (ipv4_only && (if_addrs[i].get_type() != AF_INET))
00288 continue;
00289 #if defined (ACE_HAS_IPV6)
00290
00291
00292 if (ignore_lo &&
00293 if_addrs[i].is_loopback() &&
00294 (ipv4_only ||
00295 ipv6_non_ll ||
00296 if_addrs[i].get_type() != AF_INET6))
00297 continue;
00298
00299
00300 if (ipv6_non_ll && if_addrs[i].is_linklocal())
00301 continue;
00302 #else
00303
00304
00305 if (ignore_lo && if_addrs[i].is_loopback())
00306 continue;
00307 #endif
00308 addrs.push_back(if_addrs[i]);
00309 }
00310 }
00311 #ifdef ACE_HAS_IPV6
00312
00313 size_t index_last_non_ipv6 = 0;
00314 for (size_t i = 0; i < addrs.size(); i++) {
00315 if (addrs.at(i).get_type() == AF_INET6) {
00316 if (i == index_last_non_ipv6) {
00317 ++index_last_non_ipv6;
00318 }
00319 else {
00320 std::swap(addrs.at(i), addrs.at(index_last_non_ipv6));
00321 ++index_last_non_ipv6;
00322 }
00323 }
00324 }
00325 #endif
00326 #ifdef OPENDDS_SAFETY_PROFILE
00327
00328
00329 if (addrs.empty()) {
00330 ACE_INET_Addr addr;
00331 static const char local[] = { 1, 0, 0, 127 };
00332 addr.set_address(local, sizeof local);
00333 addrs.push_back(addr);
00334 }
00335 #else
00336 if (addrs.empty()) {
00337 ACE_ERROR((LM_ERROR,
00338 "(%P|%t) ERROR: failed to find usable interface address\n"));
00339 }
00340 #endif
00341 }
00342
00343 bool set_socket_multicast_ttl(const ACE_SOCK_Dgram& socket, const unsigned char& ttl)
00344 {
00345 ACE_HANDLE handle = socket.get_handle();
00346 const void* ttlp = &ttl;
00347 #if defined(ACE_LINUX) || defined(__linux__)
00348 int ttl_2 = ttl;
00349 ttlp = &ttl_2;
00350 #define TTL ttl_2
00351 #else
00352 #define TTL ttl
00353 #endif
00354 #if defined (ACE_HAS_IPV6)
00355 ACE_INET_Addr local_addr;
00356 if (0 != socket.get_local_addr(local_addr)) {
00357 VDBG((LM_WARNING, "(%P|%t) set_socket_ttl: "
00358 "ACE_SOCK_Dgram::get_local_addr %p\n", ACE_TEXT("")));
00359 }
00360 if (local_addr.get_type () == AF_INET6) {
00361 if (0 != ACE_OS::setsockopt(handle,
00362 IPPROTO_IPV6,
00363 IPV6_MULTICAST_HOPS,
00364 static_cast<const char*>(ttlp),
00365 sizeof(TTL))) {
00366 ACE_ERROR_RETURN((LM_ERROR,
00367 ACE_TEXT("(%P|%t) ERROR: ")
00368 ACE_TEXT("set_socket_ttl: ")
00369 ACE_TEXT("failed to set IPV6 TTL: %d %p\n"),
00370 ttl,
00371 ACE_TEXT("ACE_OS::setsockopt(TTL)")),
00372 false);
00373 }
00374 } else
00375 #endif
00376 if (0 != ACE_OS::setsockopt(handle,
00377 IPPROTO_IP,
00378 IP_MULTICAST_TTL,
00379 static_cast<const char*>(ttlp),
00380 sizeof(TTL))) {
00381 ACE_ERROR_RETURN((LM_ERROR,
00382 ACE_TEXT("(%P|%t) ERROR: ")
00383 ACE_TEXT("set_socket_ttl: ")
00384 ACE_TEXT("failed to set TTL: %d %p\n"),
00385 ttl,
00386 ACE_TEXT("ACE_OS::setsockopt(TTL)")),
00387 false);
00388 }
00389 return true;
00390 }
00391
00392 bool open_appropriate_socket_type(ACE_SOCK_Dgram& socket, const ACE_INET_Addr& local_address)
00393 {
00394 #if defined (ACE_HAS_IPV6) && defined (IPV6_V6ONLY)
00395 int protocol_family = ACE_PROTOCOL_FAMILY_INET;
00396 int protocol = 0;
00397 int reuse_addr = 0;
00398 if (static_cast<ACE_Addr>(local_address) != ACE_Addr::sap_any) {
00399 protocol_family = local_address.get_type();
00400 } else if (protocol_family == PF_UNSPEC) {
00401 protocol_family = ACE::ipv6_enabled() ? PF_INET6 : PF_INET;
00402 }
00403
00404 int one = 1;
00405 socket.set_handle(ACE_OS::socket(protocol_family,
00406 SOCK_DGRAM,
00407 protocol));
00408
00409 if (socket.get_handle() == ACE_INVALID_HANDLE) {
00410 ACE_ERROR_RETURN((LM_WARNING,
00411 ACE_TEXT("(%P|%t) WARNING:")
00412 ACE_TEXT("open_appropriate_socket_type: ")
00413 ACE_TEXT("failed to set socket handle\n")),
00414 false);
00415 } else if (protocol_family != PF_UNIX &&
00416 reuse_addr &&
00417 socket.set_option(SOL_SOCKET,
00418 SO_REUSEADDR,
00419 &one,
00420 sizeof one) == -1) {
00421 socket.close();
00422 ACE_ERROR_RETURN((LM_WARNING,
00423 ACE_TEXT("(%P|%t) WARNING: ")
00424 ACE_TEXT("open_appropriate_socket_type: ")
00425 ACE_TEXT("failed to set socket SO_REUSEADDR option\n")),
00426 false);
00427 }
00428 ACE_HANDLE handle = socket.get_handle();
00429 int ipv6_only = 0;
00430 if (protocol_family == PF_INET6 &&
00431 0 != ACE_OS::setsockopt(handle,
00432 IPPROTO_IPV6,
00433 IPV6_V6ONLY,
00434 (char*)&ipv6_only,
00435 sizeof(ipv6_only))) {
00436 ACE_ERROR_RETURN((LM_WARNING,
00437 ACE_TEXT("(%P|%t) WARNING: ")
00438 ACE_TEXT("open_appropriate_socket_type: ")
00439 ACE_TEXT("failed to set IPV6_V6ONLY to 0: %p\n"),
00440 ACE_TEXT("ACE_OS::setsockopt(IPV6_V6ONLY)")),
00441 false);
00442 }
00443 bool error = false;
00444
00445 if (static_cast<ACE_Addr>(local_address) == ACE_Addr::sap_any) {
00446 if (protocol_family == PF_INET || protocol_family == PF_INET6) {
00447 if (ACE::bind_port(socket.get_handle(),
00448 INADDR_ANY,
00449 protocol_family) == -1) {
00450 error = true;
00451 }
00452 }
00453 } else if (ACE_OS::bind(socket.get_handle(),
00454 reinterpret_cast<sockaddr *> (local_address.get_addr()),
00455 local_address.get_size()) == -1) {
00456 error = true;
00457 }
00458
00459 if (error) {
00460 socket.close();
00461 VDBG_LVL((LM_WARNING, "(%P|%t) WARNING: open_appropriate_socket_type: "
00462 "failed to bind address to socket\n"), 2);
00463 return false;
00464 }
00465 return true;
00466 #else
00467 return socket.open(local_address) == 0;
00468 #endif
00469 }
00470 }
00471 }
00472
00473 OPENDDS_END_VERSIONED_NAMESPACE_DECL