From f17397a0840a43e456b46fdf641d1a52905428e5 Mon Sep 17 00:00:00 2001 From: Shreyas Zare Date: Sat, 14 Dec 2019 16:41:49 +0530 Subject: [PATCH 1/6] DhcpServer: fixed bug due to invalid host name causing scope to fail to activate. Updated SOA paramerters for zone created by dhcp. --- DnsServerCore/Dhcp/DhcpServer.cs | 18 ++++++++++-------- DnsServerCore/Dhcp/Lease.cs | 10 +++++----- DnsServerCore/Dhcp/Scope.cs | 12 ++++++------ 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/DnsServerCore/Dhcp/DhcpServer.cs b/DnsServerCore/Dhcp/DhcpServer.cs index 62d417d9..59a1317a 100644 --- a/DnsServerCore/Dhcp/DhcpServer.cs +++ b/DnsServerCore/Dhcp/DhcpServer.cs @@ -422,7 +422,7 @@ namespace DnsServerCore.Dhcp } } - if (string.IsNullOrEmpty(scope.DomainName)) + if (string.IsNullOrWhiteSpace(scope.DomainName)) { //update lease hostname leaseOffer.SetHostName(request.HostName?.HostName); @@ -441,13 +441,13 @@ namespace DnsServerCore.Dhcp } } - if (clientDomainName == null) + if (string.IsNullOrWhiteSpace(clientDomainName)) { if (request.HostName != null) clientDomainName = request.HostName.HostName.Replace(' ', '-') + "." + scope.DomainName; } - if (clientDomainName != null) + if (!string.IsNullOrWhiteSpace(clientDomainName)) { leaseOffer.SetHostName(clientDomainName.ToLower()); UpdateDnsAuthZone(true, scope, leaseOffer); @@ -611,21 +611,23 @@ namespace DnsServerCore.Dhcp if (_authoritativeZoneRoot == null) return; - if (string.IsNullOrEmpty(scope.DomainName)) + if (string.IsNullOrWhiteSpace(scope.DomainName)) return; - if (string.IsNullOrEmpty(lease.HostName)) + if (string.IsNullOrWhiteSpace(lease.HostName)) + return; + + if (!DnsClient.IsDomainNameValid(lease.HostName)) return; if (add) { //update forward zone - if (!string.IsNullOrEmpty(scope.DomainName)) { if (!_authoritativeZoneRoot.ZoneExists(scope.DomainName)) { //create forward zone - _authoritativeZoneRoot.SetRecords(scope.DomainName, DnsResourceRecordType.SOA, 14400, new DnsResourceRecordData[] { new DnsSOARecord(_authoritativeZoneRoot.ServerDomain, "hostmaster." + scope.DomainName, uint.Parse(DateTime.UtcNow.ToString("yyyyMMddHH")), 28800, 7200, 604800, 600) }); + _authoritativeZoneRoot.SetRecords(scope.DomainName, DnsResourceRecordType.SOA, 14400, new DnsResourceRecordData[] { new DnsSOARecord(_authoritativeZoneRoot.ServerDomain, "hostmaster." + scope.DomainName, 1, 14400, 3600, 604800, 900) }); _authoritativeZoneRoot.SetRecords(scope.DomainName, DnsResourceRecordType.NS, 14400, new DnsResourceRecordData[] { new DnsNSRecord(_authoritativeZoneRoot.ServerDomain) }); _authoritativeZoneRoot.MakeZoneInternal(scope.DomainName); @@ -639,7 +641,7 @@ namespace DnsServerCore.Dhcp if (!_authoritativeZoneRoot.ZoneExists(scope.ReverseZone)) { //create reverse zone - _authoritativeZoneRoot.SetRecords(scope.ReverseZone, DnsResourceRecordType.SOA, 14400, new DnsResourceRecordData[] { new DnsSOARecord(_authoritativeZoneRoot.ServerDomain, "hostmaster." + scope.ReverseZone, uint.Parse(DateTime.UtcNow.ToString("yyyyMMddHH")), 28800, 7200, 604800, 600) }); + _authoritativeZoneRoot.SetRecords(scope.ReverseZone, DnsResourceRecordType.SOA, 14400, new DnsResourceRecordData[] { new DnsSOARecord(_authoritativeZoneRoot.ServerDomain, "hostmaster." + scope.ReverseZone, 1, 14400, 3600, 604800, 900) }); _authoritativeZoneRoot.SetRecords(scope.ReverseZone, DnsResourceRecordType.NS, 14400, new DnsResourceRecordData[] { new DnsNSRecord(_authoritativeZoneRoot.ServerDomain) }); _authoritativeZoneRoot.MakeZoneInternal(scope.ReverseZone); diff --git a/DnsServerCore/Dhcp/Lease.cs b/DnsServerCore/Dhcp/Lease.cs index f4c5f338..f248ba6f 100644 --- a/DnsServerCore/Dhcp/Lease.cs +++ b/DnsServerCore/Dhcp/Lease.cs @@ -84,7 +84,7 @@ namespace DnsServerCore.Dhcp _clientIdentifier.ParseOptionValue(); _hostName = bR.ReadShortString(); - if (_hostName == "") + if (string.IsNullOrWhiteSpace(_hostName)) _hostName = null; _hardwareAddress = bR.ReadBuffer(); @@ -93,7 +93,7 @@ namespace DnsServerCore.Dhcp if (version >= 2) { _comments = bR.ReadShortString(); - if (_comments == "") + if (string.IsNullOrWhiteSpace(_comments)) _comments = null; } @@ -142,7 +142,7 @@ namespace DnsServerCore.Dhcp bW.Write((byte)_type); _clientIdentifier.WriteTo(bW.BaseStream); - if (string.IsNullOrEmpty(_hostName)) + if (string.IsNullOrWhiteSpace(_hostName)) bW.Write((byte)0); else bW.WriteShortString(_hostName); @@ -150,7 +150,7 @@ namespace DnsServerCore.Dhcp bW.WriteBuffer(_hardwareAddress); _address.WriteTo(bW); - if (string.IsNullOrEmpty(_comments)) + if (string.IsNullOrWhiteSpace(_comments)) bW.Write((byte)0); else bW.WriteShortString(_comments); @@ -163,7 +163,7 @@ namespace DnsServerCore.Dhcp { string hardwareAddress = BitConverter.ToString(_hardwareAddress); - if (string.IsNullOrEmpty(_hostName)) + if (string.IsNullOrWhiteSpace(_hostName)) return "[" + hardwareAddress + "]"; return _hostName + " [" + hardwareAddress + "]"; diff --git a/DnsServerCore/Dhcp/Scope.cs b/DnsServerCore/Dhcp/Scope.cs index 52a9835b..b4e41d96 100644 --- a/DnsServerCore/Dhcp/Scope.cs +++ b/DnsServerCore/Dhcp/Scope.cs @@ -112,7 +112,7 @@ namespace DnsServerCore.Dhcp _offerDelayTime = bR.ReadUInt16(); _domainName = bR.ReadShortString(); - if (_domainName == "") + if (string.IsNullOrWhiteSpace(_domainName)) _domainName = null; _dnsTtl = bR.ReadUInt32(); @@ -313,7 +313,7 @@ namespace DnsServerCore.Dhcp string clientDomainName; - if (request.ClientFullyQualifiedDomainName.DomainName == "") + if (string.IsNullOrWhiteSpace(request.ClientFullyQualifiedDomainName.DomainName)) { //client domain empty and expects server for a fqdn domain name if (request.HostName == null) @@ -822,13 +822,13 @@ namespace DnsServerCore.Dhcp public void ChangeNetwork(IPAddress startingAddress, IPAddress endingAddress, IPAddress subnetMask) { if (startingAddress.AddressFamily != AddressFamily.InterNetwork) - throw new ArgumentException("Address family not supported.", "startingAddress"); + throw new ArgumentException("Address family not supported.", nameof(startingAddress)); if (endingAddress.AddressFamily != AddressFamily.InterNetwork) - throw new ArgumentException("Address family not supported.", "endingAddress"); + throw new ArgumentException("Address family not supported.", nameof(endingAddress)); if (subnetMask.AddressFamily != AddressFamily.InterNetwork) - throw new ArgumentException("Address family not supported.", "subnetMask"); + throw new ArgumentException("Address family not supported.", nameof(subnetMask)); uint startingAddressNumber = startingAddress.ConvertIpToNumber(); uint endingAddressNumber = endingAddress.ConvertIpToNumber(); @@ -876,7 +876,7 @@ namespace DnsServerCore.Dhcp bW.Write(_leaseTimeMinutes); bW.Write(_offerDelayTime); - if (string.IsNullOrEmpty(_domainName)) + if (string.IsNullOrWhiteSpace(_domainName)) bW.Write((byte)0); else bW.WriteShortString(_domainName); From 08d937951a8e0b1b3cac79c59b9b2d188c629907 Mon Sep 17 00:00:00 2001 From: Shreyas Zare Date: Sat, 14 Dec 2019 16:43:46 +0530 Subject: [PATCH 2/6] webapp: implemented show inner error feature. --- DnsServerCore/www/js/common.js | 10 ++++++++-- DnsServerCore/www/js/main.js | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/DnsServerCore/www/js/common.js b/DnsServerCore/www/js/common.js index 18436225..7fe638f9 100644 --- a/DnsServerCore/www/js/common.js +++ b/DnsServerCore/www/js/common.js @@ -25,7 +25,7 @@ function htmlDecode(value) { return $('
').html(value).text(); } -function HTTPRequest(url, data, success, error, invalidToken, objAlertPlaceholder, objLoaderPlaceholder, dataIsFormData, dataContentType, dontHideAlert) { +function HTTPRequest(url, data, success, error, invalidToken, objAlertPlaceholder, objLoaderPlaceholder, dataIsFormData, dataContentType, dontHideAlert, showInnerError) { var async = false; var finalUrl; @@ -61,6 +61,12 @@ function HTTPRequest(url, data, success, error, invalidToken, objAlertPlaceholde if ((dontHideAlert == null) || !dontHideAlert) hideAlert(objAlertPlaceholder); + if (showInnerError == null) + showInnerError = arguments[0].showInnerError; + + if (showInnerError == null) + showInnerError = false; + if (objLoaderPlaceholder == null) objLoaderPlaceholder = arguments[0].objLoaderPlaceholder; @@ -117,7 +123,7 @@ function HTTPRequest(url, data, success, error, invalidToken, objAlertPlaceholde break; case "error": - showAlert("danger", "Error!", responseJson.errorMessage, objAlertPlaceholder); + showAlert("danger", "Error!", responseJson.errorMessage + (showInnerError && (responseJson.innerErrorMessage != null) ? " " + responseJson.innerErrorMessage : ""), objAlertPlaceholder); if (error != null) error(); diff --git a/DnsServerCore/www/js/main.js b/DnsServerCore/www/js/main.js index cdbc4790..31d6b7a0 100644 --- a/DnsServerCore/www/js/main.js +++ b/DnsServerCore/www/js/main.js @@ -1568,7 +1568,8 @@ function resolveQuery(importRecords) { btnOther.prop("disabled", false); showPageLogin(); }, - objLoaderPlaceholder: divDnsClientLoader + objLoaderPlaceholder: divDnsClientLoader, + showInnerError: true }); //add server name to list if doesnt exists From 58a5f75b63a778d8952a9c16ffc5990da49f9155 Mon Sep 17 00:00:00 2001 From: Shreyas Zare Date: Sat, 14 Dec 2019 16:48:05 +0530 Subject: [PATCH 3/6] WebService: implemented inner error message feature. SetDnsSettings() change to read forwarder protocol first to allow automatic config of TLS port 853. Updated zone default SOA parameters. Fixed issues in ResolveQuery() to allow querying PTR record directly. --- DnsServerCore/WebService.cs | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/DnsServerCore/WebService.cs b/DnsServerCore/WebService.cs index 13282f7c..1b0feb92 100644 --- a/DnsServerCore/WebService.cs +++ b/DnsServerCore/WebService.cs @@ -454,6 +454,12 @@ namespace DnsServerCore jsonWriter.WritePropertyName("stackTrace"); jsonWriter.WriteValue(ex.StackTrace); + if (ex.InnerException != null) + { + jsonWriter.WritePropertyName("innerErrorMessage"); + jsonWriter.WriteValue(ex.InnerException.Message); + } + jsonWriter.WriteEndObject(); jsonWriter.Flush(); } @@ -1312,6 +1318,10 @@ namespace DnsServerCore } } + string strForwarderProtocol = request.QueryString["forwarderProtocol"]; + if (!string.IsNullOrEmpty(strForwarderProtocol)) + _dnsServer.ForwarderProtocol = (DnsTransportProtocol)Enum.Parse(typeof(DnsTransportProtocol), strForwarderProtocol, true); + string strForwarders = request.QueryString["forwarders"]; if (!string.IsNullOrEmpty(strForwarders)) { @@ -1325,16 +1335,17 @@ namespace DnsServerCore NameServerAddress[] forwarders = new NameServerAddress[strForwardersList.Length]; for (int i = 0; i < strForwardersList.Length; i++) + { + if ((_dnsServer.ForwarderProtocol == DnsTransportProtocol.Tls) && IPAddress.TryParse(strForwardersList[i], out _)) + strForwardersList[i] += ":853"; + forwarders[i] = new NameServerAddress(strForwardersList[i]); + } _dnsServer.Forwarders = forwarders; } } - string strForwarderProtocol = request.QueryString["forwarderProtocol"]; - if (!string.IsNullOrEmpty(strForwarderProtocol)) - _dnsServer.ForwarderProtocol = (DnsTransportProtocol)Enum.Parse(typeof(DnsTransportProtocol), strForwarderProtocol, true); - string strBlockListUrls = request.QueryString["blockListUrls"]; if (!string.IsNullOrEmpty(strBlockListUrls)) { @@ -1986,7 +1997,7 @@ namespace DnsServerCore private void AllowZone(string domain) { - _dnsServer.AllowedZoneRoot.SetRecords(domain, DnsResourceRecordType.SOA, 60, new DnsResourceRecordData[] { new DnsSOARecord(_dnsServer.ServerDomain, "hostmaster." + _dnsServer.ServerDomain, 1, 28800, 7200, 604800, 600) }); + _dnsServer.AllowedZoneRoot.SetRecords(domain, DnsResourceRecordType.SOA, 60, new DnsResourceRecordData[] { new DnsSOARecord(_dnsServer.ServerDomain, "hostmaster." + _dnsServer.ServerDomain, 1, 14400, 3600, 604800, 900) }); } private void ListBlockedZones(HttpListenerRequest request, JsonTextWriter jsonWriter) @@ -2165,7 +2176,7 @@ namespace DnsServerCore { blockedZoneRoot.SetRecords(new DnsResourceRecord[] { - new DnsResourceRecord(domain, DnsResourceRecordType.SOA, DnsClass.IN, 60, new DnsSOARecord(_dnsServer.ServerDomain, "hostmaster." + _dnsServer.ServerDomain, 1, 28800, 7200, 604800, 600)), + new DnsResourceRecord(domain, DnsResourceRecordType.SOA, DnsClass.IN, 60, new DnsSOARecord(_dnsServer.ServerDomain, "hostmaster." + _dnsServer.ServerDomain, 1, 14400, 3600, 604800, 900)), new DnsResourceRecord(domain, DnsResourceRecordType.A, DnsClass.IN, 60, new DnsARecord(IPAddress.Any)), new DnsResourceRecord(domain, DnsResourceRecordType.AAAA, DnsClass.IN, 60, new DnsAAAARecord(IPAddress.IPv6Any)) }); @@ -2229,7 +2240,7 @@ namespace DnsServerCore private void CreateZone(string domain) { - _dnsServer.AuthoritativeZoneRoot.SetRecords(domain, DnsResourceRecordType.SOA, 14400, new DnsResourceRecordData[] { new DnsSOARecord(_dnsServer.ServerDomain, "hostmaster." + _dnsServer.ServerDomain, uint.Parse(DateTime.UtcNow.ToString("yyyyMMddHH")), 28800, 7200, 604800, 600) }); + _dnsServer.AuthoritativeZoneRoot.SetRecords(domain, DnsResourceRecordType.SOA, 14400, new DnsResourceRecordData[] { new DnsSOARecord(_dnsServer.ServerDomain, "hostmaster." + _dnsServer.ServerDomain, 1, 14400, 3600, 604800, 900) }); _dnsServer.AuthoritativeZoneRoot.SetRecords(domain, DnsResourceRecordType.NS, 14400, new DnsResourceRecordData[] { new DnsNSRecord(_dnsServer.ServerDomain) }); } @@ -2904,6 +2915,8 @@ namespace DnsServerCore if (string.IsNullOrEmpty(domain)) throw new WebServiceException("Parameter 'domain' missing."); + domain = domain.Trim(); + if (domain.EndsWith(".")) domain = domain.Substring(0, domain.Length - 1); @@ -2934,8 +2947,8 @@ namespace DnsServerCore { DnsQuestionRecord question; - if (type == DnsResourceRecordType.PTR) - question = new DnsQuestionRecord(IPAddress.Parse(domain), DnsClass.IN); + if ((type == DnsResourceRecordType.PTR) && IPAddress.TryParse(domain, out IPAddress address)) + question = new DnsQuestionRecord(address, DnsClass.IN); else question = new DnsQuestionRecord(domain, type, DnsClass.IN); @@ -3012,7 +3025,7 @@ namespace DnsServerCore } if (!SOARecordExists) - _dnsServer.AuthoritativeZoneRoot.SetRecords(domain, DnsResourceRecordType.SOA, 14400, new DnsResourceRecordData[] { new DnsSOARecord(_dnsServer.ServerDomain, "hostmaster." + _dnsServer.ServerDomain, uint.Parse(DateTime.UtcNow.ToString("yyyyMMddHH")), 28800, 7200, 604800, 600) }); + _dnsServer.AuthoritativeZoneRoot.SetRecords(domain, DnsResourceRecordType.SOA, 14400, new DnsResourceRecordData[] { new DnsSOARecord(_dnsServer.ServerDomain, "hostmaster." + _dnsServer.ServerDomain, 1, 14400, 3600, 604800, 900) }); } _dnsServer.AuthoritativeZoneRoot.SetRecords(recordsToSet); From 3b149915c9f1530ca39706fb4f3dc84e3868059b Mon Sep 17 00:00:00 2001 From: Shreyas Zare Date: Sat, 14 Dec 2019 16:49:14 +0530 Subject: [PATCH 4/6] updated readme with new blog post url. --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 00eb2786..ef5efe2a 100644 --- a/README.md +++ b/README.md @@ -56,10 +56,11 @@ Make contribution to Technitium by becoming a Patron and help making new softwar [Become a Patron now!](https://www.patreon.com/technitium) # Blog Posts -- [Scott Hanselman: Exploring DNS with the .NET Core based Technitium DNS Server](https://www.hanselman.com/blog/ExploringDNSWithTheNETCoreBasedTechnitiumDNSServer.aspx) (April 2019) +- [phra's blog: Exfiltrate Like a Pro: Using DNS over HTTPS as a C2 Channel](https://iwantmore.pizza/posts/dnscat2-over-doh.html) (Aug 2019) +- [Scott Hanselman: Exploring DNS with the .NET Core based Technitium DNS Server](https://www.hanselman.com/blog/ExploringDNSWithTheNETCoreBasedTechnitiumDNSServer.aspx) (Apr 2019) - [Technitium Blog: Turn Raspberry Pi Into Network Wide DNS Server](https://blog.technitium.com/2019/01/turn-raspberry-pi-into-network-wide-dns.html) (Jan 2019) - [Technitium Blog: Blocking Internet Ads Using DNS Sinkhole](https://blog.technitium.com/2018/10/blocking-internet-ads-using-dns-sinkhole.html) (Oct 2018) -- [Technitium Blog: Configuring DNS Server For Privacy & Security](https://blog.technitium.com/2018/06/configuring-dns-server-for-privacy.html) (June 2018) -- [Technitium Blog: Technitium DNS Server v1.3 Released!](https://blog.technitium.com/2018/06/technitium-dns-server-v13-released.html) (June 2018) +- [Technitium Blog: Configuring DNS Server For Privacy & Security](https://blog.technitium.com/2018/06/configuring-dns-server-for-privacy.html) (Jun 2018) +- [Technitium Blog: Technitium DNS Server v1.3 Released!](https://blog.technitium.com/2018/06/technitium-dns-server-v13-released.html) (Jun 2018) - [Technitium Blog: Running Technitium DNS Server on Ubuntu Linux](https://blog.technitium.com/2017/11/running-dns-server-on-ubuntu-linux.html) (Nov 2017) - [Technitium Blog: Technitium DNS Server Released!](https://blog.technitium.com/2017/11/technitium-dns-server-released.html) (Nov 2017) From 5a38e2c4d59f213dcb24e668759dfe49a02dc615 Mon Sep 17 00:00:00 2001 From: Shreyas Zare Date: Sat, 14 Dec 2019 16:50:42 +0530 Subject: [PATCH 5/6] StatsManager: fixed minor bug to count stats correctly using case insensitive domain name. --- DnsServerCore/Dns/StatsManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DnsServerCore/Dns/StatsManager.cs b/DnsServerCore/Dns/StatsManager.cs index 790a8a72..5ba5289a 100644 --- a/DnsServerCore/Dns/StatsManager.cs +++ b/DnsServerCore/Dns/StatsManager.cs @@ -1085,7 +1085,7 @@ namespace DnsServerCore.Dns case StatsResponseType.NoError: if (!"blocked".Equals(responseTag)) //skip blocked domains { - _queryDomains.GetOrAdd(query.Name, new Counter()).Increment(); + _queryDomains.GetOrAdd(query.Name.ToLower(), new Counter()).Increment(); _queries.GetOrAdd(query, new Counter()).Increment(); } @@ -1120,7 +1120,7 @@ namespace DnsServerCore.Dns break; case "blocked": - _queryBlockedDomains.GetOrAdd(query.Name, new Counter()).Increment(); + _queryBlockedDomains.GetOrAdd(query.Name.ToLower(), new Counter()).Increment(); Interlocked.Increment(ref _totalBlocked); break; } From 0deba1f7052e516372173df4aa013eef90b82c39 Mon Sep 17 00:00:00 2001 From: Shreyas Zare Date: Sat, 14 Dec 2019 16:55:16 +0530 Subject: [PATCH 6/6] DnsServer: fixed bug in Start() due to incorrect exception handing causing the server to crash when socket object fails to instantiate. Updated SOA default parameters. --- DnsServerCore/Dns/DnsServer.cs | 67 +++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/DnsServerCore/Dns/DnsServer.cs b/DnsServerCore/Dns/DnsServer.cs index 70e57d80..825fb98c 100644 --- a/DnsServerCore/Dns/DnsServer.cs +++ b/DnsServerCore/Dns/DnsServer.cs @@ -875,7 +875,7 @@ namespace DnsServerCore.Dns case DnsResourceRecordType.AXFR: case DnsResourceRecordType.MAILB: case DnsResourceRecordType.MAILA: - return new DnsDatagram(new DnsHeader(request.Header.Identifier, true, DnsOpcode.StandardQuery, false, false, request.Header.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.Refused, request.Header.QDCOUNT, 0, 0, 0), request.Question, null, null, null); + return new DnsDatagram(new DnsHeader(request.Header.Identifier, true, DnsOpcode.StandardQuery, false, false, request.Header.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NotImplemented, request.Header.QDCOUNT, 0, 0, 0), request.Question, null, null, null); } try @@ -1570,23 +1570,25 @@ namespace DnsServerCore.Dns { IPEndPoint dnsEP = new IPEndPoint(_localIPs[i], 53); - Socket udpListener = new Socket(dnsEP.AddressFamily, SocketType.Dgram, ProtocolType.Udp); - - #region this code ignores ICMP port unreachable responses which creates SocketException in ReceiveFrom() - - if (Environment.OSVersion.Platform == PlatformID.Win32NT) - { - const uint IOC_IN = 0x80000000; - const uint IOC_VENDOR = 0x18000000; - const uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12; - - udpListener.IOControl((IOControlCode)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null); - } - - #endregion + Socket udpListener = null; try { + udpListener = new Socket(dnsEP.AddressFamily, SocketType.Dgram, ProtocolType.Udp); + + #region this code ignores ICMP port unreachable responses which creates SocketException in ReceiveFrom() + + if (Environment.OSVersion.Platform == PlatformID.Win32NT) + { + const uint IOC_IN = 0x80000000; + const uint IOC_VENDOR = 0x18000000; + const uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12; + + udpListener.IOControl((IOControlCode)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null); + } + + #endregion + udpListener.Bind(dnsEP); _udpListeners.Add(udpListener); @@ -1601,13 +1603,16 @@ namespace DnsServerCore.Dns if (log != null) log.Write(dnsEP, DnsTransportProtocol.Udp, "DNS Server failed to bind.\r\n" + ex.ToString()); - udpListener.Dispose(); + if (udpListener != null) + udpListener.Dispose(); } - Socket tcpListener = new Socket(dnsEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + Socket tcpListener = null; try { + tcpListener = new Socket(dnsEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + tcpListener.Bind(dnsEP); tcpListener.Listen(100); @@ -1623,16 +1628,19 @@ namespace DnsServerCore.Dns if (log != null) log.Write(dnsEP, DnsTransportProtocol.Tcp, "DNS Server failed to bind.\r\n" + ex.ToString()); - tcpListener.Dispose(); + if (tcpListener != null) + tcpListener.Dispose(); } if (_enableDnsOverHttp) { IPEndPoint httpEP = new IPEndPoint(_localIPs[i], 8053); - Socket httpListener = new Socket(httpEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + Socket httpListener = null; try { + httpListener = new Socket(httpEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + httpListener.Bind(httpEP); httpListener.Listen(100); @@ -1650,17 +1658,20 @@ namespace DnsServerCore.Dns if (log != null) log.Write(httpEP, DnsTransportProtocol.Https, "DNS Server failed to bind.\r\n" + ex.ToString()); - httpListener.Dispose(); + if (httpListener != null) + httpListener.Dispose(); } } if (_enableDnsOverTls && (_certificate != null)) { IPEndPoint tlsEP = new IPEndPoint(_localIPs[i], 853); - Socket tlsListener = new Socket(tlsEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + Socket tlsListener = null; try { + tlsListener = new Socket(tlsEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + tlsListener.Bind(tlsEP); tlsListener.Listen(100); @@ -1676,17 +1687,20 @@ namespace DnsServerCore.Dns if (log != null) log.Write(tlsEP, DnsTransportProtocol.Tls, "DNS Server failed to bind.\r\n" + ex.ToString()); - tlsListener.Dispose(); + if (tlsListener != null) + tlsListener.Dispose(); } } if (_enableDnsOverHttps && (_certificate != null)) { IPEndPoint httpsEP = new IPEndPoint(_localIPs[i], 443); - Socket httpsListener = new Socket(httpsEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + Socket httpsListener = null; try { + httpsListener = new Socket(httpsEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + httpsListener.Bind(httpsEP); httpsListener.Listen(100); @@ -1704,7 +1718,8 @@ namespace DnsServerCore.Dns if (log != null) log.Write(httpsEP, DnsTransportProtocol.Https, "DNS Server failed to bind.\r\n" + ex.ToString()); - httpsListener.Dispose(); + if (httpsListener != null) + httpsListener.Dispose(); } } } @@ -1713,11 +1728,11 @@ namespace DnsServerCore.Dns { string serverDomain = _authoritativeZoneRoot.ServerDomain; - _authoritativeZoneRoot.SetRecords("resolver-associated-doh.arpa", DnsResourceRecordType.SOA, 14400, new DnsResourceRecordData[] { new DnsSOARecord(serverDomain, "hostmaster." + serverDomain, uint.Parse(DateTime.UtcNow.ToString("yyyyMMddHH")), 28800, 7200, 604800, 600) }); + _authoritativeZoneRoot.SetRecords("resolver-associated-doh.arpa", DnsResourceRecordType.SOA, 14400, new DnsResourceRecordData[] { new DnsSOARecord(serverDomain, "hostmaster." + serverDomain, 1, 14400, 3600, 604800, 900) }); _authoritativeZoneRoot.SetRecords("resolver-associated-doh.arpa", DnsResourceRecordType.NS, 14400, new DnsResourceRecordData[] { new DnsNSRecord(serverDomain) }); _authoritativeZoneRoot.SetRecords("resolver-associated-doh.arpa", DnsResourceRecordType.TXT, 60, new DnsResourceRecordData[] { new DnsTXTRecord("https://" + serverDomain + "/dns-query{?dns}") }); - _authoritativeZoneRoot.SetRecords("resolver-addresses.arpa", DnsResourceRecordType.SOA, 14400, new DnsResourceRecordData[] { new DnsSOARecord(serverDomain, "hostmaster." + serverDomain, uint.Parse(DateTime.UtcNow.ToString("yyyyMMddHH")), 28800, 7200, 604800, 600) }); + _authoritativeZoneRoot.SetRecords("resolver-addresses.arpa", DnsResourceRecordType.SOA, 14400, new DnsResourceRecordData[] { new DnsSOARecord(serverDomain, "hostmaster." + serverDomain, 1, 14400, 3600, 604800, 900) }); _authoritativeZoneRoot.SetRecords("resolver-addresses.arpa", DnsResourceRecordType.NS, 14400, new DnsResourceRecordData[] { new DnsNSRecord(serverDomain) }); _authoritativeZoneRoot.SetRecords("resolver-addresses.arpa", DnsResourceRecordType.CNAME, 60, new DnsResourceRecordData[] { new DnsCNAMERecord(serverDomain) });