public void Listen()
        {
            // If you call listen() on a port, then kill the process, then immediately start a new process and 
            // try to listen() on the same port, you sometimes get WSAEADDRINUSE.  Even if nothing was accepted.  
            // Ports don't immediately free themselves on process shutdown.  We call listen() in a loop on a delay 
            // for a few iterations for this reason. 
            //
            TimeSpan listenTimeout = TimeSpan.FromSeconds(1);
            BackoffTimeoutHelper backoffHelper = new BackoffTimeoutHelper(listenTimeout);

            lock (ThisLock)
            {
                if (this.listenSocket != null)
                {
                    this.listenSocket.Listen(settings.ListenBacklog);
                    isListening = true;
                }

                while (!isListening)
                {
                    try
                    {
                        this.listenSocket = new Socket(localEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

                        if (localEndpoint.AddressFamily == AddressFamily.InterNetworkV6 && settings.TeredoEnabled)
                        {
                            this.listenSocket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)23, 10);
                        }

                        this.listenSocket.Bind(localEndpoint);
                        this.listenSocket.Listen(settings.ListenBacklog);
                        isListening = true;
                    }
                    catch (SocketException socketException)
                    {
                        bool retry = false;

                        if (socketException.ErrorCode == UnsafeNativeMethods.WSAEADDRINUSE)
                        {
                            if (!backoffHelper.IsExpired())
                            {
                                backoffHelper.WaitAndBackoff();
                                retry = true;
                            }
                        }

                        if (!retry)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                SocketConnectionListener.ConvertListenException(socketException, this.localEndpoint));
                        }
                    }
                }

                this.socketAsyncEventArgsPool = new SocketAsyncEventArgsPool(GetAcceptBufferSize(this.listenSocket));
            }
        }
예제 #2
0
        IConnection TryConnect(Uri remoteUri, string resolvedAddress, BackoffTimeoutHelper backoffHelper)
        {
            const int access = UnsafeNativeMethods.GENERIC_READ | UnsafeNativeMethods.GENERIC_WRITE;
            bool lastAttempt = backoffHelper.IsExpired();

            int flags = UnsafeNativeMethods.FILE_FLAG_OVERLAPPED;

            // By default Windows named pipe connection is created with impersonation, but we want
            // to create it with anonymous and let WCF take care of impersonation/identification.
            flags |= UnsafeNativeMethods.SECURITY_QOS_PRESENT | UnsafeNativeMethods.SECURITY_ANONYMOUS;

            PipeHandle pipeHandle = UnsafeNativeMethods.CreateFile(resolvedAddress, access, 0, IntPtr.Zero,
                UnsafeNativeMethods.OPEN_EXISTING, flags, IntPtr.Zero);
            int error = Marshal.GetLastWin32Error();
            if (pipeHandle.IsInvalid)
            {
                pipeHandle.SetHandleAsInvalid();
            }
            else
            {
                int mode = UnsafeNativeMethods.PIPE_READMODE_MESSAGE;
                if (UnsafeNativeMethods.SetNamedPipeHandleState(pipeHandle, ref mode, IntPtr.Zero, IntPtr.Zero) == 0)
                {
                    error = Marshal.GetLastWin32Error();
                    pipeHandle.Close();
                    PipeException innerException = new PipeException(SR.GetString(SR.PipeModeChangeFailed,
                        PipeError.GetErrorString(error)), error);
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        CreateConnectFailedException(remoteUri, innerException));
                }
                return new PipeConnection(pipeHandle, bufferSize, false, true);
            }

            if (error == UnsafeNativeMethods.ERROR_FILE_NOT_FOUND || error == UnsafeNativeMethods.ERROR_PIPE_BUSY)
            {
                if (lastAttempt)
                {
                    Exception innerException = new PipeException(SR.GetString(SR.PipeConnectAddressFailed,
                        resolvedAddress, PipeError.GetErrorString(error)), error);

                    TimeoutException timeoutException;
                    string endpoint = remoteUri.AbsoluteUri;

                    if (error == UnsafeNativeMethods.ERROR_PIPE_BUSY)
                    {
                        timeoutException = new TimeoutException(SR.GetString(SR.PipeConnectTimedOutServerTooBusy,
                            endpoint, backoffHelper.OriginalTimeout), innerException);
                    }
                    else
                    {
                        timeoutException = new TimeoutException(SR.GetString(SR.PipeConnectTimedOut,
                            endpoint, backoffHelper.OriginalTimeout), innerException);
                    }

                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(timeoutException);
                }

                return null;
            }
            else
            {
                PipeException innerException = new PipeException(SR.GetString(SR.PipeConnectAddressFailed,
                    resolvedAddress, PipeError.GetErrorString(error)), error);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    CreateConnectFailedException(remoteUri, innerException));
            }
        }
 public void Listen()
 {
     BackoffTimeoutHelper helper = new BackoffTimeoutHelper(TimeSpan.FromSeconds(1.0));
     lock (this.ThisLock)
     {
         if (this.listenSocket != null)
         {
             this.listenSocket.Listen(this.settings.ListenBacklog);
             this.isListening = true;
         }
         while (!this.isListening)
         {
             try
             {
                 this.listenSocket = new Socket(this.localEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                 if ((this.localEndpoint.AddressFamily == AddressFamily.InterNetworkV6) && this.settings.TeredoEnabled)
                 {
                     this.listenSocket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPProtectionLevel, 10);
                 }
                 this.listenSocket.Bind(this.localEndpoint);
                 this.listenSocket.Listen(this.settings.ListenBacklog);
                 this.isListening = true;
                 continue;
             }
             catch (SocketException exception)
             {
                 bool flag = false;
                 if ((exception.ErrorCode == 0x2740) && !helper.IsExpired())
                 {
                     helper.WaitAndBackoff();
                     flag = true;
                 }
                 if (!flag)
                 {
                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ConvertListenException(exception, this.localEndpoint));
                 }
                 continue;
             }
         }
         this.socketAsyncEventArgsPool = new SocketAsyncEventArgsPool(GetAcceptBufferSize(this.listenSocket));
     }
 }
