Пример #1
0
        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;
                }
            }
        }
Пример #2
0
        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());
            }
        }
Пример #3
0
        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;
        }
Пример #4
0
        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");
        }
Пример #5
0
        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());
                }
            }
        }
Пример #6
0
 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();
     }
 }
Пример #7
0
        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);
            }
        }
Пример #8
0
        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());
                }
            }
        }
Пример #9
0
 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;
     }
 }
Пример #10
0
        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());
            }
        }
Пример #11
0
        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;
            }
        }