Cliente BitTorrent implementado desde cero
(github.com/piyushgupta53)- Go-Torrent es una implementación de cliente BitTorrent hecha en Go que implementa las funciones principales para descargar archivos usando el protocolo BitTorrent
- El alcance de la implementación incluye parseo de archivos .torrent, descubrimiento de peers, comunicación con peers y descarga de archivos, y maneja torrents de un solo archivo y de múltiples archivos
- Bencode soporta los tipos string, entero, lista y diccionario, e incluye manejo de errores y funciones de validación
- La función de descarga ofrece gestión de piezas (pieces) y bloques, descargas concurrentes, seguimiento del progreso y gestión de almacenamiento a nivel de bloque
- El proyecto todavía está en desarrollo activo, y se planea agregar soporte para Magnet links, metadata exchange protocol y DHT
Funciones que implementa Go-Torrent
- Go-Torrent es una implementación de cliente BitTorrent escrita en Go
- Implementa las funciones principales para poder descargar archivos usando el protocolo BitTorrent
- El alcance principal de la implementación es el siguiente
- Parseo de archivos torrent
- Descubrimiento de peers
- Descarga de archivos
Bencode y manejo de archivos torrent
- La codificación/decodificación Bencode soporta todos los tipos de Bencode
- Strings
- Enteros
- Listas
- Diccionarios
- Incluye manejo de errores y validación
- El manejo de archivos torrent soporta el parseo de archivos
.torrent- Torrents de un solo archivo
- Torrents de múltiples archivos
- Soporta el cálculo del info hash y la extracción de hashes de piezas (piece hash)
- Soporta los campos estándar de archivos torrent
Descubrimiento y comunicación con peers
- Soporta descubrimiento de peers mediante HTTP tracker
- Implementa el protocolo de handshake con peers
- Incluye el protocolo completo de mensajes BitTorrent
- Ofrece gestión de conexiones con peers
Descarga y gestión de almacenamiento
- La función de descarga incluye gestión de piezas (pieces) y bloques
- Puede realizar varias descargas al mismo tiempo
- Hace seguimiento del progreso de descarga
- Soporta el ensamblado de archivos tanto para torrents de un solo archivo como de múltiples archivos
- La gestión de almacenamiento funciona con granularidad a nivel de bloque
Estructura, requisitos y estado de desarrollo
- La estructura del proyecto se divide en los siguientes paquetes
cmd/: interfaz de línea de comandos y aplicación principalinternal/bencode/: codificación/decodificación Bencodeinternal/torrent/: manejo de archivos torrentinternal/tracker/: implementación del protocolo de trackerinternal/peer/: comunicación con peersinternal/download/: gestión de descargaspkg/: paquetes públicos
- El requisito es Go 1.21 o superior
- La instalación se realiza clonando el repositorio y luego ejecutando
go mod download - La documentación de uso se agregará cuando el proyecto esté más maduro
- El estado actual de la implementación puede consultarse en checkpoint.md
- Las funciones planeadas son las siguientes
- Soporte para Magnet links
- Metadata exchange protocol
- Soporte para DHT (Distributed Hash Table)
- Las referencias son BitTorrent Protocol Specification y Bencode Specification
1 comentarios
Opiniones en Hacker News
Excelente. Pero como se trata de entradas no confiables, sería buena idea limitar el tamaño de las asignaciones dinámicas en el decodificador bencode.
Una entrada maliciosa en un archivo torrent o en una respuesta announce podría obligar al cliente a hacer una asignación muy grande al parsear una cadena y llevarlo a una denegación de servicio. Un torrent bien formado no puede contener una cadena más larga que la entrada restante, así que parece razonable usar la longitud de la entrada restante como límite superior.
Me gusta que se ve limpio y simple. Estaría bueno agregar en el README una línea de ejemplo de uso que realmente descargue un archivo
.torrent.Ej.:
./go-torrent My-Linux-Distro-Wink-ISO.torrentAdemás, sería aún mejor incluir
torrent.ParseFromUrl; proyectos como este son algo que vale la pena intentar al menos una vez como ejercicio personal.Genial. En codecrafters hay un challenge que guía un poco este proceso y también ofrece tests. Lo probé un poco durante el mes gratis y fue divertido.
https://app.codecrafters.io/courses/bittorrent/overview
Genial. Yo también había pensado en algo así. Me da curiosidad qué tan difícil fue y hasta qué punto se puede considerar “terminado”. También me pregunto si maneja DHT, Magnet y toda clase de funciones para atravesar NAT.
El punto donde siempre me trababa era no saber cuál era la lista de funciones necesarias para crear un cliente que simplemente funcionara con la mayoría de los torrents que circulan en la práctica. Parece haber decenas de protocolos relacionados con torrents, y ni siquiera sé cuál es la lista completa, mucho menos qué hace cada uno.
Definitivamente fue difícil. Me tomó casi un mes aprender cómo funcionan el protocolo y bencoding, crear un modelo mental y luego escribir el código real.
Magnet y DHT todavía no están agregados.
La dificultad depende mucho de la experiencia, la familiaridad con el lenguaje de programación que uses y tu actitud para experimentar. Como referencia, yo también empecé a hacer un cliente Bittorrent en Go la semana pasada, y en una semana llegué más o menos al 80% del proyecto publicado.
Eso sí, tengo mucha experiencia con Go, bastante conocimiento de protocolos y networking, y experimentar ya es casi una segunda naturaleza para mí.
Si te interesa, la especificación central de Bittorrent en realidad es bastante corta y se puede leer y entender fácilmente en más o menos una hora: https://www.bittorrent.org/beps/bep_0003.html
Alrededor de Bittorrent hay muchas cosas como extensiones del protocolo, pero por lo que he visto hasta ahora, el nivel de soporte varía según el cliente. Por ejemplo, Protocol Encryption en la práctica es casi ofuscación: primero se intenta comunicarse con ese método y, si no funciona, según la configuración se vuelve al protocolo normal.
Para descargar una distribución de Linux, por ejemplo Debian, desde un archivo
.torrentde un sitio web, el camino es relativamente directo. Es un solo archivo, hay un tracker, muchos peers usan el protocolo normal y, si estás detrás de NAT, hasta cierto punto puedes arreglártelas sin aceptar conexiones entrantes.Naturalmente, si entras en contenido de zona gris, puede que quieras parsear enlaces Magnet, encontrar peers con DHT e implementar también UPnP para intentar mapear automáticamente un puerto en el módem. Aun así, eso también se puede ir construyendo de forma iterativa, una cosa a la vez. Cuantas más funciones tengas, más peers podrás encontrar y mayores serán las probabilidades de intercambiar datos con éxito.
No soy desarrollador Go, así que pregunto: ¿por qué usar el antiguo Go 1.21? ¿Hay alguna razón para quedarse en una versión vieja?
Edición: parece que dejó de tener soporte hace 10 meses.
El soporte para Windows 7 es una de las razones para quedarse en una versión antigua de Go. Los proyectos creados con Go 1.21.4 o anterior funcionan en todas las versiones de Windows y en computadoras fabricadas desde 2009, pero si subes a v1.21.5, sin mucho beneficio, pasan a funcionar solo en computadoras más recientes y Windows 10/11.
https://github.com/golang/go/issues/64622
El README probablemente fue generado por IA. El archivo
go.modreal indica la versión de Go 1.23.1[1], lo que significa que se necesita Go 1.23.1 o superior[2].[1] https://github.com/piyushgupta53/go-torrent-client/blob/6130...
[2] https://go.dev/doc/modules/gomod-ref#go-notes
Muy bueno. Me recuerda a mis tiempos en la universidad. Hicimos esto como proyecto final en una clase de networking de Georgia Tech.
Perdí el código hace mucho, pero las lecciones que aprendí entonces todavía me quedaron. Proyectos así también son una buena forma de aprender un lenguaje nuevo.
Es el tipo de proyecto que vale la pena intentar. Yo hice algo parecido y ver los encoders/decoders bencode que hicieron otras personas me dio una buena dosis de humildad.
También es una buena forma de explorar las capacidades de un lenguaje. Claro que intentar alcanzar todas las funciones de una biblioteca grande es bastante inútil, y diría que la compatibilidad entre clientes ya es insuficiente.
Me pregunto si hay planes de publicar documentación sobre el proceso de implementación. Personalmente, eso me interesa más que el código en sí.
Es porque no hay mucho material que profundice en el enfoque o el proceso para implementar distintos aspectos del protocolo.
Me pregunto si también hizo v2 y mutable torrents. Por favor, ojalá alguien implemente mutable torrents.
¿Soporta enlaces Magnet?
Edición: ah, era una función planeada.