werift 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -0
- package/lib/common/src/transport.d.ts +22 -9
- package/lib/common/src/transport.js +152 -25
- package/lib/common/src/transport.js.map +1 -1
- package/lib/ice/src/candidate.d.ts +16 -1
- package/lib/ice/src/candidate.js +99 -15
- package/lib/ice/src/candidate.js.map +1 -1
- package/lib/ice/src/ice.d.ts +2 -0
- package/lib/ice/src/ice.js +171 -41
- package/lib/ice/src/ice.js.map +1 -1
- package/lib/ice/src/iceBase.d.ts +23 -2
- package/lib/ice/src/iceBase.js +63 -1
- package/lib/ice/src/iceBase.js.map +1 -1
- package/lib/ice/src/index.d.ts +2 -0
- package/lib/ice/src/index.js +2 -0
- package/lib/ice/src/index.js.map +1 -1
- package/lib/ice/src/stun/const.d.ts +1 -26
- package/lib/ice/src/stun/const.js +15 -54
- package/lib/ice/src/stun/const.js.map +1 -1
- package/lib/ice/src/stun/message.d.ts +1 -25
- package/lib/ice/src/stun/message.js +15 -149
- package/lib/ice/src/stun/message.js.map +1 -1
- package/lib/ice/src/stun/protocol.d.ts +1 -1
- package/lib/ice/src/stun/protocol.js +2 -2
- package/lib/ice/src/stun/protocol.js.map +1 -1
- package/lib/ice/src/stun/tcpFrame.d.ts +5 -0
- package/lib/ice/src/stun/tcpFrame.js +26 -0
- package/lib/ice/src/stun/tcpFrame.js.map +1 -0
- package/lib/ice/src/stun/tcpProtocol.d.ts +51 -0
- package/lib/ice/src/stun/tcpProtocol.js +326 -0
- package/lib/ice/src/stun/tcpProtocol.js.map +1 -0
- package/lib/ice/src/stun/transaction.d.ts +2 -1
- package/lib/ice/src/stun/transaction.js +9 -3
- package/lib/ice/src/stun/transaction.js.map +1 -1
- package/lib/ice/src/turn/frame.d.ts +1 -0
- package/lib/ice/src/turn/frame.js +18 -0
- package/lib/ice/src/turn/frame.js.map +1 -0
- package/lib/ice/src/turn/protocol.d.ts +9 -7
- package/lib/ice/src/turn/protocol.js +32 -44
- package/lib/ice/src/turn/protocol.js.map +1 -1
- package/lib/ice/src/types/model.d.ts +1 -1
- package/lib/ice/src/types/model.js.map +1 -1
- package/lib/{ice → ice-server}/src/stun/attributes.d.ts +12 -5
- package/lib/{ice → ice-server}/src/stun/attributes.js +60 -19
- package/lib/ice-server/src/stun/attributes.js.map +1 -0
- package/lib/ice-server/src/stun/const.d.ts +28 -0
- package/lib/ice-server/src/stun/const.js +88 -0
- package/lib/ice-server/src/stun/const.js.map +1 -0
- package/lib/ice-server/src/stun/message.d.ts +37 -0
- package/lib/ice-server/src/stun/message.js +190 -0
- package/lib/ice-server/src/stun/message.js.map +1 -0
- package/lib/ice-server/src/turn/auth.d.ts +1 -0
- package/lib/ice-server/src/turn/auth.js +10 -0
- package/lib/ice-server/src/turn/auth.js.map +1 -0
- package/lib/ice-server/src/turn/frame.d.ts +13 -0
- package/lib/ice-server/src/turn/frame.js +69 -0
- package/lib/ice-server/src/turn/frame.js.map +1 -0
- package/lib/index.mjs +2688 -855
- package/lib/nonstandard/index.mjs +1753 -403
- package/lib/rtp/src/extra/container/mp4/container.d.ts +9 -6
- package/lib/rtp/src/extra/container/mp4/container.js +258 -173
- package/lib/rtp/src/extra/container/mp4/container.js.map +1 -1
- package/lib/rtp/src/extra/container/mp4/h264.d.ts +1 -0
- package/lib/rtp/src/extra/container/mp4/h264.js +13 -0
- package/lib/rtp/src/extra/container/mp4/h264.js.map +1 -1
- package/lib/rtp/src/extra/processor/mp4.d.ts +11 -7
- package/lib/rtp/src/extra/processor/mp4.js +115 -60
- package/lib/rtp/src/extra/processor/mp4.js.map +1 -1
- package/lib/rtp/src/extra/processor/mp4Callback.d.ts +2 -3
- package/lib/rtp/src/extra/processor/mp4Callback.js +5 -3
- package/lib/rtp/src/extra/processor/mp4Callback.js.map +1 -1
- package/lib/webrtc/src/dataChannel.d.ts +3 -2
- package/lib/webrtc/src/dataChannel.js +9 -2
- package/lib/webrtc/src/dataChannel.js.map +1 -1
- package/lib/webrtc/src/errors.d.ts +3 -0
- package/lib/webrtc/src/errors.js +11 -0
- package/lib/webrtc/src/errors.js.map +1 -0
- package/lib/webrtc/src/helper.d.ts +5 -1
- package/lib/webrtc/src/helper.js +33 -1
- package/lib/webrtc/src/helper.js.map +1 -1
- package/lib/webrtc/src/media/receiver/statistics.d.ts +4 -1
- package/lib/webrtc/src/media/receiver/statistics.js +22 -0
- package/lib/webrtc/src/media/receiver/statistics.js.map +1 -1
- package/lib/webrtc/src/media/rtpReceiver.d.ts +15 -2
- package/lib/webrtc/src/media/rtpReceiver.js +135 -20
- package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
- package/lib/webrtc/src/media/rtpSender.d.ts +32 -7
- package/lib/webrtc/src/media/rtpSender.js +177 -28
- package/lib/webrtc/src/media/rtpSender.js.map +1 -1
- package/lib/webrtc/src/media/rtpTransceiver.d.ts +13 -4
- package/lib/webrtc/src/media/rtpTransceiver.js +26 -5
- package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
- package/lib/webrtc/src/media/stats.d.ts +15 -1
- package/lib/webrtc/src/media/stats.js +55 -1
- package/lib/webrtc/src/media/stats.js.map +1 -1
- package/lib/webrtc/src/media/track.d.ts +2 -1
- package/lib/webrtc/src/media/track.js +7 -1
- package/lib/webrtc/src/media/track.js.map +1 -1
- package/lib/webrtc/src/nonstandard/dummyMedia.d.ts +19 -0
- package/lib/webrtc/src/nonstandard/dummyMedia.js +157 -0
- package/lib/webrtc/src/nonstandard/dummyMedia.js.map +1 -0
- package/lib/webrtc/src/nonstandard/navigator.d.ts +18 -8
- package/lib/webrtc/src/nonstandard/navigator.js +96 -32
- package/lib/webrtc/src/nonstandard/navigator.js.map +1 -1
- package/lib/webrtc/src/nonstandard/userMedia/packetizer.d.ts +16 -0
- package/lib/webrtc/src/nonstandard/userMedia/packetizer.js +360 -0
- package/lib/webrtc/src/nonstandard/userMedia/packetizer.js.map +1 -0
- package/lib/webrtc/src/nonstandard/userMedia.d.ts +71 -31
- package/lib/webrtc/src/nonstandard/userMedia.js +454 -108
- package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
- package/lib/webrtc/src/peerConnection.d.ts +183 -50
- package/lib/webrtc/src/peerConnection.js +458 -109
- package/lib/webrtc/src/peerConnection.js.map +1 -1
- package/lib/webrtc/src/sctpManager.d.ts +1 -1
- package/lib/webrtc/src/sctpManager.js +27 -7
- package/lib/webrtc/src/sctpManager.js.map +1 -1
- package/lib/webrtc/src/sdp.d.ts +10 -7
- package/lib/webrtc/src/sdp.js +39 -9
- package/lib/webrtc/src/sdp.js.map +1 -1
- package/lib/webrtc/src/sdpManager.d.ts +4 -3
- package/lib/webrtc/src/sdpManager.js +50 -27
- package/lib/webrtc/src/sdpManager.js.map +1 -1
- package/lib/webrtc/src/secureTransportManager.d.ts +13 -4
- package/lib/webrtc/src/secureTransportManager.js +100 -22
- package/lib/webrtc/src/secureTransportManager.js.map +1 -1
- package/lib/webrtc/src/transceiverManager.d.ts +5 -4
- package/lib/webrtc/src/transceiverManager.js +61 -62
- package/lib/webrtc/src/transceiverManager.js.map +1 -1
- package/lib/webrtc/src/transport/dtls.d.ts +15 -4
- package/lib/webrtc/src/transport/dtls.js +91 -23
- package/lib/webrtc/src/transport/dtls.js.map +1 -1
- package/lib/webrtc/src/transport/ice.d.ts +21 -3
- package/lib/webrtc/src/transport/ice.js +159 -30
- package/lib/webrtc/src/transport/ice.js.map +1 -1
- package/lib/webrtc/src/transport/sctp.d.ts +1 -0
- package/lib/webrtc/src/transport/sctp.js +9 -6
- package/lib/webrtc/src/transport/sctp.js.map +1 -1
- package/lib/webrtc/src/utils.d.ts +12 -4
- package/lib/webrtc/src/utils.js +118 -16
- package/lib/webrtc/src/utils.js.map +1 -1
- package/package.json +7 -4
- package/lib/ice/src/stun/attributes.js.map +0 -1
- package/lib/rtp/src/extra/container/mp4/mp4box.d.ts +0 -5
- package/lib/rtp/src/extra/container/mp4/mp4box.js +0 -32
- package/lib/rtp/src/extra/container/mp4/mp4box.js.map +0 -1
package/README.md
CHANGED
|
@@ -8,6 +8,28 @@ werift is a WebRTC Implementation for TypeScript (Node.js)
|
|
|
8
8
|
|
|
9
9
|
`npm install werift`
|
|
10
10
|
|
|
11
|
+
## Development setup
|
|
12
|
+
|
|
13
|
+
Initialize the pinned upstream WPT checkout before running the package-level WPT tooling:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
git submodule update --init --recursive
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Run the allowlisted upstream WPT subset and coverage from the repository root or from this package:
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
npm run wpt --workspace packages/webrtc
|
|
23
|
+
npm run wpt:coverage --workspace packages/webrtc
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Refresh the committed baselines when intentionally expanding upstream coverage:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
npm run wpt --workspace packages/webrtc -- --update-baseline
|
|
30
|
+
WPT_UPDATE_COVERAGE_BASELINE=1 npm run wpt:coverage --workspace packages/webrtc
|
|
31
|
+
```
|
|
32
|
+
|
|
11
33
|
# Documentation (WIP)
|
|
12
34
|
|
|
13
35
|
- [Website](https://shinyoshiaki.github.io/werift-webrtc/website/build/)
|
|
@@ -109,6 +131,30 @@ see console & chrome://webrtc-internals/
|
|
|
109
131
|
- [ ] send
|
|
110
132
|
- [ ] support more cipher suites
|
|
111
133
|
|
|
134
|
+
## RTCPeerConnection W3C compatibility notes
|
|
135
|
+
|
|
136
|
+
API reference markdown can be regenerated with `cd packages/webrtc && npm run doc`.
|
|
137
|
+
For this task, the reviewable compatibility notes live in this README and in
|
|
138
|
+
`src/peerConnection.ts`; the generated `packages/webrtc/doc/` output is not
|
|
139
|
+
tracked in git, so it is not committed as part of this change.
|
|
140
|
+
|
|
141
|
+
| Status | API | Notes |
|
|
142
|
+
| --- | --- | --- |
|
|
143
|
+
| Added | `currentLocalDescription`, `pendingLocalDescription`, `currentRemoteDescription`, `pendingRemoteDescription`, `canTrickleIceCandidates`, `sctp` | Public getters now follow W3C-style pending/current description visibility and expose SCTP/canTrickle state. |
|
|
144
|
+
| Added | `setLocalDescription()` input compatibility | Accepts omitted `type`, empty `sdp`, and provisional `pranswer`. |
|
|
145
|
+
| Added | `setRemoteDescription()` input compatibility | Accepts `pranswer` and `rollback`, updating pending/current descriptions accordingly. |
|
|
146
|
+
| Added | `addIceCandidate()` input compatibility | Accepts omitted input, `null`, and `{ candidate: "" }` as end-of-candidates, validates `sdpMid` / `sdpMLineIndex` / `usernameFragment`, updates the matching remote m-section, rejects calls before `remoteDescription` is set, and rejects malformed candidate strings. |
|
|
147
|
+
| Added | `RTCConfiguration` compatibility | Accepts `iceServers`, `iceTransportPolicy`, `bundlePolicy`, `rtcpMuxPolicy: "require"`, `iceCandidatePoolSize: 0`, and `certificates`; `setConfiguration(getConfiguration())` round-trips without changing certificates. |
|
|
148
|
+
| Deferred | `bundlePolicy: "balanced"` round-trip | `"balanced"` is accepted for input compatibility, but it is internally normalized to werift's `"max-compat"` behavior, so `getConfiguration()` returns `"max-compat"`. |
|
|
149
|
+
| Added | `RTCIceServer.urls: string \| string[]` | Arrays are accepted and parsed in order. |
|
|
150
|
+
| Added | Standard event names | `signalingstatechange`, `iceconnectionstatechange`, `icegatheringstatechange`, `connectionstatechange`, `negotiationneeded`, `icecandidate`, `track`, and `datachannel` are emitted for `addEventListener`. |
|
|
151
|
+
| Not implemented | Legacy callback overloads | Kept out of scope because they are legacy browser APIs. |
|
|
152
|
+
| Not implemented | `addStream`, `removeStream`, `createDTMFSender` | These are obsolete; use `addTrack`, `removeTrack`, and transceiver/sender APIs instead. |
|
|
153
|
+
| Deferred | `close()` return type | Remains async for backward compatibility even though W3C defines synchronous `undefined`. |
|
|
154
|
+
| Deferred | `setLocalDescription()` return type | Non-rollback calls still return the applied `SessionDescription` instead of `Promise<void>` for backward compatibility; the local `rollback` path resolves with `undefined`. |
|
|
155
|
+
| Compatible | `setRemoteDescription()` return type | `setRemoteDescription()` resolves `Promise<void>` like the W3C API. |
|
|
156
|
+
| Deferred | `RTCPeerConnection.generateCertificate()` | `RTCCertificate` and `RTCConfiguration.certificates` are supported, but the static W3C helper is still optional work. |
|
|
157
|
+
|
|
112
158
|
# reference
|
|
113
159
|
|
|
114
160
|
- aiortc https://github.com/aiortc/aiortc
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { type RemoteInfo, type Socket, type SocketType } from "dgram";
|
|
2
2
|
import * as net from "node:net";
|
|
3
|
+
import * as tls from "node:tls";
|
|
3
4
|
import { type AddressInfo } from "node:net";
|
|
4
5
|
import { type Address, type InterfaceAddresses } from "./network";
|
|
6
|
+
export type TlsConnectionOptions = Omit<tls.ConnectionOptions, "host" | "port" | "socket">;
|
|
5
7
|
export declare class UdpTransport implements Transport {
|
|
6
8
|
private socketType;
|
|
7
9
|
private options;
|
|
@@ -24,17 +26,28 @@ export declare class UdpTransport implements Transport {
|
|
|
24
26
|
close: () => Promise<void>;
|
|
25
27
|
}
|
|
26
28
|
export declare class TcpTransport implements Transport {
|
|
27
|
-
|
|
28
|
-
readonly
|
|
29
|
-
private connecting;
|
|
30
|
-
private client;
|
|
31
|
-
onData: (data: Buffer, addr: Address) => void;
|
|
32
|
-
closed: boolean;
|
|
29
|
+
readonly type: "tcp";
|
|
30
|
+
private readonly stream;
|
|
33
31
|
private constructor();
|
|
34
|
-
private connect;
|
|
35
|
-
private init;
|
|
36
32
|
static init(addr: Address): Promise<TcpTransport>;
|
|
37
|
-
|
|
33
|
+
private init;
|
|
34
|
+
get address(): net.AddressInfo;
|
|
35
|
+
get closed(): boolean;
|
|
36
|
+
get onData(): (data: Buffer, addr: Address) => void;
|
|
37
|
+
set onData(handler: (data: Buffer, addr: Address) => void);
|
|
38
|
+
send: (data: Buffer, addr?: Address) => Promise<void>;
|
|
39
|
+
close: () => Promise<void>;
|
|
40
|
+
}
|
|
41
|
+
export declare class TlsTransport implements Transport {
|
|
42
|
+
readonly type: "tls";
|
|
43
|
+
private readonly stream;
|
|
44
|
+
private constructor();
|
|
45
|
+
static init(addr: Address, options?: TlsConnectionOptions): Promise<TlsTransport>;
|
|
46
|
+
private init;
|
|
47
|
+
get address(): net.AddressInfo;
|
|
48
|
+
get closed(): boolean;
|
|
49
|
+
get onData(): (data: Buffer, addr: Address) => void;
|
|
50
|
+
set onData(handler: (data: Buffer, addr: Address) => void);
|
|
38
51
|
send: (data: Buffer, addr?: Address) => Promise<void>;
|
|
39
52
|
close: () => Promise<void>;
|
|
40
53
|
}
|
|
@@ -33,9 +33,10 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.TcpTransport = exports.UdpTransport = void 0;
|
|
36
|
+
exports.TlsTransport = exports.TcpTransport = exports.UdpTransport = void 0;
|
|
37
37
|
const dgram_1 = require("dgram");
|
|
38
38
|
const net = __importStar(require("node:net"));
|
|
39
|
+
const tls = __importStar(require("node:tls"));
|
|
39
40
|
const node_net_1 = require("node:net");
|
|
40
41
|
const log_1 = require("./log");
|
|
41
42
|
const network_1 = require("./network");
|
|
@@ -172,17 +173,137 @@ class UdpTransport {
|
|
|
172
173
|
exports.UdpTransport = UdpTransport;
|
|
173
174
|
class TcpTransport {
|
|
174
175
|
constructor(addr) {
|
|
175
|
-
Object.defineProperty(this, "
|
|
176
|
+
Object.defineProperty(this, "type", {
|
|
177
|
+
enumerable: true,
|
|
178
|
+
configurable: true,
|
|
179
|
+
writable: true,
|
|
180
|
+
value: "tcp"
|
|
181
|
+
});
|
|
182
|
+
Object.defineProperty(this, "stream", {
|
|
183
|
+
enumerable: true,
|
|
184
|
+
configurable: true,
|
|
185
|
+
writable: true,
|
|
186
|
+
value: void 0
|
|
187
|
+
});
|
|
188
|
+
Object.defineProperty(this, "send", {
|
|
176
189
|
enumerable: true,
|
|
177
190
|
configurable: true,
|
|
178
191
|
writable: true,
|
|
179
|
-
value: addr
|
|
192
|
+
value: async (data, addr) => {
|
|
193
|
+
await this.stream.send(data, addr);
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
Object.defineProperty(this, "close", {
|
|
197
|
+
enumerable: true,
|
|
198
|
+
configurable: true,
|
|
199
|
+
writable: true,
|
|
200
|
+
value: async () => {
|
|
201
|
+
await this.stream.close();
|
|
202
|
+
}
|
|
180
203
|
});
|
|
204
|
+
this.stream = new StreamTransport("tcp", () => (0, node_net_1.connect)({ port: addr[1], host: addr[0] }));
|
|
205
|
+
}
|
|
206
|
+
static async init(addr) {
|
|
207
|
+
const transport = new TcpTransport(addr);
|
|
208
|
+
await transport.init();
|
|
209
|
+
return transport;
|
|
210
|
+
}
|
|
211
|
+
async init() {
|
|
212
|
+
await this.stream.waitForConnect();
|
|
213
|
+
}
|
|
214
|
+
get address() {
|
|
215
|
+
return this.stream.address;
|
|
216
|
+
}
|
|
217
|
+
get closed() {
|
|
218
|
+
return this.stream.closed;
|
|
219
|
+
}
|
|
220
|
+
get onData() {
|
|
221
|
+
return this.stream.onData;
|
|
222
|
+
}
|
|
223
|
+
set onData(handler) {
|
|
224
|
+
this.stream.onData = handler;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
exports.TcpTransport = TcpTransport;
|
|
228
|
+
class TlsTransport {
|
|
229
|
+
constructor(addr, options = {}) {
|
|
181
230
|
Object.defineProperty(this, "type", {
|
|
182
231
|
enumerable: true,
|
|
183
232
|
configurable: true,
|
|
184
233
|
writable: true,
|
|
185
|
-
value: "
|
|
234
|
+
value: "tls"
|
|
235
|
+
});
|
|
236
|
+
Object.defineProperty(this, "stream", {
|
|
237
|
+
enumerable: true,
|
|
238
|
+
configurable: true,
|
|
239
|
+
writable: true,
|
|
240
|
+
value: void 0
|
|
241
|
+
});
|
|
242
|
+
Object.defineProperty(this, "send", {
|
|
243
|
+
enumerable: true,
|
|
244
|
+
configurable: true,
|
|
245
|
+
writable: true,
|
|
246
|
+
value: async (data, addr) => {
|
|
247
|
+
await this.stream.send(data, addr);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
Object.defineProperty(this, "close", {
|
|
251
|
+
enumerable: true,
|
|
252
|
+
configurable: true,
|
|
253
|
+
writable: true,
|
|
254
|
+
value: async () => {
|
|
255
|
+
await this.stream.close();
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
this.stream = new StreamTransport("tls", () => tls.connect({
|
|
259
|
+
...options,
|
|
260
|
+
host: addr[0],
|
|
261
|
+
port: addr[1],
|
|
262
|
+
}));
|
|
263
|
+
}
|
|
264
|
+
static async init(addr, options = {}) {
|
|
265
|
+
const transport = new TlsTransport(addr, options);
|
|
266
|
+
await transport.init();
|
|
267
|
+
return transport;
|
|
268
|
+
}
|
|
269
|
+
async init() {
|
|
270
|
+
await this.stream.waitForConnect();
|
|
271
|
+
}
|
|
272
|
+
get address() {
|
|
273
|
+
return this.stream.address;
|
|
274
|
+
}
|
|
275
|
+
get closed() {
|
|
276
|
+
return this.stream.closed;
|
|
277
|
+
}
|
|
278
|
+
get onData() {
|
|
279
|
+
return this.stream.onData;
|
|
280
|
+
}
|
|
281
|
+
set onData(handler) {
|
|
282
|
+
this.stream.onData = handler;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
exports.TlsTransport = TlsTransport;
|
|
286
|
+
class StreamTransport {
|
|
287
|
+
constructor(type, createClient, connectEvent = type === "tls"
|
|
288
|
+
? "secureConnect"
|
|
289
|
+
: "connect") {
|
|
290
|
+
Object.defineProperty(this, "createClient", {
|
|
291
|
+
enumerable: true,
|
|
292
|
+
configurable: true,
|
|
293
|
+
writable: true,
|
|
294
|
+
value: createClient
|
|
295
|
+
});
|
|
296
|
+
Object.defineProperty(this, "connectEvent", {
|
|
297
|
+
enumerable: true,
|
|
298
|
+
configurable: true,
|
|
299
|
+
writable: true,
|
|
300
|
+
value: connectEvent
|
|
301
|
+
});
|
|
302
|
+
Object.defineProperty(this, "type", {
|
|
303
|
+
enumerable: true,
|
|
304
|
+
configurable: true,
|
|
305
|
+
writable: true,
|
|
306
|
+
value: void 0
|
|
186
307
|
});
|
|
187
308
|
Object.defineProperty(this, "connecting", {
|
|
188
309
|
enumerable: true,
|
|
@@ -213,11 +334,16 @@ class TcpTransport {
|
|
|
213
334
|
configurable: true,
|
|
214
335
|
writable: true,
|
|
215
336
|
value: async (data, addr) => {
|
|
337
|
+
void addr;
|
|
216
338
|
await this.connecting;
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
339
|
+
await new Promise((resolve, reject) => {
|
|
340
|
+
this.client.write(data, (err) => {
|
|
341
|
+
if (err) {
|
|
342
|
+
reject(err);
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
resolve();
|
|
346
|
+
});
|
|
221
347
|
});
|
|
222
348
|
}
|
|
223
349
|
});
|
|
@@ -227,9 +353,10 @@ class TcpTransport {
|
|
|
227
353
|
writable: true,
|
|
228
354
|
value: async () => {
|
|
229
355
|
this.closed = true;
|
|
230
|
-
this.client
|
|
356
|
+
this.client?.destroy();
|
|
231
357
|
}
|
|
232
358
|
});
|
|
359
|
+
this.type = type;
|
|
233
360
|
this.connect();
|
|
234
361
|
}
|
|
235
362
|
connect() {
|
|
@@ -239,39 +366,39 @@ class TcpTransport {
|
|
|
239
366
|
if (this.client) {
|
|
240
367
|
this.client.destroy();
|
|
241
368
|
}
|
|
369
|
+
const client = this.createClient();
|
|
370
|
+
this.client = client;
|
|
242
371
|
this.connecting = new Promise((r, f) => {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
372
|
+
const onConnect = () => {
|
|
373
|
+
client.off("error", onConnectError);
|
|
374
|
+
r();
|
|
375
|
+
};
|
|
376
|
+
const onConnectError = (error) => {
|
|
377
|
+
client.off(this.connectEvent, onConnect);
|
|
247
378
|
f(error);
|
|
248
|
-
}
|
|
379
|
+
};
|
|
380
|
+
client.once(this.connectEvent, onConnect);
|
|
381
|
+
client.once("error", onConnectError);
|
|
249
382
|
});
|
|
250
|
-
|
|
383
|
+
client.on("data", (data) => {
|
|
251
384
|
const addr = [
|
|
252
385
|
this.client.remoteAddress,
|
|
253
386
|
this.client.remotePort,
|
|
254
387
|
];
|
|
255
388
|
this.onData(data, addr);
|
|
256
389
|
});
|
|
257
|
-
|
|
390
|
+
client.on("end", () => {
|
|
258
391
|
this.connect();
|
|
259
392
|
});
|
|
260
|
-
|
|
261
|
-
|
|
393
|
+
client.on("error", (error) => {
|
|
394
|
+
log(`${this.type} transport error`, error);
|
|
262
395
|
});
|
|
263
396
|
}
|
|
264
|
-
async
|
|
397
|
+
async waitForConnect() {
|
|
265
398
|
await this.connecting;
|
|
266
399
|
}
|
|
267
|
-
static async init(addr) {
|
|
268
|
-
const transport = new TcpTransport(addr);
|
|
269
|
-
await transport.init();
|
|
270
|
-
return transport;
|
|
271
|
-
}
|
|
272
400
|
get address() {
|
|
273
401
|
return {};
|
|
274
402
|
}
|
|
275
403
|
}
|
|
276
|
-
exports.TcpTransport = TcpTransport;
|
|
277
404
|
//# sourceMappingURL=transport.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../../common/src/transport.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type RemoteInfo,\n type Socket,\n type SocketType,\n createSocket,\n} from \"dgram\";\n\nimport * as net from \"node:net\";\n\nimport { type AddressInfo, type Socket as TcpSocket, connect } from \"node:net\";\nimport { debug } from \"./log\";\nimport {\n type Address,\n type InterfaceAddresses,\n findPort,\n interfaceAddress,\n normalizeFamilyNodeV18,\n} from \"./network\";\n\nconst log = debug(\"werift-ice:packages/ice/src/transport.ts\");\n\nexport class UdpTransport implements Transport {\n readonly type = \"udp\";\n readonly socket: Socket;\n rinfo?: Partial<Pick<RemoteInfo, \"address\" | \"port\">>;\n onData: (data: Buffer, addr: Address) => void = () => {};\n closed: boolean = false;\n\n private constructor(\n private socketType: SocketType,\n private options: {\n portRange?: [number, number];\n interfaceAddresses?: InterfaceAddresses;\n port?: number;\n } = {},\n ) {\n this.socket = createSocket(socketType);\n this.socket.on(\"message\", (data, info) => {\n if (normalizeFamilyNodeV18(info.family) === 6) {\n [info.address] = info.address.split(\"%\"); // example fe80::1d3a:8751:4ffd:eb80%wlp82s0\n }\n this.rinfo = info;\n try {\n this.onData(data, [info.address, info.port]);\n } catch (error) {\n log(\"onData error\", error);\n }\n });\n }\n\n static async init(\n type: SocketType,\n options: {\n portRange?: [number, number];\n port?: number;\n interfaceAddresses?: InterfaceAddresses;\n } = {},\n ) {\n const transport = new UdpTransport(type, options);\n await transport.init();\n return transport;\n }\n\n private async init() {\n const address = interfaceAddress(\n this.socketType,\n this.options.interfaceAddresses,\n );\n if (this.options.port) {\n this.socket.bind({ port: this.options.port, address });\n } else if (this.options.portRange) {\n const port = await findPort(\n this.options.portRange[0],\n this.options.portRange[1],\n this.socketType,\n this.options.interfaceAddresses,\n );\n this.socket.bind({ port, address });\n } else {\n this.socket.bind({ address });\n }\n await new Promise((r) => this.socket.once(\"listening\", r));\n }\n\n send = async (data: Buffer, addr?: Address) => {\n if (addr && !net.isIP(addr[0])) {\n // if address is not resolved, need to use send callback to handle dns failure.\n return new Promise<void>((r, f) => {\n this.socket.send(data, addr![1], addr![0], (error) => {\n if (error) {\n log(\"send error\", addr, data);\n f(error);\n } else {\n r();\n }\n });\n });\n } else {\n addr = addr ?? [this.rinfo?.address!, this.rinfo?.port!];\n // a preestablished remote address does not need a callback to verify dns.\n // this is faster because event loop is not used per packet.\n this.socket.send(data, addr[1], addr[0]);\n }\n };\n\n get address() {\n return this.socket.address();\n }\n\n get host() {\n return this.socket.address().address;\n }\n\n get port() {\n return this.socket.address().port;\n }\n\n close = () =>\n new Promise<void>((r) => {\n this.closed = true;\n this.socket.once(\"close\", r);\n try {\n this.socket.close();\n } catch (error) {\n r();\n }\n });\n}\n\nexport class TcpTransport implements Transport {\n readonly type = \"tcp\";\n private connecting!: Promise<void>;\n private client!: TcpSocket;\n onData: (data: Buffer, addr: Address) => void = () => {};\n closed = false;\n\n private constructor(private addr: Address) {\n this.connect();\n }\n\n private connect() {\n if (this.closed) {\n return;\n }\n\n if (this.client) {\n this.client.destroy();\n }\n this.connecting = new Promise((r, f) => {\n try {\n this.client = connect({ port: this.addr[1], host: this.addr[0] }, r);\n } catch (error) {\n f(error);\n }\n });\n\n this.client.on(\"data\", (data) => {\n const addr = [\n this.client.remoteAddress!,\n this.client.remotePort!,\n ] as Address;\n this.onData(data, addr);\n });\n this.client.on(\"end\", () => {\n this.connect();\n });\n this.client.on(\"error\", (error) => {\n console.log(\"error\", error);\n });\n }\n\n private async init() {\n await this.connecting;\n }\n\n static async init(addr: Address) {\n const transport = new TcpTransport(addr);\n await transport.init();\n return transport;\n }\n\n get address() {\n return {} as AddressInfo;\n }\n\n send = async (data: Buffer, addr?: Address) => {\n await this.connecting;\n this.client.write(data, (err) => {\n if (err) {\n console.log(\"err\", err);\n }\n });\n };\n\n close = async () => {\n this.closed = true;\n this.client.destroy();\n };\n}\n\nexport interface Transport {\n type: string;\n address: AddressInfo;\n closed: boolean;\n onData: (data: Buffer, addr: Address) => void;\n send: (data: Buffer, addr?: Address) => Promise<void>;\n close: () => Promise<void>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../../common/src/transport.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type RemoteInfo,\n type Socket,\n type SocketType,\n createSocket,\n} from \"dgram\";\n\nimport * as net from \"node:net\";\nimport * as tls from \"node:tls\";\n\nimport { type AddressInfo, type Socket as TcpSocket, connect } from \"node:net\";\nimport { debug } from \"./log\";\nimport {\n type Address,\n type InterfaceAddresses,\n findPort,\n interfaceAddress,\n normalizeFamilyNodeV18,\n} from \"./network\";\n\nconst log = debug(\"werift-ice:packages/ice/src/transport.ts\");\n\ntype StreamTransportType = \"tcp\" | \"tls\";\ntype StreamSocket = TcpSocket | tls.TLSSocket;\ntype StreamConnectEvent = \"connect\" | \"secureConnect\";\n\nexport type TlsConnectionOptions = Omit<\n tls.ConnectionOptions,\n \"host\" | \"port\" | \"socket\"\n>;\n\nexport class UdpTransport implements Transport {\n readonly type = \"udp\";\n readonly socket: Socket;\n rinfo?: Partial<Pick<RemoteInfo, \"address\" | \"port\">>;\n onData: (data: Buffer, addr: Address) => void = () => {};\n closed: boolean = false;\n\n private constructor(\n private socketType: SocketType,\n private options: {\n portRange?: [number, number];\n interfaceAddresses?: InterfaceAddresses;\n port?: number;\n } = {},\n ) {\n this.socket = createSocket(socketType);\n this.socket.on(\"message\", (data, info) => {\n if (normalizeFamilyNodeV18(info.family) === 6) {\n [info.address] = info.address.split(\"%\"); // example fe80::1d3a:8751:4ffd:eb80%wlp82s0\n }\n this.rinfo = info;\n try {\n this.onData(data, [info.address, info.port]);\n } catch (error) {\n log(\"onData error\", error);\n }\n });\n }\n\n static async init(\n type: SocketType,\n options: {\n portRange?: [number, number];\n port?: number;\n interfaceAddresses?: InterfaceAddresses;\n } = {},\n ) {\n const transport = new UdpTransport(type, options);\n await transport.init();\n return transport;\n }\n\n private async init() {\n const address = interfaceAddress(\n this.socketType,\n this.options.interfaceAddresses,\n );\n if (this.options.port) {\n this.socket.bind({ port: this.options.port, address });\n } else if (this.options.portRange) {\n const port = await findPort(\n this.options.portRange[0],\n this.options.portRange[1],\n this.socketType,\n this.options.interfaceAddresses,\n );\n this.socket.bind({ port, address });\n } else {\n this.socket.bind({ address });\n }\n await new Promise((r) => this.socket.once(\"listening\", r));\n }\n\n send = async (data: Buffer, addr?: Address) => {\n if (addr && !net.isIP(addr[0])) {\n // if address is not resolved, need to use send callback to handle dns failure.\n return new Promise<void>((r, f) => {\n this.socket.send(data, addr![1], addr![0], (error) => {\n if (error) {\n log(\"send error\", addr, data);\n f(error);\n } else {\n r();\n }\n });\n });\n } else {\n addr = addr ?? [this.rinfo?.address!, this.rinfo?.port!];\n // a preestablished remote address does not need a callback to verify dns.\n // this is faster because event loop is not used per packet.\n this.socket.send(data, addr[1], addr[0]);\n }\n };\n\n get address() {\n return this.socket.address();\n }\n\n get host() {\n return this.socket.address().address;\n }\n\n get port() {\n return this.socket.address().port;\n }\n\n close = () =>\n new Promise<void>((r) => {\n this.closed = true;\n this.socket.once(\"close\", r);\n try {\n this.socket.close();\n } catch (error) {\n r();\n }\n });\n}\n\nexport class TcpTransport implements Transport {\n readonly type = \"tcp\" as const;\n private readonly stream: StreamTransport;\n\n private constructor(addr: Address) {\n this.stream = new StreamTransport(\"tcp\", () =>\n connect({ port: addr[1], host: addr[0] }),\n );\n }\n\n static async init(addr: Address) {\n const transport = new TcpTransport(addr);\n await transport.init();\n return transport;\n }\n\n private async init() {\n await this.stream.waitForConnect();\n }\n\n get address() {\n return this.stream.address;\n }\n\n get closed() {\n return this.stream.closed;\n }\n\n get onData() {\n return this.stream.onData;\n }\n\n set onData(handler: (data: Buffer, addr: Address) => void) {\n this.stream.onData = handler;\n }\n\n send = async (data: Buffer, addr?: Address) => {\n await this.stream.send(data, addr);\n };\n\n close = async () => {\n await this.stream.close();\n };\n}\n\nexport class TlsTransport implements Transport {\n readonly type = \"tls\" as const;\n private readonly stream: StreamTransport;\n\n private constructor(addr: Address, options: TlsConnectionOptions = {}) {\n this.stream = new StreamTransport(\"tls\", () =>\n tls.connect({\n ...options,\n host: addr[0],\n port: addr[1],\n }),\n );\n }\n\n static async init(addr: Address, options: TlsConnectionOptions = {}) {\n const transport = new TlsTransport(addr, options);\n await transport.init();\n return transport;\n }\n\n private async init() {\n await this.stream.waitForConnect();\n }\n\n get address() {\n return this.stream.address;\n }\n\n get closed() {\n return this.stream.closed;\n }\n\n get onData() {\n return this.stream.onData;\n }\n\n set onData(handler: (data: Buffer, addr: Address) => void) {\n this.stream.onData = handler;\n }\n\n send = async (data: Buffer, addr?: Address) => {\n await this.stream.send(data, addr);\n };\n\n close = async () => {\n await this.stream.close();\n };\n}\n\nclass StreamTransport implements Transport {\n readonly type: StreamTransportType;\n private connecting!: Promise<void>;\n private client!: StreamSocket;\n onData: (data: Buffer, addr: Address) => void = () => {};\n closed = false;\n\n constructor(\n type: StreamTransportType,\n private createClient: () => StreamSocket,\n private connectEvent: StreamConnectEvent = type === \"tls\"\n ? \"secureConnect\"\n : \"connect\",\n ) {\n this.type = type;\n this.connect();\n }\n\n private connect() {\n if (this.closed) {\n return;\n }\n\n if (this.client) {\n this.client.destroy();\n }\n const client = this.createClient();\n this.client = client;\n this.connecting = new Promise((r, f) => {\n const onConnect = () => {\n client.off(\"error\", onConnectError);\n r();\n };\n const onConnectError = (error: Error) => {\n client.off(this.connectEvent, onConnect);\n f(error);\n };\n client.once(this.connectEvent, onConnect);\n client.once(\"error\", onConnectError);\n });\n\n client.on(\"data\", (data) => {\n const addr = [\n this.client.remoteAddress!,\n this.client.remotePort!,\n ] as Address;\n this.onData(data, addr);\n });\n client.on(\"end\", () => {\n this.connect();\n });\n client.on(\"error\", (error) => {\n log(`${this.type} transport error`, error);\n });\n }\n\n async waitForConnect() {\n await this.connecting;\n }\n\n get address() {\n return {} as AddressInfo;\n }\n\n send = async (data: Buffer, addr?: Address) => {\n void addr;\n await this.connecting;\n await new Promise<void>((resolve, reject) => {\n this.client.write(data, (err) => {\n if (err) {\n reject(err);\n return;\n }\n resolve();\n });\n });\n };\n\n close = async () => {\n this.closed = true;\n this.client?.destroy();\n };\n}\n\nexport interface Transport {\n type: string;\n address: AddressInfo;\n closed: boolean;\n onData: (data: Buffer, addr: Address) => void;\n send: (data: Buffer, addr?: Address) => Promise<void>;\n close: () => Promise<void>;\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type TcpCandidateType = "active" | "passive" | "so";
|
|
1
2
|
export declare class Candidate {
|
|
2
3
|
foundation: string;
|
|
3
4
|
component: number;
|
|
@@ -11,10 +12,24 @@ export declare class Candidate {
|
|
|
11
12
|
tcptype?: string | undefined;
|
|
12
13
|
generation?: number | undefined;
|
|
13
14
|
ufrag?: string | undefined;
|
|
15
|
+
id: string;
|
|
14
16
|
constructor(foundation: string, component: number, transport: string, priority: number, host: string, port: number, type: string, relatedAddress?: string | undefined, relatedPort?: number | undefined, tcptype?: string | undefined, generation?: number | undefined, ufrag?: string | undefined);
|
|
17
|
+
refreshId(): void;
|
|
15
18
|
static fromSdp(sdp: string): Candidate;
|
|
16
19
|
canPairWith(other: Candidate): boolean;
|
|
17
20
|
toSdp(): string;
|
|
18
21
|
}
|
|
22
|
+
export declare function candidateLocalPreference({ candidateType, transport, tcptype, otherPreference, }: {
|
|
23
|
+
candidateType: string;
|
|
24
|
+
transport?: string;
|
|
25
|
+
tcptype?: string;
|
|
26
|
+
otherPreference?: number;
|
|
27
|
+
}): number;
|
|
19
28
|
export declare function candidateFoundation(candidateType: string, candidateTransport: string, baseAddress: string): string;
|
|
20
|
-
export declare function candidatePriority(candidateType: string,
|
|
29
|
+
export declare function candidatePriority(candidateType: string, options?: number | {
|
|
30
|
+
transport?: string;
|
|
31
|
+
tcptype?: string;
|
|
32
|
+
localPreference?: number;
|
|
33
|
+
otherPreference?: number;
|
|
34
|
+
}): number;
|
|
35
|
+
export declare function remoteTcpTypeForIncoming(localTcpType?: string): TcpCandidateType;
|
package/lib/ice/src/candidate.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Candidate = void 0;
|
|
4
|
+
exports.candidateLocalPreference = candidateLocalPreference;
|
|
4
5
|
exports.candidateFoundation = candidateFoundation;
|
|
5
6
|
exports.candidatePriority = candidatePriority;
|
|
7
|
+
exports.remoteTcpTypeForIncoming = remoteTcpTypeForIncoming;
|
|
6
8
|
const crypto_1 = require("crypto");
|
|
7
9
|
const net_1 = require("net");
|
|
8
10
|
class Candidate {
|
|
9
|
-
// An ICE candidate.
|
|
10
11
|
constructor(foundation, component, transport, priority, host, port, type, relatedAddress, relatedPort, tcptype, generation, ufrag) {
|
|
11
12
|
Object.defineProperty(this, "foundation", {
|
|
12
13
|
enumerable: true,
|
|
@@ -80,6 +81,16 @@ class Candidate {
|
|
|
80
81
|
writable: true,
|
|
81
82
|
value: ufrag
|
|
82
83
|
});
|
|
84
|
+
// An ICE candidate.
|
|
85
|
+
Object.defineProperty(this, "id", {
|
|
86
|
+
enumerable: true,
|
|
87
|
+
configurable: true,
|
|
88
|
+
writable: true,
|
|
89
|
+
value: (0, crypto_1.randomUUID)().toString()
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
refreshId() {
|
|
93
|
+
this.id = (0, crypto_1.randomUUID)().toString();
|
|
83
94
|
}
|
|
84
95
|
static fromSdp(sdp) {
|
|
85
96
|
// Parse a :class:`Candidate` from SDP.
|
|
@@ -130,6 +141,7 @@ class Candidate {
|
|
|
130
141
|
const b = (0, net_1.isIPv4)(other.host);
|
|
131
142
|
return (this.component === other.component &&
|
|
132
143
|
this.transport.toLowerCase() === other.transport.toLowerCase() &&
|
|
144
|
+
canPairTcpCandidates(this, other) &&
|
|
133
145
|
a === b);
|
|
134
146
|
}
|
|
135
147
|
toSdp() {
|
|
@@ -148,6 +160,70 @@ class Candidate {
|
|
|
148
160
|
}
|
|
149
161
|
}
|
|
150
162
|
exports.Candidate = Candidate;
|
|
163
|
+
const UDP_TYPE_PREFERENCE = {
|
|
164
|
+
host: 126,
|
|
165
|
+
prflx: 110,
|
|
166
|
+
srflx: 100,
|
|
167
|
+
relay: 0,
|
|
168
|
+
};
|
|
169
|
+
const TCP_TYPE_PREFERENCE = {
|
|
170
|
+
host: 105,
|
|
171
|
+
prflx: 90,
|
|
172
|
+
srflx: 80,
|
|
173
|
+
relay: 0,
|
|
174
|
+
};
|
|
175
|
+
const ACTIVE_PASSIVE_DIRECTION_PREFERENCE = {
|
|
176
|
+
active: 6,
|
|
177
|
+
passive: 4,
|
|
178
|
+
so: 2,
|
|
179
|
+
};
|
|
180
|
+
const REFLEXIVE_DIRECTION_PREFERENCE = {
|
|
181
|
+
active: 4,
|
|
182
|
+
passive: 2,
|
|
183
|
+
so: 6,
|
|
184
|
+
};
|
|
185
|
+
function normalizeTransport(transport) {
|
|
186
|
+
return transport?.toLowerCase() ?? "udp";
|
|
187
|
+
}
|
|
188
|
+
function normalizeTcpType(tcptype) {
|
|
189
|
+
switch (tcptype) {
|
|
190
|
+
case "active":
|
|
191
|
+
case "passive":
|
|
192
|
+
case "so":
|
|
193
|
+
return tcptype;
|
|
194
|
+
default:
|
|
195
|
+
return undefined;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function canPairTcpCandidates(local, remote) {
|
|
199
|
+
if (normalizeTransport(local.transport) !== "tcp") {
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
const localType = normalizeTcpType(local.tcptype);
|
|
203
|
+
const remoteType = normalizeTcpType(remote.tcptype);
|
|
204
|
+
if (!localType || !remoteType) {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
return ((localType === "active" && remoteType === "passive") ||
|
|
208
|
+
(localType === "passive" && remoteType === "active") ||
|
|
209
|
+
(localType === "so" && remoteType === "so"));
|
|
210
|
+
}
|
|
211
|
+
function candidateLocalPreference({ candidateType, transport = "udp", tcptype, otherPreference = 8191, }) {
|
|
212
|
+
if (normalizeTransport(transport) !== "tcp") {
|
|
213
|
+
return otherPreference;
|
|
214
|
+
}
|
|
215
|
+
const tcpType = normalizeTcpType(tcptype) ?? "active";
|
|
216
|
+
const directionPreference = candidateType === "srflx" || candidateType === "prflx"
|
|
217
|
+
? REFLEXIVE_DIRECTION_PREFERENCE[tcpType]
|
|
218
|
+
: ACTIVE_PASSIVE_DIRECTION_PREFERENCE[tcpType];
|
|
219
|
+
return (1 << 13) * directionPreference + otherPreference;
|
|
220
|
+
}
|
|
221
|
+
function candidateTypePreference(candidateType, transport = "udp") {
|
|
222
|
+
const table = normalizeTransport(transport) === "tcp"
|
|
223
|
+
? TCP_TYPE_PREFERENCE
|
|
224
|
+
: UDP_TYPE_PREFERENCE;
|
|
225
|
+
return table[candidateType] ?? 0;
|
|
226
|
+
}
|
|
151
227
|
function candidateFoundation(candidateType, candidateTransport, baseAddress) {
|
|
152
228
|
// """
|
|
153
229
|
// See RFC 5245 - 4.1.1.3. Computing Foundations
|
|
@@ -156,22 +232,30 @@ function candidateFoundation(candidateType, candidateTransport, baseAddress) {
|
|
|
156
232
|
return (0, crypto_1.createHash)("md5").update(key, "ascii").digest("hex").slice(7);
|
|
157
233
|
}
|
|
158
234
|
// priorityを決める
|
|
159
|
-
function candidatePriority(candidateType,
|
|
235
|
+
function candidatePriority(candidateType, options = 65535) {
|
|
160
236
|
const candidateComponent = 1;
|
|
161
237
|
// See RFC 5245 - 4.1.2.1. Recommended Formula
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
typePref = 0;
|
|
174
|
-
}
|
|
238
|
+
const transport = typeof options === "number" ? "udp" : normalizeTransport(options.transport);
|
|
239
|
+
const localPref = typeof options === "number"
|
|
240
|
+
? options
|
|
241
|
+
: (options.localPreference ??
|
|
242
|
+
candidateLocalPreference({
|
|
243
|
+
candidateType,
|
|
244
|
+
transport,
|
|
245
|
+
tcptype: options.tcptype,
|
|
246
|
+
otherPreference: options.otherPreference,
|
|
247
|
+
}));
|
|
248
|
+
const typePref = candidateTypePreference(candidateType, transport);
|
|
175
249
|
return ((1 << 24) * typePref + (1 << 8) * localPref + (256 - candidateComponent));
|
|
176
250
|
}
|
|
251
|
+
function remoteTcpTypeForIncoming(localTcpType) {
|
|
252
|
+
switch (localTcpType) {
|
|
253
|
+
case "passive":
|
|
254
|
+
return "active";
|
|
255
|
+
case "active":
|
|
256
|
+
return "passive";
|
|
257
|
+
default:
|
|
258
|
+
return "so";
|
|
259
|
+
}
|
|
260
|
+
}
|
|
177
261
|
//# sourceMappingURL=candidate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"candidate.js","sourceRoot":"","sources":["../../../../ice/src/candidate.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"crypto\";\nimport { isIPv4 } from \"net\";\n\nexport class Candidate {\n // An ICE candidate.\n\n constructor(\n public foundation: string,\n public component: number,\n public transport: string,\n public priority: number,\n public host: string,\n public port: number,\n public type: string,\n public relatedAddress?: string,\n public relatedPort?: number,\n public tcptype?: string,\n public generation?: number,\n public ufrag?: string,\n ) {}\n\n static fromSdp(sdp: string) {\n // Parse a :class:`Candidate` from SDP.\n // .. code-block:: python\n // Candidate.from_sdp(\n // '6815297761 1 udp 659136 1.2.3.4 31102 typ host generation 0 ufrag b7l3')\n\n const bits = sdp.split(\" \");\n if (bits.length < 8) {\n throw new Error(\"SDP does not have enough properties\");\n }\n\n // 固定ワード\n const kwargs = {\n foundation: bits[0],\n component: Number(bits[1]),\n transport: bits[2],\n priority: Number(bits[3]),\n host: bits[4],\n port: Number(bits[5]),\n type: bits[7],\n };\n\n for (let i = 8, il = bits.length - 1; i < il; i += 2) {\n if (bits[i] === \"raddr\") {\n (kwargs as any)[\"related_address\"] = bits[i + 1];\n } else if (bits[i] === \"rport\") {\n (kwargs as any)[\"related_port\"] = Number(bits[i + 1]);\n } else if (bits[i] === \"tcptype\") {\n (kwargs as any)[\"tcptype\"] = bits[i + 1];\n } else if (bits[i] === \"generation\") {\n (kwargs as any)[\"generation\"] = Number(bits[i + 1]);\n } else if (bits[i] === \"ufrag\") {\n (kwargs as any)[\"ufrag\"] = bits[i + 1];\n }\n }\n const { foundation, component, transport, priority, host, port, type } =\n kwargs;\n\n return new Candidate(\n foundation,\n component,\n transport,\n priority,\n host,\n port,\n type,\n (kwargs as any)[\"related_address\"],\n (kwargs as any)[\"related_port\"],\n (kwargs as any)[\"tcptype\"],\n (kwargs as any)[\"generation\"],\n (kwargs as any)[\"ufrag\"],\n );\n }\n\n canPairWith(other: Candidate) {\n // \"\"\"\n // A local candidate is paired with a remote candidate if and only if\n // the two candidates have the same component ID and have the same IP\n // address version.\n // \"\"\"\n const a = isIPv4(this.host);\n const b = isIPv4(other.host);\n return (\n this.component === other.component &&\n this.transport.toLowerCase() === other.transport.toLowerCase() &&\n a === b\n );\n }\n\n toSdp() {\n let sdp = `${this.foundation} ${this.component} ${this.transport} ${this.priority} ${this.host} ${this.port} typ ${this.type}`;\n\n if (this.relatedAddress) sdp += ` raddr ${this.relatedAddress}`;\n if (this.relatedPort != undefined) sdp += ` rport ${this.relatedPort}`;\n if (this.tcptype) sdp += ` tcptype ${this.tcptype}`;\n if (this.generation != undefined) sdp += ` generation ${this.generation}`;\n if (this.ufrag != undefined) sdp += ` ufrag ${this.ufrag}`;\n\n return sdp;\n }\n}\n\nexport function candidateFoundation(\n candidateType: string,\n candidateTransport: string,\n baseAddress: string,\n) {\n // \"\"\"\n // See RFC 5245 - 4.1.1.3. Computing Foundations\n // \"\"\"\n const key = `${candidateType}|${candidateTransport}|${baseAddress}`;\n\n return createHash(\"md5\").update(key, \"ascii\").digest(\"hex\").slice(7);\n}\n\n// priorityを決める\nexport function candidatePriority(candidateType: string, localPref = 65535) {\n const candidateComponent: number = 1;\n // See RFC 5245 - 4.1.2.1. Recommended Formula\n let typePref = 0;\n if (candidateType === \"host\") {\n typePref = 126;\n } else if (candidateType === \"prflx\") {\n typePref = 110;\n } else if (candidateType === \"srflx\") {\n typePref = 100;\n } else {\n typePref = 0;\n }\n return (\n (1 << 24) * typePref + (1 << 8) * localPref + (256 - candidateComponent)\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"candidate.js","sourceRoot":"","sources":["../../../../ice/src/candidate.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomUUID } from \"crypto\";\nimport { isIPv4 } from \"net\";\n\nexport type TcpCandidateType = \"active\" | \"passive\" | \"so\";\n\nexport class Candidate {\n // An ICE candidate.\n id = randomUUID().toString();\n\n constructor(\n public foundation: string,\n public component: number,\n public transport: string,\n public priority: number,\n public host: string,\n public port: number,\n public type: string,\n public relatedAddress?: string,\n public relatedPort?: number,\n public tcptype?: string,\n public generation?: number,\n public ufrag?: string,\n ) {}\n\n refreshId() {\n this.id = randomUUID().toString();\n }\n\n static fromSdp(sdp: string) {\n // Parse a :class:`Candidate` from SDP.\n // .. code-block:: python\n // Candidate.from_sdp(\n // '6815297761 1 udp 659136 1.2.3.4 31102 typ host generation 0 ufrag b7l3')\n\n const bits = sdp.split(\" \");\n if (bits.length < 8) {\n throw new Error(\"SDP does not have enough properties\");\n }\n\n // 固定ワード\n const kwargs = {\n foundation: bits[0],\n component: Number(bits[1]),\n transport: bits[2],\n priority: Number(bits[3]),\n host: bits[4],\n port: Number(bits[5]),\n type: bits[7],\n };\n\n for (let i = 8, il = bits.length - 1; i < il; i += 2) {\n if (bits[i] === \"raddr\") {\n (kwargs as any)[\"related_address\"] = bits[i + 1];\n } else if (bits[i] === \"rport\") {\n (kwargs as any)[\"related_port\"] = Number(bits[i + 1]);\n } else if (bits[i] === \"tcptype\") {\n (kwargs as any)[\"tcptype\"] = bits[i + 1];\n } else if (bits[i] === \"generation\") {\n (kwargs as any)[\"generation\"] = Number(bits[i + 1]);\n } else if (bits[i] === \"ufrag\") {\n (kwargs as any)[\"ufrag\"] = bits[i + 1];\n }\n }\n const { foundation, component, transport, priority, host, port, type } =\n kwargs;\n\n return new Candidate(\n foundation,\n component,\n transport,\n priority,\n host,\n port,\n type,\n (kwargs as any)[\"related_address\"],\n (kwargs as any)[\"related_port\"],\n (kwargs as any)[\"tcptype\"],\n (kwargs as any)[\"generation\"],\n (kwargs as any)[\"ufrag\"],\n );\n }\n\n canPairWith(other: Candidate) {\n // \"\"\"\n // A local candidate is paired with a remote candidate if and only if\n // the two candidates have the same component ID and have the same IP\n // address version.\n // \"\"\"\n const a = isIPv4(this.host);\n const b = isIPv4(other.host);\n return (\n this.component === other.component &&\n this.transport.toLowerCase() === other.transport.toLowerCase() &&\n canPairTcpCandidates(this, other) &&\n a === b\n );\n }\n\n toSdp() {\n let sdp = `${this.foundation} ${this.component} ${this.transport} ${this.priority} ${this.host} ${this.port} typ ${this.type}`;\n\n if (this.relatedAddress) sdp += ` raddr ${this.relatedAddress}`;\n if (this.relatedPort != undefined) sdp += ` rport ${this.relatedPort}`;\n if (this.tcptype) sdp += ` tcptype ${this.tcptype}`;\n if (this.generation != undefined) sdp += ` generation ${this.generation}`;\n if (this.ufrag != undefined) sdp += ` ufrag ${this.ufrag}`;\n\n return sdp;\n }\n}\n\nconst UDP_TYPE_PREFERENCE: Record<string, number> = {\n host: 126,\n prflx: 110,\n srflx: 100,\n relay: 0,\n};\n\nconst TCP_TYPE_PREFERENCE: Record<string, number> = {\n host: 105,\n prflx: 90,\n srflx: 80,\n relay: 0,\n};\n\nconst ACTIVE_PASSIVE_DIRECTION_PREFERENCE: Record<TcpCandidateType, number> = {\n active: 6,\n passive: 4,\n so: 2,\n};\n\nconst REFLEXIVE_DIRECTION_PREFERENCE: Record<TcpCandidateType, number> = {\n active: 4,\n passive: 2,\n so: 6,\n};\n\nfunction normalizeTransport(transport?: string) {\n return transport?.toLowerCase() ?? \"udp\";\n}\n\nfunction normalizeTcpType(tcptype?: string) {\n switch (tcptype) {\n case \"active\":\n case \"passive\":\n case \"so\":\n return tcptype;\n default:\n return undefined;\n }\n}\n\nfunction canPairTcpCandidates(local: Candidate, remote: Candidate) {\n if (normalizeTransport(local.transport) !== \"tcp\") {\n return true;\n }\n\n const localType = normalizeTcpType(local.tcptype);\n const remoteType = normalizeTcpType(remote.tcptype);\n if (!localType || !remoteType) {\n return false;\n }\n\n return (\n (localType === \"active\" && remoteType === \"passive\") ||\n (localType === \"passive\" && remoteType === \"active\") ||\n (localType === \"so\" && remoteType === \"so\")\n );\n}\n\nexport function candidateLocalPreference({\n candidateType,\n transport = \"udp\",\n tcptype,\n otherPreference = 8191,\n}: {\n candidateType: string;\n transport?: string;\n tcptype?: string;\n otherPreference?: number;\n}) {\n if (normalizeTransport(transport) !== \"tcp\") {\n return otherPreference;\n }\n\n const tcpType = normalizeTcpType(tcptype) ?? \"active\";\n const directionPreference =\n candidateType === \"srflx\" || candidateType === \"prflx\"\n ? REFLEXIVE_DIRECTION_PREFERENCE[tcpType]\n : ACTIVE_PASSIVE_DIRECTION_PREFERENCE[tcpType];\n\n return (1 << 13) * directionPreference + otherPreference;\n}\n\nfunction candidateTypePreference(candidateType: string, transport = \"udp\") {\n const table =\n normalizeTransport(transport) === \"tcp\"\n ? TCP_TYPE_PREFERENCE\n : UDP_TYPE_PREFERENCE;\n return table[candidateType] ?? 0;\n}\n\nexport function candidateFoundation(\n candidateType: string,\n candidateTransport: string,\n baseAddress: string,\n) {\n // \"\"\"\n // See RFC 5245 - 4.1.1.3. Computing Foundations\n // \"\"\"\n const key = `${candidateType}|${candidateTransport}|${baseAddress}`;\n\n return createHash(\"md5\").update(key, \"ascii\").digest(\"hex\").slice(7);\n}\n\n// priorityを決める\nexport function candidatePriority(\n candidateType: string,\n options:\n | number\n | {\n transport?: string;\n tcptype?: string;\n localPreference?: number;\n otherPreference?: number;\n } = 65535,\n) {\n const candidateComponent: number = 1;\n // See RFC 5245 - 4.1.2.1. Recommended Formula\n const transport =\n typeof options === \"number\" ? \"udp\" : normalizeTransport(options.transport);\n const localPref =\n typeof options === \"number\"\n ? options\n : (options.localPreference ??\n candidateLocalPreference({\n candidateType,\n transport,\n tcptype: options.tcptype,\n otherPreference: options.otherPreference,\n }));\n const typePref = candidateTypePreference(candidateType, transport);\n return (\n (1 << 24) * typePref + (1 << 8) * localPref + (256 - candidateComponent)\n );\n}\n\nexport function remoteTcpTypeForIncoming(\n localTcpType?: string,\n): TcpCandidateType {\n switch (localTcpType) {\n case \"passive\":\n return \"active\";\n case \"active\":\n return \"passive\";\n default:\n return \"so\";\n }\n}\n"]}
|