diff --git a/src/pva/pvaVersion.h b/src/pva/pvaVersion.h index c33bdf8..73d02a1 100644 --- a/src/pva/pvaVersion.h +++ b/src/pva/pvaVersion.h @@ -26,7 +26,7 @@ // TODO to be generated, etc. #define EPICS_PVA_MAJOR_VERSION 4 #define EPICS_PVA_MINOR_VERSION 0 -#define EPICS_PVA_MAINTENANCE_VERSION 2 +#define EPICS_PVA_MAINTENANCE_VERSION 3 #define EPICS_PVA_DEVELOPMENT_FLAG 0 namespace epics { diff --git a/src/server/responseHandlers.cpp b/src/server/responseHandlers.cpp index bf7b251..e0f783c 100644 --- a/src/server/responseHandlers.cpp +++ b/src/server/responseHandlers.cpp @@ -14,6 +14,8 @@ #endif #include +#include +#include #include #include @@ -27,8 +29,6 @@ #include #include -#include - #include #include #include @@ -206,6 +206,8 @@ std::string ServerSearchHandler::SUPPORTED_PROTOCOL = "tcp"; ServerSearchHandler::ServerSearchHandler(ServerContextImpl::shared_pointer const & context) : AbstractServerResponseHandler(context, "Search request"), _providers(context->getChannelProviders()) { + // initialize random seed with some random value + srand ( time(NULL) ); } void ServerSearchHandler::handleResponse(osiSockAddr* responseFrom, @@ -254,8 +256,11 @@ void ServerSearchHandler::handleResponse(osiSockAddr* responseFrom, transport->ensureData(2); const int32 count = payloadBuffer->getShort() & 0xFFFF; + // TODO DoS attack? const bool responseRequired = (QOS_REPLY_REQUIRED & qosCode) != 0; + // TODO bloom filter or similar server selection (by GUID) + // // locally broadcast if unicast (qosCode & 0x80 == 0x80) // @@ -306,12 +311,17 @@ void ServerSearchHandler::handleResponse(osiSockAddr* responseFrom, { if (allowed) { + // TODO constant + #define MAX_SERVER_SEARCH_RESPONSE_DELAY_MS 100 + double period = (rand() % MAX_SERVER_SEARCH_RESPONSE_DELAY_MS)/(double)1000; + ServerChannelFindRequesterImpl* pr = new ServerChannelFindRequesterImpl(_context, 1); pr->set("", searchSequenceId, 0, responseAddress, true, true); + // TODO use std::make_shared std::tr1::shared_ptr tp(pr); - ChannelFindRequester::shared_pointer spr = tp; - spr->channelFindResult(Status::Ok, ChannelFind::shared_pointer(), false); + TimerCallback::shared_pointer tc = tp; + _context->getTimer()->scheduleAfterDelay(tc, period); } } } @@ -335,6 +345,16 @@ void ServerChannelFindRequesterImpl::clear() _serverSearch = false; } +void ServerChannelFindRequesterImpl::callback() +{ + channelFindResult(Status::Ok, ChannelFind::shared_pointer(), false); +} + +void ServerChannelFindRequesterImpl::timerStopped() +{ + // noop +} + ServerChannelFindRequesterImpl* ServerChannelFindRequesterImpl::set(std::string name, int32 searchSequenceId, int32 cid, osiSockAddr const & sendTo, bool responseRequired, bool serverSearch) { diff --git a/src/server/responseHandlers.h b/src/server/responseHandlers.h index 35b21d6..c0bc95a 100644 --- a/src/server/responseHandlers.h +++ b/src/server/responseHandlers.h @@ -7,6 +7,8 @@ #ifndef RESPONSEHANDLERS_H_ #define RESPONSEHANDLERS_H_ +#include + #include #include #include @@ -161,6 +163,7 @@ namespace pvAccess { class ServerChannelFindRequesterImpl: public ChannelFindRequester, public TransportSender, + public epics::pvData::TimerCallback, public std::tr1::enable_shared_from_this { public: @@ -170,9 +173,14 @@ namespace pvAccess { ServerChannelFindRequesterImpl* set(std::string _name, epics::pvData::int32 searchSequenceId, epics::pvData::int32 cid, osiSockAddr const & sendTo, bool responseRequired, bool serverSearch); void channelFindResult(const epics::pvData::Status& status, ChannelFind::shared_pointer const & channelFind, bool wasFound); - void lock(); + + void lock(); void unlock(); void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control); + + void callback(); + void timerStopped(); + private: GUID _guid; std::string _name; diff --git a/src/server/serverContext.cpp b/src/server/serverContext.cpp index 460bcae..48c7812 100644 --- a/src/server/serverContext.cpp +++ b/src/server/serverContext.cpp @@ -76,6 +76,16 @@ const Version& ServerContextImpl::getVersion() return ServerContextImpl::VERSION; } +/* +#ifdef WIN32 + UUID uuid; + UuidCreate ( &uuid ); +#else + uuid_t uuid; + uuid_generate_random ( uuid ); +#endif +*/ + void ServerContextImpl::generateGUID() { // TODO use UUID