#include <GuidGenerator.h>
Public Member Functions | |
GuidGenerator () | |
int | interfaceName (const char *interface) |
void | populate (DCPS::GUID_t &container) |
Private Types | |
enum | { NODE_ID_SIZE = 6 } |
typedef unsigned char | Node_ID [NODE_ID_SIZE] |
Private Member Functions | |
ACE_UINT16 | getCount () |
Private Attributes | |
Node_ID | node_id_ |
pid_t | pid_ |
ACE_Thread_Mutex | counter_lock_ |
ACE_UINT16 | counter_ |
OPENDDS_STRING | interface_name_ |
Generate GuidPrefix_t values for use with RTPS Also see GuidConverter.h in dds/DCPS 0 GUID_t.guidPrefix[ 0] == VendorId_t == 0x01 for OCI (used for OpenDDS) 1 GUID_t.guidPrefix[ 1] == VendorId_t == 0x03 for OCI (used for OpenDDS) 2 GUID_t.guidPrefix[ 2] == MAC Address 3 GUID_t.guidPrefix[ 3] == MAC Address 4 GUID_t.guidPrefix[ 4] == MAC Address 5 GUID_t.guidPrefix[ 5] == MAC Address 6 GUID_t.guidPrefix[ 6] == MAC Address 7 GUID_t.guidPrefix[ 7] == MAC Address 8 GUID_t.guidPrefix[ 8] == Process ID (MS byte) 9 GUID_t.guidPrefix[ 9] == Process ID (LS byte) 10 GUID_t.guidPrefix[10] == Counter (MS byte) 11 GUID_t.guidPrefix[11] == Counter (LS byte)
Definition at line 37 of file GuidGenerator.h.
typedef unsigned char OpenDDS::RTPS::GuidGenerator::Node_ID[NODE_ID_SIZE] [private] |
Borrowed from ACE::UUID_Node, definition of the MAC address holder type
Definition at line 55 of file GuidGenerator.h.
anonymous enum [private] |
OpenDDS::RTPS::GuidGenerator::GuidGenerator | ( | ) |
Definition at line 49 of file GuidGenerator.cpp.
References ACE_OS::getmacaddress(), getpid(), ACE_OS::gettimeofday(), ACE_OS::memcpy(), ACE_OS::macaddr_node_t::node, node_id_, NODE_ID_SIZE, pid_, ACE_OS::rand(), ACE_OS::rand_r(), and ACE_Time_Value::usec().
00050 : pid_(ACE_OS::getpid()), 00051 counter_(0) 00052 { 00053 00054 if (pid_ == -1) { 00055 unsigned seed = static_cast<unsigned>(ACE_OS::gettimeofday().usec()); 00056 pid_ = static_cast<pid_t>(ACE_OS::rand_r(&seed)); 00057 } 00058 00059 ACE_OS::macaddr_node_t macaddress; 00060 const int result = ACE_OS::getmacaddress(&macaddress); 00061 00062 if (-1 != result) { 00063 ACE_OS::memcpy(node_id_, macaddress.node, NODE_ID_SIZE); 00064 } else { 00065 for (int i = 0; i < NODE_ID_SIZE; ++i) { 00066 node_id_[i] = static_cast<unsigned char>(ACE_OS::rand()); 00067 } 00068 } 00069 }
ACE_UINT16 OpenDDS::RTPS::GuidGenerator::getCount | ( | ) | [private] |
Definition at line 72 of file GuidGenerator.cpp.
References counter_, and counter_lock_.
Referenced by populate().
00073 { 00074 ACE_Guard<ACE_SYNCH_MUTEX> guard(counter_lock_); 00075 return counter_++; 00076 }
int OpenDDS::RTPS::GuidGenerator::interfaceName | ( | const char * | interface | ) |
override the MAC address to use a specific network interface instead of just the first (non-loopback) interface
Definition at line 79 of file GuidGenerator.cpp.
References ACE_TEXT(), ACE_OS::close(), ACE_Allocator::free(), h, ifconf::ifc_len, ifreq::ifr_name, OpenDDS::DCPS::SafetyProfilePool::instance(), interface_name_, ACE_OS::ioctl(), LM_ERROR, ACE_Allocator::malloc(), node_id_, size, and ACE_OS::socket().
Referenced by OpenDDS::RTPS::RtpsDiscovery::add_domain_participant(), and OpenDDS::RTPS::RtpsDiscovery::generate_participant_guid().
00080 { 00081 if (interface_name_ == iface) { 00082 return 0; 00083 } 00084 interface_name_ = iface; 00085 // See ace/OS_NS_netdb.cpp ACE_OS::getmacaddress() 00086 #if defined ACE_WIN32 && !defined ACE_HAS_WINCE 00087 ULONG size; 00088 if (::GetAdaptersAddresses(AF_UNSPEC, 0, 0, 0, &size) 00089 != ERROR_BUFFER_OVERFLOW) { 00090 return -1; 00091 } 00092 ACE_Allocator* const alloc = DCPS::SafetyProfilePool::instance(); 00093 IP_ADAPTER_ADDRESSES* const addrs = 00094 static_cast<IP_ADAPTER_ADDRESSES*>(alloc->malloc(size)); 00095 if (!addrs) { 00096 return -1; 00097 } 00098 if (::GetAdaptersAddresses(AF_UNSPEC, 0, 0, addrs, &size) != NO_ERROR) { 00099 alloc->free(addrs); 00100 return -1; 00101 } 00102 00103 bool found = false; 00104 for (IP_ADAPTER_ADDRESSES* iter = addrs; iter && !found; iter = iter->Next) { 00105 if (ACE_Wide_To_Ascii(iter->FriendlyName).char_rep() == interface_name_) { 00106 std::memcpy(node_id_, iter->PhysicalAddress, 00107 std::min(static_cast<size_t>(iter->PhysicalAddressLength), 00108 sizeof node_id_)); 00109 found = true; 00110 } 00111 } 00112 00113 alloc->free(addrs); 00114 return found ? 0 : -1; 00115 #elif defined ACE_LINUX || defined __ANDROID_API__ 00116 ifreq ifr; 00117 // Guarantee that iface will fit in ifr.ifr_name and still be null terminated 00118 // ifr.ifr_name is sized to IFNAMSIZ 00119 if (std::strlen(iface) >= sizeof(ifr.ifr_name)) { 00120 ACE_ERROR((LM_ERROR, 00121 ACE_TEXT("Interface name %C exceeds max allowable length, must be < %d."), 00122 iface, IFNAMSIZ)); 00123 return -1; 00124 } 00125 std::strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name)); 00126 const ACE_HANDLE h = ACE_OS::socket(PF_INET, SOCK_DGRAM, 0); 00127 if (h == ACE_INVALID_HANDLE) { 00128 return -1; 00129 } 00130 if (ACE_OS::ioctl(h, SIOCGIFHWADDR, &ifr) < 0) { 00131 ACE_OS::close(h); 00132 return -1; 00133 } 00134 ACE_OS::close(h); 00135 std::memcpy(node_id_, ifr.ifr_addr.sa_data, sizeof node_id_); 00136 return 0; 00137 #elif defined ACE_HAS_SIOCGIFCONF || defined ACE_HAS_MAC_OSX 00138 const ACE_HANDLE h = ACE_OS::socket(AF_INET, SOCK_DGRAM, 0); 00139 if (h == ACE_INVALID_HANDLE) { 00140 return -1; 00141 } 00142 00143 const int BUFFERSIZE = 4000; 00144 char buffer[BUFFERSIZE]; 00145 ifconf ifc; 00146 ifc.ifc_len = BUFFERSIZE; 00147 ifc.ifc_buf = buffer; 00148 00149 if (ACE_OS::ioctl(h, SIOCGIFCONF, &ifc) < 0) { 00150 ACE_OS::close(h); 00151 return -1; 00152 } 00153 00154 bool found = false; 00155 for (const char* ptr = buffer; !found && ptr < buffer + ifc.ifc_len;) { 00156 const ifreq* ifr = reinterpret_cast<const ifreq*>(ptr); 00157 if (ifr->ifr_addr.sa_family == AF_LINK && ifr->ifr_name == interface_name_) { 00158 const sockaddr_dl* sdl = 00159 reinterpret_cast<const sockaddr_dl*>(&ifr->ifr_addr); 00160 std::memcpy(node_id_, LLADDR(sdl), sizeof node_id_); 00161 found = true; 00162 } 00163 00164 ptr += sizeof ifr->ifr_name + std::max(sizeof ifr->ifr_addr, 00165 static_cast<size_t>(ifr->ifr_addr.sa_len)); 00166 } 00167 00168 ACE_OS::close(h); 00169 return found ? 0 : -1; 00170 #elif defined ACE_VXWORKS 00171 int name[] = {CTL_NET, AF_ROUTE, 0, 0, NET_RT_IFLIST, 0}; 00172 static const size_t name_elts = sizeof name / sizeof name[0]; 00173 00174 size_t result_sz = 0u; 00175 if (sysctl(name, name_elts, 0, &result_sz, 0, 0u) != 0) { 00176 return -1; 00177 } 00178 00179 ACE_Allocator* const alloc = DCPS::SafetyProfilePool::instance(); 00180 char* const result = static_cast<char*>(alloc->malloc(result_sz)); 00181 00182 if (sysctl(name, name_elts, result, &result_sz, 0, 0u) != 0) { 00183 alloc->free(result); 00184 return -1; 00185 } 00186 00187 for (size_t pos = 0, n; pos + sizeof(if_msghdr) < result_sz; pos += n) { 00188 if_msghdr* const hdr = reinterpret_cast<if_msghdr*>(result + pos); 00189 n = hdr->ifm_msglen; 00190 sockaddr_dl* const addr = 00191 reinterpret_cast<sockaddr_dl*>(result + pos + sizeof(if_msghdr)); 00192 00193 if (hdr->ifm_type == RTM_IFINFO && (hdr->ifm_addrs & RTA_IFP) 00194 && std::memcmp(addr->sdl_data, iface, addr->sdl_nlen) == 0 00195 && addr->sdl_alen >= sizeof node_id_) { 00196 std::memcpy(node_id_, LLADDR(addr), sizeof node_id_); 00197 alloc->free(result); 00198 return 0; 00199 } 00200 00201 while (pos + n < result_sz) { 00202 if_msghdr* const nxt = reinterpret_cast<if_msghdr*>(result + pos + n); 00203 if (nxt->ifm_type != RTM_NEWADDR) { 00204 break; 00205 } 00206 n += nxt->ifm_msglen; 00207 } 00208 } 00209 00210 alloc->free(result); 00211 return -1; 00212 #else 00213 return -1; 00214 #endif 00215 }
void OpenDDS::RTPS::GuidGenerator::populate | ( | DCPS::GUID_t & | container | ) |
populate a GUID container with a unique ID. This will increment the counter, and use a lock (if compiled with MT ACE) while doing so.
Definition at line 218 of file GuidGenerator.cpp.
References getCount(), OpenDDS::DCPS::GUID_t::guidPrefix, ACE_OS::memcpy(), node_id_, NODE_ID_SIZE, pid_, and OpenDDS::DCPS::VENDORID_OCI.
Referenced by OpenDDS::RTPS::RtpsDiscovery::add_domain_participant(), and OpenDDS::RTPS::RtpsDiscovery::generate_participant_guid().
00219 { 00220 container.guidPrefix[0] = DCPS::VENDORID_OCI[0]; 00221 container.guidPrefix[1] = DCPS::VENDORID_OCI[1]; 00222 00223 const ACE_UINT16 count = getCount(); 00224 ACE_OS::memcpy(&container.guidPrefix[2], node_id_, NODE_ID_SIZE); 00225 container.guidPrefix[8] = static_cast<CORBA::Octet>(pid_ >> 8); 00226 container.guidPrefix[9] = static_cast<CORBA::Octet>(pid_ & 0xFF); 00227 container.guidPrefix[10] = static_cast<CORBA::Octet>(count >> 8); 00228 container.guidPrefix[11] = static_cast<CORBA::Octet>(count & 0xFF); 00229 }
Definition at line 62 of file GuidGenerator.h.
Referenced by getCount().
Definition at line 61 of file GuidGenerator.h.
Referenced by getCount().
OPENDDS_STRING OpenDDS::RTPS::GuidGenerator::interface_name_ [private] |
Definition at line 63 of file GuidGenerator.h.
Referenced by interfaceName().
Definition at line 59 of file GuidGenerator.h.
Referenced by GuidGenerator(), interfaceName(), and populate().
pid_t OpenDDS::RTPS::GuidGenerator::pid_ [private] |
Definition at line 60 of file GuidGenerator.h.
Referenced by GuidGenerator(), and populate().