Given a single public IP address (peer A) and a list of many other public IP addresses (a mix of IPv4 and IPv6 addresses), what is the easiest way to match up peer A the IP addr
The easiest way to find the nearest peers, would be to send each of the peers an echo request and measure the time it takes to get a response, like ping does.
As I read it, your question is way more general than your Javascript / WebRTC use case.
Who about something like: "Given a P2P network, and a central server that knows all connected peers, which is the best metric than can be used to pair them up?".
=> As good metric to pair two arbitrary nodes would be the hop-distance between them. The problem being that this value is not possible to compute (you can only guess which path the ISP routers will chose between the nodes).
How to approximate it then?
1. Use geographical distance as an approximation to hop distance
In that case, you are pretty much done. Use any "ip to latlng" service and you are done.
2. Try to guess the real hop distance by mapping the internet
I found a paper on that subject, that might be useful to you. You might as well dig a bit on their references to retrieve previous papers on the same subject:
Estimating Hop Distance Between Arbitrary Host Pairs http://nowak.ece.wisc.edu/infocom09.pdf
Abstract — Establishing a clear and timely picture of Internet topology is complicated by many factors including the vast size and dynamic nature of the infrastructure. In this paper, we describe a methodology for estimating an important characteristic of Internet topology - the hop distance between arbitrary pairs of end hosts. Our goal is to develop an approach to pairwise hop distance estimation that is accurate, scalable, timely and does not require a significant measurement infrastructure. Our methodology is based on deploying a small set of landmark nodes that use traceroute-like probes between each other to establish a set of accurate pairwise hop distances. The landmark nodes are also configured to collect source IP addresses and TTL values from passively monitored network packet traffic. We develop a novel multidimensional scaling algorithm that can be applied to both the passive and active measurements to generate pairwise hop distance estimates for all of the observed source host addresses. The basic algorithm is then enhanced to consider the autonomous system membership of source hosts via BGP routing information. We investigate the capabilities of our estimation algorithms using a set of synthetic network topologies. The results show that our method can generate highly accurate pairwise hop distance estimates over a range of network sizes and configurations, and landmark infrastructure sizes.
Install https://github.com/runk/node-maxmind
Download 'GeoLite2-City.mmdb' from: 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 );
}