Browse Source

cleanup, opti matching table memory

HOME 2 years ago
parent
commit
80100d05e9
2 changed files with 66 additions and 72 deletions
  1. 65 71
      DnsForwarder/Program.cs
  2. 1 1
      DnsForwarder/Properties/launchSettings.json

+ 65 - 71
DnsForwarder/Program.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.IO;
 using System.Linq;
 using System.Net;
@@ -9,39 +10,44 @@ using System.Text;
 
 namespace DnsForwarder
 {
-    internal class Program : ProgramRev1
+    internal class Program
     {
-        private static Socket Listener;
-        private static BlockingCollection<string> ConsoleOutout;
+        private static string _defaultDns;
+        private static string _cnDns;
+        private static IReadOnlyDictionary<string, int> _chinaList;
+        private static string[] _chinaListDns;
+
+        private static Socket _listener;
+        private static BlockingCollection<string> _consoleOutout;
 
         private static void Main(string[] args)
         {
             if (args.Length != 3)
             {
-                Console.WriteLine("<default dns server ip> <china dns server ip> <path to dnsmasq-china-list file>");
+                Console.WriteLine("<default dns server ip> <.CN dns server ip> <path to dnsmasq-china-list file>");
                 Environment.Exit(-1);
                 return;
             }
 
             Console.WriteLine("Starting...");
-            Console.WriteLine($"Default Server:{DefaultServer = args[0]}");
-            Console.WriteLine($"China DNS Server:{ChinaServer = args[1]}");
+            Console.WriteLine($"Default Server:{_defaultDns = args[0]}");
+            Console.WriteLine($"China DNS Server:{_cnDns = args[1]}");
             Console.WriteLine($"dnsmasq-china-list file:{args[2]}");
 
             Console.WriteLine("Loading list file...");
-            ChinaList = LoadListFile(args[2]).ToDictionary(p => p[0], p => p[1]);
+            LoadListFile(args[2]);
             Console.WriteLine("OK. Listening...");
 
-            Listener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
-            Listener.Bind(new IPEndPoint(IPAddress.Any, 53));
+            _listener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
+            _listener.Bind(new IPEndPoint(IPAddress.Any, 53));
 
-            ConsoleOutout = new BlockingCollection<string>();
+            _consoleOutout = new BlockingCollection<string>();
 
             StartHandleRequest();
 
             while (true)
             {
-                Console.WriteLine(ConsoleOutout.Take());
+                Console.WriteLine(_consoleOutout.Take());
             }
         }
 
@@ -49,13 +55,13 @@ namespace DnsForwarder
         {
             var buf = new byte[1500];
             EndPoint from = new IPEndPoint(IPAddress.Any, 0);
-            Listener.BeginReceiveFrom(buf, 0, buf.Length, SocketFlags.None, ref from, Callback, buf);
+            _listener.BeginReceiveFrom(buf, 0, buf.Length, SocketFlags.None, ref from, Callback, buf);
         }
 
         private static void Callback(IAsyncResult ar)
         {
             EndPoint from = new IPEndPoint(IPAddress.Any, 0);
-            var count = Listener.EndReceiveFrom(ar, ref from);
+            var count = _listener.EndReceiveFrom(ar, ref from);
             var buf = (byte[])ar.AsyncState;
 
             StartHandleRequest();
@@ -64,53 +70,10 @@ namespace DnsForwarder
 
             var target = MatchServer(domain);
 
-            ConsoleOutout.Add($"{DateTime.Now:yyyyMMdd HH:mm:ss} {from} [{target}]\t{domain}");
+            _consoleOutout.Add($"{DateTime.Now:yyyyMMdd HH:mm:ss} {from} [{target}]\t{domain}");
 
-            Listener.SendTo(GetDnsResponse(buf, count, target), from);
-        }
-    }
-
-    internal class ProgramRev1
-    {
-        protected static string DefaultServer;
-        protected static string ChinaServer;
-        protected static Dictionary<string, string> ChinaList;
-
-        private static void MainRev1(string[] args)
-        {
-            if (args.Length != 3)
-            {
-                Console.WriteLine("<default dns server ip> <china dns server ip> <path to dnsmasq-china-list file>");
-                Environment.Exit(-1);
-                return;
-            }
-
-            Console.WriteLine("Starting...");
-            Console.WriteLine($"Default Server:{DefaultServer = args[0]}");
-            Console.WriteLine($"China DNS Server:{ChinaServer = args[1]}");
-            Console.WriteLine($"dnsmasq-china-list file:{args[2]}");
-
-            Console.WriteLine("Loading list file...");
-            ChinaList = LoadListFile(args[2]).ToDictionary(p => p[0], p => p[1]);
-
-            Console.WriteLine("OK. Listing...");
-
-            var listen = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
-            listen.Bind(new IPEndPoint(IPAddress.Any, 53));
-
-            while (true)
-            {
-                EndPoint inEp = new IPEndPoint(IPAddress.Any, 0);
-                var buf = new byte[1500];
-                var count = listen.ReceiveFrom(buf, 0, buf.Length, SocketFlags.None, ref inEp);
-                var domain = ExtractDomainName(buf, count);
-
-                var target = MatchServer(domain);
-
-                Console.WriteLine($"{DateTime.Now:yyyyMMdd HH:mm:ss} {inEp} [{target}]\t{domain}");
-
-                listen.SendTo(GetDnsResponse(buf, count, target), inEp);
-            }
+            var dnsResponse = GetDnsResponse(buf, count, target);
+            if (dnsResponse != null) _listener.SendTo(dnsResponse, from);
         }
 
         protected static string ExtractDomainName(byte[] buf, int count)
@@ -143,36 +106,67 @@ namespace DnsForwarder
             using var to = new UdpClient();
             to.Connect(host, 53);
             to.Send(buf, count);
-            IPEndPoint outEp = null;
-            return to.Receive(ref outEp); //TODO: Handle Upstream TimeOut
+
+            //Handle Upstream TimeOut
+
+            var asyncResult = to.BeginReceive(null, null);
+            asyncResult.AsyncWaitHandle.WaitOne(2000);
+            if (asyncResult.IsCompleted)
+            {
+                IPEndPoint remoteEP = null;
+                byte[] receivedData = to.EndReceive(asyncResult, ref remoteEP);
+                return receivedData;
+            }
+
+            return null;
         }
 
         protected static string MatchServer(string domain)
         {
             var lower = domain.ToLower();
-            if (lower.EndsWith(".cn")) return ChinaServer;
+            if (lower.EndsWith(".cn")) return _cnDns;
 
             var parts = lower.Split('.').Reverse().ToArray();
 
             for (int i = parts.Length - 1; i >= 0; i--)
             {
                 var d = string.Join(".", parts.Take(i + 1).Reverse());
-                if (ChinaList.TryGetValue(d, out var tar)) return tar;
+                if (_chinaList.TryGetValue(d, out var tar)) return _chinaListDns[tar];
             }
 
-            return DefaultServer;
+            return _defaultDns;
         }
 
-        protected static string[][] LoadListFile(string path)
+        protected static void LoadListFile(params string[] paths)
         {
-            var lines = File.ReadAllLines(path);
-            var items = lines.Select(p =>
+            var lines = paths.SelectMany(File.ReadAllLines);
+
+            var dic = new Dictionary<string, int>();
+            var tar = new List<string>();
+
+            foreach (var line in lines)
             {
-                if (p.StartsWith("#")) return null;
+                var p = line.Trim();
+                if (p.StartsWith("#")) continue;
+
                 var parts = p.Split('/');
-                return new[] { parts[1], parts[2] };
-            }).Where(p => p != null).ToArray();
-            return items;
+                if (parts.Length != 3 && parts[0] != "server=") continue;
+
+                var domain = parts[1];
+                var dns = parts[2];
+
+                var dnsIndex = tar.IndexOf(dns);
+                if (dnsIndex == -1)
+                {
+                    tar.Add(dns);
+                    dnsIndex = tar.Count - 1;
+                }
+
+                dic[domain] = dnsIndex;
+            }
+
+            _chinaListDns = tar.ToArray();
+            _chinaList = new ReadOnlyDictionary<string, int>(dic);
         }
     }
 }

+ 1 - 1
DnsForwarder/Properties/launchSettings.json

@@ -2,7 +2,7 @@
   "profiles": {
     "DnsForwarder": {
       "commandName": "Project",
-      "commandLineArgs": "192.168.233.233 114.114.114.114 z:/accelerated-domains.china.conf.txt"
+      "commandLineArgs": "MySecureDnsServerInHosts 114.114.114.114 z:/accelerated-domains.china.conf.txt"
     }
   }
 }