Пример #1
0
        private void destConnectTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            var timer = (ServerTimer)sender;

            timer.Elapsed -= destConnectTimer_Elapsed;
            timer.Enabled  = false;
            timer.Dispose();

            if (_destConnected || _closed)
            {
                return;
            }

            var       session  = timer.Session;
            Server    server   = timer.Server;
            IStrategy strategy = _controller.GetCurrentStrategy();

            strategy?.SetFailure(server);
            Logging.Info($"{server.FriendlyName()} timed out");
            session.Remote.Close();
            Close();
        }
Пример #2
0
        private async Task StartConnect()
        {
            SaeaAwaitable serverSaea = null;

            try
            {
                CreateRemote();

                _serverSocket = new Socket(SocketType.Stream, ProtocolType.Tcp);
                _serverSocket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
                _serverSocket.SetTFO();

                // encrypt and attach encrypted buffer to ConnectAsync
                serverSaea = _argsPool.Rent();
                var realSaea = serverSaea.Saea;

                var encryptedbufLen = -1;
                Logging.Dump("StartConnect(): enc addrBuf", _addrBuf, _addrBufLength);
                DoEncrypt(_addrBuf, _addrBufLength, realSaea.Buffer, out encryptedbufLen);
                Logging.Debug("StartConnect(): addrBuf enc len " + encryptedbufLen);
                if (_remainingBytesLen > 0)
                {
                    Logging.Debug($"StartConnect(): remainingBytesLen: {_remainingBytesLen}");
                    var    encRemainingBufLen = -1;
                    byte[] tmp = new byte[4096];
                    Logging.Dump("StartConnect(): enc remaining", _remainingBytes, _remainingBytesLen);
                    DoEncrypt(_remainingBytes, _remainingBytesLen, tmp, out encRemainingBufLen);
                    Logging.Debug("StartConnect(): remaining enc len " + encRemainingBufLen);
                    Buffer.BlockCopy(tmp, 0, realSaea.Buffer, encryptedbufLen, encRemainingBufLen);
                    encryptedbufLen += encRemainingBufLen;
                }
                Logging.Debug("actual enc buf len " + encryptedbufLen);
                realSaea.RemoteEndPoint = SocketUtil.GetEndPoint(_server.server, _server.server_port);
                realSaea.SetBuffer(0, encryptedbufLen);

                _startConnectTime = DateTime.Now;
                var err = await _serverSocket.ConnectAsync(serverSaea);

                if (err != SocketError.Success)
                {
                    Logging.Error($"StartConnect: {err}");
                    Close();
                    return;
                }
                Logging.Debug("remote connected");
                if (serverSaea.Saea.BytesTransferred != encryptedbufLen)
                {
                    // not sent all data, it may caused by TFO, disable it
                    Logging.Info("Disable TCP Fast Open due to initial send failure");
                    Program.DisableTFO();
                    Close();
                    return;
                }

                _argsPool.Return(serverSaea);
                serverSaea = null;

                if (_config.isVerboseLogging)
                {
                    Logging.Info($"Socket connected to ss server: {_server.FriendlyName()}");
                }

                var latency = DateTime.Now - _startConnectTime;
                _controller.GetCurrentStrategy()?.UpdateLatency(_server, latency);
                _tcprelay.UpdateLatency(_server, latency);

                _startReceivingTime = DateTime.Now;

                Task.Factory.StartNew(StartPipe, TaskCreationOptions.PreferFairness).Forget();
            }
            catch (AggregateException agex)
            {
                foreach (var ex in agex.InnerExceptions)
                {
                    Logging.LogUsefulException(ex);
                }
                Close();
            }
            catch (Exception e)
            {
                Logging.LogUsefulException(e);
                Close();
            }
            finally
            {
                _argsPool.Return(serverSaea);
                serverSaea = null;
            }
        }