@libp2p/webrtc 5.0.26-d8f003e6e → 5.0.27-2e35b6055
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 +16 -21
- package/dist/index.min.js +31 -12
- package/dist/src/constants.d.ts +2 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +2 -0
- package/dist/src/constants.js.map +1 -1
- package/dist/src/index.d.ts +33 -21
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +16 -21
- package/dist/src/index.js.map +1 -1
- package/dist/src/maconn.d.ts +1 -0
- package/dist/src/maconn.d.ts.map +1 -1
- package/dist/src/maconn.js +4 -3
- package/dist/src/maconn.js.map +1 -1
- package/dist/src/muxer.d.ts +1 -0
- package/dist/src/muxer.d.ts.map +1 -1
- package/dist/src/muxer.js +2 -2
- package/dist/src/muxer.js.map +1 -1
- package/dist/src/private-to-private/util.d.ts +1 -0
- package/dist/src/private-to-private/util.d.ts.map +1 -1
- package/dist/src/private-to-private/util.js.map +1 -1
- package/dist/src/private-to-public/listener.browser.d.ts +17 -0
- package/dist/src/private-to-public/listener.browser.d.ts.map +1 -0
- package/dist/src/private-to-public/listener.browser.js +13 -0
- package/dist/src/private-to-public/listener.browser.js.map +1 -0
- package/dist/src/private-to-public/listener.d.ts +37 -0
- package/dist/src/private-to-public/listener.d.ts.map +1 -0
- package/dist/src/private-to-public/listener.js +175 -0
- package/dist/src/private-to-public/listener.js.map +1 -0
- package/dist/src/private-to-public/pb/message.d.ts.map +1 -0
- package/dist/src/private-to-public/pb/message.js.map +1 -0
- package/dist/src/private-to-public/transport.d.ts +10 -11
- package/dist/src/private-to-public/transport.d.ts.map +1 -1
- package/dist/src/private-to-public/transport.js +28 -155
- package/dist/src/private-to-public/transport.js.map +1 -1
- package/dist/src/private-to-public/utils/connect.d.ts +27 -0
- package/dist/src/private-to-public/utils/connect.d.ts.map +1 -0
- package/dist/src/private-to-public/utils/connect.js +142 -0
- package/dist/src/private-to-public/utils/connect.js.map +1 -0
- package/dist/src/private-to-public/utils/generate-certificates.browser.d.ts +2 -0
- package/dist/src/private-to-public/utils/generate-certificates.browser.d.ts.map +1 -0
- package/dist/src/private-to-public/utils/generate-certificates.browser.js +4 -0
- package/dist/src/private-to-public/utils/generate-certificates.browser.js.map +1 -0
- package/dist/src/private-to-public/utils/generate-certificates.d.ts +8 -0
- package/dist/src/private-to-public/utils/generate-certificates.d.ts.map +1 -0
- package/dist/src/private-to-public/utils/generate-certificates.js +39 -0
- package/dist/src/private-to-public/utils/generate-certificates.js.map +1 -0
- package/dist/src/private-to-public/utils/generate-noise-prologue.d.ts +7 -0
- package/dist/src/private-to-public/utils/generate-noise-prologue.d.ts.map +1 -0
- package/dist/src/private-to-public/utils/generate-noise-prologue.js +22 -0
- package/dist/src/private-to-public/utils/generate-noise-prologue.js.map +1 -0
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.browser.d.ts +2 -0
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.browser.d.ts.map +1 -0
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.browser.js +20 -0
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.browser.js.map +1 -0
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.d.ts +19 -0
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.d.ts.map +1 -0
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.js +86 -0
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.js.map +1 -0
- package/dist/src/private-to-public/utils/sdp.d.ts +36 -0
- package/dist/src/private-to-public/utils/sdp.d.ts.map +1 -0
- package/dist/src/private-to-public/{sdp.js → utils/sdp.js} +72 -57
- package/dist/src/private-to-public/utils/sdp.js.map +1 -0
- package/dist/src/private-to-public/utils/stun-listener.d.ts +15 -0
- package/dist/src/private-to-public/utils/stun-listener.d.ts.map +1 -0
- package/dist/src/private-to-public/utils/stun-listener.js +79 -0
- package/dist/src/private-to-public/utils/stun-listener.js.map +1 -0
- package/dist/src/stream.d.ts +2 -0
- package/dist/src/stream.d.ts.map +1 -1
- package/dist/src/stream.js +56 -12
- package/dist/src/stream.js.map +1 -1
- package/dist/src/util.d.ts +4 -0
- package/dist/src/util.d.ts.map +1 -1
- package/dist/src/util.js +7 -1
- package/dist/src/util.js.map +1 -1
- package/dist/src/webrtc/index.d.ts +2 -1
- package/dist/src/webrtc/index.d.ts.map +1 -1
- package/dist/src/webrtc/index.js +1 -1
- package/dist/src/webrtc/index.js.map +1 -1
- package/package.json +22 -11
- package/src/constants.ts +4 -0
- package/src/index.ts +35 -21
- package/src/maconn.ts +5 -3
- package/src/muxer.ts +3 -2
- package/src/private-to-private/util.ts +1 -0
- package/src/private-to-public/listener.browser.ts +28 -0
- package/src/private-to-public/listener.ts +233 -0
- package/src/private-to-public/transport.ts +39 -182
- package/src/private-to-public/utils/connect.ts +192 -0
- package/src/private-to-public/utils/generate-certificates.browser.ts +3 -0
- package/src/private-to-public/utils/generate-certificates.ts +51 -0
- package/src/private-to-public/utils/generate-noise-prologue.ts +26 -0
- package/src/private-to-public/utils/get-rtcpeerconnection.browser.ts +22 -0
- package/src/private-to-public/utils/get-rtcpeerconnection.ts +108 -0
- package/src/private-to-public/utils/sdp.ts +174 -0
- package/src/private-to-public/utils/stun-listener.ts +104 -0
- package/src/stream.ts +68 -15
- package/src/util.ts +11 -1
- package/src/webrtc/index.ts +2 -1
- package/dist/src/pb/message.d.ts.map +0 -1
- package/dist/src/pb/message.js.map +0 -1
- package/dist/src/private-to-public/options.d.ts +0 -6
- package/dist/src/private-to-public/options.d.ts.map +0 -1
- package/dist/src/private-to-public/options.js +0 -2
- package/dist/src/private-to-public/options.js.map +0 -1
- package/dist/src/private-to-public/sdp.d.ts +0 -31
- package/dist/src/private-to-public/sdp.d.ts.map +0 -1
- package/dist/src/private-to-public/sdp.js.map +0 -1
- package/dist/src/private-to-public/util.d.ts +0 -2
- package/dist/src/private-to-public/util.d.ts.map +0 -1
- package/dist/src/private-to-public/util.js +0 -3
- package/dist/src/private-to-public/util.js.map +0 -1
- package/src/private-to-public/options.ts +0 -4
- package/src/private-to-public/sdp.ts +0 -159
- package/src/private-to-public/util.ts +0 -2
- /package/dist/src/{pb → private-to-public/pb}/message.d.ts +0 -0
- /package/dist/src/{pb → private-to-public/pb}/message.js +0 -0
- /package/src/{pb → private-to-public/pb}/message.proto +0 -0
- /package/src/{pb → private-to-public/pb}/message.ts +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"get-rtcpeerconnection.browser.d.ts","sourceRoot":"","sources":["../../../../src/private-to-public/utils/get-rtcpeerconnection.browser.ts"],"names":[],"mappings":"AAAA,wBAAsB,6BAA6B,CAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,EAAE,WAAW,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAqBnP"}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
export async function createDialerRTCPeerConnection(role, ufrag, rtcConfiguration, certificate) {
|
2
|
+
if (certificate == null) {
|
3
|
+
// ECDSA is preferred over RSA here. From our testing we find that P-256 elliptic
|
4
|
+
// curve is supported by Pion, webrtc-rs, as well as Chromium (P-228 and P-384
|
5
|
+
// was not supported in Chromium). We use the same hash function as found in the
|
6
|
+
// multiaddr if it is supported.
|
7
|
+
certificate = await RTCPeerConnection.generateCertificate({
|
8
|
+
name: 'ECDSA',
|
9
|
+
// @ts-expect-error missing from lib.dom.d.ts but required by chrome
|
10
|
+
namedCurve: 'P-256'
|
11
|
+
// hash: sdp.toSupportedHashFunction(hashName)
|
12
|
+
});
|
13
|
+
}
|
14
|
+
const rtcConfig = typeof rtcConfiguration === 'function' ? await rtcConfiguration() : rtcConfiguration;
|
15
|
+
return new RTCPeerConnection({
|
16
|
+
...(rtcConfig ?? {}),
|
17
|
+
certificates: [certificate]
|
18
|
+
});
|
19
|
+
}
|
20
|
+
//# sourceMappingURL=get-rtcpeerconnection.browser.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"get-rtcpeerconnection.browser.js","sourceRoot":"","sources":["../../../../src/private-to-public/utils/get-rtcpeerconnection.browser.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,6BAA6B,CAAE,IAAyB,EAAE,KAAa,EAAE,gBAA0F,EAAE,WAA4B;IACrN,IAAI,WAAW,IAAI,IAAI,EAAE,CAAC;QACxB,iFAAiF;QACjF,8EAA8E;QAC9E,gFAAgF;QAChF,gCAAgC;QAChC,WAAW,GAAG,MAAM,iBAAiB,CAAC,mBAAmB,CAAC;YACxD,IAAI,EAAE,OAAO;YAEb,oEAAoE;YACpE,UAAU,EAAE,OAAO;YACnB,8CAA8C;SAC/C,CAAC,CAAA;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,gBAAgB,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,gBAAgB,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAA;IAEtG,OAAO,IAAI,iBAAiB,CAAC;QAC3B,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC;QACpB,YAAY,EAAE,CAAC,WAAW,CAAC;KAC5B,CAAC,CAAA;AACJ,CAAC"}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import { PeerConnection } from '@ipshipyard/node-datachannel';
|
2
|
+
import { RTCPeerConnection } from '@ipshipyard/node-datachannel/polyfill';
|
3
|
+
import type { TransportCertificate } from '../../index.js';
|
4
|
+
import type { CertificateFingerprint } from '@ipshipyard/node-datachannel';
|
5
|
+
interface DirectRTCPeerConnectionInit extends RTCConfiguration {
|
6
|
+
ufrag: string;
|
7
|
+
peerConnection: PeerConnection;
|
8
|
+
}
|
9
|
+
export declare class DirectRTCPeerConnection extends RTCPeerConnection {
|
10
|
+
private readonly peerConnection;
|
11
|
+
private readonly ufrag;
|
12
|
+
constructor(init: DirectRTCPeerConnectionInit);
|
13
|
+
createOffer(): Promise<globalThis.RTCSessionDescriptionInit | any>;
|
14
|
+
createAnswer(): Promise<globalThis.RTCSessionDescriptionInit | any>;
|
15
|
+
remoteFingerprint(): CertificateFingerprint;
|
16
|
+
}
|
17
|
+
export declare function createDialerRTCPeerConnection(role: 'client' | 'server', ufrag: string, rtcConfiguration?: RTCConfiguration | (() => RTCConfiguration | Promise<RTCConfiguration>), certificate?: TransportCertificate): Promise<DirectRTCPeerConnection>;
|
18
|
+
export {};
|
19
|
+
//# sourceMappingURL=get-rtcpeerconnection.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"get-rtcpeerconnection.d.ts","sourceRoot":"","sources":["../../../../src/private-to-public/utils/get-rtcpeerconnection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAA;AAKzE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAA;AAI1E,UAAU,2BAA4B,SAAQ,gBAAgB;IAC5D,KAAK,EAAE,MAAM,CAAA;IACb,cAAc,EAAE,cAAc,CAAA;CAC/B;AAED,qBAAa,uBAAwB,SAAQ,iBAAiB;IAC5D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAC/C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;gBAEjB,IAAI,EAAE,2BAA2B;IAOxC,WAAW,IAAK,OAAO,CAAC,UAAU,CAAC,yBAAyB,GAAG,GAAG,CAAC;IAYnE,YAAY,IAAK,OAAO,CAAC,UAAU,CAAC,yBAAyB,GAAG,GAAG,CAAC;IAY1E,iBAAiB,IAAK,sBAAsB;CAO7C;AAkBD,wBAAsB,6BAA6B,CAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,EAAE,WAAW,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CA+B/P"}
|
@@ -0,0 +1,86 @@
|
|
1
|
+
import { PeerConnection } from '@ipshipyard/node-datachannel';
|
2
|
+
import { RTCPeerConnection } from '@ipshipyard/node-datachannel/polyfill';
|
3
|
+
import { Crypto } from '@peculiar/webcrypto';
|
4
|
+
import { DEFAULT_ICE_SERVERS } from '../../constants.js';
|
5
|
+
import { MAX_MESSAGE_SIZE } from '../../stream.js';
|
6
|
+
import { generateTransportCertificate } from './generate-certificates.js';
|
7
|
+
const crypto = new Crypto();
|
8
|
+
export class DirectRTCPeerConnection extends RTCPeerConnection {
|
9
|
+
peerConnection;
|
10
|
+
ufrag;
|
11
|
+
constructor(init) {
|
12
|
+
super(init);
|
13
|
+
this.peerConnection = init.peerConnection;
|
14
|
+
this.ufrag = init.ufrag;
|
15
|
+
}
|
16
|
+
async createOffer() {
|
17
|
+
// have to set ufrag before creating offer
|
18
|
+
if (this.connectionState === 'new') {
|
19
|
+
this.peerConnection?.setLocalDescription('offer', {
|
20
|
+
iceUfrag: this.ufrag,
|
21
|
+
icePwd: this.ufrag
|
22
|
+
});
|
23
|
+
}
|
24
|
+
return super.createOffer();
|
25
|
+
}
|
26
|
+
async createAnswer() {
|
27
|
+
// have to set ufrag before creating answer
|
28
|
+
if (this.connectionState === 'new') {
|
29
|
+
this.peerConnection?.setLocalDescription('answer', {
|
30
|
+
iceUfrag: this.ufrag,
|
31
|
+
icePwd: this.ufrag
|
32
|
+
});
|
33
|
+
}
|
34
|
+
return super.createAnswer();
|
35
|
+
}
|
36
|
+
remoteFingerprint() {
|
37
|
+
if (this.peerConnection == null) {
|
38
|
+
throw new Error('Invalid state: peer connection not set');
|
39
|
+
}
|
40
|
+
return this.peerConnection.remoteFingerprint();
|
41
|
+
}
|
42
|
+
}
|
43
|
+
function mapIceServers(iceServers) {
|
44
|
+
return iceServers
|
45
|
+
?.map((server) => {
|
46
|
+
const urls = Array.isArray(server.urls) ? server.urls : [server.urls];
|
47
|
+
return urls.map((url) => {
|
48
|
+
if (server.username != null && server.credential != null) {
|
49
|
+
const [protocol, rest] = url.split(/:(.*)/);
|
50
|
+
return `${protocol}:${server.username}:${server.credential}@${rest}`;
|
51
|
+
}
|
52
|
+
return url;
|
53
|
+
});
|
54
|
+
})
|
55
|
+
.flat() ?? [];
|
56
|
+
}
|
57
|
+
export async function createDialerRTCPeerConnection(role, ufrag, rtcConfiguration, certificate) {
|
58
|
+
if (certificate == null) {
|
59
|
+
// ECDSA is preferred over RSA here. From our testing we find that P-256
|
60
|
+
// elliptic curve is supported by Pion, webrtc-rs, as well as Chromium
|
61
|
+
// (P-228 and P-384 was not supported in Chromium). We use the same hash
|
62
|
+
// function as found in the multiaddr if it is supported.
|
63
|
+
const keyPair = await crypto.subtle.generateKey({
|
64
|
+
name: 'ECDSA',
|
65
|
+
namedCurve: 'P-256'
|
66
|
+
}, true, ['sign', 'verify']);
|
67
|
+
certificate = await generateTransportCertificate(keyPair, {
|
68
|
+
days: 365
|
69
|
+
});
|
70
|
+
}
|
71
|
+
const rtcConfig = typeof rtcConfiguration === 'function' ? await rtcConfiguration() : rtcConfiguration;
|
72
|
+
return new DirectRTCPeerConnection({
|
73
|
+
...rtcConfig,
|
74
|
+
ufrag,
|
75
|
+
peerConnection: new PeerConnection(`${role}-${Date.now()}`, {
|
76
|
+
disableFingerprintVerification: true,
|
77
|
+
disableAutoNegotiation: true,
|
78
|
+
certificatePemFile: certificate.pem,
|
79
|
+
keyPemFile: certificate.privateKey,
|
80
|
+
enableIceUdpMux: role === 'server',
|
81
|
+
maxMessageSize: MAX_MESSAGE_SIZE,
|
82
|
+
iceServers: mapIceServers(rtcConfig?.iceServers ?? DEFAULT_ICE_SERVERS.map(urls => ({ urls })))
|
83
|
+
})
|
84
|
+
});
|
85
|
+
}
|
86
|
+
//# sourceMappingURL=get-rtcpeerconnection.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"get-rtcpeerconnection.js","sourceRoot":"","sources":["../../../../src/private-to-public/utils/get-rtcpeerconnection.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import type { Multiaddr } from '@multiformats/multiaddr';
|
2
|
+
import type { MultihashDigest } from 'multiformats/hashes/interface';
|
3
|
+
/**
|
4
|
+
* Get base2 | identity decoders
|
5
|
+
*/
|
6
|
+
export declare const mbdecoder: any;
|
7
|
+
export declare function getFingerprintFromSdp(sdp: string | undefined): string | undefined;
|
8
|
+
export declare function certhash(ma: Multiaddr): string;
|
9
|
+
/**
|
10
|
+
* Convert a certhash into a multihash
|
11
|
+
*/
|
12
|
+
export declare function decodeCerthash(certhash: string): MultihashDigest;
|
13
|
+
export declare function certhashToFingerprint(certhash: string): string;
|
14
|
+
/**
|
15
|
+
* Extract the fingerprint from a multiaddr
|
16
|
+
*/
|
17
|
+
export declare function ma2Fingerprint(ma: Multiaddr): string;
|
18
|
+
export declare function fingerprint2Ma(fingerprint: string): Multiaddr;
|
19
|
+
/**
|
20
|
+
* Normalize the hash name from a given multihash has name
|
21
|
+
*/
|
22
|
+
export declare function toSupportedHashFunction(code: number): 'sha-1' | 'sha-256' | 'sha-512';
|
23
|
+
/**
|
24
|
+
* Create an answer SDP message from a multiaddr - the server always operates in
|
25
|
+
* ice-lite mode and DTLS active mode.
|
26
|
+
*/
|
27
|
+
export declare function serverAnswerFromMultiaddr(ma: Multiaddr, ufrag: string): RTCSessionDescriptionInit;
|
28
|
+
/**
|
29
|
+
* Create an offer SDP message from a multiaddr
|
30
|
+
*/
|
31
|
+
export declare function clientOfferFromMultiAddr(ma: Multiaddr, ufrag: string): RTCSessionDescriptionInit;
|
32
|
+
/**
|
33
|
+
* Replace (munge) the ufrag and password values in a SDP
|
34
|
+
*/
|
35
|
+
export declare function munge(desc: RTCSessionDescriptionInit, ufrag: string): RTCSessionDescriptionInit;
|
36
|
+
//# sourceMappingURL=sdp.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"sdp.d.ts","sourceRoot":"","sources":["../../../../src/private-to-public/utils/sdp.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAEpE;;GAEG;AAEH,eAAO,MAAM,SAAS,EAAE,GAAwE,CAAA;AAGhG,wBAAgB,qBAAqB,CAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAOlF;AAGD,wBAAgB,QAAQ,CAAE,EAAE,EAAE,SAAS,GAAG,MAAM,CAS/C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAE,QAAQ,EAAE,MAAM,GAAG,eAAe,CAEjE;AAED,wBAAgB,qBAAqB,CAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAS/D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAE,EAAE,EAAE,SAAS,GAAG,MAAM,CAWrD;AAED,wBAAgB,cAAc,CAAE,WAAW,EAAE,MAAM,GAAG,SAAS,CAM9D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAE,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAWtF;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,yBAAyB,CA0BlG;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,yBAAyB,CAwBjG;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAE,IAAI,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,GAAG,yBAAyB,CAWhG"}
|
@@ -1,51 +1,25 @@
|
|
1
1
|
import { InvalidParametersError } from '@libp2p/interface';
|
2
|
-
import {} from '@multiformats/multiaddr';
|
2
|
+
import { multiaddr } from '@multiformats/multiaddr';
|
3
|
+
import { base64url } from 'multiformats/bases/base64';
|
3
4
|
import { bases, digest } from 'multiformats/basics';
|
4
|
-
import
|
5
|
-
import {
|
6
|
-
import {
|
5
|
+
import * as Digest from 'multiformats/hashes/digest';
|
6
|
+
import { sha256 } from 'multiformats/hashes/sha2';
|
7
|
+
import { InvalidFingerprintError, UnsupportedHashAlgorithmError } from '../../error.js';
|
8
|
+
import { MAX_MESSAGE_SIZE } from '../../stream.js';
|
9
|
+
import { CERTHASH_CODE } from '../transport.js';
|
7
10
|
/**
|
8
11
|
* Get base2 | identity decoders
|
9
12
|
*/
|
10
13
|
// @ts-expect-error - Not easy to combine these types.
|
11
14
|
export const mbdecoder = Object.values(bases).map(b => b.decoder).reduce((d, b) => d.or(b));
|
12
|
-
export function getLocalFingerprint(pc, options) {
|
13
|
-
// try to fetch fingerprint from local certificate
|
14
|
-
const localCert = pc.getConfiguration().certificates?.at(0);
|
15
|
-
if (localCert?.getFingerprints == null) {
|
16
|
-
options.log.trace('fetching fingerprint from local SDP');
|
17
|
-
const localDescription = pc.localDescription;
|
18
|
-
if (localDescription == null) {
|
19
|
-
return undefined;
|
20
|
-
}
|
21
|
-
return getFingerprintFromSdp(localDescription.sdp);
|
22
|
-
}
|
23
|
-
options.log.trace('fetching fingerprint from local certificate');
|
24
|
-
if (localCert.getFingerprints().length === 0) {
|
25
|
-
return undefined;
|
26
|
-
}
|
27
|
-
const fingerprint = localCert.getFingerprints()[0].value;
|
28
|
-
if (fingerprint == null) {
|
29
|
-
throw new InvalidFingerprintError('', 'no fingerprint on local certificate');
|
30
|
-
}
|
31
|
-
return fingerprint;
|
32
|
-
}
|
33
15
|
const fingerprintRegex = /^a=fingerprint:(?:\w+-[0-9]+)\s(?<fingerprint>(:?[0-9a-fA-F]{2})+)$/m;
|
34
16
|
export function getFingerprintFromSdp(sdp) {
|
17
|
+
if (sdp == null) {
|
18
|
+
return undefined;
|
19
|
+
}
|
35
20
|
const searchResult = sdp.match(fingerprintRegex);
|
36
21
|
return searchResult?.groups?.fingerprint;
|
37
22
|
}
|
38
|
-
/**
|
39
|
-
* Get base2 | identity decoders
|
40
|
-
*/
|
41
|
-
function ipv(ma) {
|
42
|
-
for (const proto of ma.protoNames()) {
|
43
|
-
if (proto.startsWith('ip')) {
|
44
|
-
return proto.toUpperCase();
|
45
|
-
}
|
46
|
-
}
|
47
|
-
return 'IP6';
|
48
|
-
}
|
49
23
|
// Extract the certhash from a multiaddr
|
50
24
|
export function certhash(ma) {
|
51
25
|
const tups = ma.stringTuples();
|
@@ -61,6 +35,15 @@ export function certhash(ma) {
|
|
61
35
|
export function decodeCerthash(certhash) {
|
62
36
|
return digest.decode(mbdecoder.decode(certhash));
|
63
37
|
}
|
38
|
+
export function certhashToFingerprint(certhash) {
|
39
|
+
const mbdecoded = decodeCerthash(certhash);
|
40
|
+
return new Array(mbdecoded.bytes.length)
|
41
|
+
.fill(0)
|
42
|
+
.map((val, index) => {
|
43
|
+
return mbdecoded.digest[index].toString(16).padStart(2, '0').toUpperCase();
|
44
|
+
})
|
45
|
+
.join(':');
|
46
|
+
}
|
64
47
|
/**
|
65
48
|
* Extract the fingerprint from a multiaddr
|
66
49
|
*/
|
@@ -72,7 +55,13 @@ export function ma2Fingerprint(ma) {
|
|
72
55
|
if (sdp == null) {
|
73
56
|
throw new InvalidFingerprintError(fingerprint, ma.toString());
|
74
57
|
}
|
75
|
-
return
|
58
|
+
return `${prefix} ${sdp.join(':').toUpperCase()}`;
|
59
|
+
}
|
60
|
+
export function fingerprint2Ma(fingerprint) {
|
61
|
+
const output = fingerprint.split(':').map(str => parseInt(str, 16));
|
62
|
+
const encoded = Uint8Array.from(output);
|
63
|
+
const digest = Digest.create(sha256.code, encoded);
|
64
|
+
return multiaddr(`/certhash/${base64url.encode(digest.bytes)}`);
|
76
65
|
}
|
77
66
|
/**
|
78
67
|
* Normalize the hash name from a given multihash has name
|
@@ -80,45 +69,70 @@ export function ma2Fingerprint(ma) {
|
|
80
69
|
export function toSupportedHashFunction(code) {
|
81
70
|
switch (code) {
|
82
71
|
case 0x11:
|
83
|
-
return '
|
72
|
+
return 'sha-1';
|
84
73
|
case 0x12:
|
85
|
-
return '
|
74
|
+
return 'sha-256';
|
86
75
|
case 0x13:
|
87
|
-
return '
|
76
|
+
return 'sha-512';
|
88
77
|
default:
|
89
78
|
throw new UnsupportedHashAlgorithmError(code);
|
90
79
|
}
|
91
80
|
}
|
92
81
|
/**
|
93
|
-
*
|
82
|
+
* Create an answer SDP message from a multiaddr - the server always operates in
|
83
|
+
* ice-lite mode and DTLS active mode.
|
94
84
|
*/
|
95
|
-
function
|
96
|
-
const { host, port } = ma.toOptions();
|
97
|
-
const
|
98
|
-
const
|
99
|
-
|
100
|
-
o=- 0 0 IN ${ipVersion} ${host}
|
85
|
+
export function serverAnswerFromMultiaddr(ma, ufrag) {
|
86
|
+
const { host, port, family } = ma.toOptions();
|
87
|
+
const fingerprint = ma2Fingerprint(ma);
|
88
|
+
const sdp = `v=0
|
89
|
+
o=- 0 0 IN IP${family} ${host}
|
101
90
|
s=-
|
102
|
-
c=IN ${ipVersion} ${host}
|
103
91
|
t=0 0
|
104
92
|
a=ice-lite
|
105
93
|
m=application ${port} UDP/DTLS/SCTP webrtc-datachannel
|
94
|
+
c=IN IP${family} ${host}
|
106
95
|
a=mid:0
|
107
|
-
a=
|
96
|
+
a=ice-options:ice2
|
108
97
|
a=ice-ufrag:${ufrag}
|
109
98
|
a=ice-pwd:${ufrag}
|
110
|
-
a=fingerprint:${
|
99
|
+
a=fingerprint:${fingerprint}
|
100
|
+
a=setup:passive
|
111
101
|
a=sctp-port:5000
|
112
102
|
a=max-message-size:${MAX_MESSAGE_SIZE}
|
113
|
-
a=candidate:1467250027 1 UDP 1467250027 ${host} ${port} typ host
|
103
|
+
a=candidate:1467250027 1 UDP 1467250027 ${host} ${port} typ host
|
104
|
+
a=end-of-candidates
|
105
|
+
`;
|
106
|
+
return {
|
107
|
+
type: 'answer',
|
108
|
+
sdp
|
109
|
+
};
|
114
110
|
}
|
115
111
|
/**
|
116
|
-
* Create an
|
112
|
+
* Create an offer SDP message from a multiaddr
|
117
113
|
*/
|
118
|
-
export function
|
114
|
+
export function clientOfferFromMultiAddr(ma, ufrag) {
|
115
|
+
const { host, port, family } = ma.toOptions();
|
116
|
+
const sdp = `v=0
|
117
|
+
o=- 0 0 IN IP${family} ${host}
|
118
|
+
s=-
|
119
|
+
c=IN IP${family} ${host}
|
120
|
+
t=0 0
|
121
|
+
a=ice-options:ice2,trickle
|
122
|
+
m=application ${port} UDP/DTLS/SCTP webrtc-datachannel
|
123
|
+
a=mid:0
|
124
|
+
a=setup:active
|
125
|
+
a=ice-ufrag:${ufrag}
|
126
|
+
a=ice-pwd:${ufrag}
|
127
|
+
a=fingerprint:sha-256 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
|
128
|
+
a=sctp-port:5000
|
129
|
+
a=max-message-size:${MAX_MESSAGE_SIZE}
|
130
|
+
a=candidate:1467250027 1 UDP 1467250027 ${host} ${port} typ host
|
131
|
+
a=end-of-candidates
|
132
|
+
`;
|
119
133
|
return {
|
120
|
-
type: '
|
121
|
-
sdp
|
134
|
+
type: 'offer',
|
135
|
+
sdp
|
122
136
|
};
|
123
137
|
}
|
124
138
|
/**
|
@@ -128,9 +142,10 @@ export function munge(desc, ufrag) {
|
|
128
142
|
if (desc.sdp === undefined) {
|
129
143
|
throw new InvalidParametersError("Can't munge a missing SDP");
|
130
144
|
}
|
145
|
+
const lineBreak = desc.sdp.includes('\r\n') ? '\r\n' : '\n';
|
131
146
|
desc.sdp = desc.sdp
|
132
|
-
.replace(/\na=ice-ufrag:[^\n]*\n/, '\na=ice-ufrag:' + ufrag +
|
133
|
-
.replace(/\na=ice-pwd:[^\n]*\n/, '\na=ice-pwd:' + ufrag +
|
147
|
+
.replace(/\na=ice-ufrag:[^\n]*\n/, '\na=ice-ufrag:' + ufrag + lineBreak)
|
148
|
+
.replace(/\na=ice-pwd:[^\n]*\n/, '\na=ice-pwd:' + ufrag + lineBreak);
|
134
149
|
return desc;
|
135
150
|
}
|
136
151
|
//# sourceMappingURL=sdp.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"sdp.js","sourceRoot":"","sources":["../../../../src/private-to-public/utils/sdp.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/// <reference types="node" />
|
2
|
+
import type { Logger } from '@libp2p/interface';
|
3
|
+
import type { AddressInfo } from 'node:net';
|
4
|
+
export interface StunServer {
|
5
|
+
close(): Promise<void>;
|
6
|
+
address(): AddressInfo;
|
7
|
+
}
|
8
|
+
export interface Callback {
|
9
|
+
(ufrag: string, remoteHost: string, remotePort: number): void;
|
10
|
+
}
|
11
|
+
export interface STUNListenerOptions {
|
12
|
+
useLibjuice?: boolean;
|
13
|
+
}
|
14
|
+
export declare function stunListener(host: string, port: number, ipVersion: 4 | 6, log: Logger, cb: Callback, opts?: STUNListenerOptions): Promise<StunServer>;
|
15
|
+
//# sourceMappingURL=stun-listener.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"stun-listener.d.ts","sourceRoot":"","sources":["../../../../src/private-to-public/utils/stun-listener.ts"],"names":[],"mappings":";AAOA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAE3C,MAAM,WAAW,UAAU;IACzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,OAAO,IAAI,WAAW,CAAA;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAC9D;AA4ED,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,wBAAsB,YAAY,CAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,UAAU,CAAC,CAMhK"}
|
@@ -0,0 +1,79 @@
|
|
1
|
+
import { createSocket } from 'node:dgram';
|
2
|
+
import { isIPv4 } from '@chainsafe/is-ip';
|
3
|
+
import { IceUdpMuxListener } from '@ipshipyard/node-datachannel';
|
4
|
+
import { pEvent } from 'p-event';
|
5
|
+
// @ts-expect-error no types
|
6
|
+
import stun from 'stun';
|
7
|
+
import { UFRAG_PREFIX } from '../../constants.js';
|
8
|
+
async function dgramListener(host, port, ipVersion, log, cb) {
|
9
|
+
const socket = createSocket({
|
10
|
+
type: `udp${ipVersion}`,
|
11
|
+
reuseAddr: true
|
12
|
+
});
|
13
|
+
try {
|
14
|
+
socket.bind(port, host);
|
15
|
+
await pEvent(socket, 'listening');
|
16
|
+
}
|
17
|
+
catch (err) {
|
18
|
+
socket.close();
|
19
|
+
throw err;
|
20
|
+
}
|
21
|
+
socket.on('message', (msg, rinfo) => {
|
22
|
+
// TODO: this needs to be rate limited keyed by the remote host to
|
23
|
+
// prevent a DOS attack
|
24
|
+
try {
|
25
|
+
log.trace('incoming STUN packet from %o', rinfo);
|
26
|
+
const stunMessage = stun.decode(msg);
|
27
|
+
const usernameAttribute = stunMessage.getAttribute(stun.constants.STUN_ATTR_USERNAME);
|
28
|
+
const username = usernameAttribute?.value?.toString();
|
29
|
+
if (username?.startsWith(UFRAG_PREFIX) !== true) {
|
30
|
+
log.trace('ufrag missing from incoming STUN message from %s:%s', rinfo.address, rinfo.port);
|
31
|
+
return;
|
32
|
+
}
|
33
|
+
const [ufrag] = username.split(':');
|
34
|
+
cb(ufrag, rinfo.address, rinfo.port);
|
35
|
+
}
|
36
|
+
catch (err) {
|
37
|
+
log.error('could not process incoming STUN data from %o', rinfo, err);
|
38
|
+
}
|
39
|
+
});
|
40
|
+
return {
|
41
|
+
close: async () => {
|
42
|
+
const p = pEvent(socket, 'close');
|
43
|
+
socket.close();
|
44
|
+
await p;
|
45
|
+
},
|
46
|
+
address: () => {
|
47
|
+
return socket.address();
|
48
|
+
}
|
49
|
+
};
|
50
|
+
}
|
51
|
+
async function libjuiceListener(host, port, log, cb) {
|
52
|
+
const listener = new IceUdpMuxListener(port, host);
|
53
|
+
listener.onUnhandledStunRequest(request => {
|
54
|
+
if (request.ufrag == null) {
|
55
|
+
return;
|
56
|
+
}
|
57
|
+
log.trace('incoming STUN packet from %s:%d %s', request.host, request.port, request.ufrag);
|
58
|
+
cb(request.ufrag, request.host, request.port);
|
59
|
+
});
|
60
|
+
return {
|
61
|
+
close: async () => {
|
62
|
+
listener.stop();
|
63
|
+
},
|
64
|
+
address: () => {
|
65
|
+
return {
|
66
|
+
address: host,
|
67
|
+
family: isIPv4(host) ? 'IPv4' : 'IPv6',
|
68
|
+
port
|
69
|
+
};
|
70
|
+
}
|
71
|
+
};
|
72
|
+
}
|
73
|
+
export async function stunListener(host, port, ipVersion, log, cb, opts = {}) {
|
74
|
+
if (opts.useLibjuice === false) {
|
75
|
+
return dgramListener(host, port, ipVersion, log, cb);
|
76
|
+
}
|
77
|
+
return libjuiceListener(host, port, log, cb);
|
78
|
+
}
|
79
|
+
//# sourceMappingURL=stun-listener.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"stun-listener.js","sourceRoot":"","sources":["../../../../src/private-to-public/utils/stun-listener.ts"],"names":[],"mappings":"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"}
|
package/dist/src/stream.d.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import { AbstractStream, type AbstractStreamInit } from '@libp2p/utils/abstract-stream';
|
2
2
|
import { Uint8ArrayList } from 'uint8arraylist';
|
3
3
|
import type { DataChannelOptions } from './index.js';
|
4
|
+
import type { RTCDataChannel } from './webrtc/index.js';
|
4
5
|
import type { AbortOptions, ComponentLogger, Direction } from '@libp2p/interface';
|
5
6
|
export interface WebRTCStreamInit extends AbstractStreamInit, DataChannelOptions {
|
6
7
|
/**
|
@@ -67,6 +68,7 @@ export declare class WebRTCStream extends AbstractStream {
|
|
67
68
|
private readonly receiveFinAck;
|
68
69
|
private readonly finAckTimeout;
|
69
70
|
private readonly openTimeout;
|
71
|
+
private readonly closeController;
|
70
72
|
constructor(init: WebRTCStreamInit);
|
71
73
|
sendNewStream(): void;
|
72
74
|
_sendMessage(data: Uint8ArrayList, checkBuffer?: boolean): Promise<void>;
|
package/dist/src/stream.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/stream.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,KAAK,kBAAkB,EAAE,MAAM,+BAA+B,CAAA;
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/stream.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,KAAK,kBAAkB,EAAE,MAAM,+BAA+B,CAAA;AASvF,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAE/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAGjF,MAAM,WAAW,gBAAiB,SAAQ,kBAAkB,EAAE,kBAAkB;IAC9E;;;;;OAKG;IACH,OAAO,EAAE,cAAc,CAAA;IAEvB,MAAM,EAAE,eAAe,CAAA;CACxB;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,QAAkB,CAAA;AAElD;;GAEG;AACH,eAAO,MAAM,2BAA2B,QAAY,CAAA;AAEpD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,QAAY,CAAA;AAsBzC;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAA8B,CAAA;AAE5D;;;;GAIG;AACH,eAAO,MAAM,eAAe,OAAO,CAAA;AAEnC;;;GAGG;AACH,eAAO,MAAM,YAAY,OAAO,CAAA;AAEhC,qBAAa,YAAa,SAAQ,cAAc;IAC9C;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IAExC;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IAEnD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAQ;IAE1C,OAAO,CAAC,QAAQ,CAAC,6BAA6B,CAAQ;IAEtD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;IAEvC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAuB;IACrD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;gBAEpC,IAAI,EAAE,gBAAgB;IA6HnC,aAAa,IAAK,IAAI;IAIhB,YAAY,CAAE,IAAI,EAAE,cAAc,EAAE,WAAW,GAAE,OAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAmD/E,QAAQ,CAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB9C,SAAS,IAAK,OAAO,CAAC,IAAI,CAAC;IAQ3B,cAAc,CAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BrD,aAAa,IAAK,OAAO,CAAC,IAAI,CAAC;IAQrC;;OAEG;IACH,OAAO,CAAC,uBAAuB;YAuCjB,SAAS;CAuBxB;AAED,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB;IAC7D;;;;;OAKG;IACH,OAAO,EAAE,cAAc,CAAA;IAEvB;;OAEG;IACH,SAAS,EAAE,SAAS,CAAA;IAEpB;;OAEG;IACH,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,IAAI,CAAA;IAErC,MAAM,EAAE,eAAe,CAAA;CACxB;AAED,wBAAgB,YAAY,CAAE,OAAO,EAAE,mBAAmB,GAAG,YAAY,CAQxE"}
|