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)); } }
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)); } }
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)); }