diff options
Diffstat (limited to 'cppe/src/IceE/Reference.cpp')
-rw-r--r-- | cppe/src/IceE/Reference.cpp | 284 |
1 files changed, 195 insertions, 89 deletions
diff --git a/cppe/src/IceE/Reference.cpp b/cppe/src/IceE/Reference.cpp index 0b5a3e71dd4..16319eab04a 100644 --- a/cppe/src/IceE/Reference.cpp +++ b/cppe/src/IceE/Reference.cpp @@ -37,6 +37,28 @@ using namespace IceInternal; IceUtil::Shared* IceInternal::upCast(IceInternal::Reference* p) { return p; } +class ConnectionIsDatagram : public unary_function<ConnectionPtr, bool> +{ +public: + + bool + operator()(ConnectionPtr p) const + { + return p->endpoint()->datagram(); + } +}; + +class ConnectionIsSecure : public unary_function<ConnectionPtr, bool> +{ +public: + + bool + operator()(ConnectionPtr p) const + { + return p->endpoint()->secure(); + } +}; + CommunicatorPtr IceInternal::Reference::getCommunicator() const { @@ -52,7 +74,7 @@ IceInternal::Reference::changeContext(const Context& newContext) const } ReferencePtr -IceInternal::Reference::changeMode(Mode newMode) const +IceInternal::Reference::changeMode(ReferenceMode newMode) const { if(newMode == _mode) { @@ -64,6 +86,18 @@ IceInternal::Reference::changeMode(Mode newMode) const } ReferencePtr +IceInternal::Reference::changeSecure(bool newSecure) const +{ + if(newSecure == _secure) + { + return ReferencePtr(const_cast<Reference*>(this)); + } + ReferencePtr r = _instance->referenceFactory()->copy(this); + r->_secure = newSecure; + return r; +} + +ReferencePtr IceInternal::Reference::changeIdentity(const Identity& newIdentity) const { if(newIdentity == _identity) @@ -233,31 +267,31 @@ IceInternal::Reference::toString() const switch(_mode) { - case ModeTwoway: + case ReferenceModeTwoway: { s += " -t"; break; } - case ModeOneway: + case ReferenceModeOneway: { s += " -o"; break; } - case ModeBatchOneway: + case ReferenceModeBatchOneway: { s += " -O"; break; } - case ModeDatagram: + case ReferenceModeDatagram: { s += " -d"; break; } - case ModeBatchDatagram: + case ReferenceModeBatchDatagram: { s += " -D"; break; @@ -404,7 +438,7 @@ IceInternal::Reference::operator<(const Reference& r) const } IceInternal::Reference::Reference(const InstancePtr& inst, const CommunicatorPtr& com, const Identity& ident, - const Context& context, const string& fs, Mode md, bool sec) : + const Context& context, const string& fs, ReferenceMode md, bool sec) : _hashInitialized(false), _instance(inst), _communicator(com), @@ -450,7 +484,7 @@ IceInternal::Reference::applyOverrides(vector<EndpointPtr>& endpts) const IceUtil::Shared* IceInternal::upCast(IceInternal::FixedReference* p) { return p; } IceInternal::FixedReference::FixedReference(const InstancePtr& inst, const CommunicatorPtr& com, const Identity& ident, - const Context& context, const string& fs, Mode md, + const Context& context, const string& fs, ReferenceMode md, const vector<ConnectionPtr>& fixedConns) : Reference(inst, com, ident, context, fs, md, false), _fixedConnections(fixedConns) @@ -527,52 +561,89 @@ IceInternal::FixedReference::toString() const ConnectionPtr IceInternal::FixedReference::getConnection() const { + vector<ConnectionPtr> connections = _fixedConnections; + switch(getMode()) + { + case ReferenceModeTwoway: + case ReferenceModeOneway: +#ifdef ICEE_HAS_BATCH + case ReferenceModeBatchOneway: +#endif + { + // + // Filter out datagram connections. + // + connections.erase(remove_if(connections.begin(), connections.end(), ConnectionIsDatagram()), + connections.end()); + break; + } + + case ReferenceModeDatagram: +#ifdef ICEE_HAS_BATCH + case ReferenceModeBatchDatagram: +#endif + { + // + // Filter out non-datagram connections. + // + connections.erase(remove_if(connections.begin(), connections.end(), not1(ConnectionIsDatagram())), + connections.end()); + break; + } + +#ifndef ICEE_HAS_BATCH + case ReferenceModeBatchDatagram: + case ReferenceModeBatchOneway: + { + throw FeatureNotSupportedException(__FILE__, __LINE__, "batch proxy mode"); + } +#endif + } + // // Randomize the order of connections. // - // If a reference is secure or the mode is datagram or batch - // datagram then we throw a NoEndpointException since IceE lacks - // this support. + random_shuffle(connections.begin(), connections.end()); + // - if(getSecure() || getMode() == ModeDatagram || getMode() == ModeBatchDatagram || _fixedConnections.empty() -#ifndef ICEE_HAS_BATCH - || getMode() == ModeBatchOneway -#endif - ) + // If a secure connection is requested or secure overrides is set, + // remove all non-secure connections. Otherwise make non-secure + // connections preferred over secure connections by partitioning + // the connection vector, so that non-secure connections come + // first. + // + // NOTE: we don't use the stable_partition algorithm from STL to + // keep the code size down. + // + vector<ConnectionPtr>::iterator p = connections.begin(); + vector<ConnectionPtr> secureConnections; + while(p != connections.end()) { - if(_fixedConnections.empty()) + if((*p)->endpoint()->secure()) { - NoEndpointException ex(__FILE__, __LINE__); - ex.proxy = ""; // No stringified representation for fixed proxies. - throw ex; + secureConnections.push_back(*p); + p = connections.erase(p); } - - FeatureNotSupportedException ex(__FILE__, __LINE__); - if(getSecure()) - { - ex.unsupportedFeature = "ssl"; - } - else if(getMode() == ModeDatagram) - { - ex.unsupportedFeature = "datagram"; - } - else if(getMode() == ModeBatchDatagram) - { - ex.unsupportedFeature = "batch datagram"; - } -#ifndef ICEE_HAS_BATCH - else if(getMode() == ModeBatchOneway) + else { - ex.unsupportedFeature = "batch"; + ++p; } -#endif - throw ex; + } + if(getSecure()) + { + connections.swap(secureConnections); + } + else + { + connections.insert(connections.end(), secureConnections.begin(), secureConnections.end()); + } + + if(connections.empty()) + { + throw NoEndpointException(__FILE__, __LINE__); // No stringified representation for fixed proxies. } - vector<ConnectionPtr> randomCons = _fixedConnections; - random_shuffle(randomCons.begin(), randomCons.end()); - - ConnectionPtr connection = randomCons[0]; + ConnectionPtr connection = connections[0]; assert(connection); connection->throwException(); // Throw in case our connection is already destroyed. @@ -699,7 +770,7 @@ IceInternal::RoutableReference::operator<(const Reference& r) const IceInternal::RoutableReference::RoutableReference(const InstancePtr& inst, const CommunicatorPtr& com, const Identity& ident, const Context& context, const string& fs, - Mode md, bool sec, const RouterInfoPtr& rtrInfo) : + ReferenceMode md, bool sec, const RouterInfoPtr& rtrInfo) : Reference(inst, com, ident, context, fs, md, sec), _routerInfo(rtrInfo) { } @@ -715,7 +786,7 @@ IceUtil::Shared* IceInternal::upCast(IceInternal::DirectReference* p) { return p #ifdef ICEE_HAS_ROUTER IceInternal::DirectReference::DirectReference(const InstancePtr& inst, const CommunicatorPtr& com, - const Identity& ident, const Context& context, const string& fs, Mode md, + const Identity& ident, const Context& context, const string& fs, ReferenceMode md, bool sec, const vector<EndpointPtr>& endpts, const RouterInfoPtr& rtrInfo) : @@ -725,7 +796,7 @@ IceInternal::DirectReference::DirectReference(const InstancePtr& inst, const Com } #else IceInternal::DirectReference::DirectReference(const InstancePtr& inst, const CommunicatorPtr& com, - const Identity& ident, const Context& context, const string& fs, Mode md, + const Identity& ident, const Context& context, const string& fs, ReferenceMode md, bool sec, const vector<EndpointPtr>& endpts) : Reference(inst, com, ident, context, fs, md, sec), _endpoints(endpts) @@ -852,9 +923,7 @@ IceInternal::DirectReference::getConnection() const vector<EndpointPtr> filteredEndpoints = filterEndpoints(endpts, getMode(), getSecure()); if(filteredEndpoints.empty()) { - NoEndpointException ex(__FILE__, __LINE__); - ex.proxy = toString(); - throw ex; + throw NoEndpointException(__FILE__, __LINE__, toString()); } OutgoingConnectionFactoryPtr factory = getInstance()->outgoingConnectionFactory(); @@ -930,7 +999,7 @@ IceUtil::Shared* IceInternal::upCast(IceInternal::IndirectReference* p) { return #ifdef ICEE_HAS_ROUTER IceInternal::IndirectReference::IndirectReference(const InstancePtr& inst, const CommunicatorPtr& com, const Identity& ident, const Context& context, const string& fs, - Mode md, bool sec, const string& adptid, + ReferenceMode md, bool sec, const string& adptid, const RouterInfoPtr& rtrInfo, const LocatorInfoPtr& locInfo) : RoutableReference(inst, com, ident, context, fs, md, sec, rtrInfo), _adapterId(adptid), @@ -940,7 +1009,7 @@ IceInternal::IndirectReference::IndirectReference(const InstancePtr& inst, const #else IceInternal::IndirectReference::IndirectReference(const InstancePtr& inst, const CommunicatorPtr& com, const Identity& ident, const Context& context, const string& fs, - Mode md, bool sec, const string& adptid, + ReferenceMode md, bool sec, const string& adptid, const LocatorInfoPtr& locInfo) : Reference(inst, com, ident, context, fs, md, sec), _adapterId(adptid), @@ -1064,9 +1133,7 @@ IceInternal::IndirectReference::getConnection() const vector<EndpointPtr> filteredEndpoints = filterEndpoints(endpts, getMode(), getSecure()); if(filteredEndpoints.empty()) { - NoEndpointException ex(__FILE__, __LINE__); - ex.proxy = toString(); - throw ex; + throw NoEndpointException(__FILE__, __LINE__, toString()); } try @@ -1201,56 +1268,95 @@ IceInternal::IndirectReference::IndirectReference(const IndirectReference& r) #endif // ICEE_HAS_LOCATOR vector<EndpointPtr> -IceInternal::filterEndpoints(const vector<EndpointPtr>& allEndpoints, Reference::Mode m, bool sec) +IceInternal::filterEndpoints(const vector<EndpointPtr>& allEndpoints, ReferenceMode m, bool sec) { - vector<EndpointPtr> endpoints; + vector<EndpointPtr> endpoints = allEndpoints; // - // If a secure endpoint, batch (if batch is not supported), - // datagram or batch datagram endpoint is requested since IceE - // lacks this support we throw an unsupported feature. + // Filter out unknown endpoints. // - if(sec || m == Reference::ModeDatagram || m == Reference::ModeBatchDatagram -#ifndef ICEE_HAS_BATCH - || m == Reference::ModeBatchOneway -#endif - ) + endpoints.erase(remove_if(endpoints.begin(), endpoints.end(), Ice::constMemFun(&Endpoint::unknown)), + endpoints.end()); + + // + // Filter out endpoints according to the mode of the reference. + // + switch(m) { - FeatureNotSupportedException ex(__FILE__, __LINE__); - if(sec) - { - ex.unsupportedFeature = "ssl"; - } - else if(m == Reference::ModeDatagram) - { - ex.unsupportedFeature = "datagram"; - } - else if(m == Reference::ModeBatchDatagram) - { - ex.unsupportedFeature = "batch datagram"; - } + case ReferenceModeTwoway: + case ReferenceModeOneway: +#ifdef ICEE_HAS_BATCH + case ReferenceModeBatchOneway: +#endif + { + // + // Filter out datagram endpoints. + // + endpoints.erase(remove_if(endpoints.begin(), endpoints.end(), Ice::constMemFun(&Endpoint::datagram)), + endpoints.end()); + break; + } + + case ReferenceModeDatagram: +#ifdef ICEE_HAS_BATCH + case ReferenceModeBatchDatagram: +#endif + { + // + // Filter out non-datagram endpoints. + // + endpoints.erase(remove_if(endpoints.begin(), endpoints.end(), + not1(Ice::constMemFun(&Endpoint::datagram))), + endpoints.end()); + break; + } + #ifndef ICEE_HAS_BATCH - else if(m == Reference::ModeBatchOneway) + case ReferenceModeBatchDatagram: + case ReferenceModeBatchOneway: { - ex.unsupportedFeature = "batch"; + throw FeatureNotSupportedException(__FILE__, __LINE__, "batch proxy mode"); } #endif - ex.unsupportedFeature += " proxy mode"; - throw ex; } - endpoints = allEndpoints; - - // - // Filter out unknown endpoints. - // - endpoints.erase(remove_if(endpoints.begin(), endpoints.end(), Ice::constMemFun(&Endpoint::unknown)), - endpoints.end()); - // // Randomize the order of endpoints. // random_shuffle(endpoints.begin(), endpoints.end()); + // + // If a secure connection is requested or secure overrides is set, + // remove all non-secure endpoints. Otherwise make non-secure + // endpoints preferred over secure endpoints by partitioning + // the endpoint vector, so that non-secure endpoints come + // first. + // + // NOTE: we don't use the stable_partition algorithm from STL to + // keep the code size down. + // + vector<EndpointPtr>::iterator p = endpoints.begin(); + vector<EndpointPtr> secureEndpoints; + while(p != endpoints.end()) + { + if((*p)->secure()) + { + secureEndpoints.push_back(*p); + p = endpoints.erase(p); + } + else + { + ++p; + } + } + if(sec) + { + endpoints.swap(secureEndpoints); + } + else + { + endpoints.insert(endpoints.end(), secureEndpoints.begin(), secureEndpoints.end()); + } + return endpoints; } |