featured show bandwidth in log form's title
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
using Shadowsocks.Model;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
|
||||
using Shadowsocks.Model;
|
||||
|
||||
namespace Shadowsocks.Controller
|
||||
{
|
||||
@@ -79,9 +79,7 @@ namespace Shadowsocks.Controller
|
||||
|
||||
// Start an asynchronous socket to listen for connections.
|
||||
Logging.Info("Shadowsocks started");
|
||||
_tcpSocket.BeginAccept(
|
||||
new AsyncCallback(AcceptCallback),
|
||||
_tcpSocket);
|
||||
_tcpSocket.BeginAccept(new AsyncCallback(AcceptCallback), _tcpSocket);
|
||||
UDPState udpState = new UDPState();
|
||||
_udpSocket.BeginReceiveFrom(udpState.buffer, 0, udpState.buffer.Length, 0, ref udpState.remoteEndPoint, new AsyncCallback(RecvFromCallback), udpState);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
|
||||
namespace Shadowsocks.Controller
|
||||
{
|
||||
|
||||
@@ -1,31 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Net.Sockets;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Timers;
|
||||
|
||||
using Shadowsocks.Controller.Strategy;
|
||||
using Shadowsocks.Encryption;
|
||||
using Shadowsocks.Model;
|
||||
using Shadowsocks.Controller.Strategy;
|
||||
using System.Timers;
|
||||
|
||||
namespace Shadowsocks.Controller
|
||||
{
|
||||
|
||||
class TCPRelay : Listener.Service
|
||||
{
|
||||
private ShadowsocksController _controller;
|
||||
private DateTime _lastSweepTime;
|
||||
|
||||
public ISet<Handler> Handlers
|
||||
public ISet<TCPHandler> Handlers
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public TCPRelay(ShadowsocksController controller)
|
||||
{
|
||||
this._controller = controller;
|
||||
this.Handlers = new HashSet<Handler>();
|
||||
this._lastSweepTime = DateTime.Now;
|
||||
_controller = controller;
|
||||
Handlers = new HashSet<TCPHandler>();
|
||||
_lastSweepTime = DateTime.Now;
|
||||
}
|
||||
|
||||
public bool Handle(byte[] firstPacket, int length, Socket socket, object state)
|
||||
@@ -39,22 +38,21 @@ namespace Shadowsocks.Controller
|
||||
return false;
|
||||
}
|
||||
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
|
||||
Handler handler = new Handler();
|
||||
TCPHandler handler = new TCPHandler(this);
|
||||
handler.connection = socket;
|
||||
handler.controller = _controller;
|
||||
handler.relay = this;
|
||||
|
||||
handler.Start(firstPacket, length);
|
||||
IList<Handler> handlersToClose = new List<Handler>();
|
||||
lock (this.Handlers)
|
||||
IList<TCPHandler> handlersToClose = new List<TCPHandler>();
|
||||
lock (Handlers)
|
||||
{
|
||||
this.Handlers.Add(handler);
|
||||
Logging.Debug($"TCP connections: {Handlers.Count}");
|
||||
Handlers.Add(handler);
|
||||
DateTime now = DateTime.Now;
|
||||
if (now - _lastSweepTime > TimeSpan.FromSeconds(1))
|
||||
{
|
||||
_lastSweepTime = now;
|
||||
foreach (Handler handler1 in this.Handlers)
|
||||
foreach (TCPHandler handler1 in Handlers)
|
||||
{
|
||||
if (now - handler1.lastActivity > TimeSpan.FromSeconds(900))
|
||||
{
|
||||
@@ -63,18 +61,28 @@ namespace Shadowsocks.Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (Handler handler1 in handlersToClose)
|
||||
foreach (TCPHandler handler1 in handlersToClose)
|
||||
{
|
||||
Logging.Debug("Closing timed out TCP connection.");
|
||||
handler1.Close();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void UpdateInboundCounter(long n)
|
||||
{
|
||||
_controller.UpdateInboundCounter(n);
|
||||
}
|
||||
|
||||
public void UpdateOutboundCounter(long n)
|
||||
{
|
||||
_controller.UpdateOutboundCounter(n);
|
||||
}
|
||||
}
|
||||
|
||||
class Handler
|
||||
class TCPHandler
|
||||
{
|
||||
//public Encryptor encryptor;
|
||||
// public Encryptor encryptor;
|
||||
public IEncryptor encryptor;
|
||||
public Server server;
|
||||
// Client socket.
|
||||
@@ -85,6 +93,7 @@ namespace Shadowsocks.Controller
|
||||
|
||||
public DateTime lastActivity;
|
||||
|
||||
private const int maxRetry = 4;
|
||||
private int retryCount = 0;
|
||||
private bool connected;
|
||||
|
||||
@@ -117,6 +126,12 @@ namespace Shadowsocks.Controller
|
||||
private object decryptionLock = new object();
|
||||
|
||||
private DateTime _startConnectTime;
|
||||
private TCPRelay tcprelay; // TODO: tcprelay ?= relay
|
||||
|
||||
public TCPHandler(TCPRelay tcprelay)
|
||||
{
|
||||
this.tcprelay = tcprelay;
|
||||
}
|
||||
|
||||
public void CreateRemote()
|
||||
{
|
||||
@@ -125,23 +140,23 @@ namespace Shadowsocks.Controller
|
||||
{
|
||||
throw new ArgumentException("No server configured");
|
||||
}
|
||||
this.encryptor = EncryptorFactory.GetEncryptor(server.method, server.password, server.auth, false);
|
||||
encryptor = EncryptorFactory.GetEncryptor(server.method, server.password, server.auth, false);
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
public void Start(byte[] firstPacket, int length)
|
||||
{
|
||||
this._firstPacket = firstPacket;
|
||||
this._firstPacketLength = length;
|
||||
this.HandshakeReceive();
|
||||
this.lastActivity = DateTime.Now;
|
||||
_firstPacket = firstPacket;
|
||||
_firstPacketLength = length;
|
||||
HandshakeReceive();
|
||||
lastActivity = DateTime.Now;
|
||||
}
|
||||
|
||||
private void CheckClose()
|
||||
{
|
||||
if (connectionShutdown && remoteShutdown)
|
||||
{
|
||||
this.Close();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +164,6 @@ namespace Shadowsocks.Controller
|
||||
{
|
||||
lock (relay.Handlers)
|
||||
{
|
||||
Logging.Debug($"TCP connections: {relay.Handlers.Count}");
|
||||
relay.Handlers.Remove(this);
|
||||
}
|
||||
lock (this)
|
||||
@@ -215,18 +229,17 @@ namespace Shadowsocks.Controller
|
||||
response = new byte[] { 0, 91 };
|
||||
Logging.Error("socks 5 protocol error");
|
||||
}
|
||||
Logging.Debug($"======Send Local Port, size:" + response.Length);
|
||||
connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(HandshakeSendCallback), null);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Close();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.LogUsefulException(e);
|
||||
this.Close();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,21 +253,19 @@ namespace Shadowsocks.Controller
|
||||
{
|
||||
connection.EndSend(ar);
|
||||
|
||||
// +----+-----+-------+------+----------+----------+
|
||||
// |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
|
||||
// +----+-----+-------+------+----------+----------+
|
||||
// | 1 | 1 | X'00' | 1 | Variable | 2 |
|
||||
// +----+-----+-------+------+----------+----------+
|
||||
// +-----+-----+-------+------+----------+----------+
|
||||
// | VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
|
||||
// +-----+-----+-------+------+----------+----------+
|
||||
// | 1 | 1 | X'00' | 1 | Variable | 2 |
|
||||
// +-----+-----+-------+------+----------+----------+
|
||||
// Skip first 3 bytes
|
||||
// TODO validate
|
||||
Logging.Debug($"======Receive Local Port, size:" + 3);
|
||||
connection.BeginReceive(connetionRecvBuffer, 0, 3, 0,
|
||||
new AsyncCallback(handshakeReceive2Callback), null);
|
||||
connection.BeginReceive(connetionRecvBuffer, 0, 3, 0, new AsyncCallback(handshakeReceive2Callback), null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.LogUsefulException(e);
|
||||
this.Close();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +285,6 @@ namespace Shadowsocks.Controller
|
||||
if (command == 1)
|
||||
{
|
||||
byte[] response = { 5, 0, 0, 1, 0, 0, 0, 0, 0, 0 };
|
||||
Logging.Debug($"======Send Local Port, size:" + response.Length);
|
||||
connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(ResponseCallback), null);
|
||||
}
|
||||
else if (command == 3)
|
||||
@@ -284,14 +294,14 @@ namespace Shadowsocks.Controller
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Error("failed to recv data in handshakeReceive2Callback");
|
||||
this.Close();
|
||||
Logging.Debug("failed to recv data in Shadowsocks.Controller.TCPHandler.handshakeReceive2Callback()");
|
||||
Close();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.LogUsefulException(e);
|
||||
this.Close();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,7 +323,6 @@ namespace Shadowsocks.Controller
|
||||
address.CopyTo(response, 4);
|
||||
response[response.Length - 1] = (byte)(port & 0xFF);
|
||||
response[response.Length - 2] = (byte)((port >> 8) & 0xFF);
|
||||
Logging.Debug($"======Send Local Port, size:" + response.Length);
|
||||
connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(ReadAll), true);
|
||||
}
|
||||
|
||||
@@ -328,29 +337,27 @@ namespace Shadowsocks.Controller
|
||||
if (ar.AsyncState != null)
|
||||
{
|
||||
connection.EndSend(ar);
|
||||
Logging.Debug($"======Receive Local Port, size:" + RecvSize);
|
||||
connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0,
|
||||
new AsyncCallback(ReadAll), null);
|
||||
Logging.Debug(remote, RecvSize, "TCP Relay");
|
||||
connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0, new AsyncCallback(ReadAll), null);
|
||||
}
|
||||
else
|
||||
{
|
||||
int bytesRead = connection.EndReceive(ar);
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
Logging.Debug($"======Receive Local Port, size:" + RecvSize);
|
||||
connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0,
|
||||
new AsyncCallback(ReadAll), null);
|
||||
Logging.Debug(remote, RecvSize, "TCP Relay");
|
||||
connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0, new AsyncCallback(ReadAll), null);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Close();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.LogUsefulException(e);
|
||||
this.Close();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,15 +373,16 @@ namespace Shadowsocks.Controller
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.LogUsefulException(e);
|
||||
this.Close();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
// inner class
|
||||
private class ServerTimer : Timer
|
||||
{
|
||||
public Server Server;
|
||||
|
||||
public ServerTimer(int p) :base(p)
|
||||
public ServerTimer(int p) : base(p)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -408,14 +416,12 @@ namespace Shadowsocks.Controller
|
||||
|
||||
connected = false;
|
||||
// Connect to the remote endpoint.
|
||||
Logging.Debug($"++++++Connect Server Port");
|
||||
remote.BeginConnect(remoteEP,
|
||||
new AsyncCallback(ConnectCallback), connectTimer);
|
||||
remote.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), connectTimer);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.LogUsefulException(e);
|
||||
this.Close();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,15 +444,15 @@ namespace Shadowsocks.Controller
|
||||
|
||||
private void RetryConnect()
|
||||
{
|
||||
if (retryCount < 4)
|
||||
if (retryCount < maxRetry)
|
||||
{
|
||||
Logging.Debug("Connection failed, retrying");
|
||||
Logging.Debug($"Connection failed, retry ({retryCount})");
|
||||
StartConnect();
|
||||
retryCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Close();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -507,17 +513,13 @@ namespace Shadowsocks.Controller
|
||||
}
|
||||
try
|
||||
{
|
||||
Logging.Debug($"++++++Receive Server Port, size:" + RecvSize);
|
||||
remote.BeginReceive(remoteRecvBuffer, 0, RecvSize, 0,
|
||||
new AsyncCallback(PipeRemoteReceiveCallback), null);
|
||||
Logging.Debug($"======Receive Local Port, size:"+ RecvSize);
|
||||
connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0,
|
||||
new AsyncCallback(PipeConnectionReceiveCallback), null);
|
||||
remote.BeginReceive(remoteRecvBuffer, 0, RecvSize, 0, new AsyncCallback(PipeRemoteReceiveCallback), null);
|
||||
connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0, new AsyncCallback(PipeConnectionReceiveCallback), null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.LogUsefulException(e);
|
||||
this.Close();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -531,10 +533,11 @@ namespace Shadowsocks.Controller
|
||||
{
|
||||
int bytesRead = remote.EndReceive(ar);
|
||||
totalRead += bytesRead;
|
||||
tcprelay.UpdateInboundCounter(bytesRead);
|
||||
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
this.lastActivity = DateTime.Now;
|
||||
lastActivity = DateTime.Now;
|
||||
int bytesToSend;
|
||||
lock (decryptionLock)
|
||||
{
|
||||
@@ -544,13 +547,13 @@ namespace Shadowsocks.Controller
|
||||
}
|
||||
encryptor.Decrypt(remoteRecvBuffer, bytesRead, remoteSendBuffer, out bytesToSend);
|
||||
}
|
||||
Logging.Debug($"======Send Local Port, size:" + bytesToSend);
|
||||
Logging.Debug(remote, bytesToSend, "TCP Relay", "@PipeRemoteReceiveCallback() (download)");
|
||||
connection.BeginSend(remoteSendBuffer, 0, bytesToSend, 0, new AsyncCallback(PipeConnectionSendCallback), null);
|
||||
|
||||
IStrategy strategy = controller.GetCurrentStrategy();
|
||||
if (strategy != null)
|
||||
{
|
||||
strategy.UpdateLastRead(this.server);
|
||||
strategy.UpdateLastRead(server);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -559,18 +562,18 @@ namespace Shadowsocks.Controller
|
||||
connectionShutdown = true;
|
||||
CheckClose();
|
||||
|
||||
if (totalRead == 0)
|
||||
{
|
||||
// closed before anything received, reports as failure
|
||||
// disable this feature
|
||||
// controller.GetCurrentStrategy().SetFailure(this.server);
|
||||
}
|
||||
//if (totalRead == 0)
|
||||
//{
|
||||
// // closed before anything received, reports as failure
|
||||
// // disable this feature
|
||||
// controller.GetCurrentStrategy().SetFailure(this.server);
|
||||
//}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.LogUsefulException(e);
|
||||
this.Close();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -584,6 +587,7 @@ namespace Shadowsocks.Controller
|
||||
{
|
||||
int bytesRead = connection.EndReceive(ar);
|
||||
totalWrite += bytesRead;
|
||||
tcprelay.UpdateOutboundCounter(bytesRead);
|
||||
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
@@ -596,13 +600,13 @@ namespace Shadowsocks.Controller
|
||||
}
|
||||
encryptor.Encrypt(connetionRecvBuffer, bytesRead, connetionSendBuffer, out bytesToSend);
|
||||
}
|
||||
Logging.Debug($"++++++Send Server Port, size:" + bytesToSend);
|
||||
Logging.Debug(remote, bytesToSend, "TCP Relay", "@PipeConnectionReceiveCallback() (upload)");
|
||||
remote.BeginSend(connetionSendBuffer, 0, bytesToSend, 0, new AsyncCallback(PipeRemoteSendCallback), null);
|
||||
|
||||
IStrategy strategy = controller.GetCurrentStrategy();
|
||||
if (strategy != null)
|
||||
{
|
||||
strategy.UpdateLastWrite(this.server);
|
||||
strategy.UpdateLastWrite(server);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -615,7 +619,7 @@ namespace Shadowsocks.Controller
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.LogUsefulException(e);
|
||||
this.Close();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -628,14 +632,12 @@ namespace Shadowsocks.Controller
|
||||
try
|
||||
{
|
||||
remote.EndSend(ar);
|
||||
Logging.Debug($"======Receive Local Port, size:" + RecvSize);
|
||||
connection.BeginReceive(this.connetionRecvBuffer, 0, RecvSize, 0,
|
||||
new AsyncCallback(PipeConnectionReceiveCallback), null);
|
||||
connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0, new AsyncCallback(PipeConnectionReceiveCallback), null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.LogUsefulException(e);
|
||||
this.Close();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -648,14 +650,12 @@ namespace Shadowsocks.Controller
|
||||
try
|
||||
{
|
||||
connection.EndSend(ar);
|
||||
Logging.Debug($"++++++Receive Server Port, size:" + RecvSize);
|
||||
remote.BeginReceive(this.remoteRecvBuffer, 0, RecvSize, 0,
|
||||
new AsyncCallback(PipeRemoteReceiveCallback), null);
|
||||
remote.BeginReceive(remoteRecvBuffer, 0, RecvSize, 0, new AsyncCallback(PipeRemoteReceiveCallback), null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.LogUsefulException(e);
|
||||
this.Close();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
using Shadowsocks.Controller.Strategy;
|
||||
using Shadowsocks.Encryption;
|
||||
using Shadowsocks.Model;
|
||||
using System.Net.Sockets;
|
||||
using System.Net;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Shadowsocks.Controller.Strategy;
|
||||
|
||||
namespace Shadowsocks.Controller
|
||||
{
|
||||
@@ -14,6 +14,10 @@ namespace Shadowsocks.Controller
|
||||
{
|
||||
private ShadowsocksController _controller;
|
||||
private LRUCache<IPEndPoint, UDPHandler> _cache;
|
||||
|
||||
public long outbound = 0;
|
||||
public long inbound = 0;
|
||||
|
||||
public UDPRelay(ShadowsocksController controller)
|
||||
{
|
||||
this._controller = controller;
|
||||
@@ -70,8 +74,8 @@ namespace Shadowsocks.Controller
|
||||
}
|
||||
_remoteEndPoint = new IPEndPoint(ipAddress, server.server_port);
|
||||
_remote = new Socket(_remoteEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
|
||||
|
||||
}
|
||||
|
||||
public void Send(byte[] data, int length)
|
||||
{
|
||||
IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password, _server.auth, true);
|
||||
@@ -80,15 +84,17 @@ namespace Shadowsocks.Controller
|
||||
byte[] dataOut = new byte[length - 3 + 16 + IVEncryptor.ONETIMEAUTH_BYTES];
|
||||
int outlen;
|
||||
encryptor.Encrypt(dataIn, length - 3, dataOut, out outlen);
|
||||
Logging.Debug($"++++++Send Server Port, size:" + outlen);
|
||||
Logging.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay");
|
||||
_remote.SendTo(dataOut, outlen, SocketFlags.None, _remoteEndPoint);
|
||||
}
|
||||
|
||||
public void Receive()
|
||||
{
|
||||
EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
|
||||
Logging.Debug($"++++++Receive Server Port, size:" + _buffer.Length);
|
||||
_remote.BeginReceiveFrom(_buffer, 0, _buffer.Length, 0, ref remoteEndPoint, new AsyncCallback(RecvFromCallback), null);
|
||||
}
|
||||
|
||||
public void RecvFromCallback(IAsyncResult ar)
|
||||
{
|
||||
try
|
||||
@@ -105,7 +111,7 @@ namespace Shadowsocks.Controller
|
||||
byte[] sendBuf = new byte[outlen + 3];
|
||||
Array.Copy(dataOut, 0, sendBuf, 3, outlen);
|
||||
|
||||
Logging.Debug($"======Send Local Port, size:" + (outlen + 3));
|
||||
Logging.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay");
|
||||
_local.SendTo(sendBuf, outlen + 3, 0, _localEndPoint);
|
||||
Receive();
|
||||
}
|
||||
@@ -121,6 +127,7 @@ namespace Shadowsocks.Controller
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
try
|
||||
@@ -142,7 +149,6 @@ namespace Shadowsocks.Controller
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// cc by-sa 3.0 http://stackoverflow.com/a/3719378/1124054
|
||||
class LRUCache<K, V> where V : UDPRelay.UDPHandler
|
||||
{
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
using System.IO;
|
||||
using Shadowsocks.Model;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Net.Sockets;
|
||||
|
||||
using Shadowsocks.Controller.Strategy;
|
||||
using System.Net;
|
||||
using Shadowsocks.Util;
|
||||
using Shadowsocks.Model;
|
||||
using Shadowsocks.Properties;
|
||||
using Shadowsocks.Util;
|
||||
|
||||
namespace Shadowsocks.Controller
|
||||
{
|
||||
@@ -30,6 +31,9 @@ namespace Shadowsocks.Controller
|
||||
public AvailabilityStatistics availabilityStatistics { get; private set; }
|
||||
public StatisticsStrategyConfiguration StatisticsConfiguration { get; private set; }
|
||||
|
||||
public long inboundCounter = 0;
|
||||
public long outboundCounter = 0;
|
||||
|
||||
private bool stopped = false;
|
||||
|
||||
private bool _systemProxyIsDirty = false;
|
||||
@@ -62,7 +66,6 @@ namespace Shadowsocks.Controller
|
||||
StartReleasingMemory();
|
||||
}
|
||||
|
||||
|
||||
public void Start()
|
||||
{
|
||||
Reload();
|
||||
@@ -302,6 +305,16 @@ namespace Shadowsocks.Controller
|
||||
Configuration.Save(_config);
|
||||
}
|
||||
|
||||
public void UpdateInboundCounter(long n)
|
||||
{
|
||||
inboundCounter += n;
|
||||
}
|
||||
|
||||
public void UpdateOutboundCounter(long n)
|
||||
{
|
||||
outboundCounter += n;
|
||||
}
|
||||
|
||||
protected void Reload()
|
||||
{
|
||||
// some logic in configuration updated the config when saving, we need to read it again
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using Shadowsocks.Controller;
|
||||
@@ -85,6 +83,33 @@ namespace Shadowsocks.Util
|
||||
}
|
||||
}
|
||||
|
||||
public static string FormatBandwide(long n)
|
||||
{
|
||||
float f = n;
|
||||
string unit = "B";
|
||||
if (f > 1024)
|
||||
{
|
||||
f = f / 1024;
|
||||
unit = "KiB";
|
||||
}
|
||||
if (f > 1024)
|
||||
{
|
||||
f = f / 1024;
|
||||
unit = "MiB";
|
||||
}
|
||||
if (f > 1024)
|
||||
{
|
||||
f = f / 1024;
|
||||
unit = "GiB";
|
||||
}
|
||||
if (f > 1024)
|
||||
{
|
||||
f = f / 1024;
|
||||
unit = "TiB";
|
||||
}
|
||||
return $"{f:.##}{unit}";
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool SetProcessWorkingSetSize(IntPtr process,
|
||||
|
||||
+14
-14
@@ -57,13 +57,13 @@
|
||||
this.LogMessageTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.LogMessageTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.LogMessageTextBox.ForeColor = System.Drawing.Color.White;
|
||||
this.LogMessageTextBox.Location = new System.Drawing.Point(3, 38);
|
||||
this.LogMessageTextBox.Location = new System.Drawing.Point(3, 40);
|
||||
this.LogMessageTextBox.MaxLength = 2147483647;
|
||||
this.LogMessageTextBox.Multiline = true;
|
||||
this.LogMessageTextBox.Name = "LogMessageTextBox";
|
||||
this.LogMessageTextBox.ReadOnly = true;
|
||||
this.LogMessageTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
||||
this.LogMessageTextBox.Size = new System.Drawing.Size(378, 99);
|
||||
this.LogMessageTextBox.Size = new System.Drawing.Size(378, 131);
|
||||
this.LogMessageTextBox.TabIndex = 0;
|
||||
//
|
||||
// MainMenu
|
||||
@@ -141,12 +141,12 @@
|
||||
//
|
||||
// TopMostCheckBox
|
||||
//
|
||||
this.TopMostCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
this.TopMostCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.TopMostCheckBox.AutoSize = true;
|
||||
this.TopMostCheckBox.Location = new System.Drawing.Point(249, 3);
|
||||
this.TopMostCheckBox.Location = new System.Drawing.Point(247, 3);
|
||||
this.TopMostCheckBox.Name = "TopMostCheckBox";
|
||||
this.TopMostCheckBox.Size = new System.Drawing.Size(72, 23);
|
||||
this.TopMostCheckBox.Size = new System.Drawing.Size(71, 25);
|
||||
this.TopMostCheckBox.TabIndex = 3;
|
||||
this.TopMostCheckBox.Text = "&Top Most";
|
||||
this.TopMostCheckBox.UseVisualStyleBackColor = true;
|
||||
@@ -157,7 +157,7 @@
|
||||
this.ChangeFontButton.AutoSize = true;
|
||||
this.ChangeFontButton.Location = new System.Drawing.Point(84, 3);
|
||||
this.ChangeFontButton.Name = "ChangeFontButton";
|
||||
this.ChangeFontButton.Size = new System.Drawing.Size(75, 23);
|
||||
this.ChangeFontButton.Size = new System.Drawing.Size(75, 25);
|
||||
this.ChangeFontButton.TabIndex = 2;
|
||||
this.ChangeFontButton.Text = "&Font";
|
||||
this.ChangeFontButton.UseVisualStyleBackColor = true;
|
||||
@@ -168,7 +168,7 @@
|
||||
this.CleanLogsButton.AutoSize = true;
|
||||
this.CleanLogsButton.Location = new System.Drawing.Point(3, 3);
|
||||
this.CleanLogsButton.Name = "CleanLogsButton";
|
||||
this.CleanLogsButton.Size = new System.Drawing.Size(75, 23);
|
||||
this.CleanLogsButton.Size = new System.Drawing.Size(75, 25);
|
||||
this.CleanLogsButton.TabIndex = 1;
|
||||
this.CleanLogsButton.Text = "&Clean Logs";
|
||||
this.CleanLogsButton.UseVisualStyleBackColor = true;
|
||||
@@ -176,12 +176,12 @@
|
||||
//
|
||||
// WrapTextCheckBox
|
||||
//
|
||||
this.WrapTextCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
this.WrapTextCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.WrapTextCheckBox.AutoSize = true;
|
||||
this.WrapTextCheckBox.Location = new System.Drawing.Point(165, 3);
|
||||
this.WrapTextCheckBox.Name = "WrapTextCheckBox";
|
||||
this.WrapTextCheckBox.Size = new System.Drawing.Size(78, 23);
|
||||
this.WrapTextCheckBox.Size = new System.Drawing.Size(76, 25);
|
||||
this.WrapTextCheckBox.TabIndex = 0;
|
||||
this.WrapTextCheckBox.Text = "&Wrap Text";
|
||||
this.WrapTextCheckBox.UseVisualStyleBackColor = true;
|
||||
@@ -199,7 +199,7 @@
|
||||
this.tableLayoutPanel1.RowCount = 2;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(384, 140);
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(384, 174);
|
||||
this.tableLayoutPanel1.TabIndex = 2;
|
||||
//
|
||||
// ToolbarFlowLayoutPanel
|
||||
@@ -212,17 +212,17 @@
|
||||
this.ToolbarFlowLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ToolbarFlowLayoutPanel.Location = new System.Drawing.Point(3, 3);
|
||||
this.ToolbarFlowLayoutPanel.Name = "ToolbarFlowLayoutPanel";
|
||||
this.ToolbarFlowLayoutPanel.Size = new System.Drawing.Size(378, 29);
|
||||
this.ToolbarFlowLayoutPanel.Size = new System.Drawing.Size(378, 31);
|
||||
this.ToolbarFlowLayoutPanel.TabIndex = 2;
|
||||
//
|
||||
// LogForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(384, 140);
|
||||
this.ClientSize = new System.Drawing.Size(384, 174);
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.Menu = this.MainMenu;
|
||||
this.MinimumSize = new System.Drawing.Size(400, 200);
|
||||
this.MinimumSize = new System.Drawing.Size(400, 213);
|
||||
this.Name = "LogForm";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "Log Viewer";
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using Shadowsocks.Controller;
|
||||
using Shadowsocks.Properties;
|
||||
using Shadowsocks.Model;
|
||||
using Shadowsocks.Util;
|
||||
|
||||
namespace Shadowsocks.View
|
||||
{
|
||||
@@ -112,11 +108,14 @@ namespace Shadowsocks.View
|
||||
|
||||
lastOffset = reader.BaseStream.Position;
|
||||
}
|
||||
|
||||
this.Text = $"Log Viewer [in: {Utils.FormatBandwide(controller.inboundCounter)}, out: {Utils.FormatBandwide(controller.outboundCounter)}]";
|
||||
}
|
||||
|
||||
private void LogForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
InitContent();
|
||||
|
||||
timer = new Timer();
|
||||
timer.Interval = 300;
|
||||
timer.Tick += Timer_Tick;
|
||||
|
||||
@@ -117,7 +117,31 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="LogMessageTextBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="MainMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="TopMostCheckBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="ChangeFontButton.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="CleanLogsButton.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="WrapTextCheckBox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="tableLayoutPanel1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="ToolbarFlowLayoutPanel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="$this.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
</root>
|
||||
Reference in New Issue
Block a user