private async Task StartSessionAsync(int millisecondsTimeout) { await OpenSocketAsync(millisecondsTimeout); _writeBuffer = new WriteBuffer(_awaitableSocket); _readBuffer = new ReadBuffer(_awaitableSocket); await WriteStartupAsync(); await _readBuffer.ReceiveAsync(); read: var message = _readBuffer.ReadMessage(); switch (message.Type) { case MessageType.AuthenticationRequest: { var authenticationRequestType = (AuthenticationRequestType)_readBuffer.ReadInt(); switch (authenticationRequestType) { case AuthenticationRequestType.AuthenticationOk: { return; } case AuthenticationRequestType.AuthenticationMD5Password: { var salt = _readBuffer.ReadBytes(4); var hash = Hashing.CreateMD5(_password, _user, salt); await _writeBuffer .StartMessage('p') .WriteBytes(hash) .EndMessage() .FlushAsync(); await _readBuffer.ReceiveAsync(); goto read; } default: throw new NotImplementedException(authenticationRequestType.ToString()); } } case MessageType.ErrorResponse: throw new InvalidOperationException(_readBuffer.ReadErrorMessage()); case MessageType.BackendKeyData: case MessageType.EmptyQueryResponse: case MessageType.ParameterStatus: case MessageType.ReadyForQuery: throw new NotImplementedException($"Unhandled MessageType '{message.Type}'"); default: throw new InvalidOperationException($"Unexpected MessageType '{message.Type}'"); } }