the ugly org - bittorrent al toque

desu

#30 El codigo esta aqui: https://github.com/vrnvu/rust-bittorrent/blob/master/bt/src/peer_download.rs

Un archivo a transmitir en torrent se parte en N trozos que representan bloques de memoria del archivo. De cada trozo se hace un SHA1 para validar. Cuando te descargas un trozo de un archivo, para cada trozo haces request de paquetes mas pequeños download_piece, puedes validar que la descarga es correcta porque el hash SHA1 sera igual. Cuando tienes todos los trozos de un archivo descargados, los puedes concatenar en memoria y te darán un archivo valido.

Desde el punto de vista del peer_downloader:

Linea 1 itero los trozos y me los descargo del peer, cuando me los descargo se valida el hash y si es correcto se guardan en memoria en un buffer de buffers: downloaded_torrent

Linea 10, hago un "concat" de mi buffer de buffers para tener un buffer aplanado con todos los trozos correctamente descargados y lo escribo en un archivo.

NOTA: TODO ESTO SE PODRIA OPTIMIZAR, ESTA ES LA VERSION DUMMY

Codigo de validation del hash:

Linea 194, miro el hash que me proporciona el torrent file, Linea 5 calculo mi hash de lo que me he descargado, compruebo si es correcto o no.

El tracker solo sirve para descubrir peers, no necesita almacenar ninguna información.


Demo con #27:

La calidad parece muy mala, no se si se esta terminado de procesar o que... Si no subiré el demo a YouTube.

1
desu

Lo del tracker http puede ser dos tipos. HTTP (HTTPS) o UDP. Y esta definido en el .torrent (o magnet si usases).


Lo que esto determina es la comunicación con el tracker para adquirir los peers. Tengo el HTTP hecho y me faltaría el UDP.

https://github.com/vrnvu/rust-bittorrent/blob/master/bt/src/http.rs

La dificultad es que no se usa json para el tracker... se usa el beencode como explique y da pereza hacerme le UDP.

Si usas mi cliente con cualquier archivo .torrent que sea un tracker HTTP funcionara si la descarga no sufre ningún error, porque no tengo todos los retries necesario.

*Los magnets serian los archivos .torrent pero aplanados en una URL.

No existe ningún protocolo establecido de como de inteligentes deben ser los trackers, lo unico necesario es el info_hash para que el tracker encuentre a los peers, todo lo demas es opcional:

Si quereis ver un tracker simple, tengo este implementado:
https://github.com/vrnvu/rust-bittorrent/blob/master/tracker/src/main.rs

1
desu

Si probáis el modo interactivo, utiliza mi tracker para listar todo el contenido disponible de todos los peers:

  1. Abres un tracker en 9999
  2. Lanzas un uploader para subir un archivo
  3. Lanzas otro uploader...
  4. Lanzas...
  5. Usas el interactive

Te saldra una lista con todos los archivos del tracker.

Aqui entraria la definicion de que el tracker puede listar y que no, y como lo hace.

La libreria que he usado es muy buena, tiene fuzzy search y un montón de opciones para hacer CLI interactivas y wizards.

1
desu

#31 Preguntas que he recibido:

es decir que el client debe descargarse las partes y meterlo en memoria, si es un fichero de 20GB no podría

Respuesta:

NOTA: TODO ESTO SE PODRIA OPTIMIZAR, ESTA ES LA VERSION DUMMY

Como sabes el offset podrias ir guardando segun descargas, que es lo que se hace, asi puedes hace stop/resume.

Lo que puede pasar raramente es que te quedes sin memoria RAM o sin memoria de disco.

desu

Primer nivel de paralelismo completado.

Cuando descargamos un torrent, utilizamos todos los peers disponibles.

el tracker

en la imagen vemos como el peer izquierdo devuelve dos partes, el derecho una parte

el peer_download

el codigo:

faltaria gestionar los errores que podemos hacer retry y descartar los que no

https://github.com/vrnvu/rust-bittorrent/commit/3a4a4a73b98aa120a497e08323a14e2a3cf3c322

desu

Voy a dejar el proyecto aquí.