werift 0.15.1 → 0.15.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/common/src/index.d.ts +1 -0
- package/lib/common/src/index.js +1 -0
- package/lib/common/src/index.js.map +1 -1
- package/lib/common/src/network.d.ts +5 -0
- package/lib/common/src/network.js +41 -0
- package/lib/common/src/network.js.map +1 -0
- package/lib/dtls/src/context/cipher.js +1 -4
- package/lib/dtls/src/context/cipher.js.map +1 -1
- package/lib/ice/src/exceptions.d.ts +4 -1
- package/lib/ice/src/exceptions.js +5 -3
- package/lib/ice/src/exceptions.js.map +1 -1
- package/lib/ice/src/ice.d.ts +1 -1
- package/lib/ice/src/ice.js +61 -25
- package/lib/ice/src/ice.js.map +1 -1
- package/lib/ice/src/stun/attributes.d.ts +16 -3
- package/lib/ice/src/stun/attributes.js +33 -1
- package/lib/ice/src/stun/attributes.js.map +1 -1
- package/lib/ice/src/stun/const.d.ts +1 -1
- package/lib/ice/src/stun/const.js +5 -2
- package/lib/ice/src/stun/const.js.map +1 -1
- package/lib/ice/src/stun/message.d.ts +6 -10
- package/lib/ice/src/stun/message.js +23 -17
- package/lib/ice/src/stun/message.js.map +1 -1
- package/lib/ice/src/stun/protocol.js +0 -1
- package/lib/ice/src/stun/protocol.js.map +1 -1
- package/lib/ice/src/stun/transaction.d.ts +0 -2
- package/lib/ice/src/stun/transaction.js +1 -1
- package/lib/ice/src/stun/transaction.js.map +1 -1
- package/lib/ice/src/transport.js +2 -2
- package/lib/ice/src/transport.js.map +1 -1
- package/lib/ice/src/turn/protocol.d.ts +8 -6
- package/lib/ice/src/turn/protocol.js +73 -71
- package/lib/ice/src/turn/protocol.js.map +1 -1
- package/lib/ice/src/utils.d.ts +0 -5
- package/lib/ice/src/utils.js +1 -38
- package/lib/ice/src/utils.js.map +1 -1
- package/lib/rtp/src/processor/webm.js +1 -2
- package/lib/rtp/src/processor/webm.js.map +1 -1
- package/lib/webrtc/src/nonstandard/userMedia.js +1 -1
- package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
- package/lib/webrtc/src/transport/dtls.js +2 -6
- package/lib/webrtc/src/transport/dtls.js.map +1 -1
- package/package.json +1 -1
- package/src/nonstandard/userMedia.ts +1 -1
- package/src/transport/dtls.ts +2 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webm.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/webm.ts"],"names":[],"mappings":"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","sourcesContent":["import Event from \"rx.mini\";\n\nimport { int, PromiseQueue } from \"../../../common/src\";\nimport {\n AV1RtpPayload,\n DePacketizerBase,\n H264RtpPayload,\n OpusRtpPayload,\n RtpPacket,\n Vp8RtpPayload,\n Vp9RtpPayload,\n} from \"..\";\nimport { SupportedCodec, WEBMBuilder } from \"../container/webm\";\nimport { Output } from \"./base\";\n\nexport class WebmOutput implements Output {\n private builder: WEBMBuilder;\n private queue = new PromiseQueue();\n private relativeTimestamp = 0;\n private timestamps: { [pt: number]: TimestampManager } = {};\n private disposer?: () => void;\n private cuePoints: CuePoint[] = [];\n private position = 0;\n stopped = false;\n\n constructor(\n /**fs/promises */\n private fs: any,\n public path: string,\n public tracks: {\n width?: number;\n height?: number;\n kind: \"audio\" | \"video\";\n codec: SupportedCodec;\n clockRate: number;\n payloadType: number;\n trackNumber: number;\n }[],\n streams?: {\n rtpStream?: Event<[RtpPacket]>;\n }\n ) {\n this.builder = new WEBMBuilder(tracks);\n\n tracks.forEach((t) => {\n this.timestamps[t.payloadType] = new TimestampManager(t.clockRate);\n });\n\n this.queue.push(() => this.init());\n\n if (streams?.rtpStream) {\n const { unSubscribe } = streams.rtpStream.subscribe((packet) => {\n this.pushRtpPackets([packet]);\n });\n this.disposer = unSubscribe;\n }\n }\n\n private async init() {\n const staticPart = Buffer.concat([\n this.builder.ebmlHeader,\n this.builder.createSegment(),\n ]);\n await this.fs.writeFile(this.path, staticPart);\n this.position += staticPart.length;\n\n const video = this.tracks.find((t) => t.kind === \"video\");\n if (video) {\n this.cuePoints.push(\n new CuePoint(this.builder, video.trackNumber, 0.0, this.position)\n );\n }\n\n const cluster = this.builder.createCluster(0.0);\n await this.fs.appendFile(this.path, cluster);\n this.position += cluster.length;\n }\n\n async stop() {\n this.stopped = true;\n if (this.disposer) {\n this.disposer();\n }\n\n const originStaticPartOffset = Buffer.concat([\n this.builder.ebmlHeader,\n this.builder.createSegment(),\n ]).length;\n const clusters = (await this.fs.readFile(this.path)).slice(\n originStaticPartOffset\n );\n\n const latestTimestamp = Object.values(this.timestamps).sort(\n (a, b) => a.relativeTimestamp - b.relativeTimestamp\n )[0].relativeTimestamp;\n const duration = this.relativeTimestamp + latestTimestamp;\n const staticPart = Buffer.concat([\n this.builder.ebmlHeader,\n this.builder.createSegment(duration),\n ]);\n // durationを挿入したことによるギャップの解消\n const staticPartGap = staticPart.length - originStaticPartOffset;\n this.cuePoints.forEach((c) => {\n c.position += staticPartGap;\n });\n\n let cuesSize = 0;\n let cues = this.builder.createCues(this.cuePoints.map((c) => c.build()));\n // cuesの最終的なサイズを再帰的に求める\n while (cuesSize !== cues.length) {\n cuesSize = cues.length;\n this.cuePoints.forEach((cue) => {\n cue.cuesLength += cuesSize;\n });\n cues = this.builder.createCues(this.cuePoints.map((c) => c.build()));\n }\n\n await this.fs.writeFile(this.path, staticPart);\n await this.fs.appendFile(this.path, cues);\n await this.fs.appendFile(this.path, clusters);\n }\n\n pushRtpPackets(packets: RtpPacket[]) {\n if (this.stopped) return;\n this.queue.push(() => this.onRtpPackets(packets));\n }\n\n private async onRtpPackets(packets: RtpPacket[]) {\n const track = this.tracks.find(\n (t) => t.payloadType === packets[0].header.payloadType\n );\n if (!track) {\n return;\n }\n\n const timestampManager = this.timestamps[track.payloadType];\n\n const { data, isKeyframe } = this.dePacketizeRtpPackets(\n track.codec,\n packets\n );\n\n const tailTimestamp = packets.slice(-1)[0].header.timestamp;\n timestampManager.update(tailTimestamp);\n\n if (\n (track.kind === \"video\" &&\n timestampManager.relativeTimestamp > 0 &&\n isKeyframe) ||\n timestampManager.relativeTimestamp > MaxSinged16Int\n ) {\n this.relativeTimestamp += timestampManager.relativeTimestamp;\n\n const cluster = this.builder.createCluster(this.relativeTimestamp);\n await this.fs.appendFile(this.path, cluster);\n this.cuePoints.push(\n new CuePoint(\n this.builder,\n track.trackNumber,\n this.relativeTimestamp,\n this.position\n )\n );\n this.position += cluster.length;\n Object.values(this.timestamps).forEach((t) => t.reset());\n }\n\n const block = this.builder.createSimpleBlock(\n data,\n isKeyframe,\n track.trackNumber,\n timestampManager.relativeTimestamp\n );\n await this.fs.appendFile(this.path, block);\n this.position += block.length;\n const [cuePoint] = this.cuePoints.slice(-1);\n if (cuePoint) {\n cuePoint.blockNumber++;\n }\n }\n\n private dePacketizeRtpPackets(codec: string, packets: RtpPacket[]) {\n const basicCodecParser = (\n DePacketizer: typeof DePacketizerBase\n ): { data: Buffer; isKeyframe: boolean } => {\n const frames = packets.map((p) => DePacketizer.deSerialize(p.payload));\n const isKeyframe = !!frames.find((f) => f.isKeyframe);\n const data = Buffer.concat(frames.map((f) => f.payload));\n return { isKeyframe, data };\n };\n\n switch (codec) {\n case \"AV1\": {\n const chunks = packets.map((p) => AV1RtpPayload.deSerialize(p.payload));\n const data = AV1RtpPayload.getFrame(chunks);\n const isKeyframe = !!chunks.find((f) => f.isKeyframe);\n return { isKeyframe, data };\n }\n case \"MPEG4/ISO/AVC\":\n return basicCodecParser(H264RtpPayload);\n case \"VP8\":\n return basicCodecParser(Vp8RtpPayload);\n case \"VP9\":\n return basicCodecParser(Vp9RtpPayload);\n case \"OPUS\":\n return basicCodecParser(OpusRtpPayload);\n default:\n throw new Error();\n }\n }\n}\n\nclass TimestampManager {\n private baseTimestamp?: number;\n relativeTimestamp = 0;\n\n constructor(public clockRate: number) {}\n\n reset() {\n this.baseTimestamp = undefined;\n this.relativeTimestamp = 0;\n }\n\n update(tailTimestamp: number) {\n if (this.baseTimestamp == undefined) {\n this.baseTimestamp = tailTimestamp;\n }\n const rotate =\n Math.abs(tailTimestamp - this.baseTimestamp) > (Max32Uint / 4) * 3;\n\n const elapsed = rotate\n ? tailTimestamp + Max32Uint - this.baseTimestamp\n : tailTimestamp - this.baseTimestamp;\n\n const relativeTimestamp = int((elapsed / this.clockRate) * 1000);\n this.relativeTimestamp = relativeTimestamp;\n }\n}\n\nclass CuePoint {\n /**\n * cuesの後のclusterのあるべき位置\n * cuesはclusterの前に挿入される\n */\n cuesLength = 0;\n blockNumber = 0;\n\n constructor(\n private readonly builder: WEBMBuilder,\n private readonly trackNumber: number,\n private readonly relativeTimestamp: number,\n public position: number\n ) {}\n\n build() {\n return this.builder.createCuePoint(\n this.relativeTimestamp,\n this.trackNumber,\n this.position - 48 + this.cuesLength,\n this.blockNumber\n );\n }\n}\n\n/**4294967295 */\nconst Max32Uint = Number(0x01n << 32n) - 1;\n/**32767 */\nconst MaxSinged16Int = (0x01 << 16) / 2 - 1;\n"]}
|
|
1
|
+
{"version":3,"file":"webm.js","sourceRoot":"","sources":["../../../../../rtp/src/processor/webm.ts"],"names":[],"mappings":"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","sourcesContent":["import Event from \"rx.mini\";\n\nimport { int, PromiseQueue } from \"../../../common/src\";\nimport {\n AV1RtpPayload,\n DePacketizerBase,\n H264RtpPayload,\n OpusRtpPayload,\n RtpPacket,\n Vp8RtpPayload,\n Vp9RtpPayload,\n} from \"..\";\nimport { SupportedCodec, WEBMBuilder } from \"../container/webm\";\nimport { Output } from \"./base\";\n\nexport class WebmOutput implements Output {\n private builder: WEBMBuilder;\n private queue = new PromiseQueue();\n private relativeTimestamp = 0;\n private timestamps: { [pt: number]: TimestampManager } = {};\n private disposer?: () => void;\n private cuePoints: CuePoint[] = [];\n private position = 0;\n stopped = false;\n\n constructor(\n /**fs/promises */\n private fs: any,\n public path: string,\n public tracks: {\n width?: number;\n height?: number;\n kind: \"audio\" | \"video\";\n codec: SupportedCodec;\n clockRate: number;\n payloadType: number;\n trackNumber: number;\n }[],\n streams?: {\n rtpStream?: Event<[RtpPacket]>;\n }\n ) {\n this.builder = new WEBMBuilder(tracks);\n\n tracks.forEach((t) => {\n this.timestamps[t.payloadType] = new TimestampManager(t.clockRate);\n });\n\n this.queue.push(() => this.init());\n\n if (streams?.rtpStream) {\n const { unSubscribe } = streams.rtpStream.subscribe((packet) => {\n this.pushRtpPackets([packet]);\n });\n this.disposer = unSubscribe;\n }\n }\n\n private async init() {\n const staticPart = Buffer.concat([\n this.builder.ebmlHeader,\n this.builder.createSegment(),\n ]);\n await this.fs.writeFile(this.path, staticPart);\n this.position += staticPart.length;\n\n const video = this.tracks.find((t) => t.kind === \"video\");\n if (video) {\n this.cuePoints.push(\n new CuePoint(this.builder, video.trackNumber, 0.0, this.position)\n );\n }\n\n const cluster = this.builder.createCluster(0.0);\n await this.fs.appendFile(this.path, cluster);\n this.position += cluster.length;\n }\n\n async stop() {\n this.stopped = true;\n if (this.disposer) {\n this.disposer();\n }\n\n const originStaticPartOffset = Buffer.concat([\n this.builder.ebmlHeader,\n this.builder.createSegment(),\n ]).length;\n const clusters = (await this.fs.readFile(this.path)).slice(\n originStaticPartOffset\n );\n\n const latestTimestamp = Object.values(this.timestamps).sort(\n (a, b) => a.relativeTimestamp - b.relativeTimestamp\n )[0].relativeTimestamp;\n const duration = this.relativeTimestamp + latestTimestamp;\n const staticPart = Buffer.concat([\n this.builder.ebmlHeader,\n this.builder.createSegment(duration),\n ]);\n // durationを挿入したことによるギャップの解消\n const staticPartGap = staticPart.length - originStaticPartOffset;\n this.cuePoints.forEach((c) => {\n c.position += staticPartGap;\n });\n\n let cuesSize = 0;\n let cues = this.builder.createCues(this.cuePoints.map((c) => c.build()));\n // cuesの最終的なサイズを再帰的に求める\n while (cuesSize !== cues.length) {\n cuesSize = cues.length;\n this.cuePoints.forEach((cue) => {\n cue.cuesLength += cuesSize;\n });\n cues = this.builder.createCues(this.cuePoints.map((c) => c.build()));\n }\n\n await this.fs.writeFile(this.path, staticPart);\n await this.fs.appendFile(this.path, cues);\n await this.fs.appendFile(this.path, clusters);\n }\n\n pushRtpPackets(packets: RtpPacket[]) {\n if (this.stopped) return;\n this.queue.push(() => this.onRtpPackets(packets));\n }\n\n private async onRtpPackets(packets: RtpPacket[]) {\n const track = this.tracks.find(\n (t) => t.payloadType === packets[0].header.payloadType\n );\n if (!track) {\n return;\n }\n\n const timestampManager = this.timestamps[track.payloadType];\n\n const { data, isKeyframe } = this.dePacketizeRtpPackets(\n track.codec,\n packets\n );\n\n const tailTimestamp = packets.slice(-1)[0].header.timestamp;\n timestampManager.update(tailTimestamp);\n\n if (\n (track.kind === \"video\" &&\n timestampManager.relativeTimestamp > 0 &&\n isKeyframe) ||\n timestampManager.relativeTimestamp > MaxSinged16Int\n ) {\n this.relativeTimestamp += timestampManager.relativeTimestamp;\n\n const cluster = this.builder.createCluster(this.relativeTimestamp);\n await this.fs.appendFile(this.path, cluster);\n this.cuePoints.push(\n new CuePoint(\n this.builder,\n track.trackNumber,\n this.relativeTimestamp,\n this.position\n )\n );\n this.position += cluster.length;\n Object.values(this.timestamps).forEach((t) => t.reset());\n }\n\n const block = this.builder.createSimpleBlock(\n data,\n isKeyframe,\n track.trackNumber,\n timestampManager.relativeTimestamp\n );\n await this.fs.appendFile(this.path, block);\n this.position += block.length;\n const [cuePoint] = this.cuePoints.slice(-1);\n if (cuePoint) {\n cuePoint.blockNumber++;\n }\n }\n\n private dePacketizeRtpPackets(codec: string, packets: RtpPacket[]) {\n const basicCodecParser = (\n DePacketizer: typeof DePacketizerBase\n ): { data: Buffer; isKeyframe: boolean } => {\n const frames = packets.map((p) => DePacketizer.deSerialize(p.payload));\n const isKeyframe = !!frames.find((f) => f.isKeyframe);\n const data = Buffer.concat(frames.map((f) => f.payload));\n return { isKeyframe, data };\n };\n\n switch (codec) {\n case \"AV1\": {\n const chunks = packets.map((p) => AV1RtpPayload.deSerialize(p.payload));\n const data = AV1RtpPayload.getFrame(chunks);\n const isKeyframe = !!chunks.find((f) => f.isKeyframe);\n return { isKeyframe, data };\n }\n case \"MPEG4/ISO/AVC\":\n return basicCodecParser(H264RtpPayload);\n case \"VP8\":\n return basicCodecParser(Vp8RtpPayload);\n case \"VP9\":\n return basicCodecParser(Vp9RtpPayload);\n case \"OPUS\":\n return basicCodecParser(OpusRtpPayload);\n default:\n throw new Error();\n }\n }\n}\n\nclass TimestampManager {\n private baseTimestamp?: number;\n relativeTimestamp = 0;\n\n constructor(public clockRate: number) {}\n\n reset() {\n this.baseTimestamp = undefined;\n this.relativeTimestamp = 0;\n }\n\n update(tailTimestamp: number) {\n if (this.baseTimestamp == undefined) {\n this.baseTimestamp = tailTimestamp;\n }\n const rotate =\n Math.abs(tailTimestamp - this.baseTimestamp) > (Max32Uint / 4) * 3;\n\n const elapsed = rotate\n ? tailTimestamp + Max32Uint - this.baseTimestamp\n : tailTimestamp - this.baseTimestamp;\n\n this.relativeTimestamp = int((elapsed / this.clockRate) * 1000);\n }\n}\n\nclass CuePoint {\n /**\n * cuesの後のclusterのあるべき位置\n * cuesはclusterの前に挿入される\n */\n cuesLength = 0;\n blockNumber = 0;\n\n constructor(\n private readonly builder: WEBMBuilder,\n private readonly trackNumber: number,\n private readonly relativeTimestamp: number,\n public position: number\n ) {}\n\n build() {\n return this.builder.createCuePoint(\n this.relativeTimestamp,\n this.trackNumber,\n this.position - 48 + this.cuesLength,\n this.blockNumber\n );\n }\n}\n\n/**4294967295 */\nconst Max32Uint = Number(0x01n << 32n) - 1;\n/**32767 */\nconst MaxSinged16Int = (0x01 << 16) / 2 - 1;\n"]}
|
|
@@ -5,7 +5,7 @@ const child_process_1 = require("child_process");
|
|
|
5
5
|
const dgram_1 = require("dgram");
|
|
6
6
|
const promises_1 = require("timers/promises");
|
|
7
7
|
const uuid_1 = require("uuid");
|
|
8
|
-
const src_1 = require("../../../
|
|
8
|
+
const src_1 = require("../../../common/src");
|
|
9
9
|
const src_2 = require("../../../rtp/src");
|
|
10
10
|
const track_1 = require("../media/track");
|
|
11
11
|
const getUserMp4 = async (path, loop) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userMedia.js","sourceRoot":"","sources":["../../../../src/nonstandard/userMedia.ts"],"names":[],"mappings":";;;AAAA,iDAAqC;AACrC,iCAAqC;AACrC,8CAA+C;AAC/C,+BAA0B;AAE1B,
|
|
1
|
+
{"version":3,"file":"userMedia.js","sourceRoot":"","sources":["../../../../src/nonstandard/userMedia.ts"],"names":[],"mappings":"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","sourcesContent":["import { exec } from \"child_process\";\nimport { createSocket } from \"dgram\";\nimport { setImmediate } from \"timers/promises\";\nimport { v4 } from \"uuid\";\n\nimport { randomPort } from \"../../../common/src\";\nimport { RtpPacket } from \"../../../rtp/src\";\nimport { MediaStreamTrack } from \"../media/track\";\n\nexport const getUserMp4 = async (path: string, loop?: boolean) => {\n const audioPort = await randomPort();\n const videoPort = await randomPort();\n\n return new MediaMp4(audioPort, videoPort, path, loop);\n};\n\nclass MediaMp4 {\n private streamId = v4();\n audio = new MediaStreamTrack({ kind: \"audio\", streamId: this.streamId });\n video = new MediaStreamTrack({ kind: \"video\", streamId: this.streamId });\n\n constructor(\n private videoPort: number,\n private audioPort: number,\n private path: string,\n private loop?: boolean\n ) {\n this.setupTrack(audioPort, this.audio);\n this.setupTrack(videoPort, this.video);\n }\n\n private setupTrack = (port: number, track: MediaStreamTrack) => {\n let payloadType = 0;\n\n const socket = createSocket(\"udp4\");\n socket.bind(port);\n socket.on(\"message\", async (buf) => {\n const rtp = RtpPacket.deSerialize(buf);\n if (!payloadType) {\n payloadType = rtp.header.payloadType;\n }\n\n // detect gStreamer restarted\n if (payloadType !== rtp.header.payloadType) {\n payloadType = rtp.header.payloadType;\n track.onSourceChanged.execute(rtp.header);\n }\n\n track.writeRtp(buf);\n });\n };\n\n async start() {\n let payloadType = 96;\n const run = async () => {\n if (payloadType > 100) payloadType = 96;\n\n const cmd = `gst-launch-1.0 filesrc location= ${this.path} ! \\\nqtdemux name=d ! \\\nqueue ! h264parse ! rtph264pay config-interval=10 pt=${payloadType++} ! \\\nudpsink host=127.0.0.1 port=${this.videoPort} d. ! \\\nqueue ! aacparse ! avdec_aac ! audioresample ! audioconvert ! opusenc ! rtpopuspay pt=${payloadType++} ! \\\nudpsink host=127.0.0.1 port=${this.audioPort}`;\n const process = exec(cmd);\n\n if (this.loop) {\n await new Promise((r) => process.on(\"close\", r));\n run();\n }\n };\n await setImmediate();\n run();\n }\n}\n"]}
|
|
@@ -153,17 +153,13 @@ class RTCDtlsTransport {
|
|
|
153
153
|
}
|
|
154
154
|
async sendRtp(payload, header) {
|
|
155
155
|
const enc = this.srtp.encrypt(payload, header);
|
|
156
|
-
await this.iceTransport.connection.send(enc).catch((err) => {
|
|
157
|
-
log("sendRtp failed", err.message);
|
|
158
|
-
});
|
|
156
|
+
await this.iceTransport.connection.send(enc).catch((err) => { });
|
|
159
157
|
return enc.length;
|
|
160
158
|
}
|
|
161
159
|
async sendRtcp(packets) {
|
|
162
160
|
const payload = Buffer.concat(packets.map((packet) => packet.serialize()));
|
|
163
161
|
const enc = this.srtcp.encrypt(payload);
|
|
164
|
-
await this.iceTransport.connection.send(enc).catch((err) => {
|
|
165
|
-
log("sendRtcp failed", err.message);
|
|
166
|
-
});
|
|
162
|
+
await this.iceTransport.connection.send(enc).catch((err) => { });
|
|
167
163
|
}
|
|
168
164
|
setState(state) {
|
|
169
165
|
if (state != this.state) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dtls.js","sourceRoot":"","sources":["../../../../src/transport/dtls.ts"],"names":[],"mappings":";;;;;;AAAA,qCAAqD;AACrD,kDAA0B;AAC1B,sDAA4B;AAC5B,8CAA6C;AAC7C,+BAA0B;AAE1B,2CAK2B;AAC3B,0DAKwC;AACxC,6DAAiE;AAGjE,0CAO0B;AAC1B,uDAAoE;AAEpE,oCAAgE;AAGhE,MAAM,GAAG,GAAG,IAAA,eAAK,EAAC,8CAA8C,CAAC,CAAC;AAElE,MAAa,gBAAgB;IAiB3B,YACW,YAA6B,EAC7B,MAAiB,EACjB,YAA8B,EACtB,eAA0B,EAAE;QAHpC,iBAAY,GAAZ,YAAY,CAAiB;QAC7B,WAAM,GAAN,MAAM,CAAW;QACjB,iBAAY,GAAZ,YAAY,CAAkB;QACtB,iBAAY,GAAZ,YAAY,CAAgB;QApB/C,OAAE,GAAG,IAAA,SAAE,GAAE,CAAC;QACV,UAAK,GAAc,KAAK,CAAC;QACzB,SAAI,GAAa,MAAM,CAAC;QACxB,gBAAW,GAAG,KAAK,CAAC;QACpB,4BAAuB,GAAG,CAAC,CAAC;QAE5B,iBAAY,GAA0B,GAAG,EAAE,GAAE,CAAC,CAAC;QAKtC,kBAAa,GAAG,IAAI,iBAAK,EAAe,CAAC;QAElD,qBAAgB,GAAoB,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAgJhD,aAAQ,GAAG,KAAK,EAAE,IAAY,EAAE,EAAE;YACzC,IAAI,CAAC,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;YACxD,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC,CAAC;IA3IC,CAAC;IAEJ,IAAI,eAAe;QACjB,OAAO,IAAI,iBAAiB,CAC1B,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,EACpE,IAAI,CAAC,IAAI,CACV,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;YAC1B,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,GACtC,MAAM,sBAAa,CAAC,kCAAkC,CACpD;gBACE,SAAS,EAAE,0BAAkB,CAAC,OAAO;gBACrC,IAAI,EAAE,qBAAa,CAAC,QAAQ;aAC7B,EACD,2BAAmB,CAAC,YAAY,CACjC,CAAC;YACJ,IAAI,CAAC,gBAAgB,GAAG,IAAI,cAAc,CACxC,MAAM,EACN,OAAO,EACP,aAAa,CACd,CAAC;SACH;QACD,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;IAED,eAAe,CAAC,gBAAmC;QACjD,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK;YAAE,MAAM,IAAI,KAAK,EAAE,CAAC;QAC5C,IAAI,IAAI,CAAC,gBAAgB,EAAE,YAAY,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,EAAE,CAAC;QAExE,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE;YACxB,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,KAAK,aAAa,EAAE;gBAC5C,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;aACtB;iBAAM;gBACL,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;aACtB;SACF;QAED,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAE5B,MAAM,IAAI,OAAO,CAAO,KAAK,EAAE,CAAC,EAAE,EAAE;YAClC,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE;gBAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,gBAAU,CAAC;oBACzB,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,OAAO;oBACpC,GAAG,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU;oBACtC,aAAa,EAAE,IAAI,CAAC,gBAAgB,EAAE,aAAa;oBACnD,SAAS,EAAE,kBAAkB,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC;oBAC3D,YAAY,EAAE,IAAI,CAAC,YAAY;oBAC/B,oBAAoB,EAAE,IAAI;oBAC1B,4BAA4B;iBAC7B,CAAC,CAAC;aACJ;iBAAM;gBACL,IAAI,CAAC,IAAI,GAAG,IAAI,gBAAU,CAAC;oBACzB,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,OAAO;oBACpC,GAAG,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU;oBACtC,aAAa,EAAE,IAAI,CAAC,gBAAgB,EAAE,aAAa;oBACnD,SAAS,EAAE,kBAAkB,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC;oBAC3D,YAAY,EAAE,IAAI,CAAC,YAAY;oBAC/B,oBAAoB,EAAE,IAAI;iBAC3B,CAAC,CAAC;aACJ;YACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE;gBACjC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;YACzB,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE;gBAC1B,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC1B,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC/B,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACxB,GAAG,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;YAC5B,CAAC,CAAC,CAAC;YAEH,IAAI,IAAI,CAAC,IAAI,YAAY,gBAAU,EAAE;gBACnC,MAAM,IAAA,qBAAU,EAAC,GAAG,CAAC,CAAC;gBACtB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;oBAClC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;oBACxB,GAAG,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;gBACpC,CAAC,CAAC,CAAC;aACJ;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE;YAChC,IAAI,CAAC,SAAS,EAAE,CAAC;SAClB;QACD,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC3B,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACxB,CAAC;IAED,SAAS;QACP,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,EAAE,CAAC;QAElC,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAC7B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAExB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;QAC3C,IAAI,CAAC,OAAO,EAAE;YACZ,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;SACrC;QACD,GAAG,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;QAEtC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,GAClD,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAA,iBAAS,EAAC,OAAO,CAAC,EAAE,IAAA,kBAAU,EAAC,OAAO,CAAC,CAAC,CAAC;QAExE,MAAM,MAAM,GAAG;YACb,IAAI,EAAE;gBACJ,cAAc,EAAE,QAAQ;gBACxB,eAAe,EAAE,SAAS;gBAC1B,eAAe,EAAE,SAAS;gBAC1B,gBAAgB,EAAE,UAAU;aAC7B;YACD,OAAO;SACR,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,IAAI,iBAAW,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,IAAI,kBAAY,CAAC,MAAM,CAAC,CAAC;QAEtC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;YACrD,IAAI,CAAC,IAAA,eAAO,EAAC,IAAI,CAAC;gBAAE,OAAO;YAC3B,IAAI,IAAA,cAAM,EAAC,IAAI,CAAC,EAAE;gBAChB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACrC,MAAM,KAAK,GAAG,yBAAmB,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;gBACnD,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;aACtD;iBAAM;gBACL,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACpC,MAAM,GAAG,GAAG,eAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;gBACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;aAC3B;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAOD,KAAK,CAAC,OAAO,CAAC,OAAe,EAAE,MAAiB;QAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC/C,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;YAChE,GAAG,CAAC,gBAAgB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,MAAM,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,OAAqB;QAClC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QAC3E,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACxC,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;YAChE,GAAG,CAAC,iBAAiB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,QAAQ,CAAC,KAAgB;QAC/B,IAAI,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE;YACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YACnB,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;SACnC;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACxB,uBAAuB;IACzB,CAAC;CACF;AA9LD,4CA8LC;AAEY,QAAA,UAAU,GAAG;IACxB,KAAK;IACL,YAAY;IACZ,WAAW;IACX,QAAQ;IACR,QAAQ;CACA,CAAC;AAKX,MAAa,cAAc;IAIzB,YACE,aAAqB,EACd,OAAe,EACf,aAA4B;QAD5B,YAAO,GAAP,OAAO,CAAQ;QACf,kBAAa,GAAb,aAAa,CAAe;QAEnC,MAAM,IAAI,GAAG,kBAAW,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACvD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACxC,IAAI,CAAC,UAAU,GAAG,iBAAU,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;IAC3E,CAAC;IAED,eAAe;QACb,OAAO;YACL,IAAI,kBAAkB,CACpB,SAAS,EACT,IAAA,mBAAW,EACT,kBAAW,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAClD,QAAQ,CACT,CACF;SACF,CAAC;IACJ,CAAC;CACF;AAzBD,wCAyBC;AAQD,MAAa,kBAAkB;IAC7B,YAAmB,SAAiB,EAAS,KAAa;QAAvC,cAAS,GAAT,SAAS,CAAQ;QAAS,UAAK,GAAL,KAAK,CAAQ;IAAG,CAAC;CAC/D;AAFD,gDAEC;AAED,MAAa,iBAAiB;IAC5B,YACS,eAAqC,EAAE,EACvC,IAAkC;QADlC,iBAAY,GAAZ,YAAY,CAA2B;QACvC,SAAI,GAAJ,IAAI,CAA8B;IACxC,CAAC;CACL;AALD,8CAKC;AAED,MAAM,YAAY;IAChB,YAAoB,GAAe;QAAf,QAAG,GAAH,GAAG,CAAY;QAS1B,SAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;QAR5B,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE;YAC3B,IAAI,IAAA,cAAM,EAAC,GAAG,CAAC,EAAE;gBACf,IAAI,IAAI,CAAC,MAAM;oBAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;aACnC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAKD,KAAK;QACH,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;CACF;AAED,MAAM,kBAAkB,GAAG,CAAC,GAAe,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC","sourcesContent":["import { Certificate, PrivateKey } from \"@fidm/x509\";\nimport debug from \"debug\";\nimport Event from \"rx.mini\";\nimport { setTimeout } from \"timers/promises\";\nimport { v4 } from \"uuid\";\n\nimport {\n DtlsClient,\n DtlsServer,\n DtlsSocket,\n Transport,\n} from \"../../../dtls/src\";\nimport {\n HashAlgorithm,\n NamedCurveAlgorithm,\n SignatureAlgorithm,\n SignatureHash,\n} from \"../../../dtls/src/cipher/const\";\nimport { CipherContext } from \"../../../dtls/src/context/cipher\";\nimport { Profile } from \"../../../dtls/src/context/srtp\";\nimport { Connection } from \"../../../ice/src\";\nimport {\n RtcpPacket,\n RtcpPacketConverter,\n RtpHeader,\n RtpPacket,\n SrtcpSession,\n SrtpSession,\n} from \"../../../rtp/src\";\nimport { keyLength, saltLength } from \"../../../rtp/src/srtp/const\";\nimport { RtpRouter } from \"../media/router\";\nimport { fingerprint, isDtls, isMedia, isRtcp } from \"../utils\";\nimport { RTCIceTransport } from \"./ice\";\n\nconst log = debug(\"werift:packages/webrtc/src/transport/dtls.ts\");\n\nexport class RTCDtlsTransport {\n id = v4();\n state: DtlsState = \"new\";\n role: DtlsRole = \"auto\";\n srtpStarted = false;\n transportSequenceNumber = 0;\n\n dataReceiver: (buf: Buffer) => void = () => {};\n dtls?: DtlsSocket;\n srtp!: SrtpSession;\n srtcp!: SrtcpSession;\n\n readonly onStateChange = new Event<[DtlsState]>();\n\n localCertificate?: RTCCertificate = this.certificates[0];\n private remoteParameters?: RTCDtlsParameters;\n\n constructor(\n readonly iceTransport: RTCIceTransport,\n readonly router: RtpRouter,\n readonly certificates: RTCCertificate[],\n private readonly srtpProfiles: Profile[] = []\n ) {}\n\n get localParameters() {\n return new RTCDtlsParameters(\n this.localCertificate ? this.localCertificate.getFingerprints() : [],\n this.role\n );\n }\n\n async setupCertificate() {\n if (!this.localCertificate) {\n const { certPem, keyPem, signatureHash } =\n await CipherContext.createSelfSignedCertificateWithKey(\n {\n signature: SignatureAlgorithm.ecdsa_3,\n hash: HashAlgorithm.sha256_4,\n },\n NamedCurveAlgorithm.secp256r1_23\n );\n this.localCertificate = new RTCCertificate(\n keyPem,\n certPem,\n signatureHash\n );\n }\n return this.localCertificate;\n }\n\n setRemoteParams(remoteParameters: RTCDtlsParameters) {\n this.remoteParameters = remoteParameters;\n }\n\n async start() {\n if (this.state !== \"new\") throw new Error();\n if (this.remoteParameters?.fingerprints.length === 0) throw new Error();\n\n if (this.role === \"auto\") {\n if (this.iceTransport.role === \"controlling\") {\n this.role = \"server\";\n } else {\n this.role = \"client\";\n }\n }\n\n this.setState(\"connecting\");\n\n await new Promise<void>(async (r) => {\n if (this.role === \"server\") {\n this.dtls = new DtlsServer({\n cert: this.localCertificate?.certPem,\n key: this.localCertificate?.privateKey,\n signatureHash: this.localCertificate?.signatureHash,\n transport: createIceTransport(this.iceTransport.connection),\n srtpProfiles: this.srtpProfiles,\n extendedMasterSecret: true,\n // certificateRequest: true,\n });\n } else {\n this.dtls = new DtlsClient({\n cert: this.localCertificate?.certPem,\n key: this.localCertificate?.privateKey,\n signatureHash: this.localCertificate?.signatureHash,\n transport: createIceTransport(this.iceTransport.connection),\n srtpProfiles: this.srtpProfiles,\n extendedMasterSecret: true,\n });\n }\n this.dtls.onData.subscribe((buf) => {\n this.dataReceiver(buf);\n });\n this.dtls.onClose.once(() => {\n this.setState(\"closed\");\n });\n this.dtls.onConnect.once(r);\n this.dtls.onError.once((error) => {\n this.setState(\"failed\");\n log(\"dtls failed\", error);\n });\n\n if (this.dtls instanceof DtlsClient) {\n await setTimeout(100);\n this.dtls.connect().catch((error) => {\n this.setState(\"failed\");\n log(\"dtls connect failed\", error);\n });\n }\n });\n\n if (this.srtpProfiles.length > 0) {\n this.startSrtp();\n }\n this.setState(\"connected\");\n log(\"dtls connected\");\n }\n\n startSrtp() {\n if (!this.dtls) throw new Error();\n\n if (this.srtpStarted) return;\n this.srtpStarted = true;\n\n const profile = this.dtls.srtp.srtpProfile;\n if (!profile) {\n throw new Error(\"need srtpProfile\");\n }\n log(\"selected SRTP Profile\", profile);\n\n const { localKey, localSalt, remoteKey, remoteSalt } =\n this.dtls.extractSessionKeys(keyLength(profile), saltLength(profile));\n\n const config = {\n keys: {\n localMasterKey: localKey,\n localMasterSalt: localSalt,\n remoteMasterKey: remoteKey,\n remoteMasterSalt: remoteSalt,\n },\n profile,\n };\n this.srtp = new SrtpSession(config);\n this.srtcp = new SrtcpSession(config);\n\n this.iceTransport.connection.onData.subscribe((data) => {\n if (!isMedia(data)) return;\n if (isRtcp(data)) {\n const dec = this.srtcp.decrypt(data);\n const rtcps = RtcpPacketConverter.deSerialize(dec);\n rtcps.forEach((rtcp) => this.router.routeRtcp(rtcp));\n } else {\n const dec = this.srtp.decrypt(data);\n const rtp = RtpPacket.deSerialize(dec);\n this.router.routeRtp(rtp);\n }\n });\n }\n\n readonly sendData = async (data: Buffer) => {\n if (!this.dtls) throw new Error(\"dtls not established\");\n await this.dtls.send(data);\n };\n\n async sendRtp(payload: Buffer, header: RtpHeader) {\n const enc = this.srtp.encrypt(payload, header);\n await this.iceTransport.connection.send(enc).catch((err: Error) => {\n log(\"sendRtp failed\", err.message);\n });\n return enc.length;\n }\n\n async sendRtcp(packets: RtcpPacket[]) {\n const payload = Buffer.concat(packets.map((packet) => packet.serialize()));\n const enc = this.srtcp.encrypt(payload);\n await this.iceTransport.connection.send(enc).catch((err: Error) => {\n log(\"sendRtcp failed\", err.message);\n });\n }\n\n private setState(state: DtlsState) {\n if (state != this.state) {\n this.state = state;\n this.onStateChange.execute(state);\n }\n }\n\n async stop() {\n this.setState(\"closed\");\n // todo impl send alert\n }\n}\n\nexport const DtlsStates = [\n \"new\",\n \"connecting\",\n \"connected\",\n \"closed\",\n \"failed\",\n] as const;\nexport type DtlsState = typeof DtlsStates[number];\n\nexport type DtlsRole = \"auto\" | \"server\" | \"client\";\n\nexport class RTCCertificate {\n publicKey: string;\n privateKey: string;\n\n constructor(\n privateKeyPem: string,\n public certPem: string,\n public signatureHash: SignatureHash\n ) {\n const cert = Certificate.fromPEM(Buffer.from(certPem));\n this.publicKey = cert.publicKey.toPEM();\n this.privateKey = PrivateKey.fromPEM(Buffer.from(privateKeyPem)).toPEM();\n }\n\n getFingerprints(): RTCDtlsFingerprint[] {\n return [\n new RTCDtlsFingerprint(\n \"sha-256\",\n fingerprint(\n Certificate.fromPEM(Buffer.from(this.certPem)).raw,\n \"sha256\"\n )\n ),\n ];\n }\n}\n\nexport type DtlsKeys = {\n certPem: string;\n keyPem: string;\n signatureHash: SignatureHash;\n};\n\nexport class RTCDtlsFingerprint {\n constructor(public algorithm: string, public value: string) {}\n}\n\nexport class RTCDtlsParameters {\n constructor(\n public fingerprints: RTCDtlsFingerprint[] = [],\n public role: \"auto\" | \"client\" | \"server\"\n ) {}\n}\n\nclass IceTransport implements Transport {\n constructor(private ice: Connection) {\n ice.onData.subscribe((buf) => {\n if (isDtls(buf)) {\n if (this.onData) this.onData(buf);\n }\n });\n }\n onData?: (buf: Buffer) => void;\n\n readonly send = this.ice.send;\n\n close() {\n this.ice.close();\n }\n}\n\nconst createIceTransport = (ice: Connection) => new IceTransport(ice);\n"]}
|
|
1
|
+
{"version":3,"file":"dtls.js","sourceRoot":"","sources":["../../../../src/transport/dtls.ts"],"names":[],"mappings":"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","sourcesContent":["import { Certificate, PrivateKey } from \"@fidm/x509\";\nimport debug from \"debug\";\nimport Event from \"rx.mini\";\nimport { setTimeout } from \"timers/promises\";\nimport { v4 } from \"uuid\";\n\nimport {\n DtlsClient,\n DtlsServer,\n DtlsSocket,\n Transport,\n} from \"../../../dtls/src\";\nimport {\n HashAlgorithm,\n NamedCurveAlgorithm,\n SignatureAlgorithm,\n SignatureHash,\n} from \"../../../dtls/src/cipher/const\";\nimport { CipherContext } from \"../../../dtls/src/context/cipher\";\nimport { Profile } from \"../../../dtls/src/context/srtp\";\nimport { Connection } from \"../../../ice/src\";\nimport {\n RtcpPacket,\n RtcpPacketConverter,\n RtpHeader,\n RtpPacket,\n SrtcpSession,\n SrtpSession,\n} from \"../../../rtp/src\";\nimport { keyLength, saltLength } from \"../../../rtp/src/srtp/const\";\nimport { RtpRouter } from \"../media/router\";\nimport { fingerprint, isDtls, isMedia, isRtcp } from \"../utils\";\nimport { RTCIceTransport } from \"./ice\";\n\nconst log = debug(\"werift:packages/webrtc/src/transport/dtls.ts\");\n\nexport class RTCDtlsTransport {\n id = v4();\n state: DtlsState = \"new\";\n role: DtlsRole = \"auto\";\n srtpStarted = false;\n transportSequenceNumber = 0;\n\n dataReceiver: (buf: Buffer) => void = () => {};\n dtls?: DtlsSocket;\n srtp!: SrtpSession;\n srtcp!: SrtcpSession;\n\n readonly onStateChange = new Event<[DtlsState]>();\n\n localCertificate?: RTCCertificate = this.certificates[0];\n private remoteParameters?: RTCDtlsParameters;\n\n constructor(\n readonly iceTransport: RTCIceTransport,\n readonly router: RtpRouter,\n readonly certificates: RTCCertificate[],\n private readonly srtpProfiles: Profile[] = []\n ) {}\n\n get localParameters() {\n return new RTCDtlsParameters(\n this.localCertificate ? this.localCertificate.getFingerprints() : [],\n this.role\n );\n }\n\n async setupCertificate() {\n if (!this.localCertificate) {\n const { certPem, keyPem, signatureHash } =\n await CipherContext.createSelfSignedCertificateWithKey(\n {\n signature: SignatureAlgorithm.ecdsa_3,\n hash: HashAlgorithm.sha256_4,\n },\n NamedCurveAlgorithm.secp256r1_23\n );\n this.localCertificate = new RTCCertificate(\n keyPem,\n certPem,\n signatureHash\n );\n }\n return this.localCertificate;\n }\n\n setRemoteParams(remoteParameters: RTCDtlsParameters) {\n this.remoteParameters = remoteParameters;\n }\n\n async start() {\n if (this.state !== \"new\") throw new Error();\n if (this.remoteParameters?.fingerprints.length === 0) throw new Error();\n\n if (this.role === \"auto\") {\n if (this.iceTransport.role === \"controlling\") {\n this.role = \"server\";\n } else {\n this.role = \"client\";\n }\n }\n\n this.setState(\"connecting\");\n\n await new Promise<void>(async (r) => {\n if (this.role === \"server\") {\n this.dtls = new DtlsServer({\n cert: this.localCertificate?.certPem,\n key: this.localCertificate?.privateKey,\n signatureHash: this.localCertificate?.signatureHash,\n transport: createIceTransport(this.iceTransport.connection),\n srtpProfiles: this.srtpProfiles,\n extendedMasterSecret: true,\n // certificateRequest: true,\n });\n } else {\n this.dtls = new DtlsClient({\n cert: this.localCertificate?.certPem,\n key: this.localCertificate?.privateKey,\n signatureHash: this.localCertificate?.signatureHash,\n transport: createIceTransport(this.iceTransport.connection),\n srtpProfiles: this.srtpProfiles,\n extendedMasterSecret: true,\n });\n }\n this.dtls.onData.subscribe((buf) => {\n this.dataReceiver(buf);\n });\n this.dtls.onClose.once(() => {\n this.setState(\"closed\");\n });\n this.dtls.onConnect.once(r);\n this.dtls.onError.once((error) => {\n this.setState(\"failed\");\n log(\"dtls failed\", error);\n });\n\n if (this.dtls instanceof DtlsClient) {\n await setTimeout(100);\n this.dtls.connect().catch((error) => {\n this.setState(\"failed\");\n log(\"dtls connect failed\", error);\n });\n }\n });\n\n if (this.srtpProfiles.length > 0) {\n this.startSrtp();\n }\n this.setState(\"connected\");\n log(\"dtls connected\");\n }\n\n startSrtp() {\n if (!this.dtls) throw new Error();\n\n if (this.srtpStarted) return;\n this.srtpStarted = true;\n\n const profile = this.dtls.srtp.srtpProfile;\n if (!profile) {\n throw new Error(\"need srtpProfile\");\n }\n log(\"selected SRTP Profile\", profile);\n\n const { localKey, localSalt, remoteKey, remoteSalt } =\n this.dtls.extractSessionKeys(keyLength(profile), saltLength(profile));\n\n const config = {\n keys: {\n localMasterKey: localKey,\n localMasterSalt: localSalt,\n remoteMasterKey: remoteKey,\n remoteMasterSalt: remoteSalt,\n },\n profile,\n };\n this.srtp = new SrtpSession(config);\n this.srtcp = new SrtcpSession(config);\n\n this.iceTransport.connection.onData.subscribe((data) => {\n if (!isMedia(data)) return;\n if (isRtcp(data)) {\n const dec = this.srtcp.decrypt(data);\n const rtcps = RtcpPacketConverter.deSerialize(dec);\n rtcps.forEach((rtcp) => this.router.routeRtcp(rtcp));\n } else {\n const dec = this.srtp.decrypt(data);\n const rtp = RtpPacket.deSerialize(dec);\n this.router.routeRtp(rtp);\n }\n });\n }\n\n readonly sendData = async (data: Buffer) => {\n if (!this.dtls) throw new Error(\"dtls not established\");\n await this.dtls.send(data);\n };\n\n async sendRtp(payload: Buffer, header: RtpHeader) {\n const enc = this.srtp.encrypt(payload, header);\n await this.iceTransport.connection.send(enc).catch((err: Error) => {});\n return enc.length;\n }\n\n async sendRtcp(packets: RtcpPacket[]) {\n const payload = Buffer.concat(packets.map((packet) => packet.serialize()));\n const enc = this.srtcp.encrypt(payload);\n await this.iceTransport.connection.send(enc).catch((err: Error) => {});\n }\n\n private setState(state: DtlsState) {\n if (state != this.state) {\n this.state = state;\n this.onStateChange.execute(state);\n }\n }\n\n async stop() {\n this.setState(\"closed\");\n // todo impl send alert\n }\n}\n\nexport const DtlsStates = [\n \"new\",\n \"connecting\",\n \"connected\",\n \"closed\",\n \"failed\",\n] as const;\nexport type DtlsState = typeof DtlsStates[number];\n\nexport type DtlsRole = \"auto\" | \"server\" | \"client\";\n\nexport class RTCCertificate {\n publicKey: string;\n privateKey: string;\n\n constructor(\n privateKeyPem: string,\n public certPem: string,\n public signatureHash: SignatureHash\n ) {\n const cert = Certificate.fromPEM(Buffer.from(certPem));\n this.publicKey = cert.publicKey.toPEM();\n this.privateKey = PrivateKey.fromPEM(Buffer.from(privateKeyPem)).toPEM();\n }\n\n getFingerprints(): RTCDtlsFingerprint[] {\n return [\n new RTCDtlsFingerprint(\n \"sha-256\",\n fingerprint(\n Certificate.fromPEM(Buffer.from(this.certPem)).raw,\n \"sha256\"\n )\n ),\n ];\n }\n}\n\nexport type DtlsKeys = {\n certPem: string;\n keyPem: string;\n signatureHash: SignatureHash;\n};\n\nexport class RTCDtlsFingerprint {\n constructor(public algorithm: string, public value: string) {}\n}\n\nexport class RTCDtlsParameters {\n constructor(\n public fingerprints: RTCDtlsFingerprint[] = [],\n public role: \"auto\" | \"client\" | \"server\"\n ) {}\n}\n\nclass IceTransport implements Transport {\n constructor(private ice: Connection) {\n ice.onData.subscribe((buf) => {\n if (isDtls(buf)) {\n if (this.onData) this.onData(buf);\n }\n });\n }\n onData?: (buf: Buffer) => void;\n\n readonly send = this.ice.send;\n\n close() {\n this.ice.close();\n }\n}\n\nconst createIceTransport = (ice: Connection) => new IceTransport(ice);\n"]}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@ import { createSocket } from "dgram";
|
|
|
3
3
|
import { setImmediate } from "timers/promises";
|
|
4
4
|
import { v4 } from "uuid";
|
|
5
5
|
|
|
6
|
-
import { randomPort } from "../../../
|
|
6
|
+
import { randomPort } from "../../../common/src";
|
|
7
7
|
import { RtpPacket } from "../../../rtp/src";
|
|
8
8
|
import { MediaStreamTrack } from "../media/track";
|
|
9
9
|
|
package/src/transport/dtls.ts
CHANGED
|
@@ -199,18 +199,14 @@ export class RTCDtlsTransport {
|
|
|
199
199
|
|
|
200
200
|
async sendRtp(payload: Buffer, header: RtpHeader) {
|
|
201
201
|
const enc = this.srtp.encrypt(payload, header);
|
|
202
|
-
await this.iceTransport.connection.send(enc).catch((err: Error) => {
|
|
203
|
-
log("sendRtp failed", err.message);
|
|
204
|
-
});
|
|
202
|
+
await this.iceTransport.connection.send(enc).catch((err: Error) => {});
|
|
205
203
|
return enc.length;
|
|
206
204
|
}
|
|
207
205
|
|
|
208
206
|
async sendRtcp(packets: RtcpPacket[]) {
|
|
209
207
|
const payload = Buffer.concat(packets.map((packet) => packet.serialize()));
|
|
210
208
|
const enc = this.srtcp.encrypt(payload);
|
|
211
|
-
await this.iceTransport.connection.send(enc).catch((err: Error) => {
|
|
212
|
-
log("sendRtcp failed", err.message);
|
|
213
|
-
});
|
|
209
|
+
await this.iceTransport.connection.send(enc).catch((err: Error) => {});
|
|
214
210
|
}
|
|
215
211
|
|
|
216
212
|
private setState(state: DtlsState) {
|