@libp2p/webrtc 3.2.6 → 3.2.7-dfbe0cc0
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/dist/index.min.js +10 -11
- package/dist/src/muxer.d.ts +9 -2
- package/dist/src/muxer.d.ts.map +1 -1
- package/dist/src/muxer.js +29 -20
- package/dist/src/muxer.js.map +1 -1
- package/dist/src/private-to-private/initiate-connection.d.ts +1 -1
- package/dist/src/private-to-private/initiate-connection.d.ts.map +1 -1
- package/dist/src/private-to-private/initiate-connection.js +4 -6
- package/dist/src/private-to-private/initiate-connection.js.map +1 -1
- package/dist/src/private-to-private/signaling-stream-handler.d.ts +2 -1
- package/dist/src/private-to-private/signaling-stream-handler.d.ts.map +1 -1
- package/dist/src/private-to-private/signaling-stream-handler.js +3 -2
- package/dist/src/private-to-private/signaling-stream-handler.js.map +1 -1
- package/dist/src/private-to-private/transport.d.ts.map +1 -1
- package/dist/src/private-to-private/transport.js +6 -8
- package/dist/src/private-to-private/transport.js.map +1 -1
- package/dist/src/private-to-private/util.d.ts +0 -1
- package/dist/src/private-to-private/util.d.ts.map +1 -1
- package/dist/src/private-to-private/util.js +0 -10
- package/dist/src/private-to-private/util.js.map +1 -1
- package/dist/src/stream.d.ts.map +1 -1
- package/dist/src/stream.js +0 -1
- package/dist/src/stream.js.map +1 -1
- package/package.json +9 -9
- package/src/muxer.ts +41 -21
- package/src/private-to-private/initiate-connection.ts +5 -7
- package/src/private-to-private/signaling-stream-handler.ts +4 -3
- package/src/private-to-private/transport.ts +6 -8
- package/src/private-to-private/util.ts +0 -13
- package/src/stream.ts +0 -1
- package/dist/typedoc-urls.json +0 -8
package/src/muxer.ts
CHANGED
|
@@ -32,6 +32,12 @@ export interface DataChannelMuxerFactoryInit {
|
|
|
32
32
|
dataChannelOptions?: DataChannelOptions
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
interface BufferedStream {
|
|
36
|
+
stream: Stream
|
|
37
|
+
channel: RTCDataChannel
|
|
38
|
+
onEnd(err?: Error): void
|
|
39
|
+
}
|
|
40
|
+
|
|
35
41
|
export class DataChannelMuxerFactory implements StreamMuxerFactory {
|
|
36
42
|
public readonly protocol: string
|
|
37
43
|
|
|
@@ -39,7 +45,7 @@ export class DataChannelMuxerFactory implements StreamMuxerFactory {
|
|
|
39
45
|
* WebRTC Peer Connection
|
|
40
46
|
*/
|
|
41
47
|
private readonly peerConnection: RTCPeerConnection
|
|
42
|
-
private
|
|
48
|
+
private bufferedStreams: BufferedStream[] = []
|
|
43
49
|
private readonly metrics?: CounterGroup
|
|
44
50
|
private readonly dataChannelOptions?: DataChannelOptions
|
|
45
51
|
|
|
@@ -51,15 +57,25 @@ export class DataChannelMuxerFactory implements StreamMuxerFactory {
|
|
|
51
57
|
|
|
52
58
|
// store any datachannels opened before upgrade has been completed
|
|
53
59
|
this.peerConnection.ondatachannel = ({ channel }) => {
|
|
60
|
+
// @ts-expect-error fields are set below
|
|
61
|
+
const bufferedStream: BufferedStream = {}
|
|
62
|
+
|
|
54
63
|
const stream = createStream({
|
|
55
64
|
channel,
|
|
56
65
|
direction: 'inbound',
|
|
57
|
-
onEnd: () => {
|
|
58
|
-
|
|
66
|
+
onEnd: (err) => {
|
|
67
|
+
bufferedStream.onEnd(err)
|
|
59
68
|
},
|
|
60
69
|
...this.dataChannelOptions
|
|
61
70
|
})
|
|
62
|
-
|
|
71
|
+
|
|
72
|
+
bufferedStream.stream = stream
|
|
73
|
+
bufferedStream.channel = channel
|
|
74
|
+
bufferedStream.onEnd = () => {
|
|
75
|
+
this.bufferedStreams = this.bufferedStreams.filter(s => s.stream.id !== stream.id)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
this.bufferedStreams.push(bufferedStream)
|
|
63
79
|
}
|
|
64
80
|
}
|
|
65
81
|
|
|
@@ -69,14 +85,14 @@ export class DataChannelMuxerFactory implements StreamMuxerFactory {
|
|
|
69
85
|
peerConnection: this.peerConnection,
|
|
70
86
|
dataChannelOptions: this.dataChannelOptions,
|
|
71
87
|
metrics: this.metrics,
|
|
72
|
-
streams: this.
|
|
88
|
+
streams: this.bufferedStreams,
|
|
73
89
|
protocol: this.protocol
|
|
74
90
|
})
|
|
75
91
|
}
|
|
76
92
|
}
|
|
77
93
|
|
|
78
94
|
export interface DataChannelMuxerInit extends DataChannelMuxerFactoryInit, StreamMuxerInit {
|
|
79
|
-
streams:
|
|
95
|
+
streams: BufferedStream[]
|
|
80
96
|
}
|
|
81
97
|
|
|
82
98
|
/**
|
|
@@ -94,7 +110,7 @@ export class DataChannelMuxer implements StreamMuxer {
|
|
|
94
110
|
private readonly metrics?: CounterGroup
|
|
95
111
|
|
|
96
112
|
constructor (readonly init: DataChannelMuxerInit) {
|
|
97
|
-
this.streams = init.streams
|
|
113
|
+
this.streams = init.streams.map(s => s.stream)
|
|
98
114
|
this.peerConnection = init.peerConnection
|
|
99
115
|
this.protocol = init.protocol ?? PROTOCOL
|
|
100
116
|
this.metrics = init.metrics
|
|
@@ -111,11 +127,7 @@ export class DataChannelMuxer implements StreamMuxer {
|
|
|
111
127
|
channel,
|
|
112
128
|
direction: 'inbound',
|
|
113
129
|
onEnd: () => {
|
|
114
|
-
|
|
115
|
-
drainAndClose(channel, `inbound ${stream.id} ${stream.protocol}`, this.dataChannelOptions.drainTimeout)
|
|
116
|
-
this.streams = this.streams.filter(s => s.id !== stream.id)
|
|
117
|
-
this.metrics?.increment({ stream_end: true })
|
|
118
|
-
init?.onStreamEnd?.(stream)
|
|
130
|
+
this.#onStreamEnd(stream, channel)
|
|
119
131
|
},
|
|
120
132
|
...this.dataChannelOptions
|
|
121
133
|
})
|
|
@@ -125,10 +137,22 @@ export class DataChannelMuxer implements StreamMuxer {
|
|
|
125
137
|
init?.onIncomingStream?.(stream)
|
|
126
138
|
}
|
|
127
139
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
140
|
+
this.init.streams.forEach(bufferedStream => {
|
|
141
|
+
bufferedStream.onEnd = () => {
|
|
142
|
+
this.#onStreamEnd(bufferedStream.stream, bufferedStream.channel)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
this.metrics?.increment({ incoming_stream: true })
|
|
146
|
+
this.init?.onIncomingStream?.(bufferedStream.stream)
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
#onStreamEnd (stream: Stream, channel: RTCDataChannel): void {
|
|
151
|
+
log.trace('stream %s %s %s onEnd', stream.direction, stream.id, stream.protocol)
|
|
152
|
+
drainAndClose(channel, `${stream.direction} ${stream.id} ${stream.protocol}`, this.dataChannelOptions.drainTimeout)
|
|
153
|
+
this.streams = this.streams.filter(s => s.id !== stream.id)
|
|
154
|
+
this.metrics?.increment({ stream_end: true })
|
|
155
|
+
this.init?.onStreamEnd?.(stream)
|
|
132
156
|
}
|
|
133
157
|
|
|
134
158
|
/**
|
|
@@ -170,11 +194,7 @@ export class DataChannelMuxer implements StreamMuxer {
|
|
|
170
194
|
channel,
|
|
171
195
|
direction: 'outbound',
|
|
172
196
|
onEnd: () => {
|
|
173
|
-
|
|
174
|
-
drainAndClose(channel, `outbound ${stream.id} ${stream.protocol}`, this.dataChannelOptions.drainTimeout)
|
|
175
|
-
this.streams = this.streams.filter(s => s.id !== stream.id)
|
|
176
|
-
this.metrics?.increment({ stream_end: true })
|
|
177
|
-
this.init?.onStreamEnd?.(stream)
|
|
197
|
+
this.#onStreamEnd(stream, channel)
|
|
178
198
|
},
|
|
179
199
|
...this.dataChannelOptions
|
|
180
200
|
})
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { CodeError } from '@libp2p/interface/errors'
|
|
2
2
|
import { logger } from '@libp2p/logger'
|
|
3
3
|
import { peerIdFromString } from '@libp2p/peer-id'
|
|
4
|
-
import { multiaddr, type Multiaddr } from '@multiformats/multiaddr'
|
|
5
4
|
import { pbStream } from 'it-protobuf-stream'
|
|
6
5
|
import pDefer, { type DeferredPromise } from 'p-defer'
|
|
7
6
|
import { type RTCPeerConnection, RTCSessionDescription } from '../webrtc/index.js'
|
|
8
7
|
import { Message } from './pb/message.js'
|
|
9
8
|
import { SIGNALING_PROTO_ID, splitAddr, type WebRTCTransportMetrics } from './transport.js'
|
|
10
|
-
import {
|
|
9
|
+
import { readCandidatesUntilConnected, resolveOnConnected } from './util.js'
|
|
11
10
|
import type { DataChannelOptions } from '../index.js'
|
|
12
11
|
import type { Connection } from '@libp2p/interface/connection'
|
|
13
12
|
import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
|
|
14
13
|
import type { IncomingStreamData } from '@libp2p/interface-internal/registrar'
|
|
15
14
|
import type { TransportManager } from '@libp2p/interface-internal/transport-manager'
|
|
15
|
+
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
16
16
|
|
|
17
17
|
const log = logger('libp2p:webrtc:initiate-connection')
|
|
18
18
|
|
|
@@ -33,7 +33,7 @@ export interface ConnectOptions {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export async function initiateConnection ({ peerConnection, signal, metrics, multiaddr: ma, connectionManager, transportManager }: ConnectOptions): Promise<{ remoteAddress: Multiaddr }> {
|
|
36
|
-
const { baseAddr
|
|
36
|
+
const { baseAddr } = splitAddr(ma)
|
|
37
37
|
|
|
38
38
|
metrics?.dialerEvents.increment({ open: true })
|
|
39
39
|
|
|
@@ -158,12 +158,10 @@ export async function initiateConnection ({ peerConnection, signal, metrics, mul
|
|
|
158
158
|
signal
|
|
159
159
|
})
|
|
160
160
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
log.trace('initiator connected to remote address %s', remoteAddress)
|
|
161
|
+
log.trace('initiator connected to remote address %s', ma)
|
|
164
162
|
|
|
165
163
|
return {
|
|
166
|
-
remoteAddress:
|
|
164
|
+
remoteAddress: ma
|
|
167
165
|
}
|
|
168
166
|
} catch (err: any) {
|
|
169
167
|
peerConnection.close()
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { CodeError } from '@libp2p/interface/errors'
|
|
2
2
|
import { logger } from '@libp2p/logger'
|
|
3
|
+
import { multiaddr, type Multiaddr } from '@multiformats/multiaddr'
|
|
3
4
|
import { pbStream } from 'it-protobuf-stream'
|
|
4
5
|
import pDefer, { type DeferredPromise } from 'p-defer'
|
|
5
6
|
import { type RTCPeerConnection, RTCSessionDescription } from '../webrtc/index.js'
|
|
6
7
|
import { Message } from './pb/message.js'
|
|
7
|
-
import {
|
|
8
|
+
import { readCandidatesUntilConnected, resolveOnConnected } from './util.js'
|
|
8
9
|
import type { IncomingStreamData } from '@libp2p/interface-internal/registrar'
|
|
9
10
|
|
|
10
11
|
const log = logger('libp2p:webrtc:signaling-stream-handler')
|
|
@@ -14,7 +15,7 @@ export interface IncomingStreamOpts extends IncomingStreamData {
|
|
|
14
15
|
signal: AbortSignal
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
export async function handleIncomingStream ({ peerConnection, stream, signal, connection }: IncomingStreamOpts): Promise<{ remoteAddress:
|
|
18
|
+
export async function handleIncomingStream ({ peerConnection, stream, signal, connection }: IncomingStreamOpts): Promise<{ remoteAddress: Multiaddr }> {
|
|
18
19
|
log.trace('new inbound signaling stream')
|
|
19
20
|
|
|
20
21
|
const messageStream = pbStream(stream).pb(Message)
|
|
@@ -121,7 +122,7 @@ export async function handleIncomingStream ({ peerConnection, stream, signal, co
|
|
|
121
122
|
}
|
|
122
123
|
}
|
|
123
124
|
|
|
124
|
-
const remoteAddress =
|
|
125
|
+
const remoteAddress = multiaddr(`/webrtc/p2p/${connection.remoteAddr.getPeerId()}`)
|
|
125
126
|
|
|
126
127
|
log.trace('recipient connected to remote address %s', remoteAddress)
|
|
127
128
|
|
|
@@ -121,10 +121,6 @@ export class WebRTCTransport implements Transport, Startable {
|
|
|
121
121
|
log.trace('dialing address: %a', ma)
|
|
122
122
|
|
|
123
123
|
const peerConnection = new RTCPeerConnection(this.init.rtcConfiguration)
|
|
124
|
-
const muxerFactory = new DataChannelMuxerFactory({
|
|
125
|
-
peerConnection,
|
|
126
|
-
dataChannelOptions: this.init.dataChannel
|
|
127
|
-
})
|
|
128
124
|
|
|
129
125
|
const { remoteAddress } = await initiateConnection({
|
|
130
126
|
peerConnection,
|
|
@@ -145,7 +141,10 @@ export class WebRTCTransport implements Transport, Startable {
|
|
|
145
141
|
const connection = await options.upgrader.upgradeOutbound(webRTCConn, {
|
|
146
142
|
skipProtection: true,
|
|
147
143
|
skipEncryption: true,
|
|
148
|
-
muxerFactory
|
|
144
|
+
muxerFactory: new DataChannelMuxerFactory({
|
|
145
|
+
peerConnection,
|
|
146
|
+
dataChannelOptions: this.init.dataChannel
|
|
147
|
+
})
|
|
149
148
|
})
|
|
150
149
|
|
|
151
150
|
// close the connection on shut down
|
|
@@ -157,7 +156,6 @@ export class WebRTCTransport implements Transport, Startable {
|
|
|
157
156
|
async _onProtocol ({ connection, stream }: IncomingStreamData): Promise<void> {
|
|
158
157
|
const signal = AbortSignal.timeout(this.init.inboundConnectionTimeout ?? INBOUND_CONNECTION_TIMEOUT)
|
|
159
158
|
const peerConnection = new RTCPeerConnection(this.init.rtcConfiguration)
|
|
160
|
-
const muxerFactory = new DataChannelMuxerFactory({ peerConnection, dataChannelOptions: this.init.dataChannel })
|
|
161
159
|
|
|
162
160
|
try {
|
|
163
161
|
const { remoteAddress } = await handleIncomingStream({
|
|
@@ -170,7 +168,7 @@ export class WebRTCTransport implements Transport, Startable {
|
|
|
170
168
|
const webRTCConn = new WebRTCMultiaddrConnection({
|
|
171
169
|
peerConnection,
|
|
172
170
|
timeline: { open: (new Date()).getTime() },
|
|
173
|
-
remoteAddr:
|
|
171
|
+
remoteAddr: remoteAddress,
|
|
174
172
|
metrics: this.metrics?.listenerEvents
|
|
175
173
|
})
|
|
176
174
|
|
|
@@ -180,7 +178,7 @@ export class WebRTCTransport implements Transport, Startable {
|
|
|
180
178
|
await this.components.upgrader.upgradeInbound(webRTCConn, {
|
|
181
179
|
skipEncryption: true,
|
|
182
180
|
skipProtection: true,
|
|
183
|
-
muxerFactory
|
|
181
|
+
muxerFactory: new DataChannelMuxerFactory({ peerConnection, dataChannelOptions: this.init.dataChannel })
|
|
184
182
|
})
|
|
185
183
|
|
|
186
184
|
// close the stream if SDP messages have been exchanged successfully
|
|
@@ -110,16 +110,3 @@ export function resolveOnConnected (pc: RTCPeerConnection, promise: DeferredProm
|
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
|
-
|
|
114
|
-
export function parseRemoteAddress (sdp: string): string {
|
|
115
|
-
// 'a=candidate:1746876089 1 udp 2113937151 0614fbad-b...ocal 54882 typ host generation 0 network-cost 999'
|
|
116
|
-
const candidateLine = sdp.split('\r\n').filter(line => line.startsWith('a=candidate')).pop()
|
|
117
|
-
const candidateParts = candidateLine?.split(' ')
|
|
118
|
-
|
|
119
|
-
if (candidateLine == null || candidateParts == null || candidateParts.length < 5) {
|
|
120
|
-
log('could not parse remote address from', candidateLine)
|
|
121
|
-
return '/webrtc'
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return `/dnsaddr/${candidateParts[4]}/${candidateParts[2].toLowerCase()}/${candidateParts[5]}/webrtc`
|
|
125
|
-
}
|
package/src/stream.ts
CHANGED
|
@@ -84,7 +84,6 @@ export class WebRTCStream extends AbstractStream {
|
|
|
84
84
|
*/
|
|
85
85
|
private readonly receiveFinAck: DeferredPromise<void>
|
|
86
86
|
private readonly finAckTimeout: number
|
|
87
|
-
// private sentFinAck: boolean
|
|
88
87
|
|
|
89
88
|
constructor (init: WebRTCStreamInit) {
|
|
90
89
|
// override onEnd to send/receive FIN_ACK before closing the stream
|
package/dist/typedoc-urls.json
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"DataChannelOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.DataChannelOptions.html",
|
|
3
|
-
".:DataChannelOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.DataChannelOptions.html",
|
|
4
|
-
"webRTC": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTC.html",
|
|
5
|
-
".:webRTC": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTC.html",
|
|
6
|
-
"webRTCDirect": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTCDirect.html",
|
|
7
|
-
".:webRTCDirect": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTCDirect.html"
|
|
8
|
-
}
|