private async Task StartConnect(int port)
            {
                SaeaAwaitable tcpSaea = null;

                try
                {
                    tcpSaea = _argsPool.Rent();
                    var realSaea = tcpSaea.Saea;
                    realSaea.RemoteEndPoint = SocketUtil.GetEndPoint("127.0.0.1", port);
                    tcpSaea.PrepareSAEABuffer(_firstPacket, _firstPacketLength);
                    var ret = await _remote.ConnectAsync(tcpSaea);

                    if (ret != SocketError.Success)
                    {
                        Close();
                        return;
                    }

                    Task.Factory.StartNew(StartPipe, TaskCreationOptions.PreferFairness).Forget();
                }
                catch (Exception e)
                {
                    Logging.LogUsefulException(e);
                    Close();
                }
                finally
                {
                    _argsPool.Return(tcpSaea);
                    tcpSaea = null;
                }
            }
Exemplo n.º 2
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);

                    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;
            }
        }
Exemplo n.º 3
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;
            }
        }
Exemplo n.º 4
0
        private async Task Accept()
        {
            SaeaAwaitable saea = null;

            try
            {
                while (IsListening)
                {
                    saea = _acceptArgsPool.Rent();

                    var socketError = await _tcpListenerSocket.AcceptAsync(saea);

                    if (socketError == SocketError.Success)
                    {
                        Logging.Debug("accepted a connection");
                        var acceptedSocket = saea.Saea.AcceptSocket;
                        Task.Factory.StartNew(async() => { await RecvFirstPacket(acceptedSocket); },
                                              TaskCreationOptions.PreferFairness).Forget();
                    }
                    else
                    {
                        Logging.Error($"Accept socket err: {socketError}");
                    }
                    _acceptArgsPool.Return(saea);
                    saea = null;
                }
            }
            catch (Exception ex)
            {
                Logging.LogUsefulException(ex);
            }
            finally
            {
                _acceptArgsPool.Return(saea);
                saea = null;
            }
        }
Exemplo n.º 5
0
            public async Task Start(byte[] data, int length)
            {
                Interlocked.Exchange(ref _state, _running);
                SaeaAwaitable upSaea   = null;
                SaeaAwaitable downSaea = null;

                try
                {
                    Logging.Debug($"-----UDP relay got {length}-----");
                    IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password);
                    byte[]     dataIn    = new byte[length - 3];
                    Array.Copy(data, 3, dataIn, 0, length - 3);

                    upSaea = _argsPool.Rent();
                    int outlen;
                    encryptor.EncryptUDP(dataIn, dataIn.Length, upSaea.Saea.Buffer, out outlen);
                    upSaea.Saea.SetBuffer(0, outlen);
                    upSaea.Saea.RemoteEndPoint = _serverEndPoint;

                    var ret = await _serverSocket.SendToAsync(upSaea);

                    if (ret != SocketError.Success)
                    {
                        Logging.Error($"[udp] remote sendto {ret},{upSaea.Saea.BytesTransferred}");
                        Close();
                        return;
                    }
                    Logging.Debug($"[udp] remote sendto {_localEndPoint} -> {_serverEndPoint} {upSaea.Saea.BytesTransferred}");

                    _argsPool.Return(upSaea);
                    upSaea = null;

                    while (IsRunning)
                    {
                        downSaea = _argsPool.Rent();
                        downSaea.Saea.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
                        ret = await _serverSocket.ReceiveFromAsync(downSaea);

                        var bytesReceived = downSaea.Saea.BytesTransferred;
                        if (ret != SocketError.Success)
                        {
                            Logging.Error($"[udp] remote recvfrom {ret},{bytesReceived}");
                            Close();
                            return;
                        }
                        Logging.Debug($"[udp] remote recvfrom {downSaea.Saea.RemoteEndPoint} -> {_localSocket.LocalEndPoint} {bytesReceived}");
                        byte[] dataOut = new byte[bytesReceived];
                        encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password);
                        encryptor.DecryptUDP(downSaea.Saea.Buffer, bytesReceived, dataOut, out outlen);
                        downSaea.ClearAndResetSaeaProperties();

                        byte[] buf = downSaea.Saea.Buffer;
                        buf[0] = buf[1] = buf[2] = 0;
                        Array.Copy(dataOut, 0, buf, 3, outlen);
                        downSaea.Saea.RemoteEndPoint = _localEndPoint;
                        downSaea.Saea.SetBuffer(0, outlen + 3);
                        ret = await _localSocket.SendToAsync(downSaea);

                        if (ret != SocketError.Success)
                        {
                            Logging.Error($"[udp] local sendto {ret},{downSaea.Saea.BytesTransferred}");
                            Close();
                            return;
                        }
                        Logging.Debug($"[udp] local sendto {_localSocket.LocalEndPoint} -> {_localEndPoint} {downSaea.Saea.BytesTransferred}");
                        _argsPool.Return(downSaea);
                        downSaea = null;
                    }
                }
                catch (Exception e)
                {
                    Logging.LogUsefulException(e);
                    Close();
                }
                finally
                {
                    _argsPool.Return(upSaea);
                    upSaea = null;
                    _argsPool.Return(downSaea);
                    downSaea = null;
                }
            }
