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()));
     }
 }
示例#6
0
 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;
 }
示例#7
0
        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;
        }
示例#9
0
        public override bool Equals(object obj)
        {
            Server o2 = (Server)obj;

            return(server == o2.server && server_port == o2.server_port);
        }
示例#10
0
 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);
            }
        }
示例#12
0
 public void UpdateLatency(Server server, TimeSpan latency)
 {
     _controller.UpdateLatency(server, latency);
 }
示例#13
0
        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();
            }
        }
示例#14
0
 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;
        }
示例#19
0
        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();
            }
        }
示例#20
0
 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;
 }
示例#21
0
 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
 }
示例#25
0
        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();
     }
 }
示例#27
0
 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;
 }
示例#29
0
        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();
            }
        }
示例#30
0
        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;
 }
示例#32
0
        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);
        }