From 2d01f2752b00e3c89770e090030cd1172b1bbf0f Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Thu, 10 Sep 2015 14:45:26 -0700 Subject: [PATCH] Catch and log uv_accept errors - This is also what is done by node.js - "tcp, pipe: don't assert on uv_accept() errors (Ben Noordhuis)" https://github.com/nodejs/node/commit/0685707bc643250de297b59f4f58878d4c17292e --- .../Http/ListenerPrimary.cs | 10 +++++++--- .../Http/ListenerSecondary.cs | 2 +- .../Http/PipeListener.cs | 13 ++++++++++++- .../Http/PipeListenerPrimary.cs | 13 ++++++++++++- .../Http/TcpListener.cs | 13 ++++++++++++- .../Http/TcpListenerPrimary.cs | 13 ++++++++++++- .../Networking/Libuv.cs | 2 +- .../Networking/UvException.cs | 12 ++++++++++++ 8 files changed, 69 insertions(+), 9 deletions(-) create mode 100644 src/Microsoft.AspNet.Server.Kestrel/Networking/UvException.cs diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/ListenerPrimary.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/ListenerPrimary.cs index 0010c2d60f..df83d66695 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/ListenerPrimary.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/ListenerPrimary.cs @@ -1,11 +1,12 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.AspNet.Server.Kestrel.Infrastructure; -using Microsoft.AspNet.Server.Kestrel.Networking; using System; using System.Collections.Generic; using System.Threading.Tasks; +using Microsoft.AspNet.Server.Kestrel.Infrastructure; +using Microsoft.AspNet.Server.Kestrel.Networking; +using Microsoft.Framework.Logging; namespace Microsoft.AspNet.Server.Kestrel.Http { @@ -56,15 +57,18 @@ namespace Microsoft.AspNet.Server.Kestrel.Http var dispatchPipe = new UvPipeHandle(Log); dispatchPipe.Init(Thread.Loop, true); + try { pipe.Accept(dispatchPipe); } - catch (Exception) + catch (UvException ex) { dispatchPipe.Dispose(); + Log.LogError("ListenerPrimary.OnListenPipe", ex); return; } + _dispatchPipes.Add(dispatchPipe); } diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/ListenerSecondary.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/ListenerSecondary.cs index 3a0d2e667c..0334c39d68 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/ListenerSecondary.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/ListenerSecondary.cs @@ -86,7 +86,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { DispatchPipe.Accept(acceptSocket); } - catch (Exception ex) + catch (UvException ex) { Log.LogError("DispatchPipe.Accept", ex); acceptSocket.Dispose(); diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/PipeListener.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/PipeListener.cs index 62e12fc9a7..a63e3a547b 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/PipeListener.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/PipeListener.cs @@ -1,8 +1,10 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using Microsoft.AspNet.Server.Kestrel.Infrastructure; using Microsoft.AspNet.Server.Kestrel.Networking; +using Microsoft.Framework.Logging; namespace Microsoft.AspNet.Server.Kestrel.Http { @@ -36,7 +38,16 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { var acceptSocket = new UvPipeHandle(Log); acceptSocket.Init(Thread.Loop, false); - listenSocket.Accept(acceptSocket); + + try + { + listenSocket.Accept(acceptSocket); + } + catch (UvException ex) + { + Log.LogError("PipeListener.OnConnection", ex); + return; + } DispatchConnection(acceptSocket); } diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/PipeListenerPrimary.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/PipeListenerPrimary.cs index 96691a2b8d..7b39014487 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/PipeListenerPrimary.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/PipeListenerPrimary.cs @@ -1,8 +1,10 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using Microsoft.AspNet.Server.Kestrel.Infrastructure; using Microsoft.AspNet.Server.Kestrel.Networking; +using Microsoft.Framework.Logging; namespace Microsoft.AspNet.Server.Kestrel.Http { @@ -36,7 +38,16 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { var acceptSocket = new UvPipeHandle(Log); acceptSocket.Init(Thread.Loop, false); - listenSocket.Accept(acceptSocket); + + try + { + listenSocket.Accept(acceptSocket); + } + catch (UvException ex) + { + Log.LogError("ListenerPrimary.OnConnection", ex); + return; + } DispatchConnection(acceptSocket); } diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListener.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListener.cs index 4fa374c0fb..2b8e4ea527 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListener.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListener.cs @@ -1,9 +1,11 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Net; using Microsoft.AspNet.Server.Kestrel.Infrastructure; using Microsoft.AspNet.Server.Kestrel.Networking; +using Microsoft.Framework.Logging; namespace Microsoft.AspNet.Server.Kestrel.Http { @@ -37,7 +39,16 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { var acceptSocket = new UvTcpHandle(Log); acceptSocket.Init(Thread.Loop, Thread.QueueCloseHandle); - listenSocket.Accept(acceptSocket); + + try + { + listenSocket.Accept(acceptSocket); + } + catch (UvException ex) + { + Log.LogError("TcpListener.OnConnection", ex); + return; + } DispatchConnection(acceptSocket); } diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListenerPrimary.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListenerPrimary.cs index 2a80f3caee..af4495784d 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListenerPrimary.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListenerPrimary.cs @@ -1,9 +1,11 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Net; using Microsoft.AspNet.Server.Kestrel.Infrastructure; using Microsoft.AspNet.Server.Kestrel.Networking; +using Microsoft.Framework.Logging; namespace Microsoft.AspNet.Server.Kestrel.Http { @@ -37,7 +39,16 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { var acceptSocket = new UvTcpHandle(Log); acceptSocket.Init(Thread.Loop, Thread.QueueCloseHandle); - listenSocket.Accept(acceptSocket); + + try + { + listenSocket.Accept(acceptSocket); + } + catch (UvException ex) + { + Log.LogError("TcpListenerPrimary.OnConnection", ex); + return; + } DispatchConnection(acceptSocket); } diff --git a/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs b/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs index 488780b93f..254483454d 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs @@ -73,7 +73,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking { var errorName = err_name(statusCode); var errorDescription = strerror(statusCode); - error = new Exception("Error " + statusCode + " " + errorName + " " + errorDescription); + error = new UvException("Error " + statusCode + " " + errorName + " " + errorDescription); } else { diff --git a/src/Microsoft.AspNet.Server.Kestrel/Networking/UvException.cs b/src/Microsoft.AspNet.Server.Kestrel/Networking/UvException.cs new file mode 100644 index 0000000000..2a6d5bce1d --- /dev/null +++ b/src/Microsoft.AspNet.Server.Kestrel/Networking/UvException.cs @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; + +namespace Microsoft.AspNet.Server.Kestrel.Networking +{ + public class UvException : Exception + { + public UvException(string message) : base(message) { } + } +}