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);
+ }
+ }
+}