@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.
- package/LICENSE +17 -0
- package/README.md +78 -0
- package/dist/api/exchange-context.d.ts +34 -0
- package/dist/api/exchange-context.d.ts.map +1 -0
- package/dist/api/exchange-context.js +2 -0
- package/dist/api/exchange-context.js.map +1 -0
- package/dist/api/headers.d.ts +10 -0
- package/dist/api/headers.d.ts.map +1 -0
- package/dist/api/headers.js +69 -0
- package/dist/api/headers.js.map +1 -0
- package/dist/api/index.d.ts +5 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +4 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/request.d.ts +11 -0
- package/dist/api/request.d.ts.map +1 -0
- package/dist/api/request.js +49 -0
- package/dist/api/request.js.map +1 -0
- package/dist/api/response.d.ts +11 -0
- package/dist/api/response.d.ts.map +1 -0
- package/dist/api/response.js +19 -0
- package/dist/api/response.js.map +1 -0
- package/dist/blockwise/block1-assembler.d.ts +26 -0
- package/dist/blockwise/block1-assembler.d.ts.map +1 -0
- package/dist/blockwise/block1-assembler.js +94 -0
- package/dist/blockwise/block1-assembler.js.map +1 -0
- package/dist/blockwise/block2-chunker.d.ts +23 -0
- package/dist/blockwise/block2-chunker.d.ts.map +1 -0
- package/dist/blockwise/block2-chunker.js +99 -0
- package/dist/blockwise/block2-chunker.js.map +1 -0
- package/dist/blockwise/index.d.ts +8 -0
- package/dist/blockwise/index.d.ts.map +1 -0
- package/dist/blockwise/index.js +5 -0
- package/dist/blockwise/index.js.map +1 -0
- package/dist/blockwise/middleware.d.ts +7 -0
- package/dist/blockwise/middleware.d.ts.map +1 -0
- package/dist/blockwise/middleware.js +120 -0
- package/dist/blockwise/middleware.js.map +1 -0
- package/dist/blockwise/option.d.ts +12 -0
- package/dist/blockwise/option.d.ts.map +1 -0
- package/dist/blockwise/option.js +55 -0
- package/dist/blockwise/option.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/message/index.d.ts +21 -0
- package/dist/message/index.d.ts.map +1 -0
- package/dist/message/index.js +79 -0
- package/dist/message/index.js.map +1 -0
- package/dist/observability.d.ts +44 -0
- package/dist/observability.d.ts.map +1 -0
- package/dist/observability.js +71 -0
- package/dist/observability.js.map +1 -0
- package/dist/observe-notification.d.ts +21 -0
- package/dist/observe-notification.d.ts.map +1 -0
- package/dist/observe-notification.js +87 -0
- package/dist/observe-notification.js.map +1 -0
- package/dist/observe.d.ts +10 -0
- package/dist/observe.d.ts.map +1 -0
- package/dist/observe.js +3 -0
- package/dist/observe.js.map +1 -0
- package/dist/option-parser/index.d.ts +30 -0
- package/dist/option-parser/index.d.ts.map +1 -0
- package/dist/option-parser/index.js +125 -0
- package/dist/option-parser/index.js.map +1 -0
- package/dist/router/app.d.ts +8 -0
- package/dist/router/app.d.ts.map +1 -0
- package/dist/router/app.js +25 -0
- package/dist/router/app.js.map +1 -0
- package/dist/router/content-format.d.ts +7 -0
- package/dist/router/content-format.d.ts.map +1 -0
- package/dist/router/content-format.js +23 -0
- package/dist/router/content-format.js.map +1 -0
- package/dist/router/index.d.ts +9 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/index.js +5 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/radix.d.ts +16 -0
- package/dist/router/radix.d.ts.map +1 -0
- package/dist/router/radix.js +69 -0
- package/dist/router/radix.js.map +1 -0
- package/dist/router/router.d.ts +38 -0
- package/dist/router/router.d.ts.map +1 -0
- package/dist/router/router.js +111 -0
- package/dist/router/router.js.map +1 -0
- package/dist/router.d.ts +2 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +2 -0
- package/dist/router.js.map +1 -0
- package/dist/security.d.ts +3 -0
- package/dist/security.d.ts.map +1 -0
- package/dist/security.js +2 -0
- package/dist/security.js.map +1 -0
- package/dist/store/index.d.ts +26 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +68 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/sqlite-store.d.ts +10 -0
- package/dist/store/sqlite-store.d.ts.map +1 -0
- package/dist/store/sqlite-store.js +75 -0
- package/dist/store/sqlite-store.js.map +1 -0
- package/dist/store.d.ts +5 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +3 -0
- package/dist/store.js.map +1 -0
- package/dist/transport/dtls.d.ts +38 -0
- package/dist/transport/dtls.d.ts.map +1 -0
- package/dist/transport/dtls.js +151 -0
- package/dist/transport/dtls.js.map +1 -0
- package/dist/transport/events.d.ts +34 -0
- package/dist/transport/events.d.ts.map +1 -0
- package/dist/transport/events.js +2 -0
- package/dist/transport/events.js.map +1 -0
- package/dist/transport/index.d.ts +10 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +5 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/tcp-connection.d.ts +18 -0
- package/dist/transport/tcp-connection.d.ts.map +1 -0
- package/dist/transport/tcp-connection.js +72 -0
- package/dist/transport/tcp-connection.js.map +1 -0
- package/dist/transport/tcp-frame.d.ts +17 -0
- package/dist/transport/tcp-frame.d.ts.map +1 -0
- package/dist/transport/tcp-frame.js +112 -0
- package/dist/transport/tcp-frame.js.map +1 -0
- package/dist/transport/tcp-stream.d.ts +21 -0
- package/dist/transport/tcp-stream.d.ts.map +1 -0
- package/dist/transport/tcp-stream.js +52 -0
- package/dist/transport/tcp-stream.js.map +1 -0
- package/dist/transport/udp.d.ts +97 -0
- package/dist/transport/udp.d.ts.map +1 -0
- package/dist/transport/udp.js +994 -0
- package/dist/transport/udp.js.map +1 -0
- package/dist/transport.d.ts +3 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +2 -0
- package/dist/transport.js.map +1 -0
- package/docs/api-reference.md +536 -0
- package/docs/blockwise.md +117 -0
- package/docs/observability.md +206 -0
- package/docs/observe.md +203 -0
- package/docs/releasing.md +106 -0
- package/docs/router.md +170 -0
- package/docs/store.md +212 -0
- package/docs/tcp-transport.md +89 -0
- package/docs/udp-transport.md +81 -0
- package/examples/slice-1.ts +12 -0
- package/examples/slice-2.ts +96 -0
- package/examples/slice-3-psk.ts +70 -0
- package/examples/slice-3-x509.ts +85 -0
- package/examples/slice-4.ts +45 -0
- package/examples/slice-5-firmware.ts +207 -0
- package/examples/slice-6-temperature.ts +163 -0
- package/examples/slice-7-file-store.ts +92 -0
- package/examples/slice-7-otel.ts +123 -0
- 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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"}
|
package/dist/store.d.ts
ADDED
|
@@ -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 @@
|
|
|
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 @@
|
|
|
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"}
|