werift 0.24.3 → 0.25.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/README.md +116 -113
  2. package/lib/common/src/event.js +2 -1
  3. package/lib/common/src/event.js.map +1 -1
  4. package/lib/common/src/transport.d.ts +22 -2
  5. package/lib/common/src/transport.js +84 -26
  6. package/lib/common/src/transport.js.map +1 -1
  7. package/lib/ice/src/exceptions.d.ts +9 -0
  8. package/lib/ice/src/exceptions.js +23 -1
  9. package/lib/ice/src/exceptions.js.map +1 -1
  10. package/lib/ice/src/ice.d.ts +40 -0
  11. package/lib/ice/src/ice.js +194 -28
  12. package/lib/ice/src/ice.js.map +1 -1
  13. package/lib/ice/src/iceBase.d.ts +26 -0
  14. package/lib/ice/src/iceBase.js.map +1 -1
  15. package/lib/ice/src/stun/const.d.ts +7 -0
  16. package/lib/ice/src/stun/const.js +8 -0
  17. package/lib/ice/src/stun/const.js.map +1 -1
  18. package/lib/ice/src/stun/protocol.js +1 -4
  19. package/lib/ice/src/stun/protocol.js.map +1 -1
  20. package/lib/ice/src/stun/tcpProtocol.d.ts +7 -1
  21. package/lib/ice/src/stun/tcpProtocol.js +65 -14
  22. package/lib/ice/src/stun/tcpProtocol.js.map +1 -1
  23. package/lib/ice/src/stun/transaction.d.ts +12 -1
  24. package/lib/ice/src/stun/transaction.js +37 -4
  25. package/lib/ice/src/stun/transaction.js.map +1 -1
  26. package/lib/ice/src/turn/protocol.d.ts +79 -22
  27. package/lib/ice/src/turn/protocol.js +282 -78
  28. package/lib/ice/src/turn/protocol.js.map +1 -1
  29. package/lib/ice/src/types/model.d.ts +8 -0
  30. package/lib/ice/src/types/model.js.map +1 -1
  31. package/lib/index.mjs +5646 -3451
  32. package/lib/nonstandard/index.mjs +287 -1004
  33. package/lib/polyfill/dom.mjs +23794 -0
  34. package/lib/polyfill/index.mjs +23794 -0
  35. package/lib/rtp/src/extra/container/mp4/container.js +12 -4
  36. package/lib/rtp/src/extra/container/mp4/container.js.map +1 -1
  37. package/lib/rtp/src/extra/processor/mp4.js +8 -3
  38. package/lib/rtp/src/extra/processor/mp4.js.map +1 -1
  39. package/lib/rtp/src/extra/processor/mp4Callback.js +3 -1
  40. package/lib/rtp/src/extra/processor/mp4Callback.js.map +1 -1
  41. package/lib/sctp/src/chunk.d.ts +5 -0
  42. package/lib/sctp/src/chunk.js +16 -11
  43. package/lib/sctp/src/chunk.js.map +1 -1
  44. package/lib/sctp/src/index.d.ts +3 -1
  45. package/lib/sctp/src/index.js +10 -1
  46. package/lib/sctp/src/index.js.map +1 -1
  47. package/lib/sctp/src/sctp.d.ts +12 -3
  48. package/lib/sctp/src/sctp.js +51 -18
  49. package/lib/sctp/src/sctp.js.map +1 -1
  50. package/lib/webrtc/src/const.js +2 -0
  51. package/lib/webrtc/src/const.js.map +1 -1
  52. package/lib/webrtc/src/errors.d.ts +9 -1
  53. package/lib/webrtc/src/errors.js +19 -0
  54. package/lib/webrtc/src/errors.js.map +1 -1
  55. package/lib/webrtc/src/media/codec.d.ts +5 -0
  56. package/lib/webrtc/src/media/codec.js +21 -0
  57. package/lib/webrtc/src/media/codec.js.map +1 -1
  58. package/lib/webrtc/src/media/codecCompatibility.d.ts +23 -0
  59. package/lib/webrtc/src/media/codecCompatibility.js +138 -0
  60. package/lib/webrtc/src/media/codecCompatibility.js.map +1 -0
  61. package/lib/webrtc/src/media/index.d.ts +1 -0
  62. package/lib/webrtc/src/media/index.js +1 -0
  63. package/lib/webrtc/src/media/index.js.map +1 -1
  64. package/lib/webrtc/src/media/router.d.ts +2 -0
  65. package/lib/webrtc/src/media/router.js +23 -3
  66. package/lib/webrtc/src/media/router.js.map +1 -1
  67. package/lib/webrtc/src/media/rtpReceiver.d.ts +12 -0
  68. package/lib/webrtc/src/media/rtpReceiver.js +35 -0
  69. package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
  70. package/lib/webrtc/src/media/rtpSender.d.ts +65 -4
  71. package/lib/webrtc/src/media/rtpSender.js +264 -35
  72. package/lib/webrtc/src/media/rtpSender.js.map +1 -1
  73. package/lib/webrtc/src/media/rtpTransceiver.d.ts +42 -0
  74. package/lib/webrtc/src/media/rtpTransceiver.js +157 -4
  75. package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
  76. package/lib/webrtc/src/media/track.d.ts +29 -1
  77. package/lib/webrtc/src/media/track.js +164 -5
  78. package/lib/webrtc/src/media/track.js.map +1 -1
  79. package/lib/webrtc/src/nonstandard/index.d.ts +0 -1
  80. package/lib/webrtc/src/nonstandard/index.js +0 -1
  81. package/lib/webrtc/src/nonstandard/index.js.map +1 -1
  82. package/lib/webrtc/src/nonstandard/recorder/writer/webm.js +2 -1
  83. package/lib/webrtc/src/nonstandard/recorder/writer/webm.js.map +1 -1
  84. package/lib/webrtc/src/nonstandard/userMedia.d.ts +1 -2
  85. package/lib/webrtc/src/nonstandard/userMedia.js +30 -14
  86. package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
  87. package/lib/webrtc/src/peerConnection.d.ts +127 -5
  88. package/lib/webrtc/src/peerConnection.js +629 -143
  89. package/lib/webrtc/src/peerConnection.js.map +1 -1
  90. package/lib/webrtc/src/polyfill/api.d.ts +14 -0
  91. package/lib/webrtc/src/polyfill/api.js +23 -0
  92. package/lib/webrtc/src/polyfill/api.js.map +1 -0
  93. package/lib/webrtc/src/polyfill/browserIdentity.d.ts +11 -0
  94. package/lib/webrtc/src/polyfill/browserIdentity.js +59 -0
  95. package/lib/webrtc/src/polyfill/browserIdentity.js.map +1 -0
  96. package/lib/webrtc/src/polyfill/dom.d.ts +11 -0
  97. package/lib/webrtc/src/polyfill/dom.js +18 -0
  98. package/lib/webrtc/src/polyfill/dom.js.map +1 -0
  99. package/lib/webrtc/src/polyfill/existingMediaDevices.d.ts +2 -0
  100. package/lib/webrtc/src/polyfill/existingMediaDevices.js +22 -0
  101. package/lib/webrtc/src/polyfill/existingMediaDevices.js.map +1 -0
  102. package/lib/webrtc/src/polyfill/globals.d.ts +28 -0
  103. package/lib/webrtc/src/polyfill/globals.js +3 -0
  104. package/lib/webrtc/src/polyfill/globals.js.map +1 -0
  105. package/lib/webrtc/src/polyfill/index.d.ts +2 -0
  106. package/lib/webrtc/src/polyfill/index.js +19 -0
  107. package/lib/webrtc/src/polyfill/index.js.map +1 -0
  108. package/lib/webrtc/src/polyfill/install.d.ts +13 -0
  109. package/lib/webrtc/src/polyfill/install.js +266 -0
  110. package/lib/webrtc/src/polyfill/install.js.map +1 -0
  111. package/lib/webrtc/src/polyfill/mediaDevices.d.ts +38 -0
  112. package/lib/webrtc/src/polyfill/mediaDevices.js +228 -0
  113. package/lib/webrtc/src/polyfill/mediaDevices.js.map +1 -0
  114. package/lib/webrtc/src/polyfill/mediaRegister.d.ts +51 -0
  115. package/lib/webrtc/src/polyfill/mediaRegister.js +14 -0
  116. package/lib/webrtc/src/polyfill/mediaRegister.js.map +1 -0
  117. package/lib/webrtc/src/polyfill/peerConnectionConfig.d.ts +3 -0
  118. package/lib/webrtc/src/polyfill/peerConnectionConfig.js +52 -0
  119. package/lib/webrtc/src/polyfill/peerConnectionConfig.js.map +1 -0
  120. package/lib/webrtc/src/polyfill/registers/callback.d.ts +16 -0
  121. package/lib/webrtc/src/polyfill/registers/callback.js +57 -0
  122. package/lib/webrtc/src/polyfill/registers/callback.js.map +1 -0
  123. package/lib/webrtc/src/polyfill/registers/empty.d.ts +2 -0
  124. package/lib/webrtc/src/polyfill/registers/empty.js +28 -0
  125. package/lib/webrtc/src/polyfill/registers/empty.js.map +1 -0
  126. package/lib/webrtc/src/polyfill/registers/mp4Webm.d.ts +36 -0
  127. package/lib/webrtc/src/polyfill/registers/mp4Webm.js +242 -0
  128. package/lib/webrtc/src/polyfill/registers/mp4Webm.js.map +1 -0
  129. package/lib/webrtc/src/polyfill/registers/rtpRtcp.d.ts +17 -0
  130. package/lib/webrtc/src/polyfill/registers/rtpRtcp.js +143 -0
  131. package/lib/webrtc/src/polyfill/registers/rtpRtcp.js.map +1 -0
  132. package/lib/webrtc/src/polyfill/rtcSessionDescription.d.ts +18 -0
  133. package/lib/webrtc/src/polyfill/rtcSessionDescription.js +36 -0
  134. package/lib/webrtc/src/polyfill/rtcSessionDescription.js.map +1 -0
  135. package/lib/webrtc/src/polyfill/rtpCodec.d.ts +17 -0
  136. package/lib/webrtc/src/polyfill/rtpCodec.js +93 -0
  137. package/lib/webrtc/src/polyfill/rtpCodec.js.map +1 -0
  138. package/lib/webrtc/src/polyfill/selectSettings.d.ts +31 -0
  139. package/lib/webrtc/src/polyfill/selectSettings.js +156 -0
  140. package/lib/webrtc/src/polyfill/selectSettings.js.map +1 -0
  141. package/lib/webrtc/src/polyfill/sourceIo.d.ts +21 -0
  142. package/lib/webrtc/src/polyfill/sourceIo.js +298 -0
  143. package/lib/webrtc/src/polyfill/sourceIo.js.map +1 -0
  144. package/lib/webrtc/src/polyfill/trackStop.d.ts +4 -0
  145. package/lib/webrtc/src/polyfill/trackStop.js +16 -0
  146. package/lib/webrtc/src/polyfill/trackStop.js.map +1 -0
  147. package/lib/webrtc/src/sctpManager.d.ts +2 -1
  148. package/lib/webrtc/src/sctpManager.js +5 -2
  149. package/lib/webrtc/src/sctpManager.js.map +1 -1
  150. package/lib/webrtc/src/sdp.d.ts +1 -1
  151. package/lib/webrtc/src/sdp.js +5 -6
  152. package/lib/webrtc/src/sdp.js.map +1 -1
  153. package/lib/webrtc/src/sdpManager.d.ts +38 -1
  154. package/lib/webrtc/src/sdpManager.js +236 -30
  155. package/lib/webrtc/src/sdpManager.js.map +1 -1
  156. package/lib/webrtc/src/secureTransportManager.d.ts +43 -12
  157. package/lib/webrtc/src/secureTransportManager.js +123 -47
  158. package/lib/webrtc/src/secureTransportManager.js.map +1 -1
  159. package/lib/webrtc/src/transceiverManager.d.ts +91 -6
  160. package/lib/webrtc/src/transceiverManager.js +477 -62
  161. package/lib/webrtc/src/transceiverManager.js.map +1 -1
  162. package/lib/webrtc/src/transport/ice.d.ts +8 -0
  163. package/lib/webrtc/src/transport/ice.js +17 -1
  164. package/lib/webrtc/src/transport/ice.js.map +1 -1
  165. package/lib/webrtc/src/transport/sctp.d.ts +3 -2
  166. package/lib/webrtc/src/transport/sctp.js +8 -2
  167. package/lib/webrtc/src/transport/sctp.js.map +1 -1
  168. package/package.json +14 -3
