protected void StartAndTune()
{
BlockingCell connectionStartCell = new BlockingCell();
m_model0.m_connectionStartCell = connectionStartCell;
m_frameHandler.Timeout = HandshakeTimeout;
m_frameHandler.SendHeader();
ConnectionStartDetails connectionStart = (ConnectionStartDetails)
connectionStartCell.Value;
if (connectionStart == null){
throw new IOException("connection.start was never received, likely due to a network timeout");
}
ServerProperties = connectionStart.m_serverProperties;
AmqpVersion serverVersion = new AmqpVersion(connectionStart.m_versionMajor,
connectionStart.m_versionMinor);
if (!serverVersion.Equals(Protocol.Version))
{
TerminateMainloop();
FinishClose();
throw new ProtocolVersionMismatchException(Protocol.MajorVersion,
Protocol.MinorVersion,
serverVersion.Major,
serverVersion.Minor);
}
m_clientProperties = new Dictionary<string, object>(m_factory.ClientProperties);
m_clientProperties["capabilities"] = Protocol.Capabilities;
// FIXME: parse out locales properly!
ConnectionTuneDetails connectionTune = default(ConnectionTuneDetails);
bool tuned = false;
try
{
string mechanismsString = Encoding.UTF8.GetString(connectionStart.m_mechanisms);
string[] mechanisms = mechanismsString.Split(' ');
AuthMechanismFactory mechanismFactory = m_factory.AuthMechanismFactory(mechanisms);
if (mechanismFactory == null) {
throw new IOException("No compatible authentication mechanism found - " +
"server offered [" + mechanismsString + "]");
}
AuthMechanism mechanism = mechanismFactory.GetInstance();
byte[] challenge = null;
do {
byte[] response = mechanism.handleChallenge(challenge, m_factory);
ConnectionSecureOrTune res;
if (challenge == null) {
res = m_model0.ConnectionStartOk(m_clientProperties,
mechanismFactory.Name,
response,
"en_US");
}
else {
res = m_model0.ConnectionSecureOk(response);
}
if (res.m_challenge == null) {
connectionTune = res.m_tuneDetails;
tuned = true;
} else {
challenge = res.m_challenge;
}
} while (!tuned);
}
catch (OperationInterruptedException e)
{
if (e.ShutdownReason != null && e.ShutdownReason.ReplyCode == CommonFraming.Constants.AccessRefused)
{
throw new AuthenticationFailureException(e.ShutdownReason.ReplyText);
}
throw new PossibleAuthenticationFailureException(
"Possibly caused by authentication failure", e);
}
ushort channelMax = (ushort) NegotiatedMaxValue(m_factory.RequestedChannelMax,
connectionTune.m_channelMax);
m_sessionManager = new SessionManager(this, channelMax);
uint frameMax = NegotiatedMaxValue(m_factory.RequestedFrameMax,
connectionTune.m_frameMax);
FrameMax = frameMax;
ushort heartbeat = (ushort) NegotiatedMaxValue(m_factory.RequestedHeartbeat,
connectionTune.m_heartbeat);
Heartbeat = heartbeat;
m_model0.ConnectionTuneOk(channelMax,
frameMax,
heartbeat);
}