コード例 #1
0
            private async Task <ClusterMaintenanceConnection> ConnectToClientNodeAsync(TcpConnectionInfo tcpConnectionInfo, TimeSpan timeout)
            {
                TcpConnectionHeaderMessage.SupportedFeatures supportedFeatures;
                Stream    connection;
                TcpClient tcpClient;

                using (_contextPool.AllocateOperationContext(out JsonOperationContext ctx))
                {
                    var result = await TcpUtils.ConnectSecuredTcpSocket(
                        tcpConnectionInfo,
                        _parent._server.Server.Certificate.Certificate,
                        _parent._server.Server.CipherSuitesPolicy,
                        TcpConnectionHeaderMessage.OperationTypes.Heartbeats,
                        NegotiateProtocolVersionAsyncForClusterSupervisor,
                        ctx,
                        timeout, null, _token);

                    tcpClient         = result.TcpClient;
                    connection        = result.Stream;
                    supportedFeatures = result.SupportedFeatures;

                    await using (var writer = new AsyncBlittableJsonTextWriter(ctx, connection))
                    {
                        await WriteClusterMaintenanceConnectionHeaderAsync(writer);
                    }
                }

                return(new ClusterMaintenanceConnection
                {
                    TcpClient = tcpClient,
                    Stream = connection,
                    SupportedFeatures = supportedFeatures
                });
            }
コード例 #2
0
ファイル: TestConnectionHandler.cs プロジェクト: ikvm/ravendb
        public static async Task ConnectToClientNodeAsync(RavenServer server, TcpConnectionInfo tcpConnectionInfo, TimeSpan timeout, Logger log, string database,
                                                          NodeConnectionTestResult result, CancellationToken token = default)
        {
            List <string> negLogs = new();

            using (server.ServerStore.ContextPool.AllocateOperationContext(out JsonOperationContext ctx))
            {
                using var tcpSocketResult = await TcpUtils.ConnectSecuredTcpSocket(tcpConnectionInfo, server.Certificate.Certificate, server.CipherSuitesPolicy,
                                                                                   TcpConnectionHeaderMessage.OperationTypes.TestConnection,
                                                                                   NegotiateWithRemote, ctx, timeout, negLogs, token);
            }

            result.Log = negLogs;

            async Task <TcpConnectionHeaderMessage.SupportedFeatures> NegotiateWithRemote(string url, TcpConnectionInfo info, Stream stream, JsonOperationContext context, List <string> logs = null)
            {
                await using (var writer = new AsyncBlittableJsonTextWriter(context, stream))
                {
                    await WriteOperationHeaderToRemote(writer, TcpConnectionHeaderMessage.OperationTypes.TestConnection, database, info.ServerId);

                    using (var responseJson = await context.ReadForMemoryAsync(stream, $"TestConnectionHandler/{url}/Read-Handshake-Response"))
                    {
                        var headerResponse = JsonDeserializationServer.TcpConnectionHeaderResponse(responseJson);
                        switch (headerResponse.Status)
                        {
                        case TcpConnectionStatus.Ok:
                            result.Success = true;
                            result.Error   = null;
                            logs?.Add($"Successfully negotiated with {url}.");
                            break;

                        case TcpConnectionStatus.AuthorizationFailed:
                            result.Success = false;
                            result.Error   = $"Connection to {url} failed because of authorization failure: {headerResponse.Message}";
                            logs?.Add(result.Error);
                            throw new AuthorizationException(result.Error);

                        case TcpConnectionStatus.TcpVersionMismatch:
                            result.Success = false;
                            result.Error   = $"Connection to {url} failed because of mismatching tcp version: {headerResponse.Message}";
                            logs?.Add(result.Error);
                            await WriteOperationHeaderToRemote(writer, TcpConnectionHeaderMessage.OperationTypes.Drop, database, info.ServerId);

                            throw new AuthorizationException(result.Error);

                        case TcpConnectionStatus.InvalidNetworkTopology:
                            result.Success = false;
                            result.Error   = $"Connection to {url} failed because of {nameof(TcpConnectionStatus.InvalidNetworkTopology)} error: {headerResponse.Message}";
                            logs?.Add(result.Error);
                            throw new InvalidNetworkTopologyException(result.Error);
                        }
                    }
                }
                return(null);
            }
        }
