diff --git a/Apps/AdvancedBlockingApp/App.cs b/Apps/AdvancedBlockingApp/App.cs index 2736f912..b880a470 100644 --- a/Apps/AdvancedBlockingApp/App.cs +++ b/Apps/AdvancedBlockingApp/App.cs @@ -1,6 +1,6 @@ /* Technitium DNS Server -Copyright (C) 2023 Shreyas Zare (shreyas@technitium.com) +Copyright (C) 2024 Shreyas Zare (shreyas@technitium.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -51,17 +51,17 @@ namespace AdvancedBlocking bool _enableBlocking; int _blockListUrlUpdateIntervalHours; - IReadOnlyDictionary _localEndPointGroupMap; - IReadOnlyDictionary _networkGroupMap; - IReadOnlyDictionary _groups; + Dictionary _localEndPointGroupMap; + Dictionary _networkGroupMap; + Dictionary _groups; - IReadOnlyDictionary _allAllowListZones = new Dictionary(0); - IReadOnlyDictionary _allBlockListZones = new Dictionary(0); + Dictionary _allAllowListZones = new Dictionary(0); + Dictionary _allBlockListZones = new Dictionary(0); - IReadOnlyDictionary _allRegexAllowListZones = new Dictionary(0); - IReadOnlyDictionary _allRegexBlockListZones = new Dictionary(0); + Dictionary _allRegexAllowListZones = new Dictionary(0); + Dictionary _allRegexBlockListZones = new Dictionary(0); - IReadOnlyDictionary _allAdBlockListZones = new Dictionary(0); + Dictionary _allAdBlockListZones = new Dictionary(0); Timer _blockListUrlUpdateTimer; DateTime _blockListUrlLastUpdatedOn; @@ -145,7 +145,7 @@ namespace AdvancedBlocking return null; } - private static bool IsZoneFound(IReadOnlyDictionary domains, string domain, out string foundZone) + private static bool IsZoneFound(Dictionary domains, string domain, out string foundZone) { do { @@ -163,7 +163,7 @@ namespace AdvancedBlocking return false; } - private static bool IsZoneFound(IReadOnlyDictionary listZones, string domain, out string foundZone, out Uri listUri) + private static bool IsZoneFound(Dictionary listZones, string domain, out string foundZone, out Uri listUri) { foreach (KeyValuePair listZone in listZones) { @@ -179,7 +179,7 @@ namespace AdvancedBlocking return false; } - private static bool IsZoneFound(IReadOnlyDictionary> listZones, string domain, out string foundZone, out UrlEntry listUri) + private static bool IsZoneFound(Dictionary> listZones, string domain, out string foundZone, out UrlEntry listUri) { foreach (KeyValuePair> listZone in listZones) { @@ -195,7 +195,7 @@ namespace AdvancedBlocking return false; } - private static bool IsZoneAllowed(IReadOnlyDictionary> listZones, string domain, out string foundZone, out UrlEntry listUri) + private static bool IsZoneAllowed(Dictionary> listZones, string domain, out string foundZone, out UrlEntry listUri) { foreach (KeyValuePair> listZone in listZones) { @@ -211,7 +211,7 @@ namespace AdvancedBlocking return false; } - private static bool IsZoneBlocked(IReadOnlyDictionary> listZones, string domain, out string foundZone, out UrlEntry listUri) + private static bool IsZoneBlocked(Dictionary> listZones, string domain, out string foundZone, out UrlEntry listUri) { foreach (KeyValuePair> listZone in listZones) { @@ -227,7 +227,7 @@ namespace AdvancedBlocking return false; } - private static bool IsMatchFound(IReadOnlyList regices, string domain, out string matchingPattern) + private static bool IsMatchFound(Regex[] regices, string domain, out string matchingPattern) { foreach (Regex regex in regices) { @@ -243,7 +243,7 @@ namespace AdvancedBlocking return false; } - private static bool IsMatchFound(IReadOnlyDictionary regexListZones, string domain, out string matchingPattern, out Uri listUri) + private static bool IsMatchFound(Dictionary regexListZones, string domain, out string matchingPattern, out Uri listUri) { foreach (KeyValuePair regexListZone in regexListZones) { @@ -259,7 +259,7 @@ namespace AdvancedBlocking return false; } - private static bool IsMatchFound(IReadOnlyDictionary> regexListZones, string domain, out string matchingPattern, out UrlEntry listUri) + private static bool IsMatchFound(Dictionary> regexListZones, string domain, out string matchingPattern, out UrlEntry listUri) { foreach (KeyValuePair> regexListZone in regexListZones) { @@ -667,8 +667,8 @@ namespace AdvancedBlocking readonly Uri _uri; readonly bool _blockAsNxDomain; - readonly IReadOnlyCollection _aRecords; - readonly IReadOnlyCollection _aaaaRecords; + readonly List _aRecords; + readonly List _aaaaRecords; #endregion @@ -752,10 +752,10 @@ namespace AdvancedBlocking public bool BlockAsNxDomain { get { return _blockAsNxDomain; } } - public IReadOnlyCollection ARecords + public List ARecords { get { return _aRecords; } } - public IReadOnlyCollection AAAARecords + public List AAAARecords { get { return _aaaaRecords; } } #endregion @@ -802,28 +802,28 @@ namespace AdvancedBlocking readonly bool _allowTxtBlockingReport; readonly bool _blockAsNxDomain; - readonly IReadOnlyCollection _aRecords; - readonly IReadOnlyCollection _aaaaRecords; + readonly List _aRecords; + readonly List _aaaaRecords; - readonly IReadOnlyDictionary _allowed; - readonly IReadOnlyDictionary _blocked; - readonly IReadOnlyList _allowListUrls; - readonly IReadOnlyList _blockListUrls; + readonly Dictionary _allowed; + readonly Dictionary _blocked; + readonly Uri[] _allowListUrls; + readonly UrlEntry[] _blockListUrls; - readonly IReadOnlyList _allowedRegex; - readonly IReadOnlyList _blockedRegex; - readonly IReadOnlyList _regexAllowListUrls; - readonly IReadOnlyList _regexBlockListUrls; + readonly Regex[] _allowedRegex; + readonly Regex[] _blockedRegex; + readonly Uri[] _regexAllowListUrls; + readonly UrlEntry[] _regexBlockListUrls; - readonly IReadOnlyList _adblockListUrls; + readonly UrlEntry[] _adblockListUrls; - IReadOnlyDictionary _allowListZones = new Dictionary(0); - IReadOnlyDictionary> _blockListZones = new Dictionary>(0); + Dictionary _allowListZones = new Dictionary(0); + Dictionary> _blockListZones = new Dictionary>(0); - IReadOnlyDictionary _regexAllowListZones = new Dictionary(0); - IReadOnlyDictionary> _regexBlockListZones = new Dictionary>(0); + Dictionary _regexAllowListZones = new Dictionary(0); + Dictionary> _regexBlockListZones = new Dictionary>(0); - IReadOnlyDictionary> _adBlockListZones = new Dictionary>(0); + Dictionary> _adBlockListZones = new Dictionary>(0); #endregion @@ -910,7 +910,7 @@ namespace AdvancedBlocking public void LoadListZones() { { - Dictionary allowListZones = new Dictionary(_allowListUrls.Count); + Dictionary allowListZones = new Dictionary(_allowListUrls.Length); foreach (Uri listUrl in _allowListUrls) { @@ -922,7 +922,7 @@ namespace AdvancedBlocking } { - Dictionary> blockListZones = new Dictionary>(_blockListUrls.Count); + Dictionary> blockListZones = new Dictionary>(_blockListUrls.Length); foreach (UrlEntry listUrl in _blockListUrls) { @@ -934,7 +934,7 @@ namespace AdvancedBlocking } { - Dictionary regexAllowListZones = new Dictionary(_regexAllowListUrls.Count); + Dictionary regexAllowListZones = new Dictionary(_regexAllowListUrls.Length); foreach (Uri listUrl in _regexAllowListUrls) { @@ -946,7 +946,7 @@ namespace AdvancedBlocking } { - Dictionary> regexBlockListZones = new Dictionary>(_regexBlockListUrls.Count); + Dictionary> regexBlockListZones = new Dictionary>(_regexBlockListUrls.Length); foreach (UrlEntry listUrl in _regexBlockListUrls) { @@ -958,7 +958,7 @@ namespace AdvancedBlocking } { - Dictionary> adBlockListZones = new Dictionary>(_adblockListUrls.Count); + Dictionary> adBlockListZones = new Dictionary>(_adblockListUrls.Length); foreach (UrlEntry listUrl in _adblockListUrls) { @@ -1054,25 +1054,25 @@ namespace AdvancedBlocking public bool BlockAsNxDomain { get { return _blockAsNxDomain; } } - public IReadOnlyCollection ARecords + public List ARecords { get { return _aRecords; } } - public IReadOnlyCollection AAAARecords + public List AAAARecords { get { return _aaaaRecords; } } - public IReadOnlyList AllowListUrls + public Uri[] AllowListUrls { get { return _allowListUrls; } } - public IReadOnlyList BlockListUrls + public UrlEntry[] BlockListUrls { get { return _blockListUrls; } } - public IReadOnlyList RegexBlockListUrls + public UrlEntry[] RegexBlockListUrls { get { return _regexBlockListUrls; } } - public IReadOnlyList RegexAllowListUrls + public Uri[] RegexAllowListUrls { get { return _regexAllowListUrls; } } - public IReadOnlyList AdblockListUrls + public UrlEntry[] AdblockListUrls { get { return _adblockListUrls; } } #endregion @@ -1106,10 +1106,7 @@ namespace AdvancedBlocking _isRegexList = isRegexList; _isAdblockList = isAdblockList; - using (HashAlgorithm hash = SHA256.Create()) - { - _listFilePath = Path.Combine(Path.Combine(_dnsServer.ApplicationFolder, "blocklists"), Convert.ToHexString(hash.ComputeHash(Encoding.UTF8.GetBytes(_listUrl.AbsoluteUri))).ToLower()); - } + _listFilePath = Path.Combine(Path.Combine(_dnsServer.ApplicationFolder, "blocklists"), Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(_listUrl.AbsoluteUri))).ToLower()); } #endregion @@ -1134,6 +1131,8 @@ namespace AdvancedBlocking } File.Copy(_listUrl.LocalPath, _listFilePath, true); + _lastModified = File.GetLastWriteTimeUtc(_listFilePath); + _dnsServer.WriteLog("Advanced Blocking app successfully downloaded " + (_isAdblockList ? "adblock" : (_isRegexList ? "regex " : "") + (_isAllowList ? "allow" : "block")) + " list (" + WebUtilities.GetFormattedSize(new FileInfo(_listFilePath).Length) + "): " + _listUrl.AbsoluteUri); return true; } @@ -1216,9 +1215,20 @@ namespace AdvancedBlocking { if (File.Exists(_listFilePath)) { - if (!_listZoneLoaded) + _lastModified = File.GetLastWriteTimeUtc(_listFilePath); + + if (_listUrl.IsFile && (File.GetLastWriteTimeUtc(_listUrl.LocalPath) > _lastModified)) { + File.Copy(_listUrl.LocalPath, _listFilePath, true); _lastModified = File.GetLastWriteTimeUtc(_listFilePath); + + _dnsServer.WriteLog("Advanced Blocking app successfully downloaded " + (_isAdblockList ? "adblock" : (_isRegexList ? "regex " : "") + (_isAllowList ? "allow" : "block")) + " list (" + WebUtilities.GetFormattedSize(new FileInfo(_listFilePath).Length) + "): " + _listUrl.AbsoluteUri); + + LoadListZone(); + _listZoneLoaded = true; + } + else if (!_listZoneLoaded) + { LoadListZone(); _listZoneLoaded = true; } @@ -1265,7 +1275,7 @@ namespace AdvancedBlocking readonly static char[] _popWordSeperator = new char[] { ' ', '\t' }; - IReadOnlyDictionary _listZone = new Dictionary(0); + Dictionary _listZone = new Dictionary(0); #endregion @@ -1421,7 +1431,7 @@ namespace AdvancedBlocking { #region variables - IReadOnlyList _regexListZone = new List(); + Regex[] _regexListZone = Array.Empty(); #endregion @@ -1499,7 +1509,7 @@ namespace AdvancedBlocking } } - _regexListZone = regexListZone; + _regexListZone = regexListZone.ToArray(); } #endregion @@ -1518,8 +1528,8 @@ namespace AdvancedBlocking { #region variables - IReadOnlyDictionary _allowedListZone = new Dictionary(0); - IReadOnlyDictionary _blockedListZone = new Dictionary(0); + Dictionary _allowedListZone = new Dictionary(0); + Dictionary _blockedListZone = new Dictionary(0); #endregion