@sirena-lwm2m/coap 0.8.0

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.
Files changed (157) hide show
  1. package/LICENSE +17 -0
  2. package/README.md +78 -0
  3. package/dist/api/exchange-context.d.ts +34 -0
  4. package/dist/api/exchange-context.d.ts.map +1 -0
  5. package/dist/api/exchange-context.js +2 -0
  6. package/dist/api/exchange-context.js.map +1 -0
  7. package/dist/api/headers.d.ts +10 -0
  8. package/dist/api/headers.d.ts.map +1 -0
  9. package/dist/api/headers.js +69 -0
  10. package/dist/api/headers.js.map +1 -0
  11. package/dist/api/index.d.ts +5 -0
  12. package/dist/api/index.d.ts.map +1 -0
  13. package/dist/api/index.js +4 -0
  14. package/dist/api/index.js.map +1 -0
  15. package/dist/api/request.d.ts +11 -0
  16. package/dist/api/request.d.ts.map +1 -0
  17. package/dist/api/request.js +49 -0
  18. package/dist/api/request.js.map +1 -0
  19. package/dist/api/response.d.ts +11 -0
  20. package/dist/api/response.d.ts.map +1 -0
  21. package/dist/api/response.js +19 -0
  22. package/dist/api/response.js.map +1 -0
  23. package/dist/blockwise/block1-assembler.d.ts +26 -0
  24. package/dist/blockwise/block1-assembler.d.ts.map +1 -0
  25. package/dist/blockwise/block1-assembler.js +94 -0
  26. package/dist/blockwise/block1-assembler.js.map +1 -0
  27. package/dist/blockwise/block2-chunker.d.ts +23 -0
  28. package/dist/blockwise/block2-chunker.d.ts.map +1 -0
  29. package/dist/blockwise/block2-chunker.js +99 -0
  30. package/dist/blockwise/block2-chunker.js.map +1 -0
  31. package/dist/blockwise/index.d.ts +8 -0
  32. package/dist/blockwise/index.d.ts.map +1 -0
  33. package/dist/blockwise/index.js +5 -0
  34. package/dist/blockwise/index.js.map +1 -0
  35. package/dist/blockwise/middleware.d.ts +7 -0
  36. package/dist/blockwise/middleware.d.ts.map +1 -0
  37. package/dist/blockwise/middleware.js +120 -0
  38. package/dist/blockwise/middleware.js.map +1 -0
  39. package/dist/blockwise/option.d.ts +12 -0
  40. package/dist/blockwise/option.d.ts.map +1 -0
  41. package/dist/blockwise/option.js +55 -0
  42. package/dist/blockwise/option.js.map +1 -0
  43. package/dist/index.d.ts +10 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +6 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/message/index.d.ts +21 -0
  48. package/dist/message/index.d.ts.map +1 -0
  49. package/dist/message/index.js +79 -0
  50. package/dist/message/index.js.map +1 -0
  51. package/dist/observability.d.ts +44 -0
  52. package/dist/observability.d.ts.map +1 -0
  53. package/dist/observability.js +71 -0
  54. package/dist/observability.js.map +1 -0
  55. package/dist/observe-notification.d.ts +21 -0
  56. package/dist/observe-notification.d.ts.map +1 -0
  57. package/dist/observe-notification.js +87 -0
  58. package/dist/observe-notification.js.map +1 -0
  59. package/dist/observe.d.ts +10 -0
  60. package/dist/observe.d.ts.map +1 -0
  61. package/dist/observe.js +3 -0
  62. package/dist/observe.js.map +1 -0
  63. package/dist/option-parser/index.d.ts +30 -0
  64. package/dist/option-parser/index.d.ts.map +1 -0
  65. package/dist/option-parser/index.js +125 -0
  66. package/dist/option-parser/index.js.map +1 -0
  67. package/dist/router/app.d.ts +8 -0
  68. package/dist/router/app.d.ts.map +1 -0
  69. package/dist/router/app.js +25 -0
  70. package/dist/router/app.js.map +1 -0
  71. package/dist/router/content-format.d.ts +7 -0
  72. package/dist/router/content-format.d.ts.map +1 -0
  73. package/dist/router/content-format.js +23 -0
  74. package/dist/router/content-format.js.map +1 -0
  75. package/dist/router/index.d.ts +9 -0
  76. package/dist/router/index.d.ts.map +1 -0
  77. package/dist/router/index.js +5 -0
  78. package/dist/router/index.js.map +1 -0
  79. package/dist/router/radix.d.ts +16 -0
  80. package/dist/router/radix.d.ts.map +1 -0
  81. package/dist/router/radix.js +69 -0
  82. package/dist/router/radix.js.map +1 -0
  83. package/dist/router/router.d.ts +38 -0
  84. package/dist/router/router.d.ts.map +1 -0
  85. package/dist/router/router.js +111 -0
  86. package/dist/router/router.js.map +1 -0
  87. package/dist/router.d.ts +2 -0
  88. package/dist/router.d.ts.map +1 -0
  89. package/dist/router.js +2 -0
  90. package/dist/router.js.map +1 -0
  91. package/dist/security.d.ts +3 -0
  92. package/dist/security.d.ts.map +1 -0
  93. package/dist/security.js +2 -0
  94. package/dist/security.js.map +1 -0
  95. package/dist/store/index.d.ts +26 -0
  96. package/dist/store/index.d.ts.map +1 -0
  97. package/dist/store/index.js +68 -0
  98. package/dist/store/index.js.map +1 -0
  99. package/dist/store/sqlite-store.d.ts +10 -0
  100. package/dist/store/sqlite-store.d.ts.map +1 -0
  101. package/dist/store/sqlite-store.js +75 -0
  102. package/dist/store/sqlite-store.js.map +1 -0
  103. package/dist/store.d.ts +5 -0
  104. package/dist/store.d.ts.map +1 -0
  105. package/dist/store.js +3 -0
  106. package/dist/store.js.map +1 -0
  107. package/dist/transport/dtls.d.ts +38 -0
  108. package/dist/transport/dtls.d.ts.map +1 -0
  109. package/dist/transport/dtls.js +151 -0
  110. package/dist/transport/dtls.js.map +1 -0
  111. package/dist/transport/events.d.ts +34 -0
  112. package/dist/transport/events.d.ts.map +1 -0
  113. package/dist/transport/events.js +2 -0
  114. package/dist/transport/events.js.map +1 -0
  115. package/dist/transport/index.d.ts +10 -0
  116. package/dist/transport/index.d.ts.map +1 -0
  117. package/dist/transport/index.js +5 -0
  118. package/dist/transport/index.js.map +1 -0
  119. package/dist/transport/tcp-connection.d.ts +18 -0
  120. package/dist/transport/tcp-connection.d.ts.map +1 -0
  121. package/dist/transport/tcp-connection.js +72 -0
  122. package/dist/transport/tcp-connection.js.map +1 -0
  123. package/dist/transport/tcp-frame.d.ts +17 -0
  124. package/dist/transport/tcp-frame.d.ts.map +1 -0
  125. package/dist/transport/tcp-frame.js +112 -0
  126. package/dist/transport/tcp-frame.js.map +1 -0
  127. package/dist/transport/tcp-stream.d.ts +21 -0
  128. package/dist/transport/tcp-stream.d.ts.map +1 -0
  129. package/dist/transport/tcp-stream.js +52 -0
  130. package/dist/transport/tcp-stream.js.map +1 -0
  131. package/dist/transport/udp.d.ts +97 -0
  132. package/dist/transport/udp.d.ts.map +1 -0
  133. package/dist/transport/udp.js +994 -0
  134. package/dist/transport/udp.js.map +1 -0
  135. package/dist/transport.d.ts +3 -0
  136. package/dist/transport.d.ts.map +1 -0
  137. package/dist/transport.js +2 -0
  138. package/dist/transport.js.map +1 -0
  139. package/docs/api-reference.md +536 -0
  140. package/docs/blockwise.md +117 -0
  141. package/docs/observability.md +206 -0
  142. package/docs/observe.md +203 -0
  143. package/docs/releasing.md +106 -0
  144. package/docs/router.md +170 -0
  145. package/docs/store.md +212 -0
  146. package/docs/tcp-transport.md +89 -0
  147. package/docs/udp-transport.md +81 -0
  148. package/examples/slice-1.ts +12 -0
  149. package/examples/slice-2.ts +96 -0
  150. package/examples/slice-3-psk.ts +70 -0
  151. package/examples/slice-3-x509.ts +85 -0
  152. package/examples/slice-4.ts +45 -0
  153. package/examples/slice-5-firmware.ts +207 -0
  154. package/examples/slice-6-temperature.ts +163 -0
  155. package/examples/slice-7-file-store.ts +92 -0
  156. package/examples/slice-7-otel.ts +123 -0
  157. package/package.json +73 -0
