public override bool Handle(ServiceUserToken obj)
        {
            byte[] firstPacket = obj.firstPacket;
            int    length      = obj.firstPacketLength;
            Socket socket      = obj.socket;

            if (socket == null)
            {
                return(false);
            }
            if (socket.ProtocolType != ProtocolType.Udp)
            {
                return(false);
            }
            if (length < 4)
            {
                return(false);
            }
            IPEndPoint remoteEndPoint = (IPEndPoint)obj.remoteEndPoint;
            UDPHandler handler        = _cache.get(remoteEndPoint);

            if (handler == null)
            {
                handler = new UDPHandler(socket,
                                         _controller.GetAServer(remoteEndPoint, null /*TODO: fix this*/),
                                         remoteEndPoint, _argsPool);
                _cache.add(remoteEndPoint, handler);
            }
            Task.Factory.StartNew(async() => { await handler.Start(firstPacket, length); }).Forget();
            return(true);
        }
 private void HandleUDPServices(ServiceUserToken token)
 {
     foreach (IService service in _services)
     {
         if (service.Handle(token))
         {
             return;
         }
     }
 }
        private async Task RecvFirstPacket(Socket clientSocket)
        {
            SaeaAwaitable arg = null;

            try
            {
                arg = _argsPool.Rent();
                var token = await clientSocket.FullReceiveTaskAsync(arg, MaxFirstPacketLen);

                var err = token.SocketError;
                ServiceUserToken serviceToken = null;
                var bytesReceived             = token.BytesTotalTransferred;
                Logging.Debug($"RecvFirstPacket: {err},{bytesReceived}");
                if (err == SocketError.Success && bytesReceived > 0)
                {
                    serviceToken = new ServiceUserToken
                    {
                        socket            = clientSocket,
                        firstPacket       = new byte[bytesReceived],
                        firstPacketLength = bytesReceived
                    };
                    Buffer.BlockCopy(arg.Saea.Buffer, 0, serviceToken.firstPacket, 0, bytesReceived);
                }
                else
                {
                    Logging.Error($"RecvFirstPacket socket err: {err},{bytesReceived}");
                    goto Shutdown;
                }
                _argsPool.Return(arg);
                arg = null;

                foreach (IService service in _services)
                {
                    if (service.Handle(serviceToken))
                    {
                        return;
                    }
                }
Shutdown:
                // no service found for this
                if (clientSocket.ProtocolType == ProtocolType.Tcp)
                {
                    clientSocket.Close();
                }
            }
            catch (Exception e)
            {
                Logging.Error(e);
            }
            finally
            {
                _argsPool.Return(arg);
                arg = null;
            }
        }
        public override bool Handle(ServiceUserToken obj)
        {
            byte[] firstPacket = obj.firstPacket;
            int    length      = obj.firstPacketLength;
            Socket socket      = obj.socket;

            if (socket == null)
            {
                return(false);
            }
            if (socket.ProtocolType != ProtocolType.Tcp ||
                (length < 2 || firstPacket[0] != 5))
            {
                return(false);
            }
            socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
            TCPHandler handler = new TCPHandler(_controller, _config, this, socket);

            IList <TCPHandler> handlersToClose = new List <TCPHandler>();

            lock (Handlers)
            {
                Handlers.Add(handler);
                DateTime now = DateTime.Now;
                if (now - _lastSweepTime > TimeSpan.FromSeconds(1))
                {
                    _lastSweepTime = now;
                    foreach (TCPHandler handler1 in Handlers)
                    {
                        if (now - handler1.lastActivity > TimeSpan.FromSeconds(900))
                        {
                            handlersToClose.Add(handler1);
                        }
                    }
                }
            }

            foreach (TCPHandler handler1 in handlersToClose)
            {
                Logging.Debug("Closing timed out TCP connection.");
                handler1.Close();
            }

            /*
             * Start after we put it into Handlers set. Otherwise if it failed in handler.Start()
             * then it will call handler.Close() before we add it into the set.
             * Then the handler will never release until the next Handle call. Sometimes it will
             * cause odd problems (especially during memory profiling).
             */
            handler.Start(firstPacket, length);
            IncrementTCPConnectionCounter();

            return(true);
        }
        private async Task StartRecvFrom()
        {
            SaeaAwaitable udpSaea = null;

            try
            {
                while (IsListening)
                {
                    udpSaea = _argsPool.Rent();
                    udpSaea.Saea.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
                    var err = await _udpSocket.ReceiveFromAsync(udpSaea);

                    var saea        = udpSaea.Saea;
                    var bytesRecved = saea.BytesTransferred;

                    if (err == SocketError.Success && bytesRecved > 0)
                    {
                        ServiceUserToken token = new ServiceUserToken
                        {
                            socket            = _udpSocket,
                            firstPacket       = new byte[bytesRecved],
                            firstPacketLength = bytesRecved,
                            remoteEndPoint    = saea.RemoteEndPoint
                        };
                        Buffer.BlockCopy(saea.Buffer, 0, token.firstPacket, 0, bytesRecved);

                        Task.Factory.StartNew(() => HandleUDPServices(token)).Forget();
                    }
                    else
                    {
                        Logging.Error($"RecvFrom: {err},{bytesRecved}");
                    }
                    _argsPool.Return(udpSaea);
                    udpSaea = null;
                }
            }
            catch (Exception e)
            {
                Logging.LogUsefulException(e);
            }
            finally
            {
                _argsPool.Return(udpSaea);
                udpSaea = null;
            }
        }
