diff options
author | Benoit Foucher <benoit@zeroc.com> | 2006-03-23 12:57:11 +0000 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2006-03-23 12:57:11 +0000 |
commit | 07ec4897c353261f24b53b7a48d0694e91fabc9e (patch) | |
tree | 21999efbc960b13bf6ddefa141be7e05dbd5a27d /cpp/src/IceUtil/UUID.cpp | |
parent | Changes for TAO 1.5 (diff) | |
download | ice-07ec4897c353261f24b53b7a48d0694e91fabc9e.tar.bz2 ice-07ec4897c353261f24b53b7a48d0694e91fabc9e.tar.xz ice-07ec4897c353261f24b53b7a48d0694e91fabc9e.zip |
Added Random.cpp
Diffstat (limited to 'cpp/src/IceUtil/UUID.cpp')
-rw-r--r-- | cpp/src/IceUtil/UUID.cpp | 143 |
1 files changed, 13 insertions, 130 deletions
diff --git a/cpp/src/IceUtil/UUID.cpp b/cpp/src/IceUtil/UUID.cpp index afd99eaf55f..169dcf32eef 100644 --- a/cpp/src/IceUtil/UUID.cpp +++ b/cpp/src/IceUtil/UUID.cpp @@ -17,11 +17,7 @@ #ifdef _WIN32 # include <rpc.h> #else -# include <IceUtil/StaticMutex.h> -# include <sys/types.h> -# include <sys/stat.h> -# include <fcntl.h> -# include <unistd.h> +# include <IceUtil/Random.h> #endif using namespace std; @@ -49,75 +45,6 @@ inline void bytesToHex(unsigned char* bytes, size_t len, char*& hexBuffer) } } - -IceUtil::UUIDGenerationException::UUIDGenerationException(const char* file, int line) : - Exception(file, line) -{ -} - -const char* IceUtil::UUIDGenerationException::_name = "IceUtil::UUIDGenerationException"; - -#ifndef _WIN32 -// -// Unfortunately on Linux (at least up to 2.6.9), concurrent access to /dev/urandom -// can return the same value. Search for "Concurrent access to /dev/urandom" in the -// linux-kernel mailing list archive for additional details. -// Since /dev/urandom on other platforms is usually a port from Linux, this problem -// could be widespread. Therefore, instead of using 122 random bits that could be -// duplicated, we replace the last 15 bits of all "random" UUIDs by the last 15 bits -// of the process id, and in each process, we serialize access to /dev/urandom using -// a static mutex. -// - -static IceUtil::StaticMutex staticMutex = ICE_STATIC_MUTEX_INITIALIZER; -static int fd = -1; -static char myPid[2]; - -namespace -{ - -// -// Close fd at exit -// -class UUIDCleanup -{ -public: - - ~UUIDCleanup() - { - IceUtil::StaticMutex::Lock lock(staticMutex); - if(fd != -1) - { - close(fd); - fd = -1; - } - } -}; -static UUIDCleanup uuidCleanup; -} - - -#endif - -const string -IceUtil::UUIDGenerationException::ice_name() const -{ - return _name; -} - -IceUtil::Exception* -IceUtil::UUIDGenerationException::ice_clone() const -{ - return new UUIDGenerationException(*this); -} - -void -IceUtil::UUIDGenerationException::ice_throw() const -{ - throw *this; -} - - string IceUtil::generateUUID() { @@ -149,62 +76,18 @@ IceUtil::generateUUID() assert(sizeof(UUID) == 16); + // + // Get a random sequence of bytes and the pid of the current + // process. Instead of using 122 random bits that could be + // duplicated (because of a bug with some Linux kernels and + // potentially other Unix platforms -- see comment in Random.cpp), + // we replace the last 15 bits of all "random" Randoms by the last + // 15 bits of the process id. + // char* buffer = reinterpret_cast<char*>(&uuid); - int reads = 0; - size_t index = 0; + char pid[2]; + generateRandomAndGetPid(buffer, sizeof(UUID), pid); - { - // - // Serialize access to /dev/urandom; see comment above. - // - IceUtil::StaticMutex::Lock lock(staticMutex); - if(fd == -1) - { - fd = open("/dev/urandom", O_RDONLY); - if (fd == -1) - { - assert(0); - throw UUIDGenerationException(__FILE__, __LINE__); - } - - // - // Initialize myPid as well - // - pid_t pid = getpid(); - myPid[0] = (pid >> 8) & 0x7F; - myPid[1] = pid & 0xFF; - } - - - // - // Limit the number of attempts to 20 reads to avoid - // a potential "for ever" loop - // - while(reads <= 20 && index != sizeof(UUID)) - { - ssize_t bytesRead = read(fd, buffer + index, sizeof(UUID) - index); - - if(bytesRead == -1 && errno != EINTR) - { - int err = errno; - cerr << "Reading /dev/urandom returned " << strerror(err) << endl; - assert(0); - throw UUIDGenerationException(__FILE__, __LINE__); - } - else - { - index += bytesRead; - reads++; - } - } - } - - if (index != sizeof(UUID)) - { - assert(0); - throw UUIDGenerationException(__FILE__, __LINE__); - } - // // Adjust the bits that say "version 4" UUID // @@ -216,8 +99,8 @@ IceUtil::generateUUID() // // Replace the end of the node by myPid (15 bits) // - uuid.node[4] = (uuid.node[4] & 0x80) | myPid[0]; - uuid.node[5] = myPid[1]; + uuid.node[4] = (uuid.node[4] & 0x80) | pid[0]; + uuid.node[5] = pid[1]; // // Convert to a UUID string |