Skip to content

Instantly share code, notes, and snippets.

@ibc
Created June 9, 2020 10:12

Revisions

  1. ibc created this gist Jun 9, 2020.
    64 changes: 64 additions & 0 deletions mediasoup-get-bindable-ip.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,64 @@
    import * as os from 'os';
    import * as dgram from 'dgram';

    async function detectBindableIp(family: 'IPv4' | 'IPv6'): Promise<string> {
    const ifaces = os.networkInterfaces();

    // Iterate all network interfaces.
    for (const iface of Object.keys(ifaces)) {
    // Iterate all network addresses in each network interface.
    for (const address of ifaces[iface]) {
    // Ignore if family doesn't match.
    if (address.family !== family) {
    continue;
    }

    // Ignore if internal.
    if (address.internal) {
    continue;
    }

    const ip = address.address;

    console.log(`detectBindableIp() | testing iface:${iface}, ip:${ip}`);

    try {
    await new Promise((resolve, reject) => {
    // Verify we can bind into it.
    const socketType = family === 'IPv4' ? 'udp4' : 'udp6';
    const socket = dgram.createSocket({ type: socketType });

    socket.on('error', error => {
    socket.close();
    reject(error);
    });

    try {
    socket.bind({ port: 0, address: ip }, () => {
    socket.close();
    resolve();
    });
    } catch (error) {
    socket.close();
    reject(error);
    }
    });

    // Resolve with this IP.
    console.log(`detectBindableIp() | got bindable ${family}: ${ip}`);

    return ip;
    } catch (error) {
    console.warn(
    `detectBindableIp() | bind test failed for ${ip}: ${error}`,
    );
    }
    }
    }

    // If we are here if means that we got no bindable IP for the requested
    // family, so throw.
    console.error(`detectBindableIp() | no bindable ${family} found`);

    throw new Error(`no bindable ${family} found`);
    }