Exemple #6
0
        private async Task StartRecvFrom()
        {
            SaeaAwaitable udpSaea = null;

            try
            {
                while (IsListening)
                {
                    udpSaea = _argsPool.Rent();
                    udpSaea.Saea.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
                    var err = await _udpSocket.ReceiveFromAsync(udpSaea);

                    ServiceUserToken token = new ServiceUserToken();
                    if (err == SocketError.Success && udpSaea.Saea.BytesTransferred > 0)
                    {
                        var e = udpSaea.Saea;
                        token.socket            = _udpSocket;
                        token.firstPacket       = new byte[e.BytesTransferred];
                        token.firstPacketLength = e.BytesTransferred;
                        token.remoteEndPoint    = e.RemoteEndPoint;
                        Buffer.BlockCopy(e.Buffer, e.Offset, token.firstPacket, 0, e.BytesTransferred);
                    }
                    _argsPool.Return(udpSaea);
                    udpSaea = null;

                    foreach (IService service in _services)
                    {
                        if (service.Handle(token))
                        {
                            return;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Logging.LogUsefulException(e);
            }
            finally
            {
                _argsPool.Return(udpSaea);
                udpSaea = null;
            }
        }
        public override bool Handle(ServiceUserToken obj)
        {
            Socket socket = obj.socket;

            if (socket == null)
            {
                return(false);
            }
            if (socket.ProtocolType != ProtocolType.Tcp)
            {
                return(false);
            }
            byte[] firstPacket = obj.firstPacket;
            int    length      = obj.firstPacketLength;

            if (length <= 0)
            {
                return(false);
            }

            new Handler().Start(firstPacket, length, socket, _targetPort, _argsPool);
            return(true);
        }
Exemple #8
0
        public override bool Handle(ServiceUserToken obj)
        {
            byte[] firstPacket = obj.firstPacket;
            int    length      = obj.firstPacketLength;
            Socket socket      = obj.socket;

            if (socket == null)
            {
                return(false);
            }
            if (socket.ProtocolType != ProtocolType.Tcp)
            {
                return(false);
            }
            try
            {
                string   request = Encoding.UTF8.GetString(firstPacket, 0, length);
                string[] lines = request.Split('\r', '\n');
                bool     hostMatch = false, pathMatch = false, useSocks = false;
                bool     secretMatch = PacSecret.IsNullOrEmpty();
                foreach (string line in lines)
                {
                    string[] kv = line.Split(new char[] { ':' }, 2);
                    if (kv.Length == 2)
                    {
                        if (kv[0] == "Host")
                        {
                            if (kv[1].Trim() == ((IPEndPoint)socket.LocalEndPoint).ToString())
                            {
                                hostMatch = true;
                            }
                        }
                        //else if (kv[0] == "User-Agent")
                        //{
                        //    // we need to drop connections when changing servers
                        //    if (kv[1].IndexOf("Chrome") >= 0)
                        //    {
                        //        useSocks = true;
                        //    }
                        //}
                    }
                    else if (kv.Length == 1)
                    {
                        if (line.IndexOf("pac", StringComparison.Ordinal) >= 0)
                        {
                            pathMatch = true;
                        }
                        if (!secretMatch)
                        {
                            if (line.IndexOf(PacSecret, StringComparison.Ordinal) >= 0)
                            {
                                secretMatch = true;
                            }
                        }
                    }
                }
                if (hostMatch && pathMatch)
                {
                    if (!secretMatch)
                    {
                        socket.Close(); // Close immediately
                    }
                    else
                    {
                        Task.Factory.StartNew(
                            async() => { await SendResponse(firstPacket, length, socket, useSocks); },
                            TaskCreationOptions.PreferFairness);
                    }
                    return(true);
                }
                return(false);
            }
            catch (ArgumentException)
            {
                return(false);
            }
        }
 public abstract bool Handle(ServiceUserToken token);