コード例 #3
0
ファイル: NodeDebugHandler.cs プロジェクト: ikvm/ravendb
        private async Task <PingResult> PingOnce(string url)
        {
            var sp     = Stopwatch.StartNew();
            var result = new PingResult
            {
                Url = url
            };

            using (var cts = new CancellationTokenSource(ServerStore.Engine.TcpConnectionTimeout))
            {
                var info = await ReplicationUtils.GetTcpInfoAsync(url, null, "PingTest", ServerStore.Engine.ClusterCertificate, cts.Token);

                result.TcpInfoTime = sp.ElapsedMilliseconds;

                using (ServerStore.ContextPool.AllocateOperationContext(out JsonOperationContext context))
                {
                    var log = new List <string>();

                    using (await TcpUtils.ConnectSecuredTcpSocket(info, ServerStore.Engine.ClusterCertificate, Server.CipherSuitesPolicy,
                                                                  TcpConnectionHeaderMessage.OperationTypes.Ping, NegotiationCallback, context, ServerStore.Engine.TcpConnectionTimeout, log, cts.Token))
                    {
                    }

                    result.Log = log;

                    async Task <TcpConnectionHeaderMessage.SupportedFeatures> NegotiationCallback(string curUrl, TcpConnectionInfo tcpInfo, Stream stream,
                                                                                                  JsonOperationContext ctx, List <string> logs = null)
                    {
                        try
                        {
                            var msg = new DynamicJsonValue
                            {
                                [nameof(TcpConnectionHeaderMessage.DatabaseName)]     = null,
                                [nameof(TcpConnectionHeaderMessage.Operation)]        = TcpConnectionHeaderMessage.OperationTypes.Ping,
                                [nameof(TcpConnectionHeaderMessage.OperationVersion)] = -1,
                                [nameof(TcpConnectionHeaderMessage.ServerId)]         = tcpInfo.ServerId
                            };

                            await using (var writer = new AsyncBlittableJsonTextWriter(ctx, stream))
                                using (var msgJson = ctx.ReadObject(msg, "message"))
                                {
                                    result.SendTime = sp.ElapsedMilliseconds;
                                    logs?.Add($"message sent to url {curUrl} at {result.SendTime} ms.");
                                    ctx.Write(writer, msgJson);
                                }

                            using (var rawResponse = await ctx.ReadForMemoryAsync(stream, "cluster-ConnectToPeer-header-response"))
                            {
                                TcpConnectionHeaderResponse response = JsonDeserializationServer.TcpConnectionHeaderResponse(rawResponse);
                                result.ReceiveTime = sp.ElapsedMilliseconds;
                                logs?.Add($"response received from url {curUrl} at {result.ReceiveTime} ms.");

                                switch (response.Status)
                                {
                                case TcpConnectionStatus.Ok:
                                    result.Error = null;
                                    logs?.Add($"Successfully negotiated with {url}.");
                                    break;

                                case TcpConnectionStatus.AuthorizationFailed:
                                    result.Error = $"Connection to {url} failed because of authorization failure: {response.Message}";
                                    logs?.Add(result.Error);
                                    throw new AuthorizationException(result.Error);

                                case TcpConnectionStatus.TcpVersionMismatch:
                                    result.Error = $"Connection to {url} failed because of mismatching tcp version: {response.Message}";
                                    logs?.Add(result.Error);
                                    throw new AuthorizationException(result.Error);

                                case TcpConnectionStatus.InvalidNetworkTopology:
                                    result.Error = $"Connection to {url} failed because of {nameof(TcpConnectionStatus.InvalidNetworkTopology)} error: {response.Message}";
                                    logs?.Add(result.Error);
                                    throw new InvalidNetworkTopologyException(result.Error);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            result.Error = e.ToString();
                            logs?.Add($"Error occurred while attempting to negotiate with the server. {e.Message}");
                            throw;
                        }

                        return(null);
                    }
                }
            }
            return(result);
        }