Skip to content

Commit ba340dd

Browse files
committed
feat: support setting ICE ufrag and pwd, and missing config values
Updates the implementation to match the latest libdatachannel with features for setting ICE ufrag/pwd and reading the remote cert fingerprint. Also adds pass-through for missing config values.
1 parent a862c23 commit ba340dd

File tree

3 files changed

+97
-3
lines changed

3 files changed

+97
-3
lines changed

lib/index.d.ts

+23-1
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,17 @@ export interface RtcConfig {
5454
enableIceTcp?: boolean;
5555
enableIceUdpMux?: boolean;
5656
disableAutoNegotiation?: boolean;
57+
disableFingerprintVerification?: boolean;
58+
disableAutoGathering?: boolean;
5759
forceMediaTransport?: boolean;
5860
portRangeBegin?: number;
5961
portRangeEnd?: number;
6062
maxMessageSize?: number;
6163
mtu?: number;
6264
iceTransportPolicy?: TransportPolicy;
65+
certificatePemFile?: string;
66+
keyPemFile?: string;
67+
keyPemPass?: string;
6368
}
6469

6570
// Lowercase to match the description type string from libdatachannel
@@ -77,6 +82,11 @@ export const enum ReliabilityType {
7782
Timed = 2,
7883
}
7984

85+
export interface LocalDescriptionInit {
86+
iceUfrag?: string;
87+
icePwd?: string;
88+
}
89+
8090
export interface DataChannelInitConfig {
8191
protocol?: string;
8292
negotiated?: boolean;
@@ -277,13 +287,25 @@ export class WebSocketServer {
277287
onClient(cb: (ws: WebSocket) => void): void;
278288
}
279289

290+
export interface CertificateFingerprint {
291+
/**
292+
* @see https://developer.mozilla.org/en-US/docs/Web/API/RTCCertificate/getFingerprints#value
293+
*/
294+
value: string;
295+
/**
296+
* @see https://developer.mozilla.org/en-US/docs/Web/API/RTCCertificate/getFingerprints#algorithm
297+
*/
298+
algorithm: 'sha-1' | 'sha-224' | 'sha-256' | 'sha-384' | 'sha-512' | 'md5' | 'md2';
299+
}
300+
280301
export class PeerConnection {
281302
constructor(peerName: string, config: RtcConfig);
282303
close(): void;
283-
setLocalDescription(type?: DescriptionType): void;
304+
setLocalDescription(type?: DescriptionType, init?: LocalDescriptionInit): void;
284305
setRemoteDescription(sdp: string, type: DescriptionType): void;
285306
localDescription(): { type: string; sdp: string } | null;
286307
remoteDescription(): { type: string; sdp: string } | null;
308+
remoteFingerprint(): CertificateFingerprint;
287309
addRemoteCandidate(candidate: string, mid: string): void;
288310
createDataChannel(label: string, config?: DataChannelInitConfig): DataChannel;
289311
addTrack(media: Video | Audio): Track;

src/peer-connection-wrapper.cpp

+73-2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ Napi::Object PeerConnectionWrapper::Init(Napi::Env env, Napi::Object exports)
4141
InstanceMethod("setRemoteDescription", &PeerConnectionWrapper::setRemoteDescription),
4242
InstanceMethod("localDescription", &PeerConnectionWrapper::localDescription),
4343
InstanceMethod("remoteDescription", &PeerConnectionWrapper::remoteDescription),
44+
InstanceMethod("remoteFingerprint", &PeerConnectionWrapper::remoteFingerprint),
4445
InstanceMethod("addRemoteCandidate", &PeerConnectionWrapper::addRemoteCandidate),
4546
InstanceMethod("createDataChannel", &PeerConnectionWrapper::createDataChannel),
4647
InstanceMethod("addTrack", &PeerConnectionWrapper::addTrack),
@@ -202,6 +203,10 @@ PeerConnectionWrapper::PeerConnectionWrapper(const Napi::CallbackInfo &info) : N
202203
if (config.Get("disableAutoNegotiation").IsBoolean())
203204
rtcConfig.disableAutoNegotiation = config.Get("disableAutoNegotiation").As<Napi::Boolean>();
204205

206+
// disableAutoGathering option
207+
if (config.Get("disableAutoGathering").IsBoolean())
208+
rtcConfig.disableAutoGathering = config.Get("disableAutoGathering").As<Napi::Boolean>();
209+
205210
// forceMediaTransport option
206211
if (config.Get("forceMediaTransport").IsBoolean())
207212
rtcConfig.forceMediaTransport = config.Get("forceMediaTransport").As<Napi::Boolean>();
@@ -234,6 +239,22 @@ PeerConnectionWrapper::PeerConnectionWrapper(const Napi::CallbackInfo &info) : N
234239
}
235240
}
236241

