@fanboynz/network-scanner 1.0.40 → 1.0.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/nettools.js +176 -36
- package/nwss.js +2 -2
- package/package.json +1 -1
package/lib/nettools.js
CHANGED
|
@@ -725,9 +725,23 @@ function createNetToolsHandler(config) {
|
|
|
725
725
|
const hasDig = digTerms && Array.isArray(digTerms) && digTerms.length > 0;
|
|
726
726
|
const hasDigOr = digOrTerms && Array.isArray(digOrTerms) && digOrTerms.length > 0;
|
|
727
727
|
|
|
728
|
-
// Add deduplication
|
|
729
|
-
const
|
|
730
|
-
|
|
728
|
+
// Add separate deduplication caches for different lookup types
|
|
729
|
+
const processedWhoisDomains = new Set();
|
|
730
|
+
const processedDigDomains = new Set();
|
|
731
|
+
// Add whois resolution caching to avoid redundant whois lookups
|
|
732
|
+
const whoisResultCache = new Map();
|
|
733
|
+
const WHOIS_CACHE_TTL = 900000; // 15 minutes cache TTL (whois data changes less frequently)
|
|
734
|
+
const MAX_CACHE_SIZE = 400; // Larger cache for whois due to longer TTL
|
|
735
|
+
// Size Memory
|
|
736
|
+
// 100 ~900KB
|
|
737
|
+
// 200 1.8MB
|
|
738
|
+
// 300 2.6MB
|
|
739
|
+
// 400 3.4MB
|
|
740
|
+
// 500 4.2MB
|
|
741
|
+
// Add DNS resolution caching to avoid redundant dig lookups
|
|
742
|
+
const digResultCache = new Map();
|
|
743
|
+
const DIG_CACHE_TTL = 300000; // 5 minutes cache TTL
|
|
744
|
+
const DIG_MAX_CACHE_SIZE = 400; // Smaller cache for dig due to shorter TTL
|
|
731
745
|
|
|
732
746
|
return async function handleNetToolsCheck(domain, originalDomain) {
|
|
733
747
|
// Helper function to log to BOTH console and debug file
|
|
@@ -761,18 +775,25 @@ function createNetToolsHandler(config) {
|
|
|
761
775
|
}
|
|
762
776
|
}
|
|
763
777
|
|
|
764
|
-
//
|
|
765
|
-
|
|
778
|
+
// Determine which domain will be used for dig lookup
|
|
779
|
+
const digDomain = digSubdomain && originalDomain ? originalDomain : domain;
|
|
780
|
+
|
|
781
|
+
// Check if we need to perform any lookups
|
|
782
|
+
const needsWhoisLookup = (hasWhois || hasWhoisOr) && !processedWhoisDomains.has(domain);
|
|
783
|
+
const needsDigLookup = (hasDig || hasDigOr) && !processedDigDomains.has(digDomain);
|
|
784
|
+
|
|
785
|
+
// Skip if we don't need to perform any lookups
|
|
786
|
+
if (!needsWhoisLookup && !needsDigLookup) {
|
|
766
787
|
if (forceDebug) {
|
|
767
|
-
logToConsoleAndFile(`${messageColors.highlight('[nettools]')} Skipping duplicate
|
|
788
|
+
logToConsoleAndFile(`${messageColors.highlight('[nettools]')} Skipping duplicate lookups for ${domain} (whois: ${!needsWhoisLookup}, dig: ${!needsDigLookup})`);
|
|
768
789
|
}
|
|
769
790
|
return;
|
|
770
791
|
}
|
|
771
792
|
|
|
772
|
-
|
|
773
|
-
processedDomains.add(domain);
|
|
793
|
+
|
|
774
794
|
if (forceDebug) {
|
|
775
|
-
|
|
795
|
+
const totalProcessed = processedWhoisDomains.size + processedDigDomains.size;
|
|
796
|
+
logToConsoleAndFile(`${messageColors.highlight('[nettools]')} Processing domain: ${domain} (whois: ${needsWhoisLookup}, dig: ${needsDigLookup}) (${totalProcessed} total processed)`);
|
|
776
797
|
}
|
|
777
798
|
|
|
778
799
|
// Log site-specific whois delay if different from default
|
|
@@ -816,6 +837,7 @@ function createNetToolsHandler(config) {
|
|
|
816
837
|
logToConsoleAndFile(`${messageColors.highlight('[nettools]')} digSubdomain setting: ${digSubdomain}`);
|
|
817
838
|
logToConsoleAndFile(`${messageColors.highlight('[nettools]')} domain parameter: ${domain}`);
|
|
818
839
|
logToConsoleAndFile(`${messageColors.highlight('[nettools]')} originalDomain parameter: ${originalDomain}`);
|
|
840
|
+
logToConsoleAndFile(`${messageColors.highlight('[nettools]')} Final digDomain will be: ${digDomain}`);
|
|
819
841
|
if (whoisServer) {
|
|
820
842
|
const serverInfo = Array.isArray(whoisServer)
|
|
821
843
|
? `randomized from [${whoisServer.join(', ')}]`
|
|
@@ -824,13 +846,6 @@ function createNetToolsHandler(config) {
|
|
|
824
846
|
}
|
|
825
847
|
}
|
|
826
848
|
|
|
827
|
-
// Determine which domain to use for dig lookup
|
|
828
|
-
const digDomain = digSubdomain && originalDomain ? originalDomain : domain;
|
|
829
|
-
|
|
830
|
-
if (forceDebug) {
|
|
831
|
-
logToConsoleAndFile(`${messageColors.highlight('[nettools]')} Final digDomain will be: ${digDomain}`);
|
|
832
|
-
}
|
|
833
|
-
|
|
834
849
|
// Enhanced dry run logging
|
|
835
850
|
if (dryRunCallback && forceDebug) {
|
|
836
851
|
logToConsoleAndFile(`${messageColors.highlight('[nettools-dryrun]')} Processing ${domain} (original: ${originalDomain})`);
|
|
@@ -863,15 +878,47 @@ function createNetToolsHandler(config) {
|
|
|
863
878
|
}
|
|
864
879
|
|
|
865
880
|
// Perform whois lookup if either whois or whois-or is configured
|
|
866
|
-
if (
|
|
881
|
+
if (needsWhoisLookup) {
|
|
882
|
+
// Mark whois domain as being processed
|
|
883
|
+
processedWhoisDomains.add(domain);
|
|
884
|
+
|
|
885
|
+
// Check whois cache first - cache key includes server for accuracy
|
|
867
886
|
const selectedServer = selectWhoisServer(whoisServer, whoisServerMode);
|
|
887
|
+
const whoisCacheKey = `${domain}-${selectedServer || 'default'}`;
|
|
888
|
+
const now = Date.now();
|
|
889
|
+
let whoisResult = null;
|
|
868
890
|
|
|
869
|
-
if (
|
|
870
|
-
const
|
|
871
|
-
|
|
891
|
+
if (whoisResultCache.has(whoisCacheKey)) {
|
|
892
|
+
const cachedEntry = whoisResultCache.get(whoisCacheKey);
|
|
893
|
+
if (now - cachedEntry.timestamp < WHOIS_CACHE_TTL) {
|
|
894
|
+
if (forceDebug) {
|
|
895
|
+
const age = Math.round((now - cachedEntry.timestamp) / 1000);
|
|
896
|
+
const serverInfo = selectedServer ? ` (server: ${selectedServer})` : ' (default server)';
|
|
897
|
+
logToConsoleAndFile(`${messageColors.highlight('[whois-cache]')} Using cached result for ${domain}${serverInfo} [age: ${age}s]`);
|
|
898
|
+
}
|
|
899
|
+
whoisResult = {
|
|
900
|
+
...cachedEntry.result,
|
|
901
|
+
// Add cache metadata
|
|
902
|
+
fromCache: true,
|
|
903
|
+
cacheAge: now - cachedEntry.timestamp,
|
|
904
|
+
originalTimestamp: cachedEntry.timestamp
|
|
905
|
+
};
|
|
906
|
+
} else {
|
|
907
|
+
// Cache expired, remove it
|
|
908
|
+
whoisResultCache.delete(whoisCacheKey);
|
|
909
|
+
if (forceDebug) {
|
|
910
|
+
logToConsoleAndFile(`${messageColors.highlight('[whois-cache]')} Cache expired for ${domain}, performing fresh lookup`);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
872
913
|
}
|
|
873
|
-
|
|
874
|
-
|
|
914
|
+
|
|
915
|
+
// Perform fresh lookup if not cached
|
|
916
|
+
if (!whoisResult) {
|
|
917
|
+
if (forceDebug) {
|
|
918
|
+
const serverInfo = selectedServer ? ` using server ${selectedServer}` : ' using default server';
|
|
919
|
+
logToConsoleAndFile(`${messageColors.highlight('[whois]')} Performing fresh whois lookup for ${domain}${serverInfo}`);
|
|
920
|
+
}
|
|
921
|
+
|
|
875
922
|
// Configure retry options based on site config or use defaults
|
|
876
923
|
const retryOptions = {
|
|
877
924
|
maxRetries: siteConfig.whois_max_retries || 2,
|
|
@@ -881,7 +928,47 @@ function createNetToolsHandler(config) {
|
|
|
881
928
|
retryOnError: siteConfig.whois_retry_on_error === true // Default false
|
|
882
929
|
};
|
|
883
930
|
|
|
884
|
-
|
|
931
|
+
try {
|
|
932
|
+
whoisResult = await whoisLookupWithRetry(domain, 8000, whoisServer, forceDebug, retryOptions, whoisDelay, logToConsoleAndFile);
|
|
933
|
+
|
|
934
|
+
// Cache successful results (and certain types of failures)
|
|
935
|
+
if (whoisResult.success ||
|
|
936
|
+
(whoisResult.error && !whoisResult.isTimeout &&
|
|
937
|
+
!whoisResult.error.toLowerCase().includes('connection') &&
|
|
938
|
+
!whoisResult.error.toLowerCase().includes('network'))) {
|
|
939
|
+
|
|
940
|
+
whoisResultCache.set(whoisCacheKey, {
|
|
941
|
+
result: whoisResult,
|
|
942
|
+
timestamp: now
|
|
943
|
+
});
|
|
944
|
+
|
|
945
|
+
if (forceDebug) {
|
|
946
|
+
const cacheType = whoisResult.success ? 'successful' : 'failed';
|
|
947
|
+
const serverInfo = selectedServer ? ` (server: ${selectedServer})` : ' (default server)';
|
|
948
|
+
logToConsoleAndFile(`${messageColors.highlight('[whois-cache]')} Cached ${cacheType} result for ${domain}${serverInfo}`);
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
} catch (whoisError) {
|
|
952
|
+
// Handle exceptions from whois lookup
|
|
953
|
+
if (forceDebug) {
|
|
954
|
+
logToConsoleAndFile(`${messageColors.highlight('[whois]')} Exception during lookup for ${domain}: ${whoisError.message}`);
|
|
955
|
+
logToConsoleAndFile(`${messageColors.highlight('[whois]')} Exception type: ${whoisError.constructor.name}`);
|
|
956
|
+
if (whoisError.stack) {
|
|
957
|
+
logToConsoleAndFile(`${messageColors.highlight('[whois]')} Stack trace: ${whoisError.stack.split('\n').slice(0, 3).join(' -> ')}`);
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
// Log whois exceptions in dry run mode
|
|
962
|
+
if (dryRunCallback && forceDebug) {
|
|
963
|
+
logToConsoleAndFile(`${messageColors.highlight('[whois-dryrun]')} Exception: ${whoisError.message}`);
|
|
964
|
+
}
|
|
965
|
+
// Continue with dig if configured
|
|
966
|
+
whoisResult = null; // Ensure we don't process a null result
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
// Process whois result (whether from cache or fresh lookup)
|
|
971
|
+
if (whoisResult) {
|
|
885
972
|
|
|
886
973
|
if (whoisResult.success) {
|
|
887
974
|
// Check AND terms if configured
|
|
@@ -891,6 +978,7 @@ function createNetToolsHandler(config) {
|
|
|
891
978
|
dryRunCallback(domain, 'whois', 'AND logic', whoisTerms.join(', '), 'All terms found in whois data', {
|
|
892
979
|
server: whoisResult.whoisServer || 'default',
|
|
893
980
|
duration: whoisResult.duration,
|
|
981
|
+
fromCache: whoisResult.fromCache || false,
|
|
894
982
|
retryAttempts: whoisResult.retryInfo?.totalAttempts || 1
|
|
895
983
|
});
|
|
896
984
|
}
|
|
@@ -908,6 +996,7 @@ function createNetToolsHandler(config) {
|
|
|
908
996
|
dryRunCallback(domain, 'whois', 'OR logic', matchedTerm, 'Term found in whois data', {
|
|
909
997
|
server: whoisResult.whoisServer || 'default',
|
|
910
998
|
duration: whoisResult.duration,
|
|
999
|
+
fromCache: whoisResult.fromCache || false,
|
|
911
1000
|
retryAttempts: whoisResult.retryInfo?.totalAttempts || 1
|
|
912
1001
|
});
|
|
913
1002
|
}
|
|
@@ -920,7 +1009,9 @@ function createNetToolsHandler(config) {
|
|
|
920
1009
|
if (forceDebug) {
|
|
921
1010
|
const serverUsed = whoisResult.whoisServer ? ` (server: ${whoisResult.whoisServer})` : ' (default server)';
|
|
922
1011
|
const retryInfo = whoisResult.retryInfo ? ` [${whoisResult.retryInfo.totalAttempts}/${whoisResult.retryInfo.maxAttempts} attempts]` : '';
|
|
923
|
-
|
|
1012
|
+
const cacheInfo = whoisResult.fromCache ? ` [CACHED - ${Math.round(whoisResult.cacheAge / 1000)}s old]` : '';
|
|
1013
|
+
const duration = whoisResult.fromCache ? `cached in 0ms` : `in ${whoisResult.duration}ms`;
|
|
1014
|
+
logToConsoleAndFile(`${messageColors.highlight('[whois]')} Lookup completed for ${domain}${serverUsed} ${duration}${retryInfo}${cacheInfo}`);
|
|
924
1015
|
|
|
925
1016
|
if (whoisResult.retryInfo && whoisResult.retryInfo.retriedAfterFailure) {
|
|
926
1017
|
logToConsoleAndFile(`${messageColors.highlight('[whois]')} Success after retry - servers attempted: [${whoisResult.retryInfo.serversAttempted.map(s => s || 'default').join(', ')}]`);
|
|
@@ -996,25 +1087,29 @@ function createNetToolsHandler(config) {
|
|
|
996
1087
|
}
|
|
997
1088
|
// Don't return early - continue with dig if configured
|
|
998
1089
|
}
|
|
999
|
-
}
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
// Periodic whois cache cleanup to prevent memory leaks
|
|
1093
|
+
if (whoisResultCache.size > MAX_CACHE_SIZE) {
|
|
1094
|
+
const now = Date.now();
|
|
1095
|
+
let cleanedCount = 0;
|
|
1096
|
+
for (const [key, entry] of whoisResultCache.entries()) {
|
|
1097
|
+
if (now - entry.timestamp > WHOIS_CACHE_TTL) {
|
|
1098
|
+
whoisResultCache.delete(key);
|
|
1099
|
+
cleanedCount++;
|
|
1005
1100
|
}
|
|
1006
1101
|
}
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
if (dryRunCallback && forceDebug) {
|
|
1010
|
-
logToConsoleAndFile(`${messageColors.highlight('[whois-dryrun]')} Exception: ${whoisError.message}`);
|
|
1102
|
+
if (forceDebug && cleanedCount > 0) {
|
|
1103
|
+
logToConsoleAndFile(`${messageColors.highlight('[whois-cache]')} Cleaned ${cleanedCount} expired entries, cache size: ${whoisResultCache.size}`);
|
|
1011
1104
|
}
|
|
1012
|
-
// Continue with dig if configured
|
|
1013
1105
|
}
|
|
1014
1106
|
}
|
|
1015
1107
|
|
|
1016
1108
|
// Perform dig lookup if configured
|
|
1017
|
-
if (
|
|
1109
|
+
if (needsDigLookup) {
|
|
1110
|
+
// Mark dig domain as being processed
|
|
1111
|
+
processedDigDomains.add(digDomain);
|
|
1112
|
+
|
|
1018
1113
|
if (forceDebug) {
|
|
1019
1114
|
const digTypes = [];
|
|
1020
1115
|
if (hasDig) digTypes.push('dig-and');
|
|
@@ -1023,7 +1118,37 @@ function createNetToolsHandler(config) {
|
|
|
1023
1118
|
}
|
|
1024
1119
|
|
|
1025
1120
|
try {
|
|
1121
|
+
// Check dig cache first to avoid redundant dig operations
|
|
1122
|
+
const digCacheKey = `${digDomain}-${digRecordType}`;
|
|
1123
|
+
const now = Date.now();
|
|
1124
|
+
let digResult = null;
|
|
1125
|
+
|
|
1126
|
+
if (digResultCache.has(digCacheKey)) {
|
|
1127
|
+
const cachedEntry = digResultCache.get(digCacheKey);
|
|
1128
|
+
if (now - cachedEntry.timestamp < DIG_CACHE_TTL) {
|
|
1129
|
+
if (forceDebug) {
|
|
1130
|
+
logToConsoleAndFile(`${messageColors.highlight('[dig-cache]')} Using cached result for ${digDomain} (${digRecordType}) [age: ${Math.round((now - cachedEntry.timestamp) / 1000)}s]`);
|
|
1131
|
+
}
|
|
1132
|
+
digResult = cachedEntry.result;
|
|
1133
|
+
} else {
|
|
1134
|
+
// Cache expired, remove it
|
|
1135
|
+
digResultCache.delete(digCacheKey);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
if (!digResult) {
|
|
1026
1140
|
const digResult = await digLookup(digDomain, digRecordType, 5000); // 5 second timeout for dig
|
|
1141
|
+
|
|
1142
|
+
// Cache the result for future use
|
|
1143
|
+
digResultCache.set(digCacheKey, {
|
|
1144
|
+
result: digResult,
|
|
1145
|
+
timestamp: now
|
|
1146
|
+
});
|
|
1147
|
+
|
|
1148
|
+
if (forceDebug && digResult.success) {
|
|
1149
|
+
logToConsoleAndFile(`${messageColors.highlight('[dig-cache]')} Cached new result for ${digDomain} (${digRecordType})`);
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1027
1152
|
|
|
1028
1153
|
if (digResult.success) {
|
|
1029
1154
|
// Check AND terms if configured
|
|
@@ -1083,6 +1208,21 @@ function createNetToolsHandler(config) {
|
|
|
1083
1208
|
logToConsoleAndFile(`${messageColors.highlight('[dig-dryrun]')} Exception: ${digError.message}`);
|
|
1084
1209
|
}
|
|
1085
1210
|
}
|
|
1211
|
+
|
|
1212
|
+
// Periodic dig cache cleanup to prevent memory leaks
|
|
1213
|
+
if (digResultCache.size > DIG_MAX_CACHE_SIZE) {
|
|
1214
|
+
const now = Date.now();
|
|
1215
|
+
let cleanedCount = 0;
|
|
1216
|
+
for (const [key, entry] of digResultCache.entries()) {
|
|
1217
|
+
if (now - entry.timestamp > DIG_CACHE_TTL) {
|
|
1218
|
+
digResultCache.delete(key);
|
|
1219
|
+
cleanedCount++;
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
if (forceDebug && cleanedCount > 0) {
|
|
1223
|
+
logToConsoleAndFile(`${messageColors.highlight('[dig-cache]')} Cleaned ${cleanedCount} expired entries, cache size: ${digResultCache.size}`);
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1086
1226
|
}
|
|
1087
1227
|
|
|
1088
1228
|
// Domain matches if any of these conditions are true:
|
package/nwss.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// === Network scanner script (nwss.js) v1.0.
|
|
1
|
+
// === Network scanner script (nwss.js) v1.0.42 ===
|
|
2
2
|
|
|
3
3
|
// puppeteer for browser automation, fs for file system operations, psl for domain parsing.
|
|
4
4
|
// const pLimit = require('p-limit'); // Will be dynamically imported
|
|
@@ -33,7 +33,7 @@ const { navigateWithRedirectHandling, handleRedirectTimeout } = require('./lib/r
|
|
|
33
33
|
const { monitorBrowserHealth, isBrowserHealthy } = require('./lib/browserhealth');
|
|
34
34
|
|
|
35
35
|
// --- Script Configuration & Constants ---
|
|
36
|
-
const VERSION = '1.0.
|
|
36
|
+
const VERSION = '1.0.42'; // Script version
|
|
37
37
|
|
|
38
38
|
// get startTime
|
|
39
39
|
const startTime = Date.now();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fanboynz/network-scanner",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.42",
|
|
4
4
|
"description": "A Puppeteer-based network scanner for analyzing web traffic, generating adblock filter rules, and identifying third-party requests. Features include fingerprint spoofing, Cloudflare bypass, content analysis with curl/grep, and multiple output formats.",
|
|
5
5
|
"main": "nwss.js",
|
|
6
6
|
"scripts": {
|