From 523af71b7f125df76c52100be2c01f0425452ba8 Mon Sep 17 00:00:00 2001 From: Matej Sekoranja Date: Thu, 17 Dec 2015 14:02:11 +0100 Subject: [PATCH] duplicate search responses from the same server bound to multiple NIFs filtered out --- src/remote/channelSearchManager.h | 6 +++-- src/remote/simpleChannelSearchManagerImpl.cpp | 8 +++---- src/remote/simpleChannelSearchManagerImpl.h | 3 ++- src/remoteClient/clientContextImpl.cpp | 23 ++++++++++++++----- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/remote/channelSearchManager.h b/src/remote/channelSearchManager.h index 5f5458d..78fac05 100644 --- a/src/remote/channelSearchManager.h +++ b/src/remote/channelSearchManager.h @@ -41,11 +41,12 @@ class SearchInstance { /** * Search response from server (channel found). + * @param guid server GUID. * @param minorRevision server minor PVA revision. * @param serverAddress server address. */ // TODO make serverAddress an URI or similar - virtual void searchResponse(int8_t minorRevision, osiSockAddr* serverAddress) = 0; + virtual void searchResponse(const GUID & guid, int8_t minorRevision, osiSockAddr* serverAddress) = 0; }; class ChannelSearchManager { @@ -78,12 +79,13 @@ class ChannelSearchManager { /** * Search response from server (channel found). + * @param guid server GUID. * @param cid client channel ID. * @param seqNo search sequence number. * @param minorRevision server minor PVA revision. * @param serverAddress server address. */ - virtual void searchResponse(pvAccessID cid, int32_t seqNo, int8_t minorRevision, osiSockAddr* serverAddress) = 0; + virtual void searchResponse(const GUID & guid, pvAccessID cid, int32_t seqNo, int8_t minorRevision, osiSockAddr* serverAddress) = 0; /** * New server detected. diff --git a/src/remote/simpleChannelSearchManagerImpl.cpp b/src/remote/simpleChannelSearchManagerImpl.cpp index 5363ca1..2e61abf 100644 --- a/src/remote/simpleChannelSearchManagerImpl.cpp +++ b/src/remote/simpleChannelSearchManagerImpl.cpp @@ -137,7 +137,7 @@ void SimpleChannelSearchManagerImpl::unregisterSearchInstance(SearchInstance::sh m_channels.erase(id); } -void SimpleChannelSearchManagerImpl::searchResponse(pvAccessID cid, int32_t /*seqNo*/, int8_t minorRevision, osiSockAddr* serverAddress) +void SimpleChannelSearchManagerImpl::searchResponse(const GUID & guid, pvAccessID cid, int32_t /*seqNo*/, int8_t minorRevision, osiSockAddr* serverAddress) { Lock guard(m_channelMutex); std::map::iterator channelsIter = m_channels.find(cid); @@ -145,10 +145,10 @@ void SimpleChannelSearchManagerImpl::searchResponse(pvAccessID cid, int32_t /*se { guard.unlock(); - // minor hack to enable duplicate reports + // enable duplicate reports SearchInstance::shared_pointer si = std::tr1::dynamic_pointer_cast(m_context.lock()->getChannel(cid)); if (si) - si->searchResponse(minorRevision, serverAddress); + si->searchResponse(guid, minorRevision, serverAddress); } else { @@ -160,7 +160,7 @@ void SimpleChannelSearchManagerImpl::searchResponse(pvAccessID cid, int32_t /*se guard.unlock(); // then notify SearchInstance - si->searchResponse(minorRevision, serverAddress); + si->searchResponse(guid, minorRevision, serverAddress); } } diff --git a/src/remote/simpleChannelSearchManagerImpl.h b/src/remote/simpleChannelSearchManagerImpl.h index cead8ff..060dc48 100644 --- a/src/remote/simpleChannelSearchManagerImpl.h +++ b/src/remote/simpleChannelSearchManagerImpl.h @@ -89,12 +89,13 @@ class SimpleChannelSearchManagerImpl : void unregisterSearchInstance(SearchInstance::shared_pointer const & channel); /** * Search response from server (channel found). + * @param guid server GUID. * @param cid client channel ID. * @param seqNo search sequence number. * @param minorRevision server minor PVA revision. * @param serverAddress server address. */ - void searchResponse(pvAccessID cid, int32_t seqNo, int8_t minorRevision, osiSockAddr* serverAddress); + void searchResponse(const GUID & guid, pvAccessID cid, int32_t seqNo, int8_t minorRevision, osiSockAddr* serverAddress); /** * New server detected. * Boost searching of all channels. diff --git a/src/remoteClient/clientContextImpl.cpp b/src/remoteClient/clientContextImpl.cpp index 1810b98..adea100 100644 --- a/src/remoteClient/clientContextImpl.cpp +++ b/src/remoteClient/clientContextImpl.cpp @@ -2862,7 +2862,7 @@ namespace epics { { transport->ensureData(4); pvAccessID cid = payloadBuffer->getInt(); - csm->searchResponse(cid, searchSequenceId, version, &serverAddress); + csm->searchResponse(guid, cid, searchSequenceId, version, &serverAddress); } @@ -3497,6 +3497,11 @@ namespace epics { /// Used by SearchInstance. int32_t m_userValue; + /** + * @brief Server GUID. + */ + GUID m_guid; + /** * Constructor. * @param context @@ -3931,21 +3936,23 @@ namespace epics { m_addressIndex = m_addresses->size()*STATIC_SEARCH_MAX_MULTIPLIER; // NOTE: calls channelConnectFailed() on failure - searchResponse(PVA_PROTOCOL_REVISION, &((*m_addresses)[ix])); + static GUID guid = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; + searchResponse(guid, PVA_PROTOCOL_REVISION, &((*m_addresses)[ix])); } virtual void timerStopped() { // noop } - virtual void searchResponse(int8 minorRevision, osiSockAddr* serverAddress) { + virtual void searchResponse(const GUID & guid, int8 minorRevision, osiSockAddr* serverAddress) { Lock guard(m_channelMutex); Transport::shared_pointer transport = m_transport; if (transport.get()) { - // TODO use GUID to determine whether there are multiple servers with the same channel - // multiple defined PV or reconnect request (same server address) - if (!sockAddrAreIdentical(transport->getRemoteAddress(), serverAddress)) + // GUID check case: same server listening on different NIF + + if (!sockAddrAreIdentical(transport->getRemoteAddress(), serverAddress) && + !std::equal(guid.value, guid.value + 12, m_guid.value)) { EXCEPTION_GUARD(m_requester->message("More than one channel with name '" + m_name + "' detected, connected to: " + inetAddressToString(*transport->getRemoteAddress()) + ", ignored: " + inetAddressToString(*serverAddress), warningMessage)); @@ -3960,6 +3967,10 @@ namespace epics { return; } + + // remember GUID + std::copy(guid.value, guid.value + 12, m_guid.value); + // create channel createChannel(transport); }