242+
// Allow skipping fingerprint validation
243+
if (config.Get("disableFingerprintVerification").IsBoolean()) {
244+
rtcConfig.disableFingerprintVerification = config.Get("disableFingerprintVerification").As<Napi::Boolean>();
245+
}
246+
247+
// Specify certificate to use if set
248+
if (config.Get("certificatePemFile").IsString()) {
249+
rtcConfig.certificatePemFile = config.Get("certificatePemFile").As<Napi::String>().ToString();
250+
}
251+
if (config.Get("keyPemFile").IsString()) {
252+
rtcConfig.keyPemFile = config.Get("keyPemFile").As<Napi::String>().ToString();
253+
}
254+
if (config.Get("keyPemPass").IsString()) {
255+
rtcConfig.keyPemPass = config.Get("keyPemPass").As<Napi::String>().ToString();
256+
}
257+
237258
// Create peer-connection
238259
try
239260
{
@@ -314,6 +335,7 @@ void PeerConnectionWrapper::setLocalDescription(const Napi::CallbackInfo &info)
314335
}
315336

316337
rtc::Description::Type type = rtc::Description::Type::Unspec;
338+
rtc::LocalDescriptionInit init;
317339

318340
// optional
319341
if (length > 0)
@@ -339,7 +361,29 @@ void PeerConnectionWrapper::setLocalDescription(const Napi::CallbackInfo &info)
339361
type = rtc::Description::Type::Rollback;
340362
}
341363

342-
mRtcPeerConnPtr->setLocalDescription(type);
364+
// optional
365+
if (length > 1)
366+
{
367+
PLOG_DEBUG << "setLocalDescription() called with LocalDescriptionInit";
368+
369+
if (info[1].IsObject())
370+
{
371+
PLOG_DEBUG << "setLocalDescription() called with LocalDescriptionInit as object";
372+
Napi::Object obj = info[1].As<Napi::Object>();
373+
374+
if (obj.Get("iceUfrag").IsString()) {
375+
PLOG_DEBUG << "setLocalDescription() has ufrag";
376+
init.iceUfrag = obj.Get("iceUfrag").As<Napi::String>();
377+
}
378+
379+
if (obj.Get("icePwd").IsString()) {
380+
PLOG_DEBUG << "setLocalDescription() has password";
381+
init.icePwd = obj.Get("icePwd").As<Napi::String>();
382+
}
383+
}
384+
}
385+
386+
mRtcPeerConnPtr->setLocalDescription(type, init);
343387
}
344388

345389
void PeerConnectionWrapper::setRemoteDescription(const Napi::CallbackInfo &info)
@@ -1049,7 +1093,34 @@ Napi::Value PeerConnectionWrapper::maxMessageSize(const Napi::CallbackInfo &info
10491093

10501094
try
10511095
{
1052-
return Napi::Number::New(env, mRtcPeerConnPtr->remoteMaxMessageSize());
1096+
return Napi::Array::New(env, mRtcPeerConnPtr->remoteMaxMessageSize());
1097+
}
1098+
catch (std::exception &ex)
1099+
{
1100+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
1101+
return Napi::Number::New(info.Env(), 0);
1102+
}
1103+
}
1104+
1105+
Napi::Value PeerConnectionWrapper::remoteFingerprint(const Napi::CallbackInfo &info)
1106+
{
1107+
PLOG_DEBUG << "remoteFingerprints() called";
1108+
Napi::Env env = info.Env();
1109+
1110+
if (!mRtcPeerConnPtr)
1111+
{
1112+
return Napi::Number::New(info.Env(), 0);
1113+
}
1114+
1115+
try
1116+
{
1117+
auto fingerprint = mRtcPeerConnPtr->remoteFingerprint();
1118+
1119+
Napi::Object fingerprintObject = Napi::Object::New(env);
1120+
fingerprintObject.Set("value", fingerprint.value);
1121+
fingerprintObject.Set("algorithm", rtc::CertificateFingerprint::AlgorithmIdentifier(fingerprint.algorithm));
1122+
1123+
return fingerprintObject;
10531124
}
10541125
catch (std::exception &ex)
10551126
{

src/peer-connection-wrapper.h

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class PeerConnectionWrapper : public Napi::ObjectWrap<PeerConnectionWrapper>
3333
Napi::Value iceState(const Napi::CallbackInfo &info);
3434
Napi::Value signalingState(const Napi::CallbackInfo &info);
3535
Napi::Value gatheringState(const Napi::CallbackInfo &info);
36+
Napi::Value remoteFingerprint(const Napi::CallbackInfo &info);
3637

3738
// Callbacks
3839
void onLocalDescription(const Napi::CallbackInfo &info);

0 commit comments

Comments
 (0)