Exemplo n.º 6
0
        private async Task HandshakeSendResponse()
        {
            SaeaAwaitable tcpSaea = null;

            try
            {
                if (_firstPacketLength <= 1)
                {
                    Logging.Debug("Invalid first packet length");
                    Close();
                    return;
                }
                byte[] response = TCPRelay.Sock5HandshakeResponseSuccess;
                if (_firstPacket[0] != 5)
                {
                    // reject socks 4
                    response = TCPRelay.Sock5HandshakeResponseReject;
                    Logging.Error("socks 5 protocol error");
                }

                tcpSaea = _argsPool.Rent();
                tcpSaea.PrepareSAEABuffer(response, response.Length);
                var token = await _localSocket.FullSendTaskAsync(tcpSaea, response.Length);

                var err       = token.SocketError;
                var bytesSent = token.BytesTotalTransferred;
                Logging.Debug($"HandshakeSendResponse: {err},{bytesSent}");
                if (err != SocketError.Success)
                {
                    Close();
                    return;
                }
                _argsPool.Return(tcpSaea);
                tcpSaea = null;
                Debug.Assert(bytesSent == response.Length);
                Task.Factory.StartNew(async() => { await Sock5RequestRecv(); }).Forget();
            }
            catch (Exception e)
            {
                Logging.LogUsefulException(e);
                Close();
            }
            finally
            {
                _argsPool.Return(tcpSaea);
                tcpSaea = null;
            }
        }
Exemplo n.º 7
0
            public async Task Start(byte[] data, int length)
            {
                Interlocked.Exchange(ref _state, _running);
                SaeaAwaitable udpSaea = null;

                try
                {
                    while (IsRunning)
                    {
                        IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password);
                        byte[]     dataIn    = new byte[length - 3];
                        Array.Copy(data, 3, dataIn, 0, length - 3);
                        udpSaea = _argsPool.Rent();

                        int outlen;
                        encryptor.EncryptUDP(dataIn, length - 3, udpSaea.Saea.Buffer, out outlen);
                        udpSaea.Saea.SetBuffer(0, outlen);
                        udpSaea.Saea.RemoteEndPoint = _remoteEndPoint;

                        Logging.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay");
                        var ret = await _remote.SendToAsync(udpSaea);

                        if (ret != SocketError.Success)
                        {
                            Close();
                            return;
                        }
                        udpSaea = _argsPool.Rent();
                        udpSaea.Saea.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
                        ret = await _remote.ReceiveFromAsync(udpSaea);

                        if (ret != SocketError.Success)
                        {
                            Close();
                            return;
                        }
                        var bytesReceived = udpSaea.Saea.BytesTransferred;
                        Logging.Debug($"++++++Receive Server Port, size:" + bytesReceived);


                        byte[] dataOut = new byte[bytesReceived];
                        encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password);
                        encryptor.DecryptUDP(udpSaea.Saea.Buffer, bytesReceived, dataOut, out outlen);
                        _argsPool.Return(udpSaea);
                        udpSaea = null;

                        udpSaea = _argsPool.Rent();
                        byte[] buf = udpSaea.Saea.Buffer;
                        buf[0] = buf[1] = buf[2] = 0;
                        Array.Copy(dataOut, 0, buf, 3, outlen);
                        udpSaea.Saea.RemoteEndPoint = _localEndPoint;
                        udpSaea.Saea.SetBuffer(0, outlen + 3);
                        Logging.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay");
                        ret = await _local.SendToAsync(udpSaea);

                        if (ret != SocketError.Success)
                        {
                            Close();
                            return;
                        }
                        _argsPool.Return(udpSaea);
                        udpSaea = null;
                    }
                }
                catch (Exception e)
                {
                    Logging.LogUsefulException(e);
                    Close();
                }
                finally
                {
                    _argsPool.Return(udpSaea);
                    udpSaea = null;
                }
            }