Idziemy dalej z naszym klientem torrenta który implementuje w Elixir. Jednak by posty o Elixir zawierały jak najwięcej elixir a jak najmniej czegoś innego, część teoretyczną jak mogę to przenoszę na osobne posty. I tak oto pewnie powstanie krótka seria postów o tym jak działa torrent, tylko po to by to od razu przedstawić zaimplementowane w Elixir. Chyba, zresztą już o tym wspominałem na blogu.

Ostatnią rzeczą jaką zrobiliśmy w Elixir to zaimplementowanie Bencoding (encoding i decoding), sposobu serializacji danych w BitTorrent. Dziś omówię strukturę pliku torrent, co z tych jest nam informacji potrzebne i dlaczego oraz do czego. Może się wydawać to dość proste, ale nie koniecznie tak jest.

Uwaga, przykłady torrent będą operować na plikach legalnych, przeważnie dystrybucjach linuxa. Nie zawsze jednak uda mi się znaleźć publicznie dostępny plik tak by zademonstrować to co chcę, więc pliki powszechnie dostępne mogą być przeze mnie lekko modyfikowane (o czym wspomnę).

Struktura pliku

Plik torrent to inaczej zakodowany słownik z wykorzystaniem bencodingu. Jego strukturę (przykładowy plik ubuntu) można przedstawić w następujący sposób:

d
    8:announce              39:http://torrent.ubuntu.com:6969/announce
    13:announce-list           
    l
        l
            39:http://torrent.ubuntu.com:6969/announce 
        e
        l
            44:http://ipv6.torrent.ubuntu.com:6969/announce
        e
    e
    7:comment               29:Ubuntu CD releases.ubuntu.com
    13:creation date        i1492077159e
    4:info
    d
        6:length            i1609039872e
        4:name              30:ubuntu-17.04-desktop-amd64.iso
        12:piece length     i524288e
        6:pieces            61380:...REMOVED...
    e
e

Jest to forma czytelna, normalnie jest to jedna linijka ciągłego tekstu, gdzie jedynie pieces rozbijają ją na wielolinijkowe arcydzieła.

Słownik pliku torrent

Jak pamiętamy z bencode, d odnosi się do słownika, l do listy, i do liczby a XX: do liczby liter w ciągu znaków, z tego możemy wyciągnąć następujące dane:

  • announce: url (protokół może być różny, w tym i UDP!) do trackera. Czyli serwisu do którego podpinają się wszystkie aplikacje klienckie i który wie co dany klient posiada już ściągniętego. Do tego jeszcze wrócimy.
  • announce-list: kiedyś, announce mogło zawierać listę adresów, to się teraz zmieniło i zamiast tego, jak chcemy podać listę zapasowych trackerów, to robimy to właśnie tutaj.  Podobnie jak powyżej, to może być dowolny protokół.
  • comment: komentarz, może być twórca tego torrentu albo informacja co to za torrent. Cokolwiek.
  • creation date: data w postaci czasu uniksowego, czyli czasu od początku 1970 roku.
  • created by: tego u nas brakuje, ale jest to imię/ksywka autora.
  • encoding: też tego nie ma, ale jest to kodowanie jako zostało użyte do wygenerowania pieces z info. O czym zaraz.
  • info: słownik zawierający informacje na temat pliku/plików jakie ten torrent zawiera – w tym w zależności od tego czy mamy jeden czy więcej plików zwracamy różne wartości

Jedynie announce i info są danymi wymaganymi. Wszystkie pozostałe są opcjonalne.

Słownik info

Domyślnie info zawiera:

  • private: flaga 0 lub 1. Jeżeli mamy 1 (czyli prywatny) to jdynym sposobem na to by trackers o nas wiedziało jest przez oficjalny tracker podany w annouce lub announce-list. Także to jest jedyny sposób otrzymania listy ludzi którzy też udostępniają plik. Przy 0, my możemy być dalej przekazywani jako klienci jak i uzyskiwać klientów z różnych źródeł, na przykład poprzez distributed hash tables.
  • piece length: liczbą bajtów w każdym piece, oprócz ostatniego, który może być mniejszy.
  • piecies: ciąg znaków połączonych 20 bajtowych haszy SHA1 – jeden hash per piece. Czyli, cały ten ciąg jest podzielny przez 20 :)

Przy czym, jedynie private jest opcjonalny. Pozostała parametry info są uzależnione od tego czy torrent tyczy jednego pliku czy kilku:

  • name: nazwa pliku który ściągamy, lub katalogu do którego mamy ściągane pliki zapisywać. Nasz klient NIE MUSI brać tego pod uwagę, choć parametr jest wymagany, to jego wartość jest jedynie poradą, której nie musimy wziąć pod uwagę.
  • (single) length: wielkość pliku w bajtach
  • (single) md5sum: 32 znakowy ciąg znaków hex odpowiadających sumie kontrolnej MD5. Pomaga zweryfikować integralność pliku.
  • (multi) files: słownik zawierający informacje o length, md5sum oraz path o którym warto napisać więcej.
    • path: lista która składa się na pełną ścieżkę do pliku wraz z nazwą pliku (ostatnim elementem listy). Czyli jeżeli mamy tylko nazwę pliku to wartość będzie l21:MOJ_PLIK.ROZSZERZENIEe, ale jak już mamy katalog, to będzie to wyglądało tak: l3:kat21:MOJ_PLIK.ROZSZERZENIEe co odpowiada kat\MOJ_PLIK.ROZSZERZENIE

Z tych jedynie md5sum jest opcjonalny.

Do czego te informacje są nam potrzebne?

Kilka rzeczy z miejsca się nasuwa:

  • Wiedza co oznaczają i co zawierają parametry, daje informacje co będzie trzeba zaimplementować. Na przykład tworzenie katalogów czy też obsługę weryfikacji pliku.
  • Daje nam tak samo pogląd co możemy pominąć i się w ogóle ty nie przejmować. Na przykład po co mamy robić weryfikację pliku za pomocą MD5 sum.
  • Informacje, gdzie mamy uderzyć by dostać dane do ściągnięcia.

Jedną rzeczą, która nie jest taka jasna to co dalej :) Kolejnym krokiem jest zbudowanie za pomocą danych które posiadamy zapytania do trackera po to by:

  • Zapisać się na listę klientów
  • Dostać listę klientów już zapisanych

Jest to jeden z ostatnich kroków przed pobraniem danych. Ale bez niego nie będziemy mogli nawet spróbować pobrać dane.

Podsumowanie

Dziś poznaliśmy w pełni strukturę danych pliku torrent oraz jesteśmy wstanie nakreślić kolejne kroki (zdobywania wiedzy jak i implementacji) w tym także funkcjonalność jaką aplikacja powinna mieć (tworzenie folderów, weryfikacji plików itp.). Jak na razie nic specjalnie trudnego a jednocześnie bardzo wartościowego (dla mnie i mojego projektu). Mam nadzieję, że też dla Ciebie.

Z ciekawostek jest to, że nie pisze o tym specyfikacja a jednak, trafiam na torrenty zawierające protokół UDP a nie HTTP przy announce. Co jest dość ważne, zobaczymy jak to nam pójdzie w implementacji.

1 KOMENTARZ

Comments are closed.