Пример #1
0
        public int FillTrojanRequest(Span <byte> data, Destination.Destination destination, bool isUdpPayload = false, ushort udpPayloadSize = 0)
        {
            Span <byte> crlf = stackalloc byte[2];

            crlf[0] = 0x0D;
            crlf[1] = 0x0A;
            int len = 0;

            if (!isUdpPayload)
            {
                hashedPassword.Span.CopyTo(data);
                len += hashedPassword.Length;
                crlf.CopyTo(data.Slice(len, 2));
                len += crlf.Length;
                switch (destination.TransportProtocol)
                {
                case TransportProtocol.Tcp:
                    data[len++] = 1;
                    break;

                case TransportProtocol.Udp:
                    data[len++] = 3;
                    break;
                }
            }
            len += destination.FillSocks5StyleAddress(data.Slice(len));
            if (isUdpPayload)
            {
                data[len++] = (byte)(udpPayloadSize >> 8);
                data[len++] = (byte)(udpPayloadSize & 0xFF);
            }
            crlf.CopyTo(data.Slice(len));
            len += 2;
            return(len);
        }
Пример #2
0
 public void SendPacketToRemote(Memory <byte> data, Destination.Destination destination)
 {
     if (!MemoryMarshal.TryGetArray <byte>(data, out var segment))
     {
         throw new NotSupportedException("Cannot get segment from memory");
     }
     _ = datagramSocket.OutputStream.WriteAsync(segment.Array.AsBuffer(segment.Offset, segment.Count));
 }
Пример #3
0
        public async void SendPacketToRemote(Memory <byte> data, Destination.Destination destination)
        {
            var sendBuf = sendArrayPool.Rent(data.Length + destination.Host.Size + 8);

            try
            {
                var headerLen = FillTrojanRequest(sendBuf, destination, true, (ushort)data.Length);
                data.Span.CopyTo(sendBuf.AsSpan(headerLen));
                await outputStream.WriteAsync(sendBuf.AsBuffer(0, headerLen + data.Length));
            }
            finally
            {
                sendArrayPool.Return(sendBuf);
            }
        }
Пример #4
0
        public static Destination.Destination ParseDestinationFromRequest(ReadOnlySpan <byte> payload)
        {
            if (payload.Length < 8)
            {
                throw RequestTooShortException;
            }
            if (payload[0] != 5)
            {
                throw BadRequestException;
            }
            TransportProtocol protocol;

            switch (payload[1])
            {
            case 1:
                protocol = TransportProtocol.Tcp;
                break;

            case 3:
                protocol = TransportProtocol.Udp;
                break;

            default:
                throw UnknownTypeException;
            }
            if (Adapter.Destination.Destination.TryParseSocks5StyleAddress(payload.Slice(3), out Destination.Destination destination, protocol) == 0)
            {
                throw RequestTooShortException;
            }

            // Some SOCKS5 clients (e.g. curl) can resolve IP addresses locally.
            // In this case, we got a fake IP address and need to
            // convert it back to the corresponding domain name.
            switch (destination.Host)
            {
            case Ipv4Host ipv4:
                destination = new Destination.Destination(DnsProxyServer.TryLookup(ipv4.Data), destination.Port, protocol);
                break;
            }
            return(destination);
        }
Пример #5
0
        public async void SendPacketToRemote(Memory <byte> data, Destination.Destination destination)
        {
            try
            {
                await udpSendLock.WaitAsync().ConfigureAwait(false);
            }
            catch (NullReferenceException)
            {
                return;
            }
            catch (ObjectDisposedException)
            {
                return;
            }
            var udpSendBuffer    = sendArrayPool.Rent(destination.Host.Size + data.Length + 4);
            var udpSendEncBuffer = sendArrayPool.Rent(destination.Host.Size + data.Length + 52);

            try
            {
                // TODO: avoid copy
                var headerLen = destination.FillSocks5StyleAddress(udpSendBuffer);
                data.Span.CopyTo(udpSendBuffer.AsSpan(headerLen));
                var cryptor = ShadowsocksFactory.GlobalCryptorFactory.CreateCryptor();
                var ivLen   = Encrypt(Array.Empty <byte>(), udpSendEncBuffer, cryptor); // Fill IV/Salt first
                var len     = EncryptAll(udpSendBuffer.AsSpan(0, headerLen + data.Length), udpSendEncBuffer.AsSpan((int)ivLen), cryptor);
                _ = udpOutputStream.WriteAsync(udpSendEncBuffer.AsBuffer(0, (int)(len + ivLen)));
            }
            finally
            {
                try
                {
                    udpSendLock.Release();
                }
                catch (ObjectDisposedException) { }
                sendArrayPool.Return(udpSendBuffer);
                sendArrayPool.Return(udpSendEncBuffer);
            }
        }
Пример #6
0
        internal TunSocketAdapter(TcpSocket socket, TunInterface tun, IRemoteAdapter remoteAdapter)
        {
            Interlocked.Increment(ref OpenCount);
            var pipe = new Pipe();

            inboundReader = pipe.Reader;
            inboundWriter = pipe.Writer;
            _socket       = socket;
            _tun          = tun;

            socket.DataReceived += Socket_DataReceived;
            socket.DataSent     += Socket_DataSent;
            socket.SocketError  += Socket_SocketError;
            socket.RecvFinished += Socket_RecvFinished;

            // Resolve destination host
            var host = DnsProxyServer.TryLookup(socket.RemoteAddr);

            Destination = new Destination.Destination(host, socket.RemotePort, TransportProtocol.Tcp);

            this.remoteAdapter = remoteAdapter;
            StartPush();
            Init();
        }
Пример #7
0
        public static int ParseDestinationFromUdpPayload(ReadOnlySpan <byte> payload, out Destination.Destination destination)
        {
            if (payload.Length < 9)
            {
                destination = default;
                return(0);
            }
            if (payload[2] != 0)
            {
                // FRAG is not supported
            }
            var len = 3;

            len += Adapter.Destination.Destination.TryParseSocks5StyleAddress(payload.Slice(3), out destination, TransportProtocol.Udp);
            if (len == 0)
            {
                destination = default;
                return(0);
            }
            return(len);
        }
Пример #8
0
 public void SendPacketToRemote(Memory <byte> data, Destination.Destination destination)
 {
 }