示例#1
0
        /// <summary>
        /// Performs client protocol handshake.
        /// </summary>
        private static void Handshake(Socket sock, ClientProtocolVersion version)
        {
            var res = SendReceive(sock, stream =>
            {
                // Handshake.
                stream.WriteByte(OpHandshake);

                // Protocol version.
                stream.WriteShort(version.Major);
                stream.WriteShort(version.Minor);
                stream.WriteShort(version.Maintenance);

                // Client type: platform.
                stream.WriteByte(ClientType);
            }, 20);

            using (var stream = new BinaryHeapStream(res))
            {
                var success = stream.ReadBool();

                if (success)
                {
                    return;
                }

                var serverVersion =
                    new ClientProtocolVersion(stream.ReadShort(), stream.ReadShort(), stream.ReadShort());

                var errMsg = BinaryUtils.Marshaller.Unmarshal <string>(stream);

                throw new IgniteClientException(string.Format(
                                                    "Client handhsake failed: '{0}'. Client version: {1}. Server version: {2}",
                                                    errMsg, version, serverVersion));
            }
        }
示例#2
0
        /// <summary>
        /// Handles the notification message, if present in the given stream.
        /// </summary>
        private bool HandleNotification(long requestId, BinaryHeapStream stream)
        {
            if (ServerVersion < Ver160)
            {
                return(false);
            }

            var flags = (ClientFlags)stream.ReadShort();

            stream.Seek(-2, SeekOrigin.Current);

            if ((flags & ClientFlags.Notification) != ClientFlags.Notification)
            {
                return(false);
            }

            var count = Interlocked.Decrement(ref _expectedNotifications);

            if (count < 0)
            {
                throw new IgniteClientException("Unexpected thin client notification: " + requestId);
            }

            _notificationListeners.GetOrAdd(requestId, _ => new ClientNotificationHandler(_logger))
            .Handle(stream, null);

            return(true);
        }
示例#3
0
        /// <summary>
        /// Performs client protocol handshake.
        /// </summary>
        private void Handshake(ClientProtocolVersion version)
        {
            // Send request.
            int messageLen;
            var buf = WriteMessage(stream =>
            {
                // Handshake.
                stream.WriteByte(OpHandshake);

                // Protocol version.
                stream.WriteShort(version.Major);
                stream.WriteShort(version.Minor);
                stream.WriteShort(version.Maintenance);

                // Client type: platform.
                stream.WriteByte(ClientType);
            }, 12, out messageLen);

            Debug.Assert(messageLen == 12);

            var sent = _socket.Send(buf, messageLen, SocketFlags.None);

            Debug.Assert(sent == messageLen);

            // Decode response.
            var res = ReceiveMessage();

            using (var stream = new BinaryHeapStream(res))
            {
                var success = stream.ReadBool();

                if (success)
                {
                    return;
                }

                var serverVersion =
                    new ClientProtocolVersion(stream.ReadShort(), stream.ReadShort(), stream.ReadShort());

                var errMsg = BinaryUtils.Marshaller.Unmarshal <string>(stream);

                throw new IgniteClientException(string.Format(
                                                    "Client handshake failed: '{0}'. Client version: {1}. Server version: {2}",
                                                    errMsg, version, serverVersion));
            }
        }
示例#4
0
        /// <summary>
        /// Decodes the response that we got from <see cref="HandleResponse"/>.
        /// </summary>
        private T DecodeResponse <T>(BinaryHeapStream stream, Func <ClientResponseContext, T> readFunc,
                                     Func <ClientStatusCode, string, T> errorFunc)
        {
            ClientStatusCode statusCode;

            if (ServerVersion >= Ver140)
            {
                var flags = (ClientFlags)stream.ReadShort();

                if ((flags & ClientFlags.AffinityTopologyChanged) == ClientFlags.AffinityTopologyChanged)
                {
                    var topVer = new AffinityTopologyVersion(stream.ReadLong(), stream.ReadInt());
                    if (_topVerCallback != null)
                    {
                        _topVerCallback(topVer);
                    }
                }

                statusCode = (flags & ClientFlags.Error) == ClientFlags.Error
                    ? (ClientStatusCode)stream.ReadInt()
                    : ClientStatusCode.Success;
            }
            else
            {
                statusCode = (ClientStatusCode)stream.ReadInt();
            }

            if (statusCode == ClientStatusCode.Success)
            {
                return(readFunc != null
                    ? readFunc(new ClientResponseContext(stream, this))
                    : default(T));
            }

            var msg = BinaryUtils.Marshaller.StartUnmarshal(stream).ReadString();

            if (errorFunc != null)
            {
                return(errorFunc(statusCode, msg));
            }

            throw new IgniteClientException(msg, null, statusCode);
        }
示例#5
0
        /// <summary>
        /// Handles the notification message, if present in the given stream.
        /// </summary>
        private bool HandleNotification(long requestId, BinaryHeapStream stream)
        {
            if (ServerVersion < Ver160)
            {
                return(false);
            }

            var flags = (ClientFlags)stream.ReadShort();

            stream.Seek(-2, SeekOrigin.Current);

            if ((flags & ClientFlags.Notification) != ClientFlags.Notification)
            {
                return(false);
            }

            _notificationListeners.GetOrAdd(requestId, _ => new ClientNotificationHandler(_logger))
            .Handle(stream, null);

            return(true);
        }
