miércoles, 4 de marzo de 2009

Bittorrent

Començo el nou blog amb un post sobre protocols, avui Bittorrent!

Suposo que tothom, més o menys coneix el Bittorrent, aquest "programa per descarregar pel·lícules". Doncs bé, bittorrent és el nom del protocol, també de l'empresa que el va fer i d'un programa que utilitza aquest protocol. Sí, realment poca imaginació.

Bàsicament és un protocol per distribuir fitxers, fa temps s'usa de forma popular, però últimament ha tingut bastant resó mediàtic pel judici que ha tingut lloc a Suècia contra la pàgina d'emmagatzemament de .torrents The Pirate Bay. Al final sembla ser que poca cosa han pogut fer perquè tal pàgina tant sols guardava els fitxers .torrent i només actuava de tracker, i això no és delicte oi ?, ara probablement algú es preguntarà què és un .torrent? què és un tracker ? ara anem a això!

Protocol

El gran avantate que té el bittorrent sobre l'HTTP clàssic és que quan hi ha diverses baixades del mateix fitxer de forma concurrent (diverses persones volen baixar-se el mateix fitxer alhora), aquests usuaris s'envien trossos del fitxer entre ells. Per tant, com més persones hi hagi baixant un fitxer millor.

Com funciona.

El funcionament de cara l'usuari és ben senzill.


Un usuari es baixa un fitxer amb extensió .torrent, és un fitxer petit, menys de 60ks. Tot seguit s'obre amb el client de bittorrent i el fitxer es comença a descarregar. Pim pam.

En resum i explicat d'una forma planera el que passa és el següent:

Quan l'usuari obre el fitxer .torrent amb el seu client, aquest contacta amb el tracker (la direcció del tracker està dins el fitxer .torrent) que és un programa instal·lat en un servidor d'internet, i s'identifica com un usuari que es vol baixar aquell fitxer en concret. Tot seguit el tracker contesta amb les IP's dels diferents peers (altres usuaris) que s'estan baixant el fitxer, i que per tant, en ténen trossos. Seguidament el client contacta amb aquesta llista d'usuaris i els hi comença a demanar trossos, més endavant aquest client també compartirà els trossos que ja té.

De tant en tant contactaran amb el tracker de nou per refrescar la llista d'usuaris connectats que comparteixen aquest fitxer.

Fitxer Torrent

El fitxer .torrent és un fitxer binari. Bàsicament és un diccionari amb els següents camps i valors:
  • announce: La URL del tracker.
  • info: És un altre diccionari que conté:
    • name: Nom suggerit per guardar el fitxer o el directori.
    • pieces length: Mida dels trossos en que es parteix el fitxer (o fitxers) en bytes. El protocol parteix el fitxer en trossos del mateix tamany, amb la única possible excepció de l'últim tros. Els trossos normalment són de 256Ks tot i que es veu que en versions del protocol anteriors els trossos eren de 1Mb.
    • pieces: És un string, la mida del qual és múltiple de 20. Cada 20 caràcters representa el hashing SHA1 del tros que representa, per tant hi haurà tants subtrossos de 20 com trossos tingui el fitxer, i a cada posició 20*i , sient 0 <= i < #trossos hi ha el hashing per a aquell tros en concret.
    • length/files: O bé hi ha length o bé hi ha files, però estrictament un (i només un) dels dos. En cas de que sigui length, significa que el que s'està baixant és un sol fitxer i en length és el tamany total d'aquest en bytes. En cas de que sigui files representa un conjunt de fitxers dins d'una estructura de directori.
    • path: Una llista d'strings que corresponen a noms de subdirectoris, en cas de que existeixin.


Tracker

El tracker és el software que comunica els usuaris amb altres usuaris, hi ha diverses implementacions, una de les més famoses és opentracker, que és la que utilitzen entre d'altres The Pirate Bay i la Wikipedia. A destacar la seva llicència, beerware.

Quan un client fa un GET (demana informació) a un tracker, la comanda HTTP té els següents valors:
  • info_hash: És un string de 20 bytes amb el hash SHA1 de l'apartat info del fitxer de metainfomració (aka .torrent)
  • peer_id: Id de l'usuari que es vol baixar el fitxer, aquest id és totalment aleatori i és generat pel client cada vegada que comença a baixar-se un fitxer de nou.
  • ip: (Paràmetre opcional) IP del client.
  • port: És el port al qual escolta el client, normalment és el 6881, en cas de que estigui ocupat és el 6882 i anar pujant fins al 6889.
  • uploaded: Els bytes que s'han pujat d'aquest fitxer. Això són els bytes que aquest client en particular ha enviat a altres peers.
  • downloaded: Bytes que s'han baixat fins aquest moment.
  • left: Número de bytes que falten per completar la transferència del fitxer. Cal notar que no té perquè ser el mateix que el resultat de la mida del fitxer - downloaded, ja que pot ser que hi hagi hagut una corrupció de dades o problemes de transferència, i que per tant algun tros de fitxer s'hagi de tornar a baixar.
  • event: És l'estat del client, pot ser started, quan s'està començant a baixar des del començament, completed un cop té tot el fitxer o stopped, un cop es para de baixar.