@@ -0,0 +1,68 @@
1
+ export const EXCHANGE_LIFETIME = 247_000;
2
+ export const NON_LIFETIME = 250_000;
3
+ function serializeKey(key) {
4
+ if (key.discriminant === 'mid') {
5
+ return `mid\x00${key.remote}\x00${key.mid}`;
6
+ }
7
+ return `tok\x00${key.remote}\x00${key.token}`;
8
+ }
9
+ class InMemoryStore {
10
+ map = new Map();
11
+ keyRemote = new Map();
12
+ remoteOrder = new Map();
13
+ lruCap;
14
+ constructor(options = {}) {
15
+ this.lruCap = options.lruCap ?? 64;
16
+ }
17
+ set(key, entry) {
18
+ const serialized = serializeKey(key);
19
+ const isNew = !this.map.has(serialized);
20
+ this.map.set(serialized, entry);
21
+ if (isNew) {
22
+ this.keyRemote.set(serialized, key.remote);
23
+ const order = this.remoteOrder.get(key.remote);
24
+ if (order === undefined) {
25
+ this.remoteOrder.set(key.remote, [serialized]);
26
+ }
27
+ else {
28
+ order.push(serialized);
29
+ if (order.length > this.lruCap) {
30
+ const evicted = order.shift();
31
+ this.map.delete(evicted);
32
+ this.keyRemote.delete(evicted);
33
+ }
34
+ }
35
+ }
36
+ }
37
+ get(key) {
38
+ return this.map.get(serializeKey(key));
39
+ }
40
+ delete(key) {
41
+ const serialized = serializeKey(key);
42
+ this._deleteBySerial(serialized, key.remote);
43
+ }
44
+ prune() {
45
+ const now = Date.now();
46
+ for (const [k, entry] of this.map) {
47
+ if (entry.expiresAt < now) {
48
+ const remote = this.keyRemote.get(k);
49
+ this._deleteBySerial(k, remote);
50
+ }
51
+ }
52
+ }
53
+ _deleteBySerial(serialized, remote) {
54
+ if (this.map.delete(serialized)) {
55
+ this.keyRemote.delete(serialized);
56
+ const order = this.remoteOrder.get(remote);
57
+ if (order !== undefined) {
58
+ const idx = order.indexOf(serialized);
59
+ if (idx !== -1)
60
+ order.splice(idx, 1);
61
+ }
62
+ }
63
+ }
64
+ }
65
+ export function createInMemoryStore(options) {
66
+ return new InMemoryStore(options);
67
+ }
68
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { TransactionStore } from './index.js';
2
+ export interface SqliteStoreOptions {
3
+ path?: string;
4
+ sweepIntervalMs?: number;
5
+ }
6
+ export interface SqliteStore extends TransactionStore {
7
+ close(): void;
8
+ }
9
+ export declare function createSqliteStore(options?: SqliteStoreOptions): Promise<SqliteStore>;
10
+ //# sourceMappingURL=sqlite-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-store.d.ts","sourceRoot":"","sources":["../../src/store/sqlite-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAwB,MAAM,YAAY,CAAC;AAEzE,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AA6ED,MAAM,WAAW,WAAY,SAAQ,gBAAgB;IACnD,KAAK,IAAI,IAAI,CAAC;CACf;AAED,wBAAsB,iBAAiB,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,WAAW,CAAC,CAc9F"}
@@ -0,0 +1,75 @@
1
+ function serializeKey(key) {
2
+ if (key.discriminant === 'mid') {
3
+ return `mid\x00${key.remote}\x00${key.mid}`;
4
+ }
5
+ return `tok\x00${key.remote}\x00${key.token}`;
6
+ }
7
+ class SqliteStoreImpl {
8
+ db;
9
+ stmtSet;
10
+ stmtGet;
11
+ stmtDelete;
12
+ stmtPrune;
13
+ sweepTimer;
14
+ constructor(Database, options = {}) {
15
+ const dbPath = options.path ?? ':memory:';
16
+ this.db = new Database(dbPath);
17
+ // WAL mode for concurrent read/write performance
18
+ this.db.pragma('journal_mode = WAL');
19
+ this.db.exec(`
20
+ CREATE TABLE IF NOT EXISTS dedup (
21
+ key TEXT PRIMARY KEY,
22
+ expires INTEGER NOT NULL,
23
+ payload BLOB
24
+ )
25
+ `);
26
+ this.stmtSet = this.db.prepare('INSERT INTO dedup (key, expires, payload) VALUES (?, ?, ?) ON CONFLICT(key) DO UPDATE SET expires = excluded.expires, payload = excluded.payload');
27
+ this.stmtGet = this.db.prepare('SELECT expires, payload FROM dedup WHERE key = ?');
28
+ this.stmtDelete = this.db.prepare('DELETE FROM dedup WHERE key = ?');
29
+ this.stmtPrune = this.db.prepare('DELETE FROM dedup WHERE expires < ?');
30
+ const intervalMs = options.sweepIntervalMs ?? 5_000;
31
+ this.sweepTimer = setInterval(() => this.prune(), intervalMs);
32
+ if (typeof this.sweepTimer.unref === 'function') {
33
+ this.sweepTimer.unref();
34
+ }
35
+ }
36
+ set(key, entry) {
37
+ const k = serializeKey(key);
38
+ const payload = entry.responsePayload != null ? Buffer.from(entry.responsePayload) : null;
39
+ this.stmtSet.run(k, entry.expiresAt, payload);
40
+ }
41
+ get(key) {
42
+ const k = serializeKey(key);
43
+ const row = this.stmtGet.get(k);
44
+ if (!row)
45
+ return undefined;
46
+ const entry = { expiresAt: row.expires };
47
+ if (row.payload != null) {
48
+ entry.responsePayload = new Uint8Array(row.payload);
49
+ }
50
+ return entry;
51
+ }
52
+ delete(key) {
53
+ this.stmtDelete.run(serializeKey(key));
54
+ }
55
+ prune() {
56
+ this.stmtPrune.run(Date.now());
57
+ }
58
+ close() {
59
+ clearInterval(this.sweepTimer);
60
+ this.db.close();
61
+ }
62
+ }
63
+ export async function createSqliteStore(options = {}) {
64
+ const { path: dbPath } = options;
65
+ let Database;
66
+ try {
67
+ const mod = await import('better-sqlite3');
68
+ Database = mod.default;
69
+ }
70
+ catch {
71
+ throw new Error(`SqliteStore: better-sqlite3 is not installed${dbPath !== undefined ? ` (required for file-backed store at "${dbPath}")` : ''}. Install it: npm install better-sqlite3`);
72
+ }
73
+ return new SqliteStoreImpl(Database, options);
74
+ }
75
+ //# sourceMappingURL=sqlite-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-store.js","sourceRoot":"","sources":["../../src/store/sqlite-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export type { TransactionStore, StoreKey, StoreEntry } from './store/index.js';
2
+ export { createInMemoryStore, EXCHANGE_LIFETIME, NON_LIFETIME } from './store/index.js';
3
+ export { createSqliteStore } from './store/sqlite-store.js';
4
+ export type { SqliteStoreOptions, SqliteStore } from './store/sqlite-store.js';
5
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC"}
package/dist/store.js ADDED
@@ -0,0 +1,3 @@
1
+ export { createInMemoryStore, EXCHANGE_LIFETIME, NON_LIFETIME } from './store/index.js';
2
+ export { createSqliteStore } from './store/sqlite-store.js';
3
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,38 @@
1
+ import dgram from 'node:dgram';
2
+ import { EventEmitter } from 'node:events';
3
+ import type { X509Certificate } from 'node:crypto';
4
+ import type { SecurityOptions, ResolvedAddress, Logger } from './udp.js';
5
+ export type DtlsPeer = {
6
+ mode: 'anonymous';
7
+ } | {
8
+ mode: 'psk';
9
+ identity: string;
10
+ } | {
11
+ mode: 'x509';
12
+ certChain: X509Certificate[];
13
+ };
14
+ export interface DtlsHandshakePayload {
15
+ peer: DtlsPeer;
16
+ durationMs: number;
17
+ rinfo: {
18
+ address: string;
19
+ port: number;
20
+ };
21
+ }
22
+ export interface DtlsSocket extends EventEmitter {
23
+ bind(): Promise<{
24
+ host: string;
25
+ port: number;
26
+ }>;
27
+ close(): Promise<void>;
28
+ send(msg: Buffer | Uint8Array, address: string, port: number): void;
29
+ on(event: 'message', listener: (msg: Buffer, rinfo: dgram.RemoteInfo, peer: DtlsPeer) => void): this;
30
+ on(event: 'error', listener: (err: Error) => void): this;
31
+ on(event: 'exchange-error', listener: (err: Error) => void): this;
32
+ on(event: 'dtls-handshake', listener: (payload: DtlsHandshakePayload) => void): this;
33
+ on(event: string, listener: (...args: unknown[]) => void): this;
34
+ }
35
+ export declare function createDtlsSocket(address: ResolvedAddress, security: SecurityOptions, opts: {
36
+ logger: Logger;
37
+ }): DtlsSocket;
38
+ //# sourceMappingURL=dtls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dtls.d.ts","sourceRoot":"","sources":["../../src/transport/dtls.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEzE,MAAM,MAAM,QAAQ,GAChB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,eAAe,EAAE,CAAA;CAAE,CAAC;AAEnD,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1C;AAKD,MAAM,WAAW,UAAW,SAAQ,YAAY;IAC9C,IAAI,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpE,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,QAAQ,KAAK,IAAI,GAAG,IAAI,CAAC;IACrG,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IACzD,EAAE,CAAC,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IAClE,EAAE,CAAC,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,GAAG,IAAI,CAAC;IACrF,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;CACjE;AAsKD,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,eAAe,EACzB,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GACvB,UAAU,CAEZ"}
@@ -0,0 +1,151 @@
1
+ import tls from 'node:tls';
2
+ import { EventEmitter } from 'node:events';
3
+ class DtlsSocketImpl extends EventEmitter {
4
+ address;
5
+ security;
6
+ log;
7
+ tlsSrv = null;
8
+ // Maps "remoteAddress:remotePort" → TLS socket, for sending responses
9
+ connections = new Map();
10
+ // Session cache for resumption: sessionId hex → session Buffer
11
+ sessionCache = new Map();
12
+ constructor(address, security, opts) {
13
+ super();
14
+ this.address = address;
15
+ this.security = security;
16
+ this.log = opts.logger;
17
+ }
18
+ bind() {
19
+ return new Promise((resolve, reject) => {
20
+ const identityByTlsSock = new WeakMap();
21
+ const tlsOpts = {
22
+ sessionTimeout: 300,
23
+ };
24
+ if (this.security.mode === 'psk') {
25
+ const pskFn = this.security.psk;
26
+ tlsOpts.pskCallback = (socket, identity) => {
27
+ const psk = pskFn(identity);
28
+ if (!psk)
29
+ return null;
30
+ identityByTlsSock.set(socket, identity);
31
+ return psk;
32
+ };
33
+ }
34
+ else {
35
+ tlsOpts.key = this.security.key;
36
+ tlsOpts.cert = this.security.cert;
37
+ if (this.security.ca)
38
+ tlsOpts.ca = this.security.ca;
39
+ if (this.security.requestClientCert) {
40
+ tlsOpts.requestCert = true;
41
+ tlsOpts.rejectUnauthorized = true;
42
+ }
43
+ }
44
+ const srv = tls.createServer(tlsOpts, (tlsSock) => {
45
+ const handshakeStart = Date.now();
46
+ const remoteAddr = tlsSock.remoteAddress ?? '';
47
+ const remotePort = tlsSock.remotePort ?? 0;
48
+ const key = `${remoteAddr}:${remotePort}`;
49
+ let peer;
50
+ if (this.security.mode === 'psk') {
51
+ peer = { mode: 'psk', identity: identityByTlsSock.get(tlsSock) ?? 'unknown' };
52
+ }
53
+ else {
54
+ const certChain = [];
55
+ let cert = tlsSock.getPeerX509Certificate();
56
+ while (cert) {
57
+ certChain.push(cert);
58
+ cert = cert.issuerCertificate;
59
+ }
60
+ peer = { mode: 'x509', certChain };
61
+ }
62
+ const durationMs = Date.now() - handshakeStart;
63
+ this.connections.set(key, { tlsSock, peer });
64
+ const rinfo = { address: remoteAddr, port: remotePort };
65
+ this.log.debug('dtls handshake complete', { key, durationMs, peer });
66
+ this.emit('dtls-handshake', { peer, durationMs, rinfo });
67
+ tlsSock.on('data', (chunk) => {
68
+ // CoAP messages arrive as individual writes; the stream may deliver
69
+ // multiple in one chunk or split them. We emit the raw chunk and let
70
+ // the CoAP decoder handle framing (same as the UDP path).
71
+ const remoteInfo = {
72
+ address: remoteAddr,
73
+ port: remotePort,
74
+ family: 'IPv4',
75
+ size: chunk.length,
76
+ };
77
+ this.emit('message', chunk, remoteInfo, peer);
78
+ });
79
+ tlsSock.on('error', (err) => {
80
+ this.log.warn('dtls connection error', { key, err: err.message });
81
+ this.emit('exchange-error', new Error(`DTLS connection error for ${key}: ${err.message}`));
82
+ this.connections.delete(key);
83
+ });
84
+ tlsSock.on('close', () => {
85
+ this.connections.delete(key);
86
+ });
87
+ });
88
+ srv.on('tlsClientError', (err) => {
89
+ this.log.warn('dtls handshake failure', { err: err.message });
90
+ this.emit('exchange-error', new Error(`DTLS handshake failed: ${err.message}`));
91
+ });
92
+ srv.on('newSession', (sessionId, sessionData, callback) => {
93
+ const key = sessionId.toString('hex');
94
+ const cacheSize = this.security.sessionCacheSize ?? 100;
95
+ if (this.sessionCache.size >= cacheSize) {
96
+ const oldest = this.sessionCache.keys().next().value;
97
+ if (oldest !== undefined)
98
+ this.sessionCache.delete(oldest);
99
+ }
100
+ this.sessionCache.set(key, sessionData);
101
+ callback();
102
+ });
103
+ srv.on('resumeSession', (sessionId, callback) => {
104
+ const key = sessionId.toString('hex');
105
+ const sessionData = this.sessionCache.get(key) ?? null;
106
+ callback(null, sessionData);
107
+ });
108
+ srv.once('error', reject);
109
+ srv.listen(this.address.port, this.address.host, () => {
110
+ srv.removeListener('error', reject);
111
+ this.tlsSrv = srv;
112
+ const actual = srv.address();
113
+ this.log.debug('dtls tls server started', { host: actual.address, port: actual.port });
114
+ resolve({ host: actual.address, port: actual.port });
115
+ });
116
+ });
117
+ }
118
+ close() {
119
+ return new Promise(resolve => {
120
+ for (const { tlsSock } of this.connections.values()) {
121
+ try {
122
+ tlsSock.destroy();
123
+ }
124
+ catch { /* ignore */ }
125
+ }
126
+ this.connections.clear();
127
+ if (this.tlsSrv) {
128
+ const srv = this.tlsSrv;
129
+ this.tlsSrv = null;
130
+ srv.close(() => resolve());
131
+ }
132
+ else {
133
+ resolve();
134
+ }
135
+ });
136
+ }
137
+ send(msg, address, port) {
138
+ const key = `${address}:${port}`;
139
+ const conn = this.connections.get(key);
140
+ if (!conn) {
141
+ this.log.warn('dtls send: no connection for peer', { key });
142
+ return;
143
+ }
144
+ const buf = Buffer.isBuffer(msg) ? msg : Buffer.from(msg);
145
+ conn.tlsSock.write(buf);
146
+ }
147
+ }
148
+ export function createDtlsSocket(address, security, opts) {
149
+ return new DtlsSocketImpl(address, security, opts);
150
+ }
151
+ //# sourceMappingURL=dtls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dtls.js","sourceRoot":"","sources":["../../src/transport/dtls.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,UAAU,CAAC;AAG3B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAkC3C,MAAM,cAAe,SAAQ,YAAY;IACtB,OAAO,CAAkB;IACzB,QAAQ,CAAkB;IAC1B,GAAG,CAAS;IAErB,MAAM,GAAsB,IAAI,CAAC;IAEzC,sEAAsE;IACrD,WAAW,GAAG,IAAI,GAAG,EAA+B,CAAC;IAEtE,+DAA+D;IAC9C,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE1D,YAAY,OAAwB,EAAE,QAAyB,EAAE,IAAwB;QACvF,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;IACzB,CAAC;IAED,IAAI;QACF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,iBAAiB,GAAG,IAAI,OAAO,EAAyB,CAAC;YAE/D,MAAM,OAAO,GAAmB;gBAC9B,cAAc,EAAE,GAAG;aACpB,CAAC;YAEF,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBACjC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAChC,OAAO,CAAC,WAAW,GAAG,CAAC,MAAqB,EAAE,QAAgB,EAAiC,EAAE;oBAC/F,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;oBAC5B,IAAI,CAAC,GAAG;wBAAE,OAAO,IAAI,CAAC;oBACtB,iBAAiB,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;oBACxC,OAAO,GAAG,CAAC;gBACb,CAAC,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAChC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,EAAE;oBAAE,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACpD,IAAI,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE,CAAC;oBACpC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;oBAC3B,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;gBACpC,CAAC;YACH,CAAC;YAED,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,OAAsB,EAAE,EAAE;gBAC/D,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAClC,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;gBAC/C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC;gBAC3C,MAAM,GAAG,GAAG,GAAG,UAAU,IAAI,UAAU,EAAE,CAAC;gBAE1C,IAAI,IAAc,CAAC;gBACnB,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;oBACjC,IAAI,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,SAAS,EAAE,CAAC;gBAChF,CAAC;qBAAM,CAAC;oBACN,MAAM,SAAS,GAAsB,EAAE,CAAC;oBACxC,IAAI,IAAI,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC;oBAC5C,OAAO,IAAI,EAAE,CAAC;wBACZ,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBACrB,IAAI,GAAG,IAAI,CAAC,iBAAgD,CAAC;oBAC/D,CAAC;oBACD,IAAI,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;gBACrC,CAAC;gBAED,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC;gBAC/C,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBAE7C,MAAM,KAAK,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;gBACxD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,yBAAyB,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;gBACrE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;gBAEzD,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;oBACnC,oEAAoE;oBACpE,qEAAqE;oBACrE,0DAA0D;oBAC1D,MAAM,UAAU,GAAqB;wBACnC,OAAO,EAAE,UAAU;wBACnB,IAAI,EAAE,UAAU;wBAChB,MAAM,EAAE,MAAM;wBACd,IAAI,EAAE,KAAK,CAAC,MAAM;qBACnB,CAAC;oBACF,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;gBAChD,CAAC,CAAC,CAAC;gBAEH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;oBACjC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;oBAClE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,KAAK,CAAC,6BAA6B,GAAG,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;oBAC3F,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC/B,CAAC,CAAC,CAAC;gBAEH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;oBACvB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC/B,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,GAAG,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC,GAAU,EAAE,EAAE;gBACtC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC9D,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,KAAK,CAAC,0BAA0B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAClF,CAAC,CAAC,CAAC;YAEH,GAAG,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,SAAiB,EAAE,WAAmB,EAAE,QAAoB,EAAE,EAAE;gBACpF,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACtC,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,gBAAgB,IAAI,GAAG,CAAC;gBACxD,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,IAAI,SAAS,EAAE,CAAC;oBACxC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;oBACrD,IAAI,MAAM,KAAK,SAAS;wBAAE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC7D,CAAC;gBACD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;gBACxC,QAAQ,EAAE,CAAC;YACb,CAAC,CAAC,CAAC;YAEH,GAAG,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,SAAiB,EAAE,QAAiE,EAAE,EAAE;gBAC/G,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACtC,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;gBACvD,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YAC9B,CAAC,CAAC,CAAC;YAEH,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAE1B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE;gBACpD,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBACpC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;gBAClB,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,EAAqB,CAAC;gBAChD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,yBAAyB,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;gBACvF,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YACvD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK;QACH,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;YAC3B,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;gBACpD,IAAI,CAAC;oBAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;YACnD,CAAC;YACD,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;YAEzB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;gBACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;gBACnB,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,GAAwB,EAAE,OAAe,EAAE,IAAY;QAC1D,MAAM,GAAG,GAAG,GAAG,OAAO,IAAI,IAAI,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,mCAAmC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;YAC5D,OAAO;QACT,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1D,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;CACF;AAED,MAAM,UAAU,gBAAgB,CAC9B,OAAwB,EACxB,QAAyB,EACzB,IAAwB;IAExB,OAAO,IAAI,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;AACrD,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { Request } from '../api/index.js';
2
+ import type { ExchangeContext, Peer } from '../api/index.js';
3
+ export interface ObserveRegistration {
4
+ remote: string;
5
+ token: Uint8Array;
6
+ }
7
+ export interface BlockTransferCompleteEvent {
8
+ remote: string;
9
+ token: Uint8Array;
10
+ }
11
+ export interface BlockTransferAbortedEvent {
12
+ remote: string;
13
+ token: Uint8Array;
14
+ reason: string;
15
+ }
16
+ export interface ServerEventMap {
17
+ 'request': [req: Request, ctx: ExchangeContext];
18
+ 'response': [ctx: ExchangeContext];
19
+ 'exchange-error': [err: Error];
20
+ 'message-dropped': [reason: string];
21
+ 'dtls-handshake': [event: {
22
+ peer: Peer;
23
+ durationMs: number;
24
+ }];
25
+ 'tls-handshake': [event: {
26
+ peer: Peer;
27
+ durationMs: number;
28
+ }];
29
+ 'observe-registered': [reg: ObserveRegistration];
30
+ 'observe-cancelled': [reg: ObserveRegistration];
31
+ 'block-transfer-complete': [event: BlockTransferCompleteEvent];
32
+ 'block-transfer-aborted': [event: BlockTransferAbortedEvent];
33
+ }
34
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/transport/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE7D,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,UAAU,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,eAAe,CAAC,CAAC;IAChD,UAAU,EAAE,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IACnC,gBAAgB,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC/B,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,gBAAgB,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,eAAe,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,oBAAoB,EAAE,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC;IACjD,mBAAmB,EAAE,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC;IAChD,yBAAyB,EAAE,CAAC,KAAK,EAAE,0BAA0B,CAAC,CAAC;IAC/D,wBAAwB,EAAE,CAAC,KAAK,EAAE,yBAAyB,CAAC,CAAC;CAC9D"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/transport/events.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ export { createServer, parseListenAddress } from './udp.js';
2
+ export type { Server, ServerOptions, ListenAddress, ResolvedAddress, Logger, StoreSummaryEntry, SecurityOptions, PskSecurityOptions, X509SecurityOptions, DtlsHandshakeEvent, TlsHandshakeEvent, UpdateTlsOptions } from './udp.js';
3
+ export type { ServerEventMap, ObserveRegistration, BlockTransferCompleteEvent, BlockTransferAbortedEvent } from './events.js';
4
+ export { encodeTcpFrame, decodeTcpFrame, TcpFrameDecodeError } from './tcp-frame.js';
5
+ export type { TcpFrame } from './tcp-frame.js';
6
+ export { TcpConnectionManager } from './tcp-connection.js';
7
+ export type { TcpConnectionManagerOptions } from './tcp-connection.js';
8
+ export { TcpFrameStream } from './tcp-stream.js';
9
+ export type { ExchangeHandle } from './tcp-stream.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transport/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC5D,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,EAAE,iBAAiB,EAAE,eAAe,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACpO,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAC9H,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrF,YAAY,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,YAAY,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { createServer, parseListenAddress } from './udp.js';
2
+ export { encodeTcpFrame, decodeTcpFrame, TcpFrameDecodeError } from './tcp-frame.js';
3
+ export { TcpConnectionManager } from './tcp-connection.js';
4
+ export { TcpFrameStream } from './tcp-stream.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/transport/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAG5D,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAErF,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import net from 'node:net';
2
+ import type { Logger } from './udp.js';
3
+ export interface TcpConnectionManagerOptions {
4
+ idleTimeoutMs: number;
5
+ logger: Logger;
6
+ }
7
+ export declare class TcpConnectionManager {
8
+ private readonly idleTimeoutMs;
9
+ private readonly log;
10
+ private readonly timers;
11
+ constructor(options: TcpConnectionManagerOptions);
12
+ track(socket: net.Socket): void;
13
+ untrack(socket: net.Socket): void;
14
+ closeAll(): Promise<void>;
15
+ private _resetTimer;
16
+ private _clearTimer;
17
+ }
18
+ //# sourceMappingURL=tcp-connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tcp-connection.d.ts","sourceRoot":"","sources":["../../src/transport/tcp-connection.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,UAAU,CAAC;AAC3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,MAAM,WAAW,2BAA2B;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyC;gBAEpD,OAAO,EAAE,2BAA2B;IAKhD,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,IAAI;IAqB/B,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,IAAI;IAKjC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IA2BzB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,WAAW;CAMpB"}
@@ -0,0 +1,72 @@
1
+ export class TcpConnectionManager {
2
+ idleTimeoutMs;
3
+ log;
4
+ timers = new Map();
5
+ constructor(options) {
6
+ this.idleTimeoutMs = options.idleTimeoutMs;
7
+ this.log = options.logger;
8
+ }
9
+ track(socket) {
10
+ this._resetTimer(socket);
11
+ socket.on('data', () => this._resetTimer(socket));
12
+ socket.once('end', () => {
13
+ socket.end();
14
+ });
15
+ socket.once('error', (err) => {
16
+ this.log.error('tcp socket error', { err: err.message });
17
+ this._clearTimer(socket);
18
+ socket.destroy();
19
+ });
20
+ socket.once('close', () => {
21
+ this._clearTimer(socket);
22
+ this.timers.delete(socket);
23
+ });
24
+ }
25
+ untrack(socket) {
26
+ this._clearTimer(socket);
27
+ this.timers.delete(socket);
28
+ }
29
+ closeAll() {
30
+ const sockets = [...this.timers.keys()];
31
+ if (sockets.length === 0)
32
+ return Promise.resolve();
33
+ return new Promise(resolve => {
34
+ let remaining = sockets.length;
35
+ const onClose = () => {
36
+ remaining--;
37
+ if (remaining === 0)
38
+ resolve();
39
+ };
40
+ for (const sock of sockets) {
41
+ this._clearTimer(sock);
42
+ this.timers.delete(sock);
43
+ if (sock.destroyed) {
44
+ remaining--;
45
+ if (remaining === 0) {
46
+ resolve();
47
+ return;
48
+ }
49
+ }
50
+ else {
51
+ sock.once('close', onClose);
52
+ sock.destroy();
53
+ }
54
+ }
55
+ });
56
+ }
57
+ _resetTimer(socket) {
58
+ this._clearTimer(socket);
59
+ const timer = setTimeout(() => {
60
+ this.log.debug('tcp idle timeout', { idleTimeoutMs: this.idleTimeoutMs });
61
+ socket.destroy();
62
+ }, this.idleTimeoutMs);
63
+ this.timers.set(socket, timer);
64
+ }
65
+ _clearTimer(socket) {
66
+ const timer = this.timers.get(socket);
67
+ if (timer !== undefined) {
68
+ clearTimeout(timer);
69
+ }
70
+ }
71
+ }
72
+ //# sourceMappingURL=tcp-connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tcp-connection.js","sourceRoot":"","sources":["../../src/transport/tcp-connection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { CoapOption } from '../option-parser/index.js';
2
+ export type { CoapOption };
3
+ export interface TcpFrame {
4
+ code: number;
5
+ token: Uint8Array;
6
+ options: CoapOption[];
7
+ payload: Uint8Array;
8
+ }
9
+ export declare class TcpFrameDecodeError extends Error {
10
+ constructor(message: string);
11
+ }
12
+ export declare function encodeTcpFrame(frame: TcpFrame): Uint8Array;
13
+ export declare function decodeTcpFrame(buf: Uint8Array): {
14
+ frame: TcpFrame;
15
+ bytesConsumed: number;
16
+ } | null;
17
+ //# sourceMappingURL=tcp-frame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tcp-frame.d.ts","sourceRoot":"","sources":["../../src/transport/tcp-frame.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,YAAY,EAAE,UAAU,EAAE,CAAC;AAE3B,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,OAAO,EAAE,UAAU,CAAC;CACrB;AAED,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AA8BD,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,GAAG,UAAU,CA2B1D;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAkDjG"}