Now it will close all existing TCP relay connections while reloading the listener. Signed-off-by: noisyfox <timemanager.rick@gmail.com>tags/3.3
@@ -1,5 +1,6 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Linq; | |||||
using System.Net; | using System.Net; | ||||
using System.Net.NetworkInformation; | using System.Net.NetworkInformation; | ||||
using System.Net.Sockets; | using System.Net.Sockets; | ||||
@@ -10,9 +11,18 @@ namespace Shadowsocks.Controller | |||||
{ | { | ||||
public class Listener | public class Listener | ||||
{ | { | ||||
public interface Service | |||||
public interface IService | |||||
{ | { | ||||
bool Handle(byte[] firstPacket, int length, Socket socket, object state); | 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 | public class UDPState | ||||
@@ -25,9 +35,9 @@ namespace Shadowsocks.Controller | |||||
bool _shareOverLAN; | bool _shareOverLAN; | ||||
Socket _tcpSocket; | Socket _tcpSocket; | ||||
Socket _udpSocket; | Socket _udpSocket; | ||||
IList<Service> _services; | |||||
List<IService> _services; | |||||
public Listener(IList<Service> services) | |||||
public Listener(List<IService> services) | |||||
{ | { | ||||
this._services = services; | this._services = services; | ||||
} | } | ||||
@@ -97,6 +107,8 @@ namespace Shadowsocks.Controller | |||||
_udpSocket.Close(); | _udpSocket.Close(); | ||||
_udpSocket = null; | _udpSocket = null; | ||||
} | } | ||||
_services.ForEach(s=>s.Stop()); | |||||
} | } | ||||
public void RecvFromCallback(IAsyncResult ar) | public void RecvFromCallback(IAsyncResult ar) | ||||
@@ -105,7 +117,7 @@ namespace Shadowsocks.Controller | |||||
try | try | ||||
{ | { | ||||
int bytesRead = _udpSocket.EndReceiveFrom(ar, ref state.remoteEndPoint); | 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)) | if (service.Handle(state.buffer, bytesRead, _udpSocket, state)) | ||||
{ | { | ||||
@@ -187,7 +199,7 @@ namespace Shadowsocks.Controller | |||||
try | try | ||||
{ | { | ||||
int bytesRead = conn.EndReceive(ar); | int bytesRead = conn.EndReceive(ar); | ||||
foreach (Service service in _services) | |||||
foreach (IService service in _services) | |||||
{ | { | ||||
if (service.Handle(buf, bytesRead, conn, null)) | if (service.Handle(buf, bytesRead, conn, null)) | ||||
{ | { | ||||
@@ -35,7 +35,7 @@ namespace Shadowsocks.Controller | |||||
this._config = config; | 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) | if (socket.ProtocolType != ProtocolType.Tcp) | ||||
{ | { | ||||
@@ -14,7 +14,7 @@ namespace Shadowsocks.Controller | |||||
this._targetPort = targetPort; | 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) | if (socket.ProtocolType != ProtocolType.Tcp) | ||||
{ | { | ||||
@@ -29,7 +29,7 @@ namespace Shadowsocks.Controller | |||||
_lastSweepTime = DateTime.Now; | _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 | if (socket.ProtocolType != ProtocolType.Tcp | ||||
|| (length < 2 || firstPacket[0] != 5)) | || (length < 2 || firstPacket[0] != 5)) | ||||
@@ -62,6 +62,16 @@ namespace Shadowsocks.Controller | |||||
return true; | return true; | ||||
} | } | ||||
public override void Stop() | |||||
{ | |||||
List<TCPHandler> handlersToClose = new List<TCPHandler>(); | |||||
lock (Handlers) | |||||
{ | |||||
handlersToClose.AddRange(Handlers); | |||||
} | |||||
handlersToClose.ForEach(h=>h.Close()); | |||||
} | |||||
public void UpdateInboundCounter(Server server, long n) | public void UpdateInboundCounter(Server server, long n) | ||||
{ | { | ||||
_controller.UpdateInboundCounter(server, n); | _controller.UpdateInboundCounter(server, n); | ||||
@@ -24,7 +24,7 @@ namespace Shadowsocks.Controller | |||||
this._cache = new LRUCache<IPEndPoint, UDPHandler>(512); // todo: choose a smart number | this._cache = new LRUCache<IPEndPoint, UDPHandler>(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) | if (socket.ProtocolType != ProtocolType.Udp) | ||||
{ | { | ||||
@@ -429,7 +429,7 @@ namespace Shadowsocks.Controller | |||||
TCPRelay tcpRelay = new TCPRelay(this, _config); | TCPRelay tcpRelay = new TCPRelay(this, _config); | ||||
UDPRelay udpRelay = new UDPRelay(this); | UDPRelay udpRelay = new UDPRelay(this); | ||||
List<Listener.Service> services = new List<Listener.Service>(); | |||||
List<Listener.IService> services = new List<Listener.IService>(); | |||||
services.Add(tcpRelay); | services.Add(tcpRelay); | ||||
services.Add(udpRelay); | services.Add(udpRelay); | ||||
services.Add(_pacServer); | services.Add(_pacServer); | ||||