La resposta del tracker al client també són diccionaris en binari. Pot ser que el tracker contesti amb una entrada de failure, amb un contingut que és un string llegible amb el missatge d'error. En cas de que tot hagi anat bé el diccionari conté dues claus, la primera interval, que són el número de segons en que el client hauria de tornar a fer una petició d'informació al tracker. La següent entrada serà peers, que conté una llista de id's, ips i ports dels peers que s'estan baixant el fitxer. En cas de que hi hagi algun aconteixement especial un client pot fer una requesta d'informació al tracker encara que no hagi passat el temps indicat per aquest.

Comunicació entre peers

La comunicació entre peers és simètrica. Els missatges que s'envien d'un peer a l'altre són del mateix format i les dades (del fitxer que s'està compartint) poden anar també en els dos sentits.

Els peers es refereixen als diferents trossos del fitxer compartit amb indexs, que són exactament els mateixos indexs que hi ha al fitxer de metainformació. Un cop un client s'ha baixat un tros del fitxer i n'ha comprovat l'integritat amb el mapa SHA1 ho comunica a la resta de peers.

Les connexions entre peer i peer contenen dos bits d'estat. El primer, choked (tapat), si o no, i el segon, interessat, si o no. El bit the choked indica que el client està tapat, això vol dir que no enviarà més informació fins que sigui "destapat".

Una transferència de dades entre dos peers té lloc quan un dels dos està interessat i l'altre no està tapat. En cas de que un client no estigui interessat en res que tingui un altre client (sempre que aquest últim estigui destapat) aquest ho ha de fer constar amb el bit de interessat a fals.

El protocol recomana que quan s'està enviant dades, els clients haurien de tenir encuades a memòria diverses peticions de trossos per tenir una bona rendiment TCP, per altra banda quan s'està enviant dades a un altre peer també haurien de tenir els trossos a enviar a memòria, i en cas de que s'anul·li per qualsevol motiu la transferència, probablement el client quedi tapat. aquests trossos es poden borrar fàcilment. Això com ja he dit són recomanacions del protocol, caldria mirar exactament com s'implementa en cada client.

Per tant, quan dos clients s'envien missatges tenim bàsicament que comencen amb un handshake seguit per un fluxe d'informació de mida prefixada.

El handshake comença amb el número 19 en decimal seguit de l'string 'BitTorrent protocol'. A partir d'aquí, tots els números seran enters codficats en 4 bytes en big-endian. Seguidament venen els 20 bytes de hash SHA1 de la taula info_value del fitxer de metainformació, en cas de que els dos clients no donguin exactament el mateix hash, es talla la comunicació entre ells. En cas de que tot vagi bé s'envien 20 bytes més amb l'identificació del clients, en cas de que aquesta informació (l'id del client amb qui s'està comunicant) no aparegui a la informació sobre clients que havia donat el tracker, es talla la comunicació.

Tot seguit tenim el que és la comunicació en si entre peers, els missatges amb mida de cos cero són pings per fer saber i mantenir l'estat dels peers i s'envien cada dos minuts. En cas de que el cos del missatge tingui més d'un byte llavors cal mirar quin tipus de missatge es tracte:
  • 0 - Choke
  • 1 - Unchoke
  • 2 - Interested
  • 3 - Not Interested
  • 4 - Have: És un número que indica que s'ha acabat de transferir i comprovat la integritat d'un nou tros.
  • 5 - Bitfield: És un mapa de bits on cadascun indica quins trossos de fitxer s'ha enviat.
  • 6 - request: Bàsicament és una petició perquè li enviin un tros. De paràmetre té un index.
  • 7 - piece: Les dades en si del fitxer.
  • 8 - cancel: Demana per cancel·lar una transmissió.
A l'hora de baixar els trossos normalment els clients trien els trossos de forma aleatori, així s'aconsegueix que estranyament es donguin situacions d'inanició que són les quals en que hi ha alguns trossos del fitxer que només estiguin en un o poc clients, cosa que faria que en el cas que aquests paressin de pujar fitxers ningú podria tenir el fitxer complert. Això forma part del protocol oficial de Bittorrent, tot i que algunes implementacions intenten millorar aquest aspecte fent que els trossos menys continguts en global entre els clients siguin els que tenen més prioritat per ser enviats.

i bàsicament... és això :)

Jerga

Vinga va, una mica de paraulotes relacionades amb el tema:
  • p2p: Peer 2 Peer, d'un a l'altre, d'un punt a l'altre, d'una persona a una altre, bla bla bla
  • peer: Un punt (ordinador, màquina, persona...) que participa en una comunicació P2P
  • seed: En el món bittorrent seeder és una persona que permet que d'altres puguin obtenir el fitxer un cop ell/a ja el té. Per tant, que no borra el fitxer una vegada l'ha baixat, sinó que el continua compartint.
  • leecher: justament al revés que el seeder, una persona que no comparteix el fitxer, tant sols el baixa.
Links


No hay comentarios:

Publicar un comentario en la entrada

Comenta: