Files
siprouter/ts/call/rtp-port-pool.ts
Juergen Kunz f3e1c96872 initial commit — SIP B2BUA + WebRTC bridge with Rust codec engine
Full-featured SIP router with multi-provider trunking, browser softphone
via WebRTC, real-time Opus/G.722/PCM transcoding in Rust, RNNoise ML
noise suppression, Kokoro neural TTS announcements, and a Lit-based
web dashboard with live call monitoring and REST API.
2026-04-09 23:03:55 +00:00

72 lines
2.0 KiB
TypeScript

/**
* Unified RTP port pool — replaces the three separate allocators
* in sipproxy.ts, calloriginator.ts, and webrtcbridge.ts.
*
* Allocates even-numbered UDP ports from a configured range.
* Each allocation binds a dgram socket and returns it ready to use.
*/
import dgram from 'node:dgram';
export interface IRtpAllocation {
port: number;
sock: dgram.Socket;
}
export class RtpPortPool {
private min: number;
private max: number;
private allocated = new Map<number, dgram.Socket>();
private log: (msg: string) => void;
constructor(min: number, max: number, log: (msg: string) => void) {
this.min = min % 2 === 0 ? min : min + 1; // ensure even start
this.max = max;
this.log = log;
}
/**
* Allocate an even-numbered port and bind a UDP socket to it.
* Returns null if the pool is exhausted.
*/
allocate(): IRtpAllocation | null {
for (let port = this.min; port < this.max; port += 2) {
if (this.allocated.has(port)) continue;
const sock = dgram.createSocket('udp4');
try {
sock.bind(port, '0.0.0.0');
} catch {
try { sock.close(); } catch { /* ignore */ }
continue;
}
this.allocated.set(port, sock);
this.log(`[rtp-pool] allocated port ${port} (${this.allocated.size} in use)`);
return { port, sock };
}
this.log('[rtp-pool] WARN: port pool exhausted');
return null;
}
/**
* Release a port back to the pool and close its socket.
*/
release(port: number): void {
const sock = this.allocated.get(port);
if (!sock) return;
try { sock.close(); } catch { /* ignore */ }
this.allocated.delete(port);
this.log(`[rtp-pool] released port ${port} (${this.allocated.size} in use)`);
}
/** Number of currently allocated ports. */
get size(): number {
return this.allocated.size;
}
/** Total capacity (number of even ports in range). */
get capacity(): number {
return Math.floor((this.max - this.min) / 2);
}
}