@blockcast/mmt-container 2.0.0 → 2.0.1

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.
@@ -33,6 +33,12 @@ export interface MulticastTransportConfig {
33
33
  * are "MHM2" passes ahead of the packet_id read and the allow-list, and is
34
34
  * never counted toward a packet_id. On an unprotected join it is an
35
35
  * unparseable MMTP packet, as before.
36
+ *
37
+ * A protected join admits only datagrams whose reported sender is the
38
+ * flow's S (`sourceAddress`, or `senderAddress` on ASM), compared as IP
39
+ * addresses, before anything hashes them (multicast-02 7.2.7). A datagram
40
+ * with no reported sender is dropped, and a join that cannot report one
41
+ * (no S, or an ATSC 3.0 tuner) is declined `invalid-request`.
36
42
  */
37
43
  protected?: boolean;
38
44
  }
@@ -131,7 +137,8 @@ export interface MulticastTransportStats {
131
137
  * one (G, port, packet_id); the first sender whose packet is accepted owns
132
138
  * the sub-flow until the next join, and every other sender is dropped here,
133
139
  * before any gap, duplicate or FEC ledger sees it. A join or a silence
134
- * failback releases the lock.
140
+ * failback releases the lock. On a protected join it also counts every
141
+ * datagram whose sender is not the flow's S, or is not reported.
135
142
  */
136
143
  packetsDroppedForeignSender: number;
137
144
  }
