private Task StartUdpRelay() { return(Task.Factory.StartNew(async() => { try { int dataNumber = 0; while (true) { var readTask = _udp.ReceiveAsync(); var complete = await Task.WhenAny(readTask, Task.Delay(TimeSpan.FromSeconds(30))); if (complete != readTask) { Logger.LogWarning("Udp relay receive timeout, {0}", Id); break; } var readed = readTask.Result; var remote = readed.RemoteEndPoint; if (readed.Buffer.Length == 0) { break; } var requset = Socks5UdpRelayRequest.Parse(readed.Buffer); if (requset.Fraged) { // drop fraged datas continue; } // TODO: address check! if (_target.Port != 0 && remote.Port != _target.Port) { // drop not matched source datas by port continue; } _lastEndpoint = remote; var block = new BlockData() { Id = Id, BlockNumber = dataNumber++, Type = BlockType.DATA }; block.Data = requset.Data.ToBytes(); Shark.EncryptBlock(ref block); await Shark.WriteBlock(block); } } catch (Exception e) { Logger.LogError(e, "Socks udp relay errored"); } CloseConnetion(); _socksFailed = true; }).Unwrap()); }
public static Socks5UdpRelayRequest Parse(byte[] buffer) { var result = new Socks5UdpRelayRequest { Frag = buffer[2], Data = UdpPackData.Parse(new ReadOnlyMemory <byte>(buffer, 3, buffer.Length - 3)) }; return(result); }