From 787ad4841fc171d99c2e1ac5d56271ddfaa78974 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 18 Dec 2019 20:55:29 -0800 Subject: [PATCH] better GUID --- src/server.cpp | 97 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 39 deletions(-) diff --git a/src/server.cpp b/src/server.cpp index 60fd854..3da0990 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -4,6 +4,13 @@ * in file LICENSE that is included with this distribution. */ +#if defined(_WIN32) +# include +#elif !defined(__rtems__) && !defined(vxWorks) +# include +# include +#endif + #include #include #include @@ -296,45 +303,6 @@ Server::Pvt::Pvt(Config&& conf) evsocket dummy(AF_INET, SOCK_DGRAM, 0); - { - // choose new GUID. - // treat as 3x 32-bit unsigned. - union { - std::array i; - std::array b; - } pun; - static_assert (sizeof(pun)==12, ""); - - // i[0] time - epicsTimeStamp now; - epicsTimeGetCurrent(&now); - pun.i[0] = now.secPastEpoch ^ now.nsec; - - // i[1] host - // mix together all local bcast addresses - pun.i[1] = 0xdeadbeef; // because... why not - { - ELLLIST bcasts = ELLLIST_INIT; - osiSockAddr match; - match.ia.sin_family = AF_INET; - match.ia.sin_addr.s_addr = htonl(INADDR_ANY); - match.ia.sin_port = 0; - osiSockDiscoverBroadcastAddresses(&bcasts, dummy.sock, &match); - - while(ELLNODE *cur = ellGet(&bcasts)) { - osiSockAddrNode *node = CONTAINER(cur, osiSockAddrNode, node); - if(node->addr.sa.sa_family==AF_INET) - pun.i[1] ^= ntohl(node->addr.ia.sin_addr.s_addr); - free(cur); - } - } - - // i[2] random - pun.i[2] = (rand()/double(RAND_MAX))*0xffffffff; - - std::copy(pun.b.begin(), pun.b.end(), effective.guid.begin()); - } - acceptor_loop.call([this, &dummy](){ // from acceptor worker @@ -391,6 +359,57 @@ Server::Pvt::Pvt(Config&& conf) effective.auto_beacon = false; }); + { + // choose new GUID. + // treat as 3x 32-bit unsigned. + union { + std::array i; + std::array b; + } pun; + static_assert (sizeof(pun)==12, ""); + + // i[0] (start) time + epicsTimeStamp now; + epicsTimeGetCurrent(&now); + pun.i[0] = now.secPastEpoch ^ now.nsec; + + // i[1] host + // mix together all local bcast addresses + pun.i[1] = 0xdeadbeef; // because... why not + { + ELLLIST bcasts = ELLLIST_INIT; + osiSockAddr match; + match.ia.sin_family = AF_INET; + match.ia.sin_addr.s_addr = htonl(INADDR_ANY); + match.ia.sin_port = 0; + osiSockDiscoverBroadcastAddresses(&bcasts, dummy.sock, &match); + + while(ELLNODE *cur = ellGet(&bcasts)) { + osiSockAddrNode *node = CONTAINER(cur, osiSockAddrNode, node); + if(node->addr.sa.sa_family==AF_INET) + pun.i[1] ^= ntohl(node->addr.ia.sin_addr.s_addr); + free(cur); + } + } + + // i[2] process on host +#if defined(_WIN32) + pun.i[2] = GetCurrentProcessId(); +#elif !defined(__rtems__) && !defined(vxWorks) + pun.i[2] = getpid(); +#else + pun.i[2] = 0xdeadbeef; +#endif + // and a bit of server instance within this process + pun.i[2] ^= uint32_t(effective.tcp_port)<<16u; + // maybe a little bit of randomness (eg. ASLR on Linux) + pun.i[2] ^= size_t(this); + if(sizeof(size_t)>4) + pun.i[2] ^= size_t(this)>>32u; + + std::copy(pun.b.begin(), pun.b.end(), effective.guid.begin()); + } + // Add magic "server" PV { auto L = sourcesLock.lockWriter();