private async Task <ClusterMaintenanceConnection> ConnectToClientNodeAsync(TcpConnectionInfo tcpConnectionInfo, TimeSpan timeout) { TcpConnectionHeaderMessage.SupportedFeatures supportedFeatures; TcpClient tcpClient; string url; (tcpClient, url) = await TcpUtils.ConnectSocketAsync(tcpConnectionInfo, timeout, _log); var connection = await TcpUtils.WrapStreamWithSslAsync(tcpClient, tcpConnectionInfo, _parent._server.Server.Certificate.Certificate, timeout); using (_contextPool.AllocateOperationContext(out JsonOperationContext ctx)) using (var writer = new BlittableJsonTextWriter(ctx, connection)) { var parameters = new TcpNegotiateParameters { Database = null, Operation = TcpConnectionHeaderMessage.OperationTypes.Heartbeats, Version = TcpConnectionHeaderMessage.HeartbeatsTcpVersion, ReadResponseAndGetVersionCallback = SupervisorReadResponseAndGetVersion, DestinationUrl = url, DestinationNodeTag = ClusterTag }; supportedFeatures = TcpNegotiation.NegotiateProtocolVersion(ctx, connection, parameters); WriteClusterMaintenanceConnectionHeader(writer); } return(new ClusterMaintenanceConnection { TcpClient = tcpClient, Stream = connection, SupportedFeatures = supportedFeatures }); }
private void WriteHeaderToRemotePeer() { using (_database.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext documentsContext)) using (var writer = new BlittableJsonTextWriter(documentsContext, _stream)) { var parameters = new TcpNegotiateParameters { Database = Destination.Database, Operation = TcpConnectionHeaderMessage.OperationTypes.Replication, SourceNodeTag = _parent._server.NodeTag, DestinationNodeTag = GetNode(), DestinationUrl = Destination.Url, ReadResponseAndGetVersionCallback = ReadHeaderResponseAndThrowIfUnAuthorized, Version = TcpConnectionHeaderMessage.ReplicationTcpVersion }; //This will either throw or return acceptable protocol version. SupportedFeatures = TcpNegotiation.NegotiateProtocolVersion(documentsContext, _stream, parameters); if (SupportedFeatures.ProtocolVersion <= 0) { throw new InvalidOperationException( $"{OutgoingReplicationThreadName}: TCP negotiation resulted with an invalid protocol version:{SupportedFeatures.ProtocolVersion}"); } //start request/response for fetching last etag var request = new DynamicJsonValue { ["Type"] = "GetLastEtag", [nameof(ReplicationLatestEtagRequest.SourceDatabaseId)] = _database.DbId.ToString(), [nameof(ReplicationLatestEtagRequest.SourceDatabaseName)] = _database.Name, [nameof(ReplicationLatestEtagRequest.SourceUrl)] = _parent._server.GetNodeHttpServerUrl(), [nameof(ReplicationLatestEtagRequest.SourceTag)] = _parent._server.NodeTag, [nameof(ReplicationLatestEtagRequest.SourceMachineName)] = Environment.MachineName }; documentsContext.Write(writer, request); writer.Flush(); } }