@apocaliss92/nodelink-js 0.5.1-beta.10 → 0.5.1-beta.11
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/dist/{chunk-27IU7NXS.js → chunk-COUH6ZJT.js} +129 -15
- package/dist/chunk-COUH6ZJT.js.map +1 -0
- package/dist/cli/rtsp-server.cjs +126 -14
- package/dist/cli/rtsp-server.cjs.map +1 -1
- package/dist/cli/rtsp-server.js +1 -1
- package/dist/index.cjs +130 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -1
- package/dist/index.d.ts +17 -0
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-27IU7NXS.js.map +0 -1
|
@@ -656,6 +656,10 @@ function sleep(ms) {
|
|
|
656
656
|
return new Promise((r) => setTimeout(r, ms));
|
|
657
657
|
}
|
|
658
658
|
var P2P_RELAY_HOSTNAMES = [
|
|
659
|
+
// Master anycast routers — try first.
|
|
660
|
+
"p2pm-abr.reolink.com",
|
|
661
|
+
"p2pm-ali.reolink.com",
|
|
662
|
+
// Numbered regional relays.
|
|
659
663
|
"p2p.reolink.com",
|
|
660
664
|
"p2p1.reolink.com",
|
|
661
665
|
"p2p2.reolink.com",
|
|
@@ -667,8 +671,29 @@ var P2P_RELAY_HOSTNAMES = [
|
|
|
667
671
|
"p2p8.reolink.com",
|
|
668
672
|
"p2p9.reolink.com",
|
|
669
673
|
"p2p10.reolink.com",
|
|
670
|
-
"p2p11.reolink.com"
|
|
674
|
+
"p2p11.reolink.com",
|
|
675
|
+
// China-region fallbacks (intentionally last).
|
|
676
|
+
"p2p.reolink.com.cn",
|
|
677
|
+
"p2p1.reolink.com.cn",
|
|
678
|
+
"p2p2.reolink.com.cn",
|
|
679
|
+
"p2p3.reolink.com.cn",
|
|
680
|
+
"p2p4.reolink.com.cn",
|
|
681
|
+
"p2p5.reolink.com.cn",
|
|
682
|
+
"p2p6.reolink.com.cn",
|
|
683
|
+
"p2p7.reolink.com.cn",
|
|
684
|
+
"p2p8.reolink.com.cn",
|
|
685
|
+
"p2p9.reolink.com.cn"
|
|
671
686
|
];
|
|
687
|
+
function isUnroutableForP2P(ip) {
|
|
688
|
+
if (!ip) return true;
|
|
689
|
+
if (ip === "0.0.0.0") return true;
|
|
690
|
+
if (ip.startsWith("127.")) return true;
|
|
691
|
+
if (ip.startsWith("10.")) return true;
|
|
692
|
+
if (ip.startsWith("192.168.")) return true;
|
|
693
|
+
if (/^172\.(1[6-9]|2[0-9]|3[0-1])\./.test(ip)) return true;
|
|
694
|
+
if (/^100\.(6[4-9]|[7-9][0-9]|1[01][0-9]|12[0-7])\./.test(ip)) return true;
|
|
695
|
+
return false;
|
|
696
|
+
}
|
|
672
697
|
var P2P_LOOKUP_PORT = 9999;
|
|
673
698
|
var P2P_MAX_WAIT_MS = 15e3;
|
|
674
699
|
var P2P_RESEND_WAIT_MS = 500;
|
|
@@ -835,19 +860,30 @@ var BcUdpStream = class extends EventEmitter {
|
|
|
835
860
|
}
|
|
836
861
|
async p2pUidLookup(sock, uid) {
|
|
837
862
|
const resolved = [];
|
|
863
|
+
const sinkholed = [];
|
|
838
864
|
for (const host of P2P_RELAY_HOSTNAMES) {
|
|
839
865
|
try {
|
|
840
866
|
const answers = await dns.lookup(host, { family: 4, all: true });
|
|
841
867
|
for (const a of answers) {
|
|
842
|
-
if (
|
|
843
|
-
|
|
868
|
+
if (!a.address) continue;
|
|
869
|
+
if (isUnroutableForP2P(a.address)) {
|
|
870
|
+
sinkholed.push({ host, ip: a.address });
|
|
871
|
+
continue;
|
|
872
|
+
}
|
|
873
|
+
if (!resolved.includes(a.address)) resolved.push(a.address);
|
|
844
874
|
}
|
|
845
875
|
} catch {
|
|
846
876
|
}
|
|
847
877
|
}
|
|
848
878
|
if (resolved.length === 0) {
|
|
879
|
+
if (sinkholed.length > 0) {
|
|
880
|
+
const samples = sinkholed.slice(0, 3).map((s) => `${s.host} \u2192 ${s.ip}`).join(", ");
|
|
881
|
+
throw new Error(
|
|
882
|
+
`P2P UID lookup failed: DNS resolves Reolink P2P hostnames to non-routable IPs (${samples}). This is almost certainly an /etc/hosts rewrite or a DNS filter (Pi-hole, AdGuard, NextDNS) blocking *.reolink.com. Battery cameras cannot connect without P2P \u2014 whitelist *.reolink.com (at least p2p*.reolink.com on UDP/9999) or remove the override. Verify with \`getent hosts p2p.reolink.com\` inside your container \u2014 if it differs from \`nslookup p2p.reolink.com\`, the offender is /etc/hosts.`
|
|
883
|
+
);
|
|
884
|
+
}
|
|
849
885
|
throw new Error(
|
|
850
|
-
"P2P UID lookup failed: no p2p.reolink.com addresses resolved"
|
|
886
|
+
"P2P UID lookup failed: no p2p.reolink.com addresses resolved (DNS failure)"
|
|
851
887
|
);
|
|
852
888
|
}
|
|
853
889
|
const start = Date.now();
|
|
@@ -24262,19 +24298,95 @@ function isTcpFailureThatShouldFallbackToUdp(e) {
|
|
|
24262
24298
|
return message.includes("ECONNREFUSED") || message.includes("ETIMEDOUT") || message.includes("EHOSTUNREACH") || message.includes("ENETUNREACH") || message.includes("socket hang up") || message.includes("TCP connection timeout") || message.includes("Baichuan socket closed") || message.includes("timeout waiting for nonce") || message.includes("expected encryption info") || message.includes("ECONNRESET") || message.includes("EPIPE");
|
|
24263
24299
|
}
|
|
24264
24300
|
async function pingHost(host, timeoutMs = 3e3) {
|
|
24265
|
-
|
|
24301
|
+
if (!host || typeof host !== "string") return false;
|
|
24266
24302
|
const platform2 = process.platform;
|
|
24267
|
-
const
|
|
24268
|
-
|
|
24269
|
-
|
|
24270
|
-
|
|
24271
|
-
|
|
24272
|
-
|
|
24273
|
-
|
|
24303
|
+
const pingCandidates = platform2 === "win32" ? ["ping"] : platform2 === "darwin" ? ["/sbin/ping", "/usr/sbin/ping", "ping"] : ["/bin/ping", "/usr/bin/ping", "ping"];
|
|
24304
|
+
const pingArgs = (bin) => {
|
|
24305
|
+
void bin;
|
|
24306
|
+
if (platform2 === "win32") {
|
|
24307
|
+
return ["-n", "1", "-w", String(timeoutMs), host];
|
|
24308
|
+
}
|
|
24309
|
+
if (platform2 === "darwin") {
|
|
24310
|
+
return ["-c", "1", "-W", String(timeoutMs), host];
|
|
24311
|
+
}
|
|
24312
|
+
return ["-c", "1", "-W", String(Math.max(1, Math.floor(timeoutMs / 1e3))), host];
|
|
24313
|
+
};
|
|
24314
|
+
const { spawn: spawn3 } = await import("child_process");
|
|
24315
|
+
for (const bin of pingCandidates) {
|
|
24316
|
+
const ranOk = await new Promise((resolve) => {
|
|
24317
|
+
let settled = false;
|
|
24318
|
+
let child;
|
|
24319
|
+
try {
|
|
24320
|
+
child = spawn3(bin, pingArgs(bin), { stdio: "ignore" });
|
|
24321
|
+
} catch {
|
|
24322
|
+
resolve("spawn-failed");
|
|
24323
|
+
return;
|
|
24324
|
+
}
|
|
24325
|
+
const timer = setTimeout(() => {
|
|
24326
|
+
if (settled) return;
|
|
24327
|
+
settled = true;
|
|
24328
|
+
try {
|
|
24329
|
+
child?.kill("SIGKILL");
|
|
24330
|
+
} catch {
|
|
24331
|
+
}
|
|
24332
|
+
resolve(false);
|
|
24333
|
+
}, timeoutMs + 500);
|
|
24334
|
+
child.on("error", () => {
|
|
24335
|
+
if (settled) return;
|
|
24336
|
+
settled = true;
|
|
24337
|
+
clearTimeout(timer);
|
|
24338
|
+
resolve("spawn-failed");
|
|
24339
|
+
});
|
|
24340
|
+
child.on("exit", (code) => {
|
|
24341
|
+
if (settled) return;
|
|
24342
|
+
settled = true;
|
|
24343
|
+
clearTimeout(timer);
|
|
24344
|
+
resolve(code === 0);
|
|
24345
|
+
});
|
|
24346
|
+
});
|
|
24347
|
+
if (ranOk === true) return true;
|
|
24348
|
+
if (ranOk === "spawn-failed") continue;
|
|
24349
|
+
break;
|
|
24350
|
+
}
|
|
24351
|
+
for (const port of [9e3, 443, 80]) {
|
|
24352
|
+
if (await tcpReachabilityProbe(host, port, 800)) return true;
|
|
24353
|
+
}
|
|
24354
|
+
return false;
|
|
24355
|
+
}
|
|
24356
|
+
async function tcpReachabilityProbe(host, port, timeoutMs) {
|
|
24357
|
+
const net4 = await import("net");
|
|
24274
24358
|
return new Promise((resolve) => {
|
|
24275
|
-
|
|
24276
|
-
|
|
24359
|
+
let settled = false;
|
|
24360
|
+
const socket = new net4.Socket();
|
|
24361
|
+
const timer = setTimeout(() => {
|
|
24362
|
+
if (settled) return;
|
|
24363
|
+
settled = true;
|
|
24364
|
+
try {
|
|
24365
|
+
socket.destroy();
|
|
24366
|
+
} catch {
|
|
24367
|
+
}
|
|
24368
|
+
resolve(false);
|
|
24369
|
+
}, timeoutMs);
|
|
24370
|
+
const finish = (reachable) => {
|
|
24371
|
+
if (settled) return;
|
|
24372
|
+
settled = true;
|
|
24373
|
+
clearTimeout(timer);
|
|
24374
|
+
try {
|
|
24375
|
+
socket.destroy();
|
|
24376
|
+
} catch {
|
|
24377
|
+
}
|
|
24378
|
+
resolve(reachable);
|
|
24379
|
+
};
|
|
24380
|
+
socket.once("connect", () => finish(true));
|
|
24381
|
+
socket.once("error", (err) => {
|
|
24382
|
+
if (err?.code === "ECONNREFUSED") finish(true);
|
|
24383
|
+
else finish(false);
|
|
24277
24384
|
});
|
|
24385
|
+
try {
|
|
24386
|
+
socket.connect(port, host);
|
|
24387
|
+
} catch {
|
|
24388
|
+
finish(false);
|
|
24389
|
+
}
|
|
24278
24390
|
});
|
|
24279
24391
|
}
|
|
24280
24392
|
function createBaichuanApi(inputs, transport) {
|
|
@@ -24790,6 +24902,7 @@ export {
|
|
|
24790
24902
|
encodeHeader,
|
|
24791
24903
|
decodeHeader,
|
|
24792
24904
|
BaichuanFrameParser,
|
|
24905
|
+
isUnroutableForP2P,
|
|
24793
24906
|
BcUdpStream,
|
|
24794
24907
|
asLogger,
|
|
24795
24908
|
createNullLogger,
|
|
@@ -24854,6 +24967,7 @@ export {
|
|
|
24854
24967
|
normalizeUid,
|
|
24855
24968
|
maskUid,
|
|
24856
24969
|
isTcpFailureThatShouldFallbackToUdp,
|
|
24970
|
+
tcpReachabilityProbe,
|
|
24857
24971
|
autoDetectDeviceType
|
|
24858
24972
|
};
|
|
24859
|
-
//# sourceMappingURL=chunk-
|
|
24973
|
+
//# sourceMappingURL=chunk-COUH6ZJT.js.map
|