Skip to content

Commit 9b6a996

Browse files
committed
Add UDP NAT hole punching, from zoolyka
1 parent 121388a commit 9b6a996

1 file changed

Lines changed: 16 additions & 4 deletions

File tree

lib/RTSPClient.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,8 @@ export default class RTSPClient extends EventEmitter {
298298
let setupRes;
299299
let rtpChannel;
300300
let rtcpChannel;
301+
let rtpReceiver: dgram.Socket|null = null; // UDP mode init value
302+
let rtcpReceiver: dgram.Socket|null = null; // UDP mode init value
301303

302304
if (connection === "udp") {
303305
// Create a pair of UDP listeners, even numbered port for RTP
@@ -308,15 +310,15 @@ export default class RTSPClient extends EventEmitter {
308310
this._nextFreeUDPPort += 2;
309311

310312
const rtpPort = rtpChannel;
311-
const rtpReceiver = dgram.createSocket("udp4");
313+
rtpReceiver = dgram.createSocket("udp4");
312314

313315
rtpReceiver.on("message", (buf, remote) => {
314316
const packet = parseRTPPacket(buf);
315317
this.emit("data", rtpPort, packet.payload, packet);
316318
});
317319

318320
const rtcpPort = rtcpChannel;
319-
const rtcpReceiver = dgram.createSocket("udp4");
321+
rtcpReceiver = dgram.createSocket("udp4");
320322

321323
rtcpReceiver.on("message", (buf, remote) => {
322324
const packet = parseRTCPPacket(buf);
@@ -329,11 +331,11 @@ export default class RTSPClient extends EventEmitter {
329331
// Block until both UDP sockets are open.
330332

331333
await new Promise((resolve) => {
332-
rtpReceiver.bind(rtpPort, () => resolve({}));
334+
rtpReceiver?.bind(rtpPort, () => resolve({}));
333335
});
334336

335337
await new Promise((resolve) => {
336-
rtcpReceiver.bind(rtcpPort, () => resolve({}));
338+
rtcpReceiver?.bind(rtcpPort, () => resolve({}));
337339
});
338340

339341
const setupHeader = {
@@ -386,6 +388,16 @@ export default class RTSPClient extends EventEmitter {
386388
);
387389
}
388390

391+
// Patch from zoolyka (Zoltan Hajdu).
392+
// Try to open a hole in the NAT router (to allow incoming UDP packets)
393+
// by send a UDP packet for RTP and RTCP to the remote RTSP server.
394+
// Note, Roger did not have a router that needed this so the feature is untested.
395+
// May be better to change the RTCP message to a Receiver Report, leaving the RTP message as zero bytes
396+
if (connection === "udp" && transport && rtpReceiver && rtcpReceiver) {
397+
rtpReceiver.send(Buffer.from(''), Number(transport.parameters["server_port"].split("-")[0]), hostname);
398+
rtcpReceiver.send(Buffer.from(''), Number(transport.parameters["server_port"].split("-")[1]), hostname);
399+
}
400+
389401
if (headers.Unsupported) {
390402
this._unsupportedExtensions = headers.Unsupported.split(",");
391403
}

0 commit comments

Comments
 (0)