Le protocole BitTorrent et ses extensions

Extensions

Dans la partie précédente, on a vu comment les choses se passaient du point de vue de la spécification BitTorrent de base. De nombreuses extensions existent, à l'état de draft mais néanmoins supportées par la plupart des clients logiciels pour BitTorrent.

µTP

Le peer protocol est très fréquemment remplacé dans les faits par µTP (Micro Transport Protocol) pour au moins deux raisons :

La spécification de µTP est assez indigeste. Il ré-implémente un algorithme de contrôle de flux similaire à celui de TCP (mais avec des paquets UDP ): une fenêtre d'émission va définir le nombre maximal d'octets en transit (pas encore acquittés). A la différence de TCP, la taille de cette fenêtre va être basée sur une estimation du délai d'aller retour des paquets dans le réseau. Les modems ont en général des buffers suffisants pour stocker plusieurs secondes de trafic ; toutefois dans l'idéal un paquet µTP n'est jamais bufferisé. Le principe est que si d'autre flux (qui n'ont pas ce mécanisme) remplissent les buffers, le temps d'aller-retour va augmenter et µTP va diminuer sa fenêtre d'émission. Dans les faits, le trafic µTP va donc être moins prioritaire que les autres flux.

La courbe suivante (trouvée dans une étude de µTP sur le blog officiel de BitTorrent) présente un flux µTP qui cède sa bande passante à un flux TCP qui arrive (pour avoir eu l'immense joie d'essayer de mettre en oeuvre de la QoS au niveau client, je trouve cette courbe un peu trop propre pour être honnête)

Magnet links

Dans ce que j'ai détaillé jusqu'ici, il y a encore deux éléments qui ne sont pas encore distribués. Il faut télécharger un fichier torrent sur un serveur et contacter un tracker qui est un serveur central. Deux extensions permettent de distribuer ces éléments ; la première défini les magnet links.

Sur le web, il est de plus en plus courant de rencontrer des magnet links en lieu et place des des fichier torrent. Ce sont des liens du type :

magnet:?xt=urn:btih:info-hash&dn=name&tr=tracker-url

On y retrouve l'info_hash du torrent, le nom du torrent et l'URL du tracker. En utilisant ce lien dans un client logiciel BitTorrent, on va contacter le tracker pour obtenir une liste de peers. La première chose que l'on va faire avec ces peers est de télécharger le ficher torrent.

Depuis février 2012, The Pirate Bay n'utilise que des magnet links. A l'époque il avait été calculé qu'on pouvait alors stocker un mirroir complet des torrent référencés sur 90MB

Mainline DHT

Seul le tracker nécessite encore un serveur. Il existe toutefois un système dit trackerless (l'adjectif n'est pas très heureux puisqu'en réalité c'est l'inverse : chaque peers devient un tracker) qui utilise un mécanisme de table de hachage distribuée. Ce système c'est Mainline DHT, qui est l'implémentation pour BitTorrent d'un protocole plus général appelé Kademlia.

Pour être d'accord sur les termes employés : dans la suite, un noeud sera une station participant au protocole DHT et les peers seront toujours celles participant aux échanges BitTorrent

Mainline DHT repose sur plusieurs principes de base :

Pour communiquer entre eux, les noeuds de DHT maintiennent des tables de routage. Tout l'espace [0, 2^160 [ (ensemble des mots de 20 octets) est découpé en buckets. Au départ on a qu'un seul bucket qui rempli tout l'espace et on choisi notre ID au hasard (point rouge) :

En communiquant, on rencontre deux nouveaux noeuds. On les ajoute dans le bucket :

Imaginons que le protocole définisse un bucket contenant deux noeuds comme "plein". Lorsqu'on rencontre un troisième noeud, il faut scinder le bucket :

Ensuite, lorsqu'on rencontrera un nouveau noeud, on ne le stockera que si il appartient au même bucket que nous. En continuant à ajouter des noeuds, on finira par connaitre beaucoup de noeuds proches de notre propre ID et peu de noeuds éloignés

On représente souvent l'espace des id/info_hash sous la forme d'un cercle :

Imaginons que l'on soit la station avec l'ID 8, et que l'on souhaite télécharger un fichier dont l'info_hash est 42. Si on connait (dans notre table de routage) la station 12, on va lui demander la liste des peers qui participent à la diffusion du ficher 42 :

Elle va nous répondre qu'elle ne connait aucune peers pour le info_hash 42 mais qu'en revanche elle connait des noeuds DHT plus proches de l'ID 42 qu'elle ne l'est elle même (en l'occurence ici, 40 et 48) :

On retransmet donc cette demande de peers au noeuds 40 et 48 :

Les noeuds 40 et 48 vont nous répondre que eux non plus ne connaissent pas de peers pour ce torrent en particulier :

La station 48 nous réponds qu'il connait 40. On a déjà reçu 40 en réponse à une précédente requête (sur la station 12), cela constitue une condition d'arrêt de la recherche de peers (la condition est plus complexe en réalité, j'ai simplifié pour les besoins de l'explications). La règle fondamentale est de toujours terminer une recherche (fructueuse ou non) en s'annonçant en tant que peer vers le noeud connu le plus proche de l'ID de notre torrent (ici le noeud 40). Le noeud 40 va stocker cette information

Maintenant, imaginons que le noeud d'ID 50 souhaite télécharger le fichier 42. Il peut commencer par demander des peers au noeud 48 :

Le noeud 48 lui répond qu'il ne connait pas de peers mais qu'il connait le noeud 40 :

Le noeud 50 va ré-itérer sa demande vers le noeud 40 :

Le noeud 40 va enfin pouvoir répondre que oui, il connait une peers pour le fichier 42.

L'échange du fichier par peer protocol où µTP peut commencer. Mais attention, puisqu'il vient de terminer sa recherche, il doit également s'annoncer en temps que peer :

Les prochaines requêtes sur le noeud 40 retournerons deux peers.

Les plus perspicaces se poseront la question de "comment connaître le premier noeud (le bootstrap node) ?" Plusieurs solutions :

Des chercheurs se sont amusé à mesurer Mainline DHT. La procédure (statistique) permettant de compter le nombre de noeud est un peu complexe mais le résultat principal est le suivant :

Mainline DHT est donc une table de hachage distribuée sur plusieurs millions de noeuds (entre 15 et 28 millions de noeuds selon l'heure de la journée).

(Ces même chercheurs ont également conduit une étude intéressante sur la sécurité de MainlineDHT et des attaques qui s'y déroulent. Ils ont identifié des attaques permanentes en provenance d'un ISP international et d'un inconnu louant une architecture AWS)