void StartAndTune() { var connectionStartCell = new BlockingCell <ConnectionStartDetails>(); m_model0.m_connectionStartCell = connectionStartCell; m_model0.HandshakeContinuationTimeout = m_factory.HandshakeContinuationTimeout; m_frameHandler.ReadTimeout = (int)m_factory.HandshakeContinuationTimeout.TotalMilliseconds; m_frameHandler.SendHeader(); var connectionStart = connectionStartCell.WaitForValue(); if (connectionStart == null) { throw new IOException("connection.start was never received, likely due to a network timeout"); } ServerProperties = connectionStart.m_serverProperties; var 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; m_clientProperties["connection_name"] = this.ClientProvidedName; // FIXME: parse out locales properly! ConnectionTuneDetails connectionTune = default(ConnectionTuneDetails); bool tuned = false; try { string mechanismsString = Encoding.UTF8.GetString(connectionStart.m_mechanisms, 0, connectionStart.m_mechanisms.Length); 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 == Constants.AccessRefused) { throw new AuthenticationFailureException(e.ShutdownReason.ReplyText); } throw new PossibleAuthenticationFailureException( "Possibly caused by authentication failure", e); } var 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; var heartbeat = (ushort)NegotiatedMaxValue(m_factory.RequestedHeartbeat, connectionTune.m_heartbeat); Heartbeat = heartbeat; m_model0.ConnectionTuneOk(channelMax, frameMax, heartbeat); // now we can start heartbeat timers MaybeStartHeartbeatTimers(); }
private void StartAndTune() { var connectionStartCell = new BlockingCell <ConnectionStartDetails>(); _model0.m_connectionStartCell = connectionStartCell; _model0.HandshakeContinuationTimeout = _config.HandshakeContinuationTimeout; _frameHandler.ReadTimeout = _config.HandshakeContinuationTimeout; _frameHandler.SendHeader(); ConnectionStartDetails connectionStart = connectionStartCell.WaitForValue(); if (connectionStart is null) { throw new IOException("connection.start was never received, likely due to a network timeout"); } ServerProperties = connectionStart.m_serverProperties; var 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); } // FIXME: parse out locales properly! ConnectionTuneDetails connectionTune = default; bool tuned = false; try { string mechanismsString = Encoding.UTF8.GetString(connectionStart.m_mechanisms); IAuthMechanismFactory mechanismFactory = GetAuthMechanismFactory(mechanismsString); IAuthMechanism mechanism = mechanismFactory.GetInstance(); byte[]? challenge = null; do { byte[] response = mechanism.handleChallenge(challenge, _config); ConnectionSecureOrTune res; if (challenge is null) { res = _model0.ConnectionStartOk(ClientProperties, mechanismFactory.Name, response, "en_US"); } else { res = _model0.ConnectionSecureOk(response); } if (res.m_challenge is null) { connectionTune = res.m_tuneDetails; tuned = true; } else { challenge = res.m_challenge; } }while (!tuned); } catch (OperationInterruptedException e) { if (e.ShutdownReason != null && e.ShutdownReason.ReplyCode == Constants.AccessRefused) { throw new AuthenticationFailureException(e.ShutdownReason.ReplyText); } throw new PossibleAuthenticationFailureException( "Possibly caused by authentication failure", e); } ushort channelMax = (ushort)NegotiatedMaxValue(_config.MaxChannelCount, connectionTune.m_channelMax); _sessionManager = new SessionManager(this, channelMax); uint frameMax = NegotiatedMaxValue(_config.MaxFrameSize, connectionTune.m_frameMax); FrameMax = frameMax; MaxPayloadSize = frameMax == 0 ? int.MaxValue : (int)frameMax - Client.Impl.Framing.BaseFrameSize; uint heartbeatInSeconds = NegotiatedMaxValue((uint)_config.HeartbeatInterval.TotalSeconds, (uint)connectionTune.m_heartbeatInSeconds); Heartbeat = TimeSpan.FromSeconds(heartbeatInSeconds); _model0.ConnectionTuneOk(channelMax, frameMax, (ushort)Heartbeat.TotalSeconds); // now we can start heartbeat timers MaybeStartHeartbeatTimers(); }