WebRTC:匹配最近的同行

2024-01-05

给定一个公共 IP 地址(对等点 A)和许多其他公共 IP 地址(IPv4 和 IPv6 地址的混合)列表,将对等点 A 的 IP 地址匹配的最简单方法是什么?n最近的对等点,而无需让对等点手动相互 ping 通以进行延迟基准测试?

我认为使用 BGP 和一堆复杂的查询(可能还涉及 OSPF)是可能的,但我希望可能有一个解决方案或库可以使它像下面的理论功能调用一样简单。

// `peer` is a single IP address. `peer_list` is a list of IP addresses
// get the 5 nearest peers (ordered) to `peer` from `peer_list`
nearest_peers = get_nearest_ips(peer, peer_list, 5);

我应该只使用 MaxMind 的 GeoIP 数据库 + Haversine/Vincenty 的本地实例,还是通过库(在需要时使用适当的缓存)使用 BGP 来实现此目的是否可行?

尽管我无法找到适合此用例的任何内容,但似乎这种代码可能存在于开源任播路由实现中。

该解决方案或建议的库不必在 Node.js 上工作——任何语言都可以。


Install https://github.com/runk/node-maxmind https://github.com/runk/node-maxmind

从以下位置下载“GeoLite2-City.mmdb”:http://dev.maxmind.com/geoip/geoip2/geolite2/ http://dev.maxmind.com/geoip/geoip2/geolite2/

var maxmind = require('maxmind');
var lookup = maxmind.open('./GeoLite2-City.mmdb');

/**/
var peers = [
    '31.193.128.0', // UK
    '23.112.0.0', // USA
    '5.24.0.0', // Turkey
    '196.203.0.0', // Tunisia
    '77.243.64.0' // Malta
];

var peerLocations = {};

peers.forEach(function(peer) {

    var tmp = lookup.get(peer);

    if (!tmp || !tmp.location) {
        throw new Error('Unable to get initial peer location: ' + peer);
    }
    peerLocations[peer] = tmp.location;
});


/**/

var testIp = '84.17.64.0'; // Turkey
// 84.17.64.0   // Turkey
// 37.219.0.0   // Finland
// 5.39.0.0     // France
// 37.75.32.0   // Malta
// 5.2.96.0     // UK
// 15.0.0.0     // USA
// 41.224.0.0   // Tunisia

console.log( findClosestPeer(testIp, 3) );

function findClosestPeer(ip, len) {

    var ipData = lookup.get(ip);
    var distances = [];

    if (ipData && ipData.location) {

        Object.keys(peerLocations).forEach(function(key) {

            var peer = peerLocations[key];
            var distance = getDistanceFromLatLonInKM(ipData.location.latitude, ipData.location.longitude, 
                peer.latitude, peer.longitude);

            distances.push({ip: key, distance: distance});
        });
    }

    // 0 ... 9
    distances.sort(function(a, b) {
        return a.distance - b.distance;
    });

    return len > 1 ? distances.slice(0, len)
        : distances.shift();
}



/* http://stackoverflow.com/a/21279990/605399 */
function getDistanceFromLatLonInKM(lat1, lon1, lat2, lon2) {

    var R = 6371; // Radius of the earth in km

    var dLat = deg2rad(lat2 - lat1);  // deg2rad below
    var dLon = deg2rad(lon2 - lon1); 
    var a = 
        Math.sin(dLat/2) * Math.sin(dLat/2) +
        Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * 
        Math.sin(dLon/2) * Math.sin(dLon/2)
    ;

    var c = 2 * Math.atan2( Math.sqrt(a), Math.sqrt(1 - a) ); 
    var d = R * c; // Distance in km

    return d;
}

function deg2rad(deg) {
    return deg * ( Math.PI / 180 );
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WebRTC:匹配最近的同行 的相关文章