diff options
author | Stephen D. Huston <shuston@apache.org> | 2011-10-21 14:42:12 +0000 |
---|---|---|
committer | Stephen D. Huston <shuston@apache.org> | 2011-10-21 14:42:12 +0000 |
commit | f83677056891e436bf5ba99e79240df2a44528cd (patch) | |
tree | 625bfd644b948e89105630759cf6decb0435354d /cpp/src/qpid/broker/ConnectionHandler.cpp | |
parent | ebfd9ff053b04ab379acfc0fefedee5a31b6d8a5 (diff) | |
download | qpid-python-QPID-2519.tar.gz |
Merged out from trunkQPID-2519
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/QPID-2519@1187375 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid/broker/ConnectionHandler.cpp')
-rw-r--r-- | cpp/src/qpid/broker/ConnectionHandler.cpp | 78 |
1 files changed, 57 insertions, 21 deletions
diff --git a/cpp/src/qpid/broker/ConnectionHandler.cpp b/cpp/src/qpid/broker/ConnectionHandler.cpp index 3f97e5b9de..7cd91ae539 100644 --- a/cpp/src/qpid/broker/ConnectionHandler.cpp +++ b/cpp/src/qpid/broker/ConnectionHandler.cpp @@ -26,6 +26,7 @@ #include "qpid/broker/SecureConnection.h" #include "qpid/Url.h" #include "qpid/framing/AllInvoker.h" +#include "qpid/framing/ConnectionStartOkBody.h" #include "qpid/framing/enum.h" #include "qpid/log/Statement.h" #include "qpid/sys/SecurityLayer.h" @@ -63,13 +64,31 @@ void ConnectionHandler::heartbeat() handler->proxy.heartbeat(); } +bool ConnectionHandler::handle(const framing::AMQMethodBody& method) +{ + //Need special handling for start-ok, in order to distinguish + //between null and empty response + if (method.isA<ConnectionStartOkBody>()) { + handler->startOk(dynamic_cast<const ConnectionStartOkBody&>(method)); + return true; + } else { + return invoke(static_cast<AMQP_AllOperations::ConnectionHandler&>(*handler), method); + } +} + void ConnectionHandler::handle(framing::AMQFrame& frame) { AMQMethodBody* method=frame.getBody()->getMethod(); Connection::ErrorListener* errorListener = handler->connection.getErrorListener(); try{ - if (!invoke(static_cast<AMQP_AllOperations::ConnectionHandler&>(*handler.get()), *method)) { + if (method && handle(*method)) { + // This is a connection control frame, nothing more to do. + } else if (isOpen()) { handler->connection.getChannel(frame.getChannel()).in(frame); + } else { + handler->proxy.close( + connection::CLOSE_CODE_FRAMING_ERROR, + "Connection not yet open, invalid frame received."); } }catch(ConnectionException& e){ if (errorListener) errorListener->connectionError(e.what()); @@ -89,13 +108,10 @@ ConnectionHandler::ConnectionHandler(Connection& connection, bool isClient, bool ConnectionHandler::Handler::Handler(Connection& c, bool isClient, bool isShadow) : proxy(c.getOutput()), - connection(c), serverMode(!isClient), acl(0), secured(0), + connection(c), serverMode(!isClient), secured(0), isOpen(false) { if (serverMode) { - - acl = connection.getBroker().getAcl(); - FieldTable properties; Array mechanisms(0x95); @@ -118,13 +134,20 @@ ConnectionHandler::Handler::Handler(Connection& c, bool isClient, bool isShadow) ConnectionHandler::Handler::~Handler() {} -void ConnectionHandler::Handler::startOk(const framing::FieldTable& clientProperties, - const string& mechanism, - const string& response, +void ConnectionHandler::Handler::startOk(const framing::FieldTable& /*clientProperties*/, + const string& /*mechanism*/, + const string& /*response*/, const string& /*locale*/) { + //Need special handling for start-ok, in order to distinguish + //between null and empty response -> should never use this method + assert(false); +} + +void ConnectionHandler::Handler::startOk(const ConnectionStartOkBody& body) +{ try { - authenticator->start(mechanism, response); + authenticator->start(body.getMechanism(), body.hasResponse() ? &body.getResponse() : 0); } catch (std::exception& /*e*/) { management::ManagementAgent* agent = connection.getAgent(); if (agent) { @@ -136,9 +159,14 @@ void ConnectionHandler::Handler::startOk(const framing::FieldTable& clientProper } throw; } + const framing::FieldTable& clientProperties = body.getClientProperties(); connection.setFederationLink(clientProperties.get(QPID_FED_LINK)); - connection.setFederationPeerTag(clientProperties.getAsString(QPID_FED_TAG)); + if (clientProperties.isSet(QPID_FED_TAG)) { + connection.setFederationPeerTag(clientProperties.getAsString(QPID_FED_TAG)); + } if (connection.isFederationLink()) { + AclModule* acl = connection.getBroker().getAcl(); + FieldTable properties; if (acl && !acl->authorise(connection.getUserId(),acl::ACT_CREATE,acl::OBJ_LINK,"")){ proxy.close(framing::connection::CLOSE_CODE_CONNECTION_FORCED,"ACL denied creating a federation link"); return; @@ -183,7 +211,7 @@ void ConnectionHandler::Handler::secureOk(const string& response) void ConnectionHandler::Handler::tuneOk(uint16_t /*channelmax*/, uint16_t framemax, uint16_t heartbeat) { - connection.setFrameMax(framemax); + if (framemax) connection.setFrameMax(framemax); connection.setHeartbeatInterval(heartbeat); } @@ -256,7 +284,6 @@ void ConnectionHandler::Handler::start(const FieldTable& serverProperties, false ); // disallow interaction } std::string supportedMechanismsList; - bool requestedMechanismIsSupported = false; Array::const_iterator i; /* @@ -269,11 +296,9 @@ void ConnectionHandler::Handler::start(const FieldTable& serverProperties, if (i != supportedMechanisms.begin()) supportedMechanismsList += SPACE; supportedMechanismsList += (*i)->get<std::string>(); - requestedMechanismIsSupported = true; } } else { - requestedMechanismIsSupported = false; /* The caller has requested a mechanism. If it's available, make sure it ends up at the head of the list. @@ -282,7 +307,6 @@ void ConnectionHandler::Handler::start(const FieldTable& serverProperties, string currentMechanism = (*i)->get<std::string>(); if ( requestedMechanism == currentMechanism ) { - requestedMechanismIsSupported = true; supportedMechanismsList = currentMechanism + SPACE + supportedMechanismsList; } else { if (i != supportedMechanisms.begin()) @@ -292,7 +316,9 @@ void ConnectionHandler::Handler::start(const FieldTable& serverProperties, } } - connection.setFederationPeerTag(serverProperties.getAsString(QPID_FED_TAG)); + if (serverProperties.isSet(QPID_FED_TAG)) { + connection.setFederationPeerTag(serverProperties.getAsString(QPID_FED_TAG)); + } FieldTable ft; ft.setInt(QPID_FED_LINK,1); @@ -301,11 +327,21 @@ void ConnectionHandler::Handler::start(const FieldTable& serverProperties, string response; if (sasl.get()) { const qpid::sys::SecuritySettings& ss = connection.getExternalSecuritySettings(); - response = sasl->start ( requestedMechanism.empty() - ? supportedMechanismsList - : requestedMechanism, - & ss ); - proxy.startOk ( ft, sasl->getMechanism(), response, en_US ); + if (sasl->start ( requestedMechanism.empty() + ? supportedMechanismsList + : requestedMechanism, + response, + & ss )) { + proxy.startOk ( ft, sasl->getMechanism(), response, en_US ); + } else { + //response was null + ConnectionStartOkBody body; + body.setClientProperties(ft); + body.setMechanism(sasl->getMechanism()); + //Don't set response, as none was given + body.setLocale(en_US); + proxy.send(body); + } } else { response = ((char)0) + username + ((char)0) + password; |