private bool SaveOldSelectedServer() { try { if (_lastSelectedIndex == -1 || _lastSelectedIndex >= _modifiedConfiguration.configs.Count) { return true; } Server server = new Server { server = IPTextBox.Text, server_port = int.Parse(ServerPortTextBox.Text), password = PasswordTextBox.Text, method = EncryptionSelect.Text, remarks = RemarksTextBox.Text }; int localPort = int.Parse(ProxyPortTextBox.Text); Configuration.CheckServer(server); Configuration.CheckLocalPort(localPort); _modifiedConfiguration.configs[_lastSelectedIndex] = server; _modifiedConfiguration.localPort = localPort; return true; } catch (FormatException) { MessageBox.Show(I18N.GetString("Illegal port number format")); } catch (Exception ex) { MessageBox.Show(ex.Message); } return false; }
public static void CheckServer(Server server) { CheckPort(server.server_port); CheckPassword(server.password); CheckServer(server.server); CheckTimeout(server.timeout, Server.MaxServerTimeoutSec); }
public StatisticsStrategy(ShadowsocksController controller) { _controller = controller; var servers = controller.GetCurrentConfiguration().configs; var randomIndex = new Random().Next() % servers.Count(); _currentServer = servers[randomIndex]; //choose a server randomly at first _timer = new Timer(ReloadStatisticsAndChooseAServer); }
public bool AddServerBySSURL(string ssURL) { try { var server = new Server(ssURL); _config.configs.Add(server); _config.index = _config.configs.Count - 1; SaveConfig(_config); return true; } catch (Exception e) { Logging.LogUsefulException(e); return false; } }
/** * once failed, try after 5 min * and (last write - last read) < 5s * and (now - last read) < 5s // means not stuck * and latency < 200ms, try after 30s */ public void ChooseNewServer() { Server oldServer = _currentServer; List<ServerStatus> servers = new List<ServerStatus>(_serverStatus.Values); DateTime now = DateTime.Now; foreach (var status in servers) { // all of failure, latency, (lastread - lastwrite) normalized to 1000, then // 100 * failure - 2 * latency - 0.5 * (lastread - lastwrite) status.score = 100 * 1000 * Math.Min(5 * 60, (now - status.lastFailure).TotalSeconds) -2 * 5 * (Math.Min(2000, status.latency.TotalMilliseconds) / (1 + (now - status.lastTimeDetectLatency).TotalSeconds / 30 / 10) + -0.5 * 200 * Math.Min(5, (status.lastRead - status.lastWrite).TotalSeconds)); Logging.Debug(String.Format("server: {0} latency:{1} score: {2}", status.server.FriendlyName(), status.latency, status.score)); } ServerStatus max = null; foreach (var status in servers) { if (max == null) { max = status; } else { if (status.score >= max.score) { max = status; } } } if (max != null) { _currentServer = max.server; if (_currentServer != oldServer) { Console.WriteLine("HA switching to server: {0}", _currentServer.FriendlyName()); } Logging.Debug(String.Format("choosing server: {0}", _currentServer.FriendlyName())); } }
public void CreateRemote() { Server server = controller.GetAServer(IStrategyCallerType.TCP, (IPEndPoint)connection.RemoteEndPoint); if (server == null || server.server == "") { throw new ArgumentException("No server configured"); } encryptor = EncryptorFactory.GetEncryptor(server.method, server.password, server.auth, false); this.server = server; }
public void ReConnect() { ResetTimeout(0); reconnectTimesRemain--; reconnectTimes++; if (this.State != ConnectState.HANDSHAKE && this.State != ConnectState.READY) { lock (server) { server.ServerSpeedLog().AddDisconnectTimes(); server.GetConnections().DecRef(this.connection); } } if (reconnectTimes < 2) { server = this.getCurrentServer(true); } else { server = this.getCurrentServer(true, true); } CloseSocket(ref remote); CloseSocket(ref remoteUDP); if (remoteTDP != null) { try { remoteTDP.Shutdown(); //remoteTDP.Close(); } catch (Exception e) { Logging.LogUsefulException(e); } //remoteTDP = null; } if (obfs != null) { obfs.Dispose(); obfs = null; } if (protocol != null) { protocol.Dispose(); protocol = null; } connectionShutdown = false; remoteShutdown = false; speedTester.sizeUpload = 0; speedTester.sizeDownload = 0; lastErrCode = 0; Thread.Sleep(100); try { Connect(); } catch (Exception e) { LogSocketException(e); if (!Logging.LogSocketException(server.remarks, server.server, e)) Logging.LogUsefulException(e); this.Close(); } }
private bool SaveOldSelectedServer() { try { if (_lastSelectedIndex == -1 || _lastSelectedIndex >= _modifiedConfiguration.configs.Count) { return true; } Server server = new Server(); server.server = IPTextBox.Text.Trim(); try { server.server_port = int.Parse(ServerPortTextBox.Text); } catch (FormatException) { MessageBox.Show(I18N.GetString("Illegal port number format")); ServerPortTextBox.Clear(); return false; } server.password = PasswordTextBox.Text; server.method = EncryptionSelect.Text; server.remarks = RemarksTextBox.Text; try { server.timeout = int.Parse(TimeoutTextBox.Text); } catch (FormatException) { MessageBox.Show(I18N.GetString("Illegal timeout format")); TimeoutTextBox.Clear(); return false; } server.auth = OneTimeAuth.Checked; int localPort = int.Parse(ProxyPortTextBox.Text); Configuration.CheckServer(server); Configuration.CheckLocalPort(localPort); _modifiedConfiguration.configs[_lastSelectedIndex] = server; _modifiedConfiguration.localPort = localPort; return true; } catch (Exception ex) { MessageBox.Show(ex.Message); } return false; }
public override bool Equals(object obj) { Server o2 = (Server)obj; return(server == o2.server && server_port == o2.server_port); }
public static void CheckServer(Server server) { CheckPort(server.server_port); CheckPassword(server.password); CheckServer(server.server); }
private void ChooseNewServer(List<Server> servers) { if (_filteredStatistics == null || servers.Count == 0) { return; } try { var bestResult = (from server in servers let name = server.FriendlyName() where _filteredStatistics.ContainsKey(name) select new { server, score = GetScore(name) } ).Aggregate((result1, result2) => result1.score > result2.score ? result1 : result2); LogWhenEnabled($"Switch to server: {bestResult.server.FriendlyName()} by statistics: score {bestResult.score}"); _currentServer = bestResult.server; } catch (Exception e) { Logging.LogUsefulException(e); } }
public void UpdateLatency(Server server, TimeSpan latency) { _controller.UpdateLatency(server, latency); }
public void ReConnect() { ResetTimeout(0); reconnectTimesRemain--; reconnectTimes++; lock (server) { server.ServerSpeedLog().AddDisconnectTimes(); server.GetConnections().DecRef(this.connection); } if (reconnectTimes < 2) { server = this.getCurrentServer(true); } else { server = this.getCurrentServer(true, true); } CloseSocket(ref remote); CloseSocket(ref remoteUDP); if (remoteTDP != null) { try { remoteTDP.Shutdown(); //remoteTDP.Close(); } catch (Exception e) { Logging.LogUsefulException(e); } remoteTDP = null; } if (obfs != null) { obfs.Dispose(); obfs = null; } connectionShutdown = false; remoteShutdown = false; speedTester.sizeUpload = 0; speedTester.sizeDownload = 0; lastErrCode = 0; obfs = ObfsFactory.GetObfs(server.obfs); try { Connect(); } catch (Exception e) { LogSocketException(e); if (!Logging.LogSocketException(server.remarks, server.server, e)) Logging.LogUsefulException(e); this.Close(); } }
public ServerIndex(int i, Server s) { index = i; this.server = s; }
public void UpdateOutboundCounter(Server server, long n) { long count; if (_outboundCounter.TryGetValue(server.Identifier(), out count)) { count += n; } else { count = n; _lastOutboundCounter[server.Identifier()] = 0; } _outboundCounter[server.Identifier()] = count; }
public void UpdateLatency(Server server, int latency) { List<int> records; _latencyRecords.TryGetValue(server.Identifier(), out records); if (records == null) { records = new List<int>(); } records.Add(latency); _latencyRecords[server.Identifier()] = records; }
internal ICMPResult(Server server) { Server = server; }
private async Task<ICMPResult> ICMPTest(Server server) { Logging.Debug("Ping " + server.FriendlyName()); if (server.server == "") return null; var result = new ICMPResult(server); try { var IP = Dns.GetHostAddresses(server.server) .First( ip => ip.AddressFamily == AddressFamily.InterNetwork || ip.AddressFamily == AddressFamily.InterNetworkV6); var ping = new Ping(); foreach (var _ in Enumerable.Range(0, Repeat)) { try { var reply = await ping.SendTaskAsync(IP, TimeoutMilliseconds); if (reply.Status.Equals(IPStatus.Success)) { result.RoundtripTime.Add((int?) reply.RoundtripTime); } else { result.RoundtripTime.Add(null); } //Do ICMPTest in a random frequency Thread.Sleep(TimeoutMilliseconds + new Random().Next()%TimeoutMilliseconds); } catch (Exception e) { Logging.Error($"An exception occured while eveluating {server.FriendlyName()}"); Logging.LogUsefulException(e); } } } catch (Exception e) { Logging.Error($"An exception occured while eveluating {server.FriendlyName()}"); Logging.LogUsefulException(e); } return result; }
private void ConnectCallback(IAsyncResult ar) { Server server = null; if (closed) { return; } try { ServerTimer timer = (ServerTimer)ar.AsyncState; server = timer.Server; timer.Elapsed -= connectTimer_Elapsed; timer.Enabled = false; timer.Dispose(); // Complete the connection. remote.EndConnect(ar); connected = true; Logging.Debug($"Socket connected to {remote.RemoteEndPoint}"); var latency = DateTime.Now - _startConnectTime; IStrategy strategy = controller.GetCurrentStrategy(); strategy?.UpdateLatency(server, latency); tcprelay.UpdateLatency(server, latency); StartPipe(); } catch (ArgumentException) { } catch (Exception e) { if (server != null) { IStrategy strategy = controller.GetCurrentStrategy(); if (strategy != null) { strategy.SetFailure(server); } } Logging.LogUsefulException(e); RetryConnect(); } }
public Server Clone() { Server ret = new Server(); ret.server = (string)server.Clone(); ret.server_port = server_port; ret.password = (string)password.Clone(); ret.method = (string)method.Clone(); ret.obfs = (string)obfs.Clone(); ret.remarks = (string)remarks.Clone(); ret.enable = enable; ret.udp_over_tcp = udp_over_tcp; ret.tcp_protocol = tcp_protocol; ret.obfs_udp = obfs_udp; return ret; }
public void UpdateOutboundCounter(Server server, long n) { _controller.UpdateOutboundCounter(server, n); }
public string GetSSRemarksLinkForServer(Server server) { string parts = server.method + ":" + server.password + "@" + server.server + ":" + server.server_port + "#" + server.remarks; string base64 = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(parts)); return "ss://" + base64; }
public void UpdateLatency(Server server, TimeSpan latency) { if (_config.availabilityStatistics) { new Task(() => availabilityStatistics.UpdateLatency(server, (int) latency.TotalMilliseconds)).Start(); } }
public void UpdateLatency(Server server, TimeSpan latency) { //TODO: combine this part of data with ICMP statics }
private int SaveOldSelectedServer() { try { if (_oldSelectedIndex == -1 || _oldSelectedIndex >= _modifiedConfiguration.configs.Count) { return 0; // no changes } Server server = new Server { server = IPTextBox.Text, server_port = int.Parse(ServerPortTextBox.Text), password = PasswordTextBox.Text, method = EncryptionSelect.Text, obfs = ObfsCombo.Text, obfsparam = textObfsParam.Text, remarks = RemarksTextBox.Text, tcp_over_udp = CheckTCPoverUDP.Checked, udp_over_tcp = CheckUDPoverUDP.Checked, protocol = TCPProtocolComboBox.Text, obfs_udp = CheckObfsUDP.Checked, id = _SelectedID }; Configuration.CheckServer(server); int ret = 0; if (_modifiedConfiguration.configs[_oldSelectedIndex].server != server.server || _modifiedConfiguration.configs[_oldSelectedIndex].server_port != server.server_port || _modifiedConfiguration.configs[_oldSelectedIndex].remarks_base64 != server.remarks_base64 ) { ret = 1; // display changed } Server oldServer = _modifiedConfiguration.configs[_oldSelectedIndex]; if (oldServer.server == server.server && oldServer.server_port == server.server_port && oldServer.password == server.password && oldServer.method == server.method && oldServer.obfs == server.obfs && oldServer.obfsparam == server.obfsparam ) { server.setObfsData(oldServer.getObfsData()); } _modifiedConfiguration.configs[_oldSelectedIndex] = server; return ret; } catch (FormatException) { MessageBox.Show(I18N.GetString("Illegal port number format")); } catch (Exception ex) { MessageBox.Show(ex.Message); } return -1; // ERROR }
public void UpdateOutboundCounter(Server server, long n) { Interlocked.Add(ref outboundCounter, n); if (_config.availabilityStatistics) { new Task(() => availabilityStatistics.UpdateOutboundCounter(server, n)).Start(); } }
public void CopyServer(Server Server) { this.serverSpeedLog = Server.serverSpeedLog; this.dnsBuffer = Server.dnsBuffer; this.dnsTargetBuffer = Server.dnsTargetBuffer; this.Connections = Server.Connections; this.enable = Server.enable; }
public string GetSSLinkForServer(Server server) { string parts = server.method + ":" + server.password + "@" + server.server + ":" + server.server_port; if (server.obfs != "plain") parts = server.obfs + ":" + parts; string base64 = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(parts)); return "ss://" + base64; }
private void ProxyConnectCallback(IAsyncResult ar) { Server server = null; if (_closed) { return; } try { var session = (AsyncSession<ProxyTimer>) ar.AsyncState; ProxyTimer timer = session.State; var destEndPoint = timer.DestEndPoint; server = timer.Server; timer.Elapsed -= proxyConnectTimer_Elapsed; timer.Enabled = false; timer.Dispose(); var remote = session.Remote; // Complete the connection. remote.EndConnectProxy(ar); _proxyConnected = true; if (_config.isVerboseLogging) { if (!(remote is DirectConnect)) { Logging.Info($"Socket connected to proxy {remote.ProxyEndPoint}"); } } _startConnectTime = DateTime.Now; ServerTimer connectTimer = new ServerTimer(3000); connectTimer.AutoReset = false; connectTimer.Elapsed += destConnectTimer_Elapsed; connectTimer.Enabled = true; connectTimer.Session = session; connectTimer.Server = server; _destConnected = false; // Connect to the remote endpoint. remote.BeginConnectDest(destEndPoint, new AsyncCallback(ConnectCallback), new AsyncSession<ServerTimer>(session, connectTimer)); } catch (ArgumentException) { } catch (Exception e) { Logging.LogUsefulException(e); RetryConnect(); } }
private void ConnectCallback(IAsyncResult ar) { if (_closed) return; try { var session = (AsyncSession<ServerTimer>) ar.AsyncState; ServerTimer timer = session.State; _server = timer.Server; timer.Elapsed -= destConnectTimer_Elapsed; timer.Enabled = false; timer.Dispose(); var remote = session.Remote; // Complete the connection. remote.EndConnectDest(ar); _destConnected = true; if (_config.isVerboseLogging) { Logging.Info($"Socket connected to ss server: {_server.FriendlyName()}"); } var latency = DateTime.Now - _startConnectTime; IStrategy strategy = _controller.GetCurrentStrategy(); strategy?.UpdateLatency(_server, latency); _tcprelay.UpdateLatency(_server, latency); StartPipe(session); } catch (ArgumentException) { } catch (Exception e) { if (_server != null) { IStrategy strategy = _controller.GetCurrentStrategy(); strategy?.SetFailure(_server); } Logging.LogUsefulException(e); Close(); } }
public static string GetQRCode(Server server) { string parts = server.method + ":" + server.password + "@" + server.server + ":" + server.server_port; string base64 = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(parts)); return "ss://" + base64; }
private static Server ServerFromSSR(string ssrURL, string force_group = "") { var result = new Server(); // ssr://host:port:protocol:method:obfs:base64pass/?obfsparam=base64&remarks=base64&group=base64&udpport=0&uot=1 Match ssr = Regex.Match(ssrURL, "ssr://([A-Za-z0-9_-]+)", RegexOptions.IgnoreCase); if (!ssr.Success) { return(null); } string data = Util.Base64.DecodeUrlSafeBase64(ssr.Groups[1].Value); Dictionary <string, string> params_dict = new Dictionary <string, string>(); Match match = null; for (int nTry = 0; nTry < 2; ++nTry) { int param_start_pos = data.IndexOf("?"); if (param_start_pos > 0) { params_dict = ParseParam(data.Substring(param_start_pos + 1)); data = data.Substring(0, param_start_pos); } if (data.IndexOf("/") >= 0) { data = data.Substring(0, data.LastIndexOf("/")); } Regex UrlFinder = new Regex("^(.+):([^:]+):([^:]*):([^:]+):([^:]*):([^:]+)"); match = UrlFinder.Match(data); if (match.Success) { break; } // try match which not encode to base64 //ssr = Regex.Match(ssrURL, @"ssr://([A-Za-z0-9-_.:=?&/\[\]]+)", RegexOptions.IgnoreCase); //if (ssr.Success) // data = ssr.Groups[1].Value; //else throw new FormatException(); } if (match == null || !match.Success) { throw new FormatException(); } result.server = match.Groups[1].Value; result.server_port = int.Parse(match.Groups[2].Value); result.protocol = match.Groups[3].Value.Length == 0 ? "origin" : match.Groups[3].Value; result.protocol = result.protocol.Replace("_compatible", ""); result.method = match.Groups[4].Value; result.obfs = match.Groups[5].Value.Length == 0 ? "plain" : match.Groups[5].Value; result.obfs = result.obfs.Replace("_compatible", ""); result.password = Util.Base64.DecodeStandardSSRUrlSafeBase64(match.Groups[6].Value); if (params_dict.ContainsKey("protoparam")) { result.protocolparam = Util.Base64.DecodeStandardSSRUrlSafeBase64(params_dict["protoparam"]); } if (params_dict.ContainsKey("obfsparam")) { result.obfsparam = Util.Base64.DecodeStandardSSRUrlSafeBase64(params_dict["obfsparam"]); } if (params_dict.ContainsKey("remarks")) { result.remarks = Util.Base64.DecodeStandardSSRUrlSafeBase64(params_dict["remarks"]); } if (params_dict.ContainsKey("group")) { result.group = Util.Base64.DecodeStandardSSRUrlSafeBase64(params_dict["group"]); } else { result.group = ""; } if (params_dict.ContainsKey("uot")) { result.udp_over_tcp = int.Parse(params_dict["uot"]) != 0; } if (params_dict.ContainsKey("udpport")) { result.server_udp_port = int.Parse(params_dict["udpport"]); } if (!String.IsNullOrEmpty(force_group)) { result.group = force_group; } return(result); }