Skip to content

Commit

Permalink
Merge pull request #396 from koush/race
Browse files Browse the repository at this point in the history
Fix race conditions by switching to node webcrypto
  • Loading branch information
shinyoshiaki authored Aug 7, 2024
2 parents 528966e + a583b70 commit 47b12fa
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 38 deletions.
4 changes: 4 additions & 0 deletions packages/ice/src/dns/lookup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ export class MdnsLookup {
cache = new Map<string, Promise<string>>();
mdnsInstance = mdns();

constructor() {
this.mdnsInstance.setMaxListeners(50);
}

lookup(host: string): Promise<string> {
return new Promise((r, f) => {
const cleanup = () => {
Expand Down
37 changes: 24 additions & 13 deletions packages/ice/src/ice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ export class Connection {
"host",
);

this.pairLocalProtocol(protocol)
candidates.push(protocol.localCandidate);
if (cb) {
cb(protocol.localCandidate);
Expand Down Expand Up @@ -911,22 +912,32 @@ export class Connection {
}
}

private pairRemoteCandidate = (remoteCandidate: Candidate) => {
for (const protocol of this.protocols) {
private tryPair(protocol: Protocol, remoteCandidate: Candidate) {
if (
protocol.localCandidate?.canPairWith(remoteCandidate) &&
!this.findPair(protocol, remoteCandidate)
) {
const pair = new CandidatePair(protocol, remoteCandidate);
if (
protocol.localCandidate?.canPairWith(remoteCandidate) &&
!this.findPair(protocol, remoteCandidate)
this.options.filterCandidatePair &&
!this.options.filterCandidatePair(pair)
) {
const pair = new CandidatePair(protocol, remoteCandidate);
if (
this.options.filterCandidatePair &&
!this.options.filterCandidatePair(pair)
) {
continue;
}
this.checkList.push(pair);
this.setPairState(pair, CandidatePairState.WAITING);
return;
}
this.checkList.push(pair);
this.setPairState(pair, CandidatePairState.WAITING);
}
}

private pairLocalProtocol(protocol: Protocol) {
for (const remoteCandidate of this.remoteCandidates) {
this.tryPair(protocol, remoteCandidate);
}
}

private pairRemoteCandidate = (remoteCandidate: Candidate) => {
for (const protocol of this.protocols) {
this.tryPair(protocol, remoteCandidate);
}
};

Expand Down
34 changes: 12 additions & 22 deletions packages/webrtc/src/peerConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -508,8 +508,10 @@ export class RTCPeerConnection extends EventTarget {
});

iceTransport.iceGather.onIceCandidate = (candidate) => {
if (!this.localDescription) return;

if (!this.localDescription) {
log("localDescription not found when ice candidate was gathered");
return;
}
if (this.config.bundlePolicy === "max-bundle" || this.remoteIsBundled) {
candidate.sdpMLineIndex = 0;
const media = this._localDescription?.media[0];
Expand Down Expand Up @@ -653,14 +655,6 @@ export class RTCPeerConnection extends EventTarget {
// for trickle ice
this.setLocal(description);

// connect transports
if (description.type === "answer") {
this.connect().catch((err) => {
log("connect failed", err);
this.setConnectionState("failed");
});
}

// # gather candidates
const connected = this.iceTransports.find(
(transport) => transport.state === "connected",
Expand All @@ -676,6 +670,14 @@ export class RTCPeerConnection extends EventTarget {
);
}

// connect transports
if (description.type === "answer") {
this.connect().catch((err) => {
log("connect failed", err);
this.setConnectionState("failed");
});
}

description.media
.filter((m) => ["audio", "video"].includes(m.kind))
.forEach((m, i) => {
Expand Down Expand Up @@ -998,18 +1000,6 @@ export class RTCPeerConnection extends EventTarget {
});
}

const connected = this.iceTransports.find(
(transport) => transport.state === "connected",
);
if (this.remoteIsBundled && connected) {
// no need to gather ice candidates on an existing bundled connection
await connected.iceGather.gather();
} else {
await Promise.allSettled(
transports.map((iceTransport) => iceTransport.iceGather.gather()),
);
}

this.negotiationneeded = false;
if (this.shouldNegotiationneeded) {
this.needNegotiation();
Expand Down
17 changes: 14 additions & 3 deletions packages/webrtc/src/transport/dtls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export class RTCDtlsTransport {
readonly onStateChange = new Event<[DtlsState]>();

localCertificate?: RTCCertificate;
localCertificatePromise?: Promise<RTCCertificate>;
private remoteParameters?: RTCDtlsParameters;

constructor(
Expand All @@ -72,7 +73,15 @@ export class RTCDtlsTransport {
}

async setupCertificate() {
if (!this.localCertificate) {
if (this.localCertificate) {
return this.localCertificate;
}

if (this.localCertificatePromise) {
return this.localCertificatePromise;
}

this.localCertificatePromise = (async () => {
const { certPem, keyPem, signatureHash } =
await CipherContext.createSelfSignedCertificateWithKey(
{
Expand All @@ -86,8 +95,10 @@ export class RTCDtlsTransport {
certPem,
signatureHash,
);
}
return this.localCertificate;
return this.localCertificate;
})();

return this.localCertificatePromise;
}

setRemoteParams(remoteParameters: RTCDtlsParameters) {
Expand Down

0 comments on commit 47b12fa

Please sign in to comment.