From 6e0e64c69d5052d5640b2244a50ec8bd2046857c Mon Sep 17 00:00:00 2001 From: xljiulang <366193849@qq.com> Date: Sat, 17 Jul 2021 19:39:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0dns=E7=AB=AF=E5=8F=A3?= =?UTF-8?q?=E5=8D=A0=E7=94=A8=E8=BF=9B=E7=A8=8B=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FastGithub.Dns/DnsServerHostedService.cs | 9 ++- FastGithub.Dns/FastGithub.Dns.csproj | 1 + FastGithub.Dns/UdpTable.cs | 94 ++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 FastGithub.Dns/UdpTable.cs diff --git a/FastGithub.Dns/DnsServerHostedService.cs b/FastGithub.Dns/DnsServerHostedService.cs index 812f3af..773a06b 100644 --- a/FastGithub.Dns/DnsServerHostedService.cs +++ b/FastGithub.Dns/DnsServerHostedService.cs @@ -3,6 +3,7 @@ using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; +using System.Diagnostics; using System.Net; using System.Net.Sockets; using System.Threading; @@ -46,7 +47,13 @@ namespace FastGithub.Dns /// public override Task StartAsync(CancellationToken cancellationToken) { - this.socket.Bind(new IPEndPoint(IPAddress.Any, 53)); + const int DNS_PORT = 53; + if (OperatingSystem.IsWindows() && UdpTable.TryGetOwnerProcessId(DNS_PORT, out var processId)) + { + Process.GetProcessById(processId).Kill(); + } + + this.socket.Bind(new IPEndPoint(IPAddress.Any, DNS_PORT)); if (OperatingSystem.IsWindows()) { const int SIO_UDP_CONNRESET = unchecked((int)0x9800000C); diff --git a/FastGithub.Dns/FastGithub.Dns.csproj b/FastGithub.Dns/FastGithub.Dns.csproj index efd748e..6e90918 100644 --- a/FastGithub.Dns/FastGithub.Dns.csproj +++ b/FastGithub.Dns/FastGithub.Dns.csproj @@ -2,6 +2,7 @@ net5.0 + true diff --git a/FastGithub.Dns/UdpTable.cs b/FastGithub.Dns/UdpTable.cs new file mode 100644 index 0000000..73ec7f1 --- /dev/null +++ b/FastGithub.Dns/UdpTable.cs @@ -0,0 +1,94 @@ +using System; +using System.Buffers.Binary; +using System.Net; +using System.Net.Sockets; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; + +namespace FastGithub.Dns +{ + /// + /// windows iphlpapi + /// + [SupportedOSPlatform("windows")] + unsafe static class UdpTable + { + private const int ERROR_INSUFFICIENT_BUFFER = 122; + + [DllImport("iphlpapi.dll", SetLastError = true)] + private static extern uint GetExtendedUdpTable(void* pUdpTable, ref int pdwSize, bool bOrder, AddressFamily ulAf, UDP_TABLE_CLASS tableClass, uint reserved = 0); + + /// + /// 获取udp端口的占用进程id + /// + /// + /// + /// + public static bool TryGetOwnerProcessId(int port, out int processId) + { + processId = 0; + var pdwSize = 0; + var result = GetExtendedUdpTable(null, ref pdwSize, false, AddressFamily.InterNetwork, UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID); + if (result != ERROR_INSUFFICIENT_BUFFER) + { + return false; + } + + var buffer = new byte[pdwSize]; + fixed (byte* pUdpTable = &buffer[0]) + { + result = GetExtendedUdpTable(pUdpTable, ref pdwSize, false, AddressFamily.InterNetwork, UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID); + if (result != 0) + { + return false; + } + + var table = Marshal.PtrToStructure(new IntPtr(pUdpTable)); + foreach (var row in table.rows) + { + if (row.LocalPort == port) + { + processId = row.ProcessId; + return true; + } + } + } + + return false; + } + + + private enum UDP_TABLE_CLASS + { + UDP_TABLE_BASIC, + UDP_TABLE_OWNER_PID, + UDP_TABLE_OWNER_MODULE + } + + [StructLayout(LayoutKind.Sequential)] + private struct MIB_UDPTABLE_OWNER_PID + { + public uint dwNumEntries; + + [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)] + public MIB_UDPROW_OWNER_PID[] rows; + } + + [StructLayout(LayoutKind.Sequential)] + private struct MIB_UDPROW_OWNER_PID + { + public uint localAddr; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public byte[] localPort; + + public int owningPid; + + public int ProcessId => owningPid; + + public IPAddress LocalAddress => new(localAddr); + + public ushort LocalPort => BinaryPrimitives.ReadUInt16BigEndian(this.localPort); + } + } +}