werift 0.24.3 → 0.24.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/common/src/event.js +2 -1
- package/lib/common/src/event.js.map +1 -1
- package/lib/ice/src/turn/protocol.d.ts +39 -7
- package/lib/ice/src/turn/protocol.js +142 -47
- package/lib/ice/src/turn/protocol.js.map +1 -1
- package/lib/index.mjs +145 -52
- package/lib/nonstandard/index.mjs +1 -1
- package/lib/webrtc/src/peerConnection.d.ts +1 -0
- package/lib/webrtc/src/peerConnection.js +20 -7
- package/lib/webrtc/src/peerConnection.js.map +1 -1
- package/package.json +2 -1
package/lib/index.mjs
CHANGED
|
@@ -517,7 +517,7 @@ var Event2 = class {
|
|
|
517
517
|
};
|
|
518
518
|
allUnsubscribe = () => {
|
|
519
519
|
if (this.ended) {
|
|
520
|
-
|
|
520
|
+
return;
|
|
521
521
|
}
|
|
522
522
|
this.event = {
|
|
523
523
|
stack: [],
|
|
@@ -7928,6 +7928,12 @@ var UDP_TRANSPORT = 285212672;
|
|
|
7928
7928
|
function isStreamTransport(transport) {
|
|
7929
7929
|
return transport.type === "tcp" || transport.type === "tls";
|
|
7930
7930
|
}
|
|
7931
|
+
function permissionKey(addr) {
|
|
7932
|
+
return addr[0];
|
|
7933
|
+
}
|
|
7934
|
+
function channelKey(addr) {
|
|
7935
|
+
return JSON.stringify(addr);
|
|
7936
|
+
}
|
|
7931
7937
|
var StunOverTurnProtocol = class _StunOverTurnProtocol {
|
|
7932
7938
|
constructor(turn) {
|
|
7933
7939
|
this.turn = turn;
|
|
@@ -8030,11 +8036,24 @@ var TurnProtocol = class _TurnProtocol {
|
|
|
8030
8036
|
addrByChannel = {};
|
|
8031
8037
|
/**sec */
|
|
8032
8038
|
channelRefreshTime;
|
|
8033
|
-
|
|
8034
|
-
|
|
8039
|
+
/**
|
|
8040
|
+
* Serializes ChannelBind requests so allocation-wide auth state
|
|
8041
|
+
* (nonce/realm/integrityKey) is not updated concurrently. Rejections
|
|
8042
|
+
* must not poison this tail — see channelBindQueue assignment sites.
|
|
8043
|
+
*/
|
|
8044
|
+
channelBindQueue = Promise.resolve();
|
|
8045
|
+
/** In-flight ChannelBind per peer transport address (dedupe concurrent). */
|
|
8046
|
+
channelBindingByAddr = /* @__PURE__ */ new Map();
|
|
8035
8047
|
tcpBuffer = Buffer.alloc(0);
|
|
8048
|
+
/** Permission cache keyed by peer IP only (RFC 8656). */
|
|
8036
8049
|
permissionByAddr = {};
|
|
8037
|
-
|
|
8050
|
+
/**
|
|
8051
|
+
* Serializes CreatePermission requests (auth state race avoidance).
|
|
8052
|
+
* Rejections must not poison this tail.
|
|
8053
|
+
*/
|
|
8054
|
+
permissionQueue = Promise.resolve();
|
|
8055
|
+
/** In-flight CreatePermission per peer IP (dedupe concurrent). */
|
|
8056
|
+
creatingPermissionByAddr = /* @__PURE__ */ new Map();
|
|
8038
8057
|
async connectionMade() {
|
|
8039
8058
|
this.transport.onData = (data, addr) => {
|
|
8040
8059
|
this.dataReceived(data, addr);
|
|
@@ -8119,10 +8138,7 @@ var TurnProtocol = class _TurnProtocol {
|
|
|
8119
8138
|
async createPermission(peerAddress) {
|
|
8120
8139
|
const request = new Message(8 /* CREATE_PERMISSION */, 0 /* REQUEST */);
|
|
8121
8140
|
request.setAttribute("XOR-PEER-ADDRESS", peerAddress).setAttribute("USERNAME", this.username).setAttribute("REALM", this.realm).setAttribute("NONCE", this.nonce);
|
|
8122
|
-
await this.
|
|
8123
|
-
request;
|
|
8124
|
-
throw e;
|
|
8125
|
-
});
|
|
8141
|
+
await this.requestWithRetry(request, this.server);
|
|
8126
8142
|
}
|
|
8127
8143
|
refresh = (exp) => {
|
|
8128
8144
|
this.refreshHandle = cancelable(async (_, __, onCancel) => {
|
|
@@ -8202,10 +8218,13 @@ var TurnProtocol = class _TurnProtocol {
|
|
|
8202
8218
|
return [message, address];
|
|
8203
8219
|
}
|
|
8204
8220
|
async sendData(data, addr) {
|
|
8205
|
-
|
|
8206
|
-
|
|
8207
|
-
|
|
8208
|
-
|
|
8221
|
+
let channel;
|
|
8222
|
+
try {
|
|
8223
|
+
channel = await this.getChannel(addr);
|
|
8224
|
+
} catch (e) {
|
|
8225
|
+
log21("channelBind error; falling back to Send Indication", e);
|
|
8226
|
+
}
|
|
8227
|
+
if (!channel) {
|
|
8209
8228
|
await this.getPermission(addr);
|
|
8210
8229
|
const indicate = new Message(6 /* SEND */, 16 /* INDICATION */).setAttribute("DATA", data).setAttribute("XOR-PEER-ADDRESS", addr);
|
|
8211
8230
|
await this.sendStun(indicate, this.server);
|
|
@@ -8213,49 +8232,111 @@ var TurnProtocol = class _TurnProtocol {
|
|
|
8213
8232
|
}
|
|
8214
8233
|
await this.send(encodeChannelData(channel.number, data), this.server);
|
|
8215
8234
|
}
|
|
8235
|
+
/**
|
|
8236
|
+
* Ensure a CreatePermission exists for the peer IP.
|
|
8237
|
+
* Peer failures are isolated: a rejection for peer A does not poison peer B.
|
|
8238
|
+
*/
|
|
8216
8239
|
async getPermission(addr) {
|
|
8217
|
-
|
|
8218
|
-
|
|
8219
|
-
|
|
8220
|
-
|
|
8221
|
-
|
|
8222
|
-
|
|
8223
|
-
|
|
8224
|
-
|
|
8225
|
-
|
|
8240
|
+
const key = permissionKey(addr);
|
|
8241
|
+
if (this.permissionByAddr[key]) {
|
|
8242
|
+
return;
|
|
8243
|
+
}
|
|
8244
|
+
const existing = this.creatingPermissionByAddr.get(key);
|
|
8245
|
+
if (existing) {
|
|
8246
|
+
return existing;
|
|
8247
|
+
}
|
|
8248
|
+
const operation = this.permissionQueue.then(async () => {
|
|
8249
|
+
if (this.permissionByAddr[key]) {
|
|
8250
|
+
return;
|
|
8251
|
+
}
|
|
8252
|
+
await this.createPermission(addr);
|
|
8253
|
+
this.permissionByAddr[key] = true;
|
|
8254
|
+
});
|
|
8255
|
+
this.permissionQueue = operation.then(
|
|
8256
|
+
() => void 0,
|
|
8257
|
+
() => void 0
|
|
8258
|
+
);
|
|
8259
|
+
this.creatingPermissionByAddr.set(key, operation);
|
|
8260
|
+
try {
|
|
8261
|
+
await operation;
|
|
8262
|
+
} catch (error) {
|
|
8263
|
+
log21("createPermission error", error);
|
|
8264
|
+
throw error;
|
|
8265
|
+
} finally {
|
|
8266
|
+
if (this.creatingPermissionByAddr.get(key) === operation) {
|
|
8267
|
+
this.creatingPermissionByAddr.delete(key);
|
|
8268
|
+
}
|
|
8226
8269
|
}
|
|
8227
8270
|
}
|
|
8271
|
+
/**
|
|
8272
|
+
* Ensure a ChannelBind exists for the peer transport address.
|
|
8273
|
+
* Peer failures are isolated; concurrent same-peer calls share one Promise.
|
|
8274
|
+
*/
|
|
8228
8275
|
async getChannel(addr) {
|
|
8229
|
-
|
|
8230
|
-
|
|
8276
|
+
const key = channelKey(addr);
|
|
8277
|
+
const existing = this.channelBindingByAddr.get(key);
|
|
8278
|
+
if (existing) {
|
|
8279
|
+
return existing;
|
|
8280
|
+
}
|
|
8281
|
+
const cached = this.channelByAddr[key];
|
|
8282
|
+
const now = int(Date.now() / 1e3);
|
|
8283
|
+
if (cached && cached.refreshAt > now) {
|
|
8284
|
+
return cached;
|
|
8231
8285
|
}
|
|
8232
|
-
|
|
8286
|
+
const operation = this.channelBindQueue.then(
|
|
8287
|
+
() => this.ensureChannel(addr)
|
|
8288
|
+
);
|
|
8289
|
+
this.channelBindQueue = operation.then(
|
|
8290
|
+
() => void 0,
|
|
8291
|
+
() => void 0
|
|
8292
|
+
);
|
|
8293
|
+
this.channelBindingByAddr.set(key, operation);
|
|
8294
|
+
try {
|
|
8295
|
+
return await operation;
|
|
8296
|
+
} catch (error) {
|
|
8297
|
+
log21("channelBind error", error);
|
|
8298
|
+
throw error;
|
|
8299
|
+
} finally {
|
|
8300
|
+
if (this.channelBindingByAddr.get(key) === operation) {
|
|
8301
|
+
this.channelBindingByAddr.delete(key);
|
|
8302
|
+
}
|
|
8303
|
+
}
|
|
8304
|
+
}
|
|
8305
|
+
/**
|
|
8306
|
+
* Create or refresh a channel for addr. Provisional mapping is installed
|
|
8307
|
+
* before the request so early ChannelData can be decoded; only a failed
|
|
8308
|
+
* *initial* bind rolls the mapping back. Failed channel numbers are never
|
|
8309
|
+
* reused.
|
|
8310
|
+
*/
|
|
8311
|
+
async ensureChannel(addr) {
|
|
8312
|
+
const key = channelKey(addr);
|
|
8313
|
+
const now = int(Date.now() / 1e3);
|
|
8314
|
+
let channel = this.channelByAddr[key];
|
|
8315
|
+
if (channel && channel.refreshAt > now) {
|
|
8316
|
+
return channel;
|
|
8317
|
+
}
|
|
8318
|
+
const isNew = !channel;
|
|
8233
8319
|
if (!channel) {
|
|
8234
|
-
|
|
8320
|
+
channel = {
|
|
8235
8321
|
number: this.channelNumber++,
|
|
8236
|
-
address: addr
|
|
8322
|
+
address: addr,
|
|
8323
|
+
refreshAt: 0
|
|
8237
8324
|
};
|
|
8238
|
-
|
|
8325
|
+
this.channelByAddr[key] = channel;
|
|
8239
8326
|
this.addrByChannel[channel.number] = addr;
|
|
8240
|
-
this.channelBinding = this.channelBind(channel.number, addr);
|
|
8241
|
-
await this.channelBinding.catch((e) => {
|
|
8242
|
-
log21("channelBind error", e);
|
|
8243
|
-
throw e;
|
|
8244
|
-
});
|
|
8245
|
-
this.channelRefreshAt = int(Date.now() / 1e3) + this.channelRefreshTime;
|
|
8246
|
-
this.channelBinding = void 0;
|
|
8247
|
-
log21("channelBind", channel);
|
|
8248
|
-
} else if (this.channelRefreshAt < int(Date.now() / 1e3)) {
|
|
8249
|
-
this.channelBinding = this.channelBind(channel.number, addr);
|
|
8250
|
-
this.channelRefreshAt = int(Date.now() / 1e3) + this.channelRefreshTime;
|
|
8251
|
-
await this.channelBinding.catch((e) => {
|
|
8252
|
-
log21("channelBind error", e);
|
|
8253
|
-
throw e;
|
|
8254
|
-
});
|
|
8255
|
-
this.channelBinding = void 0;
|
|
8256
|
-
log21("channelBind refresh", channel);
|
|
8257
8327
|
}
|
|
8258
|
-
|
|
8328
|
+
try {
|
|
8329
|
+
await this.channelBind(channel.number, addr);
|
|
8330
|
+
channel.refreshAt = int(Date.now() / 1e3) + this.channelRefreshTime;
|
|
8331
|
+
log21(isNew ? "channelBind" : "channelBind refresh", channel);
|
|
8332
|
+
return channel;
|
|
8333
|
+
} catch (error) {
|
|
8334
|
+
if (isNew) {
|
|
8335
|
+
delete this.channelByAddr[key];
|
|
8336
|
+
delete this.addrByChannel[channel.number];
|
|
8337
|
+
}
|
|
8338
|
+
throw error;
|
|
8339
|
+
}
|
|
8259
8340
|
}
|
|
8260
8341
|
async channelBind(channelNumber, addr) {
|
|
8261
8342
|
const request = new Message(9 /* CHANNEL_BIND */, 0 /* REQUEST */);
|
|
@@ -17883,15 +17964,27 @@ var RTCPeerConnection = class extends EventTarget {
|
|
|
17883
17964
|
this.transceiverManager.close();
|
|
17884
17965
|
await this.secureManager.close();
|
|
17885
17966
|
await this.sctpManager.close();
|
|
17886
|
-
this.
|
|
17887
|
-
this.iceGatheringStateChange.allUnsubscribe();
|
|
17888
|
-
this.iceConnectionStateChange.allUnsubscribe();
|
|
17889
|
-
this.signalingStateChange.allUnsubscribe();
|
|
17890
|
-
this.onTransceiverAdded.allUnsubscribe();
|
|
17891
|
-
this.onRemoteTransceiverAdded.allUnsubscribe();
|
|
17892
|
-
this.onIceCandidate.allUnsubscribe();
|
|
17967
|
+
this.completePeerEvents();
|
|
17893
17968
|
log37("peerConnection closed");
|
|
17894
17969
|
}
|
|
17970
|
+
completePeerEvents() {
|
|
17971
|
+
const events = [
|
|
17972
|
+
this.onDataChannel,
|
|
17973
|
+
this.iceGatheringStateChange,
|
|
17974
|
+
this.iceConnectionStateChange,
|
|
17975
|
+
this.signalingStateChange,
|
|
17976
|
+
this.connectionStateChange,
|
|
17977
|
+
this.onTransceiverAdded,
|
|
17978
|
+
this.onRemoteTransceiverAdded,
|
|
17979
|
+
this.onIceCandidate,
|
|
17980
|
+
this.onNegotiationneeded
|
|
17981
|
+
];
|
|
17982
|
+
for (const event of events) {
|
|
17983
|
+
if (!event.ended) {
|
|
17984
|
+
event.complete();
|
|
17985
|
+
}
|
|
17986
|
+
}
|
|
17987
|
+
}
|
|
17895
17988
|
};
|
|
17896
17989
|
var findCodecByMimeType = (codecs, target) => codecs.find(
|
|
17897
17990
|
(localCodec) => localCodec.mimeType.toLowerCase() === target.mimeType.toLowerCase()
|
|
@@ -198,6 +198,7 @@ export declare class RTCPeerConnection extends EventTarget {
|
|
|
198
198
|
private createPeerConnectionStats;
|
|
199
199
|
getStats(selector?: MediaStreamTrack | null): Promise<RTCStatsReport>;
|
|
200
200
|
close(): Promise<void>;
|
|
201
|
+
private completePeerEvents;
|
|
201
202
|
}
|
|
202
203
|
export type DebugConfig = Partial<{
|
|
203
204
|
/**% */
|
|
@@ -1047,15 +1047,28 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
1047
1047
|
this.transceiverManager.close();
|
|
1048
1048
|
await this.secureManager.close();
|
|
1049
1049
|
await this.sctpManager.close();
|
|
1050
|
-
|
|
1051
|
-
this.
|
|
1052
|
-
this.iceConnectionStateChange.allUnsubscribe();
|
|
1053
|
-
this.signalingStateChange.allUnsubscribe();
|
|
1054
|
-
this.onTransceiverAdded.allUnsubscribe();
|
|
1055
|
-
this.onRemoteTransceiverAdded.allUnsubscribe();
|
|
1056
|
-
this.onIceCandidate.allUnsubscribe();
|
|
1050
|
+
// 公開 Event を完了させ、購読者・クロージャが PeerConnection を保持し続けないようにする
|
|
1051
|
+
this.completePeerEvents();
|
|
1057
1052
|
log("peerConnection closed");
|
|
1058
1053
|
}
|
|
1054
|
+
completePeerEvents() {
|
|
1055
|
+
const events = [
|
|
1056
|
+
this.onDataChannel,
|
|
1057
|
+
this.iceGatheringStateChange,
|
|
1058
|
+
this.iceConnectionStateChange,
|
|
1059
|
+
this.signalingStateChange,
|
|
1060
|
+
this.connectionStateChange,
|
|
1061
|
+
this.onTransceiverAdded,
|
|
1062
|
+
this.onRemoteTransceiverAdded,
|
|
1063
|
+
this.onIceCandidate,
|
|
1064
|
+
this.onNegotiationneeded,
|
|
1065
|
+
];
|
|
1066
|
+
for (const event of events) {
|
|
1067
|
+
if (!event.ended) {
|
|
1068
|
+
event.complete();
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1059
1072
|
}
|
|
1060
1073
|
exports.RTCPeerConnection = RTCPeerConnection;
|
|
1061
1074
|
const findCodecByMimeType = (codecs, target) => codecs.find((localCodec) => localCodec.mimeType.toLowerCase() === target.mimeType.toLowerCase())
|