public async Task ConnectAsync(ConnectionSettings cs, IOBehavior ioBehavior, CancellationToken cancellationToken) { lock (m_lock) { VerifyState(State.Created); m_state = State.Connecting; } var connected = false; if (cs.ConnectionType == ConnectionType.Tcp) { connected = await OpenTcpSocketAsync(cs, ioBehavior, cancellationToken).ConfigureAwait(false); } else if (cs.ConnectionType == ConnectionType.Unix) { connected = await OpenUnixSocketAsync(cs, ioBehavior, cancellationToken).ConfigureAwait(false); } if (!connected) { lock (m_lock) m_state = State.Failed; throw new MySqlException("Unable to connect to any of the specified MySQL hosts."); } var byteHandler = new SocketByteHandler(m_socket); m_payloadHandler = new StandardPayloadHandler(byteHandler); var payload = await ReceiveAsync(ioBehavior, cancellationToken).ConfigureAwait(false); var reader = new ByteArrayReader(payload.ArraySegment.Array, payload.ArraySegment.Offset, payload.ArraySegment.Count); var initialHandshake = new InitialHandshakePacket(reader); // if PluginAuth is supported, then use the specified auth plugin; else, fall back to protocol capabilities to determine the auth type to use string authPluginName; if ((initialHandshake.ProtocolCapabilities & ProtocolCapabilities.PluginAuth) != 0) { authPluginName = initialHandshake.AuthPluginName; } else { authPluginName = (initialHandshake.ProtocolCapabilities & ProtocolCapabilities.SecureConnection) == 0 ? "mysql_old_password" : "mysql_native_password"; } if (authPluginName != "mysql_native_password" && authPluginName != "sha256_password") { throw new NotSupportedException("Authentication method '{0}' is not supported.".FormatInvariant(initialHandshake.AuthPluginName)); } ServerVersion = new ServerVersion(Encoding.ASCII.GetString(initialHandshake.ServerVersion)); ConnectionId = initialHandshake.ConnectionId; AuthPluginData = initialHandshake.AuthPluginData; m_useCompression = cs.UseCompression && (initialHandshake.ProtocolCapabilities & ProtocolCapabilities.Compress) != 0; var serverSupportsSsl = (initialHandshake.ProtocolCapabilities & ProtocolCapabilities.Ssl) != 0; if (cs.SslMode != MySqlSslMode.None && (cs.SslMode != MySqlSslMode.Preferred || serverSupportsSsl)) { if (!serverSupportsSsl) { throw new MySqlException("Server does not support SSL"); } await InitSslAsync(initialHandshake.ProtocolCapabilities, cs, ioBehavior, cancellationToken).ConfigureAwait(false); } m_supportsConnectionAttributes = (initialHandshake.ProtocolCapabilities & ProtocolCapabilities.ConnectionAttributes) != 0; if (m_supportsConnectionAttributes && s_connectionAttributes == null) { s_connectionAttributes = CreateConnectionAttributes(); } var response = HandshakeResponse41Packet.Create(initialHandshake, cs, m_useCompression, m_supportsConnectionAttributes ? s_connectionAttributes : null); payload = new PayloadData(new ArraySegment <byte>(response)); await SendReplyAsync(payload, ioBehavior, cancellationToken).ConfigureAwait(false); payload = await ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false); // if server doesn't support the authentication fast path, it will send a new challenge if (payload.HeaderByte == AuthenticationMethodSwitchRequestPayload.Signature) { await SwitchAuthenticationAsync(cs, payload, ioBehavior, cancellationToken).ConfigureAwait(false); payload = await ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false); } OkPayload.Create(payload); if (m_useCompression) { m_payloadHandler = new CompressedPayloadHandler(m_payloadHandler.ByteHandler); } }