'use strict'; const config = require('../config'); const net = require('net'); /* Run: node bindable.js In networking, "bindable" refers to the ability to assign or allocate a specific IP address and port combination to a network service or application. Binding an IP address and port allows the service or application to listen for incoming network connections on that particular address and port. When we say an IP address and port are "bindable," it means that there are no conflicts or issues preventing the service or application from using that specific combination. In other words, the IP address is available, and the port is not already in use by another process or service on the same machine. If an IP address and port are bindable, it indicates that the network service or application can successfully bind to that combination, allowing it to accept incoming connections and communicate over the network. On the other hand, if the IP address and port are not bindable, it suggests that there may be conflicts or restrictions preventing the service or application from using them, such as another process already listening on the same IP address and port. */ async function main() { // Server listen const serverListenIp = config.server.listen.ip; const serverListenPort = config.server.listen.port; // WebRtcServerActive const webRtcServerActive = config.mediasoup.webRtcServerActive; // WebRtcTransportOptions const webRtcTransportIpInfo = config.mediasoup.webRtcTransport.listenInfos[0]; const webRtcTransportIpAddress = webRtcTransportIpInfo.ip !== '0.0.0.0' ? webRtcTransportIpInfo.ip : webRtcTransportIpInfo.announcedAddress; // WorkersOptions | webRtcTransportOptions const workers = config.mediasoup.numWorkers; const { min, max } = config.mediasoup.webRtcTransport.listenInfos[0].portRange; const rtcMinPort = config.mediasoup.worker.rtcMinPort || min || 40000; const rtcMaxPort = config.mediasoup.worker.rtcMaxPort || max || 40100; console.log('=================================='); console.log('checkServerListenPorts'); console.log('=================================='); await checkServerListenPorts(serverListenIp, serverListenPort); console.log('=================================='); console.log('checkWebRtcTransportPorts'); console.log('=================================='); await checkWebRtcTransportPorts(webRtcTransportIpAddress, rtcMinPort, rtcMaxPort); if (webRtcServerActive) { console.log('=================================='); console.log('checkWebRtcServerPorts'); console.log('=================================='); // WebRtcServerOptions const webRtcServerIpInfo = config.mediasoup.webRtcServerOptions.listenInfos[0]; const webRtcServerIpAddress = webRtcServerIpInfo.ip !== '0.0.0.0' ? webRtcServerIpInfo.ip : webRtcServerIpInfo.announcedAddress; const webRtcServerStartPort = webRtcServerIpInfo.port; await checkWebRtcServerPorts(webRtcServerIpAddress, webRtcServerStartPort, workers); } } /** * Check if Server listen port is bindable * @param {string} ipAddress * @param {integer} port */ async function checkServerListenPorts(ipAddress, port) { const bindable = await isBindable(ipAddress, port); if (bindable) { console.log(`${ipAddress}:${port} is bindable 🟢`); } else { console.log(`${ipAddress}:${port} is not bindable 🔴`); } } /** * Check if WebRtcServer ports are bindable * @param {string} ipAddress * @param {integer} startPort * @param {integer} workers */ async function checkWebRtcServerPorts(ipAddress, startPort, workers) { let port = startPort; for (let i = 0; i < workers; i++) { try { const bindable = await isBindable(ipAddress, port); if (bindable) { console.log(`${ipAddress}:${port} is bindable 🟢`); } else { console.log(`${ipAddress}:${port} is not bindable 🔴`); } port++; } catch (err) { console.error('Error occurred:', err); } } } /** * Check if WebRtcTransport Worker ports are bindable * @param {string} ipAddress * @param {integer} minPort * @param {integer} maxPort */ async function checkWebRtcTransportPorts(ipAddress, minPort, maxPort) { let port = minPort; for (let i = 0; i <= maxPort - minPort; i++) { try { const bindable = await isBindable(ipAddress, port); if (bindable) { console.log(`${ipAddress}:${port} is bindable 🟢`); } else { console.log(`${ipAddress}:${port} is not bindable 🔴`); } port++; } catch (err) { console.error('Error occurred:', err); } } } /** * Check if ipAddress:port are bindable * @param {string} ipAddress * @param {integer} port * @returns {Promise} A promise that resolves to true if the address is bindable, false otherwise. */ async function isBindable(ipAddress, port) { return new Promise((resolve, reject) => { const server = net.createServer(); server.once('error', (err) => { if (err.code === 'EADDRINUSE') { resolve(false); // Address is already in use } else { reject(err); // Other error occurred } }); server.once('listening', () => { server.close(); resolve(true); // Address is bindable }); server.listen(port, ipAddress); }); } main().catch((err) => { console.error('Error occurred in main function:', err.message); });