werift 0.14.0 → 0.14.2-debug1

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 (61) hide show
  1. package/lib/common/src/binary.d.ts +10 -0
  2. package/lib/common/src/binary.js +83 -1
  3. package/lib/common/src/binary.js.map +1 -1
  4. package/lib/dtls/src/context/cipher.d.ts +1 -2
  5. package/lib/dtls/src/context/cipher.js +69 -68
  6. package/lib/dtls/src/context/cipher.js.map +1 -1
  7. package/lib/ice/src/ice.js +10 -4
  8. package/lib/ice/src/ice.js.map +1 -1
  9. package/lib/rtp/src/index.d.ts +12 -9
  10. package/lib/rtp/src/index.js +12 -18
  11. package/lib/rtp/src/index.js.map +1 -1
  12. package/lib/rtp/src/processor/jitterBuffer.js +1 -1
  13. package/lib/rtp/src/processor/jitterBuffer.js.map +1 -1
  14. package/lib/rtp/src/rtp/red/encoder.d.ts +14 -0
  15. package/lib/rtp/src/rtp/red/encoder.js +40 -0
  16. package/lib/rtp/src/rtp/red/encoder.js.map +1 -0
  17. package/lib/rtp/src/rtp/{red.d.ts → red/packet.d.ts} +5 -5
  18. package/lib/rtp/src/rtp/red/packet.js +115 -0
  19. package/lib/rtp/src/rtp/red/packet.js.map +1 -0
  20. package/lib/rtp/src/rtp/rtp.d.ts +1 -1
  21. package/lib/rtp/src/rtp/rtp.js +1 -1
  22. package/lib/rtp/src/rtp/rtp.js.map +1 -1
  23. package/lib/sctp/src/sctp.d.ts +2 -1
  24. package/lib/sctp/src/sctp.js +4 -2
  25. package/lib/sctp/src/sctp.js.map +1 -1
  26. package/lib/webrtc/src/const.d.ts +2 -0
  27. package/lib/webrtc/src/const.js +3 -1
  28. package/lib/webrtc/src/const.js.map +1 -1
  29. package/lib/webrtc/src/index.d.ts +1 -0
  30. package/lib/webrtc/src/index.js +1 -0
  31. package/lib/webrtc/src/index.js.map +1 -1
  32. package/lib/webrtc/src/media/receiver/red.js +8 -6
  33. package/lib/webrtc/src/media/receiver/red.js.map +1 -1
  34. package/lib/webrtc/src/media/rtpSender.d.ts +8 -6
  35. package/lib/webrtc/src/media/rtpSender.js +16 -25
  36. package/lib/webrtc/src/media/rtpSender.js.map +1 -1
  37. package/lib/webrtc/src/peerConnection.d.ts +9 -3
  38. package/lib/webrtc/src/peerConnection.js +17 -4
  39. package/lib/webrtc/src/peerConnection.js.map +1 -1
  40. package/lib/webrtc/src/sdp.js +2 -1
  41. package/lib/webrtc/src/sdp.js.map +1 -1
  42. package/lib/webrtc/src/transport/dtls.d.ts +5 -0
  43. package/lib/webrtc/src/transport/dtls.js.map +1 -1
  44. package/lib/webrtc/src/transport/sctp.d.ts +1 -0
  45. package/lib/webrtc/src/transport/sctp.js +5 -1
  46. package/lib/webrtc/src/transport/sctp.js.map +1 -1
  47. package/lib/webrtc/src/utils.d.ts +10 -0
  48. package/lib/webrtc/src/utils.js +8 -1
  49. package/lib/webrtc/src/utils.js.map +1 -1
  50. package/package.json +2 -1
  51. package/src/const.ts +6 -0
  52. package/src/index.ts +1 -0
  53. package/src/media/receiver/red.ts +11 -12
  54. package/src/media/rtpSender.ts +19 -42
  55. package/src/peerConnection.ts +28 -8
  56. package/src/sdp.ts +2 -1
  57. package/src/transport/dtls.ts +6 -0
  58. package/src/transport/sctp.ts +6 -1
  59. package/src/utils.ts +9 -0
  60. package/lib/rtp/src/rtp/red.js +0 -104
  61. package/lib/rtp/src/rtp/red.js.map +0 -1
