Un client BitTorrent implémenté entièrement from scratch
(github.com/piyushgupta53)- Ce projet open source est un client BitTorrent implémenté en Go, avec une logique fondamentale de téléchargement développée en interne
- Il gère directement l’encodage/décodage Bencode et inclut de solides fonctions de validation des erreurs
- Il prend en charge de manière complète les fonctionnalités clés comme l’analyse des fichiers
.torrent, le calcul du hash d’information et la communication entre pairs - Il inclut des fonctions utiles en conditions réelles, comme le téléchargement concurrent, l’assemblage des fichiers et la gestion du stockage par blocs
- Par rapport aux projets open source BitTorrent existants, il se distingue par la simplicité de Go, la clarté de sa structure de code et sa modularité
Aperçu
Ce projet implémente directement un client BitTorrent en Go
Il fournit, sous forme de développement maison, une fonctionnalité de téléchargement de fichiers utilisant le protocole BitTorrent
Il couvre principalement l’analyse des fichiers torrent, la découverte des pairs et le téléchargement de fichiers
Fonctionnalités principales
-
Encodage/décodage Bencode
- Prise en charge de tous les types Bencode : chaînes, entiers, listes et dictionnaires
- Application d’une gestion robuste des erreurs et de la validation des données
-
Traitement des fichiers torrent
- Analyse possible des torrents mono-fichier et multi-fichiers
- Extraction du hash Info et du hash de chaque pièce, avec prise en charge de tous les champs standard
-
Découverte des pairs et communication
- Prise en charge des trackers HTTP
- Implémentation du protocole de handshake entre pairs
- Gestion du protocole de messages BitTorrent et des connexions entre pairs
-
Fonctionnalités de téléchargement
- Gestion par pièces et par blocs
- Traitement des téléchargements concurrents
- Suivi de la progression du téléchargement et assemblage des fichiers
- Gestion du stockage au niveau des blocs pour plus d’efficacité
Structure du projet
- cmd/ : interface en ligne de commande et exécutables
- internal/
- bencode/ : fonctions d’encodage et de décodage Bencode
- torrent/ : analyse et traitement des fichiers torrent
- tracker/ : implémentation du protocole tracker
- peer/ : fonctions de communication entre pairs
- download/ : fonctions de gestion du téléchargement
- pkg/ : ensemble de packages exposables à l’extérieur
Prérequis
- Go 1.21 ou supérieur requis
Utilisation
- Le projet en est actuellement à un stade initial de développement ; un guide d’utilisation sera ajouté ultérieurement
État du développement et feuille de route
- Le développement est actuellement actif
- Les étapes détaillées du développement sont consignées dans le fichier
checkpoint.md - Plans futurs :
- Prise en charge des liens Magnet
- Protocole d’échange de métadonnées
- Prise en charge de DHT (table de hachage distribuée)
Documentation de référence
- Spécification du protocole BitTorrent
- Spécification Bencode
Importance et points forts du projet
- Ce projet exploite la syntaxe simple et la concurrence propres à Go pour implémenter les éléments complexes d’un client BitTorrent de manière clairement modulaire
- Sa structure claire offre des avantages en extensibilité et en maintenabilité, aussi bien pour l’apprentissage que pour une utilisation en situation réelle
- Bien qu’à un stade relativement précoce, il a déjà concrétisé rapidement les fonctionnalités essentielles du protocole BitTorrent
1 commentaires
Avis Hacker News
Suggestion de limiter la taille des allocations mémoire dynamiques dans le décodeur bencode. Les valeurs reçues depuis le fichier torrent ou via
announcene sont pas fiables, donc une entrée malveillante peut demander une allocation énorme et provoquer un déni de service (DoS). Lors du parsing des chaînes, une borne supérieure appropriée peut être définie à la longueur restante de l’entrée, puisqu’un torrent valide ne peut pas contenir une chaîne plus longue que ce qu’il reste dans le fichierLe projet paraît propre et simple, ce qui est appréciable. Ce serait bien d’ajouter dans le README un exemple d’utilisation en une ligne, par exemple une phrase montrant quelque chose comme
./go-torrent My-Linux-Distro-Wink-ISO.torrent. Si une fonctionnalitétorrent.ParseFromUrlest aussi ajoutée, ce serait encore mieux. Tout le monde mérite de vivre ce genre d’expérience dans son propre « voyage spirituel »Présentation d’un challenge similaire proposé par codecrafters. Le parcours aide avec l’avancement du processus et les tests, et l’auteur l’a essayé gratuitement pendant un mois en trouvant ça assez amusant
https://app.codecrafters.io/courses/bittorrent/overview
Sans être développeur Go, quelqu’un se demande pourquoi utiliser l’ancienne version Go 1.21. Question sur l’éventuelle raison de s’accrocher à une vieille version, d’autant qu’elle n’est déjà plus supportée depuis 10 mois selon ce qu’il a trouvé
C’est à cause du support de Windows 7. Un projet écrit avec Go 1.21.4 ou antérieur fonctionne sur presque tous les Windows sortis depuis 2009 et sur pratiquement tous les ordinateurs, alors qu’avec 1.21.5 ou plus, cela ne fonctionne plus que sur des machines récentes avec Windows 10 ou 11, sans avantage particulier
https://github.com/golang/go/issues/64622
Le README a probablement été écrit par une IA. Le fichier
go.mod, lui, indique en réalité la version Go 1.23.1, ce qui implique au final Go 1.23.1 ou plushttps://github.com/piyushgupta53/go-torrent-client/blob/6130f4e/go.mod#L3 https://go.dev/doc/modules/gomod-ref#go-notes
Vraiment un super projet. Quelqu’un raconte avoir eu ça comme projet final dans un cours de réseaux à Georgia Tech à l’université. Le code a été perdu depuis, mais les leçons apprises sont restées pour la vie. Ce genre de projet est excellent pour apprendre un nouveau langage
Question sur le support des liens magnet.
Edit : il a été appris que c’est une fonctionnalité prévue pour plus tard
Question sur la manière dont cela a été construit. Est-ce que le protocole a été étudié directement à partir de la spécification, ou en s’inspirant d’autres implémentations ? La personne dit s’être toujours demandé comment on implémente ce genre de chose à partir de zéro
https://www.bittorrent.org/beps/bep_0003.html
Les extensions supplémentaires sont listées ici
https://www.bittorrent.org/beps/bep_0000.html
L’important est de découper le travail en toutes petites étapes et de vérifier soi-même les résultats au fur et à mesure. Par exemple, il a commencé par parser un fichier
.torrent, ce qui a obligé à implémenter bencoding à la main. En téléchargeant un.torrentd’Arch Linux, il est tombé sur un format inattendu avec des clés commeurl-list. Après recherche, cela s’est avéré lié à bep_0019. Il a finalement réussi à parser le fichier.torrentde Debian LinuxEnsuite, il a implémenté la requête HTTP
announcedu tracker ainsi que le protocole peer. Le protocole peer était assez difficile, et une approche expérimentale a beaucoup aidé. Il a supprimé l’URLannouncedu torrent Debian pour n’avoir aucun peer, puis a ajouté directement son client dans KTorrent afin d’observer les messages échangés et d’ajuster son propre code en conséquence. Il y a eu énormément d’essais, d’erreurs et de débogageCertains détails du protocole étaient introuvables dans la documentation officielle, donc il lui est arrivé de poser quelques petites questions à ChatGPT, et les implémentations variant selon les clients, les algorithmes détaillés ne sont pas toujours clairs. Le choix des blocs à recevoir, des peers auxquels se connecter, ou encore le fonctionnement de choke/unchoke ne sont pas vraiment bien documentés. La recherche web aide beaucoup
En complément, le site https://wiki.theory.org/Main_Page contient aussi des informations utiles
À ce stade, le client arrive à télécharger et uploader complètement avec KTorrent. Il reste maintenant à développer l’algorithme pour récupérer des peers depuis le tracker, choisir les blocs à télécharger et les écrire dans le fichier
N’hésitez pas à poser d’autres questions si vous voulez des détails supplémentaires
Question sur la difficulté d’ajouter une GUI. La personne dit ne pas avoir vu beaucoup d’exemples d’interfaces graphiques en Go
Personnellement, préférence pour https://github.com/AllenDang/giu, un wrapper ImGui
Le plus complet semble être unison, même s’il n’est pas certain qu’il soit réellement largement utilisé, et sa documentation a l’air très insuffisante https://github.com/richardwilkes/unison
Gio est un framework GUI d’un genre nouveau, utilisé par Tailscale et gotraceui https://gioui.org
Wails est facile à prendre en main si on a une expérience en développement web https://wails.io
Les bindings GTK4 ont aussi l’air corrects https://github.com/diamondburned/gotk4
Cogent Core a aussi l’air intéressant, mais il n’a été essayé que brièvement avant de passer du Go au langage Odin https://www.cogentcore.org/core
Fyne a personnellement causé pas mal de problèmes de performances sur plusieurs ordinateurs et OS, mais cela reste malgré tout le framework GUI le plus connu https://fyne.io
Quelqu’un dit être intéressé par ce type de projet et avoir envisagé d’en faire un. Il demande à quel point c’est difficile, à quel niveau de complétude on peut arriver, et si des fonctionnalités complexes comme DHT, Magnet ou la traversée de NAT ont été implémentées. Il dit aussi ne même pas bien savoir quelles sont les fonctionnalités indispensables pour couvrir la quasi-totalité des torrents disponibles dans la pratique, tant les protocoles liés au torrent sont nombreux, sans même parler de leur rôle respectif
Le niveau de difficulté varie énormément selon l’expérience, la maîtrise du langage et l’habitude d’expérimenter. À titre d’exemple, quelqu’un a lui-même commencé la semaine dernière à écrire un client Bittorrent en Go et a atteint en une semaine environ 80 % du niveau du projet présenté ici. Comme il connaît bien Go, les protocoles et le réseau, et qu’il a l’habitude de tester des choses, il a avancé rapidement
La spécification officielle de Bittorrent elle-même est très courte, et peut être lue et comprise en une heure environ https://www.bittorrent.org/beps/bep_0003.html
Mais il existe énormément de protocoles d’extension autour, et chaque client les prend en charge à des degrés divers. Par exemple, beaucoup tentent d’abord le chiffrement du protocole — qui est en réalité plutôt une obfuscation — puis repassent au protocole normal si cela échoue
Si l’objectif est simplement de télécharger depuis des fichiers
.torrentofficiels comme ceux des distributions Linux, la difficulté est clairement plus faible. Il s’agit généralement d’un seul fichier, avec un tracker, et la plupart des peers utilisent le protocole standard ; même derrière un NAT, cela fonctionne souvent très bien sans ouverture de port côté entrantBien sûr, pour des torrents plus généraux — en particulier dans des zones grises — il faut progressivement ajouter le parsing des liens magnet, la DHT pour découvrir des peers, puis l’UPnP pour le mapping automatique de port. Mais cela reste implémentable fonctionnalité par fonctionnalité, étape par étape. Plus on ajoute de fonctionnalités, plus on peut trouver de peers et échanger avec succès
C’était assez exigeant, et il a fallu presque un mois pour se familiariser avec le protocole et le bencoding, se représenter l’architecture globale, puis écrire le code. Magnet et DHT ne sont pas encore pris en charge
Question pour savoir si v2 et les mutable torrents ont été implémentés. Souhait exprimé de voir absolument le support des mutable torrents