summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/Connection.cpp
diff options
context:
space:
mode:
authorMarc Laukien <marc@zeroc.com>2002-09-26 20:05:00 +0000
committerMarc Laukien <marc@zeroc.com>2002-09-26 20:05:00 +0000
commit57ec89e8da9e0d0f7ecd4ed6b144d068513371b1 (patch)
treec5e80d25f5e3b2bcd818d00a1686ccdaa0076a14 /cpp/src/Ice/Connection.cpp
parentdo not commit servant after destroyObject (diff)
downloadice-57ec89e8da9e0d0f7ecd4ed6b144d068513371b1.tar.bz2
ice-57ec89e8da9e0d0f7ecd4ed6b144d068513371b1.tar.xz
ice-57ec89e8da9e0d0f7ecd4ed6b144d068513371b1.zip
rewrote connection validation code
Diffstat (limited to 'cpp/src/Ice/Connection.cpp')
-rw-r--r--cpp/src/Ice/Connection.cpp189
1 files changed, 84 insertions, 105 deletions
diff --git a/cpp/src/Ice/Connection.cpp b/cpp/src/Ice/Connection.cpp
index a48b9649f4a..0a824b0a0fa 100644
--- a/cpp/src/Ice/Connection.cpp
+++ b/cpp/src/Ice/Connection.cpp
@@ -39,6 +39,85 @@ IceInternal::Connection::destroyed() const
}
void
+IceInternal::Connection::validate()
+{
+ IceUtil::RecMutex::Lock sync(*this);
+
+ if(_endpoint->datagram())
+ {
+ //
+ // Datagram connections are always implicitly validated.
+ //
+ return;
+ }
+
+ try
+ {
+ if(_adapter)
+ {
+ //
+ // Incoming connections play the active role with respect to
+ // connection validation.
+ //
+ BasicStream os(_instance);
+ os.write(protocolVersion);
+ os.write(encodingVersion);
+ os.write(validateConnectionMsg);
+ os.write(headerSize); // Message size.
+ os.i = os.b.begin();
+ traceHeader("sending validate connection", os, _logger, _traceLevels);
+ _transceiver->write(os, _endpoint->timeout());
+ }
+ else
+ {
+ //
+ // Outgoing connection play the passive role with respect to
+ // connection validation.
+ //
+ BasicStream is(_instance);
+ is.b.resize(headerSize);
+ is.i = is.b.begin();
+ _transceiver->read(is, _endpoint->timeout());
+ assert(is.i == is.b.end());
+ int pos = is.i - is.b.begin();
+ assert(pos >= headerSize);
+ is.i = is.b.begin();
+ Byte protVer;
+ is.read(protVer);
+ if(protVer != protocolVersion)
+ {
+ throw UnsupportedProtocolException(__FILE__, __LINE__);
+ }
+ Byte encVer;
+ is.read(encVer);
+ if(encVer != encodingVersion)
+ {
+ throw UnsupportedEncodingException(__FILE__, __LINE__);
+ }
+ Byte messageType;
+ is.read(messageType);
+ if(messageType != validateConnectionMsg)
+ {
+ throw ConnectionNotValidatedException(__FILE__, __LINE__);
+ }
+ Int size;
+ is.read(size);
+ if(size != headerSize)
+ {
+ throw IllegalMessageSizeException(__FILE__, __LINE__);
+ }
+ traceHeader("received validate connection", is, _logger, _traceLevels);
+ }
+ }
+ catch(const LocalException& ex)
+ {
+ setState(StateClosed, ex);
+ assert(_exception.get());
+ _exception->ice_throw();
+ }
+}
+
+void
IceInternal::Connection::hold()
{
IceUtil::RecMutex::Lock sync(*this);
@@ -416,22 +495,6 @@ IceInternal::Connection::message(BasicStream& stream, const ThreadPoolPtr& threa
stream.read(messageType);
//
- // Check whether the connection is validated.
- //
- if(!_connectionValidated && messageType != validateConnectionMsg)
- {
- //
- // Yes, we must set _connectionValidated to true
- // here. The connection gets implicitly validated by
- // any kind of message. However, it's still a protocol
- // error like any other if no explicit connection
- // validation message was sent first.
- //
- _connectionValidated = true;
- throw ConnectionNotValidatedException(__FILE__, __LINE__);
- }
-
- //
// Uncompress if necessary.
//
if(messageType == compressedRequestMsg ||
@@ -567,18 +630,11 @@ IceInternal::Connection::message(BasicStream& stream, const ThreadPoolPtr& threa
case validateConnectionMsg:
{
traceHeader("received validate connection", stream, _logger, _traceLevels);
- if(_endpoint->datagram())
- {
- if(_warn)
- {
- Warning out(_logger);
- out << "ignoring validate connection message for datagram connection:\n"
- << _transceiver->toString();
- }
- }
- else
+ if(_warn)
{
- _connectionValidated = true;
+ Warning out(_logger);
+ out << "ignoring unexpected validate connection message:\n"
+ << _transceiver->toString();
}
break;
}
@@ -822,49 +878,6 @@ IceInternal::Connection::Connection(const InstancePtr& instance,
_state(StateHolding),
_registeredWithPool(false)
{
- if(_endpoint->datagram())
- {
- //
- // Datagram connections are always implicitly validated.
- //
- _connectionValidated = true;
- }
- else
- {
- if(_adapter)
- {
- //
- // Incoming connections play the active role with respect
- // to connection validation, and are implicitly validated.
- //
- try
- {
- validateConnection();
- }
- catch(const LocalException& ex)
- {
- if(_warn)
- {
- Warning out(_logger);
- out << "connection exception:\n" << ex << '\n' << _transceiver->toString();
- }
- _transceiver->close();
- _state = StateClosed;
- ex.ice_throw();
- }
-
- _connectionValidated = true;
- }
- else
- {
- //
- // Outgoing connections are passive with respect to
- // validation, i.e., they wait until they get a validate
- // connection message from the server.
- //
- _connectionValidated = false;
- }
- }
}
IceInternal::Connection::~Connection()
@@ -903,28 +916,7 @@ IceInternal::Connection::setState(State state, const LocalException& ex)
if(!_exception.get())
{
- if(!_connectionValidated && dynamic_cast<const ConnectionLostException*>(&ex))
- {
- //
- // If the connection has not been validated yet, we treat
- // a connection loss just as if we would have received a
- // close connection messsage. This way, Ice will retry a
- // request if the peer just accepts and closes a
- // connection. This can happen, for example, if a
- // connection is in the server's backlog, but not yet
- // accepted by the server. In such case, the connection
- // has been established from the client point of view, but
- // not yet from the server point of view. If the server
- // then closes the acceptor socket, the client will get a
- // connection loss without receiving an explicit close
- // connection message first.
- //
- _exception = auto_ptr<LocalException>(new CloseConnectionException(__FILE__, __LINE__));
- }
- else
- {
- _exception = auto_ptr<LocalException>(dynamic_cast<LocalException*>(ex.ice_clone()));
- }
+ _exception = auto_ptr<LocalException>(dynamic_cast<LocalException*>(ex.ice_clone()));
if(_warn)
{
@@ -1039,19 +1031,6 @@ IceInternal::Connection::setState(State state)
}
void
-IceInternal::Connection::validateConnection() const
-{
- BasicStream os(_instance);
- os.write(protocolVersion);
- os.write(encodingVersion);
- os.write(validateConnectionMsg);
- os.write(headerSize); // Message size.
- os.i = os.b.begin();
- traceHeader("sending validate connection", os, _logger, _traceLevels);
- _transceiver->write(os, _endpoint->timeout());
-}
-
-void
IceInternal::Connection::closeConnection() const
{
BasicStream os(_instance);