From ed54b249db0e3710c265436bfffa815b5e00abce Mon Sep 17 00:00:00 2001 From: noisyfox Date: Fri, 26 Aug 2016 21:08:04 +1000 Subject: [PATCH] Close services while closing listener. Now it will close all existing TCP relay connections while reloading the listener. Signed-off-by: noisyfox --- .../Controller/Service/Listener.cs | 22 ++++++++++++++----- .../Controller/Service/PACServer.cs | 2 +- .../Controller/Service/PortForwarder.cs | 2 +- .../Controller/Service/TCPRelay.cs | 12 +++++++++- .../Controller/Service/UDPRelay.cs | 2 +- .../Controller/ShadowsocksController.cs | 2 +- 6 files changed, 32 insertions(+), 10 deletions(-) diff --git a/shadowsocks-csharp/Controller/Service/Listener.cs b/shadowsocks-csharp/Controller/Service/Listener.cs index 9fed2cb7..b2c33262 100644 --- a/shadowsocks-csharp/Controller/Service/Listener.cs +++ b/shadowsocks-csharp/Controller/Service/Listener.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; @@ -10,9 +11,18 @@ namespace Shadowsocks.Controller { public class Listener { - public interface Service + public interface IService { bool Handle(byte[] firstPacket, int length, Socket socket, object state); + + void Stop(); + } + + public abstract class Service : IService + { + public abstract bool Handle(byte[] firstPacket, int length, Socket socket, object state); + + public virtual void Stop() { } } public class UDPState @@ -25,9 +35,9 @@ namespace Shadowsocks.Controller bool _shareOverLAN; Socket _tcpSocket; Socket _udpSocket; - IList _services; + List _services; - public Listener(IList services) + public Listener(List services) { this._services = services; } @@ -97,6 +107,8 @@ namespace Shadowsocks.Controller _udpSocket.Close(); _udpSocket = null; } + + _services.ForEach(s=>s.Stop()); } public void RecvFromCallback(IAsyncResult ar) @@ -105,7 +117,7 @@ namespace Shadowsocks.Controller try { int bytesRead = _udpSocket.EndReceiveFrom(ar, ref state.remoteEndPoint); - foreach (Service service in _services) + foreach (IService service in _services) { if (service.Handle(state.buffer, bytesRead, _udpSocket, state)) { @@ -187,7 +199,7 @@ namespace Shadowsocks.Controller try { int bytesRead = conn.EndReceive(ar); - foreach (Service service in _services) + foreach (IService service in _services) { if (service.Handle(buf, bytesRead, conn, null)) { diff --git a/shadowsocks-csharp/Controller/Service/PACServer.cs b/shadowsocks-csharp/Controller/Service/PACServer.cs index c6853331..3fb0461a 100644 --- a/shadowsocks-csharp/Controller/Service/PACServer.cs +++ b/shadowsocks-csharp/Controller/Service/PACServer.cs @@ -35,7 +35,7 @@ namespace Shadowsocks.Controller this._config = config; } - public bool Handle(byte[] firstPacket, int length, Socket socket, object state) + public override bool Handle(byte[] firstPacket, int length, Socket socket, object state) { if (socket.ProtocolType != ProtocolType.Tcp) { diff --git a/shadowsocks-csharp/Controller/Service/PortForwarder.cs b/shadowsocks-csharp/Controller/Service/PortForwarder.cs index dcac75bf..6be4dbef 100644 --- a/shadowsocks-csharp/Controller/Service/PortForwarder.cs +++ b/shadowsocks-csharp/Controller/Service/PortForwarder.cs @@ -14,7 +14,7 @@ namespace Shadowsocks.Controller this._targetPort = targetPort; } - public bool Handle(byte[] firstPacket, int length, Socket socket, object state) + public override bool Handle(byte[] firstPacket, int length, Socket socket, object state) { if (socket.ProtocolType != ProtocolType.Tcp) { diff --git a/shadowsocks-csharp/Controller/Service/TCPRelay.cs b/shadowsocks-csharp/Controller/Service/TCPRelay.cs index 2d86de25..7a80fefb 100644 --- a/shadowsocks-csharp/Controller/Service/TCPRelay.cs +++ b/shadowsocks-csharp/Controller/Service/TCPRelay.cs @@ -29,7 +29,7 @@ namespace Shadowsocks.Controller _lastSweepTime = DateTime.Now; } - public bool Handle(byte[] firstPacket, int length, Socket socket, object state) + public override bool Handle(byte[] firstPacket, int length, Socket socket, object state) { if (socket.ProtocolType != ProtocolType.Tcp || (length < 2 || firstPacket[0] != 5)) @@ -62,6 +62,16 @@ namespace Shadowsocks.Controller return true; } + public override void Stop() + { + List handlersToClose = new List(); + lock (Handlers) + { + handlersToClose.AddRange(Handlers); + } + handlersToClose.ForEach(h=>h.Close()); + } + public void UpdateInboundCounter(Server server, long n) { _controller.UpdateInboundCounter(server, n); diff --git a/shadowsocks-csharp/Controller/Service/UDPRelay.cs b/shadowsocks-csharp/Controller/Service/UDPRelay.cs index 5f0d2363..e7beb46c 100644 --- a/shadowsocks-csharp/Controller/Service/UDPRelay.cs +++ b/shadowsocks-csharp/Controller/Service/UDPRelay.cs @@ -24,7 +24,7 @@ namespace Shadowsocks.Controller this._cache = new LRUCache(512); // todo: choose a smart number } - public bool Handle(byte[] firstPacket, int length, Socket socket, object state) + public override bool Handle(byte[] firstPacket, int length, Socket socket, object state) { if (socket.ProtocolType != ProtocolType.Udp) { diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index a2a34eee..089fbaee 100644 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -429,7 +429,7 @@ namespace Shadowsocks.Controller TCPRelay tcpRelay = new TCPRelay(this, _config); UDPRelay udpRelay = new UDPRelay(this); - List services = new List(); + List services = new List(); services.Add(tcpRelay); services.Add(udpRelay); services.Add(_pacServer);