@@ -1 +1 @@
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\";\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 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 private 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 }\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 sendRtp(payload: Buffer, header: RtpHeader) {\n const enc = this.srtp.encrypt(payload, header);\n this.iceTransport.connection.send(enc);\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 try {\n await this.iceTransport.connection.send(enc);\n } catch (error) {\n throw new Error(\"ice\");\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 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\";\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 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 private 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 }\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 sendRtp(payload: Buffer, header: RtpHeader) {\n const enc = this.srtp.encrypt(payload, header);\n this.iceTransport.connection.send(enc);\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 try {\n await this.iceTransport.connection.send(enc);\n } catch (error) {\n throw new Error(\"ice\");\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"]}
@@ -25,6 +25,7 @@ export declare class RTCSctpTransport {
25
25
  private dataChannelFlush;
26
26
  datachannelSend: (channel: RTCDataChannel, data: Buffer | string) => void;
27
27
  static getCapabilities(): RTCSctpCapabilities;
28
+ setRemotePort(port: number): void;
28
29
  start(remotePort: number): Promise<void>;
29
30
  stop(): Promise<void>;
30
31
  dataChannelClose(channel: RTCDataChannel): void;
@@ -259,6 +259,9 @@ class RTCSctpTransport {
259
259
  static getCapabilities() {
260
260
  return new RTCSctpCapabilities(65536);
261
261
  }
262
+ setRemotePort(port) {
263
+ this.sctp.setRemotePort(port);
264
+ }
262
265
  async start(remotePort) {
263
266
  if (this.isServer) {
264
267
  this.dataChannelId = 0;
@@ -267,7 +270,8 @@ class RTCSctpTransport {
267
270
  this.dataChannelId = 1;
268
271
  }
269
272
  this.sctp.isServer = this.isServer;
270
- await this.sctp.start(remotePort);
273
+ this.setRemotePort(remotePort);
274
+ await this.sctp.start();
271
275
  }
272
276
  async stop() {
273
277
  this.dtlsTransport.dataReceiver = () => { };
@@ -1 +1 @@
1
- {"version":3,"file":"sctp.js","sourceRoot":"","sources":["../../../../src/transport/sctp.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\nimport { jspack } from \"jspack\";\nimport { Event } from \"rx.mini\";\nimport * as uuid from \"uuid\";\n\nimport { SCTP, SCTP_STATE, Transport } from \"../../../sctp/src\";\nimport {\n DATA_CHANNEL_ACK,\n DATA_CHANNEL_OPEN,\n DATA_CHANNEL_RELIABLE,\n WEBRTC_BINARY,\n WEBRTC_BINARY_EMPTY,\n WEBRTC_DCEP,\n WEBRTC_STRING,\n WEBRTC_STRING_EMPTY,\n} from \"../const\";\nimport {\n DCState,\n RTCDataChannel,\n RTCDataChannelParameters,\n} from \"../dataChannel\";\nimport { RTCDtlsTransport } from \"./dtls\";\n\nconst log = debug(\"werift/webrtc/transport/sctp\");\n\nexport class RTCSctpTransport {\n readonly onDataChannel = new Event<[RTCDataChannel]>();\n readonly uuid = uuid.v4();\n readonly sctp = new SCTP(new BridgeDtls(this.dtlsTransport), this.port);\n mid?: string;\n bundled = false;\n dataChannels: { [key: number]: RTCDataChannel } = {};\n\n private dataChannelQueue: [RTCDataChannel, number, Buffer][] = [];\n private dataChannelId?: number;\n\n constructor(public dtlsTransport: RTCDtlsTransport, public port = 5000) {\n this.sctp.onReceive.subscribe(this.datachannelReceive);\n this.sctp.onReconfigStreams.subscribe((ids: number[]) => {\n ids.forEach((id) => {\n const dc = this.dataChannels[id];\n if (!dc) return;\n // todo fix\n dc.setReadyState(\"closing\");\n dc.setReadyState(\"closed\");\n delete this.dataChannels[id];\n });\n });\n this.sctp.stateChanged.connected.subscribe(() => {\n Object.values(this.dataChannels).forEach((channel) => {\n if (channel.negotiated && channel.readyState !== \"open\") {\n channel.setReadyState(\"open\");\n }\n });\n this.dataChannelFlush();\n });\n this.sctp.stateChanged.closed.subscribe(() => {\n Object.values(this.dataChannels).forEach((dc) => {\n dc.setReadyState(\"closed\");\n });\n this.dataChannels = {};\n });\n this.sctp.onSackReceived = async () => {\n await this.dataChannelFlush();\n };\n\n this.dtlsTransport.onStateChange.subscribe((state) => {\n if (state === \"closed\") {\n this.sctp.setState(SCTP_STATE.CLOSED);\n }\n });\n }\n\n private get isServer() {\n return this.dtlsTransport.iceTransport.role !== \"controlling\";\n }\n\n channelByLabel(label: string) {\n return Object.values(this.dataChannels).find((d) => d.label === label);\n }\n\n private datachannelReceive = async (\n streamId: number,\n ppId: number,\n data: Buffer\n ) => {\n if (ppId === WEBRTC_DCEP && data.length > 0) {\n log(\"DCEP\", streamId, ppId, data);\n switch (data[0]) {\n case DATA_CHANNEL_OPEN:\n {\n if (data.length >= 12) {\n if (Object.keys(this.dataChannels).includes(streamId.toString()))\n throw new Error();\n\n const [\n ,\n channelType,\n ,\n reliability,\n labelLength,\n protocolLength,\n ] = jspack.Unpack(\"!BBHLHH\", data);\n\n let pos = 12;\n const label = data.slice(pos, pos + labelLength).toString(\"utf8\");\n pos += labelLength;\n const protocol = data\n .slice(pos, pos + protocolLength)\n .toString(\"utf8\");\n\n log(\"DATA_CHANNEL_OPEN\", {\n channelType,\n reliability,\n streamId,\n label,\n protocol,\n });\n\n const maxRetransmits =\n (channelType & 0x03) === 1 ? reliability : undefined;\n const maxPacketLifeTime =\n (channelType & 0x03) === 2 ? reliability : undefined;\n\n // # register channel\n const parameters = new RTCDataChannelParameters({\n label,\n ordered: (channelType & 0x80) === 0,\n maxPacketLifeTime,\n maxRetransmits,\n protocol,\n id: streamId,\n });\n const channel = new RTCDataChannel(this, parameters, false);\n channel.isCreatedByRemote = true;\n this.dataChannels[streamId] = channel;\n\n this.dataChannelQueue.push([\n channel,\n WEBRTC_DCEP,\n Buffer.from(jspack.Pack(\"!B\", [DATA_CHANNEL_ACK])),\n ]);\n\n this.onDataChannel.execute(channel);\n channel.setReadyState(\"open\");\n\n await this.dataChannelFlush();\n }\n }\n break;\n case DATA_CHANNEL_ACK:\n log(\"DATA_CHANNEL_ACK\");\n const channel = this.dataChannels[streamId];\n if (!channel) throw new Error();\n channel.setReadyState(\"open\");\n break;\n }\n } else {\n const channel = this.dataChannels[streamId];\n if (channel) {\n const msg = (() => {\n switch (ppId) {\n case WEBRTC_STRING:\n return data.toString(\"utf8\");\n case WEBRTC_STRING_EMPTY:\n return \"\";\n case WEBRTC_BINARY:\n return data;\n case WEBRTC_BINARY_EMPTY:\n return Buffer.from([]);\n default:\n throw new Error();\n }\n })();\n channel.message.execute(msg);\n channel.emit(\"message\", { data: msg });\n if (channel.onmessage) channel.onmessage({ data: msg });\n }\n }\n };\n\n dataChannelAddNegotiated(channel: RTCDataChannel) {\n if (channel.id == undefined) {\n throw new Error();\n }\n if (this.dataChannels[channel.id]) {\n throw new Error();\n }\n\n this.dataChannels[channel.id] = channel;\n\n if (this.sctp.associationState === SCTP_STATE.ESTABLISHED) {\n channel.setReadyState(\"open\");\n }\n }\n\n dataChannelOpen(channel: RTCDataChannel) {\n if (channel.id) {\n if (this.dataChannels[channel.id])\n throw new Error(\n `Data channel with ID ${channel.id} already registered`\n );\n this.dataChannels[channel.id] = channel;\n }\n\n let channelType = DATA_CHANNEL_RELIABLE;\n const priority = 0;\n let reliability = 0;\n\n if (!channel.ordered) {\n channelType = 0x80;\n }\n if (channel.maxRetransmits) {\n channelType = 1;\n reliability = channel.maxRetransmits;\n } else if (channel.maxPacketLifeTime) {\n channelType = 2;\n reliability = channel.maxPacketLifeTime;\n }\n\n // 5.1. DATA_CHANNEL_OPEN Message\n const data = jspack.Pack(\"!BBHLHH\", [\n DATA_CHANNEL_OPEN,\n channelType,\n priority,\n reliability,\n channel.label.length,\n channel.protocol.length,\n ]);\n const send = Buffer.concat([\n Buffer.from(data),\n Buffer.from(channel.label, \"utf8\"),\n Buffer.from(channel.protocol, \"utf8\"),\n ]);\n this.dataChannelQueue.push([channel, WEBRTC_DCEP, send]);\n this.dataChannelFlush();\n }\n\n private async dataChannelFlush() {\n // \"\"\"\n // Try to flush buffered data to the SCTP layer.\n\n // We wait until the association is established, as we need to know\n // whether we are a client or a server to correctly assign an odd/even ID\n // to the data channels.\n // \"\"\"\n\n if (this.sctp.associationState != SCTP_STATE.ESTABLISHED) return;\n if (this.sctp.outboundQueue.length > 0) return;\n\n while (this.dataChannelQueue.length > 0) {\n const [channel, protocol, userData] = this.dataChannelQueue.shift()!;\n\n let streamId = channel.id;\n if (streamId === undefined) {\n streamId = this.dataChannelId!;\n while (Object.keys(this.dataChannels).includes(streamId.toString())) {\n streamId += 2;\n }\n this.dataChannels[streamId] = channel;\n channel.setId(streamId);\n }\n\n if (protocol === WEBRTC_DCEP) {\n await this.sctp.send(streamId, protocol, userData);\n } else {\n const expiry = channel.maxPacketLifeTime\n ? Date.now() + channel.maxPacketLifeTime / 1000\n : undefined;\n\n await this.sctp.send(\n streamId,\n protocol,\n userData,\n expiry,\n channel.maxRetransmits,\n channel.ordered\n );\n channel.addBufferedAmount(-userData.length);\n }\n }\n }\n\n datachannelSend = (channel: RTCDataChannel, data: Buffer | string) => {\n channel.addBufferedAmount(data.length);\n\n this.dataChannelQueue.push(\n typeof data === \"string\"\n ? [channel, WEBRTC_STRING, Buffer.from(data)]\n : [channel, WEBRTC_BINARY, data]\n );\n\n if (this.sctp.associationState !== SCTP_STATE.ESTABLISHED) {\n log(\"sctp not established\", this.sctp.associationState);\n }\n\n this.dataChannelFlush();\n };\n\n static getCapabilities() {\n return new RTCSctpCapabilities(65536);\n }\n\n async start(remotePort: number) {\n if (this.isServer) {\n this.dataChannelId = 0;\n } else {\n this.dataChannelId = 1;\n }\n this.sctp.isServer = this.isServer;\n\n await this.sctp.start(remotePort);\n }\n\n async stop() {\n this.dtlsTransport.dataReceiver = () => {};\n await this.sctp.stop();\n }\n\n dataChannelClose(channel: RTCDataChannel) {\n if (!([\"closing\", \"closed\"] as DCState[]).includes(channel.readyState)) {\n channel.setReadyState(\"closing\");\n\n if (this.sctp.associationState === SCTP_STATE.ESTABLISHED) {\n this.sctp.reconfigQueue.push(channel.id);\n if (this.sctp.reconfigQueue.length === 1) {\n this.sctp.transmitReconfigRequest();\n }\n } else {\n this.dataChannelQueue = this.dataChannelQueue.filter(\n (queueItem) => queueItem[0].id !== channel.id\n );\n if (channel.id) {\n delete this.dataChannels[channel.id];\n }\n channel.setReadyState(\"closed\");\n }\n }\n }\n}\n\nexport class RTCSctpCapabilities {\n constructor(public maxMessageSize: number) {}\n}\n\nclass BridgeDtls implements Transport {\n constructor(private dtls: RTCDtlsTransport) {}\n set onData(onData: (buf: Buffer) => void) {\n this.dtls.dataReceiver = onData;\n }\n readonly send = this.dtls.sendData;\n close() {}\n}\n"]}
1
+ {"version":3,"file":"sctp.js","sourceRoot":"","sources":["../../../../src/transport/sctp.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\nimport { jspack } from \"jspack\";\nimport { Event } from \"rx.mini\";\nimport * as uuid from \"uuid\";\n\nimport { SCTP, SCTP_STATE, Transport } from \"../../../sctp/src\";\nimport {\n DATA_CHANNEL_ACK,\n DATA_CHANNEL_OPEN,\n DATA_CHANNEL_RELIABLE,\n WEBRTC_BINARY,\n WEBRTC_BINARY_EMPTY,\n WEBRTC_DCEP,\n WEBRTC_STRING,\n WEBRTC_STRING_EMPTY,\n} from \"../const\";\nimport {\n DCState,\n RTCDataChannel,\n RTCDataChannelParameters,\n} from \"../dataChannel\";\nimport { RTCDtlsTransport } from \"./dtls\";\n\nconst log = debug(\"werift/webrtc/transport/sctp\");\n\nexport class RTCSctpTransport {\n readonly onDataChannel = new Event<[RTCDataChannel]>();\n readonly uuid = uuid.v4();\n readonly sctp = new SCTP(new BridgeDtls(this.dtlsTransport), this.port);\n mid?: string;\n bundled = false;\n dataChannels: { [key: number]: RTCDataChannel } = {};\n\n private dataChannelQueue: [RTCDataChannel, number, Buffer][] = [];\n private dataChannelId?: number;\n\n constructor(public dtlsTransport: RTCDtlsTransport, public port = 5000) {\n this.sctp.onReceive.subscribe(this.datachannelReceive);\n this.sctp.onReconfigStreams.subscribe((ids: number[]) => {\n ids.forEach((id) => {\n const dc = this.dataChannels[id];\n if (!dc) return;\n // todo fix\n dc.setReadyState(\"closing\");\n dc.setReadyState(\"closed\");\n delete this.dataChannels[id];\n });\n });\n this.sctp.stateChanged.connected.subscribe(() => {\n Object.values(this.dataChannels).forEach((channel) => {\n if (channel.negotiated && channel.readyState !== \"open\") {\n channel.setReadyState(\"open\");\n }\n });\n this.dataChannelFlush();\n });\n this.sctp.stateChanged.closed.subscribe(() => {\n Object.values(this.dataChannels).forEach((dc) => {\n dc.setReadyState(\"closed\");\n });\n this.dataChannels = {};\n });\n this.sctp.onSackReceived = async () => {\n await this.dataChannelFlush();\n };\n\n this.dtlsTransport.onStateChange.subscribe((state) => {\n if (state === \"closed\") {\n this.sctp.setState(SCTP_STATE.CLOSED);\n }\n });\n }\n\n private get isServer() {\n return this.dtlsTransport.iceTransport.role !== \"controlling\";\n }\n\n channelByLabel(label: string) {\n return Object.values(this.dataChannels).find((d) => d.label === label);\n }\n\n private datachannelReceive = async (\n streamId: number,\n ppId: number,\n data: Buffer\n ) => {\n if (ppId === WEBRTC_DCEP && data.length > 0) {\n log(\"DCEP\", streamId, ppId, data);\n switch (data[0]) {\n case DATA_CHANNEL_OPEN:\n {\n if (data.length >= 12) {\n if (Object.keys(this.dataChannels).includes(streamId.toString()))\n throw new Error();\n\n const [\n ,\n channelType,\n ,\n reliability,\n labelLength,\n protocolLength,\n ] = jspack.Unpack(\"!BBHLHH\", data);\n\n let pos = 12;\n const label = data.slice(pos, pos + labelLength).toString(\"utf8\");\n pos += labelLength;\n const protocol = data\n .slice(pos, pos + protocolLength)\n .toString(\"utf8\");\n\n log(\"DATA_CHANNEL_OPEN\", {\n channelType,\n reliability,\n streamId,\n label,\n protocol,\n });\n\n const maxRetransmits =\n (channelType & 0x03) === 1 ? reliability : undefined;\n const maxPacketLifeTime =\n (channelType & 0x03) === 2 ? reliability : undefined;\n\n // # register channel\n const parameters = new RTCDataChannelParameters({\n label,\n ordered: (channelType & 0x80) === 0,\n maxPacketLifeTime,\n maxRetransmits,\n protocol,\n id: streamId,\n });\n const channel = new RTCDataChannel(this, parameters, false);\n channel.isCreatedByRemote = true;\n this.dataChannels[streamId] = channel;\n\n this.dataChannelQueue.push([\n channel,\n WEBRTC_DCEP,\n Buffer.from(jspack.Pack(\"!B\", [DATA_CHANNEL_ACK])),\n ]);\n\n this.onDataChannel.execute(channel);\n channel.setReadyState(\"open\");\n\n await this.dataChannelFlush();\n }\n }\n break;\n case DATA_CHANNEL_ACK:\n log(\"DATA_CHANNEL_ACK\");\n const channel = this.dataChannels[streamId];\n if (!channel) throw new Error();\n channel.setReadyState(\"open\");\n break;\n }\n } else {\n const channel = this.dataChannels[streamId];\n if (channel) {\n const msg = (() => {\n switch (ppId) {\n case WEBRTC_STRING:\n return data.toString(\"utf8\");\n case WEBRTC_STRING_EMPTY:\n return \"\";\n case WEBRTC_BINARY:\n return data;\n case WEBRTC_BINARY_EMPTY:\n return Buffer.from([]);\n default:\n throw new Error();\n }\n })();\n channel.message.execute(msg);\n channel.emit(\"message\", { data: msg });\n if (channel.onmessage) channel.onmessage({ data: msg });\n }\n }\n };\n\n dataChannelAddNegotiated(channel: RTCDataChannel) {\n if (channel.id == undefined) {\n throw new Error();\n }\n if (this.dataChannels[channel.id]) {\n throw new Error();\n }\n\n this.dataChannels[channel.id] = channel;\n\n if (this.sctp.associationState === SCTP_STATE.ESTABLISHED) {\n channel.setReadyState(\"open\");\n }\n }\n\n dataChannelOpen(channel: RTCDataChannel) {\n if (channel.id) {\n if (this.dataChannels[channel.id])\n throw new Error(\n `Data channel with ID ${channel.id} already registered`\n );\n this.dataChannels[channel.id] = channel;\n }\n\n let channelType = DATA_CHANNEL_RELIABLE;\n const priority = 0;\n let reliability = 0;\n\n if (!channel.ordered) {\n channelType = 0x80;\n }\n if (channel.maxRetransmits) {\n channelType = 1;\n reliability = channel.maxRetransmits;\n } else if (channel.maxPacketLifeTime) {\n channelType = 2;\n reliability = channel.maxPacketLifeTime;\n }\n\n // 5.1. DATA_CHANNEL_OPEN Message\n const data = jspack.Pack(\"!BBHLHH\", [\n DATA_CHANNEL_OPEN,\n channelType,\n priority,\n reliability,\n channel.label.length,\n channel.protocol.length,\n ]);\n const send = Buffer.concat([\n Buffer.from(data),\n Buffer.from(channel.label, \"utf8\"),\n Buffer.from(channel.protocol, \"utf8\"),\n ]);\n this.dataChannelQueue.push([channel, WEBRTC_DCEP, send]);\n this.dataChannelFlush();\n }\n\n private async dataChannelFlush() {\n // \"\"\"\n // Try to flush buffered data to the SCTP layer.\n\n // We wait until the association is established, as we need to know\n // whether we are a client or a server to correctly assign an odd/even ID\n // to the data channels.\n // \"\"\"\n\n if (this.sctp.associationState != SCTP_STATE.ESTABLISHED) return;\n if (this.sctp.outboundQueue.length > 0) return;\n\n while (this.dataChannelQueue.length > 0) {\n const [channel, protocol, userData] = this.dataChannelQueue.shift()!;\n\n let streamId = channel.id;\n if (streamId === undefined) {\n streamId = this.dataChannelId!;\n while (Object.keys(this.dataChannels).includes(streamId.toString())) {\n streamId += 2;\n }\n this.dataChannels[streamId] = channel;\n channel.setId(streamId);\n }\n\n if (protocol === WEBRTC_DCEP) {\n await this.sctp.send(streamId, protocol, userData);\n } else {\n const expiry = channel.maxPacketLifeTime\n ? Date.now() + channel.maxPacketLifeTime / 1000\n : undefined;\n\n await this.sctp.send(\n streamId,\n protocol,\n userData,\n expiry,\n channel.maxRetransmits,\n channel.ordered\n );\n channel.addBufferedAmount(-userData.length);\n }\n }\n }\n\n datachannelSend = (channel: RTCDataChannel, data: Buffer | string) => {\n channel.addBufferedAmount(data.length);\n\n this.dataChannelQueue.push(\n typeof data === \"string\"\n ? [channel, WEBRTC_STRING, Buffer.from(data)]\n : [channel, WEBRTC_BINARY, data]\n );\n\n if (this.sctp.associationState !== SCTP_STATE.ESTABLISHED) {\n log(\"sctp not established\", this.sctp.associationState);\n }\n\n this.dataChannelFlush();\n };\n\n static getCapabilities() {\n return new RTCSctpCapabilities(65536);\n }\n\n setRemotePort(port: number) {\n this.sctp.setRemotePort(port);\n }\n\n async start(remotePort: number) {\n if (this.isServer) {\n this.dataChannelId = 0;\n } else {\n this.dataChannelId = 1;\n }\n this.sctp.isServer = this.isServer;\n\n this.setRemotePort(remotePort);\n await this.sctp.start();\n }\n\n async stop() {\n this.dtlsTransport.dataReceiver = () => {};\n await this.sctp.stop();\n }\n\n dataChannelClose(channel: RTCDataChannel) {\n if (!([\"closing\", \"closed\"] as DCState[]).includes(channel.readyState)) {\n channel.setReadyState(\"closing\");\n\n if (this.sctp.associationState === SCTP_STATE.ESTABLISHED) {\n this.sctp.reconfigQueue.push(channel.id);\n if (this.sctp.reconfigQueue.length === 1) {\n this.sctp.transmitReconfigRequest();\n }\n } else {\n this.dataChannelQueue = this.dataChannelQueue.filter(\n (queueItem) => queueItem[0].id !== channel.id\n );\n if (channel.id) {\n delete this.dataChannels[channel.id];\n }\n channel.setReadyState(\"closed\");\n }\n }\n }\n}\n\nexport class RTCSctpCapabilities {\n constructor(public maxMessageSize: number) {}\n}\n\nclass BridgeDtls implements Transport {\n constructor(private dtls: RTCDtlsTransport) {}\n set onData(onData: (buf: Buffer) => void) {\n this.dtls.dataReceiver = onData;\n }\n readonly send = this.dtls.sendData;\n close() {}\n}\n"]}
@@ -27,3 +27,13 @@ export declare class RtpBuilder {
27
27
  timestamp: number;
28
28
  create(payload: Buffer): RtpPacket;
29
29
  }
30
+ /**
31
+ *
32
+ * @param signatureHash
33
+ * @param namedCurveAlgorithm necessary when use ecdsa
34
+ */
35
+ export declare const createSelfSignedCertificate: (signatureHash: import(".").SignatureHash, namedCurveAlgorithm?: import(".").NamedCurveAlgorithms | undefined) => Promise<{
36
+ certPem: string;
37
+ keyPem: string;
38
+ signatureHash: import(".").SignatureHash;
39
+ }>;
@@ -3,12 +3,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.RtpBuilder = exports.parseIceServers = exports.compactNtp = exports.ntpTime = exports.milliTime = exports.microTime = exports.reverseDirection = exports.orDirection = exports.andDirection = exports.reverseSimulcastDirection = exports.isRtcp = exports.isMedia = exports.isDtls = exports.fingerprint = void 0;
6
+ exports.createSelfSignedCertificate = exports.RtpBuilder = exports.parseIceServers = exports.compactNtp = exports.ntpTime = exports.milliTime = exports.microTime = exports.reverseDirection = exports.orDirection = exports.andDirection = exports.reverseSimulcastDirection = exports.isRtcp = exports.isMedia = exports.isDtls = exports.fingerprint = void 0;
7
7
  /* eslint-disable prefer-const */
8
8
  const crypto_1 = require("crypto");
9
9
  const debug_1 = __importDefault(require("debug"));
10
10
  const perf_hooks_1 = require("perf_hooks");
11
11
  const src_1 = require("../../common/src");
12
+ const cipher_1 = require("../../dtls/src/context/cipher");
12
13
  const src_2 = require("../../rtp/src");
13
14
  const rtpTransceiver_1 = require("./media/rtpTransceiver");
14
15
  const now = require("nano-time");
@@ -113,4 +114,10 @@ class RtpBuilder {
113
114
  }
114
115
  }
115
116
  exports.RtpBuilder = RtpBuilder;
117
+ /**
118
+ *
119
+ * @param signatureHash
120
+ * @param namedCurveAlgorithm necessary when use ecdsa
121
+ */
122
+ exports.createSelfSignedCertificate = cipher_1.CipherContext.createSelfSignedCertificateWithKey;
116
123
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable prefer-const */\nimport { createHash } from \"crypto\";\nimport debug from \"debug\";\nimport { performance } from \"perf_hooks\";\n\nimport {\n bufferReader,\n bufferWriter,\n random16,\n random32,\n uint16Add,\n uint32Add,\n} from \"../../common/src\";\nimport { Address } from \"../../ice/src\";\nimport { RtpHeader, RtpPacket } from \"../../rtp/src\";\nimport { Direction, Directions } from \"./media/rtpTransceiver\";\nimport { RTCIceServer } from \"./peerConnection\";\nconst now = require(\"nano-time\");\n\nconst log = debug(\"werift/webrtc/utils\");\n\nexport function fingerprint(file: Buffer, hashName: string) {\n const upper = (s: string) => s.toUpperCase();\n const colon = (s: any) => s.match(/(.{2})/g).join(\":\");\n\n const hash = createHash(hashName).update(file).digest(\"hex\");\n\n return colon(upper(hash));\n}\n\nexport function isDtls(buf: Buffer) {\n const firstByte = buf[0];\n return firstByte > 19 && firstByte < 64;\n}\n\nexport function isMedia(buf: Buffer) {\n const firstByte = buf[0];\n return firstByte > 127 && firstByte < 192;\n}\n\nexport function isRtcp(buf: Buffer) {\n return buf.length >= 2 && buf[1] >= 192 && buf[1] <= 208;\n}\n\nexport function reverseSimulcastDirection(dir: \"recv\" | \"send\") {\n if (dir === \"recv\") return \"send\";\n return \"recv\";\n}\n\nexport const andDirection = (a: Direction, b: Direction) =>\n Directions[Directions.indexOf(a) & Directions.indexOf(b)];\n\nexport const orDirection = (a: Direction, b: Direction) =>\n Directions[Directions.indexOf(a) & Directions.indexOf(b)];\n\nexport function reverseDirection(dir: Direction): Direction {\n if (dir === \"sendonly\") return \"recvonly\";\n if (dir === \"recvonly\") return \"sendonly\";\n return dir;\n}\n\nexport const microTime = () => now.micro() as number;\n\nexport const milliTime = () => new Date().getTime();\n\n/**https://datatracker.ietf.org/doc/html/rfc3550#section-4 */\nexport const ntpTime = () => {\n const now = performance.timeOrigin + performance.now() - Date.UTC(1900, 0, 1);\n\n const seconds = now / 1000;\n const [sec, msec] = seconds.toString().split(\".\").map(Number);\n\n const buf = bufferWriter([4, 4], [sec, msec]);\n\n return buf.readBigUInt64BE();\n};\n\n/**https://datatracker.ietf.org/doc/html/rfc3550#section-4 */\nexport const compactNtp = (ntp: bigint) => {\n const buf = bufferWriter([8], [ntp]);\n const [, sec, msec] = bufferReader(buf, [2, 2, 2, 2]);\n return bufferWriter([2, 2], [sec, msec]).readUInt32BE();\n};\n\nexport function parseIceServers(iceServers: RTCIceServer[]) {\n const url2Address = (url?: string) => {\n if (!url) return;\n const [address, port] = url.split(\":\");\n return [address, parseInt(port)] as Address;\n };\n\n const stunServer = url2Address(\n iceServers.find(({ urls }) => urls.includes(\"stun:\"))?.urls.slice(5)\n );\n const turnServer = url2Address(\n iceServers.find(({ urls }) => urls.includes(\"turn:\"))?.urls.slice(5)\n );\n const { credential, username } =\n iceServers.find(({ urls }) => urls.includes(\"turn:\")) || {};\n\n const options = {\n stunServer,\n turnServer,\n turnUsername: username,\n turnPassword: credential,\n };\n log(\"iceOptions\", options);\n return options;\n}\n\nexport class RtpBuilder {\n sequenceNumber = random16();\n timestamp = random32();\n\n create(payload: Buffer) {\n this.sequenceNumber = uint16Add(this.sequenceNumber, 1);\n this.timestamp = uint32Add(this.timestamp, 960);\n\n const header = new RtpHeader({\n sequenceNumber: this.sequenceNumber,\n timestamp: Number(this.timestamp),\n payloadType: 96,\n extension: true,\n marker: false,\n padding: false,\n });\n const rtp = new RtpPacket(header, payload);\n return rtp;\n }\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable prefer-const */\nimport { createHash } from \"crypto\";\nimport debug from \"debug\";\nimport { performance } from \"perf_hooks\";\n\nimport {\n bufferReader,\n bufferWriter,\n random16,\n random32,\n uint16Add,\n uint32Add,\n} from \"../../common/src\";\nimport { CipherContext } from \"../../dtls/src/context/cipher\";\nimport { Address } from \"../../ice/src\";\nimport { RtpHeader, RtpPacket } from \"../../rtp/src\";\nimport { Direction, Directions } from \"./media/rtpTransceiver\";\nimport { RTCIceServer } from \"./peerConnection\";\nconst now = require(\"nano-time\");\n\nconst log = debug(\"werift/webrtc/utils\");\n\nexport function fingerprint(file: Buffer, hashName: string) {\n const upper = (s: string) => s.toUpperCase();\n const colon = (s: any) => s.match(/(.{2})/g).join(\":\");\n\n const hash = createHash(hashName).update(file).digest(\"hex\");\n\n return colon(upper(hash));\n}\n\nexport function isDtls(buf: Buffer) {\n const firstByte = buf[0];\n return firstByte > 19 && firstByte < 64;\n}\n\nexport function isMedia(buf: Buffer) {\n const firstByte = buf[0];\n return firstByte > 127 && firstByte < 192;\n}\n\nexport function isRtcp(buf: Buffer) {\n return buf.length >= 2 && buf[1] >= 192 && buf[1] <= 208;\n}\n\nexport function reverseSimulcastDirection(dir: \"recv\" | \"send\") {\n if (dir === \"recv\") return \"send\";\n return \"recv\";\n}\n\nexport const andDirection = (a: Direction, b: Direction) =>\n Directions[Directions.indexOf(a) & Directions.indexOf(b)];\n\nexport const orDirection = (a: Direction, b: Direction) =>\n Directions[Directions.indexOf(a) & Directions.indexOf(b)];\n\nexport function reverseDirection(dir: Direction): Direction {\n if (dir === \"sendonly\") return \"recvonly\";\n if (dir === \"recvonly\") return \"sendonly\";\n return dir;\n}\n\nexport const microTime = () => now.micro() as number;\n\nexport const milliTime = () => new Date().getTime();\n\n/**https://datatracker.ietf.org/doc/html/rfc3550#section-4 */\nexport const ntpTime = () => {\n const now = performance.timeOrigin + performance.now() - Date.UTC(1900, 0, 1);\n\n const seconds = now / 1000;\n const [sec, msec] = seconds.toString().split(\".\").map(Number);\n\n const buf = bufferWriter([4, 4], [sec, msec]);\n\n return buf.readBigUInt64BE();\n};\n\n/**https://datatracker.ietf.org/doc/html/rfc3550#section-4 */\nexport const compactNtp = (ntp: bigint) => {\n const buf = bufferWriter([8], [ntp]);\n const [, sec, msec] = bufferReader(buf, [2, 2, 2, 2]);\n return bufferWriter([2, 2], [sec, msec]).readUInt32BE();\n};\n\nexport function parseIceServers(iceServers: RTCIceServer[]) {\n const url2Address = (url?: string) => {\n if (!url) return;\n const [address, port] = url.split(\":\");\n return [address, parseInt(port)] as Address;\n };\n\n const stunServer = url2Address(\n iceServers.find(({ urls }) => urls.includes(\"stun:\"))?.urls.slice(5)\n );\n const turnServer = url2Address(\n iceServers.find(({ urls }) => urls.includes(\"turn:\"))?.urls.slice(5)\n );\n const { credential, username } =\n iceServers.find(({ urls }) => urls.includes(\"turn:\")) || {};\n\n const options = {\n stunServer,\n turnServer,\n turnUsername: username,\n turnPassword: credential,\n };\n log(\"iceOptions\", options);\n return options;\n}\n\nexport class RtpBuilder {\n sequenceNumber = random16();\n timestamp = random32();\n\n create(payload: Buffer) {\n this.sequenceNumber = uint16Add(this.sequenceNumber, 1);\n this.timestamp = uint32Add(this.timestamp, 960);\n\n const header = new RtpHeader({\n sequenceNumber: this.sequenceNumber,\n timestamp: Number(this.timestamp),\n payloadType: 96,\n extension: true,\n marker: false,\n padding: false,\n });\n const rtp = new RtpPacket(header, payload);\n return rtp;\n }\n}\n\n/**\n *\n * @param signatureHash\n * @param namedCurveAlgorithm necessary when use ecdsa\n */\nexport const createSelfSignedCertificate =\n CipherContext.createSelfSignedCertificateWithKey;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "werift",
3
- "version": "0.14.0",
3
+ "version": "0.14.2-debug1",
4
4
  "description": "WebRTC Implementation for TypeScript (Node.js)",
5
5
  "keywords": [
6
6
  "WebRTC",
@@ -28,6 +28,7 @@
28
28
  "format": "yarn unused && yarn lint && prettier --write src/**/*.ts",
29
29
  "lint": "eslint ./src --fix",
30
30
  "publish:tag": "yarn publish --tag maintain-dtls",
31
+ "deploy": "yarn build && yarn publish",
31
32
  "test": "npm run type && jest --runInBand --forceExit --coverage",
32
33
  "type": "tsc --noEmit --project ./tsconfig.json",
33
34
  "unused": "organize-imports-cli src/**/*.ts"
package/src/const.ts CHANGED
@@ -1,3 +1,7 @@
1
+ import {
2
+ HashAlgorithms,
3
+ SignatureAlgorithm,
4
+ } from "../../dtls/src/cipher/const";
1
5
  import {
2
6
  ProtectionProfileAeadAes128Gcm,
3
7
  ProtectionProfileAes128CmHmacSha1_80,
@@ -58,3 +62,5 @@ export const SRTP_PROFILE = {
58
62
 
59
63
  export const SenderDirections = ["sendonly", "sendrecv"];
60
64
  export const NotSenderDirections = ["inactive", "recvonly"];
65
+
66
+ export { HashAlgorithms, SignatureAlgorithm };
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "../../common/src";
2
+ export * from "../../dtls/src/cipher/const";
2
3
  export * from "../../ice/src";
3
4
  export * from "../../rtp/src";
4
5
  export * from "./dataChannel";
@@ -7,7 +7,11 @@ export class RedHandler {
7
7
  push(red: Red, rtp: RtpPacket) {
8
8
  const packets: RtpPacket[] = [];
9
9
 
10
- red.payloads.forEach(({ blockPT, timestampOffset, bin }, i) => {
10
+ red.blocks.forEach(({ blockPT, timestampOffset, block }, i) => {
11
+ const sequenceNumber = uint16Add(
12
+ rtp.header.sequenceNumber,
13
+ -(red.blocks.length - (i + 1))
14
+ );
11
15
  if (timestampOffset) {
12
16
  packets.push(
13
17
  new RtpPacket(
@@ -15,13 +19,10 @@ export class RedHandler {
15
19
  timestamp: uint32Add(rtp.header.timestamp, -timestampOffset),
16
20
  payloadType: blockPT,
17
21
  ssrc: rtp.header.ssrc,
18
- sequenceNumber: uint16Add(
19
- rtp.header.sequenceNumber,
20
- -(red.payloads.length - (i + 1))
21
- ),
22
+ sequenceNumber,
22
23
  marker: true,
23
24
  }),
24
- bin
25
+ block
25
26
  )
26
27
  );
27
28
  } else {
@@ -31,19 +32,16 @@ export class RedHandler {
31
32
  timestamp: rtp.header.timestamp,
32
33
  payloadType: blockPT,
33
34
  ssrc: rtp.header.ssrc,
34
- sequenceNumber: uint16Add(
35
- rtp.header.sequenceNumber,
36
- -(red.payloads.length - (i + 1))
37
- ),
35
+ sequenceNumber,
38
36
  marker: true,
39
37
  }),
40
- bin
38
+ block
41
39
  )
42
40
  );
43
41
  }
44
42
  });
45
43
 
46
- return packets.filter((p) => {
44
+ const filtered = packets.filter((p) => {
47
45
  if (this.sequenceNumbers.includes(p.header.sequenceNumber)) {
48
46
  return false;
49
47
  } else {
@@ -54,5 +52,6 @@ export class RedHandler {
54
52
  return true;
55
53
  }
56
54
  });
55
+ return filtered;
57
56
  }
58
57
  }
@@ -16,7 +16,7 @@ import {
16
16
  GenericNack,
17
17
  PictureLossIndication,
18
18
  ReceiverEstimatedMaxBitrate,
19
- Red,
19
+ RedEncoder,
20
20
  RtcpPacket,
21
21
  RtcpPayloadSpecificFeedback,
22
22
  RtcpRrPacket,
@@ -70,8 +70,9 @@ export class RTCRtpSender {
70
70
  private repairedRtpStreamId?: string;
71
71
  private rtxPayloadType?: number;
72
72
  private rtxSequenceNumber = random16();
73
- private redRedundantPayloadType?: number;
74
- redDistance = 2;
73
+ redRedundantPayloadType?: number;
74
+ private _redDistance = 2;
75
+ redEncoder = new RedEncoder(this._redDistance);
75
76
  private headerExtensions: RTCRtpHeaderExtensionParameters[] = [];
76
77
  private disposeTrack?: () => void;
77
78
 
@@ -91,7 +92,7 @@ export class RTCRtpSender {
91
92
  private timestampOffset = 0;
92
93
  private seqOffset = 0;
93
94
  private rtpCache: RtpPacket[] = [];
94
- private codec?: RTCRtpCodecParameters;
95
+ codec?: RTCRtpCodecParameters;
95
96
 
96
97
  track?: MediaStreamTrack;
97
98
  stopped = false;
@@ -115,6 +116,14 @@ export class RTCRtpSender {
115
116
  }
116
117
  }
117
118
 
119
+ get redDistance() {
120
+ return this._redDistance;
121
+ }
122
+ set redDistance(n: number) {
123
+ this._redDistance = n;
124
+ this.redEncoder.distance = n;
125
+ }
126
+
118
127
  prepareSend(params: RTCRtpSendParameters) {
119
128
  this.cname = params.rtcp?.cname;
120
129
  this.mid = params.muxId;
@@ -327,20 +336,12 @@ export class RTCRtpSender {
327
336
  let rtpPayload = rtp.payload;
328
337
 
329
338
  if (this.redRedundantPayloadType) {
330
- const redundantPackets = [...Array(this.redDistance).keys()]
331
- .map((i) => {
332
- return this.rtpCache.find(
333
- (c) =>
334
- c.header.sequenceNumber ===
335
- header.sequenceNumber - (this.redDistance - i)
336
- );
337
- })
338
- .filter((p): p is NonNullable<typeof p> => typeof p !== "undefined");
339
- const red = buildRedPacket(
340
- redundantPackets,
341
- this.redRedundantPayloadType,
342
- rtp
343
- );
339
+ this.redEncoder.push({
340
+ block: rtpPayload,
341
+ timestamp: header.timestamp,
342
+ blockPT: this.redRedundantPayloadType,
343
+ });
344
+ const red = this.redEncoder.build();
344
345
  rtpPayload = red.serialize();
345
346
  }
346
347
 
@@ -462,27 +463,3 @@ export function wrapRtx(
462
463
  );
463
464
  return rtx;
464
465
  }
465
-
466
- export function buildRedPacket(
467
- redundantPackets: RtpPacket[],
468
- blockPT: number,
469
- presentPacket: RtpPacket
470
- ) {
471
- const red = new Red();
472
- redundantPackets.forEach((redundant) => {
473
- red.payloads.push({
474
- bin: redundant.payload,
475
- blockPT,
476
- timestampOffset: uint32Add(
477
- presentPacket.header.timestamp,
478
- -redundant.header.timestamp
479
- ),
480
- });
481
- });
482
-
483
- red.payloads.push({
484
- bin: presentPacket.payload,
485
- blockPT,
486
- });
487
- return red;
488
- }
@@ -4,7 +4,7 @@ import Event from "rx.mini";
4
4
  import * as uuid from "uuid";
5
5
 
6
6
  import { Profile } from "../../dtls/src/context/srtp";
7
- import { codecParametersFromString } from ".";
7
+ import { codecParametersFromString, DtlsKeys } from ".";
8
8
  import {
9
9
  DISCARD_HOST,
10
10
  DISCARD_PORT,
@@ -97,7 +97,7 @@ export class RTCPeerConnection extends EventTarget {
97
97
 
98
98
  private readonly router = new RtpRouter();
99
99
  private readonly certificates: RTCCertificate[] = [];
100
- private sctpRemotePort?: number;
100
+ sctpRemotePort?: number;
101
101
  private seenMid = new Set<string>();
102
102
  private currentLocalDescription?: SessionDescription;
103
103
  private currentRemoteDescription?: SessionDescription;
@@ -112,6 +112,7 @@ export class RTCPeerConnection extends EventTarget {
112
112
  iceServers,
113
113
  iceTransportPolicy,
114
114
  icePortRange,
115
+ dtls,
115
116
  }: Partial<PeerConfig> = {}) {
116
117
  super();
117
118
 
@@ -159,6 +160,15 @@ export class RTCPeerConnection extends EventTarget {
159
160
  v.id = 1 + i;
160
161
  });
161
162
 
163
+ if (dtls) {
164
+ const { keys } = dtls;
165
+ if (keys) {
166
+ this.certificates.push(
167
+ new RTCCertificate(keys.keyPem, keys.certPem, keys.signatureHash)
168
+ );
169
+ }
170
+ }
171
+
162
172
  this.iceConnectionStateChange.subscribe((state) => {
163
173
  switch (state) {
164
174
  case "disconnected":
@@ -728,16 +738,18 @@ export class RTCPeerConnection extends EventTarget {
728
738
 
729
739
  transceiver.receiver.setupTWCC(remoteMedia.ssrc[0]?.ssrc);
730
740
  } else if (remoteMedia.kind === "application") {
741
+ // # configure sctp
742
+ this.sctpRemotePort = remoteMedia.sctpPort;
731
743
  if (!this.sctpTransport) {
744
+ if (!this.sctpRemotePort) {
745
+ throw new Error("sctpRemotePort not exist");
746
+ }
732
747
  this.sctpTransport = this.createSctpTransport();
748
+ this.sctpTransport.setRemotePort(this.sctpRemotePort);
733
749
  }
734
-
735
750
  if (!this.sctpTransport.mid) {
736
751
  this.sctpTransport.mid = remoteMedia.rtp.muxId;
737
752
  }
738
-
739
- // # configure sctp
740
- this.sctpRemotePort = remoteMedia.sctpPort;
741
753
  }
742
754
 
743
755
  if (remoteMedia.iceParams && remoteMedia.dtlsParams) {
@@ -896,7 +908,7 @@ export class RTCPeerConnection extends EventTarget {
896
908
  return this.transceivers;
897
909
  }
898
910
 
899
- getSenders() {
911
+ getSenders(): RTCRtpSender[] {
900
912
  return this.getTransceivers().map((t) => t.sender);
901
913
  }
902
914
 
@@ -905,7 +917,11 @@ export class RTCPeerConnection extends EventTarget {
905
917
  }
906
918
 
907
919
  // todo fix
908
- addTrack(track: MediaStreamTrack, ms?: MediaStream) {
920
+ addTrack(
921
+ track: MediaStreamTrack,
922
+ /**todo impl */
923
+ ms?: MediaStream
924
+ ) {
909
925
  if (this.isClosed) throw new Error("is closed");
910
926
  if (this.getSenders().find((sender) => sender.track?.uuid === track.uuid)) {
911
927
  throw new Error("track exist");
@@ -1202,6 +1218,9 @@ export interface PeerConfig {
1202
1218
  iceServers: RTCIceServer[];
1203
1219
  /**Minimum port and Maximum port must not be the same value */
1204
1220
  icePortRange: [number, number] | undefined;
1221
+ dtls: Partial<{
1222
+ keys: DtlsKeys;
1223
+ }>;
1205
1224
  }
1206
1225
 
1207
1226
  export const findCodecByMimeType = (
@@ -1252,6 +1271,7 @@ export const defaultPeerConfig: PeerConfig = {
1252
1271
  iceTransportPolicy: "all",
1253
1272
  iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
1254
1273
  icePortRange: undefined,
1274
+ dtls: {},
1255
1275
  };
1256
1276
 
1257
1277
  export interface RTCTrackEvent {
package/src/sdp.ts CHANGED
@@ -223,7 +223,8 @@ export class SessionDescription {
223
223
  case "sctpmap":
224
224
  if (!value) throw new Error();
225
225
  const [formatId, formatDesc] = divide(value, " ");
226
- (currentMedia as any)[attr][parseInt(formatId)] = formatDesc;
226
+ currentMedia.sctpMap[parseInt(formatId)] = formatDesc;
227
+ currentMedia.sctpPort = parseInt(formatId);
227
228
  break;
228
229
  case "sctp-port":
229
230
  if (!value) throw new Error();
@@ -261,6 +261,12 @@ export class RTCCertificate {
261
261
  }
262
262
  }
263
263
 
264
+ export type DtlsKeys = {
265
+ certPem: string;
266
+ keyPem: string;
267
+ signatureHash: SignatureHash;
268
+ };
269
+
264
270
  export class RTCDtlsFingerprint {
265
271
  constructor(public algorithm: string, public value: string) {}
266
272
  }
@@ -301,6 +301,10 @@ export class RTCSctpTransport {
301
301
  return new RTCSctpCapabilities(65536);
302
302
  }
303
303
 
304
+ setRemotePort(port: number) {
305
+ this.sctp.setRemotePort(port);
306
+ }
307
+
304
308
  async start(remotePort: number) {
305
309
  if (this.isServer) {
306
310
  this.dataChannelId = 0;
@@ -309,7 +313,8 @@ export class RTCSctpTransport {
309
313
  }
310
314
  this.sctp.isServer = this.isServer;
311
315
 
312
- await this.sctp.start(remotePort);
316
+ this.setRemotePort(remotePort);
317
+ await this.sctp.start();
313
318
  }
314
319
 
315
320
  async stop() {