示例#6
0
        /// <summary>
        /// Performs client protocol handshake.
        /// </summary>
        private void Handshake(IgniteClientConfiguration clientConfiguration, ClientProtocolVersion version)
        {
            bool auth = version.CompareTo(Ver110) >= 0 && clientConfiguration.UserName != null;

            // Send request.
            int messageLen;
            var buf = WriteMessage(stream =>
            {
                // Handshake.
                stream.WriteByte(OpHandshake);

                // Protocol version.
                stream.WriteShort(version.Major);
                stream.WriteShort(version.Minor);
                stream.WriteShort(version.Maintenance);

                // Client type: platform.
                stream.WriteByte(ClientType);

                // Authentication data.
                if (auth)
                {
                    var writer = BinaryUtils.Marshaller.StartMarshal(stream);

                    writer.WriteString(clientConfiguration.UserName);
                    writer.WriteString(clientConfiguration.Password);

                    BinaryUtils.Marshaller.FinishMarshal(writer);
                }
            }, 12, out messageLen);

            SocketWrite(buf, messageLen);

            // Decode response.
            var res = ReceiveMessage();

            using (var stream = new BinaryHeapStream(res))
            {
                // Read input.
                var success = stream.ReadBool();

                if (success)
                {
                    if (version.CompareTo(Ver140) >= 0)
                    {
                        ServerNodeId = BinaryUtils.Marshaller.Unmarshal <Guid>(stream);
                    }

                    ServerVersion = version;

                    return;
                }

                ServerVersion =
                    new ClientProtocolVersion(stream.ReadShort(), stream.ReadShort(), stream.ReadShort());

                var errMsg = BinaryUtils.Marshaller.Unmarshal <string>(stream);

                ClientStatusCode errCode = ClientStatusCode.Fail;

                if (stream.Remaining > 0)
                {
                    errCode = (ClientStatusCode)stream.ReadInt();
                }

                // Authentication error is handled immediately.
                if (errCode == ClientStatusCode.AuthenticationFailed)
                {
                    throw new IgniteClientException(errMsg, null, ClientStatusCode.AuthenticationFailed);
                }

                // Re-try if possible.
                bool retry = ServerVersion.CompareTo(version) < 0 && ServerVersion.Equals(Ver100);

                if (retry)
                {
                    Handshake(clientConfiguration, ServerVersion);
                }
                else
                {
                    throw new IgniteClientException(string.Format(
                                                        "Client handshake failed: '{0}'. Client version: {1}. Server version: {2}",
                                                        errMsg, version, ServerVersion), null, errCode);
                }
            }
        }
示例#7
0
        /// <summary>
        /// Performs client protocol handshake.
        /// </summary>
        private ClientFeatures Handshake(IgniteClientConfiguration clientConfiguration, ClientProtocolVersion version)
        {
            var hasAuth     = version >= Ver110 && clientConfiguration.UserName != null;
            var hasFeatures = version >= Ver170;

            // Send request.
            int messageLen;
            var buf = WriteMessage(stream =>
            {
                // Handshake.
                stream.WriteByte(OpHandshake);

                // Protocol version.
                stream.WriteShort(version.Major);
                stream.WriteShort(version.Minor);
                stream.WriteShort(version.Maintenance);

                // Client type: platform.
                stream.WriteByte(ClientType);

                // Writing features.
                if (hasFeatures)
                {
                    BinaryUtils.Marshaller.Marshal(stream,
                                                   w => w.WriteByteArray(ClientFeatures.AllFeatures));
                }

                // Authentication data.
                if (hasAuth)
                {
                    BinaryUtils.Marshaller.Marshal(stream, writer =>
                    {
                        writer.WriteString(clientConfiguration.UserName);
                        writer.WriteString(clientConfiguration.Password);
                    });
                }
            }, 12, out messageLen);

            SocketWrite(buf, messageLen);

            // Decode response.
            var res = ReceiveMessage();

            using (var stream = new BinaryHeapStream(res))
            {
                // Read input.
                var success = stream.ReadBool();

                if (success)
                {
                    BitArray featureBits = null;

                    if (hasFeatures)
                    {
                        featureBits = new BitArray(BinaryUtils.Marshaller.Unmarshal <byte[]>(stream));
                    }

                    if (version >= Ver140)
                    {
                        ServerNodeId = BinaryUtils.Marshaller.Unmarshal <Guid>(stream);
                    }

                    ServerVersion = version;

                    _logger.Debug("Handshake completed on {0}, protocol version = {1}",
                                  _socket.RemoteEndPoint, version);

                    return(new ClientFeatures(version, featureBits));
                }

                ServerVersion =
                    new ClientProtocolVersion(stream.ReadShort(), stream.ReadShort(), stream.ReadShort());

                var errMsg = BinaryUtils.Marshaller.Unmarshal <string>(stream);

                ClientStatusCode errCode = ClientStatusCode.Fail;

                if (stream.Remaining > 0)
                {
                    errCode = (ClientStatusCode)stream.ReadInt();
                }

                _logger.Debug("Handshake failed on {0}, requested protocol version = {1}, " +
                              "server protocol version = {2}, status = {3}, message = {4}",
                              _socket.RemoteEndPoint, version, ServerVersion, errCode, errMsg);

                // Authentication error is handled immediately.
                if (errCode == ClientStatusCode.AuthenticationFailed)
                {
                    throw new IgniteClientException(errMsg, null, ClientStatusCode.AuthenticationFailed);
                }

                // Retry if server version is different and falls within supported version range.
                var retry = ServerVersion != version &&
                            ServerVersion >= Ver100 &&
                            ServerVersion <= CurrentProtocolVersion;

                if (retry)
                {
                    _logger.Debug("Retrying handshake on {0} with protocol version {1}",
                                  _socket.RemoteEndPoint, ServerVersion);

                    return(Handshake(clientConfiguration, ServerVersion));
                }

                throw new IgniteClientException(string.Format(
                                                    "Client handshake failed: '{0}'. Client version: {1}. Server version: {2}",
                                                    errMsg, version, ServerVersion), null, errCode);
            }
        }