From ee395a5a1947bb33b82ac17f3fa7e3d4d4e5d4b0 Mon Sep 17 00:00:00 2001 From: achingbrain Date: Mon, 17 Jun 2024 10:38:21 +0100 Subject: [PATCH] fix: create RTCPeerConnection after dialing remote peer Chrome limits how many RTCPeerConnections a given tab can instantiated during it's lifetime - https://issues.chromium.org/issues/41378764 To delay hitting this limit, only create the dial-end RTCPeerConnection once a relayed connection has successfully been opened to the dial target, this prevents needlessly creating RTCPeerConnections when the dial fails before they are actually used. Fixes #2591 --- .../src/private-to-private/initiate-connection.ts | 10 ++++++---- .../src/private-to-private/transport.ts | 14 ++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/transport-webrtc/src/private-to-private/initiate-connection.ts b/packages/transport-webrtc/src/private-to-private/initiate-connection.ts index 3350f0ac8c..3136558e44 100644 --- a/packages/transport-webrtc/src/private-to-private/initiate-connection.ts +++ b/packages/transport-webrtc/src/private-to-private/initiate-connection.ts @@ -1,7 +1,7 @@ import { CodeError } from '@libp2p/interface' import { peerIdFromString } from '@libp2p/peer-id' import { pbStream } from 'it-protobuf-stream' -import { type RTCPeerConnection, RTCSessionDescription } from '../webrtc/index.js' +import { RTCPeerConnection, RTCSessionDescription } from '../webrtc/index.js' import { Message } from './pb/message.js' import { SIGNALING_PROTO_ID, splitAddr, type WebRTCTransportMetrics } from './transport.js' import { readCandidatesUntilConnected } from './util.js' @@ -17,7 +17,7 @@ export interface IncomingStreamOpts extends IncomingStreamData { } export interface ConnectOptions extends LoggerOptions { - peerConnection: RTCPeerConnection + rtcConfiguration?: RTCConfiguration multiaddr: Multiaddr connectionManager: ConnectionManager transportManager: TransportManager @@ -26,7 +26,7 @@ export interface ConnectOptions extends LoggerOptions { metrics?: WebRTCTransportMetrics } -export async function initiateConnection ({ peerConnection, signal, metrics, multiaddr: ma, connectionManager, transportManager, log }: ConnectOptions): Promise<{ remoteAddress: Multiaddr }> { +export async function initiateConnection ({ rtcConfiguration, signal, metrics, multiaddr: ma, connectionManager, transportManager, log }: ConnectOptions): Promise<{ remoteAddress: Multiaddr, peerConnection: RTCPeerConnection }> { const { baseAddr } = splitAddr(ma) metrics?.dialerEvents.increment({ open: true }) @@ -64,6 +64,7 @@ export async function initiateConnection ({ peerConnection, signal, metrics, mul }) const messageStream = pbStream(stream).pb(Message) + const peerConnection = new RTCPeerConnection(rtcConfiguration) try { // we create the channel so that the RTCPeerConnection has a component for @@ -150,7 +151,8 @@ export async function initiateConnection ({ peerConnection, signal, metrics, mul log.trace('initiator connected to remote address %s', ma) return { - remoteAddress: ma + remoteAddress: ma, + peerConnection } } catch (err: any) { peerConnection.close() diff --git a/packages/transport-webrtc/src/private-to-private/transport.ts b/packages/transport-webrtc/src/private-to-private/transport.ts index 89ad2ee48b..6e283dabb3 100644 --- a/packages/transport-webrtc/src/private-to-private/transport.ts +++ b/packages/transport-webrtc/src/private-to-private/transport.ts @@ -133,14 +133,7 @@ export class WebRTCTransport implements Transport, Startable { async dial (ma: Multiaddr, options: DialOptions): Promise { this.log.trace('dialing address: %a', ma) - const peerConnection = new RTCPeerConnection(this.init.rtcConfiguration) - const muxerFactory = new DataChannelMuxerFactory(this.components, { - peerConnection, - dataChannelOptions: this.init.dataChannel - }) - - const { remoteAddress } = await initiateConnection({ - peerConnection, + const { remoteAddress, peerConnection } = await initiateConnection({ multiaddr: ma, dataChannelOptions: this.init.dataChannel, signal: options.signal, @@ -156,6 +149,11 @@ export class WebRTCTransport implements Transport, Startable { metrics: this.metrics?.dialerEvents }) + const muxerFactory = new DataChannelMuxerFactory(this.components, { + peerConnection, + dataChannelOptions: this.init.dataChannel + }) + const connection = await options.upgrader.upgradeOutbound(webRTCConn, { skipProtection: true, skipEncryption: true,