@@ -1 +1 @@
1
- {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../../common/src/transport.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type RemoteInfo,\n type Socket,\n type SocketType,\n createSocket,\n} from \"dgram\";\n\nimport * as net from \"node:net\";\nimport * as tls from \"node:tls\";\n\nimport { type AddressInfo, type Socket as TcpSocket, connect } from \"node:net\";\nimport { debug } from \"./log\";\nimport {\n type Address,\n type InterfaceAddresses,\n findPort,\n interfaceAddress,\n normalizeFamilyNodeV18,\n} from \"./network\";\n\nconst log = debug(\"werift-ice:packages/ice/src/transport.ts\");\n\ntype StreamTransportType = \"tcp\" | \"tls\";\ntype StreamSocket = TcpSocket | tls.TLSSocket;\ntype StreamConnectEvent = \"connect\" | \"secureConnect\";\n\nexport type TlsConnectionOptions = Omit<\n tls.ConnectionOptions,\n \"host\" | \"port\" | \"socket\"\n>;\n\nexport class UdpTransport implements Transport {\n readonly type = \"udp\";\n readonly socket: Socket;\n rinfo?: Partial<Pick<RemoteInfo, \"address\" | \"port\">>;\n onData: (data: Buffer, addr: Address) => void = () => {};\n closed: boolean = false;\n\n private constructor(\n private socketType: SocketType,\n private options: {\n portRange?: [number, number];\n interfaceAddresses?: InterfaceAddresses;\n port?: number;\n } = {},\n ) {\n this.socket = createSocket(socketType);\n this.socket.on(\"message\", (data, info) => {\n if (normalizeFamilyNodeV18(info.family) === 6) {\n [info.address] = info.address.split(\"%\"); // example fe80::1d3a:8751:4ffd:eb80%wlp82s0\n }\n this.rinfo = info;\n try {\n this.onData(data, [info.address, info.port]);\n } catch (error) {\n log(\"onData error\", error);\n }\n });\n }\n\n static async init(\n type: SocketType,\n options: {\n portRange?: [number, number];\n port?: number;\n interfaceAddresses?: InterfaceAddresses;\n } = {},\n ) {\n const transport = new UdpTransport(type, options);\n await transport.init();\n return transport;\n }\n\n private async init() {\n const address = interfaceAddress(\n this.socketType,\n this.options.interfaceAddresses,\n );\n if (this.options.port) {\n this.socket.bind({ port: this.options.port, address });\n } else if (this.options.portRange) {\n const port = await findPort(\n this.options.portRange[0],\n this.options.portRange[1],\n this.socketType,\n this.options.interfaceAddresses,\n );\n this.socket.bind({ port, address });\n } else {\n this.socket.bind({ address });\n }\n await new Promise((r) => this.socket.once(\"listening\", r));\n }\n\n send = async (data: Buffer, addr?: Address) => {\n if (addr && !net.isIP(addr[0])) {\n // if address is not resolved, need to use send callback to handle dns failure.\n return new Promise<void>((r, f) => {\n this.socket.send(data, addr![1], addr![0], (error) => {\n if (error) {\n log(\"send error\", addr, data);\n f(error);\n } else {\n r();\n }\n });\n });\n } else {\n addr = addr ?? [this.rinfo?.address!, this.rinfo?.port!];\n // a preestablished remote address does not need a callback to verify dns.\n // this is faster because event loop is not used per packet.\n this.socket.send(data, addr[1], addr[0]);\n }\n };\n\n get address() {\n return this.socket.address();\n }\n\n get host() {\n return this.socket.address().address;\n }\n\n get port() {\n return this.socket.address().port;\n }\n\n close = () =>\n new Promise<void>((r) => {\n this.closed = true;\n this.socket.once(\"close\", r);\n try {\n this.socket.close();\n } catch (error) {\n r();\n }\n });\n}\n\nexport class TcpTransport implements Transport {\n readonly type = \"tcp\" as const;\n private readonly stream: StreamTransport;\n\n private constructor(addr: Address) {\n this.stream = new StreamTransport(\"tcp\", () =>\n connect({ port: addr[1], host: addr[0] }),\n );\n }\n\n static async init(addr: Address) {\n const transport = new TcpTransport(addr);\n await transport.init();\n return transport;\n }\n\n private async init() {\n await this.stream.waitForConnect();\n }\n\n get address() {\n return this.stream.address;\n }\n\n get closed() {\n return this.stream.closed;\n }\n\n get onData() {\n return this.stream.onData;\n }\n\n set onData(handler: (data: Buffer, addr: Address) => void) {\n this.stream.onData = handler;\n }\n\n send = async (data: Buffer, addr?: Address) => {\n await this.stream.send(data, addr);\n };\n\n close = async () => {\n await this.stream.close();\n };\n}\n\nexport class TlsTransport implements Transport {\n readonly type = \"tls\" as const;\n private readonly stream: StreamTransport;\n\n private constructor(addr: Address, options: TlsConnectionOptions = {}) {\n this.stream = new StreamTransport(\"tls\", () =>\n tls.connect({\n ...options,\n host: addr[0],\n port: addr[1],\n }),\n );\n }\n\n static async init(addr: Address, options: TlsConnectionOptions = {}) {\n const transport = new TlsTransport(addr, options);\n await transport.init();\n return transport;\n }\n\n private async init() {\n await this.stream.waitForConnect();\n }\n\n get address() {\n return this.stream.address;\n }\n\n get closed() {\n return this.stream.closed;\n }\n\n get onData() {\n return this.stream.onData;\n }\n\n set onData(handler: (data: Buffer, addr: Address) => void) {\n this.stream.onData = handler;\n }\n\n send = async (data: Buffer, addr?: Address) => {\n await this.stream.send(data, addr);\n };\n\n close = async () => {\n await this.stream.close();\n };\n}\n\nclass StreamTransport implements Transport {\n readonly type: StreamTransportType;\n private connecting!: Promise<void>;\n private client!: StreamSocket;\n onData: (data: Buffer, addr: Address) => void = () => {};\n closed = false;\n\n constructor(\n type: StreamTransportType,\n private createClient: () => StreamSocket,\n private connectEvent: StreamConnectEvent = type === \"tls\"\n ? \"secureConnect\"\n : \"connect\",\n ) {\n this.type = type;\n this.connect();\n }\n\n private connect() {\n if (this.closed) {\n return;\n }\n\n if (this.client) {\n this.client.destroy();\n }\n const client = this.createClient();\n this.client = client;\n this.connecting = new Promise((r, f) => {\n const onConnect = () => {\n client.off(\"error\", onConnectError);\n r();\n };\n const onConnectError = (error: Error) => {\n client.off(this.connectEvent, onConnect);\n f(error);\n };\n client.once(this.connectEvent, onConnect);\n client.once(\"error\", onConnectError);\n });\n\n client.on(\"data\", (data) => {\n const addr = [\n this.client.remoteAddress!,\n this.client.remotePort!,\n ] as Address;\n this.onData(data, addr);\n });\n client.on(\"end\", () => {\n this.connect();\n });\n client.on(\"error\", (error) => {\n log(`${this.type} transport error`, error);\n });\n }\n\n async waitForConnect() {\n await this.connecting;\n }\n\n get address() {\n return {} as AddressInfo;\n }\n\n send = async (data: Buffer, addr?: Address) => {\n void addr;\n await this.connecting;\n await new Promise<void>((resolve, reject) => {\n this.client.write(data, (err) => {\n if (err) {\n reject(err);\n return;\n }\n resolve();\n });\n });\n };\n\n close = async () => {\n this.closed = true;\n this.client?.destroy();\n };\n}\n\nexport interface Transport {\n type: string;\n address: AddressInfo;\n closed: boolean;\n onData: (data: Buffer, addr: Address) => void;\n send: (data: Buffer, addr?: Address) => Promise<void>;\n close: () => Promise<void>;\n}\n"]}
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../../common/src/transport.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iCAKe;AAEf,8CAAgC;AAChC,8CAAgC;AAEhC,uCAA+E;AAC/E,+BAA8B;AAC9B,uCAMmB;AAEnB,MAAM,GAAG,GAAG,IAAA,WAAK,EAAC,0CAA0C,CAAC,CAAC;AAgB9D,MAAM,0BAA0B,GAAG,IAAI,CAAC;AAExC,MAAa,YAAY;IAOvB,YACU,UAAsB,EACtB,UAIJ,EAAE;QALN;;;;mBAAQ,UAAU;WAAY;QAC9B;;;;mBAAQ,OAAO;WAIT;QAZC;;;;mBAAO,KAAK;WAAC;QACb;;;;;WAAe;QACxB;;;;;WAAsD;QACtD;;;;mBAAgD,GAAG,EAAE,GAAE,CAAC;WAAC;QACzD;;;;mBAAkB,KAAK;WAAC;QA0DxB;;;;mBAAO,KAAK,EAAE,IAAY,EAAE,IAAc,EAAE,EAAE;gBAC5C,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC/B,+EAA+E;oBAC/E,OAAO,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;wBAChC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAK,CAAC,CAAC,CAAC,EAAE,IAAK,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE;4BACnD,IAAI,KAAK,EAAE,CAAC;gCACV,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;gCAC9B,CAAC,CAAC,KAAK,CAAC,CAAC;4BACX,CAAC;iCAAM,CAAC;gCACN,CAAC,EAAE,CAAC;4BACN,CAAC;wBACH,CAAC,CAAC,CAAC;oBACL,CAAC,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,OAAQ,EAAE,IAAI,CAAC,KAAK,EAAE,IAAK,CAAC,CAAC;oBACzD,0EAA0E;oBAC1E,4DAA4D;oBAC5D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;WAAC;QAmBF;;;;mBAAQ,GAAG,EAAE,CACX,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE;gBACtB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;gBACnB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBAC7B,IAAI,CAAC;oBACH,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;gBACtB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,CAAC,EAAE,CAAC;gBACN,CAAC;YACH,CAAC,CAAC;WAAC;QA/FH,IAAI,CAAC,MAAM,GAAG,IAAA,oBAAY,EAAC,UAAU,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;YACvC,IAAI,IAAA,gCAAsB,EAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9C,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,4CAA4C;YACxF,CAAC;YACD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAClB,IAAI,CAAC;gBACH,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAC/C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,GAAG,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,IAAI,CACf,IAAgB,EAChB,UAII,EAAE;QAEN,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;QACvB,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,KAAK,CAAC,IAAI;QAChB,MAAM,OAAO,GAAG,IAAA,0BAAgB,EAC9B,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAChC,CAAC;QACF,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACtB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QACzD,CAAC;aAAM,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG,MAAM,IAAA,kBAAQ,EACzB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EACzB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EACzB,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAChC,CAAC;YACF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QAChC,CAAC;QACD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC;IAuBD,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;IAC/B,CAAC;IAED,6DAA6D;IAC7D,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC;IACvC,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC;IACpC,CAAC;CAYF;AA/GD,oCA+GC;AAED,MAAa,YAAY;IAIvB,YAAoB,IAAa,EAAE,UAAkC,EAAE;QAH9D;;;;mBAAO,KAAc;WAAC;QACd;;;;;WAAwB;QA8CzC;;;;mBAAO,KAAK,EAAE,IAAY,EAAE,IAAc,EAAE,EAAE;gBAC5C,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACrC,CAAC;WAAC;QAEF;;;;mBAAQ,KAAK,IAAI,EAAE;gBACjB,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAC5B,CAAC;WAAC;QAjDA,IAAI,CAAC,MAAM,GAAG,IAAI,eAAe,CAC/B,KAAK,EACL,GAAG,EAAE,CAAC,IAAA,kBAAO,EAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAC/C,SAAS,EACT,OAAO,CAAC,gBAAgB,CACzB,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAa,EAAE,UAAkC,EAAE;QACnE,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;YACvB,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;YACxB,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,IAAI;QAChB,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;IACrC,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;IAC7B,CAAC;IAED,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;IACnC,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,IAAI,MAAM,CAAC,OAA8C;QACvD,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC;IAC/B,CAAC;CASF;AAvDD,oCAuDC;AAED,MAAa,YAAY;IAIvB,YACE,IAAa,EACb,UAAgC,EAAE,EAClC,gBAAwC,EAAE;QANnC;;;;mBAAO,KAAc;WAAC;QACd;;;;;WAAwB;QA2DzC;;;;mBAAO,KAAK,EAAE,IAAY,EAAE,IAAc,EAAE,EAAE;gBAC5C,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACrC,CAAC;WAAC;QAEF;;;;mBAAQ,KAAK,IAAI,EAAE;gBACjB,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAC5B,CAAC;WAAC;QA1DA,IAAI,CAAC,MAAM,GAAG,IAAI,eAAe,CAC/B,KAAK,EACL,GAAG,EAAE,CACH,GAAG,CAAC,OAAO,CAAC;YACV,GAAG,OAAO;YACV,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;YACb,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;SACd,CAAC,EACJ,SAAS,EACT,aAAa,CAAC,gBAAgB,CAC/B,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,IAAI,CACf,IAAa,EACb,UAAgC,EAAE,EAClC,gBAAwC,EAAE;QAE1C,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;QACjE,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;YACvB,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;YACxB,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,IAAI;QAChB,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;IACrC,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;IAC7B,CAAC;IAED,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;IACnC,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,IAAI,MAAM,CAAC,OAA8C;QACvD,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC;IAC/B,CAAC;CASF;AApED,oCAoEC;AAED,MAAM,eAAe;IAQnB,YACE,IAAyB,EACjB,YAAgC,EAChC,eAAmC,IAAI,KAAK,KAAK;QACvD,CAAC,CAAC,eAAe;QACjB,CAAC,CAAC,SAAS,EACL,mBAAmB,0BAA0B;QAJrD;;;;mBAAQ,YAAY;WAAoB;QACxC;;;;mBAAQ,YAAY;WAEP;QACb;;;;mBAAQ,gBAAgB;WAA6B;QAb9C;;;;;WAA0B;QAC3B;;;;;WAA2B;QAC3B;;;;;WAAsB;QAC9B;;;;mBAAgD,GAAG,EAAE,GAAE,CAAC;WAAC;QACzD;;;;mBAAS,KAAK;WAAC;QACP;;;;;WAA0C;QAkFlD;;;;mBAAO,KAAK,EAAE,IAAY,EAAE,IAAc,EAAE,EAAE;gBAC5C,KAAK,IAAI,CAAC;gBACV,MAAM,IAAI,CAAC,UAAU,CAAC;gBACtB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;oBAC1C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;wBAC9B,IAAI,GAAG,EAAE,CAAC;4BACR,MAAM,CAAC,GAAG,CAAC,CAAC;4BACZ,OAAO;wBACT,CAAC;wBACD,OAAO,EAAE,CAAC;oBACZ,CAAC,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;YACL,CAAC;WAAC;QAEF;;;;mBAAQ,KAAK,IAAI,EAAE;gBACjB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;gBACnB,IAAI,CAAC,gBAAgB,EAAE,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,mBAAmB,CAAC,CAAC,CAAC;gBACpE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YACzB,CAAC;WAAC;QA1FA,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAEO,OAAO;QACb,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACxB,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACnC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAChD,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,EAAE;gBAC/B,IAAI,OAAO;oBAAE,OAAO;gBACpB,OAAO,GAAG,IAAI,CAAC;gBACf,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;gBACzC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;gBACpC,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;gBAClC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;YACpC,CAAC,CAAC;YACF,MAAM,SAAS,GAAG,GAAG,EAAE;gBACrB,MAAM,EAAE,CAAC;YACX,CAAC,CAAC;YACF,MAAM,cAAc,GAAG,CAAC,KAAY,EAAE,EAAE;gBACtC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;gBACnB,MAAM,CAAC,KAAK,CAAC,CAAC;gBACd,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,CAAC,CAAC;YACF,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;gBACnB,MAAM,CACJ,IAAI,KAAK,CACP,GAAG,IAAI,CAAC,IAAI,4BAA4B,IAAI,CAAC,gBAAgB,IAAI,CAClE,CACF,CAAC;gBACF,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,CAAC,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAC1B,IAAI,CAAC,gBAAgB,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACjD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;YAC1C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,aAAc,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC3B,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,kBAAkB,EAAE,KAAK,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,MAAM,IAAI,CAAC,UAAU,CAAC;IACxB,CAAC;IAED,IAAI,OAAO;QACT,OAAO,EAAiB,CAAC;IAC3B,CAAC;IAED,2DAA2D;IAC3D,IAAI,aAAa;QACf,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QAClD,IAAI,CAAC,aAAa,IAAI,CAAC,UAAU,EAAE,CAAC;YAClC,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,UAAU,CAAC,CAAC;IAClD,CAAC;CAqBF;AAED,mEAAmE;AACnE,SAAS,WAAW,CAAC,OAAe;IAClC,OAAO,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/B,CAAC","sourcesContent":["import {\n type RemoteInfo,\n type Socket,\n type SocketType,\n createSocket,\n} from \"dgram\";\n\nimport * as net from \"node:net\";\nimport * as tls from \"node:tls\";\n\nimport { type AddressInfo, type Socket as TcpSocket, connect } from \"node:net\";\nimport { debug } from \"./log\";\nimport {\n type Address,\n type InterfaceAddresses,\n findPort,\n interfaceAddress,\n normalizeFamilyNodeV18,\n} from \"./network\";\n\nconst log = debug(\"werift-ice:packages/ice/src/transport.ts\");\n\ntype StreamTransportType = \"tcp\" | \"tls\";\ntype StreamSocket = TcpSocket | tls.TLSSocket;\ntype StreamConnectEvent = \"connect\" | \"secureConnect\";\n\nexport type TlsConnectionOptions = Omit<\n tls.ConnectionOptions,\n \"host\" | \"port\" | \"socket\"\n>;\n\nexport interface StreamTransportOptions {\n /** Maximum time to wait for TCP/TLS connection establishment, in milliseconds. */\n connectTimeoutMs?: number;\n}\n\nconst DEFAULT_CONNECT_TIMEOUT_MS = 8000;\n\nexport class UdpTransport implements Transport {\n readonly type = \"udp\";\n readonly socket: Socket;\n rinfo?: Partial<Pick<RemoteInfo, \"address\" | \"port\">>;\n onData: (data: Buffer, addr: Address) => void = () => {};\n closed: boolean = false;\n\n private constructor(\n private socketType: SocketType,\n private options: {\n portRange?: [number, number];\n interfaceAddresses?: InterfaceAddresses;\n port?: number;\n } = {},\n ) {\n this.socket = createSocket(socketType);\n this.socket.on(\"message\", (data, info) => {\n if (normalizeFamilyNodeV18(info.family) === 6) {\n [info.address] = info.address.split(\"%\"); // example fe80::1d3a:8751:4ffd:eb80%wlp82s0\n }\n this.rinfo = info;\n try {\n this.onData(data, [info.address, info.port]);\n } catch (error) {\n log(\"onData error\", error);\n }\n });\n }\n\n static async init(\n type: SocketType,\n options: {\n portRange?: [number, number];\n port?: number;\n interfaceAddresses?: InterfaceAddresses;\n } = {},\n ) {\n const transport = new UdpTransport(type, options);\n await transport.init();\n return transport;\n }\n\n private async init() {\n const address = interfaceAddress(\n this.socketType,\n this.options.interfaceAddresses,\n );\n if (this.options.port) {\n this.socket.bind({ port: this.options.port, address });\n } else if (this.options.portRange) {\n const port = await findPort(\n this.options.portRange[0],\n this.options.portRange[1],\n this.socketType,\n this.options.interfaceAddresses,\n );\n this.socket.bind({ port, address });\n } else {\n this.socket.bind({ address });\n }\n await new Promise((r) => this.socket.once(\"listening\", r));\n }\n\n send = async (data: Buffer, addr?: Address) => {\n if (addr && !net.isIP(addr[0])) {\n // if address is not resolved, need to use send callback to handle dns failure.\n return new Promise<void>((r, f) => {\n this.socket.send(data, addr![1], addr![0], (error) => {\n if (error) {\n log(\"send error\", addr, data);\n f(error);\n } else {\n r();\n }\n });\n });\n } else {\n addr = addr ?? [this.rinfo?.address!, this.rinfo?.port!];\n // a preestablished remote address does not need a callback to verify dns.\n // this is faster because event loop is not used per packet.\n this.socket.send(data, addr[1], addr[0]);\n }\n };\n\n get address() {\n return this.socket.address();\n }\n\n /** IP family of the bound socket: 4 for udp4, 6 for udp6. */\n get addressFamily(): IpAddressFamily {\n return this.socketType === \"udp6\" ? 6 : 4;\n }\n\n get host() {\n return this.socket.address().address;\n }\n\n get port() {\n return this.socket.address().port;\n }\n\n close = () =>\n new Promise<void>((r) => {\n this.closed = true;\n this.socket.once(\"close\", r);\n try {\n this.socket.close();\n } catch (error) {\n r();\n }\n });\n}\n\nexport class TcpTransport implements Transport {\n readonly type = \"tcp\" as const;\n private readonly stream: StreamTransport;\n\n private constructor(addr: Address, options: StreamTransportOptions = {}) {\n this.stream = new StreamTransport(\n \"tcp\",\n () => connect({ port: addr[1], host: addr[0] }),\n undefined,\n options.connectTimeoutMs,\n );\n }\n\n static async init(addr: Address, options: StreamTransportOptions = {}) {\n const transport = new TcpTransport(addr, options);\n try {\n await transport.init();\n return transport;\n } catch (error) {\n await transport.close();\n throw error;\n }\n }\n\n private async init() {\n await this.stream.waitForConnect();\n }\n\n get address() {\n return this.stream.address;\n }\n\n get remoteAddress() {\n return this.stream.remoteAddress;\n }\n\n get closed() {\n return this.stream.closed;\n }\n\n get onData() {\n return this.stream.onData;\n }\n\n set onData(handler: (data: Buffer, addr: Address) => void) {\n this.stream.onData = handler;\n }\n\n send = async (data: Buffer, addr?: Address) => {\n await this.stream.send(data, addr);\n };\n\n close = async () => {\n await this.stream.close();\n };\n}\n\nexport class TlsTransport implements Transport {\n readonly type = \"tls\" as const;\n private readonly stream: StreamTransport;\n\n private constructor(\n addr: Address,\n options: TlsConnectionOptions = {},\n streamOptions: StreamTransportOptions = {},\n ) {\n this.stream = new StreamTransport(\n \"tls\",\n () =>\n tls.connect({\n ...options,\n host: addr[0],\n port: addr[1],\n }),\n undefined,\n streamOptions.connectTimeoutMs,\n );\n }\n\n static async init(\n addr: Address,\n options: TlsConnectionOptions = {},\n streamOptions: StreamTransportOptions = {},\n ) {\n const transport = new TlsTransport(addr, options, streamOptions);\n try {\n await transport.init();\n return transport;\n } catch (error) {\n await transport.close();\n throw error;\n }\n }\n\n private async init() {\n await this.stream.waitForConnect();\n }\n\n get address() {\n return this.stream.address;\n }\n\n get remoteAddress() {\n return this.stream.remoteAddress;\n }\n\n get closed() {\n return this.stream.closed;\n }\n\n get onData() {\n return this.stream.onData;\n }\n\n set onData(handler: (data: Buffer, addr: Address) => void) {\n this.stream.onData = handler;\n }\n\n send = async (data: Buffer, addr?: Address) => {\n await this.stream.send(data, addr);\n };\n\n close = async () => {\n await this.stream.close();\n };\n}\n\nclass StreamTransport implements Transport {\n readonly type: StreamTransportType;\n private connecting!: Promise<void>;\n private client!: StreamSocket;\n onData: (data: Buffer, addr: Address) => void = () => {};\n closed = false;\n private rejectConnecting?: (error: Error) => void;\n\n constructor(\n type: StreamTransportType,\n private createClient: () => StreamSocket,\n private connectEvent: StreamConnectEvent = type === \"tls\"\n ? \"secureConnect\"\n : \"connect\",\n private connectTimeoutMs = DEFAULT_CONNECT_TIMEOUT_MS,\n ) {\n this.type = type;\n this.connect();\n }\n\n private connect() {\n if (this.closed) {\n return;\n }\n\n if (this.client) {\n this.client.destroy();\n }\n const client = this.createClient();\n this.client = client;\n this.connecting = new Promise((resolve, reject) => {\n let settled = false;\n const settle = (error?: Error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n client.off(this.connectEvent, onConnect);\n client.off(\"error\", onConnectError);\n this.rejectConnecting = undefined;\n error ? reject(error) : resolve();\n };\n const onConnect = () => {\n settle();\n };\n const onConnectError = (error: Error) => {\n this.closed = true;\n settle(error);\n client.destroy();\n };\n const timer = setTimeout(() => {\n this.closed = true;\n settle(\n new Error(\n `${this.type} connect timed out after ${this.connectTimeoutMs}ms`,\n ),\n );\n client.destroy();\n }, this.connectTimeoutMs);\n this.rejectConnecting = (error) => settle(error);\n client.once(this.connectEvent, onConnect);\n client.once(\"error\", onConnectError);\n });\n\n client.on(\"data\", (data) => {\n this.onData(data, this.remoteAddress!);\n });\n client.on(\"error\", (error) => {\n log(`${this.type} transport error`, error);\n });\n }\n\n async waitForConnect() {\n await this.connecting;\n }\n\n get address() {\n return {} as AddressInfo;\n }\n\n /** The peer the stream is connected to, once connected. */\n get remoteAddress(): Address | undefined {\n const { remoteAddress, remotePort } = this.client;\n if (!remoteAddress || !remotePort) {\n return undefined;\n }\n return [stripZoneId(remoteAddress), remotePort];\n }\n\n send = async (data: Buffer, addr?: Address) => {\n void addr;\n await this.connecting;\n await new Promise<void>((resolve, reject) => {\n this.client.write(data, (err) => {\n if (err) {\n reject(err);\n return;\n }\n resolve();\n });\n });\n };\n\n close = async () => {\n this.closed = true;\n this.rejectConnecting?.(new Error(`${this.type} transport closed`));\n this.client?.destroy();\n };\n}\n\n/** Strip an IPv6 zone identifier, e.g. fe80::1%eth0 -> fe80::1. */\nfunction stripZoneId(address: string) {\n return address.split(\"%\")[0];\n}\n\nexport type IpAddressFamily = 4 | 6;\n\nexport interface Transport {\n type: string;\n address: AddressInfo;\n closed: boolean;\n onData: (data: Buffer, addr: Address) => void;\n send: (data: Buffer, addr?: Address) => Promise<void>;\n close: () => Promise<void>;\n /**\n * IP family of a datagram socket. A datagram transport can only reach\n * addresses of this family. Built-in UDP transports always set it; a custom\n * transport that leaves it unset gets no family preference.\n */\n addressFamily?: IpAddressFamily;\n /**\n * The peer a connected (stream) transport is talking to. Responses arrive\n * from this address. Built-in TCP/TLS transports set it once connected.\n */\n remoteAddress?: Address;\n}\n"]}
@@ -13,3 +13,12 @@ export declare class TransactionFailed extends TransactionError {
13
13
  export declare class TransactionTimeout extends TransactionError {
14
14
  get str(): string;
15
15
  }
16
+ /**
17
+ * The request target is an IP literal of a different family than the socket
18
+ * that would carry it, so it can never be delivered.
19
+ */
20
+ export declare class AddressFamilyMismatch extends Error {
21
+ addr: Address;
22
+ socketFamily: 4 | 6;
23
+ constructor(addr: Address, socketFamily: 4 | 6);
24
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TransactionTimeout = exports.TransactionFailed = exports.TransactionError = void 0;
3
+ exports.AddressFamilyMismatch = exports.TransactionTimeout = exports.TransactionFailed = exports.TransactionError = void 0;
4
4
  class TransactionError extends Error {
5
5
  constructor() {
6
6
  super(...arguments);
@@ -52,4 +52,26 @@ class TransactionTimeout extends TransactionError {
52
52
  }
53
53
  }
54
54
  exports.TransactionTimeout = TransactionTimeout;
55
+ /**
56
+ * The request target is an IP literal of a different family than the socket
57
+ * that would carry it, so it can never be delivered.
58
+ */
59
+ class AddressFamilyMismatch extends Error {
60
+ constructor(addr, socketFamily) {
61
+ super(`cannot reach ${addr[0]}:${addr[1]} from an IPv${socketFamily} socket`);
62
+ Object.defineProperty(this, "addr", {
63
+ enumerable: true,
64
+ configurable: true,
65
+ writable: true,
66
+ value: addr
67
+ });
68
+ Object.defineProperty(this, "socketFamily", {
69
+ enumerable: true,
70
+ configurable: true,
71
+ writable: true,
72
+ value: socketFamily
73
+ });
74
+ }
75
+ }
76
+ exports.AddressFamilyMismatch = AddressFamilyMismatch;
55
77
  //# sourceMappingURL=exceptions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"exceptions.js","sourceRoot":"","sources":["../../../../ice/src/exceptions.ts"],"names":[],"mappings":";;;AAGA,MAAa,gBAAiB,SAAQ,KAAK;IAA3C;;QACE;;;;;WAAmB;QACnB;;;;;WAAe;IACjB,CAAC;CAAA;AAHD,4CAGC;AAED,MAAa,iBAAkB,SAAQ,gBAAgB;IACrD,YACS,QAAiB,EACjB,IAAa;QAEpB,KAAK,EAAE,CAAC;QAHR;;;;mBAAO,QAAQ;WAAS;QACxB;;;;mBAAO,IAAI;WAAS;IAGtB,CAAC;IAED,IAAI,GAAG;QACL,IAAI,GAAG,GAAG,yBAAyB,CAAC;QACpC,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;QAChE,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC;YAC9B,GAAG,IAAI,KAAK,IAAI,MAAM,GAAG,GAAG,CAAC;QAC/B,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;CACF;AAjBD,8CAiBC;AAED,MAAa,kBAAmB,SAAQ,gBAAgB;IACtD,IAAI,GAAG;QACL,OAAO,4BAA4B,CAAC;IACtC,CAAC;CACF;AAJD,gDAIC","sourcesContent":["import type { Address } from \"./imports/common\";\nimport type { Message } from \"./stun/message\";\n\nexport class TransactionError extends Error {\n response?: Message;\n addr?: Address;\n}\n\nexport class TransactionFailed extends TransactionError {\n constructor(\n public response: Message,\n public addr: Address,\n ) {\n super();\n }\n\n get str() {\n let out = \"STUN transaction failed\";\n const attribute = this.response.getAttributeValue(\"ERROR-CODE\");\n if (attribute) {\n const [code, msg] = attribute;\n out += ` (${code} - ${msg})`;\n }\n return out;\n }\n}\n\nexport class TransactionTimeout extends TransactionError {\n get str() {\n return \"STUN transaction timed out\";\n }\n}\n"]}
1
+ {"version":3,"file":"exceptions.js","sourceRoot":"","sources":["../../../../ice/src/exceptions.ts"],"names":[],"mappings":";;;AAGA,MAAa,gBAAiB,SAAQ,KAAK;IAA3C;;QACE;;;;;WAAmB;QACnB;;;;;WAAe;IACjB,CAAC;CAAA;AAHD,4CAGC;AAED,MAAa,iBAAkB,SAAQ,gBAAgB;IACrD,YACS,QAAiB,EACjB,IAAa;QAEpB,KAAK,EAAE,CAAC;QAHR;;;;mBAAO,QAAQ;WAAS;QACxB;;;;mBAAO,IAAI;WAAS;IAGtB,CAAC;IAED,IAAI,GAAG;QACL,IAAI,GAAG,GAAG,yBAAyB,CAAC;QACpC,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;QAChE,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC;YAC9B,GAAG,IAAI,KAAK,IAAI,MAAM,GAAG,GAAG,CAAC;QAC/B,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;CACF;AAjBD,8CAiBC;AAED,MAAa,kBAAmB,SAAQ,gBAAgB;IACtD,IAAI,GAAG;QACL,OAAO,4BAA4B,CAAC;IACtC,CAAC;CACF;AAJD,gDAIC;AAED;;;GAGG;AACH,MAAa,qBAAsB,SAAQ,KAAK;IAC9C,YACS,IAAa,EACb,YAAmB;QAE1B,KAAK,CACH,gBAAgB,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,eAAe,YAAY,SAAS,CACvE,CAAC;QALF;;;;mBAAO,IAAI;WAAS;QACpB;;;;mBAAO,YAAY;WAAO;IAK5B,CAAC;CACF;AATD,sDASC","sourcesContent":["import type { Address } from \"./imports/common\";\nimport type { Message } from \"./stun/message\";\n\nexport class TransactionError extends Error {\n response?: Message;\n addr?: Address;\n}\n\nexport class TransactionFailed extends TransactionError {\n constructor(\n public response: Message,\n public addr: Address,\n ) {\n super();\n }\n\n get str() {\n let out = \"STUN transaction failed\";\n const attribute = this.response.getAttributeValue(\"ERROR-CODE\");\n if (attribute) {\n const [code, msg] = attribute;\n out += ` (${code} - ${msg})`;\n }\n return out;\n }\n}\n\nexport class TransactionTimeout extends TransactionError {\n get str() {\n return \"STUN transaction timed out\";\n }\n}\n\n/**\n * The request target is an IP literal of a different family than the socket\n * that would carry it, so it can never be delivered.\n */\nexport class AddressFamilyMismatch extends Error {\n constructor(\n public addr: Address,\n public socketFamily: 4 | 6,\n ) {\n super(\n `cannot reach ${addr[0]}:${addr[1]} from an IPv${socketFamily} socket`,\n );\n }\n}\n"]}
@@ -45,6 +45,22 @@ export declare class Connection implements IceConnection {
45
45
  readonly stateChanged: Event<[IceState]>;
46
46
  readonly onIceCandidate: Event<[Candidate]>;
47
47
  constructor(_iceControlling: boolean, options?: Partial<IceOptions>);
48
+ /**
49
+ * Replace STUN/TURN servers after construction.
50
+ * Server-related fields are replaced (not partial-merged) so that removing
51
+ * TURN clears residual credentials. W3C setConfiguration replaces the ICE
52
+ * server list rather than merging additively.
53
+ *
54
+ * Used when servers are learned after the gatherer was built (e.g. WHIP
55
+ * Link headers) and must take effect before the next gather pass.
56
+ */
57
+ setIceServers(options: Partial<IceOptions>): void;
58
+ /**
59
+ * Derive Connection.stunServer / turnServer from this.options.
60
+ * Shared by the constructor and setIceServers so both paths validate and
61
+ * default identically.
62
+ */
63
+ private applyStunTurnServersFromOptions;
48
64
  get iceControlling(): boolean;
49
65
  set iceControlling(value: boolean);
50
66
  get iceLite(): boolean;
@@ -58,6 +74,12 @@ export declare class Connection implements IceConnection {
58
74
  gatherCandidates(): Promise<void>;
59
75
  private appendLocalCandidate;
60
76
  private ensureProtocol;
77
+ /**
78
+ * RFC 6544: the selected TCP connection is the only path for this component;
79
+ * once it is closed no application data or consent check can reach the peer,
80
+ * so fail the same way as a consent expiry instead of waiting for it.
81
+ */
82
+ private handleConnectionClosed;
61
83
  private getCandidatePromises;
62
84
  connect(): Promise<void>;
63
85
  private unfreezeInitial;
@@ -94,6 +116,24 @@ export declare class Connection implements IceConnection {
94
116
  resolve: (value: void | PromiseLike<void>) => void;
95
117
  reject: (reason?: any) => void;
96
118
  };
119
+ private isTcpPair;
120
+ /**
121
+ * Aggressive nomination lets each side settle on whichever TCP connection
122
+ * finished first; the two sides can then pick different connections and
123
+ * pruning destroys the peer's choice. For TCP the controlling agent instead
124
+ * nominates exactly one valid pair (RFC 8445 §8.1.1 regular nomination).
125
+ */
126
+ private usesTcpRegularNomination;
127
+ private checkRequestOptions;
128
+ /**
129
+ * Controlling side: nominate the highest-priority TCP pair once every
130
+ * higher-priority TCP pair has finished its check, so the choice does not
131
+ * depend on which connection happened to complete first.
132
+ */
133
+ private nominateTcpPairIfReady;
134
+ private nominateTcpPair;
135
+ /** The agent was closed or restarted while the nomination was in flight. */
136
+ private isStaleNomination;
97
137
  private addPair;
98
138
  checkIncoming(message: Message, addr: Address, protocol: Protocol): void;
99
139
  private tryPair;
@@ -49,6 +49,8 @@ const tcpProtocol_1 = require("./stun/tcpProtocol");
49
49
  const protocol_2 = require("./turn/protocol");
50
50
  const utils_1 = require("./utils");
51
51
  const log = (0, common_1.debug)("werift-ice : packages/ice/src/ice.ts : log");
52
+ /** Fallback STUN server when none is configured (constructor / setIceServers). */
53
+ const DEFAULT_STUN_SERVER = ["stun.l.google.com", 19302];
52
54
  class Connection {
53
55
  constructor(_iceControlling, options) {
54
56
  Object.defineProperty(this, "_iceControlling", {
@@ -463,7 +465,8 @@ class Connection {
463
465
  const result = {};
464
466
  const { remotePassword, remoteUsername, generation } = this;
465
467
  const localUsername = pair.localCandidate.ufrag ?? this.localUsername;
466
- const nominate = this.iceControlling && !this.remoteIsLite;
468
+ // TCP pairs use regular nomination (see nominateTcpPairIfReady).
469
+ const nominate = this.iceControlling && !this.remoteIsLite && !this.isTcpPair(pair);
467
470
  const request = this.buildRequest({
468
471
  nominate,
469
472
  localUsername,
@@ -475,11 +478,7 @@ class Connection {
475
478
  const startTime = performance.now();
476
479
  try {
477
480
  pair.requestsSent++;
478
- const [response, addr] = await pair.protocol.request(request, pair.remoteAddr, Buffer.from(remotePassword, "utf8"), pair.localCandidate.transport.toLowerCase() === "tcp" ? 0 : 4, (attempt) => {
479
- if (attempt > 0) {
480
- pair.retransmissionsSent++;
481
- }
482
- });
481
+ const [response, addr] = await pair.protocol.request(request, pair.remoteAddr, Buffer.from(remotePassword, "utf8"), this.checkRequestOptions(pair));
483
482
  pair.responsesReceived++;
484
483
  // Calculate RTT
485
484
  const endTime = performance.now();
@@ -546,6 +545,9 @@ class Connection {
546
545
  // # nominated by agressive nomination or the remote party
547
546
  pair.nominated = true;
548
547
  }
548
+ else if (this.usesTcpRegularNomination(pair)) {
549
+ // # nominated later by nominateTcpPairIfReady (from checkComplete)
550
+ }
549
551
  else if (this.iceControlling && !this.nominating) {
550
552
  // # perform regular nomination
551
553
  this.nominating = true;
@@ -558,14 +560,11 @@ class Connection {
558
560
  });
559
561
  try {
560
562
  pair.requestsSent++;
561
- await pair.protocol.request(request, pair.remoteAddr, Buffer.from(this.remotePassword, "utf8"), pair.localCandidate.transport.toLowerCase() === "tcp" ? 0 : 4, (attempt) => {
562
- if (attempt > 0) {
563
- pair.retransmissionsSent++;
564
- }
565
- });
563
+ await pair.protocol.request(request, pair.remoteAddr, Buffer.from(this.remotePassword, "utf8"), this.checkRequestOptions(pair));
566
564
  pair.responsesReceived++;
567
565
  }
568
566
  catch (error) {
567
+ this.nominating = false;
569
568
  pair.updateState(iceBase_1.CandidatePairState.FAILED);
570
569
  this.checkComplete(pair);
571
570
  return;
@@ -594,15 +593,55 @@ class Connection {
594
593
  if (this.iceLite) {
595
594
  this._iceControlling = false;
596
595
  }
597
- const { stunServer, turnServer } = this.options;
598
- this.stunServer = (0, iceBase_1.validateAddress)(stunServer) ?? [
599
- "stun.l.google.com",
600
- 19302,
601
- ];
602
- this.turnServer = (0, iceBase_1.validateAddress)(turnServer);
596
+ this.applyStunTurnServersFromOptions();
603
597
  this.restart();
604
598
  log("new Connection", this.options);
605
599
  }
600
+ /**
601
+ * Replace STUN/TURN servers after construction.
602
+ * Server-related fields are replaced (not partial-merged) so that removing
603
+ * TURN clears residual credentials. W3C setConfiguration replaces the ICE
604
+ * server list rather than merging additively.
605
+ *
606
+ * Used when servers are learned after the gatherer was built (e.g. WHIP
607
+ * Link headers) and must take effect before the next gather pass.
608
+ */
609
+ setIceServers(options) {
610
+ // Explicitly assign server fields even when undefined so a STUN-only
611
+ // update cannot leave a previous TURN host/credential in options.
612
+ this.options = {
613
+ ...this.options,
614
+ stunServer: options.stunServer,
615
+ turnServer: options.turnServer,
616
+ turnUsername: options.turnUsername,
617
+ turnPassword: options.turnPassword,
618
+ turnTransport: options.turnTransport,
619
+ };
620
+ if (options.forceTurn !== undefined) {
621
+ this.options.forceTurn = options.forceTurn;
622
+ }
623
+ if (options.useTcp !== undefined) {
624
+ this.options.useTcp = options.useTcp;
625
+ }
626
+ if (options.turnTlsOptions !== undefined) {
627
+ this.options.turnTlsOptions = options.turnTlsOptions;
628
+ }
629
+ if (options.turnUdpFamily !== undefined) {
630
+ this.options.turnUdpFamily = options.turnUdpFamily;
631
+ }
632
+ this.applyStunTurnServersFromOptions();
633
+ log("Connection ice servers updated", this.options);
634
+ }
635
+ /**
636
+ * Derive Connection.stunServer / turnServer from this.options.
637
+ * Shared by the constructor and setIceServers so both paths validate and
638
+ * default identically.
639
+ */
640
+ applyStunTurnServersFromOptions() {
641
+ this.stunServer =
642
+ (0, iceBase_1.validateAddress)(this.options.stunServer) ?? DEFAULT_STUN_SERVER;
643
+ this.turnServer = (0, iceBase_1.validateAddress)(this.options.turnServer);
644
+ }
606
645
  get iceControlling() {
607
646
  return this._iceControlling;
608
647
  }
@@ -698,7 +737,7 @@ class Connection {
698
737
  if (this.options.additionalHostAddresses) {
699
738
  address = Array.from(new Set([...this.options.additionalHostAddresses, ...address]));
700
739
  }
701
- const candidatePromises = this.getCandidatePromises(address, 5);
740
+ const candidatePromises = this.getCandidatePromises(address, this.options.stunGatherTimeout);
702
741
  await Promise.allSettled(candidatePromises);
703
742
  this.localCandidatesEnd = true;
704
743
  }
@@ -775,6 +814,29 @@ class Connection {
775
814
  log("dataReceived", error);
776
815
  }
777
816
  });
817
+ protocol.onConnectionClosed?.subscribe((remoteAddr) => {
818
+ this.handleConnectionClosed(protocol, remoteAddr);
819
+ });
820
+ }
821
+ /**
822
+ * RFC 6544: the selected TCP connection is the only path for this component;
823
+ * once it is closed no application data or consent check can reach the peer,
824
+ * so fail the same way as a consent expiry instead of waiting for it.
825
+ */
826
+ handleConnectionClosed(protocol, remoteAddr) {
827
+ const nominated = this.nominated;
828
+ if (!nominated ||
829
+ nominated.protocol !== protocol ||
830
+ nominated.remoteAddr[0] !== remoteAddr[0] ||
831
+ nominated.remoteAddr[1] !== remoteAddr[1]) {
832
+ return;
833
+ }
834
+ if (this.state === "closed" || this.state === "failed") {
835
+ return;
836
+ }
837
+ log("selected tcp connection closed", nominated.toJSON());
838
+ this.stopConsentLifecycle();
839
+ this.setState("failed");
778
840
  }
779
841
  getCandidatePromises(addresses, timeout = 5) {
780
842
  const candidatePromises = [];
@@ -823,16 +885,21 @@ class Connection {
823
885
  }
824
886
  if (!gatherRelayOnly && this.options.useTcp) {
825
887
  const tcpCandidatePromises = addresses.map(async (address) => {
826
- const passiveProtocol = new tcpProtocol_1.TcpPassiveProtocol();
827
- this.ensureProtocol(passiveProtocol);
828
- await passiveProtocol.connectionMade(address, this.options.portRange);
829
- passiveProtocol.localIp = address;
830
- passiveProtocol.localCandidate = new candidate_1.Candidate((0, candidate_1.candidateFoundation)("host", "tcp", address), 1, "tcp", (0, candidate_1.candidatePriority)("host", {
831
- transport: "tcp",
832
- tcptype: "passive",
833
- }), address, passiveProtocol.listeningPort, "host", undefined, undefined, "passive", this.generation, this.localUsername);
834
- this.protocols.push(passiveProtocol);
835
- this.appendLocalCandidate(passiveProtocol.localCandidate);
888
+ // Passive candidates open a listening TCP server; skip them when the
889
+ // agent only makes outbound connections (tcpPassive === false). Active
890
+ // candidates below still dial out, so direct TCP egress is unaffected.
891
+ if (this.options.tcpPassive !== false) {
892
+ const passiveProtocol = new tcpProtocol_1.TcpPassiveProtocol();
893
+ this.ensureProtocol(passiveProtocol);
894
+ await passiveProtocol.connectionMade(address, this.options.portRange);
895
+ passiveProtocol.localIp = address;
896
+ passiveProtocol.localCandidate = new candidate_1.Candidate((0, candidate_1.candidateFoundation)("host", "tcp", address), 1, "tcp", (0, candidate_1.candidatePriority)("host", {
897
+ transport: "tcp",
898
+ tcptype: "passive",
899
+ }), address, passiveProtocol.listeningPort, "host", undefined, undefined, "passive", this.generation, this.localUsername);
900
+ this.protocols.push(passiveProtocol);
901
+ this.appendLocalCandidate(passiveProtocol.localCandidate);
902
+ }
836
903
  if (!gatherIceLite) {
837
904
  const activeProtocol = new tcpProtocol_1.TcpActiveProtocol();
838
905
  this.ensureProtocol(activeProtocol);
@@ -890,6 +957,8 @@ class Connection {
890
957
  interfaceAddresses: this.options.interfaceAddresses,
891
958
  transport: turnTransport,
892
959
  tlsOptions: this.options.turnTlsOptions,
960
+ connectTimeoutMs: (this.options.turnConnectTimeout ?? 8) * 1000,
961
+ udpFamily: this.options.turnUdpFamily,
893
962
  }).catch(async (e) => {
894
963
  if (turnTransport === "udp") {
895
964
  return await (0, protocol_2.createStunOverTurnClient)({
@@ -900,6 +969,7 @@ class Connection {
900
969
  portRange: this.options.portRange,
901
970
  interfaceAddresses: this.options.interfaceAddresses,
902
971
  transport: "tcp",
972
+ connectTimeoutMs: (this.options.turnConnectTimeout ?? 8) * 1000,
903
973
  });
904
974
  }
905
975
  else {
@@ -1268,6 +1338,11 @@ class Connection {
1268
1338
  }
1269
1339
  }
1270
1340
  }
1341
+ this.nominateTcpPairIfReady();
1342
+ // A nomination request is still in flight; its result decides the outcome.
1343
+ if (this.nominating) {
1344
+ return;
1345
+ }
1271
1346
  {
1272
1347
  const list = [iceBase_1.CandidatePairState.SUCCEEDED, iceBase_1.CandidatePairState.FAILED];
1273
1348
  if (this.checkList.find(({ state }) => !list.includes(state))) {
@@ -1287,6 +1362,97 @@ class Connection {
1287
1362
  }));
1288
1363
  }
1289
1364
  }
1365
+ isTcpPair(pair) {
1366
+ return pair.localCandidate.transport.toLowerCase() === "tcp";
1367
+ }
1368
+ /**
1369
+ * Aggressive nomination lets each side settle on whichever TCP connection
1370
+ * finished first; the two sides can then pick different connections and
1371
+ * pruning destroys the peer's choice. For TCP the controlling agent instead
1372
+ * nominates exactly one valid pair (RFC 8445 §8.1.1 regular nomination).
1373
+ */
1374
+ usesTcpRegularNomination(pair) {
1375
+ return this.iceControlling && !this.remoteIsLite && this.isTcpPair(pair);
1376
+ }
1377
+ checkRequestOptions(pair) {
1378
+ const onRequestSent = (attempt) => {
1379
+ if (attempt > 0) {
1380
+ pair.retransmissionsSent++;
1381
+ }
1382
+ };
1383
+ if (this.isTcpPair(pair)) {
1384
+ // RFC 5389 §7.2.2: no retransmissions over a reliable transport.
1385
+ return {
1386
+ retransmissions: 0,
1387
+ responseTimeout: const_1.TCP_CHECK_RESPONSE_TIMEOUT_MS,
1388
+ onRequestSent,
1389
+ };
1390
+ }
1391
+ return { retransmissions: 4, onRequestSent };
1392
+ }
1393
+ /**
1394
+ * Controlling side: nominate the highest-priority TCP pair once every
1395
+ * higher-priority TCP pair has finished its check, so the choice does not
1396
+ * depend on which connection happened to complete first.
1397
+ */
1398
+ nominateTcpPairIfReady() {
1399
+ if (!this.iceControlling ||
1400
+ this.remoteIsLite ||
1401
+ this.nominated ||
1402
+ this.nominating) {
1403
+ return;
1404
+ }
1405
+ for (const pair of this.checkList) {
1406
+ if (!this.isTcpPair(pair)) {
1407
+ continue;
1408
+ }
1409
+ if (pair.state === iceBase_1.CandidatePairState.SUCCEEDED) {
1410
+ this.nominateTcpPair(pair);
1411
+ return;
1412
+ }
1413
+ if (pair.state !== iceBase_1.CandidatePairState.FAILED) {
1414
+ // A higher-priority pair may still succeed.
1415
+ return;
1416
+ }
1417
+ }
1418
+ }
1419
+ nominateTcpPair(pair) {
1420
+ this.nominating = true;
1421
+ const { generation } = this;
1422
+ const request = this.buildRequest({
1423
+ nominate: true,
1424
+ localUsername: pair.localCandidate.ufrag ?? this.localUsername,
1425
+ remoteUsername: this.remoteUsername,
1426
+ iceControlling: this.iceControlling,
1427
+ localCandidate: pair.localCandidate,
1428
+ });
1429
+ pair.requestsSent++;
1430
+ pair.protocol
1431
+ .request(request, pair.remoteAddr, Buffer.from(this.remotePassword, "utf8"), this.checkRequestOptions(pair))
1432
+ .then(() => {
1433
+ if (this.isStaleNomination(pair, generation)) {
1434
+ return;
1435
+ }
1436
+ pair.responsesReceived++;
1437
+ pair.nominated = true;
1438
+ this.nominating = false;
1439
+ this.checkComplete(pair);
1440
+ }, (error) => {
1441
+ if (this.isStaleNomination(pair, generation)) {
1442
+ return;
1443
+ }
1444
+ log("tcp nomination failed", pair.toJSON(), error);
1445
+ this.nominating = false;
1446
+ pair.updateState(iceBase_1.CandidatePairState.FAILED);
1447
+ this.checkComplete(pair);
1448
+ });
1449
+ }
1450
+ /** The agent was closed or restarted while the nomination was in flight. */
1451
+ isStaleNomination(pair, generation) {
1452
+ return (this.state === "closed" ||
1453
+ this.generation !== generation ||
1454
+ !this.checkList.includes(pair));
1455
+ }
1290
1456
  addPair(pair) {
1291
1457
  this.checkList.push(pair);
1292
1458
  this.sortCheckList();