Пример #1
0
        private void TrySendStatusMessageToActive(PassiveStatusMsg.Flags statusFlags, long requestAckCounter, out NetworkTransportException sendException, out bool sendSkippedBecauseChannelBusy)
        {
            sendException = null;
            sendSkippedBecauseChannelBusy = false;
            NetworkChannel netCh = this.m_netChannel;

            if (this.m_asyncNetWritePending || netCh == null)
            {
                PassiveBlockMode.Tracer.TraceError((long)this.GetHashCode(), "SendStatusMessageToActive skipped because channel is busy");
                sendSkippedBecauseChannelBusy = true;
                return;
            }
            ReplayState replayState        = this.Configuration.ReplayState;
            long        highestCompleteGen = replayState.CopyNotificationGenerationNumber;

            byte[] statusMsgBuf = PassiveStatusMsg.SerializeToBytes(statusFlags, requestAckCounter, (uint)highestCompleteGen, (uint)replayState.CopyGenerationNumber, (uint)replayState.InspectorGenerationNumber, (uint)replayState.ReplayGenerationNumber, this.m_isCrossSite);
            bool   writeStarted = false;

            try
            {
                Exception ex = NetworkChannel.RunNetworkFunction(delegate
                {
                    ExTraceGlobals.FaultInjectionTracer.TraceTest(PassiveBlockMode.ackMessageSendFailed);
                    PassiveBlockMode.Tracer.TraceDebug <string, long>((long)this.GetHashCode(), "Sending PassiveStatusMsg({0}) Gen 0x{1:X}", this.DatabaseName, highestCompleteGen);
                    this.m_nextPingDue          = DateTime.UtcNow.AddMilliseconds((double)RegistryParameters.LogShipTimeoutInMsec);
                    this.m_asyncNetWritePending = true;
                    netCh.TcpChannel.Stream.BeginWrite(statusMsgBuf, 0, statusMsgBuf.Length, new AsyncCallback(this.NetWriteCompletion), netCh);
                    writeStarted = true;
                });
                if (ex != null)
                {
                    PassiveBlockMode.Tracer.TraceError <Exception>((long)this.GetHashCode(), "SendStatusMessageToActive Failed to ping Active: {0}", ex);
                    ReplayEventLogConstants.Tuple_NotifyActiveSendFailed.LogEvent(null, new object[]
                    {
                        this.DatabaseName,
                        replayState.ReplayGenerationNumber,
                        replayState.InspectorGenerationNumber,
                        replayState.CopyGenerationNumber,
                        ex.Message
                    });
                    sendException = (ex as NetworkTransportException);
                    if (sendException == null)
                    {
                        sendException = new NetworkCommunicationException(netCh.PartnerNodeName, ex.Message, ex);
                    }
                }
            }
            finally
            {
                if (!writeStarted)
                {
                    this.m_asyncNetWritePending = false;
                }
            }
        }
