2016-05-26 12 views
22

Angesichts einer einzigen öffentlichen IP-Adresse (Peer A) und einer Liste von vielen anderen öffentlichen IP-Adressen (eine Mischung aus IPv4-und IPv6-Adressen), ist der einfachste Weg, Peer A die IP Adressen der n nächsten Peers, ohne dass sich die Peers beim Latenz-Benchmarking gegenseitig manuell pingen?WebRTC: Abgleich nächster Peers

Ich denke, dass dies mit BGP mit einer Reihe von komplizierten Abfragen möglich ist (und vielleicht etwas mit OSPF), aber ich hatte gehofft, dass es eine Lösung oder Bibliothek geben könnte, die es so einfach wie den theoretischen Funktionsaufruf machen würde .

// `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); 

Soll ich nur eine lokale Instanz der GeoIP-Datenbank MaxMind verwenden + Haversine/Vincenty, oder ist es praktisch, BGP über eine Bibliothek zu verwenden (mit dem richtigen Caching, wo erforderlich), dies zu erreichen?

Es scheint, als ob diese Art von Code in einer Open-Source-Anycast-Routing-Implementierung existiert, obwohl ich nichts gefunden habe, das zu diesem Anwendungsfall passt.

Die Lösung oder vorgeschlagene Bibliothek muss nicht auf node.js funktionieren - jede Sprache ist in Ordnung.

+0

Ich nehme an, die Liste der IPs sind externe IP-Adressen. Ich würde die GeoIP-Datenbank von MaxMind verwenden, um die Koordinaten jedes IP zu erhalten und dann die Haversine-Formel zu verwenden, um den kürzesten Ort zu bestimmen. Wahrscheinlich wäre der Flaschenhals die Reaktionszeit von MaxMind (Beispiel <400 ms), aber ich habe auch festgestellt, dass sie Ihnen die GeoIP-Datenbank verkaufen, um sie bei Bedarf lokal zu hosten. https://www.maxmind.com/en/geoip2-databases – spicyramen

+0

@spicyramen Ja, wenn ich nicht herausfinden kann, wie man das in BGP macht, ist eine lokale MaxMind db meine Fallbackalternative für jetzt. –

Antwort

3

Als ich es gelesen habe, ist Ihre Frage Art und Weise allgemeiner als Ihre Javascript/WebRTC Anwendungsfall.

Wer über so etwas wie: "Gegeben ein P2P-Netzwerk, und ein zentraler Server, der alle verbundenen Peers kennt, welches ist die beste Metrik als verwendet werden kann, um sie zu paaren?".

=> Eine gute Metrik, um zwei beliebige Knoten zu paaren, wäre die Hop-Distanz zwischen ihnen. Das Problem ist, dass dieser Wert nicht berechnet werden kann (Sie können nur erraten, welchen Pfad die ISP-Router zwischen den Knoten wählen).

Wie wird es dann approximiert?

1. Verwenden geographischer Entfernung als Annäherung Entfernung In diesem Fall

zu hüpfen, sind Sie ziemlich viel getan. Verwenden Sie einen Dienst "ip to latlng" und Sie sind fertig.

2. Versuchen Sie, die wirkliche Sprungdistanz zu erraten, durch das Internet Mapping

ich zu diesem Thema ein Papier gefunden, die für Sie nützlich sein könnten.Genauso gut könnte man ein bisschen auf ihre Referenzen graben zu früheren Arbeiten auf dem gleichen Thema abrufen:

Estimating Hop Entfernung zwischen beliebigen Host-Pairs http://nowak.ece.wisc.edu/infocom09.pdf

Abstract - Einrichtung eines klaren und aktuelles Bild von Internet Topologie wird durch viele Faktoren einschließlich der enormen Größe und dynamische Natur der Infrastruktur kompliziert. In diesem Artikel beschreiben wir eine Methodik zur Schätzung eines wichtigen Merkmals der Internet-Topologie - die Hop-Abstand zwischen beliebigen Paaren der End-Hosts. Unser Ziel ist es, einen Ansatz zur paarweisen Sprungdistanzschätzung zu entwickeln, der genau, skalierbar, zeitgerecht ist und keine signifikante Messinfrastruktur erfordert. Unsere Methodologie basiert auf dem Einsatz eines kleinen Satzes von Knotenpunkten, die traceroute-ähnliche Sonden untereinander verwenden, um eine Menge von genauen paarweisen Sprungdistanzen aufzubauen. Die Orientierungspunkte Knoten sind auch konfiguriert, um Quell-IP-Adressen und TTL-Werte aus passiv überwachtem Netzwerkpaketverkehr zu sammeln. Wir entwickeln einen neuartigen multidimensionalen Skalierungsalgorithmus, der sowohl auf die passiven als auch auf die aktiven Messungen angewendet werden kann, um paarweise Sprungentfernungsschätzungen für alle beobachteten Quellen-Hostadressen zu generieren. Der Basisalgorithmus wird dann auf erweitert, um die autonome Systemmitgliedschaft von Quellhosts über BGP-Routing-Informationen zu betrachten. Wir untersuchen die Fähigkeiten unserer Schätzalgorithmen mit einer Reihe von synthetischen Netzwerktopologien. Die Ergebnisse zeigen, dass unsere Methode sehr genaue paarweise Sprungdistanzschätzungen über eine Reihe von Netzwerkgrößen und Konfigurationen und Landmark-Infrastrukturgrößen generieren kann.

+0

Danke für den Link zu diesem Papier. Genau das suche ich! –

2

Der einfachste Weg, die nächsten Peers zu finden, wäre, jedem der Peers eine Echo-Anfrage zu senden und die Zeit zu messen, die es braucht, um eine Antwort zu bekommen, wie Ping.

9

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

Herunterladen 'GeoLite2-City.mmdb' aus: 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); 
}