@lakutata/webrtc 0.0.0-stage → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +23 -0
- package/README.md +509 -2
- package/README.zh-CN.md +399 -0
- package/THIRD_PARTY_NOTICES.md +652 -0
- package/dist/cjs/client/SignalingConnection.d.ts +81 -0
- package/dist/cjs/client/SignalingConnection.js +67 -0
- package/dist/cjs/cluster/Cluster.d.ts +503 -0
- package/dist/cjs/cluster/Cluster.js +546 -0
- package/dist/cjs/cluster/ClusterFrames.d.ts +24 -0
- package/dist/cjs/cluster/ClusterFrames.js +90 -0
- package/dist/cjs/cluster/ClusterTURN.d.ts +63 -0
- package/dist/cjs/cluster/ClusterTURN.js +78 -0
- package/dist/cjs/cluster/Rendezvous.d.ts +8 -0
- package/dist/cjs/cluster/Rendezvous.js +23 -0
- package/dist/cjs/cluster/transports/ClusterTransport.d.ts +34 -0
- package/dist/cjs/cluster/transports/ClusterTransport.js +2 -0
- package/dist/cjs/cluster/transports/LoadClient.d.ts +6 -0
- package/dist/cjs/cluster/transports/LoadClient.js +80 -0
- package/dist/cjs/cluster/transports/MemoryClusterTransport.d.ts +13 -0
- package/dist/cjs/cluster/transports/MemoryClusterTransport.js +47 -0
- package/dist/cjs/cluster/transports/NATSClusterTransport.d.ts +23 -0
- package/dist/cjs/cluster/transports/NATSClusterTransport.js +70 -0
- package/dist/cjs/cluster/transports/RedisClusterTransport.d.ts +23 -0
- package/dist/cjs/cluster/transports/RedisClusterTransport.js +77 -0
- package/dist/cjs/exceptions/ClusterRequestException.d.ts +11 -0
- package/dist/cjs/exceptions/ClusterRequestException.js +18 -0
- package/dist/cjs/exceptions/ClusterTimeoutException.d.ts +10 -0
- package/dist/cjs/exceptions/ClusterTimeoutException.js +17 -0
- package/dist/cjs/exceptions/ClusterTransportNotFoundException.d.ts +11 -0
- package/dist/cjs/exceptions/ClusterTransportNotFoundException.js +18 -0
- package/dist/cjs/exceptions/SignalingClientRequiredException.d.ts +12 -0
- package/dist/cjs/exceptions/SignalingClientRequiredException.js +19 -0
- package/dist/cjs/exceptions/SignalingConnectionException.d.ts +12 -0
- package/dist/cjs/exceptions/SignalingConnectionException.js +19 -0
- package/dist/cjs/exceptions/SignalingDeniedException.d.ts +11 -0
- package/dist/cjs/exceptions/SignalingDeniedException.js +18 -0
- package/dist/cjs/exceptions/SignalingLimitException.d.ts +11 -0
- package/dist/cjs/exceptions/SignalingLimitException.js +18 -0
- package/dist/cjs/exceptions/SignalingNotAMemberException.d.ts +11 -0
- package/dist/cjs/exceptions/SignalingNotAMemberException.js +18 -0
- package/dist/cjs/exceptions/WHEPDeniedException.d.ts +15 -0
- package/dist/cjs/exceptions/WHEPDeniedException.js +22 -0
- package/dist/cjs/exceptions/WHEPLimitException.d.ts +15 -0
- package/dist/cjs/exceptions/WHEPLimitException.js +22 -0
- package/dist/cjs/exceptions/WHEPMediaTypeException.d.ts +15 -0
- package/dist/cjs/exceptions/WHEPMediaTypeException.js +22 -0
- package/dist/cjs/exceptions/WHEPOfferException.d.ts +16 -0
- package/dist/cjs/exceptions/WHEPOfferException.js +23 -0
- package/dist/cjs/exceptions/WHEPSessionNotFoundException.d.ts +15 -0
- package/dist/cjs/exceptions/WHEPSessionNotFoundException.js +22 -0
- package/dist/cjs/exceptions/WHIPDeniedException.d.ts +15 -0
- package/dist/cjs/exceptions/WHIPDeniedException.js +22 -0
- package/dist/cjs/exceptions/WHIPLimitException.d.ts +15 -0
- package/dist/cjs/exceptions/WHIPLimitException.js +22 -0
- package/dist/cjs/exceptions/WHIPMediaTypeException.d.ts +15 -0
- package/dist/cjs/exceptions/WHIPMediaTypeException.js +22 -0
- package/dist/cjs/exceptions/WHIPOfferException.d.ts +16 -0
- package/dist/cjs/exceptions/WHIPOfferException.js +23 -0
- package/dist/cjs/exceptions/WHIPSessionNotFoundException.d.ts +15 -0
- package/dist/cjs/exceptions/WHIPSessionNotFoundException.js +22 -0
- package/dist/cjs/exports/Client.d.ts +11 -0
- package/dist/cjs/exports/Client.js +29 -0
- package/dist/cjs/exports/WebRTC.d.ts +48 -0
- package/dist/cjs/exports/WebRTC.js +72 -0
- package/dist/cjs/lib/common/binary.d.ts +51 -0
- package/dist/cjs/lib/common/binary.js +264 -0
- package/dist/cjs/lib/common/binaryData.d.ts +116 -0
- package/dist/cjs/lib/common/binaryData.js +400 -0
- package/dist/cjs/lib/common/crc.d.ts +4 -0
- package/dist/cjs/lib/common/crc.js +122 -0
- package/dist/cjs/lib/common/deque.d.ts +36 -0
- package/dist/cjs/lib/common/deque.js +89 -0
- package/dist/cjs/lib/common/event.d.ts +48 -0
- package/dist/cjs/lib/common/event.js +207 -0
- package/dist/cjs/lib/common/index.d.ts +11 -0
- package/dist/cjs/lib/common/index.js +50 -0
- package/dist/cjs/lib/common/log.d.ts +47 -0
- package/dist/cjs/lib/common/log.js +62 -0
- package/dist/cjs/lib/common/network.d.ts +10 -0
- package/dist/cjs/lib/common/network.js +60 -0
- package/dist/cjs/lib/common/number.d.ts +13 -0
- package/dist/cjs/lib/common/number.js +43 -0
- package/dist/cjs/lib/common/promise.d.ts +21 -0
- package/dist/cjs/lib/common/promise.js +70 -0
- package/dist/cjs/lib/common/transport.d.ts +104 -0
- package/dist/cjs/lib/common/transport.js +441 -0
- package/dist/cjs/lib/common/type.d.ts +3 -0
- package/dist/cjs/lib/common/type.js +2 -0
- package/dist/cjs/lib/dtls/cipher/const.d.ts +42 -0
- package/dist/cjs/lib/dtls/cipher/const.js +33 -0
- package/dist/cjs/lib/dtls/cipher/create.d.ts +21 -0
- package/dist/cjs/lib/dtls/cipher/create.js +105 -0
- package/dist/cjs/lib/dtls/cipher/ec.d.ts +28 -0
- package/dist/cjs/lib/dtls/cipher/ec.js +44 -0
- package/dist/cjs/lib/dtls/cipher/key-exchange.d.ts +43 -0
- package/dist/cjs/lib/dtls/cipher/key-exchange.js +113 -0
- package/dist/cjs/lib/dtls/cipher/namedCurve.d.ts +7 -0
- package/dist/cjs/lib/dtls/cipher/namedCurve.js +27 -0
- package/dist/cjs/lib/dtls/cipher/prf.d.ts +17 -0
- package/dist/cjs/lib/dtls/cipher/prf.js +92 -0
- package/dist/cjs/lib/dtls/cipher/suites/abstract.d.ts +40 -0
- package/dist/cjs/lib/dtls/cipher/suites/abstract.js +41 -0
- package/dist/cjs/lib/dtls/cipher/suites/aead.d.ts +28 -0
- package/dist/cjs/lib/dtls/cipher/suites/aead.js +132 -0
- package/dist/cjs/lib/dtls/cipher/suites/null.d.ts +24 -0
- package/dist/cjs/lib/dtls/cipher/suites/null.js +41 -0
- package/dist/cjs/lib/dtls/cipher/utils.d.ts +18 -0
- package/dist/cjs/lib/dtls/cipher/utils.js +70 -0
- package/dist/cjs/lib/dtls/cipher/x509.d.ts +33 -0
- package/dist/cjs/lib/dtls/cipher/x509.js +100 -0
- package/dist/cjs/lib/dtls/client.d.ts +7 -0
- package/dist/cjs/lib/dtls/client.js +76 -0
- package/dist/cjs/lib/dtls/context/cipher.d.ts +42 -0
- package/dist/cjs/lib/dtls/context/cipher.js +87 -0
- package/dist/cjs/lib/dtls/context/dtls.d.ts +38 -0
- package/dist/cjs/lib/dtls/context/dtls.js +49 -0
- package/dist/cjs/lib/dtls/context/srtp.d.ts +5 -0
- package/dist/cjs/lib/dtls/context/srtp.js +12 -0
- package/dist/cjs/lib/dtls/context/transport.d.ts +8 -0
- package/dist/cjs/lib/dtls/context/transport.js +17 -0
- package/dist/cjs/lib/dtls/flight/client/flight1.d.ts +10 -0
- package/dist/cjs/lib/dtls/flight/client/flight1.js +26 -0
- package/dist/cjs/lib/dtls/flight/client/flight3.d.ts +8 -0
- package/dist/cjs/lib/dtls/flight/client/flight3.js +25 -0
- package/dist/cjs/lib/dtls/flight/client/flight5.d.ts +18 -0
- package/dist/cjs/lib/dtls/flight/client/flight5.js +206 -0
- package/dist/cjs/lib/dtls/flight/flight.d.ts +18 -0
- package/dist/cjs/lib/dtls/flight/flight.js +68 -0
- package/dist/cjs/lib/dtls/flight/server/flight2.d.ts +6 -0
- package/dist/cjs/lib/dtls/flight/server/flight2.js +126 -0
- package/dist/cjs/lib/dtls/flight/server/flight4.d.ts +17 -0
- package/dist/cjs/lib/dtls/flight/server/flight4.js +87 -0
- package/dist/cjs/lib/dtls/flight/server/flight6.d.ts +13 -0
- package/dist/cjs/lib/dtls/flight/server/flight6.js +111 -0
- package/dist/cjs/lib/dtls/handshake/binary.d.ts +16 -0
- package/dist/cjs/lib/dtls/handshake/binary.js +20 -0
- package/dist/cjs/lib/dtls/handshake/const.d.ts +13 -0
- package/dist/cjs/lib/dtls/handshake/const.js +17 -0
- package/dist/cjs/lib/dtls/handshake/extensions/ellipticCurves.d.ts +17 -0
- package/dist/cjs/lib/dtls/handshake/extensions/ellipticCurves.js +40 -0
- package/dist/cjs/lib/dtls/handshake/extensions/extendedMasterSecret.d.ts +3 -0
- package/dist/cjs/lib/dtls/handshake/extensions/extendedMasterSecret.js +7 -0
- package/dist/cjs/lib/dtls/handshake/extensions/renegotiationIndication.d.ts +18 -0
- package/dist/cjs/lib/dtls/handshake/extensions/renegotiationIndication.js +34 -0
- package/dist/cjs/lib/dtls/handshake/extensions/signature.d.ts +26 -0
- package/dist/cjs/lib/dtls/handshake/extensions/signature.js +39 -0
- package/dist/cjs/lib/dtls/handshake/extensions/useSrtp.d.ts +19 -0
- package/dist/cjs/lib/dtls/handshake/extensions/useSrtp.js +65 -0
- package/dist/cjs/lib/dtls/handshake/message/alert.d.ts +12 -0
- package/dist/cjs/lib/dtls/handshake/message/alert.js +24 -0
- package/dist/cjs/lib/dtls/handshake/message/certificate.d.ts +17 -0
- package/dist/cjs/lib/dtls/handshake/message/certificate.js +35 -0
- package/dist/cjs/lib/dtls/handshake/message/changeCipherSpec.d.ts +11 -0
- package/dist/cjs/lib/dtls/handshake/message/changeCipherSpec.js +24 -0
- package/dist/cjs/lib/dtls/handshake/message/client/certificateVerify.d.ts +20 -0
- package/dist/cjs/lib/dtls/handshake/message/client/certificateVerify.js +35 -0
- package/dist/cjs/lib/dtls/handshake/message/client/hello.d.ts +50 -0
- package/dist/cjs/lib/dtls/handshake/message/client/hello.js +48 -0
- package/dist/cjs/lib/dtls/handshake/message/client/keyExchange.d.ts +17 -0
- package/dist/cjs/lib/dtls/handshake/message/client/keyExchange.js +33 -0
- package/dist/cjs/lib/dtls/handshake/message/finished.d.ts +13 -0
- package/dist/cjs/lib/dtls/handshake/message/finished.js +26 -0
- package/dist/cjs/lib/dtls/handshake/message/server/certificateRequest.d.ts +31 -0
- package/dist/cjs/lib/dtls/handshake/message/server/certificateRequest.js +38 -0
- package/dist/cjs/lib/dtls/handshake/message/server/hello.d.ts +33 -0
- package/dist/cjs/lib/dtls/handshake/message/server/hello.js +57 -0
- package/dist/cjs/lib/dtls/handshake/message/server/helloDone.d.ts +12 -0
- package/dist/cjs/lib/dtls/handshake/message/server/helloDone.js +30 -0
- package/dist/cjs/lib/dtls/handshake/message/server/helloVerifyRequest.d.ts +32 -0
- package/dist/cjs/lib/dtls/handshake/message/server/helloVerifyRequest.js +42 -0
- package/dist/cjs/lib/dtls/handshake/message/server/keyExchange.d.ts +32 -0
- package/dist/cjs/lib/dtls/handshake/message/server/keyExchange.js +49 -0
- package/dist/cjs/lib/dtls/handshake/random.d.ts +13 -0
- package/dist/cjs/lib/dtls/handshake/random.js +29 -0
- package/dist/cjs/lib/dtls/helper.d.ts +4 -0
- package/dist/cjs/lib/dtls/helper.js +30 -0
- package/dist/cjs/lib/dtls/imports/common.d.ts +1 -0
- package/dist/cjs/lib/dtls/imports/common.js +17 -0
- package/dist/cjs/lib/dtls/imports/rtp.d.ts +1 -0
- package/dist/cjs/lib/dtls/imports/rtp.js +17 -0
- package/dist/cjs/lib/dtls/index.d.ts +7 -0
- package/dist/cjs/lib/dtls/index.js +117 -0
- package/dist/cjs/lib/dtls/record/antiReplayWindow.d.ts +27 -0
- package/dist/cjs/lib/dtls/record/antiReplayWindow.js +102 -0
- package/dist/cjs/lib/dtls/record/builder.d.ts +9 -0
- package/dist/cjs/lib/dtls/record/builder.js +27 -0
- package/dist/cjs/lib/dtls/record/const.d.ts +33 -0
- package/dist/cjs/lib/dtls/record/const.js +38 -0
- package/dist/cjs/lib/dtls/record/message/fragment.d.ts +26 -0
- package/dist/cjs/lib/dtls/record/message/fragment.js +96 -0
- package/dist/cjs/lib/dtls/record/message/header.d.ts +38 -0
- package/dist/cjs/lib/dtls/record/message/header.js +34 -0
- package/dist/cjs/lib/dtls/record/message/plaintext.d.ts +14 -0
- package/dist/cjs/lib/dtls/record/message/plaintext.js +63 -0
- package/dist/cjs/lib/dtls/record/receive.d.ts +9 -0
- package/dist/cjs/lib/dtls/record/receive.js +91 -0
- package/dist/cjs/lib/dtls/server.d.ts +6 -0
- package/dist/cjs/lib/dtls/server.js +78 -0
- package/dist/cjs/lib/dtls/socket.d.ts +52 -0
- package/dist/cjs/lib/dtls/socket.js +188 -0
- package/dist/cjs/lib/dtls/typings/domain.d.ts +20 -0
- package/dist/cjs/lib/dtls/typings/domain.js +2 -0
- package/dist/cjs/lib/dtls/util/binary.d.ts +2 -0
- package/dist/cjs/lib/dtls/util/binary.js +8 -0
- package/dist/cjs/lib/ice/candidate.d.ts +35 -0
- package/dist/cjs/lib/ice/candidate.js +198 -0
- package/dist/cjs/lib/ice/dns/lookup.d.ts +16 -0
- package/dist/cjs/lib/ice/dns/lookup.js +133 -0
- package/dist/cjs/lib/ice/dns/mdns.d.ts +38 -0
- package/dist/cjs/lib/ice/dns/mdns.js +145 -0
- package/dist/cjs/lib/ice/exceptions.d.ts +24 -0
- package/dist/cjs/lib/ice/exceptions.js +41 -0
- package/dist/cjs/lib/ice/helper.d.ts +17 -0
- package/dist/cjs/lib/ice/helper.js +74 -0
- package/dist/cjs/lib/ice/ice.d.ts +182 -0
- package/dist/cjs/lib/ice/ice.js +1584 -0
- package/dist/cjs/lib/ice/iceBase.d.ts +214 -0
- package/dist/cjs/lib/ice/iceBase.js +182 -0
- package/dist/cjs/lib/ice/imports/common.d.ts +1 -0
- package/dist/cjs/lib/ice/imports/common.js +17 -0
- package/dist/cjs/lib/ice/index.d.ts +12 -0
- package/dist/cjs/lib/ice/index.js +30 -0
- package/dist/cjs/lib/ice/internal/selectAddresses.d.ts +9 -0
- package/dist/cjs/lib/ice/internal/selectAddresses.js +39 -0
- package/dist/cjs/lib/ice/stun/attributes.d.ts +1 -0
- package/dist/cjs/lib/ice/stun/attributes.js +17 -0
- package/dist/cjs/lib/ice/stun/const.d.ts +8 -0
- package/dist/cjs/lib/ice/stun/const.js +25 -0
- package/dist/cjs/lib/ice/stun/message.d.ts +1 -0
- package/dist/cjs/lib/ice/stun/message.js +17 -0
- package/dist/cjs/lib/ice/stun/protocol.d.ts +30 -0
- package/dist/cjs/lib/ice/stun/protocol.js +125 -0
- package/dist/cjs/lib/ice/stun/tcpFrame.d.ts +5 -0
- package/dist/cjs/lib/ice/stun/tcpFrame.js +25 -0
- package/dist/cjs/lib/ice/stun/tcpProtocol.d.ts +57 -0
- package/dist/cjs/lib/ice/stun/tcpProtocol.js +323 -0
- package/dist/cjs/lib/ice/stun/transaction.d.ts +75 -0
- package/dist/cjs/lib/ice/stun/transaction.js +239 -0
- package/dist/cjs/lib/ice/turn/frame.d.ts +1 -0
- package/dist/cjs/lib/ice/turn/frame.js +17 -0
- package/dist/cjs/lib/ice/turn/protocol.d.ts +170 -0
- package/dist/cjs/lib/ice/turn/protocol.js +638 -0
- package/dist/cjs/lib/ice/types/model.d.ts +56 -0
- package/dist/cjs/lib/ice/types/model.js +2 -0
- package/dist/cjs/lib/ice/utils.d.ts +13 -0
- package/dist/cjs/lib/ice/utils.js +84 -0
- package/dist/cjs/lib/peer/const.d.ts +36 -0
- package/dist/cjs/lib/peer/const.js +53 -0
- package/dist/cjs/lib/peer/dataChannel.d.ts +69 -0
- package/dist/cjs/lib/peer/dataChannel.js +133 -0
- package/dist/cjs/lib/peer/errors.d.ts +11 -0
- package/dist/cjs/lib/peer/errors.js +23 -0
- package/dist/cjs/lib/peer/helper.d.ts +20 -0
- package/dist/cjs/lib/peer/helper.js +84 -0
- package/dist/cjs/lib/peer/imports/common.d.ts +1 -0
- package/dist/cjs/lib/peer/imports/common.js +17 -0
- package/dist/cjs/lib/peer/imports/dtls.d.ts +1 -0
- package/dist/cjs/lib/peer/imports/dtls.js +17 -0
- package/dist/cjs/lib/peer/imports/ice.d.ts +1 -0
- package/dist/cjs/lib/peer/imports/ice.js +17 -0
- package/dist/cjs/lib/peer/imports/rtp.d.ts +1 -0
- package/dist/cjs/lib/peer/imports/rtp.js +17 -0
- package/dist/cjs/lib/peer/index.d.ts +14 -0
- package/dist/cjs/lib/peer/index.js +30 -0
- package/dist/cjs/lib/peer/media/codec.d.ts +15 -0
- package/dist/cjs/lib/peer/media/codec.js +80 -0
- package/dist/cjs/lib/peer/media/codecCompatibility.d.ts +23 -0
- package/dist/cjs/lib/peer/media/codecCompatibility.js +137 -0
- package/dist/cjs/lib/peer/media/extension/rtcpFeedback.d.ts +6 -0
- package/dist/cjs/lib/peer/media/extension/rtcpFeedback.js +13 -0
- package/dist/cjs/lib/peer/media/extension/rtpExtension.d.ts +9 -0
- package/dist/cjs/lib/peer/media/extension/rtpExtension.js +52 -0
- package/dist/cjs/lib/peer/media/index.d.ts +12 -0
- package/dist/cjs/lib/peer/media/index.js +28 -0
- package/dist/cjs/lib/peer/media/parameters.d.ts +65 -0
- package/dist/cjs/lib/peer/media/parameters.js +60 -0
- package/dist/cjs/lib/peer/media/receiver/nack.d.ts +23 -0
- package/dist/cjs/lib/peer/media/receiver/nack.js +104 -0
- package/dist/cjs/lib/peer/media/receiver/receiverTwcc.d.ts +47 -0
- package/dist/cjs/lib/peer/media/receiver/receiverTwcc.js +179 -0
- package/dist/cjs/lib/peer/media/receiver/statistics.d.ts +22 -0
- package/dist/cjs/lib/peer/media/receiver/statistics.js +71 -0
- package/dist/cjs/lib/peer/media/router.d.ts +25 -0
- package/dist/cjs/lib/peer/media/router.js +166 -0
- package/dist/cjs/lib/peer/media/rtpReceiver.d.ts +90 -0
- package/dist/cjs/lib/peer/media/rtpReceiver.js +407 -0
- package/dist/cjs/lib/peer/media/rtpSender.d.ts +209 -0
- package/dist/cjs/lib/peer/media/rtpSender.js +826 -0
- package/dist/cjs/lib/peer/media/rtpTransceiver.d.ts +117 -0
- package/dist/cjs/lib/peer/media/rtpTransceiver.js +245 -0
- package/dist/cjs/lib/peer/media/sender/cumulativeResult.d.ts +19 -0
- package/dist/cjs/lib/peer/media/sender/cumulativeResult.js +61 -0
- package/dist/cjs/lib/peer/media/sender/senderBWE.d.ts +32 -0
- package/dist/cjs/lib/peer/media/sender/senderBWE.js +99 -0
- package/dist/cjs/lib/peer/media/stats.d.ts +293 -0
- package/dist/cjs/lib/peer/media/stats.js +90 -0
- package/dist/cjs/lib/peer/media/track.d.ts +67 -0
- package/dist/cjs/lib/peer/media/track.js +216 -0
- package/dist/cjs/lib/peer/peerConnection.d.ts +458 -0
- package/dist/cjs/lib/peer/peerConnection.js +1591 -0
- package/dist/cjs/lib/peer/sctpManager.d.ts +28 -0
- package/dist/cjs/lib/peer/sctpManager.js +138 -0
- package/dist/cjs/lib/peer/sdp.d.ts +97 -0
- package/dist/cjs/lib/peer/sdp.js +628 -0
- package/dist/cjs/lib/peer/sdpManager.d.ts +116 -0
- package/dist/cjs/lib/peer/sdpManager.js +573 -0
- package/dist/cjs/lib/peer/secureTransportManager.d.ts +96 -0
- package/dist/cjs/lib/peer/secureTransportManager.js +472 -0
- package/dist/cjs/lib/peer/transceiverManager.d.ts +151 -0
- package/dist/cjs/lib/peer/transceiverManager.js +767 -0
- package/dist/cjs/lib/peer/transport/dtls.d.ts +95 -0
- package/dist/cjs/lib/peer/transport/dtls.js +571 -0
- package/dist/cjs/lib/peer/transport/ice.d.ts +143 -0
- package/dist/cjs/lib/peer/transport/ice.js +436 -0
- package/dist/cjs/lib/peer/transport/sctp.d.ts +56 -0
- package/dist/cjs/lib/peer/transport/sctp.js +387 -0
- package/dist/cjs/lib/peer/types/domain.d.ts +5 -0
- package/dist/cjs/lib/peer/types/domain.js +19 -0
- package/dist/cjs/lib/peer/types/util.d.ts +2 -0
- package/dist/cjs/lib/peer/types/util.js +2 -0
- package/dist/cjs/lib/peer/utils.d.ts +73 -0
- package/dist/cjs/lib/peer/utils.js +306 -0
- package/dist/cjs/lib/rtp/codec/av1.d.ts +56 -0
- package/dist/cjs/lib/rtp/codec/av1.js +209 -0
- package/dist/cjs/lib/rtp/codec/base.d.ts +8 -0
- package/dist/cjs/lib/rtp/codec/base.js +15 -0
- package/dist/cjs/lib/rtp/codec/h264.d.ts +32 -0
- package/dist/cjs/lib/rtp/codec/h264.js +122 -0
- package/dist/cjs/lib/rtp/codec/index.d.ts +16 -0
- package/dist/cjs/lib/rtp/codec/index.js +84 -0
- package/dist/cjs/lib/rtp/codec/leb128.d.ts +5 -0
- package/dist/cjs/lib/rtp/codec/leb128.js +23 -0
- package/dist/cjs/lib/rtp/codec/opus.d.ts +9 -0
- package/dist/cjs/lib/rtp/codec/opus.js +25 -0
- package/dist/cjs/lib/rtp/codec/vp8.d.ts +27 -0
- package/dist/cjs/lib/rtp/codec/vp8.js +109 -0
- package/dist/cjs/lib/rtp/codec/vp9.d.ts +46 -0
- package/dist/cjs/lib/rtp/codec/vp9.js +161 -0
- package/dist/cjs/lib/rtp/const.d.ts +1 -0
- package/dist/cjs/lib/rtp/const.js +4 -0
- package/dist/cjs/lib/rtp/helper.d.ts +8 -0
- package/dist/cjs/lib/rtp/helper.js +36 -0
- package/dist/cjs/lib/rtp/imports/common.d.ts +1 -0
- package/dist/cjs/lib/rtp/imports/common.js +17 -0
- package/dist/cjs/lib/rtp/index.d.ts +25 -0
- package/dist/cjs/lib/rtp/index.js +41 -0
- package/dist/cjs/lib/rtp/rtcp/header.d.ts +13 -0
- package/dist/cjs/lib/rtp/rtcp/header.js +50 -0
- package/dist/cjs/lib/rtp/rtcp/psfb/fullIntraRequest.d.ts +16 -0
- package/dist/cjs/lib/rtp/rtcp/psfb/fullIntraRequest.js +34 -0
- package/dist/cjs/lib/rtp/rtcp/psfb/index.d.ts +14 -0
- package/dist/cjs/lib/rtp/rtcp/psfb/index.js +39 -0
- package/dist/cjs/lib/rtp/rtcp/psfb/pictureLossIndication.d.ts +10 -0
- package/dist/cjs/lib/rtp/rtcp/psfb/pictureLossIndication.js +20 -0
- package/dist/cjs/lib/rtp/rtcp/psfb/remb.d.ts +16 -0
- package/dist/cjs/lib/rtp/rtcp/psfb/remb.js +53 -0
- package/dist/cjs/lib/rtp/rtcp/rr.d.ts +32 -0
- package/dist/cjs/lib/rtp/rtcp/rr.js +73 -0
- package/dist/cjs/lib/rtp/rtcp/rtcp.d.ts +10 -0
- package/dist/cjs/lib/rtp/rtcp/rtcp.js +58 -0
- package/dist/cjs/lib/rtp/rtcp/rtpfb/const.d.ts +1 -0
- package/dist/cjs/lib/rtp/rtcp/rtpfb/const.js +4 -0
- package/dist/cjs/lib/rtp/rtcp/rtpfb/index.d.ts +14 -0
- package/dist/cjs/lib/rtp/rtcp/rtpfb/index.js +35 -0
- package/dist/cjs/lib/rtp/rtcp/rtpfb/nack.d.ts +17 -0
- package/dist/cjs/lib/rtp/rtcp/rtpfb/nack.js +77 -0
- package/dist/cjs/lib/rtp/rtcp/rtpfb/twcc.d.ts +71 -0
- package/dist/cjs/lib/rtp/rtcp/rtpfb/twcc.js +352 -0
- package/dist/cjs/lib/rtp/rtcp/sdes.d.ts +26 -0
- package/dist/cjs/lib/rtp/rtcp/sdes.js +97 -0
- package/dist/cjs/lib/rtp/rtcp/sr.d.ts +41 -0
- package/dist/cjs/lib/rtp/rtcp/sr.js +110 -0
- package/dist/cjs/lib/rtp/rtp/headerExtension.d.ts +72 -0
- package/dist/cjs/lib/rtp/rtp/headerExtension.js +117 -0
- package/dist/cjs/lib/rtp/rtp/red/encoder.d.ts +13 -0
- package/dist/cjs/lib/rtp/rtp/red/encoder.js +44 -0
- package/dist/cjs/lib/rtp/rtp/red/handler.d.ts +6 -0
- package/dist/cjs/lib/rtp/rtp/red/handler.js +59 -0
- package/dist/cjs/lib/rtp/rtp/red/packet.d.ts +26 -0
- package/dist/cjs/lib/rtp/rtp/red/packet.js +112 -0
- package/dist/cjs/lib/rtp/rtp/rtp.d.ts +44 -0
- package/dist/cjs/lib/rtp/rtp/rtp.js +271 -0
- package/dist/cjs/lib/rtp/rtp/rtx.d.ts +3 -0
- package/dist/cjs/lib/rtp/rtp/rtx.js +29 -0
- package/dist/cjs/lib/rtp/srtp/cipher/ctr.d.ts +16 -0
- package/dist/cjs/lib/rtp/srtp/cipher/ctr.js +107 -0
- package/dist/cjs/lib/rtp/srtp/cipher/gcm.d.ts +17 -0
- package/dist/cjs/lib/rtp/srtp/cipher/gcm.js +145 -0
- package/dist/cjs/lib/rtp/srtp/cipher/index.d.ts +13 -0
- package/dist/cjs/lib/rtp/srtp/cipher/index.js +24 -0
- package/dist/cjs/lib/rtp/srtp/const.d.ts +6 -0
- package/dist/cjs/lib/rtp/srtp/const.js +26 -0
- package/dist/cjs/lib/rtp/srtp/context/context.d.ts +45 -0
- package/dist/cjs/lib/rtp/srtp/context/context.js +180 -0
- package/dist/cjs/lib/rtp/srtp/context/srtcp.d.ts +8 -0
- package/dist/cjs/lib/rtp/srtp/context/srtcp.js +25 -0
- package/dist/cjs/lib/rtp/srtp/context/srtp.d.ts +9 -0
- package/dist/cjs/lib/rtp/srtp/context/srtp.js +41 -0
- package/dist/cjs/lib/rtp/srtp/error.d.ts +3 -0
- package/dist/cjs/lib/rtp/srtp/error.js +10 -0
- package/dist/cjs/lib/rtp/srtp/packet.d.ts +5 -0
- package/dist/cjs/lib/rtp/srtp/packet.js +47 -0
- package/dist/cjs/lib/rtp/srtp/session.d.ts +19 -0
- package/dist/cjs/lib/rtp/srtp/session.js +13 -0
- package/dist/cjs/lib/rtp/srtp/srtcp.d.ts +8 -0
- package/dist/cjs/lib/rtp/srtp/srtcp.js +21 -0
- package/dist/cjs/lib/rtp/srtp/srtp.d.ts +9 -0
- package/dist/cjs/lib/rtp/srtp/srtp.js +20 -0
- package/dist/cjs/lib/rtp/transport.d.ts +15 -0
- package/dist/cjs/lib/rtp/transport.js +23 -0
- package/dist/cjs/lib/rtp/util.d.ts +11 -0
- package/dist/cjs/lib/rtp/util.js +28 -0
- package/dist/cjs/lib/sctp/chunk.d.ts +164 -0
- package/dist/cjs/lib/sctp/chunk.js +542 -0
- package/dist/cjs/lib/sctp/const.d.ts +17 -0
- package/dist/cjs/lib/sctp/const.js +22 -0
- package/dist/cjs/lib/sctp/helper.d.ts +5 -0
- package/dist/cjs/lib/sctp/helper.js +14 -0
- package/dist/cjs/lib/sctp/imports/common.d.ts +1 -0
- package/dist/cjs/lib/sctp/imports/common.js +17 -0
- package/dist/cjs/lib/sctp/index.d.ts +6 -0
- package/dist/cjs/lib/sctp/index.js +20 -0
- package/dist/cjs/lib/sctp/param.d.ts +40 -0
- package/dist/cjs/lib/sctp/param.js +132 -0
- package/dist/cjs/lib/sctp/sctp.d.ts +210 -0
- package/dist/cjs/lib/sctp/sctp.js +1467 -0
- package/dist/cjs/lib/sctp/transport.d.ts +15 -0
- package/dist/cjs/lib/sctp/transport.js +28 -0
- package/dist/cjs/lib/turn/index.d.ts +9 -0
- package/dist/cjs/lib/turn/index.js +25 -0
- package/dist/cjs/lib/turn/node/server.d.ts +21 -0
- package/dist/cjs/lib/turn/node/server.js +94 -0
- package/dist/cjs/lib/turn/node/turnServer.d.ts +91 -0
- package/dist/cjs/lib/turn/node/turnServer.js +565 -0
- package/dist/cjs/lib/turn/protocol.d.ts +47 -0
- package/dist/cjs/lib/turn/protocol.js +116 -0
- package/dist/cjs/lib/turn/stun/attributes.d.ts +37 -0
- package/dist/cjs/lib/turn/stun/attributes.js +208 -0
- package/dist/cjs/lib/turn/stun/const.d.ts +28 -0
- package/dist/cjs/lib/turn/stun/const.js +87 -0
- package/dist/cjs/lib/turn/stun/ip.d.ts +12 -0
- package/dist/cjs/lib/turn/stun/ip.js +87 -0
- package/dist/cjs/lib/turn/stun/message.d.ts +37 -0
- package/dist/cjs/lib/turn/stun/message.js +180 -0
- package/dist/cjs/lib/turn/turn/auth.d.ts +1 -0
- package/dist/cjs/lib/turn/turn/auth.js +9 -0
- package/dist/cjs/lib/turn/turn/frame.d.ts +13 -0
- package/dist/cjs/lib/turn/turn/frame.js +68 -0
- package/dist/cjs/lib/turn/turn/protocol.d.ts +147 -0
- package/dist/cjs/lib/turn/turn/protocol.js +785 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/peer/Endpoints.d.ts +75 -0
- package/dist/cjs/peer/Endpoints.js +154 -0
- package/dist/cjs/peer/EngineConfig.d.ts +20 -0
- package/dist/cjs/peer/EngineConfig.js +36 -0
- package/dist/cjs/peer/EngineConnection.d.ts +22 -0
- package/dist/cjs/peer/EngineConnection.js +27 -0
- package/dist/cjs/peer/Events.d.ts +55 -0
- package/dist/cjs/peer/Events.js +85 -0
- package/dist/cjs/peer/MediaCodecs.d.ts +27 -0
- package/dist/cjs/peer/MediaCodecs.js +53 -0
- package/dist/cjs/peer/MediaTrack.d.ts +212 -0
- package/dist/cjs/peer/MediaTrack.js +313 -0
- package/dist/cjs/peer/PeerChannel.d.ts +248 -0
- package/dist/cjs/peer/PeerChannel.js +319 -0
- package/dist/cjs/peer/PeerConnection.d.ts +603 -0
- package/dist/cjs/peer/PeerConnection.js +697 -0
- package/dist/cjs/peer/PeerThreadChannel.d.ts +112 -0
- package/dist/cjs/peer/PeerThreadChannel.js +273 -0
- package/dist/cjs/peer/PeerThreadProtocol.d.ts +325 -0
- package/dist/cjs/peer/PeerThreadProtocol.js +2 -0
- package/dist/cjs/peer/PeerThreads.d.ts +114 -0
- package/dist/cjs/peer/PeerThreads.js +268 -0
- package/dist/cjs/peer/PeerWorker.d.ts +6 -0
- package/dist/cjs/peer/PeerWorker.js +461 -0
- package/dist/cjs/peer/PeerWorkerCode.d.ts +5 -0
- package/dist/cjs/peer/PeerWorkerCode.js +4 -0
- package/dist/cjs/peer/RemoteConnection.d.ts +314 -0
- package/dist/cjs/peer/RemoteConnection.js +913 -0
- package/dist/cjs/peer/RtpPacket.d.ts +112 -0
- package/dist/cjs/peer/RtpPacket.js +92 -0
- package/dist/cjs/peer/RtpTransceiver.d.ts +167 -0
- package/dist/cjs/peer/RtpTransceiver.js +235 -0
- package/dist/cjs/peer/SignalingClient.d.ts +236 -0
- package/dist/cjs/peer/SignalingClient.js +285 -0
- package/dist/cjs/protocol/SignalingProtocol.d.ts +266 -0
- package/dist/cjs/protocol/SignalingProtocol.js +65 -0
- package/dist/cjs/service/WebRTCServiceEntrypoint.d.ts +158 -0
- package/dist/cjs/service/WebRTCServiceEntrypoint.js +356 -0
- package/dist/cjs/sfu/SFU.d.ts +356 -0
- package/dist/cjs/sfu/SFU.js +763 -0
- package/dist/cjs/sfu/SFUAccess.d.ts +48 -0
- package/dist/cjs/sfu/SFUAccess.js +15 -0
- package/dist/cjs/sfu/SFUClusterLeg.d.ts +101 -0
- package/dist/cjs/sfu/SFUClusterLeg.js +106 -0
- package/dist/cjs/sfu/SFURoom.d.ts +148 -0
- package/dist/cjs/sfu/SFURoom.js +1300 -0
- package/dist/cjs/sfu/SFUWorker.d.ts +13 -0
- package/dist/cjs/sfu/SFUWorker.js +168 -0
- package/dist/cjs/sfu/SFUWorkerChannel.d.ts +204 -0
- package/dist/cjs/sfu/SFUWorkerChannel.js +105 -0
- package/dist/cjs/sfu/SFUWorkerCode.d.ts +5 -0
- package/dist/cjs/sfu/SFUWorkerCode.js +4 -0
- package/dist/cjs/sfu/SFUWorkers.d.ts +247 -0
- package/dist/cjs/sfu/SFUWorkers.js +552 -0
- package/dist/cjs/shared/ChunkedChannel.d.ts +122 -0
- package/dist/cjs/shared/ChunkedChannel.js +182 -0
- package/dist/cjs/shared/Connections.d.ts +231 -0
- package/dist/cjs/shared/Connections.js +2 -0
- package/dist/cjs/shared/Emitter.d.ts +50 -0
- package/dist/cjs/shared/Emitter.js +80 -0
- package/dist/cjs/shared/Peer.d.ts +182 -0
- package/dist/cjs/shared/Peer.js +509 -0
- package/dist/cjs/shared/PeerServiceProxy.d.ts +173 -0
- package/dist/cjs/shared/PeerServiceProxy.js +304 -0
- package/dist/cjs/shared/Room.d.ts +143 -0
- package/dist/cjs/shared/Room.js +515 -0
- package/dist/cjs/shared/SignalingError.d.ts +40 -0
- package/dist/cjs/shared/SignalingError.js +48 -0
- package/dist/cjs/shared/SignalingSession.d.ts +97 -0
- package/dist/cjs/shared/SignalingSession.js +347 -0
- package/dist/cjs/shared/Transports.d.ts +139 -0
- package/dist/cjs/shared/Transports.js +285 -0
- package/dist/cjs/signaling/MediaServers.d.ts +40 -0
- package/dist/cjs/signaling/MediaServers.js +16 -0
- package/dist/cjs/signaling/Signaling.d.ts +573 -0
- package/dist/cjs/signaling/Signaling.js +945 -0
- package/dist/cjs/signaling/SignalingController.d.ts +128 -0
- package/dist/cjs/signaling/SignalingController.js +229 -0
- package/dist/cjs/turn/TURNCredentials.d.ts +49 -0
- package/dist/cjs/turn/TURNCredentials.js +49 -0
- package/dist/cjs/turn/TURNIceServers.d.ts +11 -0
- package/dist/cjs/turn/TURNIceServers.js +25 -0
- package/dist/cjs/turn/TURNServer.d.ts +309 -0
- package/dist/cjs/turn/TURNServer.js +331 -0
- package/dist/cjs/turn/TURNWorker.d.ts +42 -0
- package/dist/cjs/turn/TURNWorker.js +52 -0
- package/dist/cjs/turn/TURNWorkerCode.d.ts +5 -0
- package/dist/cjs/turn/TURNWorkerCode.js +4 -0
- package/dist/cjs/turn/TURNWorkers.d.ts +52 -0
- package/dist/cjs/turn/TURNWorkers.js +211 -0
- package/dist/cjs/whep/WHEP.d.ts +386 -0
- package/dist/cjs/whep/WHEP.js +426 -0
- package/dist/cjs/whep/WHEPController.d.ts +134 -0
- package/dist/cjs/whep/WHEPController.js +301 -0
- package/dist/cjs/whip/WHIP.d.ts +426 -0
- package/dist/cjs/whip/WHIP.js +470 -0
- package/dist/cjs/whip/WHIPController.d.ts +132 -0
- package/dist/cjs/whip/WHIPController.js +299 -0
- package/dist/esm/client/SignalingConnection.js +63 -0
- package/dist/esm/cluster/Cluster.js +542 -0
- package/dist/esm/cluster/ClusterFrames.js +85 -0
- package/dist/esm/cluster/ClusterTURN.js +73 -0
- package/dist/esm/cluster/Rendezvous.js +20 -0
- package/dist/esm/cluster/transports/ClusterTransport.js +1 -0
- package/dist/esm/cluster/transports/LoadClient.js +44 -0
- package/dist/esm/cluster/transports/MemoryClusterTransport.js +43 -0
- package/dist/esm/cluster/transports/NATSClusterTransport.js +66 -0
- package/dist/esm/cluster/transports/RedisClusterTransport.js +73 -0
- package/dist/esm/exceptions/ClusterRequestException.js +14 -0
- package/dist/esm/exceptions/ClusterTimeoutException.js +13 -0
- package/dist/esm/exceptions/ClusterTransportNotFoundException.js +14 -0
- package/dist/esm/exceptions/SignalingClientRequiredException.js +15 -0
- package/dist/esm/exceptions/SignalingConnectionException.js +15 -0
- package/dist/esm/exceptions/SignalingDeniedException.js +14 -0
- package/dist/esm/exceptions/SignalingLimitException.js +14 -0
- package/dist/esm/exceptions/SignalingNotAMemberException.js +14 -0
- package/dist/esm/exceptions/WHEPDeniedException.js +18 -0
- package/dist/esm/exceptions/WHEPLimitException.js +18 -0
- package/dist/esm/exceptions/WHEPMediaTypeException.js +18 -0
- package/dist/esm/exceptions/WHEPOfferException.js +19 -0
- package/dist/esm/exceptions/WHEPSessionNotFoundException.js +18 -0
- package/dist/esm/exceptions/WHIPDeniedException.js +18 -0
- package/dist/esm/exceptions/WHIPLimitException.js +18 -0
- package/dist/esm/exceptions/WHIPMediaTypeException.js +18 -0
- package/dist/esm/exceptions/WHIPOfferException.js +19 -0
- package/dist/esm/exceptions/WHIPSessionNotFoundException.js +18 -0
- package/dist/esm/exports/Client.js +5 -0
- package/dist/esm/exports/WebRTC.js +41 -0
- package/dist/esm/lib/common/binary.js +244 -0
- package/dist/esm/lib/common/binaryData.js +392 -0
- package/dist/esm/lib/common/crc.js +118 -0
- package/dist/esm/lib/common/deque.js +85 -0
- package/dist/esm/lib/common/event.js +202 -0
- package/dist/esm/lib/common/index.js +11 -0
- package/dist/esm/lib/common/log.js +55 -0
- package/dist/esm/lib/common/network.js +52 -0
- package/dist/esm/lib/common/number.js +31 -0
- package/dist/esm/lib/common/promise.js +64 -0
- package/dist/esm/lib/common/transport.js +401 -0
- package/dist/esm/lib/common/type.js +1 -0
- package/dist/esm/lib/dtls/cipher/const.js +30 -0
- package/dist/esm/lib/dtls/cipher/create.js +98 -0
- package/dist/esm/lib/dtls/cipher/ec.js +37 -0
- package/dist/esm/lib/dtls/cipher/key-exchange.js +103 -0
- package/dist/esm/lib/dtls/cipher/namedCurve.js +24 -0
- package/dist/esm/lib/dtls/cipher/prf.js +79 -0
- package/dist/esm/lib/dtls/cipher/suites/abstract.js +37 -0
- package/dist/esm/lib/dtls/cipher/suites/aead.js +96 -0
- package/dist/esm/lib/dtls/cipher/suites/null.js +35 -0
- package/dist/esm/lib/dtls/cipher/utils.js +34 -0
- package/dist/esm/lib/dtls/cipher/x509.js +94 -0
- package/dist/esm/lib/dtls/client.js +72 -0
- package/dist/esm/lib/dtls/context/cipher.js +83 -0
- package/dist/esm/lib/dtls/context/dtls.js +45 -0
- package/dist/esm/lib/dtls/context/srtp.js +8 -0
- package/dist/esm/lib/dtls/context/transport.js +13 -0
- package/dist/esm/lib/dtls/flight/client/flight1.js +22 -0
- package/dist/esm/lib/dtls/flight/client/flight3.js +21 -0
- package/dist/esm/lib/dtls/flight/client/flight5.js +202 -0
- package/dist/esm/lib/dtls/flight/flight.js +64 -0
- package/dist/esm/lib/dtls/flight/server/flight2.js +122 -0
- package/dist/esm/lib/dtls/flight/server/flight4.js +83 -0
- package/dist/esm/lib/dtls/flight/server/flight6.js +107 -0
- package/dist/esm/lib/dtls/handshake/binary.js +17 -0
- package/dist/esm/lib/dtls/handshake/const.js +14 -0
- package/dist/esm/lib/dtls/handshake/extensions/ellipticCurves.js +36 -0
- package/dist/esm/lib/dtls/handshake/extensions/extendedMasterSecret.js +3 -0
- package/dist/esm/lib/dtls/handshake/extensions/renegotiationIndication.js +30 -0
- package/dist/esm/lib/dtls/handshake/extensions/signature.js +35 -0
- package/dist/esm/lib/dtls/handshake/extensions/useSrtp.js +61 -0
- package/dist/esm/lib/dtls/handshake/message/alert.js +20 -0
- package/dist/esm/lib/dtls/handshake/message/certificate.js +31 -0
- package/dist/esm/lib/dtls/handshake/message/changeCipherSpec.js +20 -0
- package/dist/esm/lib/dtls/handshake/message/client/certificateVerify.js +31 -0
- package/dist/esm/lib/dtls/handshake/message/client/hello.js +44 -0
- package/dist/esm/lib/dtls/handshake/message/client/keyExchange.js +29 -0
- package/dist/esm/lib/dtls/handshake/message/finished.js +22 -0
- package/dist/esm/lib/dtls/handshake/message/server/certificateRequest.js +34 -0
- package/dist/esm/lib/dtls/handshake/message/server/hello.js +53 -0
- package/dist/esm/lib/dtls/handshake/message/server/helloDone.js +26 -0
- package/dist/esm/lib/dtls/handshake/message/server/helloVerifyRequest.js +38 -0
- package/dist/esm/lib/dtls/handshake/message/server/keyExchange.js +45 -0
- package/dist/esm/lib/dtls/handshake/random.js +25 -0
- package/dist/esm/lib/dtls/helper.js +23 -0
- package/dist/esm/lib/dtls/imports/common.js +1 -0
- package/dist/esm/lib/dtls/imports/rtp.js +1 -0
- package/dist/esm/lib/dtls/index.js +97 -0
- package/dist/esm/lib/dtls/record/antiReplayWindow.js +98 -0
- package/dist/esm/lib/dtls/record/builder.js +22 -0
- package/dist/esm/lib/dtls/record/const.js +35 -0
- package/dist/esm/lib/dtls/record/message/fragment.js +92 -0
- package/dist/esm/lib/dtls/record/message/header.js +30 -0
- package/dist/esm/lib/dtls/record/message/plaintext.js +59 -0
- package/dist/esm/lib/dtls/record/receive.js +86 -0
- package/dist/esm/lib/dtls/server.js +74 -0
- package/dist/esm/lib/dtls/socket.js +184 -0
- package/dist/esm/lib/dtls/typings/domain.js +1 -0
- package/dist/esm/lib/dtls/util/binary.js +5 -0
- package/dist/esm/lib/ice/candidate.js +190 -0
- package/dist/esm/lib/ice/dns/lookup.js +95 -0
- package/dist/esm/lib/ice/dns/mdns.js +139 -0
- package/dist/esm/lib/ice/exceptions.js +34 -0
- package/dist/esm/lib/ice/helper.js +65 -0
- package/dist/esm/lib/ice/ice.js +1547 -0
- package/dist/esm/lib/ice/iceBase.js +172 -0
- package/dist/esm/lib/ice/imports/common.js +1 -0
- package/dist/esm/lib/ice/index.js +12 -0
- package/dist/esm/lib/ice/internal/selectAddresses.js +36 -0
- package/dist/esm/lib/ice/stun/attributes.js +1 -0
- package/dist/esm/lib/ice/stun/const.js +8 -0
- package/dist/esm/lib/ice/stun/message.js +1 -0
- package/dist/esm/lib/ice/stun/protocol.js +121 -0
- package/dist/esm/lib/ice/stun/tcpFrame.js +21 -0
- package/dist/esm/lib/ice/stun/tcpProtocol.js +318 -0
- package/dist/esm/lib/ice/stun/transaction.js +230 -0
- package/dist/esm/lib/ice/turn/frame.js +1 -0
- package/dist/esm/lib/ice/turn/protocol.js +630 -0
- package/dist/esm/lib/ice/types/model.js +1 -0
- package/dist/esm/lib/ice/utils.js +43 -0
- package/dist/esm/lib/peer/const.js +50 -0
- package/dist/esm/lib/peer/dataChannel.js +127 -0
- package/dist/esm/lib/peer/errors.js +17 -0
- package/dist/esm/lib/peer/helper.js +77 -0
- package/dist/esm/lib/peer/imports/common.js +1 -0
- package/dist/esm/lib/peer/imports/dtls.js +1 -0
- package/dist/esm/lib/peer/imports/ice.js +1 -0
- package/dist/esm/lib/peer/imports/rtp.js +1 -0
- package/dist/esm/lib/peer/index.js +14 -0
- package/dist/esm/lib/peer/media/codec.js +69 -0
- package/dist/esm/lib/peer/media/codecCompatibility.js +128 -0
- package/dist/esm/lib/peer/media/extension/rtcpFeedback.js +5 -0
- package/dist/esm/lib/peer/media/extension/rtpExtension.js +42 -0
- package/dist/esm/lib/peer/media/index.js +12 -0
- package/dist/esm/lib/peer/media/parameters.js +50 -0
- package/dist/esm/lib/peer/media/receiver/nack.js +100 -0
- package/dist/esm/lib/peer/media/receiver/receiverTwcc.js +175 -0
- package/dist/esm/lib/peer/media/receiver/statistics.js +67 -0
- package/dist/esm/lib/peer/media/router.js +162 -0
- package/dist/esm/lib/peer/media/rtpReceiver.js +403 -0
- package/dist/esm/lib/peer/media/rtpSender.js +822 -0
- package/dist/esm/lib/peer/media/rtpTransceiver.js +241 -0
- package/dist/esm/lib/peer/media/sender/cumulativeResult.js +57 -0
- package/dist/esm/lib/peer/media/sender/senderBWE.js +95 -0
- package/dist/esm/lib/peer/media/stats.js +81 -0
- package/dist/esm/lib/peer/media/track.js +208 -0
- package/dist/esm/lib/peer/peerConnection.js +1585 -0
- package/dist/esm/lib/peer/sctpManager.js +134 -0
- package/dist/esm/lib/peer/sdp.js +614 -0
- package/dist/esm/lib/peer/sdpManager.js +569 -0
- package/dist/esm/lib/peer/secureTransportManager.js +468 -0
- package/dist/esm/lib/peer/transceiverManager.js +763 -0
- package/dist/esm/lib/peer/transport/dtls.js +564 -0
- package/dist/esm/lib/peer/transport/ice.js +426 -0
- package/dist/esm/lib/peer/transport/sctp.js +382 -0
- package/dist/esm/lib/peer/types/domain.js +16 -0
- package/dist/esm/lib/peer/types/util.js +1 -0
- package/dist/esm/lib/peer/utils.js +286 -0
- package/dist/esm/lib/rtp/codec/av1.js +203 -0
- package/dist/esm/lib/rtp/codec/base.js +11 -0
- package/dist/esm/lib/rtp/codec/h264.js +118 -0
- package/dist/esm/lib/rtp/codec/index.js +66 -0
- package/dist/esm/lib/rtp/codec/leb128.js +20 -0
- package/dist/esm/lib/rtp/codec/opus.js +21 -0
- package/dist/esm/lib/rtp/codec/vp8.js +105 -0
- package/dist/esm/lib/rtp/codec/vp9.js +157 -0
- package/dist/esm/lib/rtp/const.js +1 -0
- package/dist/esm/lib/rtp/helper.js +29 -0
- package/dist/esm/lib/rtp/imports/common.js +1 -0
- package/dist/esm/lib/rtp/index.js +25 -0
- package/dist/esm/lib/rtp/rtcp/header.js +46 -0
- package/dist/esm/lib/rtp/rtcp/psfb/fullIntraRequest.js +30 -0
- package/dist/esm/lib/rtp/rtcp/psfb/index.js +35 -0
- package/dist/esm/lib/rtp/rtcp/psfb/pictureLossIndication.js +16 -0
- package/dist/esm/lib/rtp/rtcp/psfb/remb.js +49 -0
- package/dist/esm/lib/rtp/rtcp/rr.js +68 -0
- package/dist/esm/lib/rtp/rtcp/rtcp.js +53 -0
- package/dist/esm/lib/rtp/rtcp/rtpfb/const.js +1 -0
- package/dist/esm/lib/rtp/rtcp/rtpfb/index.js +31 -0
- package/dist/esm/lib/rtp/rtcp/rtpfb/nack.js +73 -0
- package/dist/esm/lib/rtp/rtcp/rtpfb/twcc.js +344 -0
- package/dist/esm/lib/rtp/rtcp/sdes.js +91 -0
- package/dist/esm/lib/rtp/rtcp/sr.js +104 -0
- package/dist/esm/lib/rtp/rtp/headerExtension.js +102 -0
- package/dist/esm/lib/rtp/rtp/red/encoder.js +40 -0
- package/dist/esm/lib/rtp/rtp/red/handler.js +55 -0
- package/dist/esm/lib/rtp/rtp/red/packet.js +107 -0
- package/dist/esm/lib/rtp/rtp/rtp.js +266 -0
- package/dist/esm/lib/rtp/rtp/rtx.js +25 -0
- package/dist/esm/lib/rtp/srtp/cipher/ctr.js +103 -0
- package/dist/esm/lib/rtp/srtp/cipher/gcm.js +141 -0
- package/dist/esm/lib/rtp/srtp/cipher/index.js +20 -0
- package/dist/esm/lib/rtp/srtp/const.js +21 -0
- package/dist/esm/lib/rtp/srtp/context/context.js +175 -0
- package/dist/esm/lib/rtp/srtp/context/srtcp.js +21 -0
- package/dist/esm/lib/rtp/srtp/context/srtp.js +37 -0
- package/dist/esm/lib/rtp/srtp/error.js +6 -0
- package/dist/esm/lib/rtp/srtp/packet.js +42 -0
- package/dist/esm/lib/rtp/srtp/session.js +9 -0
- package/dist/esm/lib/rtp/srtp/srtcp.js +17 -0
- package/dist/esm/lib/rtp/srtp/srtp.js +16 -0
- package/dist/esm/lib/rtp/transport.js +18 -0
- package/dist/esm/lib/rtp/util.js +24 -0
- package/dist/esm/lib/sctp/chunk.js +515 -0
- package/dist/esm/lib/sctp/const.js +19 -0
- package/dist/esm/lib/sctp/helper.js +10 -0
- package/dist/esm/lib/sctp/imports/common.js +1 -0
- package/dist/esm/lib/sctp/index.js +4 -0
- package/dist/esm/lib/sctp/param.js +126 -0
- package/dist/esm/lib/sctp/sctp.js +1459 -0
- package/dist/esm/lib/sctp/transport.js +23 -0
- package/dist/esm/lib/turn/index.js +9 -0
- package/dist/esm/lib/turn/node/server.js +89 -0
- package/dist/esm/lib/turn/node/turnServer.js +560 -0
- package/dist/esm/lib/turn/protocol.js +112 -0
- package/dist/esm/lib/turn/stun/attributes.js +198 -0
- package/dist/esm/lib/turn/stun/const.js +82 -0
- package/dist/esm/lib/turn/stun/ip.js +81 -0
- package/dist/esm/lib/turn/stun/message.js +174 -0
- package/dist/esm/lib/turn/turn/auth.js +6 -0
- package/dist/esm/lib/turn/turn/frame.js +61 -0
- package/dist/esm/lib/turn/turn/protocol.js +781 -0
- package/dist/esm/peer/Endpoints.js +143 -0
- package/dist/esm/peer/EngineConfig.js +33 -0
- package/dist/esm/peer/EngineConnection.js +22 -0
- package/dist/esm/peer/Events.js +81 -0
- package/dist/esm/peer/MediaCodecs.js +47 -0
- package/dist/esm/peer/MediaTrack.js +305 -0
- package/dist/esm/peer/PeerChannel.js +315 -0
- package/dist/esm/peer/PeerConnection.js +694 -0
- package/dist/esm/peer/PeerThreadChannel.js +266 -0
- package/dist/esm/peer/PeerThreadProtocol.js +1 -0
- package/dist/esm/peer/PeerThreads.js +264 -0
- package/dist/esm/peer/PeerWorker.js +458 -0
- package/dist/esm/peer/PeerWorkerCode.js +1 -0
- package/dist/esm/peer/RemoteConnection.js +905 -0
- package/dist/esm/peer/RtpPacket.js +86 -0
- package/dist/esm/peer/RtpTransceiver.js +225 -0
- package/dist/esm/peer/SignalingClient.js +249 -0
- package/dist/esm/protocol/SignalingProtocol.js +62 -0
- package/dist/esm/service/WebRTCServiceEntrypoint.js +352 -0
- package/dist/esm/sfu/SFU.js +759 -0
- package/dist/esm/sfu/SFUAccess.js +12 -0
- package/dist/esm/sfu/SFUClusterLeg.js +102 -0
- package/dist/esm/sfu/SFURoom.js +1296 -0
- package/dist/esm/sfu/SFUWorker.js +165 -0
- package/dist/esm/sfu/SFUWorkerChannel.js +101 -0
- package/dist/esm/sfu/SFUWorkerCode.js +1 -0
- package/dist/esm/sfu/SFUWorkers.js +547 -0
- package/dist/esm/shared/ChunkedChannel.js +178 -0
- package/dist/esm/shared/Connections.js +1 -0
- package/dist/esm/shared/Emitter.js +76 -0
- package/dist/esm/shared/Peer.js +505 -0
- package/dist/esm/shared/PeerServiceProxy.js +299 -0
- package/dist/esm/shared/Room.js +511 -0
- package/dist/esm/shared/SignalingError.js +43 -0
- package/dist/esm/shared/SignalingSession.js +343 -0
- package/dist/esm/shared/Transports.js +279 -0
- package/dist/esm/signaling/MediaServers.js +13 -0
- package/dist/esm/signaling/Signaling.js +941 -0
- package/dist/esm/signaling/SignalingController.js +225 -0
- package/dist/esm/turn/TURNCredentials.js +44 -0
- package/dist/esm/turn/TURNIceServers.js +22 -0
- package/dist/esm/turn/TURNServer.js +327 -0
- package/dist/esm/turn/TURNWorker.js +49 -0
- package/dist/esm/turn/TURNWorkerCode.js +1 -0
- package/dist/esm/turn/TURNWorkers.js +206 -0
- package/dist/esm/whep/WHEP.js +422 -0
- package/dist/esm/whep/WHEPController.js +298 -0
- package/dist/esm/whip/WHIP.js +466 -0
- package/dist/esm/whip/WHIPController.js +296 -0
- package/dist/types/client/SignalingConnection.d.ts +81 -0
- package/dist/types/cluster/Cluster.d.ts +503 -0
- package/dist/types/cluster/ClusterFrames.d.ts +24 -0
- package/dist/types/cluster/ClusterTURN.d.ts +63 -0
- package/dist/types/cluster/Rendezvous.d.ts +8 -0
- package/dist/types/cluster/transports/ClusterTransport.d.ts +34 -0
- package/dist/types/cluster/transports/LoadClient.d.ts +6 -0
- package/dist/types/cluster/transports/MemoryClusterTransport.d.ts +13 -0
- package/dist/types/cluster/transports/NATSClusterTransport.d.ts +23 -0
- package/dist/types/cluster/transports/RedisClusterTransport.d.ts +23 -0
- package/dist/types/exceptions/ClusterRequestException.d.ts +11 -0
- package/dist/types/exceptions/ClusterTimeoutException.d.ts +10 -0
- package/dist/types/exceptions/ClusterTransportNotFoundException.d.ts +11 -0
- package/dist/types/exceptions/SignalingClientRequiredException.d.ts +12 -0
- package/dist/types/exceptions/SignalingConnectionException.d.ts +12 -0
- package/dist/types/exceptions/SignalingDeniedException.d.ts +11 -0
- package/dist/types/exceptions/SignalingLimitException.d.ts +11 -0
- package/dist/types/exceptions/SignalingNotAMemberException.d.ts +11 -0
- package/dist/types/exceptions/WHEPDeniedException.d.ts +15 -0
- package/dist/types/exceptions/WHEPLimitException.d.ts +15 -0
- package/dist/types/exceptions/WHEPMediaTypeException.d.ts +15 -0
- package/dist/types/exceptions/WHEPOfferException.d.ts +16 -0
- package/dist/types/exceptions/WHEPSessionNotFoundException.d.ts +15 -0
- package/dist/types/exceptions/WHIPDeniedException.d.ts +15 -0
- package/dist/types/exceptions/WHIPLimitException.d.ts +15 -0
- package/dist/types/exceptions/WHIPMediaTypeException.d.ts +15 -0
- package/dist/types/exceptions/WHIPOfferException.d.ts +16 -0
- package/dist/types/exceptions/WHIPSessionNotFoundException.d.ts +15 -0
- package/dist/types/exports/Client.d.ts +11 -0
- package/dist/types/exports/WebRTC.d.ts +48 -0
- package/dist/types/lib/common/binary.d.ts +51 -0
- package/dist/types/lib/common/binaryData.d.ts +116 -0
- package/dist/types/lib/common/crc.d.ts +4 -0
- package/dist/types/lib/common/deque.d.ts +36 -0
- package/dist/types/lib/common/event.d.ts +48 -0
- package/dist/types/lib/common/index.d.ts +11 -0
- package/dist/types/lib/common/log.d.ts +47 -0
- package/dist/types/lib/common/network.d.ts +10 -0
- package/dist/types/lib/common/number.d.ts +13 -0
- package/dist/types/lib/common/promise.d.ts +21 -0
- package/dist/types/lib/common/transport.d.ts +104 -0
- package/dist/types/lib/common/type.d.ts +3 -0
- package/dist/types/lib/dtls/cipher/const.d.ts +42 -0
- package/dist/types/lib/dtls/cipher/create.d.ts +21 -0
- package/dist/types/lib/dtls/cipher/ec.d.ts +28 -0
- package/dist/types/lib/dtls/cipher/key-exchange.d.ts +43 -0
- package/dist/types/lib/dtls/cipher/namedCurve.d.ts +7 -0
- package/dist/types/lib/dtls/cipher/prf.d.ts +17 -0
- package/dist/types/lib/dtls/cipher/suites/abstract.d.ts +40 -0
- package/dist/types/lib/dtls/cipher/suites/aead.d.ts +28 -0
- package/dist/types/lib/dtls/cipher/suites/null.d.ts +24 -0
- package/dist/types/lib/dtls/cipher/utils.d.ts +18 -0
- package/dist/types/lib/dtls/cipher/x509.d.ts +33 -0
- package/dist/types/lib/dtls/client.d.ts +7 -0
- package/dist/types/lib/dtls/context/cipher.d.ts +42 -0
- package/dist/types/lib/dtls/context/dtls.d.ts +38 -0
- package/dist/types/lib/dtls/context/srtp.d.ts +5 -0
- package/dist/types/lib/dtls/context/transport.d.ts +8 -0
- package/dist/types/lib/dtls/flight/client/flight1.d.ts +10 -0
- package/dist/types/lib/dtls/flight/client/flight3.d.ts +8 -0
- package/dist/types/lib/dtls/flight/client/flight5.d.ts +18 -0
- package/dist/types/lib/dtls/flight/flight.d.ts +18 -0
- package/dist/types/lib/dtls/flight/server/flight2.d.ts +6 -0
- package/dist/types/lib/dtls/flight/server/flight4.d.ts +17 -0
- package/dist/types/lib/dtls/flight/server/flight6.d.ts +13 -0
- package/dist/types/lib/dtls/handshake/binary.d.ts +16 -0
- package/dist/types/lib/dtls/handshake/const.d.ts +13 -0
- package/dist/types/lib/dtls/handshake/extensions/ellipticCurves.d.ts +17 -0
- package/dist/types/lib/dtls/handshake/extensions/extendedMasterSecret.d.ts +3 -0
- package/dist/types/lib/dtls/handshake/extensions/renegotiationIndication.d.ts +18 -0
- package/dist/types/lib/dtls/handshake/extensions/signature.d.ts +26 -0
- package/dist/types/lib/dtls/handshake/extensions/useSrtp.d.ts +19 -0
- package/dist/types/lib/dtls/handshake/message/alert.d.ts +12 -0
- package/dist/types/lib/dtls/handshake/message/certificate.d.ts +17 -0
- package/dist/types/lib/dtls/handshake/message/changeCipherSpec.d.ts +11 -0
- package/dist/types/lib/dtls/handshake/message/client/certificateVerify.d.ts +20 -0
- package/dist/types/lib/dtls/handshake/message/client/hello.d.ts +50 -0
- package/dist/types/lib/dtls/handshake/message/client/keyExchange.d.ts +17 -0
- package/dist/types/lib/dtls/handshake/message/finished.d.ts +13 -0
- package/dist/types/lib/dtls/handshake/message/server/certificateRequest.d.ts +31 -0
- package/dist/types/lib/dtls/handshake/message/server/hello.d.ts +33 -0
- package/dist/types/lib/dtls/handshake/message/server/helloDone.d.ts +12 -0
- package/dist/types/lib/dtls/handshake/message/server/helloVerifyRequest.d.ts +32 -0
- package/dist/types/lib/dtls/handshake/message/server/keyExchange.d.ts +32 -0
- package/dist/types/lib/dtls/handshake/random.d.ts +13 -0
- package/dist/types/lib/dtls/helper.d.ts +4 -0
- package/dist/types/lib/dtls/imports/common.d.ts +1 -0
- package/dist/types/lib/dtls/imports/rtp.d.ts +1 -0
- package/dist/types/lib/dtls/index.d.ts +7 -0
- package/dist/types/lib/dtls/record/antiReplayWindow.d.ts +27 -0
- package/dist/types/lib/dtls/record/builder.d.ts +9 -0
- package/dist/types/lib/dtls/record/const.d.ts +33 -0
- package/dist/types/lib/dtls/record/message/fragment.d.ts +26 -0
- package/dist/types/lib/dtls/record/message/header.d.ts +38 -0
- package/dist/types/lib/dtls/record/message/plaintext.d.ts +14 -0
- package/dist/types/lib/dtls/record/receive.d.ts +9 -0
- package/dist/types/lib/dtls/server.d.ts +6 -0
- package/dist/types/lib/dtls/socket.d.ts +52 -0
- package/dist/types/lib/dtls/typings/domain.d.ts +20 -0
- package/dist/types/lib/dtls/util/binary.d.ts +2 -0
- package/dist/types/lib/ice/candidate.d.ts +35 -0
- package/dist/types/lib/ice/dns/lookup.d.ts +16 -0
- package/dist/types/lib/ice/dns/mdns.d.ts +38 -0
- package/dist/types/lib/ice/exceptions.d.ts +24 -0
- package/dist/types/lib/ice/helper.d.ts +17 -0
- package/dist/types/lib/ice/ice.d.ts +182 -0
- package/dist/types/lib/ice/iceBase.d.ts +214 -0
- package/dist/types/lib/ice/imports/common.d.ts +1 -0
- package/dist/types/lib/ice/index.d.ts +12 -0
- package/dist/types/lib/ice/internal/selectAddresses.d.ts +9 -0
- package/dist/types/lib/ice/stun/attributes.d.ts +1 -0
- package/dist/types/lib/ice/stun/const.d.ts +8 -0
- package/dist/types/lib/ice/stun/message.d.ts +1 -0
- package/dist/types/lib/ice/stun/protocol.d.ts +30 -0
- package/dist/types/lib/ice/stun/tcpFrame.d.ts +5 -0
- package/dist/types/lib/ice/stun/tcpProtocol.d.ts +57 -0
- package/dist/types/lib/ice/stun/transaction.d.ts +75 -0
- package/dist/types/lib/ice/turn/frame.d.ts +1 -0
- package/dist/types/lib/ice/turn/protocol.d.ts +170 -0
- package/dist/types/lib/ice/types/model.d.ts +56 -0
- package/dist/types/lib/ice/utils.d.ts +13 -0
- package/dist/types/lib/peer/const.d.ts +36 -0
- package/dist/types/lib/peer/dataChannel.d.ts +69 -0
- package/dist/types/lib/peer/errors.d.ts +11 -0
- package/dist/types/lib/peer/helper.d.ts +20 -0
- package/dist/types/lib/peer/imports/common.d.ts +1 -0
- package/dist/types/lib/peer/imports/dtls.d.ts +1 -0
- package/dist/types/lib/peer/imports/ice.d.ts +1 -0
- package/dist/types/lib/peer/imports/rtp.d.ts +1 -0
- package/dist/types/lib/peer/index.d.ts +14 -0
- package/dist/types/lib/peer/media/codec.d.ts +15 -0
- package/dist/types/lib/peer/media/codecCompatibility.d.ts +23 -0
- package/dist/types/lib/peer/media/extension/rtcpFeedback.d.ts +6 -0
- package/dist/types/lib/peer/media/extension/rtpExtension.d.ts +9 -0
- package/dist/types/lib/peer/media/index.d.ts +12 -0
- package/dist/types/lib/peer/media/parameters.d.ts +65 -0
- package/dist/types/lib/peer/media/receiver/nack.d.ts +23 -0
- package/dist/types/lib/peer/media/receiver/receiverTwcc.d.ts +47 -0
- package/dist/types/lib/peer/media/receiver/statistics.d.ts +22 -0
- package/dist/types/lib/peer/media/router.d.ts +25 -0
- package/dist/types/lib/peer/media/rtpReceiver.d.ts +90 -0
- package/dist/types/lib/peer/media/rtpSender.d.ts +209 -0
- package/dist/types/lib/peer/media/rtpTransceiver.d.ts +117 -0
- package/dist/types/lib/peer/media/sender/cumulativeResult.d.ts +19 -0
- package/dist/types/lib/peer/media/sender/senderBWE.d.ts +32 -0
- package/dist/types/lib/peer/media/stats.d.ts +293 -0
- package/dist/types/lib/peer/media/track.d.ts +67 -0
- package/dist/types/lib/peer/peerConnection.d.ts +458 -0
- package/dist/types/lib/peer/sctpManager.d.ts +28 -0
- package/dist/types/lib/peer/sdp.d.ts +97 -0
- package/dist/types/lib/peer/sdpManager.d.ts +116 -0
- package/dist/types/lib/peer/secureTransportManager.d.ts +96 -0
- package/dist/types/lib/peer/transceiverManager.d.ts +151 -0
- package/dist/types/lib/peer/transport/dtls.d.ts +95 -0
- package/dist/types/lib/peer/transport/ice.d.ts +143 -0
- package/dist/types/lib/peer/transport/sctp.d.ts +56 -0
- package/dist/types/lib/peer/types/domain.d.ts +5 -0
- package/dist/types/lib/peer/types/util.d.ts +2 -0
- package/dist/types/lib/peer/utils.d.ts +73 -0
- package/dist/types/lib/rtp/codec/av1.d.ts +56 -0
- package/dist/types/lib/rtp/codec/base.d.ts +8 -0
- package/dist/types/lib/rtp/codec/h264.d.ts +32 -0
- package/dist/types/lib/rtp/codec/index.d.ts +16 -0
- package/dist/types/lib/rtp/codec/leb128.d.ts +5 -0
- package/dist/types/lib/rtp/codec/opus.d.ts +9 -0
- package/dist/types/lib/rtp/codec/vp8.d.ts +27 -0
- package/dist/types/lib/rtp/codec/vp9.d.ts +46 -0
- package/dist/types/lib/rtp/const.d.ts +1 -0
- package/dist/types/lib/rtp/helper.d.ts +8 -0
- package/dist/types/lib/rtp/imports/common.d.ts +1 -0
- package/dist/types/lib/rtp/index.d.ts +25 -0
- package/dist/types/lib/rtp/rtcp/header.d.ts +13 -0
- package/dist/types/lib/rtp/rtcp/psfb/fullIntraRequest.d.ts +16 -0
- package/dist/types/lib/rtp/rtcp/psfb/index.d.ts +14 -0
- package/dist/types/lib/rtp/rtcp/psfb/pictureLossIndication.d.ts +10 -0
- package/dist/types/lib/rtp/rtcp/psfb/remb.d.ts +16 -0
- package/dist/types/lib/rtp/rtcp/rr.d.ts +32 -0
- package/dist/types/lib/rtp/rtcp/rtcp.d.ts +10 -0
- package/dist/types/lib/rtp/rtcp/rtpfb/const.d.ts +1 -0
- package/dist/types/lib/rtp/rtcp/rtpfb/index.d.ts +14 -0
- package/dist/types/lib/rtp/rtcp/rtpfb/nack.d.ts +17 -0
- package/dist/types/lib/rtp/rtcp/rtpfb/twcc.d.ts +71 -0
- package/dist/types/lib/rtp/rtcp/sdes.d.ts +26 -0
- package/dist/types/lib/rtp/rtcp/sr.d.ts +41 -0
- package/dist/types/lib/rtp/rtp/headerExtension.d.ts +72 -0
- package/dist/types/lib/rtp/rtp/red/encoder.d.ts +13 -0
- package/dist/types/lib/rtp/rtp/red/handler.d.ts +6 -0
- package/dist/types/lib/rtp/rtp/red/packet.d.ts +26 -0
- package/dist/types/lib/rtp/rtp/rtp.d.ts +44 -0
- package/dist/types/lib/rtp/rtp/rtx.d.ts +3 -0
- package/dist/types/lib/rtp/srtp/cipher/ctr.d.ts +16 -0
- package/dist/types/lib/rtp/srtp/cipher/gcm.d.ts +17 -0
- package/dist/types/lib/rtp/srtp/cipher/index.d.ts +13 -0
- package/dist/types/lib/rtp/srtp/const.d.ts +6 -0
- package/dist/types/lib/rtp/srtp/context/context.d.ts +45 -0
- package/dist/types/lib/rtp/srtp/context/srtcp.d.ts +8 -0
- package/dist/types/lib/rtp/srtp/context/srtp.d.ts +9 -0
- package/dist/types/lib/rtp/srtp/error.d.ts +3 -0
- package/dist/types/lib/rtp/srtp/packet.d.ts +5 -0
- package/dist/types/lib/rtp/srtp/session.d.ts +19 -0
- package/dist/types/lib/rtp/srtp/srtcp.d.ts +8 -0
- package/dist/types/lib/rtp/srtp/srtp.d.ts +9 -0
- package/dist/types/lib/rtp/transport.d.ts +15 -0
- package/dist/types/lib/rtp/util.d.ts +11 -0
- package/dist/types/lib/sctp/chunk.d.ts +164 -0
- package/dist/types/lib/sctp/const.d.ts +17 -0
- package/dist/types/lib/sctp/helper.d.ts +5 -0
- package/dist/types/lib/sctp/imports/common.d.ts +1 -0
- package/dist/types/lib/sctp/index.d.ts +6 -0
- package/dist/types/lib/sctp/param.d.ts +40 -0
- package/dist/types/lib/sctp/sctp.d.ts +210 -0
- package/dist/types/lib/sctp/transport.d.ts +15 -0
- package/dist/types/lib/turn/index.d.ts +9 -0
- package/dist/types/lib/turn/node/server.d.ts +21 -0
- package/dist/types/lib/turn/node/turnServer.d.ts +91 -0
- package/dist/types/lib/turn/protocol.d.ts +47 -0
- package/dist/types/lib/turn/stun/attributes.d.ts +37 -0
- package/dist/types/lib/turn/stun/const.d.ts +28 -0
- package/dist/types/lib/turn/stun/ip.d.ts +12 -0
- package/dist/types/lib/turn/stun/message.d.ts +37 -0
- package/dist/types/lib/turn/turn/auth.d.ts +1 -0
- package/dist/types/lib/turn/turn/frame.d.ts +13 -0
- package/dist/types/lib/turn/turn/protocol.d.ts +147 -0
- package/dist/types/peer/Endpoints.d.ts +75 -0
- package/dist/types/peer/EngineConfig.d.ts +20 -0
- package/dist/types/peer/EngineConnection.d.ts +22 -0
- package/dist/types/peer/Events.d.ts +55 -0
- package/dist/types/peer/MediaCodecs.d.ts +27 -0
- package/dist/types/peer/MediaTrack.d.ts +212 -0
- package/dist/types/peer/PeerChannel.d.ts +248 -0
- package/dist/types/peer/PeerConnection.d.ts +603 -0
- package/dist/types/peer/PeerThreadChannel.d.ts +112 -0
- package/dist/types/peer/PeerThreadProtocol.d.ts +325 -0
- package/dist/types/peer/PeerThreads.d.ts +114 -0
- package/dist/types/peer/PeerWorker.d.ts +6 -0
- package/dist/types/peer/PeerWorkerCode.d.ts +5 -0
- package/dist/types/peer/RemoteConnection.d.ts +314 -0
- package/dist/types/peer/RtpPacket.d.ts +112 -0
- package/dist/types/peer/RtpTransceiver.d.ts +167 -0
- package/dist/types/peer/SignalingClient.d.ts +236 -0
- package/dist/types/protocol/SignalingProtocol.d.ts +266 -0
- package/dist/types/service/WebRTCServiceEntrypoint.d.ts +158 -0
- package/dist/types/sfu/SFU.d.ts +356 -0
- package/dist/types/sfu/SFUAccess.d.ts +48 -0
- package/dist/types/sfu/SFUClusterLeg.d.ts +101 -0
- package/dist/types/sfu/SFURoom.d.ts +148 -0
- package/dist/types/sfu/SFUWorker.d.ts +13 -0
- package/dist/types/sfu/SFUWorkerChannel.d.ts +204 -0
- package/dist/types/sfu/SFUWorkerCode.d.ts +5 -0
- package/dist/types/sfu/SFUWorkers.d.ts +247 -0
- package/dist/types/shared/ChunkedChannel.d.ts +122 -0
- package/dist/types/shared/Connections.d.ts +231 -0
- package/dist/types/shared/Emitter.d.ts +50 -0
- package/dist/types/shared/Peer.d.ts +182 -0
- package/dist/types/shared/PeerServiceProxy.d.ts +173 -0
- package/dist/types/shared/Room.d.ts +143 -0
- package/dist/types/shared/SignalingError.d.ts +40 -0
- package/dist/types/shared/SignalingSession.d.ts +97 -0
- package/dist/types/shared/Transports.d.ts +139 -0
- package/dist/types/signaling/MediaServers.d.ts +40 -0
- package/dist/types/signaling/Signaling.d.ts +573 -0
- package/dist/types/signaling/SignalingController.d.ts +128 -0
- package/dist/types/turn/TURNCredentials.d.ts +49 -0
- package/dist/types/turn/TURNIceServers.d.ts +11 -0
- package/dist/types/turn/TURNServer.d.ts +309 -0
- package/dist/types/turn/TURNWorker.d.ts +42 -0
- package/dist/types/turn/TURNWorkerCode.d.ts +5 -0
- package/dist/types/turn/TURNWorkers.d.ts +52 -0
- package/dist/types/whep/WHEP.d.ts +386 -0
- package/dist/types/whep/WHEPController.d.ts +134 -0
- package/dist/types/whip/WHIP.d.ts +426 -0
- package/dist/types/whip/WHIPController.d.ts +132 -0
- package/package.json +115 -4
|
@@ -0,0 +1,1547 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { isIPv4 } from 'node:net';
|
|
3
|
+
import * as timers from 'node:timers/promises';
|
|
4
|
+
import { Event, debug } from './imports/common.js';
|
|
5
|
+
import { Candidate, candidateFoundation, candidatePriority, remoteTcpTypeForIncoming } from './candidate.js';
|
|
6
|
+
import { MdnsLookup } from './dns/lookup.js';
|
|
7
|
+
import { PQueue, cancelable, randomString } from './helper.js';
|
|
8
|
+
import { CONSENT_INTERVAL, CONSENT_TIMEOUT, CandidatePair, CandidatePairState, ICE_COMPLETED, ICE_FAILED, consentResponseTimeoutMs, defaultOptions, serverReflexiveCandidate, sortCandidatePairs, validateAddress, validateRemoteCandidate } from './iceBase.js';
|
|
9
|
+
import { TCP_CHECK_RESPONSE_TIMEOUT_MS, classes, methods } from './stun/const.js';
|
|
10
|
+
import { Message } from './stun/message.js';
|
|
11
|
+
import { StunProtocol } from './stun/protocol.js';
|
|
12
|
+
import { TcpActiveProtocol, TcpPassiveProtocol } from './stun/tcpProtocol.js';
|
|
13
|
+
import { createStunOverTurnClient } from './turn/protocol.js';
|
|
14
|
+
import { getHostAddresses } from './utils.js';
|
|
15
|
+
const log = debug('webrtc/ice/ice:log');
|
|
16
|
+
/**How long a transport to a TURN server is given before the next one is tried as well (ms) */
|
|
17
|
+
const RELAY_ATTEMPT_DELAY = 1000;
|
|
18
|
+
/**
|
|
19
|
+
* How long the checks wait without any pair, in milliseconds: the candidates of the other side may be names this side
|
|
20
|
+
* cannot resolve (mDNS), its checks still come once it has this side's description, and give its address as a peer
|
|
21
|
+
* reflexive candidate
|
|
22
|
+
*/
|
|
23
|
+
const NO_PAIR_TIMEOUT = 30000;
|
|
24
|
+
/**The local preference of a relay candidate by the transport to its server: UDP first, then TCP, then TLS */
|
|
25
|
+
const RELAY_PREFERENCE = { udp: 65535, tcp: 49151, tls: 32767 };
|
|
26
|
+
/**
|
|
27
|
+
* The TURN servers of the options: the entries of a host are the transports of one server (an entry without a
|
|
28
|
+
* transport is UDP, then TCP when UDP fails).
|
|
29
|
+
*/
|
|
30
|
+
function relayServersOf(options) {
|
|
31
|
+
const entries = [];
|
|
32
|
+
if (options.turnServer && options.turnUsername && options.turnPassword) {
|
|
33
|
+
entries.push({
|
|
34
|
+
address: options.turnServer,
|
|
35
|
+
username: options.turnUsername,
|
|
36
|
+
password: options.turnPassword,
|
|
37
|
+
transport: options.turnTransport
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
entries.push(...(options.turnServers ?? []));
|
|
41
|
+
const servers = new Map();
|
|
42
|
+
for (const entry of entries) {
|
|
43
|
+
const address = validateAddress(entry.address);
|
|
44
|
+
if (!address || !entry.username || !entry.password)
|
|
45
|
+
continue;
|
|
46
|
+
const key = address[0].toLowerCase();
|
|
47
|
+
let server = servers.get(key);
|
|
48
|
+
if (!server) {
|
|
49
|
+
server = { key, attempts: [] };
|
|
50
|
+
servers.set(key, server);
|
|
51
|
+
}
|
|
52
|
+
const transports = entry.transport === undefined || entry.transport === 'udp' ? ['udp', 'tcp'] : [entry.transport];
|
|
53
|
+
for (const transport of transports) {
|
|
54
|
+
const known = server.attempts.some((attempt) => attempt.transport === transport &&
|
|
55
|
+
attempt.address[1] === address[1] &&
|
|
56
|
+
attempt.username === entry.username &&
|
|
57
|
+
attempt.password === entry.password);
|
|
58
|
+
if (!known)
|
|
59
|
+
server.attempts.push({ address, transport, username: entry.username, password: entry.password });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return [...servers.values()];
|
|
63
|
+
}
|
|
64
|
+
/** The STUN servers of the options, each once. */
|
|
65
|
+
function stunServersOf(options) {
|
|
66
|
+
const servers = [];
|
|
67
|
+
for (const server of [options.stunServer, ...(options.stunServers ?? [])]) {
|
|
68
|
+
const address = validateAddress(server);
|
|
69
|
+
if (address && !servers.some(([host, port]) => host === address[0] && port === address[1]))
|
|
70
|
+
servers.push(address);
|
|
71
|
+
}
|
|
72
|
+
return servers;
|
|
73
|
+
}
|
|
74
|
+
export class Connection {
|
|
75
|
+
constructor(_iceControlling, options) {
|
|
76
|
+
this._iceControlling = _iceControlling;
|
|
77
|
+
this.localUsername = randomString(4);
|
|
78
|
+
this.localPassword = randomString(22);
|
|
79
|
+
this.remoteIsLite = false;
|
|
80
|
+
this.remotePassword = '';
|
|
81
|
+
this.remoteUsername = '';
|
|
82
|
+
this.checkList = [];
|
|
83
|
+
this.localCandidates = [];
|
|
84
|
+
this.stunServers = [];
|
|
85
|
+
this.relayServers = [];
|
|
86
|
+
/**the relays by the host of their TURN server */
|
|
87
|
+
this.relays = new Map();
|
|
88
|
+
this.remoteCandidatesEnd = false;
|
|
89
|
+
this.localCandidatesEnd = false;
|
|
90
|
+
this.generation = -1;
|
|
91
|
+
this.userHistory = {};
|
|
92
|
+
this.tieBreaker = randomBytes(8).readBigUInt64BE(0);
|
|
93
|
+
this.state = 'new';
|
|
94
|
+
this._remoteCandidates = [];
|
|
95
|
+
this.nominating = false;
|
|
96
|
+
this.checkListDone = false;
|
|
97
|
+
this.checkListState = new PQueue();
|
|
98
|
+
this.earlyChecks = [];
|
|
99
|
+
this.earlyChecksDone = false;
|
|
100
|
+
this.localCandidatesStart = false;
|
|
101
|
+
this.protocols = [];
|
|
102
|
+
/** RFC 7675 consent-to-send: application data may use the selected pair. */
|
|
103
|
+
this.consentFresh = false;
|
|
104
|
+
/** Invalidates in-flight consent callbacks on restart / close / replace / expire. */
|
|
105
|
+
this.consentSessionId = 0;
|
|
106
|
+
//The remote candidates whose mDNS names are being resolved: more pairs may come
|
|
107
|
+
this.resolvingRemoteCandidates = 0;
|
|
108
|
+
//Until when the checks wait for a first pair
|
|
109
|
+
this.noPairDeadline = 0;
|
|
110
|
+
this.onData = new Event();
|
|
111
|
+
this.stateChanged = new Event();
|
|
112
|
+
this.onIceCandidate = new Event();
|
|
113
|
+
// RFC 7675 consent freshness
|
|
114
|
+
this.queryConsent = () => {
|
|
115
|
+
if (this.iceLite) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
// Invalidate any previous consent session before starting a new one.
|
|
119
|
+
this.stopConsentLifecycle();
|
|
120
|
+
const sessionId = this.consentSessionId;
|
|
121
|
+
this.consentFresh = true;
|
|
122
|
+
const handle = cancelable(async (_, __, onCancel) => {
|
|
123
|
+
let canceled = false;
|
|
124
|
+
const cancelEvent = new AbortController();
|
|
125
|
+
const clearConsentExpiry = () => {
|
|
126
|
+
if (this.consentExpiryTimer === undefined) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
clearTimeout(this.consentExpiryTimer);
|
|
130
|
+
this.consentExpiryTimer = undefined;
|
|
131
|
+
};
|
|
132
|
+
const refreshConsentExpiry = () => {
|
|
133
|
+
// Only the active session may refresh the shared expiry timer.
|
|
134
|
+
if (canceled || sessionId !== this.consentSessionId) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
clearConsentExpiry();
|
|
138
|
+
this.consentExpiryTimer = setTimeout(() => {
|
|
139
|
+
this.consentExpiryTimer = undefined;
|
|
140
|
+
if (canceled || sessionId !== this.consentSessionId) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (this.state === 'closed' || this.state === 'failed') {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
log('Consent to send expired');
|
|
147
|
+
// Expire independently of request cadence / failure count (RFC 7675).
|
|
148
|
+
this.consentFresh = false;
|
|
149
|
+
this.consentSessionId++;
|
|
150
|
+
this.consentRequestAbort?.abort();
|
|
151
|
+
this.consentRequestAbort = undefined;
|
|
152
|
+
if (this.queryConsentHandle === handle) {
|
|
153
|
+
this.queryConsentHandle = undefined;
|
|
154
|
+
}
|
|
155
|
+
canceled = true;
|
|
156
|
+
cancelEvent.abort();
|
|
157
|
+
// Transport stays available for ICE restart; explicit close() uses "closed".
|
|
158
|
+
this.setState('failed');
|
|
159
|
+
}, CONSENT_TIMEOUT * 1000);
|
|
160
|
+
};
|
|
161
|
+
onCancel.once(() => {
|
|
162
|
+
canceled = true;
|
|
163
|
+
// Avoid clearing a replacement session's timer/handle.
|
|
164
|
+
if (sessionId === this.consentSessionId) {
|
|
165
|
+
clearConsentExpiry();
|
|
166
|
+
this.consentRequestAbort?.abort();
|
|
167
|
+
this.consentRequestAbort = undefined;
|
|
168
|
+
}
|
|
169
|
+
cancelEvent.abort();
|
|
170
|
+
if (this.queryConsentHandle === handle) {
|
|
171
|
+
this.queryConsentHandle = undefined;
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
// Initial ICE check success is the first valid consent response.
|
|
175
|
+
refreshConsentExpiry();
|
|
176
|
+
const randomizedConsentInterval = () => CONSENT_INTERVAL * (0.8 + 0.4 * Math.random()) * 1000;
|
|
177
|
+
// Cadence is measured between request *starts*, not response completions.
|
|
178
|
+
let nextConsentAt = Date.now() + randomizedConsentInterval();
|
|
179
|
+
const isTerminalState = () => this.state === 'closed' || this.state === 'failed';
|
|
180
|
+
try {
|
|
181
|
+
while (!isTerminalState() &&
|
|
182
|
+
!canceled &&
|
|
183
|
+
sessionId === this.consentSessionId) {
|
|
184
|
+
await this.abortableDelay(Math.max(0, nextConsentAt - Date.now()), cancelEvent.signal);
|
|
185
|
+
if (canceled ||
|
|
186
|
+
isTerminalState() ||
|
|
187
|
+
sessionId !== this.consentSessionId) {
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
// Fix next start time before awaiting any response (independent timers).
|
|
191
|
+
nextConsentAt = Date.now() + randomizedConsentInterval();
|
|
192
|
+
const nominated = this.nominated;
|
|
193
|
+
if (!nominated) {
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
const pairId = nominated.id;
|
|
197
|
+
const generation = this.generation;
|
|
198
|
+
const remotePassword = this.remotePassword;
|
|
199
|
+
const { localUsername, remoteUsername, iceControlling } = this;
|
|
200
|
+
const request = this.buildRequest({
|
|
201
|
+
nominate: this.shouldNominateConsentRequest(nominated),
|
|
202
|
+
localUsername,
|
|
203
|
+
remoteUsername,
|
|
204
|
+
iceControlling,
|
|
205
|
+
localCandidate: nominated.localCandidate
|
|
206
|
+
});
|
|
207
|
+
this.consentRequestAbort?.abort();
|
|
208
|
+
const requestAbort = new AbortController();
|
|
209
|
+
this.consentRequestAbort = requestAbort;
|
|
210
|
+
nominated.consentRequestsSent++;
|
|
211
|
+
nominated.requestsSent++;
|
|
212
|
+
// RTT-aware wait (floor 500ms); independent of retransmissions: 0.
|
|
213
|
+
const responseTimeout = consentResponseTimeoutMs(nominated.rtt);
|
|
214
|
+
const requestStartedAt = performance.now();
|
|
215
|
+
// Do not await here: response wait must not stretch the 4–6s cadence.
|
|
216
|
+
nominated.protocol
|
|
217
|
+
.request(request, nominated.remoteAddr, Buffer.from(remotePassword, 'utf8'), {
|
|
218
|
+
retransmissions: 0,
|
|
219
|
+
responseTimeout,
|
|
220
|
+
signal: requestAbort.signal,
|
|
221
|
+
onRequestSent: (attempt) => {
|
|
222
|
+
if (attempt > 0) {
|
|
223
|
+
nominated.retransmissionsSent++;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
})
|
|
227
|
+
.then(() => {
|
|
228
|
+
// Accept only responses for the current pair / generation / session.
|
|
229
|
+
// Address / MESSAGE-INTEGRITY / response class are enforced in Transaction + protocol.
|
|
230
|
+
if (sessionId !== this.consentSessionId || canceled) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const state = this.state;
|
|
234
|
+
if (state === 'closed' || state === 'failed') {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (this.nominated?.id !== pairId) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
if (this.generation !== generation) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
if (this.remotePassword !== remotePassword) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const rtt = (performance.now() - requestStartedAt) / 1000; // seconds
|
|
247
|
+
nominated.rtt = rtt;
|
|
248
|
+
nominated.totalRoundTripTime += rtt;
|
|
249
|
+
nominated.roundTripTimeMeasurements++;
|
|
250
|
+
nominated.responsesReceived++;
|
|
251
|
+
this.consentFresh = true;
|
|
252
|
+
refreshConsentExpiry();
|
|
253
|
+
if (state === 'disconnected') {
|
|
254
|
+
this.setState('connected');
|
|
255
|
+
}
|
|
256
|
+
})
|
|
257
|
+
.catch((error) => {
|
|
258
|
+
// Individual request loss is expected; keep monitoring (RFC 7675).
|
|
259
|
+
if (sessionId === this.consentSessionId &&
|
|
260
|
+
this.nominated?.id === pairId) {
|
|
261
|
+
log('no stun response', error);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
// Abort during delay is normal on cancel / expire.
|
|
268
|
+
}
|
|
269
|
+
finally {
|
|
270
|
+
if (sessionId === this.consentSessionId) {
|
|
271
|
+
clearConsentExpiry();
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
this.queryConsentHandle = handle;
|
|
276
|
+
};
|
|
277
|
+
this.send = async (data) => {
|
|
278
|
+
// RFC 7675: after consent expiry, do not send application data on the 5-tuple.
|
|
279
|
+
if (!this.canSendApplicationData()) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
const activePair = this.nominated;
|
|
283
|
+
await activePair.protocol.sendData(data, activePair.remoteAddr);
|
|
284
|
+
// Update statistics
|
|
285
|
+
activePair.packetsSent++;
|
|
286
|
+
activePair.bytesSent += data.length;
|
|
287
|
+
};
|
|
288
|
+
// 3. Terminology : Check
|
|
289
|
+
this.checkStart = (pair) => cancelable(async (r) => {
|
|
290
|
+
// """
|
|
291
|
+
// Starts a check.
|
|
292
|
+
// """
|
|
293
|
+
log('check start', pair.toJSON());
|
|
294
|
+
pair.updateState(CandidatePairState.IN_PROGRESS);
|
|
295
|
+
const result = {};
|
|
296
|
+
const { remotePassword, remoteUsername, generation } = this;
|
|
297
|
+
const localUsername = pair.localCandidate.ufrag ?? this.localUsername;
|
|
298
|
+
//Regular nomination (RFC 8445): the checks do not nominate, the controlling side nominates one pair afterwards.
|
|
299
|
+
//With USE-CANDIDATE on every check, each side selected the first pair succeeding on its side, and the two
|
|
300
|
+
//could select different pairs
|
|
301
|
+
const nominate = false;
|
|
302
|
+
const request = this.buildRequest({
|
|
303
|
+
nominate,
|
|
304
|
+
localUsername,
|
|
305
|
+
remoteUsername,
|
|
306
|
+
iceControlling: this.iceControlling,
|
|
307
|
+
localCandidate: pair.localCandidate
|
|
308
|
+
});
|
|
309
|
+
// Record start time for RTT calculation
|
|
310
|
+
const startTime = performance.now();
|
|
311
|
+
try {
|
|
312
|
+
pair.requestsSent++;
|
|
313
|
+
const [response, addr] = await pair.protocol.request(request, pair.remoteAddr, Buffer.from(remotePassword, 'utf8'), this.checkRequestOptions(pair));
|
|
314
|
+
pair.responsesReceived++;
|
|
315
|
+
// Calculate RTT
|
|
316
|
+
const endTime = performance.now();
|
|
317
|
+
const rtt = (endTime - startTime) / 1000; // Convert to seconds
|
|
318
|
+
// Update RTT statistics
|
|
319
|
+
pair.rtt = rtt;
|
|
320
|
+
pair.totalRoundTripTime += rtt;
|
|
321
|
+
pair.roundTripTimeMeasurements++;
|
|
322
|
+
log('response received', request.toJSON(), response.toJSON(), addr, {
|
|
323
|
+
localUsername,
|
|
324
|
+
remoteUsername,
|
|
325
|
+
remotePassword,
|
|
326
|
+
generation,
|
|
327
|
+
rtt
|
|
328
|
+
});
|
|
329
|
+
result.response = response;
|
|
330
|
+
result.addr = addr;
|
|
331
|
+
}
|
|
332
|
+
catch (error) {
|
|
333
|
+
const exc = error;
|
|
334
|
+
// 7.1.3.1. Failure Cases
|
|
335
|
+
log('failure case', request.toJSON(), exc.response ? JSON.stringify(exc.response.toJSON(), null, 2) : error, {
|
|
336
|
+
localUsername,
|
|
337
|
+
remoteUsername,
|
|
338
|
+
remotePassword,
|
|
339
|
+
generation
|
|
340
|
+
}, pair.remoteAddr);
|
|
341
|
+
if (exc.response?.getAttributeValue('ERROR-CODE')[0] === 487) {
|
|
342
|
+
if (request.attributesKeys.includes('ICE-CONTROLLED')) {
|
|
343
|
+
this.switchRole(true);
|
|
344
|
+
}
|
|
345
|
+
else if (request.attributesKeys.includes('ICE-CONTROLLING')) {
|
|
346
|
+
this.switchRole(false);
|
|
347
|
+
}
|
|
348
|
+
await this.checkStart(pair).awaitable;
|
|
349
|
+
r();
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
if (exc.response?.getAttributeValue('ERROR-CODE')[0] === 401) {
|
|
353
|
+
log('retry 401', pair.toJSON());
|
|
354
|
+
await this.checkStart(pair).awaitable;
|
|
355
|
+
r();
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
// timeout
|
|
360
|
+
log('checkStart CandidatePairState.FAILED', pair.toJSON());
|
|
361
|
+
pair.updateState(CandidatePairState.FAILED);
|
|
362
|
+
this.checkComplete(pair);
|
|
363
|
+
r();
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
// # check remote address matches
|
|
368
|
+
if (result.addr[0] !== pair.remoteAddr[0] ||
|
|
369
|
+
result.addr[1] !== pair.remoteAddr[1]) {
|
|
370
|
+
pair.updateState(CandidatePairState.FAILED);
|
|
371
|
+
this.checkComplete(pair);
|
|
372
|
+
r();
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
// # success
|
|
376
|
+
if (nominate || pair.remoteNominated) {
|
|
377
|
+
// # nominated by agressive nomination or the remote party
|
|
378
|
+
pair.nominated = true;
|
|
379
|
+
}
|
|
380
|
+
else if (this.usesTcpRegularNomination(pair)) {
|
|
381
|
+
// # nominated later by nominateTcpPairIfReady (from checkComplete)
|
|
382
|
+
}
|
|
383
|
+
else if (this.iceControlling && !this.nominating && !this.nominated) {
|
|
384
|
+
// # perform regular nomination: one pair, the first succeeding
|
|
385
|
+
this.nominating = true;
|
|
386
|
+
const request = this.buildRequest({
|
|
387
|
+
nominate: true,
|
|
388
|
+
localUsername,
|
|
389
|
+
remoteUsername,
|
|
390
|
+
iceControlling: this.iceControlling,
|
|
391
|
+
localCandidate: pair.localCandidate
|
|
392
|
+
});
|
|
393
|
+
try {
|
|
394
|
+
pair.requestsSent++;
|
|
395
|
+
await pair.protocol.request(request, pair.remoteAddr, Buffer.from(this.remotePassword, 'utf8'), this.checkRequestOptions(pair));
|
|
396
|
+
pair.responsesReceived++;
|
|
397
|
+
}
|
|
398
|
+
catch (error) {
|
|
399
|
+
this.nominating = false;
|
|
400
|
+
pair.updateState(CandidatePairState.FAILED);
|
|
401
|
+
this.checkComplete(pair);
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
pair.nominated = true;
|
|
405
|
+
}
|
|
406
|
+
pair.updateState(CandidatePairState.SUCCEEDED);
|
|
407
|
+
this.checkComplete(pair);
|
|
408
|
+
r();
|
|
409
|
+
});
|
|
410
|
+
this.pairRemoteCandidate = (remoteCandidate) => {
|
|
411
|
+
for (const protocol of this.protocols) {
|
|
412
|
+
this.tryPair(protocol, remoteCandidate);
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
this.options = {
|
|
416
|
+
...defaultOptions,
|
|
417
|
+
...options
|
|
418
|
+
};
|
|
419
|
+
if (this.iceLite) {
|
|
420
|
+
this._iceControlling = false;
|
|
421
|
+
}
|
|
422
|
+
this.applyStunTurnServersFromOptions();
|
|
423
|
+
this.restart().catch((error) => log('restart failed', error));
|
|
424
|
+
log('new Connection', this.options);
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Replace STUN/TURN servers after construction.
|
|
428
|
+
* Server-related fields are replaced (not partial-merged) so that removing
|
|
429
|
+
* TURN clears residual credentials. W3C setConfiguration replaces the ICE
|
|
430
|
+
* server list rather than merging additively.
|
|
431
|
+
*
|
|
432
|
+
* Used when servers are learned after the gatherer was built (e.g. WHIP
|
|
433
|
+
* Link headers) and must take effect before the next gather pass.
|
|
434
|
+
*/
|
|
435
|
+
setIceServers(options) {
|
|
436
|
+
// Explicitly assign server fields even when undefined so a STUN-only
|
|
437
|
+
// update cannot leave a previous TURN host/credential in options.
|
|
438
|
+
this.options = {
|
|
439
|
+
...this.options,
|
|
440
|
+
stunServer: options.stunServer,
|
|
441
|
+
turnServer: options.turnServer,
|
|
442
|
+
turnUsername: options.turnUsername,
|
|
443
|
+
turnPassword: options.turnPassword,
|
|
444
|
+
turnTransport: options.turnTransport,
|
|
445
|
+
stunServers: options.stunServers,
|
|
446
|
+
turnServers: options.turnServers
|
|
447
|
+
};
|
|
448
|
+
if (options.forceTurn !== undefined) {
|
|
449
|
+
this.options.forceTurn = options.forceTurn;
|
|
450
|
+
}
|
|
451
|
+
if (options.useTcp !== undefined) {
|
|
452
|
+
this.options.useTcp = options.useTcp;
|
|
453
|
+
}
|
|
454
|
+
if (options.turnTlsOptions !== undefined) {
|
|
455
|
+
this.options.turnTlsOptions = options.turnTlsOptions;
|
|
456
|
+
}
|
|
457
|
+
if (options.turnUdpFamily !== undefined) {
|
|
458
|
+
this.options.turnUdpFamily = options.turnUdpFamily;
|
|
459
|
+
}
|
|
460
|
+
this.applyStunTurnServersFromOptions();
|
|
461
|
+
log('Connection ice servers updated', this.options);
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Derive Connection.stunServer / turnServer from this.options.
|
|
465
|
+
* Shared by the constructor and setIceServers so both paths validate and
|
|
466
|
+
* default identically.
|
|
467
|
+
*/
|
|
468
|
+
applyStunTurnServersFromOptions() {
|
|
469
|
+
//No STUN server unless one is configured, as RTCPeerConnection (no request to a public server by default)
|
|
470
|
+
this.stunServers = stunServersOf(this.options);
|
|
471
|
+
this.relayServers = relayServersOf(this.options);
|
|
472
|
+
this.stunServer = this.stunServers[0];
|
|
473
|
+
this.turnServer = validateAddress(this.options.turnServer) ?? this.relayServers[0]?.attempts[0]?.address;
|
|
474
|
+
}
|
|
475
|
+
get iceControlling() {
|
|
476
|
+
return this._iceControlling;
|
|
477
|
+
}
|
|
478
|
+
set iceControlling(value) {
|
|
479
|
+
if (this.iceLite) {
|
|
480
|
+
value = false;
|
|
481
|
+
}
|
|
482
|
+
// While a pair is selected, keep the negotiated role. ICE restart clears
|
|
483
|
+
// `nominated`, so offer/answer role and RFC 8445 role-conflict repair can
|
|
484
|
+
// reassign controlling/controlled for the new generation.
|
|
485
|
+
if (this.nominated) {
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
this.applyIceControlling(value);
|
|
489
|
+
}
|
|
490
|
+
get iceLite() {
|
|
491
|
+
return this.options.iceLite;
|
|
492
|
+
}
|
|
493
|
+
async restart() {
|
|
494
|
+
this.generation++;
|
|
495
|
+
this.localUsername = randomString(4);
|
|
496
|
+
this.localPassword = randomString(22);
|
|
497
|
+
if (this.options.localPasswordPrefix) {
|
|
498
|
+
this.localPassword =
|
|
499
|
+
this.options.localPasswordPrefix +
|
|
500
|
+
this.localPassword.slice(this.options.localPasswordPrefix.length);
|
|
501
|
+
}
|
|
502
|
+
this.userHistory[this.localUsername] = this.localPassword;
|
|
503
|
+
this.remoteUsername = '';
|
|
504
|
+
this.remotePassword = '';
|
|
505
|
+
this.localCandidates = [];
|
|
506
|
+
this._remoteCandidates = [];
|
|
507
|
+
this.remoteCandidatesEnd = false;
|
|
508
|
+
this.localCandidatesEnd = false;
|
|
509
|
+
this.state = 'new';
|
|
510
|
+
this.lookup?.close?.();
|
|
511
|
+
this.lookup = undefined;
|
|
512
|
+
this.nominated = undefined;
|
|
513
|
+
this.nominating = false;
|
|
514
|
+
this.checkList = [];
|
|
515
|
+
this.checkListDone = false;
|
|
516
|
+
this.checkListState = new PQueue();
|
|
517
|
+
this.earlyChecks = [];
|
|
518
|
+
this.earlyChecksDone = false;
|
|
519
|
+
this.localCandidatesStart = false;
|
|
520
|
+
// protocolsはincomingのearlyCheckに使うかもしれないので残す
|
|
521
|
+
for (const protocol of this.protocols) {
|
|
522
|
+
//The checks of the new session go to any address
|
|
523
|
+
protocol.disconnect?.();
|
|
524
|
+
if (protocol.localCandidate) {
|
|
525
|
+
protocol.localCandidate.refreshId();
|
|
526
|
+
protocol.localCandidate.generation = this.generation;
|
|
527
|
+
protocol.localCandidate.ufrag = this.localUsername;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
// Tear down consent timers/transactions; new credentials require a new session.
|
|
531
|
+
this.stopConsentLifecycle();
|
|
532
|
+
}
|
|
533
|
+
resetNominatedPair() {
|
|
534
|
+
log('resetNominatedPair');
|
|
535
|
+
for (const protocol of this.protocols)
|
|
536
|
+
protocol.disconnect?.();
|
|
537
|
+
this.nominated = undefined;
|
|
538
|
+
this.nominating = false;
|
|
539
|
+
// Drop old pair's consent timers/transactions; restarted when a new pair is nominated.
|
|
540
|
+
this.stopConsentLifecycle();
|
|
541
|
+
}
|
|
542
|
+
setRemoteParams({ iceLite, usernameFragment, password }) {
|
|
543
|
+
log('setRemoteParams', { iceLite, usernameFragment, password });
|
|
544
|
+
this.remoteIsLite = iceLite;
|
|
545
|
+
this.remoteUsername = usernameFragment;
|
|
546
|
+
this.remotePassword = password;
|
|
547
|
+
}
|
|
548
|
+
// 4.1.1 Gathering Candidates
|
|
549
|
+
async gatherCandidates() {
|
|
550
|
+
if (!this.localCandidatesStart) {
|
|
551
|
+
this.localCandidatesStart = true;
|
|
552
|
+
// ICE restart keeps transport protocols; re-advertise their host candidates
|
|
553
|
+
// with the new generation / ufrag before gathering additional addresses.
|
|
554
|
+
// A relay is advertised again once its allocation is known to be still there.
|
|
555
|
+
const relays = [...this.relays.values()];
|
|
556
|
+
for (const protocol of this.protocols) {
|
|
557
|
+
if (protocol.localCandidate && !relays.includes(protocol)) {
|
|
558
|
+
protocol.localCandidate.generation = this.generation;
|
|
559
|
+
protocol.localCandidate.ufrag = this.localUsername;
|
|
560
|
+
this.appendLocalCandidate(protocol.localCandidate);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
let address = getHostAddresses(this.options.useIpv4, this.options.useIpv6, {
|
|
564
|
+
useLinkLocalAddress: this.options.useLinkLocalAddress
|
|
565
|
+
});
|
|
566
|
+
const { interfaceAddresses } = this.options;
|
|
567
|
+
if (interfaceAddresses) {
|
|
568
|
+
const filteredAddresses = address.filter((check) => Object.values(interfaceAddresses).includes(check));
|
|
569
|
+
if (filteredAddresses.length) {
|
|
570
|
+
address = filteredAddresses;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
if (this.options.additionalHostAddresses) {
|
|
574
|
+
address = Array.from(new Set([...this.options.additionalHostAddresses, ...address]));
|
|
575
|
+
}
|
|
576
|
+
const candidatePromises = this.getCandidatePromises(address, this.options.stunGatherTimeout);
|
|
577
|
+
await Promise.allSettled(candidatePromises);
|
|
578
|
+
this.localCandidatesEnd = true;
|
|
579
|
+
}
|
|
580
|
+
this.setState('completed');
|
|
581
|
+
}
|
|
582
|
+
appendLocalCandidate(candidate) {
|
|
583
|
+
this.localCandidates.push(candidate);
|
|
584
|
+
this.onIceCandidate.execute(candidate);
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Whether a candidate with the same address and base was gathered already
|
|
588
|
+
* (RFC 8445, section 5.1.3): a server reflexive address that is a host
|
|
589
|
+
* address, or that another STUN server gave too.
|
|
590
|
+
*/
|
|
591
|
+
isRedundant(candidate) {
|
|
592
|
+
const baseOf = (other) => other.type === 'host' ? `${other.host}|${other.port}` : `${other.relatedAddress}|${other.relatedPort}`;
|
|
593
|
+
return this.localCandidates.some((other) => other.transport === candidate.transport &&
|
|
594
|
+
other.host === candidate.host &&
|
|
595
|
+
other.port === candidate.port &&
|
|
596
|
+
other.type !== 'relay' &&
|
|
597
|
+
baseOf(other) === baseOf(candidate));
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* A relay candidate from each TURN server. An ICE restart keeps the
|
|
601
|
+
* allocation of a server when the server still has it; the relays of the
|
|
602
|
+
* servers no longer configured are closed.
|
|
603
|
+
*/
|
|
604
|
+
gatherRelayCandidates(servers) {
|
|
605
|
+
for (const [key, relay] of this.relays) {
|
|
606
|
+
if (!servers.some((server) => server.key === key))
|
|
607
|
+
this.dropRelay(key, relay);
|
|
608
|
+
}
|
|
609
|
+
return servers.map(async (server) => {
|
|
610
|
+
const existing = this.relays.get(server.key);
|
|
611
|
+
if (existing) {
|
|
612
|
+
if (await existing.turn.refreshAllocation()) {
|
|
613
|
+
if (this.relays.get(server.key) !== existing)
|
|
614
|
+
return;
|
|
615
|
+
existing.localCandidate.generation = this.generation;
|
|
616
|
+
existing.localCandidate.ufrag = this.localUsername;
|
|
617
|
+
this.appendLocalCandidate(existing.localCandidate);
|
|
618
|
+
return existing.localCandidate;
|
|
619
|
+
}
|
|
620
|
+
this.dropRelay(server.key, existing);
|
|
621
|
+
}
|
|
622
|
+
const { protocol, attempt } = await this.allocateRelay(server);
|
|
623
|
+
if (this.state === 'closed' || this.relays.has(server.key)) {
|
|
624
|
+
await protocol.close();
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
this.ensureProtocol(protocol);
|
|
628
|
+
this.protocols.push(protocol);
|
|
629
|
+
this.relays.set(server.key, protocol);
|
|
630
|
+
const candidateAddress = protocol.turn.relayedAddress;
|
|
631
|
+
const relatedAddress = protocol.turn.mappedAddress;
|
|
632
|
+
log('turn candidateAddress', candidateAddress);
|
|
633
|
+
protocol.localCandidate = new Candidate(candidateFoundation('relay', 'udp', candidateAddress[0], `${server.key}|${attempt.transport}`), 1, 'udp', candidatePriority('relay', RELAY_PREFERENCE[attempt.transport]), candidateAddress[0], candidateAddress[1], 'relay', relatedAddress[0], relatedAddress[1], undefined, this.generation, this.localUsername);
|
|
634
|
+
this.appendLocalCandidate(protocol.localCandidate);
|
|
635
|
+
return protocol.localCandidate;
|
|
636
|
+
}).map((promise) => promise.catch((error) => {
|
|
637
|
+
log('query TURN server', error);
|
|
638
|
+
}));
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Allocate a relay on a TURN server: its transports are tried in order, the
|
|
642
|
+
* next one when the one before fails or has not answered within
|
|
643
|
+
* RELAY_ATTEMPT_DELAY; the first allocation made is kept, a later one is
|
|
644
|
+
* deleted.
|
|
645
|
+
*/
|
|
646
|
+
allocateRelay(server) {
|
|
647
|
+
return new Promise((resolve, reject) => {
|
|
648
|
+
let next = 0;
|
|
649
|
+
let pending = 0;
|
|
650
|
+
let done = false;
|
|
651
|
+
let timer;
|
|
652
|
+
const start = () => {
|
|
653
|
+
clearTimeout(timer);
|
|
654
|
+
if (done || next >= server.attempts.length)
|
|
655
|
+
return;
|
|
656
|
+
const attempt = server.attempts[next++];
|
|
657
|
+
pending++;
|
|
658
|
+
timer = setTimeout(start, RELAY_ATTEMPT_DELAY);
|
|
659
|
+
createStunOverTurnClient({ address: attempt.address, username: attempt.username, password: attempt.password }, {
|
|
660
|
+
portRange: this.options.portRange,
|
|
661
|
+
interfaceAddresses: this.options.interfaceAddresses,
|
|
662
|
+
transport: attempt.transport,
|
|
663
|
+
tlsOptions: this.options.turnTlsOptions,
|
|
664
|
+
connectTimeoutMs: (this.options.turnConnectTimeout ?? 8) * 1000,
|
|
665
|
+
udpFamily: this.options.turnUdpFamily
|
|
666
|
+
}).then((protocol) => {
|
|
667
|
+
pending--;
|
|
668
|
+
if (done) {
|
|
669
|
+
protocol.close().catch((error) => log('close TURN relay', error));
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
done = true;
|
|
673
|
+
clearTimeout(timer);
|
|
674
|
+
resolve({ protocol, attempt });
|
|
675
|
+
}, (error) => {
|
|
676
|
+
pending--;
|
|
677
|
+
log('TURN allocation failed', attempt.transport, attempt.address, error);
|
|
678
|
+
if (done)
|
|
679
|
+
return;
|
|
680
|
+
if (next < server.attempts.length) {
|
|
681
|
+
start();
|
|
682
|
+
}
|
|
683
|
+
else if (!pending) {
|
|
684
|
+
done = true;
|
|
685
|
+
reject(error);
|
|
686
|
+
}
|
|
687
|
+
});
|
|
688
|
+
};
|
|
689
|
+
start();
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
/** Stop using a relay and delete its allocation. */
|
|
693
|
+
dropRelay(key, relay) {
|
|
694
|
+
this.relays.delete(key);
|
|
695
|
+
this.protocols = this.protocols.filter((protocol) => protocol !== relay);
|
|
696
|
+
relay.close().catch((error) => log('close TURN relay', error));
|
|
697
|
+
}
|
|
698
|
+
ensureProtocol(protocol) {
|
|
699
|
+
protocol.onRequestReceived.subscribe((msg, addr) => {
|
|
700
|
+
if (msg.messageMethod !== methods.BINDING) {
|
|
701
|
+
this.respondError(msg, addr, protocol, [400, 'Bad Request']);
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
const txUsername = msg.getAttributeValue('USERNAME');
|
|
705
|
+
// 相手にとってのremoteは自分にとってのlocal
|
|
706
|
+
const { remoteUsername: localUsername } = decodeTxUsername(txUsername);
|
|
707
|
+
const localPassword = this.userHistory[localUsername] ?? this.localPassword;
|
|
708
|
+
const { iceControlling } = this;
|
|
709
|
+
// 7.2.1.1. Detecting and Repairing Role Conflicts
|
|
710
|
+
if (iceControlling && msg.attributesKeys.includes('ICE-CONTROLLING')) {
|
|
711
|
+
if (this.tieBreaker >= msg.getAttributeValue('ICE-CONTROLLING')) {
|
|
712
|
+
this.respondError(msg, addr, protocol, [487, 'Role Conflict']);
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
else {
|
|
716
|
+
this.switchRole(false);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
else if (!iceControlling &&
|
|
720
|
+
msg.attributesKeys.includes('ICE-CONTROLLED')) {
|
|
721
|
+
if (this.iceLite ||
|
|
722
|
+
this.tieBreaker < msg.getAttributeValue('ICE-CONTROLLED')) {
|
|
723
|
+
this.respondError(msg, addr, protocol, [487, 'Role Conflict']);
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
else {
|
|
727
|
+
this.switchRole(true);
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
if (this.options.filterStunResponse &&
|
|
732
|
+
!this.options.filterStunResponse(msg, addr, protocol)) {
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
// # send binding response
|
|
736
|
+
const response = new Message(methods.BINDING, classes.RESPONSE, msg.transactionId);
|
|
737
|
+
response
|
|
738
|
+
.setAttribute('XOR-MAPPED-ADDRESS', addr)
|
|
739
|
+
.addMessageIntegrity(Buffer.from(localPassword, 'utf8'))
|
|
740
|
+
.addFingerprint();
|
|
741
|
+
protocol.sendStun(response, addr).catch((e) => {
|
|
742
|
+
log('sendStun error', e);
|
|
743
|
+
});
|
|
744
|
+
if (this.checkList.length === 0 && !this.earlyChecksDone) {
|
|
745
|
+
this.earlyChecks.push([msg, addr, protocol]);
|
|
746
|
+
}
|
|
747
|
+
else {
|
|
748
|
+
this.checkIncoming(msg, addr, protocol);
|
|
749
|
+
}
|
|
750
|
+
});
|
|
751
|
+
protocol.onDataReceived.subscribe((data) => {
|
|
752
|
+
try {
|
|
753
|
+
// Update statistics for the nominated pair
|
|
754
|
+
const activePair = this.nominated;
|
|
755
|
+
if (activePair && activePair.protocol === protocol) {
|
|
756
|
+
activePair.packetsReceived++;
|
|
757
|
+
activePair.bytesReceived += data.length;
|
|
758
|
+
}
|
|
759
|
+
this.onData.execute(data);
|
|
760
|
+
}
|
|
761
|
+
catch (error) {
|
|
762
|
+
log('dataReceived', error);
|
|
763
|
+
}
|
|
764
|
+
});
|
|
765
|
+
protocol.onConnectionClosed?.subscribe((remoteAddr) => {
|
|
766
|
+
this.handleConnectionClosed(protocol, remoteAddr);
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
* RFC 6544: the selected TCP connection is the only path for this component;
|
|
771
|
+
* once it is closed no application data or consent check can reach the peer,
|
|
772
|
+
* so fail the same way as a consent expiry instead of waiting for it.
|
|
773
|
+
*/
|
|
774
|
+
handleConnectionClosed(protocol, remoteAddr) {
|
|
775
|
+
const nominated = this.nominated;
|
|
776
|
+
if (!nominated ||
|
|
777
|
+
nominated.protocol !== protocol ||
|
|
778
|
+
nominated.remoteAddr[0] !== remoteAddr[0] ||
|
|
779
|
+
nominated.remoteAddr[1] !== remoteAddr[1]) {
|
|
780
|
+
return;
|
|
781
|
+
}
|
|
782
|
+
if (this.state === 'closed' || this.state === 'failed') {
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
log('selected tcp connection closed', nominated.toJSON());
|
|
786
|
+
this.stopConsentLifecycle();
|
|
787
|
+
this.setState('failed');
|
|
788
|
+
}
|
|
789
|
+
getCandidatePromises(addresses, timeout = 5) {
|
|
790
|
+
const candidatePromises = [];
|
|
791
|
+
const { stunServers, relayServers } = this;
|
|
792
|
+
const gatherIceLite = this.iceLite;
|
|
793
|
+
const gatherRelayOnly = !gatherIceLite && this.options.forceTurn && relayServers.length > 0;
|
|
794
|
+
//The UDP host candidates of the generations before (an ICE restart) are queried again with the STUN servers
|
|
795
|
+
const knownHostProtocols = this.protocols.filter((protocol) => protocol instanceof StunProtocol && !!protocol.localCandidate);
|
|
796
|
+
addresses = addresses.filter((address) => {
|
|
797
|
+
// ice restartで同じアドレスが追加されるのを防ぐ
|
|
798
|
+
if (this.protocols.find((protocol) => protocol.localIp === address)) {
|
|
799
|
+
return false;
|
|
800
|
+
}
|
|
801
|
+
return true;
|
|
802
|
+
});
|
|
803
|
+
const localStunPromises = gatherRelayOnly
|
|
804
|
+
? []
|
|
805
|
+
: addresses.map(async (address) => {
|
|
806
|
+
// # create transport
|
|
807
|
+
const protocol = new StunProtocol();
|
|
808
|
+
this.ensureProtocol(protocol);
|
|
809
|
+
try {
|
|
810
|
+
await protocol.connectionMade(isIPv4(address), this.options.portRange, this.options.interfaceAddresses);
|
|
811
|
+
protocol.localIp = address;
|
|
812
|
+
this.protocols.push(protocol);
|
|
813
|
+
log('protocol', protocol.localIp);
|
|
814
|
+
// # add host candidate
|
|
815
|
+
const candidateAddress = [
|
|
816
|
+
address,
|
|
817
|
+
protocol.getExtraInfo()[1]
|
|
818
|
+
];
|
|
819
|
+
protocol.localCandidate = new Candidate(candidateFoundation('host', 'udp', candidateAddress[0]), 1, 'udp', candidatePriority('host', { transport: 'udp' }), candidateAddress[0], candidateAddress[1], 'host', undefined, undefined, undefined, this.generation, this.localUsername);
|
|
820
|
+
this.pairLocalProtocol(protocol);
|
|
821
|
+
this.appendLocalCandidate(protocol.localCandidate);
|
|
822
|
+
return protocol;
|
|
823
|
+
}
|
|
824
|
+
catch (error) {
|
|
825
|
+
log('error protocol STUN', error);
|
|
826
|
+
}
|
|
827
|
+
});
|
|
828
|
+
if (!gatherRelayOnly) {
|
|
829
|
+
candidatePromises.push(...localStunPromises.map((localPromise) => localPromise.then((protocol) => protocol?.localCandidate)));
|
|
830
|
+
}
|
|
831
|
+
if (!gatherRelayOnly && this.options.useTcp) {
|
|
832
|
+
const tcpCandidatePromises = addresses.map(async (address) => {
|
|
833
|
+
// Passive candidates open a listening TCP server; skip them when the
|
|
834
|
+
// agent only makes outbound connections (tcpPassive === false). Active
|
|
835
|
+
// candidates below still dial out, so direct TCP egress is unaffected.
|
|
836
|
+
if (this.options.tcpPassive !== false) {
|
|
837
|
+
const passiveProtocol = new TcpPassiveProtocol();
|
|
838
|
+
this.ensureProtocol(passiveProtocol);
|
|
839
|
+
await passiveProtocol.connectionMade(address, this.options.portRange);
|
|
840
|
+
passiveProtocol.localIp = address;
|
|
841
|
+
passiveProtocol.localCandidate = new Candidate(candidateFoundation('host', 'tcp', address), 1, 'tcp', candidatePriority('host', {
|
|
842
|
+
transport: 'tcp',
|
|
843
|
+
tcptype: 'passive'
|
|
844
|
+
}), address, passiveProtocol.listeningPort, 'host', undefined, undefined, 'passive', this.generation, this.localUsername);
|
|
845
|
+
this.protocols.push(passiveProtocol);
|
|
846
|
+
this.appendLocalCandidate(passiveProtocol.localCandidate);
|
|
847
|
+
}
|
|
848
|
+
if (!gatherIceLite) {
|
|
849
|
+
const activeProtocol = new TcpActiveProtocol();
|
|
850
|
+
this.ensureProtocol(activeProtocol);
|
|
851
|
+
await activeProtocol.connectionMade(address);
|
|
852
|
+
activeProtocol.localIp = address;
|
|
853
|
+
activeProtocol.localCandidate = new Candidate(candidateFoundation('host', 'tcp', address), 1, 'tcp', candidatePriority('host', {
|
|
854
|
+
transport: 'tcp',
|
|
855
|
+
tcptype: 'active'
|
|
856
|
+
}), address, 9, 'host', undefined, undefined, 'active', this.generation, this.localUsername);
|
|
857
|
+
this.protocols.push(activeProtocol);
|
|
858
|
+
this.pairLocalProtocol(activeProtocol);
|
|
859
|
+
this.appendLocalCandidate(activeProtocol.localCandidate);
|
|
860
|
+
}
|
|
861
|
+
});
|
|
862
|
+
candidatePromises.push(...tcpCandidatePromises);
|
|
863
|
+
}
|
|
864
|
+
if (!gatherIceLite && !gatherRelayOnly && stunServers.length) {
|
|
865
|
+
const hostProtocols = [
|
|
866
|
+
...knownHostProtocols.map((protocol) => Promise.resolve(protocol)),
|
|
867
|
+
...localStunPromises
|
|
868
|
+
];
|
|
869
|
+
const stunCandidatePromises = hostProtocols.flatMap((protocolPromise) => stunServers.map(async (stunServer) => {
|
|
870
|
+
const protocol = await protocolPromise;
|
|
871
|
+
if (!protocol)
|
|
872
|
+
return;
|
|
873
|
+
//The server reflexive candidate of an IPv4 host candidate; gathering waits for it at most timeout
|
|
874
|
+
//seconds (a late answer still adds its candidate, unless ICE restarted meanwhile)
|
|
875
|
+
const generation = this.generation;
|
|
876
|
+
const query = (async () => {
|
|
877
|
+
const host = protocol.localCandidate?.host;
|
|
878
|
+
if (!host || !isIPv4(host))
|
|
879
|
+
return;
|
|
880
|
+
const candidate = await serverReflexiveCandidate(protocol, stunServer).catch((error) => {
|
|
881
|
+
log('error', error);
|
|
882
|
+
});
|
|
883
|
+
if (!candidate || generation !== this.generation || this.isRedundant(candidate))
|
|
884
|
+
return;
|
|
885
|
+
candidate.generation = this.generation;
|
|
886
|
+
candidate.ufrag = this.localUsername;
|
|
887
|
+
this.appendLocalCandidate(candidate);
|
|
888
|
+
return candidate;
|
|
889
|
+
})();
|
|
890
|
+
let timer;
|
|
891
|
+
const timeLimit = new Promise((_, f) => {
|
|
892
|
+
timer = setTimeout(() => f(new Error('STUN query timeout')), timeout * 1000);
|
|
893
|
+
});
|
|
894
|
+
return Promise.race([query, timeLimit])
|
|
895
|
+
.finally(() => clearTimeout(timer))
|
|
896
|
+
.catch((error) => {
|
|
897
|
+
log('query STUN server', error);
|
|
898
|
+
});
|
|
899
|
+
}));
|
|
900
|
+
candidatePromises.push(...stunCandidatePromises);
|
|
901
|
+
}
|
|
902
|
+
if (!gatherIceLite) {
|
|
903
|
+
candidatePromises.push(...this.gatherRelayCandidates(relayServers));
|
|
904
|
+
}
|
|
905
|
+
return candidatePromises;
|
|
906
|
+
}
|
|
907
|
+
async connect() {
|
|
908
|
+
// """
|
|
909
|
+
// Perform ICE handshake.
|
|
910
|
+
//
|
|
911
|
+
// This coroutine returns if a candidate pair was successfully nominated
|
|
912
|
+
// and raises an exception otherwise.
|
|
913
|
+
// """
|
|
914
|
+
log('start connect ice');
|
|
915
|
+
if (!this.localCandidatesEnd) {
|
|
916
|
+
if (!this.localCandidatesStart) {
|
|
917
|
+
throw new Error('Local candidates gathering was not performed');
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
if (!this.remoteUsername || !this.remotePassword) {
|
|
921
|
+
throw new Error('Remote username or password is missing');
|
|
922
|
+
}
|
|
923
|
+
// # 5.7.1. Forming Candidate Pairs
|
|
924
|
+
for (const c of this.remoteCandidates) {
|
|
925
|
+
this.pairRemoteCandidate(c);
|
|
926
|
+
}
|
|
927
|
+
this.sortCheckList();
|
|
928
|
+
if (!this.iceLite) {
|
|
929
|
+
this.unfreezeInitial();
|
|
930
|
+
}
|
|
931
|
+
log('earlyChecks', this.localPassword, this.earlyChecks.length);
|
|
932
|
+
// # handle early checks
|
|
933
|
+
for (const earlyCheck of this.earlyChecks) {
|
|
934
|
+
this.checkIncoming(...earlyCheck);
|
|
935
|
+
}
|
|
936
|
+
this.earlyChecks = [];
|
|
937
|
+
this.earlyChecksDone = true;
|
|
938
|
+
if (this.iceLite) {
|
|
939
|
+
if (!this.nominated) {
|
|
940
|
+
let res = ICE_FAILED;
|
|
941
|
+
while (!this.checkListDone && this.state !== 'closed') {
|
|
942
|
+
res = await this.checkListState.get();
|
|
943
|
+
log('checkListState', res);
|
|
944
|
+
if (res === ICE_COMPLETED) {
|
|
945
|
+
break;
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
if (res !== ICE_COMPLETED && !this.nominated) {
|
|
949
|
+
throw new Error('ICE negotiation failed');
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
this.setState('connected');
|
|
953
|
+
return;
|
|
954
|
+
}
|
|
955
|
+
// # perform checks
|
|
956
|
+
// 5.8. Scheduling Checks
|
|
957
|
+
this.noPairDeadline = Date.now() + NO_PAIR_TIMEOUT;
|
|
958
|
+
for (;;) {
|
|
959
|
+
if (this.state === 'closed')
|
|
960
|
+
break;
|
|
961
|
+
if (!this.schedulingChecks())
|
|
962
|
+
break;
|
|
963
|
+
await timers.setTimeout(20);
|
|
964
|
+
}
|
|
965
|
+
// # wait for completion (closing the connection ends the wait)
|
|
966
|
+
let res = ICE_FAILED;
|
|
967
|
+
while (this.checkList.length > 0 && res === ICE_FAILED && this.state !== 'closed') {
|
|
968
|
+
res = await this.checkListState.get();
|
|
969
|
+
log('checkListState', res);
|
|
970
|
+
}
|
|
971
|
+
// # cancel remaining checks
|
|
972
|
+
for (const check of this.checkList) {
|
|
973
|
+
check.handle?.resolve?.();
|
|
974
|
+
}
|
|
975
|
+
if (res !== ICE_COMPLETED) {
|
|
976
|
+
throw new Error('ICE negotiation failed');
|
|
977
|
+
}
|
|
978
|
+
// # start consent freshness tests
|
|
979
|
+
this.queryConsent();
|
|
980
|
+
this.setState('connected');
|
|
981
|
+
}
|
|
982
|
+
unfreezeInitial() {
|
|
983
|
+
// # unfreeze first pair for the first component
|
|
984
|
+
const [firstPair] = this.checkList;
|
|
985
|
+
if (!firstPair)
|
|
986
|
+
return;
|
|
987
|
+
if (firstPair.state === CandidatePairState.FROZEN) {
|
|
988
|
+
firstPair.updateState(CandidatePairState.WAITING);
|
|
989
|
+
}
|
|
990
|
+
// # unfreeze pairs with same component but different foundations
|
|
991
|
+
const seenFoundations = new Set(firstPair.localCandidate.foundation);
|
|
992
|
+
for (const pair of this.checkList) {
|
|
993
|
+
if (pair.component === firstPair.component &&
|
|
994
|
+
!seenFoundations.has(pair.localCandidate.foundation) &&
|
|
995
|
+
pair.state === CandidatePairState.FROZEN) {
|
|
996
|
+
pair.updateState(CandidatePairState.WAITING);
|
|
997
|
+
seenFoundations.add(pair.localCandidate.foundation);
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
// 5.8 Scheduling Checks
|
|
1002
|
+
schedulingChecks() {
|
|
1003
|
+
//A pair is being nominated: no other check meanwhile (they resume if the nomination fails)
|
|
1004
|
+
if (this.nominating && !this.nominated)
|
|
1005
|
+
return true;
|
|
1006
|
+
// Ordinary Check
|
|
1007
|
+
{
|
|
1008
|
+
// # find the highest-priority pair that is in the waiting state
|
|
1009
|
+
const pair = this.checkList
|
|
1010
|
+
.filter((pair) => {
|
|
1011
|
+
if (this.options.forceTurn &&
|
|
1012
|
+
pair.protocol.type === StunProtocol.type)
|
|
1013
|
+
return false;
|
|
1014
|
+
return true;
|
|
1015
|
+
})
|
|
1016
|
+
.find((pair) => pair.state === CandidatePairState.WAITING);
|
|
1017
|
+
if (pair) {
|
|
1018
|
+
pair.handle = this.checkStart(pair);
|
|
1019
|
+
return true;
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
{
|
|
1023
|
+
// # find the highest-priority pair that is in the frozen state
|
|
1024
|
+
const pair = this.checkList.find((pair) => pair.state === CandidatePairState.FROZEN);
|
|
1025
|
+
if (pair) {
|
|
1026
|
+
pair.handle = this.checkStart(pair);
|
|
1027
|
+
return true;
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
// # if we expect more candidates, keep going: their end has not come, some are being resolved, or there is no
|
|
1031
|
+
// pair yet (the checks of the other side may give one)
|
|
1032
|
+
if (!this.remoteCandidatesEnd || this.resolvingRemoteCandidates > 0 || (!this.checkList.length && Date.now() < this.noPairDeadline)) {
|
|
1033
|
+
return !this.checkListDone;
|
|
1034
|
+
}
|
|
1035
|
+
return false;
|
|
1036
|
+
}
|
|
1037
|
+
/**
|
|
1038
|
+
* Stop consent request cadence, expiry timer, and outstanding transactions.
|
|
1039
|
+
* Does not change ICE state by itself.
|
|
1040
|
+
*/
|
|
1041
|
+
stopConsentLifecycle() {
|
|
1042
|
+
this.consentSessionId++;
|
|
1043
|
+
this.consentFresh = false;
|
|
1044
|
+
if (this.consentExpiryTimer !== undefined) {
|
|
1045
|
+
clearTimeout(this.consentExpiryTimer);
|
|
1046
|
+
this.consentExpiryTimer = undefined;
|
|
1047
|
+
}
|
|
1048
|
+
this.consentRequestAbort?.abort();
|
|
1049
|
+
this.consentRequestAbort = undefined;
|
|
1050
|
+
const handle = this.queryConsentHandle;
|
|
1051
|
+
this.queryConsentHandle = undefined;
|
|
1052
|
+
// Resolve after clearing the field so a stale onCancel cannot wipe a replacement.
|
|
1053
|
+
handle?.resolve?.();
|
|
1054
|
+
}
|
|
1055
|
+
/**
|
|
1056
|
+
* ICE-lite interop only (not required by RFC 7675): mirror libwebrtc
|
|
1057
|
+
* semi-aggressive nomination — attach USE-CANDIDATE when we are controlling,
|
|
1058
|
+
* the remote is ICE-lite, and the target is the current selected pair.
|
|
1059
|
+
*/
|
|
1060
|
+
shouldNominateConsentRequest(pair) {
|
|
1061
|
+
return (this.iceControlling && this.remoteIsLite && this.nominated?.id === pair.id);
|
|
1062
|
+
}
|
|
1063
|
+
canSendApplicationData() {
|
|
1064
|
+
if (!this.nominated) {
|
|
1065
|
+
return false;
|
|
1066
|
+
}
|
|
1067
|
+
if (this.state === 'closed' || this.state === 'failed') {
|
|
1068
|
+
return false;
|
|
1069
|
+
}
|
|
1070
|
+
// Local ICE-lite does not run consent checks; full agents need fresh consent.
|
|
1071
|
+
if (this.iceLite) {
|
|
1072
|
+
return true;
|
|
1073
|
+
}
|
|
1074
|
+
return this.consentFresh;
|
|
1075
|
+
}
|
|
1076
|
+
abortableDelay(ms, signal) {
|
|
1077
|
+
return new Promise((resolve, reject) => {
|
|
1078
|
+
if (signal.aborted) {
|
|
1079
|
+
reject(new DOMException('The operation was aborted', 'AbortError'));
|
|
1080
|
+
return;
|
|
1081
|
+
}
|
|
1082
|
+
const timer = setTimeout(() => {
|
|
1083
|
+
signal.removeEventListener('abort', onAbort);
|
|
1084
|
+
resolve();
|
|
1085
|
+
}, ms);
|
|
1086
|
+
const onAbort = () => {
|
|
1087
|
+
clearTimeout(timer);
|
|
1088
|
+
reject(new DOMException('The operation was aborted', 'AbortError'));
|
|
1089
|
+
};
|
|
1090
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
1091
|
+
});
|
|
1092
|
+
}
|
|
1093
|
+
async close() {
|
|
1094
|
+
// """
|
|
1095
|
+
// Close the connection.
|
|
1096
|
+
// """
|
|
1097
|
+
this.setState('closed');
|
|
1098
|
+
// # stop consent freshness tests
|
|
1099
|
+
this.stopConsentLifecycle();
|
|
1100
|
+
// # stop check list
|
|
1101
|
+
if (this.checkList && !this.checkListDone) {
|
|
1102
|
+
this.checkListState.put(new Promise((r) => {
|
|
1103
|
+
r(ICE_FAILED);
|
|
1104
|
+
}));
|
|
1105
|
+
}
|
|
1106
|
+
this.nominated = undefined;
|
|
1107
|
+
const protocols = this.protocols;
|
|
1108
|
+
this.protocols = [];
|
|
1109
|
+
this.relays.clear();
|
|
1110
|
+
//Together: closing a relay waits for its server to delete the allocation
|
|
1111
|
+
await Promise.all(protocols.map(async (protocol) => {
|
|
1112
|
+
await protocol.close?.();
|
|
1113
|
+
}));
|
|
1114
|
+
this.localCandidates = [];
|
|
1115
|
+
this.lookup?.close?.();
|
|
1116
|
+
this.lookup = undefined;
|
|
1117
|
+
}
|
|
1118
|
+
setState(state) {
|
|
1119
|
+
this.state = state;
|
|
1120
|
+
this.stateChanged.execute(state);
|
|
1121
|
+
}
|
|
1122
|
+
async addRemoteCandidate(remoteCandidate) {
|
|
1123
|
+
// """
|
|
1124
|
+
// Add a remote candidate or signal end-of-candidates.
|
|
1125
|
+
// To signal end-of-candidates, pass `None`.
|
|
1126
|
+
// :param remote_candidate: A :class:`Candidate` instance or `None`.
|
|
1127
|
+
// """
|
|
1128
|
+
if (!remoteCandidate) {
|
|
1129
|
+
this.remoteCandidatesEnd = true;
|
|
1130
|
+
return;
|
|
1131
|
+
}
|
|
1132
|
+
//An mDNS name is resolved meanwhile, as the browsers do: a name nobody answers for (up to 10 seconds) does not
|
|
1133
|
+
//hold the descriptions and the candidates applied after it; the checks wait for it
|
|
1134
|
+
if (remoteCandidate.host.includes('.local')) {
|
|
1135
|
+
void this.resolveRemoteCandidate(remoteCandidate);
|
|
1136
|
+
return;
|
|
1137
|
+
}
|
|
1138
|
+
this.addResolvedRemoteCandidate(remoteCandidate);
|
|
1139
|
+
}
|
|
1140
|
+
/**
|
|
1141
|
+
* Resolve the mDNS name of a remote candidate, then add it, unless ICE restarted or closed meanwhile
|
|
1142
|
+
* @param remoteCandidate
|
|
1143
|
+
*/
|
|
1144
|
+
async resolveRemoteCandidate(remoteCandidate) {
|
|
1145
|
+
const generation = this.generation;
|
|
1146
|
+
this.resolvingRemoteCandidates++;
|
|
1147
|
+
try {
|
|
1148
|
+
if (!this.lookup) {
|
|
1149
|
+
this.lookup = new MdnsLookup();
|
|
1150
|
+
}
|
|
1151
|
+
remoteCandidate.host = await this.lookup.lookup(remoteCandidate.host);
|
|
1152
|
+
}
|
|
1153
|
+
catch {
|
|
1154
|
+
return;
|
|
1155
|
+
}
|
|
1156
|
+
finally {
|
|
1157
|
+
this.resolvingRemoteCandidates--;
|
|
1158
|
+
}
|
|
1159
|
+
if (generation !== this.generation || this.state === 'closed')
|
|
1160
|
+
return;
|
|
1161
|
+
this.addResolvedRemoteCandidate(remoteCandidate);
|
|
1162
|
+
}
|
|
1163
|
+
/**
|
|
1164
|
+
* Add a remote candidate with an address, and pair it
|
|
1165
|
+
* @param remoteCandidate
|
|
1166
|
+
*/
|
|
1167
|
+
addResolvedRemoteCandidate(remoteCandidate) {
|
|
1168
|
+
try {
|
|
1169
|
+
validateRemoteCandidate(remoteCandidate);
|
|
1170
|
+
}
|
|
1171
|
+
catch (error) {
|
|
1172
|
+
return;
|
|
1173
|
+
}
|
|
1174
|
+
//Known already: each description applied gives its candidates again
|
|
1175
|
+
if (this._remoteCandidates.some((known) => known.host === remoteCandidate.host
|
|
1176
|
+
&& known.port === remoteCandidate.port
|
|
1177
|
+
&& known.component === remoteCandidate.component
|
|
1178
|
+
&& known.type === remoteCandidate.type
|
|
1179
|
+
&& known.transport.toLowerCase() === remoteCandidate.transport.toLowerCase())) {
|
|
1180
|
+
return;
|
|
1181
|
+
}
|
|
1182
|
+
log('addRemoteCandidate', remoteCandidate);
|
|
1183
|
+
this._remoteCandidates.push(remoteCandidate);
|
|
1184
|
+
this.pairRemoteCandidate(remoteCandidate);
|
|
1185
|
+
this.sortCheckList();
|
|
1186
|
+
}
|
|
1187
|
+
getDefaultCandidate() {
|
|
1188
|
+
const candidates = this.localCandidates.sort((a, b) => a.priority - b.priority);
|
|
1189
|
+
const [candidate] = candidates;
|
|
1190
|
+
return candidate;
|
|
1191
|
+
}
|
|
1192
|
+
// for test only
|
|
1193
|
+
set remoteCandidates(value) {
|
|
1194
|
+
if (this.remoteCandidatesEnd)
|
|
1195
|
+
throw new Error('Cannot set remote candidates after end-of-candidates.');
|
|
1196
|
+
this._remoteCandidates = [];
|
|
1197
|
+
for (const remoteCandidate of value) {
|
|
1198
|
+
try {
|
|
1199
|
+
validateRemoteCandidate(remoteCandidate);
|
|
1200
|
+
}
|
|
1201
|
+
catch (error) {
|
|
1202
|
+
continue;
|
|
1203
|
+
}
|
|
1204
|
+
this._remoteCandidates.push(remoteCandidate);
|
|
1205
|
+
}
|
|
1206
|
+
this.remoteCandidatesEnd = true;
|
|
1207
|
+
}
|
|
1208
|
+
get remoteCandidates() {
|
|
1209
|
+
return this._remoteCandidates;
|
|
1210
|
+
}
|
|
1211
|
+
get candidatePairs() {
|
|
1212
|
+
return this.checkList;
|
|
1213
|
+
}
|
|
1214
|
+
sortCheckList() {
|
|
1215
|
+
sortCandidatePairs(this.checkList, this.iceControlling);
|
|
1216
|
+
}
|
|
1217
|
+
findPair(protocol, remoteCandidate) {
|
|
1218
|
+
const pair = this.checkList.find((pair) => pair.protocol === protocol && pair.remoteCandidate === remoteCandidate);
|
|
1219
|
+
return pair;
|
|
1220
|
+
}
|
|
1221
|
+
applyIceControlling(iceControlling) {
|
|
1222
|
+
this._iceControlling = iceControlling;
|
|
1223
|
+
for (const pair of this.checkList) {
|
|
1224
|
+
pair.iceControlling = iceControlling;
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
switchRole(iceControlling) {
|
|
1228
|
+
log('switch role', iceControlling);
|
|
1229
|
+
// Role conflicts must be repaired even after a prior generation or while
|
|
1230
|
+
// connectivity checks are in flight (RFC 8445 §7.2.5.1 / §7.3.1.1).
|
|
1231
|
+
if (this.iceLite) {
|
|
1232
|
+
iceControlling = false;
|
|
1233
|
+
}
|
|
1234
|
+
this.applyIceControlling(iceControlling);
|
|
1235
|
+
this.sortCheckList();
|
|
1236
|
+
}
|
|
1237
|
+
checkComplete(pair) {
|
|
1238
|
+
pair.handle = undefined;
|
|
1239
|
+
if (pair.state === CandidatePairState.SUCCEEDED) {
|
|
1240
|
+
// Updating the Nominated Flag
|
|
1241
|
+
// https://www.rfc-editor.org/rfc/rfc8445#section-7.3.1.5,
|
|
1242
|
+
// Once the nominated flag is set for a component of a data stream, it
|
|
1243
|
+
// concludes the ICE processing for that component. See Section 8.
|
|
1244
|
+
// So disallow overwriting of the pair nominated for that component
|
|
1245
|
+
//A candidate of the current session of the other side: the candidates and the pairs of a session before are gone
|
|
1246
|
+
//(restart), and the generation a candidate gives is the one the other side counts (Chrome gives 0 always),
|
|
1247
|
+
//so only its ufrag, when given, tells
|
|
1248
|
+
if (pair.nominated &&
|
|
1249
|
+
(pair.remoteCandidate.ufrag == undefined || pair.remoteCandidate.ufrag === this.remoteUsername) &&
|
|
1250
|
+
this.nominated == undefined) {
|
|
1251
|
+
log('nominated', pair.toJSON());
|
|
1252
|
+
this.nominated = pair;
|
|
1253
|
+
this.nominating = false;
|
|
1254
|
+
this.pruneTcpConnections(pair);
|
|
1255
|
+
//Its socket sends only to the other side from now on, once the other side is seen using the pair
|
|
1256
|
+
pair.protocol.connectTo?.(pair.remoteAddr);
|
|
1257
|
+
// After resetNominatedPair / renomination while already connected,
|
|
1258
|
+
// restart consent freshness on the new selected pair.
|
|
1259
|
+
if (!this.iceLite &&
|
|
1260
|
+
(this.state === 'connected' || this.state === 'completed')) {
|
|
1261
|
+
this.queryConsent();
|
|
1262
|
+
}
|
|
1263
|
+
// 8.1.2. Updating States
|
|
1264
|
+
// The agent MUST remove all Waiting and Frozen pairs in the check
|
|
1265
|
+
// list and triggered check queue for the same component as the
|
|
1266
|
+
// nominated pairs for that media stream.
|
|
1267
|
+
for (const p of this.checkList) {
|
|
1268
|
+
if (p.component === pair.component &&
|
|
1269
|
+
[CandidatePairState.WAITING, CandidatePairState.FROZEN].includes(p.state)) {
|
|
1270
|
+
p.updateState(CandidatePairState.FAILED);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
// Once there is at least one nominated pair in the valid list for
|
|
1275
|
+
// every component of at least one media stream and the state of the
|
|
1276
|
+
// check list is Running:
|
|
1277
|
+
if (this.nominated) {
|
|
1278
|
+
if (!this.checkListDone) {
|
|
1279
|
+
log('ICE completed');
|
|
1280
|
+
this.checkListState.put(new Promise((r) => r(ICE_COMPLETED)));
|
|
1281
|
+
this.checkListDone = true;
|
|
1282
|
+
}
|
|
1283
|
+
return;
|
|
1284
|
+
}
|
|
1285
|
+
log('not completed', pair.toJSON());
|
|
1286
|
+
// 7.1.3.2.3. Updating Pair States
|
|
1287
|
+
for (const p of this.checkList) {
|
|
1288
|
+
if (p.localCandidate.foundation === pair.localCandidate.foundation &&
|
|
1289
|
+
p.state === CandidatePairState.FROZEN) {
|
|
1290
|
+
p.updateState(CandidatePairState.WAITING);
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
this.nominateTcpPairIfReady();
|
|
1295
|
+
// A nomination request is still in flight; its result decides the outcome.
|
|
1296
|
+
if (this.nominating) {
|
|
1297
|
+
return;
|
|
1298
|
+
}
|
|
1299
|
+
{
|
|
1300
|
+
const list = [CandidatePairState.SUCCEEDED, CandidatePairState.FAILED];
|
|
1301
|
+
if (this.checkList.find(({ state }) => !list.includes(state))) {
|
|
1302
|
+
return;
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
if (!this.iceControlling) {
|
|
1306
|
+
const target = CandidatePairState.SUCCEEDED;
|
|
1307
|
+
if (this.checkList.find(({ state }) => state === target)) {
|
|
1308
|
+
return;
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
if (!this.checkListDone) {
|
|
1312
|
+
log('ICE failed');
|
|
1313
|
+
this.checkListState.put(new Promise((r) => {
|
|
1314
|
+
r(ICE_FAILED);
|
|
1315
|
+
}));
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
isTcpPair(pair) {
|
|
1319
|
+
return pair.localCandidate.transport.toLowerCase() === 'tcp';
|
|
1320
|
+
}
|
|
1321
|
+
/**
|
|
1322
|
+
* Aggressive nomination lets each side settle on whichever TCP connection
|
|
1323
|
+
* finished first; the two sides can then pick different connections and
|
|
1324
|
+
* pruning destroys the peer's choice. For TCP the controlling agent instead
|
|
1325
|
+
* nominates exactly one valid pair (RFC 8445 §8.1.1 regular nomination).
|
|
1326
|
+
*/
|
|
1327
|
+
usesTcpRegularNomination(pair) {
|
|
1328
|
+
return this.iceControlling && !this.remoteIsLite && this.isTcpPair(pair);
|
|
1329
|
+
}
|
|
1330
|
+
checkRequestOptions(pair) {
|
|
1331
|
+
const onRequestSent = (attempt) => {
|
|
1332
|
+
if (attempt > 0) {
|
|
1333
|
+
pair.retransmissionsSent++;
|
|
1334
|
+
}
|
|
1335
|
+
};
|
|
1336
|
+
if (this.isTcpPair(pair)) {
|
|
1337
|
+
// RFC 5389 §7.2.2: no retransmissions over a reliable transport.
|
|
1338
|
+
return {
|
|
1339
|
+
retransmissions: 0,
|
|
1340
|
+
responseTimeout: TCP_CHECK_RESPONSE_TIMEOUT_MS,
|
|
1341
|
+
onRequestSent
|
|
1342
|
+
};
|
|
1343
|
+
}
|
|
1344
|
+
return { retransmissions: 4, onRequestSent };
|
|
1345
|
+
}
|
|
1346
|
+
/**
|
|
1347
|
+
* Controlling side: nominate the highest-priority TCP pair once every
|
|
1348
|
+
* higher-priority TCP pair has finished its check, so the choice does not
|
|
1349
|
+
* depend on which connection happened to complete first.
|
|
1350
|
+
*/
|
|
1351
|
+
nominateTcpPairIfReady() {
|
|
1352
|
+
if (!this.iceControlling ||
|
|
1353
|
+
this.remoteIsLite ||
|
|
1354
|
+
this.nominated ||
|
|
1355
|
+
this.nominating) {
|
|
1356
|
+
return;
|
|
1357
|
+
}
|
|
1358
|
+
for (const pair of this.checkList) {
|
|
1359
|
+
if (!this.isTcpPair(pair)) {
|
|
1360
|
+
continue;
|
|
1361
|
+
}
|
|
1362
|
+
if (pair.state === CandidatePairState.SUCCEEDED) {
|
|
1363
|
+
this.nominateTcpPair(pair);
|
|
1364
|
+
return;
|
|
1365
|
+
}
|
|
1366
|
+
if (pair.state !== CandidatePairState.FAILED) {
|
|
1367
|
+
// A higher-priority pair may still succeed.
|
|
1368
|
+
return;
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
nominateTcpPair(pair) {
|
|
1373
|
+
this.nominating = true;
|
|
1374
|
+
const { generation } = this;
|
|
1375
|
+
const request = this.buildRequest({
|
|
1376
|
+
nominate: true,
|
|
1377
|
+
localUsername: pair.localCandidate.ufrag ?? this.localUsername,
|
|
1378
|
+
remoteUsername: this.remoteUsername,
|
|
1379
|
+
iceControlling: this.iceControlling,
|
|
1380
|
+
localCandidate: pair.localCandidate
|
|
1381
|
+
});
|
|
1382
|
+
pair.requestsSent++;
|
|
1383
|
+
pair.protocol
|
|
1384
|
+
.request(request, pair.remoteAddr, Buffer.from(this.remotePassword, 'utf8'), this.checkRequestOptions(pair))
|
|
1385
|
+
.then(() => {
|
|
1386
|
+
if (this.isStaleNomination(pair, generation)) {
|
|
1387
|
+
return;
|
|
1388
|
+
}
|
|
1389
|
+
pair.responsesReceived++;
|
|
1390
|
+
pair.nominated = true;
|
|
1391
|
+
this.nominating = false;
|
|
1392
|
+
this.checkComplete(pair);
|
|
1393
|
+
}, (error) => {
|
|
1394
|
+
if (this.isStaleNomination(pair, generation)) {
|
|
1395
|
+
return;
|
|
1396
|
+
}
|
|
1397
|
+
log('tcp nomination failed', pair.toJSON(), error);
|
|
1398
|
+
this.nominating = false;
|
|
1399
|
+
pair.updateState(CandidatePairState.FAILED);
|
|
1400
|
+
this.checkComplete(pair);
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
/** The agent was closed or restarted while the nomination was in flight. */
|
|
1404
|
+
isStaleNomination(pair, generation) {
|
|
1405
|
+
return (this.state === 'closed' ||
|
|
1406
|
+
this.generation !== generation ||
|
|
1407
|
+
!this.checkList.includes(pair));
|
|
1408
|
+
}
|
|
1409
|
+
addPair(pair) {
|
|
1410
|
+
this.checkList.push(pair);
|
|
1411
|
+
this.sortCheckList();
|
|
1412
|
+
}
|
|
1413
|
+
// 7.2. STUN Server Procedures
|
|
1414
|
+
// 7.2.1.3、7.2.1.4、および7.2.1.5
|
|
1415
|
+
checkIncoming(message, addr, protocol) {
|
|
1416
|
+
// """
|
|
1417
|
+
// Handle a successful incoming check.
|
|
1418
|
+
// """
|
|
1419
|
+
const txUsername = message.getAttributeValue('USERNAME');
|
|
1420
|
+
const { remoteUsername: localUsername } = decodeTxUsername(txUsername);
|
|
1421
|
+
// find remote candidate
|
|
1422
|
+
let remoteCandidate;
|
|
1423
|
+
const [host, port] = addr;
|
|
1424
|
+
for (const c of this.remoteCandidates) {
|
|
1425
|
+
if (c.host === host && c.port === port) {
|
|
1426
|
+
remoteCandidate = c;
|
|
1427
|
+
break;
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
if (!remoteCandidate) {
|
|
1431
|
+
// 7.2.1.3. Learning Peer Reflexive Candidates
|
|
1432
|
+
remoteCandidate = new Candidate(randomString(10), 1, protocol.localCandidate?.transport ?? 'udp', message.getAttributeValue('PRIORITY'), host, port, 'prflx', undefined, undefined, protocol.localCandidate?.transport === 'tcp'
|
|
1433
|
+
? remoteTcpTypeForIncoming(protocol.localCandidate.tcptype)
|
|
1434
|
+
: undefined, undefined, undefined);
|
|
1435
|
+
this._remoteCandidates.push(remoteCandidate);
|
|
1436
|
+
}
|
|
1437
|
+
// find pair
|
|
1438
|
+
let pair = this.findPair(protocol, remoteCandidate);
|
|
1439
|
+
if (!pair) {
|
|
1440
|
+
pair = new CandidatePair(protocol, remoteCandidate, this.iceControlling);
|
|
1441
|
+
pair.updateState(CandidatePairState.WAITING);
|
|
1442
|
+
this.addPair(pair);
|
|
1443
|
+
}
|
|
1444
|
+
pair.noteIncomingRequest(message.transactionIdHex);
|
|
1445
|
+
pair.requestsReceived++;
|
|
1446
|
+
pair.responsesSent++;
|
|
1447
|
+
pair.localCandidate.ufrag = localUsername;
|
|
1448
|
+
log('Triggered Checks', message.toJSON(), pair.toJSON(), {
|
|
1449
|
+
localUsername: this.localUsername,
|
|
1450
|
+
remoteUsername: this.remoteUsername,
|
|
1451
|
+
localPassword: this.localPassword,
|
|
1452
|
+
remotePassword: this.remotePassword,
|
|
1453
|
+
generation: this.generation
|
|
1454
|
+
});
|
|
1455
|
+
if (this.iceLite) {
|
|
1456
|
+
if (message.attributesKeys.includes('USE-CANDIDATE') &&
|
|
1457
|
+
!this.iceControlling) {
|
|
1458
|
+
pair.remoteNominated = true;
|
|
1459
|
+
pair.nominated = true;
|
|
1460
|
+
pair.updateState(CandidatePairState.SUCCEEDED);
|
|
1461
|
+
this.checkComplete(pair);
|
|
1462
|
+
}
|
|
1463
|
+
return;
|
|
1464
|
+
}
|
|
1465
|
+
// 7.2.1.4. Triggered Checks
|
|
1466
|
+
if ([CandidatePairState.WAITING, CandidatePairState.FAILED].includes(pair.state)) {
|
|
1467
|
+
pair.handle = this.checkStart(pair);
|
|
1468
|
+
}
|
|
1469
|
+
// 7.2.1.5. Updating the Nominated Flag
|
|
1470
|
+
if (message.attributesKeys.includes('USE-CANDIDATE') &&
|
|
1471
|
+
!this.iceControlling) {
|
|
1472
|
+
pair.remoteNominated = true;
|
|
1473
|
+
if (pair.state === CandidatePairState.SUCCEEDED) {
|
|
1474
|
+
pair.nominated = true;
|
|
1475
|
+
this.checkComplete(pair);
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
tryPair(protocol, remoteCandidate) {
|
|
1480
|
+
if (protocol.localCandidate?.canPairWith(remoteCandidate) &&
|
|
1481
|
+
!(protocol.localCandidate.transport.toLowerCase() === 'tcp' &&
|
|
1482
|
+
protocol.localCandidate.tcptype === 'passive' &&
|
|
1483
|
+
remoteCandidate.type !== 'prflx') &&
|
|
1484
|
+
!this.findPair(protocol, remoteCandidate)) {
|
|
1485
|
+
const pair = new CandidatePair(protocol, remoteCandidate, this.iceControlling);
|
|
1486
|
+
if (this.options.filterCandidatePair &&
|
|
1487
|
+
!this.options.filterCandidatePair(pair)) {
|
|
1488
|
+
return;
|
|
1489
|
+
}
|
|
1490
|
+
pair.updateState(CandidatePairState.WAITING);
|
|
1491
|
+
this.addPair(pair);
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
pairLocalProtocol(protocol) {
|
|
1495
|
+
for (const remoteCandidate of this.remoteCandidates) {
|
|
1496
|
+
this.tryPair(protocol, remoteCandidate);
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
buildRequest({ nominate, remoteUsername, localUsername, iceControlling, localCandidate }) {
|
|
1500
|
+
const txUsername = encodeTxUsername({ remoteUsername, localUsername });
|
|
1501
|
+
const request = new Message(methods.BINDING, classes.REQUEST);
|
|
1502
|
+
request.setAttribute('USERNAME', txUsername).setAttribute('PRIORITY', candidatePriority('prflx', {
|
|
1503
|
+
transport: localCandidate?.transport,
|
|
1504
|
+
tcptype: localCandidate?.tcptype
|
|
1505
|
+
}));
|
|
1506
|
+
if (iceControlling) {
|
|
1507
|
+
request.setAttribute('ICE-CONTROLLING', this.tieBreaker);
|
|
1508
|
+
if (nominate) {
|
|
1509
|
+
request.setAttribute('USE-CANDIDATE', null);
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
else {
|
|
1513
|
+
request.setAttribute('ICE-CONTROLLED', this.tieBreaker);
|
|
1514
|
+
}
|
|
1515
|
+
return request;
|
|
1516
|
+
}
|
|
1517
|
+
pruneTcpConnections(selectedPair) {
|
|
1518
|
+
for (const protocol of this.protocols) {
|
|
1519
|
+
if (protocol.localCandidate?.transport.toLowerCase() !== 'tcp') {
|
|
1520
|
+
continue;
|
|
1521
|
+
}
|
|
1522
|
+
if ('pruneForSelection' in protocol &&
|
|
1523
|
+
typeof protocol.pruneForSelection === 'function') {
|
|
1524
|
+
void protocol.pruneForSelection(protocol === selectedPair.protocol
|
|
1525
|
+
? selectedPair.remoteAddr
|
|
1526
|
+
: undefined);
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
respondError(request, addr, protocol, errorCode) {
|
|
1531
|
+
const response = new Message(request.messageMethod, classes.ERROR, request.transactionId);
|
|
1532
|
+
response
|
|
1533
|
+
.setAttribute('ERROR-CODE', errorCode)
|
|
1534
|
+
.addMessageIntegrity(Buffer.from(this.localPassword, 'utf8'))
|
|
1535
|
+
.addFingerprint();
|
|
1536
|
+
protocol.sendStun(response, addr).catch((e) => {
|
|
1537
|
+
log('sendStun error', e);
|
|
1538
|
+
});
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
const encodeTxUsername = ({ remoteUsername, localUsername }) => {
|
|
1542
|
+
return `${remoteUsername}:${localUsername}`;
|
|
1543
|
+
};
|
|
1544
|
+
const decodeTxUsername = (txUsername) => {
|
|
1545
|
+
const [remoteUsername, localUsername] = txUsername.split(':');
|
|
1546
|
+
return { remoteUsername, localUsername };
|
|
1547
|
+
};
|