private async void doWork() { while (await taskChannel.Reader.WaitToReadAsync()) { taskChannel.Reader.TryRead(out var act); try { #if YTLOG_VERBOSE var sw = Stopwatch.StartNew(); #endif act(); #if YTLOG_VERBOSE //Debug.WriteLine($"{dispatchWorks.Count} tasks remain {sw.ElapsedMilliseconds}"); #endif } catch (Exception e) { DebugLogger.Log("Error from task queue: " + e.ToString()); var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings.Values; if (localSettings.TryGetValue("lastError", out var lastErr) && lastErr is string lastErrStr) { lastErrStr += "\r\n" + e.ToString(); } else { lastErrStr = e.ToString(); } localSettings["lastError"] = lastErrStr; } } }
public void Encapsulate(VpnChannel channel, VpnPacketBufferList packets, VpnPacketBufferList encapulatedPackets) { try { uint packetCount = packets.Size; var tun = context.tun; if (tun == null) { return; } while (packetCount-- > 0) { #if YTLOG_VERBOSE LogLine("Encapsulating " + packets.Size.ToString(), channel); #endif var packet = packets.RemoveAtBegin(); tun.PushPacket(packet.Buffer.ToArray()); packets.Append(packet); } } catch (Exception ex) { DebugLogger.Log("Error encapsulating packets: " + ex.ToString()); } }
public async void Deinit() { if (!running) { return; } running = false; DebugLogger.Log("Tun deinit req"); wintun.PacketPoped -= W_PopPacket; TcpSocket.EstablishedTcp -= W_EstablishTcp; foreach (var weakAdapter in tunAdapters.Where(w => w.TryGetTarget(out var a) /* TODO: && a.IsShutdown != 0 */)) { try { weakAdapter.TryGetTarget(out var adapter); adapter.Reset(); } catch (Exception) { } } TunDatagramAdapter.socketMap.Clear(); await Task.Delay(300).ConfigureAwait(false); wintun.Deinit(); tunAdapters.Clear(); // To avoid problems after reconnecting // dnsServer.Clear(); // dispatchWorker = null; taskChannel.Writer.TryComplete(); // debugSocket?.Dispose(); // debugSocket = null; DebugLogger.initNeeded = null; }
public void Run(IBackgroundTaskInstance taskInstance) { var initDebugSocketNeeded = DebugLogger.InitNeeded(); if (initDebugSocketNeeded) { try { var _ = DebugLogger.InitDebugSocket(); } catch (Exception) { } } VpnChannel.ProcessEventAsync(Plugin, taskInstance.TriggerDetails); DebugLogger.Log("VPN Background task finished"); }
private async void StartRecv() { while (u != null) { try { var recv = await u.ReceiveAsync().ConfigureAwait(false); tun?.PushPacket(recv.Buffer); } catch (ObjectDisposedException) { } catch (Exception ex) { DebugLogger.Log("Error receiving from packet processor: " + ex.ToString()); } } }
private void Tun_PacketPoped(object sender, byte[] e) { try { // await s?.OutputStream.WriteAsync(e.AsBuffer()); // await (u?.SendAsync(e, e.Length, pluginEndpoint) ?? Task.CompletedTask).ConfigureAwait(false); _ = outPackets.Writer.TryWrite(e); _ = u.SendAsync(DUMMY_DATA, DUMMY_DATA.Length, pluginEndpoint); } catch (Exception ex) { DebugLogger.Log("Error popping a packet: " + ex.ToString()); } finally { // packetPopLock.Release(); } }
public async void Init() { if (running) { return; } adapterFactory = await AdapterConfig.GetAdapterFactoryFromDefaultFile(); running = true; taskChannel = Channel.CreateUnbounded <Action>(new UnboundedChannelOptions() { SingleReader = true }); var _ = Task.Run(() => doWork()); wintun.PacketPoped += W_PopPacket; TcpSocket.EstablishedTcp += W_EstablishTcp; wintun.Init(); int i = 0; while (running) { i++; await executeLwipTask(() => { wintun.CheckTimeout(); return(0); }).ConfigureAwait(false); if (i % 10 == 0) { tunAdapters.RemoveAll(w => !w.TryGetTarget(out var a) /* TODO: || a.IsShutdown == 1 */); if (DebugLogger.LogNeeded()) { DebugLogger.Log("# of connections in local stack: " + ConnectionCount); DebugLogger.Log($"# of open/all adapters: {TunSocketAdapter.OpenCount} {tunAdapters.Count}"); DebugLogger.Log($"# of recv/send: {TunSocketAdapter.RecvingCount} {TunSocketAdapter.SendingCount}"); } } await Task.Delay(250).ConfigureAwait(false); } }
public void PushPacket([ReadOnlyArray] byte[] packet) { // Packets must contain valid IPv4 headers if (packet.Length < 20 || packet[0] >> 4 != 4) { return; } var proto = packet[9]; switch (proto) { case 6: // TCP break; case 17: // UDP break; default: return; } if (DebugLogger.LogNeeded()) { var _ = DebugLogger.LogPacketWithTimestamp(packet); } if (proto == 6) { _ = executeLwipTask(() => wintun.PushPacket(packet)); } else { try { TunDatagramAdapter.ProcessIpPayload(packet, this); } catch (Exception ex) { DebugLogger.Log("Error processing udp ip packet: " + ex.ToString()); } } }
public void Disconnect(VpnChannel channel) { try { State = VpnPluginState.Disconnecting; DebugLogger.Log("Stopping channel"); channel.Stop(); DebugLogger.Log("Stopping context"); context.Stop(); DebugLogger.Log("Context stopped"); } catch (Exception ex) { DebugLogger.Log("Error disconnecting: " + ex.ToString()); } finally { State = VpnPluginState.Disconnected; var _ = DebugLogger.ResetLoggers(); DebugLogger.initNeeded = null; } }
public void Decapsulate(VpnChannel channel, VpnPacketBuffer encapPacketBuffer, VpnPacketBufferList decapsulatedPackets, VpnPacketBufferList controlPacketsToSend) { try { var reader = context.outPackets?.Reader; if (reader == null) { return; } while (reader.TryRead(out var bytes)) { var encapBuffer = channel.GetVpnReceivePacketBuffer(); var encapBuf = encapBuffer.Buffer; bytes.CopyTo(encapBuf); encapBuf.Length = (uint)bytes.Length; decapsulatedPackets.Append(encapBuffer); } } catch (Exception ex) { DebugLogger.Log("Error decapsulating packets: " + ex.ToString()); } }
public void Connect(VpnChannel channel) { State = VpnPluginState.Connecting; DebugLogger.Logger = s => { channel.LogDiagnosticMessage(s); }; DebugLogger.Log("Starting connection to VPN tunnel"); try { var transport = new DatagramSocket(); channel.AssociateTransport(transport, null); DebugLogger.Log("Initializing context"); #if !YT_MOCK var configPath = AdapterConfig.GetDefaultConfigFilePath(); if (string.IsNullOrEmpty(configPath)) { channel.TerminateConnection("Default server configuration not set. Please launch YtFlow app and select a server configuration as default."); return; } try { var config = AdapterConfig.GetConfigFromFilePath(configPath); if (config == null) { channel.TerminateConnection("Could not read server configuration."); return; } } catch (Exception ex) { channel.TerminateConnection("Error reading server configuration: " + ex.ToString()); return; } #endif DebugLogger.Log("Config read, binding endpoint"); if (!transport.BindEndpointAsync(new HostName("127.0.0.1"), string.Empty).AsTask().ContinueWith(t => { if (t.IsFaulted || t.IsCanceled) { DebugLogger.Log("Error binding endpoint: " + t.Exception.ToString()); return(false); } else { DebugLogger.Log("Binded"); return(true); } }).Result) { return; } DebugLogger.Log("Endpoint binded, init context"); var rport = context.Init(int.Parse(transport.Information.LocalPort)).ToString(); DebugLogger.Log("Context initialized"); /* var rport = context.Init(transport.Information.LocalPort, str => * { * LogLine(str, channel); * return null; * }); */ DebugLogger.Log("Connecting to local packet processor"); if (!transport.ConnectAsync(new HostName("127.0.0.1"), rport).AsTask().ContinueWith(t => { if (t.IsFaulted || t.IsCanceled) { channel.TerminateConnection("Error connecting to local packet processor: " + t.Exception.ToString()); DebugLogger.Log("Local packet processor connected"); return(false); } else { return(true); } }).Result) { return; } DebugLogger.Log("Connected to local packet processor"); VpnRouteAssignment routeScope = new VpnRouteAssignment() { ExcludeLocalSubnets = true }; var inclusionRoutes = routeScope.Ipv4InclusionRoutes; // DNS server inclusionRoutes.Add(new VpnRoute(new HostName("1.1.1.1"), 32)); // main CIDR inclusionRoutes.Add(new VpnRoute(new HostName("11.17.0.0"), 16)); // proxy inclusionRoutes.Add(new VpnRoute(new HostName("172.17.255.0"), 24)); var assignment = new VpnDomainNameAssignment(); assignment.DomainNameList.Add(new VpnDomainNameInfo( ".", VpnDomainNameType.Suffix, new[] { new HostName("1.1.1.1") }, Array.Empty <HostName>())); var now = DateTime.Now; DebugLogger.Log("Starting transport"); channel.StartWithMainTransport( new[] { new HostName("192.168.3.1") }, null, null, routeScope, assignment, 1500u, 1512u, false, transport ); var delta = DateTime.Now - now; _ = context.u.SendAsync(new byte[] { 0 }, 1, context.pluginEndpoint); DebugLogger.Log($"Transport started in {delta.TotalMilliseconds} ms."); State = VpnPluginState.Connected; } catch (Exception ex) { var msg = "Error connecting to VPN tunnel: " + ex.ToString(); channel.TerminateConnection(msg); DebugLogger.Log(msg); State = VpnPluginState.Disconnected; } }