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); }
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)); }
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); } }
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); }
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); } }
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(); }
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); }
public void SendPacketToRemote(Memory <byte> data, Destination.Destination destination) { }