@@ -1 +1 @@
1
- {"version":3,"file":"multicast-transport.d.ts","sourceRoot":"","sources":["../src/multicast-transport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"multicast-transport.d.ts","sourceRoot":"","sources":["../src/multicast-transport.ts"],"names":[],"mappings":"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"}
@@ -1263,6 +1263,9 @@ var AMTGatewayManager = class {
1263
1263
  */
1264
1264
  async subscribe(config) {
1265
1265
  const { key } = config;
1266
+ if (config.protected) {
1267
+ throw new Error("AMTGatewayManager refuses a protected join: it reports no per-datagram sender (multicast-02 7.2.7)");
1268
+ }
1266
1269
  const keyStr = this.getKeyString(key);
1267
1270
  if (this.subscriptions.has(keyStr)) {
1268
1271
  console.log(`[AMT] Reusing existing subscription to ${keyStr}`);
@@ -1437,6 +1440,73 @@ var FEC_BLOCK_PROFILES2 = Object.freeze([
1437
1440
  "iso-ssbg1-v1"
1438
1441
  ]);
1439
1442
 
1443
+ // ../mmt-base/dist/ip-address.js
1444
+ var DEC_OCTET = /^(?:0|[1-9]\d{0,2})$/;
1445
+ var H16 = /^[0-9A-Fa-f]{1,4}$/;
1446
+ function parseIpv4(text2) {
1447
+ const fields = text2.split(".");
1448
+ if (fields.length !== 4)
1449
+ return void 0;
1450
+ const octets = [];
1451
+ for (const field of fields) {
1452
+ if (!DEC_OCTET.test(field))
1453
+ return void 0;
1454
+ const value = Number(field);
1455
+ if (value > 255)
1456
+ return void 0;
1457
+ octets.push(value);
1458
+ }
1459
+ return octets;
1460
+ }
1461
+ function parseIpv6(text2) {
1462
+ const halves = text2.split("::");
1463
+ if (halves.length > 2)
1464
+ return void 0;
1465
+ const groupsOf = (part) => part === "" ? [] : part.split(":");
1466
+ const left = groupsOf(halves[0]);
1467
+ const right = halves.length === 2 ? groupsOf(halves[1]) : [];
1468
+ const words = [];
1469
+ const all = [...left, ...right];
1470
+ const last = halves.length === 2 && right.length === 0 ? -1 : all.length - 1;
1471
+ for (let index = 0; index < all.length; index++) {
1472
+ const group = all[index];
1473
+ if (index === last && group.includes(".")) {
1474
+ const v4 = parseIpv4(group);
1475
+ if (!v4)
1476
+ return void 0;
1477
+ words.push([v4[0] << 8 | v4[1], v4[2] << 8 | v4[3]]);
1478
+ } else if (H16.test(group)) {
1479
+ words.push([Number.parseInt(group, 16)]);
1480
+ } else {
1481
+ return void 0;
1482
+ }
1483
+ }
1484
+ const leftWords = words.slice(0, left.length).flat();
1485
+ const rightWords = words.slice(left.length).flat();
1486
+ const missing = 8 - leftWords.length - rightWords.length;
1487
+ if (halves.length === 2 ? missing < 1 : missing !== 0)
1488
+ return void 0;
1489
+ const out = new Uint8Array(16);
1490
+ [...leftWords, ...new Array(missing).fill(0), ...rightWords].forEach((word, index) => {
1491
+ out[index * 2] = word >> 8;
1492
+ out[index * 2 + 1] = word & 255;
1493
+ });
1494
+ return out;
1495
+ }
1496
+ function parseIpAddressLiteral2(text2) {
1497
+ if (typeof text2 !== "string")
1498
+ return void 0;
1499
+ if (text2.includes(":"))
1500
+ return parseIpv6(text2);
1501
+ const v4 = parseIpv4(text2);
1502
+ return v4 ? Uint8Array.from(v4) : void 0;
1503
+ }
1504
+ function sameIpAddress(a, b) {
1505
+ const x = parseIpAddressLiteral2(a);
1506
+ const y = parseIpAddressLiteral2(b);
1507
+ return x !== void 0 && y !== void 0 && x.length === y.length && x.every((octet, index) => octet === y[index]);
1508
+ }
1509
+
1440
1510
  // ../mmt-base/dist/fec-bindings.js
1441
1511
  var RUNTIME_FEC_RECEIVER2 = Object.freeze({
1442
1512
  schemes: Object.freeze(["raptorq", "reed-solomon"]),
@@ -1557,6 +1627,10 @@ var MulticastTransport = class {
1557
1627
  #acceptedBytesByPacketId = /* @__PURE__ */ new Map();
1558
1628
  #packetIds = null;
1559
1629
  #protected = false;
1630
+ // A protected join's S, and the last sender spelling that matched it, so a
1631
+ // matching sender parses once per spelling rather than per datagram.
1632
+ #protectedSource = void 0;
1633
+ #matchedSource = void 0;
1560
1634
  // The sender S this join's accepted packets came from, once known; see
1561
1635
  // packetsDroppedForeignSender. Cleared by every join and by a silence
1562
1636
  // failback, so a replacement publisher is not locked out.
@@ -1608,6 +1682,11 @@ var MulticastTransport = class {
1608
1682
  return this.#declined(generation, "unavailable");
1609
1683
  }
1610
1684
  let failure = "invalid-request";
1685
+ const protectedSource = config.protected === true ? config.sourceAddress ?? config.senderAddress : void 0;
1686
+ if (config.protected === true && (protectedSource === void 0 || config.atsc3)) {
1687
+ console.warn("[MulticastTransport] protected join refused: the path reports no per-datagram sender to check against S");
1688
+ return this.#declined(generation, "invalid-request");
1689
+ }
1611
1690
  try {
1612
1691
  const packetIds = config.packetIds?.length ? new Set(config.packetIds) : null;
1613
1692
  console.log(
@@ -1643,7 +1722,7 @@ var MulticastTransport = class {
1643
1722
  this.#subscription = subscription;
1644
1723
  const live = () => !this.#disposed && generation === this.#joinGeneration;
1645
1724
  const anySource = !config.sourceAddress && !config.senderAddress && !config.atsc3;
1646
- const packetListener = !anySource && subscriptionDeliversPacketBatches(subscription) ? {
1725
+ const packetListener = !anySource && protectedSource === void 0 && subscriptionDeliversPacketBatches(subscription) ? {
1647
1726
  type: "packets",
1648
1727
  listener: (event) => {
1649
1728
  if (!live()) return;
@@ -1659,6 +1738,8 @@ var MulticastTransport = class {
1659
1738
  this.#packetListener = packetListener;
1660
1739
  this.#packetIds = packetIds;
1661
1740
  this.#protected = config.protected === true;
1741
+ this.#protectedSource = protectedSource;
1742
+ this.#matchedSource = void 0;
1662
1743
  this.#providerFilter = {
1663
1744
  acknowledged: packetIds,
1664
1745
  sent: 0,
@@ -2118,13 +2199,23 @@ var MulticastTransport = class {
2118
2199
  this.#delivery = void 0;
2119
2200
  this.#packetIds = null;
2120
2201
  this.#protected = false;
2202
+ this.#protectedSource = void 0;
2203
+ this.#matchedSource = void 0;
2121
2204
  this.#providerFilter = null;
2122
2205
  this.#context = void 0;
2123
2206
  this.#withdrawnPacketIds.clear();
2124
2207
  }
2125
2208
  /** The ingress filter; an accepted packet is counted here, once. */
2126
2209
  #acceptPacket(packet, sourceAddress) {
2127
- const owner = this.#lockedTo?.() ?? this.#sender;
2210
+ const source = this.#protectedSource;
2211
+ if (source !== void 0 && (sourceAddress === void 0 || sourceAddress !== this.#matchedSource)) {
2212
+ if (sourceAddress === void 0 || !sameIpAddress(sourceAddress, source)) {
2213
+ this.#stats.packetsDroppedForeignSender++;
2214
+ return false;
2215
+ }
2216
+ this.#matchedSource = sourceAddress;
2217
+ }
2218
+ const owner = source === void 0 ? this.#lockedTo?.() ?? this.#sender : void 0;
2128
2219
  if (sourceAddress !== void 0 && owner !== void 0 && sourceAddress !== owner) {
2129
2220
  this.#stats.packetsDroppedForeignSender++;
2130
2221
  return false;