Пример #2
0
        internal static bool TryOpenChannel(NetworkPath netPath, int timeoutInMs, out TcpClientChannel channel, out NetworkTransportException networkEx)
        {
            channel   = null;
            networkEx = null;
            Exception       ex              = null;
            Socket          socket          = null;
            Stream          stream          = null;
            NegotiateStream negotiateStream = null;
            ReplayStopwatch replayStopwatch = new ReplayStopwatch();

            replayStopwatch.Start();
            try
            {
                socket = new Socket(netPath.TargetEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                if (netPath.Purpose == NetworkPath.ConnectionPurpose.Seeding)
                {
                    socket.ReceiveBufferSize = RegistryParameters.SeedingNetworkTransferSize;
                    socket.SendBufferSize    = RegistryParameters.SeedingNetworkTransferSize;
                }
                else
                {
                    socket.ReceiveBufferSize = RegistryParameters.LogCopyNetworkTransferSize;
                    socket.SendBufferSize    = RegistryParameters.LogCopyNetworkTransferSize;
                }
                if (netPath.HasSourceEndpoint())
                {
                    socket.Bind(netPath.SourceEndPoint);
                }
                TcpClientChannel.ConnectAbandon connectAbandon = new TcpClientChannel.ConnectAbandon(socket);
                IAsyncResult asyncResult = socket.BeginConnect(netPath.TargetEndPoint.Address, netPath.TargetEndPoint.Port, null, connectAbandon);
                if (!asyncResult.AsyncWaitHandle.WaitOne(timeoutInMs, false))
                {
                    socket = null;
                    connectAbandon.Cancel(asyncResult);
                    TcpChannel.ThrowTimeoutException(netPath.TargetNodeName, ReplayStrings.NetworkConnectionTimeout(timeoutInMs / 1000));
                }
                socket.EndConnect(asyncResult);
                long elapsedMilliseconds = replayStopwatch.ElapsedMilliseconds;
                ExTraceGlobals.TcpClientTracer.TraceDebug <long>(0L, "Connection took {0}ms", elapsedMilliseconds);
                socket.LingerState = new LingerOption(true, 0);
                if (!netPath.UseSocketStream || RegistryParameters.DisableSocketStream)
                {
                    stream = new NetworkStream(socket, false);
                }
                else
                {
                    stream = new SocketStream(socket, netPath.SocketStreamBufferPool, netPath.SocketStreamAsyncArgPool, netPath.SocketStreamPerfCounters);
                }
                negotiateStream     = new NegotiateStream(stream, false);
                stream              = null;
                elapsedMilliseconds = replayStopwatch.ElapsedMilliseconds;
                if (elapsedMilliseconds >= (long)timeoutInMs)
                {
                    TcpChannel.ThrowTimeoutException(netPath.TargetNodeName, ReplayStrings.NetworkConnectionTimeout(timeoutInMs / 1000));
                }
                int num = timeoutInMs - (int)elapsedMilliseconds;
                negotiateStream.WriteTimeout = num;
                negotiateStream.ReadTimeout  = num;
                TcpClientChannel.AuthAbandon authAbandon = new TcpClientChannel.AuthAbandon(socket, negotiateStream);
                string targetName;
                if (netPath.UseNullSpn)
                {
                    targetName = "";
                }
                else
                {
                    targetName = "HOST/" + netPath.TargetNodeName;
                }
                bool            encrypt = netPath.Encrypt;
                ProtectionLevel protectionLevel;
                if (encrypt)
                {
                    protectionLevel = ProtectionLevel.EncryptAndSign;
                }
                else if (RegistryParameters.DisableNetworkSigning)
                {
                    protectionLevel = ProtectionLevel.None;
                }
                else
                {
                    protectionLevel = ProtectionLevel.Sign;
                }
                asyncResult = negotiateStream.BeginAuthenticateAsClient(CredentialCache.DefaultNetworkCredentials, targetName, protectionLevel, TokenImpersonationLevel.Identification, null, authAbandon);
                if (!asyncResult.AsyncWaitHandle.WaitOne(num, false))
                {
                    negotiateStream = null;
                    socket          = null;
                    authAbandon.Abandon(asyncResult);
                    TcpChannel.ThrowTimeoutException(netPath.TargetNodeName, ReplayStrings.NetworkConnectionTimeout(timeoutInMs / 1000));
                }
                negotiateStream.EndAuthenticateAsClient(asyncResult);
                bool flag = false;
                if (!negotiateStream.IsAuthenticated)
                {
                    flag = true;
                }
                else if (protectionLevel != ProtectionLevel.None && !negotiateStream.IsMutuallyAuthenticated)
                {
                    if (netPath.IgnoreMutualAuth || MachineName.Comparer.Equals(netPath.TargetNodeName, Environment.MachineName))
                    {
                        ExTraceGlobals.TcpClientTracer.TraceDebug(0L, "Ignoring mutual auth since we are local");
                    }
                    else
                    {
                        flag = true;
                    }
                }
                if (!flag && encrypt && !negotiateStream.IsEncrypted)
                {
                    ExTraceGlobals.TcpClientTracer.TraceError(0L, "Encryption requested, but could not be negotiated");
                    flag = true;
                }
                if (flag)
                {
                    ExTraceGlobals.TcpClientTracer.TraceError <bool, bool, bool>(0L, "Security Negotiation failed. Auth={0},MAuth={1},Encrypt={2}", negotiateStream.IsAuthenticated, negotiateStream.IsMutuallyAuthenticated, negotiateStream.IsEncrypted);
                    NetworkManager.ThrowException(new NetworkCommunicationException(netPath.TargetNodeName, ReplayStrings.NetworkSecurityFailed));
                }
                ExTraceGlobals.TcpClientTracer.TraceDebug <long, bool, ProtectionLevel>(0L, "Authenticated Connection took {0}ms. Encrypt={1} ProtRequested={2}", replayStopwatch.ElapsedMilliseconds, negotiateStream.IsEncrypted, protectionLevel);
                channel = new TcpClientChannel(netPath.TargetNodeName, socket, negotiateStream, timeoutInMs);
                return(true);
            }
            catch (SocketException ex2)
            {
                ex = ex2;
            }
            catch (IOException ex3)
            {
                ex = ex3;
            }
            catch (AuthenticationException ex4)
            {
                ex = ex4;
            }
            catch (NetworkTransportException ex5)
            {
                ex = ex5;
            }
            finally
            {
                if (channel == null)
                {
                    if (negotiateStream != null)
                    {
                        negotiateStream.Dispose();
                    }
                    else if (stream != null)
                    {
                        stream.Dispose();
                    }
                    if (socket != null)
                    {
                        socket.Close();
                    }
                }
                else
                {
                    ReplayCrimsonEvents.NetworkConnectionSuccess.Log <string, IPEndPoint, IPEndPoint>(netPath.TargetNodeName, netPath.TargetEndPoint, channel.LocalEndpoint);
                }
            }
            ExTraceGlobals.TcpClientTracer.TraceError <Exception>(0L, "TryOpenChannel failed. Ex={0}", ex);
            ReplayCrimsonEvents.NetworkConnectionFailure.Log <string, IPEndPoint, IPEndPoint, string>(netPath.TargetNodeName, netPath.TargetEndPoint, netPath.SourceEndPoint, ex.ToString());
            if (ex is NetworkTransportException)
            {
                networkEx = (NetworkTransportException)ex;
            }
            else
            {
                networkEx = new NetworkCommunicationException(netPath.TargetNodeName, ex.Message, ex);
            }
            return(false);
        }
Пример #3
0
 private void ProcessReadCallback(PassiveReadRequest ioReq, int bytesAvailable, bool completionIsSynchronous, Exception readEx)
 {
     PassiveBlockMode.Tracer.TraceFunction <string>((long)this.GetHashCode(), "ProcessReadCallback({0}) entered", this.DatabaseName);
     lock (this.m_workerLock)
     {
         this.DisableTimer();
         Exception ex    = null;
         bool      flag2 = false;
         try
         {
             this.m_recursionDepth++;
             DiagCore.RetailAssert(this.m_recursionDepth == 1 || completionIsSynchronous, "recursive async completion", new object[0]);
             ioReq.CompletionWasProcessed = true;
             if (completionIsSynchronous)
             {
                 ioReq.CompletedSynchronously = completionIsSynchronous;
             }
             if (readEx != null)
             {
                 PassiveBlockMode.Tracer.TraceError <string, Exception>((long)this.GetHashCode(), "ProcessReadCallback({0}) read failed: ex={1}", this.DatabaseName, readEx);
                 ex = new NetworkCommunicationException(this.Configuration.SourceMachine, readEx.Message, readEx);
             }
             else if (bytesAvailable == 0)
             {
                 PassiveBlockMode.Tracer.TraceError <string>((long)this.GetHashCode(), "ProcessReadCallback({0}) active closed connection", this.DatabaseName);
                 ex = new NetworkEndOfDataException(this.Configuration.SourceMachine, ReplayStrings.NetworkReadEOF);
             }
             else if (ioReq.Channel != this.m_netChannel)
             {
                 ex    = new NetworkEndOfDataException(this.Configuration.SourceMachine, ReplayStrings.NetworkReadEOF);
                 flag2 = true;
                 ioReq.Channel.Close();
             }
             else if (!this.IsBlockModeActive)
             {
                 PassiveBlockMode.Tracer.TraceError <string>((long)this.GetHashCode(), "Discarding read since BM was already terminated", this.DatabaseName);
             }
             else
             {
                 QueuedBlockMsg queuedBlockMsg = this.ReadInputMessage(ioReq.Channel);
                 if (queuedBlockMsg != null)
                 {
                     this.ProcessInput(queuedBlockMsg);
                     if (BitMasker.IsOn((int)queuedBlockMsg.EmitContext.grbitOperationalFlags, 2))
                     {
                         this.HandleActiveDismount();
                         return;
                     }
                     if (BitMasker.IsOn((int)queuedBlockMsg.EmitContext.grbitOperationalFlags, 16))
                     {
                         this.Copier.TrackLastContactTime(queuedBlockMsg.MessageUtc);
                     }
                 }
                 if (this.m_recursionDepth == 1)
                 {
                     while (this.IsBlockModeActive)
                     {
                         PassiveReadRequest passiveReadRequest = this.StartRead();
                         if (!passiveReadRequest.CompletionWasProcessed)
                         {
                             if (!this.m_runningAcll)
                             {
                                 this.ScheduleTimer();
                                 break;
                             }
                             break;
                         }
                     }
                 }
                 else
                 {
                     PassiveBlockMode.Tracer.TraceDebug <int>((long)this.GetHashCode(), "Recursive read avoided. Depth={0}", this.m_recursionDepth);
                 }
             }
         }
         catch (NetworkTransportException ex2)
         {
             ex = ex2;
         }
         catch (NetworkRemoteException ex3)
         {
             ex = ex3;
         }
         catch (GranularReplicationOverflowException ex4)
         {
             ex = ex4;
         }
         finally
         {
             this.m_recursionDepth--;
             if (ex != null && !flag2)
             {
                 this.Terminate();
             }
             PassiveBlockMode.Tracer.TraceFunction <string>((long)this.GetHashCode(), "ProcessReadCallback({0}) exits", this.DatabaseName);
         }
     }
 }