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