예제 #4
0
        void PrepareConnect(Uri remoteUri, TimeSpan timeout, out string resolvedAddress, out BackoffTimeoutHelper backoffHelper)
        {
            PipeUri.Validate(remoteUri);
            if (DiagnosticUtility.ShouldTraceInformation)
            {
                TraceUtility.TraceEvent(System.Diagnostics.TraceEventType.Information, TraceCode.InitiatingNamedPipeConnection,
                    SR.GetString(SR.TraceCodeInitiatingNamedPipeConnection),
                    new StringTraceRecord("Uri", remoteUri.ToString()), this, null);
            }
            resolvedAddress = GetPipeName(remoteUri, this.pipeSettings);
            const int backoffBufferMilliseconds = 150;
            TimeSpan backoffTimeout;
            if (timeout >= TimeSpan.FromMilliseconds(backoffBufferMilliseconds * 2))
            {
                backoffTimeout = TimeoutHelper.Add(timeout, TimeSpan.Zero - TimeSpan.FromMilliseconds(backoffBufferMilliseconds));
            }
            else
            {
                backoffTimeout = Ticks.ToTimeSpan((Ticks.FromMilliseconds(backoffBufferMilliseconds) / 2) + 1);
            }

            backoffHelper = new BackoffTimeoutHelper(backoffTimeout, TimeSpan.FromMinutes(5));
        }
 private ServiceControllerStatus ExitServiceStatus(ServiceController service, int pollMin, int pollMax, ServiceControllerStatus status)
 {
     ServiceControllerStatus status2;
     BackoffTimeoutHelper helper = new BackoffTimeoutHelper(TimeSpan.MaxValue, TimeSpan.FromMilliseconds((double) pollMax), TimeSpan.FromMilliseconds((double) pollMin));
     do
     {
         if (this.closed)
         {
             return service.Status;
         }
         helper.WaitAndBackoff();
         service.Refresh();
         status2 = service.Status;
     }
     while (status2 == status);
     return status2;
 }
 private void ReconnectCallback(object state)
 {
     BackoffTimeoutHelper helper = new BackoffTimeoutHelper(TimeSpan.MaxValue, TimeSpan.FromMinutes(5.0), TimeSpan.FromSeconds(30.0));
     while (this.state == CommunicationState.Opening)
     {
         try
         {
             this.StartListen(true);
         }
         catch (Exception exception)
         {
             if (Fx.IsFatal(exception))
             {
                 throw;
             }
             if (DiagnosticUtility.ShouldTraceError)
             {
                 DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Error);
             }
         }
         if (this.state == CommunicationState.Opening)
         {
             helper.WaitAndBackoff();
         }
     }
 }
 private IConnection TryConnect(Uri remoteUri, string resolvedAddress, BackoffTimeoutHelper backoffHelper)
 {
     bool flag = backoffHelper.IsExpired();
     int dwFlagsAndAttributes = 0x40000000;
     if (this.includeSecurityIdentity)
     {
         dwFlagsAndAttributes |= 0x110000;
     }
     PipeHandle handle = UnsafeNativeMethods.CreateFile(resolvedAddress, -1073741824, 0, IntPtr.Zero, 3, dwFlagsAndAttributes, IntPtr.Zero);
     int errorCode = Marshal.GetLastWin32Error();
     if (handle.IsInvalid)
     {
         handle.SetHandleAsInvalid();
     }
     else
     {
         int mode = 2;
         if (UnsafeNativeMethods.SetNamedPipeHandleState(handle, ref mode, IntPtr.Zero, IntPtr.Zero) == 0)
         {
             errorCode = Marshal.GetLastWin32Error();
             handle.Close();
             PipeException exception = new PipeException(System.ServiceModel.SR.GetString("PipeModeChangeFailed", new object[] { PipeError.GetErrorString(errorCode) }), errorCode);
             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(this.CreateConnectFailedException(remoteUri, exception));
         }
         return new PipeConnection(handle, this.bufferSize, false, true);
     }
     if ((errorCode == 2) || (errorCode == 0xe7))
     {
         TimeoutException exception3;
         if (!flag)
         {
             return null;
         }
         Exception exception2 = new PipeException(System.ServiceModel.SR.GetString("PipeConnectAddressFailed", new object[] { resolvedAddress, PipeError.GetErrorString(errorCode) }), errorCode);
         string absoluteUri = remoteUri.AbsoluteUri;
         if (errorCode == 0xe7)
         {
             exception3 = new TimeoutException(System.ServiceModel.SR.GetString("PipeConnectTimedOutServerTooBusy", new object[] { absoluteUri, backoffHelper.OriginalTimeout }), exception2);
         }
         else
         {
             exception3 = new TimeoutException(System.ServiceModel.SR.GetString("PipeConnectTimedOut", new object[] { absoluteUri, backoffHelper.OriginalTimeout }), exception2);
         }
         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception3);
     }
     PipeException innerException = new PipeException(System.ServiceModel.SR.GetString("PipeConnectAddressFailed", new object[] { resolvedAddress, PipeError.GetErrorString(errorCode) }), errorCode);
     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(this.CreateConnectFailedException(remoteUri, innerException));
 }
 private void PrepareConnect(Uri remoteUri, TimeSpan timeout, out string resolvedAddress, out BackoffTimeoutHelper backoffHelper)
 {
     TimeSpan span;
     PipeUri.Validate(remoteUri);
     if (DiagnosticUtility.ShouldTraceInformation)
     {
         TraceUtility.TraceEvent(TraceEventType.Information, 0x4002a, System.ServiceModel.SR.GetString("TraceCodeInitiatingNamedPipeConnection"), new StringTraceRecord("Uri", remoteUri.ToString()), this, null);
     }
     resolvedAddress = GetPipeName(remoteUri);
     if (timeout >= TimeSpan.FromMilliseconds(300.0))
     {
         span = TimeoutHelper.Add(timeout, TimeSpan.Zero - TimeSpan.FromMilliseconds(150.0));
     }
     else
     {
         span = Ticks.ToTimeSpan((Ticks.FromMilliseconds(150) / 2L) + 1L);
     }
     backoffHelper = new BackoffTimeoutHelper(span, TimeSpan.FromMinutes(5.0));
 }