UDP Trackery

Proposal 160
Zavřeno
Author zzz
Created 2022-01-03
Last Updated 2025-06-25
Target Version 0.9.67

Stav

Schváleno při kontrole 2025-06-24. Specifikace je na UDP specification. Implementováno v zzzot 0.20.0-beta2. Implementováno v i2psnark od API 0.9.67. Zkontrolujte dokumentaci dalších implementací pro stav.

Přehled

Tento návrh je pro implementaci UDP trackerů v I2P.

Change History

Předběžný návrh pro UDP trackery v I2P byl zveřejněn na naší stránce specifikace bittorrent v květnu 2014; tento návrh předcházel našemu formálnímu procesu návrhů a nikdy nebyl implementován. Tento návrh byl vytvořen začátkem roku 2022 a zjednodušuje verzi z roku 2014.

Jelikož tento návrh spoléhá na odpověditelné datagramy, byl pozastaven, jakmile jsme začali pracovat na návrhu Datagram2 na začátku roku 2023. Tento návrh byl schválen v dubnu 2025.

Verze tohoto návrhu z roku 2023 specifikovala dva režimy, “kompatibilní” a “rychlý”. Další analýza odhalila, že rychlý režim by byl nezabezpečený a také by byl neefektivní pro klienty s velkým počtem torrentů. Navíc BiglyBT vyjádřil preferenci pro kompatibilní režim. Tento režim bude jednodušší implementovat pro jakýkoli tracker nebo klient podporující standardní BEP 15.

Zatímco režim kompatibility je komplexnější na implementaci od nuly na straně klienta, máme pro něj předběžný kód, který jsme začali vyvíjet v roce 2023.

Proto byla současná verze zde dále zjednodušena pro odstranění rychlého režimu a odstranění termínu “kompatibilita”. Současná verze přechází na nový formát Datagram2 a přidává odkazy na protokol UDP announce rozšíření BEP 41.

Také je do odpovědi na připojení přidáno pole životnosti ID připojení, aby se rozšířily výkonnostní zisky tohoto protokolu.

Motivation

Jak se uživatelská základna obecně a počet uživatelů bittorrentu konkrétně nadále zvyšuje, potřebujeme učinit trackery a oznámení efektivnějšími, aby trackery nebyly přetížené.

Bittorrent navrhl UDP trackery v BEP 15 BEP 15 v roce 2008 a drtivá většina trackerů na clearnetu nyní používá pouze UDP.

Je obtížné vypočítat úspory šířky pásma u datagramů oproti streamovacímu protokolu. Odpověditelnýá žádost má přibližně stejnou velikost jako streamovací SYN, ale payload je asi o 500 bajtů menší, protože HTTP GET má obrovský 600bajtový řetězec URL parametrů. Samotná odpověď je mnohem menší než streamovací SYN ACK, což poskytuje významné snížení odchozího provozu trackeru.

Kromě toho by mělo dojít k implementačně specifickým úsporám paměti, protože datagramy vyžadují mnohem méně stavu v paměti než streamovací spojení.

Post-kvantové šifrování a podpisy podle návrhu v /en/proposals/169-pq-crypto/ podstatně zvýší režii šifrovaných a podepsaných struktur, včetně destinací, leaseSets, streaming SYN a SYN ACK. Je důležité tuto režii minimalizovat všude, kde je to možné, než bude PQ kryptografie v I2P přijata.

Motivace

Tento návrh používá repliable datagram2, repliable datagram3 a raw datagramy, jak jsou definovány v /en/docs/spec/datagrams/. Datagram2 a Datagram3 jsou nové varianty repliable datagramů, definované v Návrhu 163 /en/proposals/163-datagram2/. Datagram2 přidává ochranu proti replay útokům a podporu offline podpisů. Datagram3 je menší než starý formát datagramu, ale bez autentifikace.

BEP 15

Pro referenci je tok zpráv definovaný v BEP 15 následující:

Client                        Tracker
    Connect Req. ------------->
      <-------------- Connect Resp.
    Announce Req. ------------->
      <-------------- Announce Resp.
    Announce Req. ------------->
      <-------------- Announce Resp.

Fáze připojení je vyžadována pro zabránění IP address spoofingu. Tracker vrací connection ID, které klient používá v následujících announce zprávách. Toto connection ID vyprší ve výchozím nastavení za jednu minutu u klienta a za dvě minuty u trackeru.

I2P bude používat stejný tok zpráv jako BEP 15, pro snadné přijetí ve stávajících kódových základnách klientů schopných UDP: kvůli efektivitě a z bezpečnostních důvodů diskutovaných níže:

Client                        Tracker
    Connect Req. ------------->       (Repliable Datagram2)
      <-------------- Connect Resp.   (Raw)
    Announce Req. ------------->      (Repliable Datagram3)
      <-------------- Announce Resp.  (Raw)
    Announce Req. ------------->      (Repliable Datagram3)
      <-------------- Announce Resp.  (Raw)
             ...

Toto potenciálně poskytuje značné úspory šířky pásma oproti streamovacím (TCP) oznámením. Zatímco Datagram2 má přibližně stejnou velikost jako streamovací SYN, surová odpověď je mnohem menší než streamovací SYN ACK. Následující požadavky používají Datagram3 a následující odpovědi jsou surové.

Požadavky na announce jsou Datagram3, takže tracker nemusí udržovat velkou mapovací tabulku ID připojení k announce cíli nebo hash. Místo toho může tracker generovat ID připojení kryptograficky z hash odesílatele, aktuálního časového razítka (založeného na určitém intervalu) a tajné hodnoty. Když je přijat požadavek na announce, tracker validuje ID připojení a poté použije hash odesílatele Datagram3 jako cíl pro odeslání.

Historie změn

Pro integrovanou aplikaci (router a klient v jednom procesu, například i2psnark a ZzzOT Java plugin), nebo pro aplikaci založenou na I2CP (například BiglyBT), by mělo být jednoduché implementovat a směrovat streaming a datagram provoz odděleně. ZzzOT a i2psnark by měly být první tracker a klient, které tento návrh implementují.

Neintegrované trackery a klienti jsou probrány níže.

Trackers

Existují čtyři známé implementace I2P trackerů:

  • zzzot, integrovaný Java router plugin, běžící na opentracker.dg2.i2p a několika dalších
  • tracker2.postman.i2p, běžící pravděpodobně za Java routerem a HTTP Server tunelem
  • Starý C opentracker, portovaný uživatelem zzz, s komentovanou UDP podporou
  • Nový C opentracker, portovaný uživatelem r4sas, běžící na opentracker.r4sas.i2p a možná dalších, běžící pravděpodobně za i2pd routerem a HTTP Server tunelem

Pro externí tracker aplikaci, která v současnosti používá HTTP server tunnel pro příjem announce požadavků, by mohla být implementace poměrně obtížná. Mohl by být vyvinut specializovaný tunnel pro překlad datagramů na lokální HTTP požadavky/odpovědi. Nebo by mohl být navržen specializovaný tunnel, který zpracovává jak HTTP požadavky, tak datagramy a který by předával datagramy externímu procesu. Tato návrhová rozhodnutí budou silně záviset na konkrétních implementacích routeru a trackeru a jsou mimo rozsah tohoto návrhu.

Clients

Externí SAM-based torrent klienti jako qbittorrent a další klienti založené na libtorrent by vyžadovali SAM v3.3, které není podporováno v i2pd. To je také vyžadováno pro podporu DHT a je dostatečně složité na to, aby to žádný známý SAM torrent klient neimplementoval. Žádné SAM-based implementace tohoto návrhu se neočekávají v blízké době.

Connection Lifetime

BEP 15 specifikuje, že connection ID vyprší za jednu minutu u klienta a za dvě minuty u trackeru. Není to konfigurovatelné. To omezuje potenciální zisky v efektivitě, pokud by klienti nesdružovali announces, aby je všechny provedli v rámci jednominutového okna. i2psnark v současnosti announces nesdružuje; rozkládá je v čase, aby se vyhnul nárazům provozu. Pokročilí uživatelé údajně provozují tisíce torrentů najednou a soustředění tolika announces do jedné minuty není realistické.

Zde navrhujeme rozšířit odpověď připojení o volitelné pole životnosti připojení. Výchozí hodnota, pokud není přítomna, je jedna minuta. V opačném případě bude klientem použita životnost specifikovaná v sekundách a tracker bude udržovat ID připojení o jednu minutu déle.

Compatibility with BEP 15

Tento design zachovává kompatibilitu s BEP 15 co nejvíce, aby omezil změny požadované v existujících klientech a trackerech.

Jedinou požadovanou změnou je formát informací o peerech v announce response. Přidání pole lifetime v connect response není povinné, ale je důrazně doporučeno kvůli efektivitě, jak je vysvětleno výše.

BEP 15

Důležitým cílem UDP announce protokolu je zabránit padělání adres. Klient musí skutečně existovat a obsahovat skutečný leaseset. Musí mít příchozí tunely pro příjem Connect Response. Tyto tunely by mohly být zero-hop a vybudované okamžitě, ale to by odhalilo tvůrce. Tento protokol tohoto cíle dosahuje.

Podpora Tracker/Client

  • Tento návrh nepodporuje blinded destinations, ale může být rozšířen, aby tak činil. Viz níže.

Návrh

Protocols and Ports

Repliable Datagram2 používá I2CP protokol 19; repliable Datagram3 používá I2CP protokol 20; raw datagramy používají I2CP protokol 18. Požadavky mohou být Datagram2 nebo Datagram3. Odpovědi jsou vždy raw. Starší repliable datagram (“Datagram1”) formát používající I2CP protokol 17 NESMÍ být používán pro požadavky nebo odpovědi; tyto musí být zahozeny, pokud jsou přijaty na request/reply portech. Poznámka: Datagram1 protokol 17 je stále používán pro DHT protokol.

Požadavky používají I2CP “to port” z announce URL; viz níže. “From port” požadavku je zvolen klientem, ale měl by být nenulový a jiný port než ty používané DHT, aby mohly být odpovědi snadno klasifikovány. Trackery by měly odmítat požadavky přijaté na nesprávném portu.

Odpovědi používají I2CP “to port” z požadavku. “From port” požadavku je “to port” z požadavku.

Announce URL

Formát announce URL není specifikován v BEP 15, ale stejně jako na clearnetu mají UDP announce URL formu “udp://host:port/path”. Cesta je ignorována a může být prázdná, ale na clearnetu je typicky “/announce”. Část :port by měla být vždy přítomna, avšak pokud je část “:port” vynechána, použij výchozí I2CP port 6969, protože to je běžný port na clearnetu. Mohou být také připojeny cgi parametry &a=b&c=d, ty mohou být zpracovány a poskytnuty v announce požadavku, viz BEP 41. Pokud nejsou žádné parametry nebo cesta, koncové / může být také vynecháno, jak je naznačeno v BEP 41.

Životnost připojení

Všechny hodnoty jsou odesílány v síťovém bajtovém pořadí (big endian). Neočekávejte, že pakety budou mít přesně určitou velikost. Budoucí rozšíření by mohla zvětšit velikost paketů.

Connect Request

Klient ke trackeru. 16 bajtů. Musí být repliable Datagram2. Stejné jako v BEP 15. Žádné změny.

Offset  Size            Name            Value
  0       64-bit integer  protocol_id     0x41727101980 // magic constant
  8       32-bit integer  action          0 // connect
  12      32-bit integer  transaction_id

Connect Response

Tracker ke klientovi. 16 nebo 18 bajtů. Musí být raw. Stejné jako v BEP 15 kromě níže uvedených poznámek.

Offset  Size            Name            Value
  0       32-bit integer  action          0 // connect
  4       32-bit integer  transaction_id
  8       64-bit integer  connection_id
  16      16-bit integer  lifetime        optional  // Change from BEP 15

Odpověď MUSÍ být odeslána na I2CP “to port”, který byl přijat jako “from port” požadavku.

Pole lifetime je volitelné a udává životnost connection_id klienta v sekundách. Výchozí hodnota je 60 a minimum, pokud je specifikováno, je 60. Maximum je 65535 nebo přibližně 18 hodin. Tracker by měl udržovat connection_id o 60 sekund déle než je životnost klienta.

Announce Request

Klient na tracker. Minimálně 98 bajtů. Musí být repliable Datagram3. Stejné jako v BEP 15 kromě případů uvedených níže.

connection_id je takové, jak bylo přijato v odpovědi connect.

Offset  Size            Name            Value
  0       64-bit integer  connection_id
  8       32-bit integer  action          1     // announce
  12      32-bit integer  transaction_id
  16      20-byte string  info_hash
  36      20-byte string  peer_id
  56      64-bit integer  downloaded
  64      64-bit integer  left
  72      64-bit integer  uploaded
  80      32-bit integer  event           0     // 0: none; 1: completed; 2: started; 3: stopped
  84      32-bit integer  IP address      0     // default
  88      32-bit integer  key
  92      32-bit integer  num_want        -1    // default
  96      16-bit integer  port
  98      varies          options     optional  // As specified in BEP 41

Změny oproti BEP 15:

  • klíč je ignorován
  • port je pravděpodobně ignorován
  • Sekce options, pokud je přítomna, je definována v BEP 41

Odpověď MUSÍ být odeslána na I2CP “to port”, který byl přijat jako “from port” požadavku. Nepoužívejte port z announce požadavku.

Announce Response

Tracker ke klientovi. Minimálně 20 bajtů. Musí být surový. Stejné jako v BEP 15 kromě níže uvedených poznámek.

Offset  Size            Name            Value
  0           32-bit integer  action          1 // announce
  4           32-bit integer  transaction_id
  8           32-bit integer  interval
  12          32-bit integer  leechers
  16          32-bit integer  seeders
  20   32 * n 32-byte hash    binary hashes     // Change from BEP 15
  ...                                           // Change from BEP 15

Změny oproti BEP 15:

  • Namísto 6-bajtové IPv4+port nebo 18-bajtové IPv6+port vracíme násobek 32-bajtových “kompaktních odpovědí” s binárními SHA-256 hashy peerů. Stejně jako u TCP kompaktních odpovědí nezahrnujeme port.

Odpověď MUSÍ být odeslána na I2CP “to port”, který byl přijat jako “from port” požadavku. Nepoužívejte port z announce požadavku.

I2P datagramy mají velmi velkou maximální velikost přibližně 64 KB; nicméně pro spolehlivé doručení by se mělo vyhnout datagramům větším než 4 KB. Pro efektivní využití šířky pásma by trackery pravděpodobně měly omezit maximální počet peerů na přibližně 50, což odpovídá přibližně 1600 bajtovému paketu před režijními náklady na různých vrstvách a mělo by se vejít do limitu dvou-tunnel-message payload po fragmentaci.

Stejně jako v BEP 15, není zde uveden počet adres peerů (IP/port pro BEP 15, zde hashe), které následují. Ačkoliv to není v BEP 15 zamýšleno, mohl by být definován značkovač konce peerů obsahující samé nuly, který by indikoval, že informace o peerech jsou kompletní a následují nějaká rozšiřující data.

Aby bylo rozšíření možné v budoucnosti, klienti by měli ignorovat 32-bajtový hash složený ze samých nul a jakákoli data, která následují. Trackery by měly odmítat oznámení od hash složeného ze samých nul, ačkoli tento hash je již zakázán Java routery.

Scrape

Scrape request/response z BEP 15 není tímto návrhem vyžadován, ale může být implementován podle potřeby, nejsou nutné žádné změny. Klient musí nejprve získat connection ID. Scrape request je vždy repliable Datagram3. Scrape response je vždy raw.

Trackery

Tracker ke klientovi. Minimálně 8 bajtů (pokud je zpráva prázdná). Musí být raw. Stejné jako v BEP 15. Žádné změny.

Offset  Size            Name            Value
  0       32-bit integer  action          3 // error
  4       32-bit integer  transaction_id
  8       string          message

Extensions

Rozšiřující bity nebo pole verze nejsou zahrnuty. Klienti a trackery by neměli předpokládat, že pakety budou mít určitou velikost. Tímto způsobem lze přidat další pole bez narušení kompatibility. Pokud je to vyžadováno, doporučuje se formát rozšíření definovaný v BEP 41.

Odpověď na připojení je upravena tak, aby přidala volitelnou životnost ID připojení.

Pokud je vyžadována podpora blinded destination, můžeme buď přidat blinded 35-bajtovou adresu na konec announce požadavku, nebo požadovat blinded hashe v odpovědích pomocí formátu BEP 41 (parametry budou určeny později). Sada blinded 35-bajtových peer adres by mohla být přidána na konec announce odpovědi po 32-bajtovém hashi sestávajícím ze samých nul.

Implementation guidelines

Viz sekci návrhu výše pro diskusi výzev pro neintegrované, non-I2CP klienty a trackery.

Kompatibilita s BEP 15

Pro daný hostname trackeru by měl klient upřednostnit UDP před HTTP URL a neměl by oznamovat na obě.

Klienti s existující podporou BEP 15 by měli vyžadovat pouze malé úpravy.

Pokud klient podporuje DHT nebo jiné datagramové protokoly, měl by pravděpodobně vybrat jiný port jako „zdrojový port" požadavku, aby se odpovědi vrátily na tento port a nepomíchaly se s DHT zprávami. Klient přijímá pouze surové datagramy jako odpovědi. Trackery nikdy nepošlou klientovi odpověditelný datagram2.

Klienti s výchozím seznamem opentrackerů by měli aktualizovat seznam a přidat UDP URL poté, co je známo, že známé opentrackery podporují UDP.

Klienti mohou nebo nemusí implementovat opakované odesílání požadavků. Opakovaná odesílání, pokud jsou implementována, by měla používat počáteční timeout nejméně 15 sekund a zdvojnásobit timeout pro každé opakované odeslání (exponenciální backoff).

Klienti se musí stáhnout po obdržení chybové odpovědi.

Analýza bezpečnosti

Trackery s existující podporou BEP 15 by měly vyžadovat pouze malé úpravy. Tento návrh se liší od návrhu z roku 2014 v tom, že tracker musí podporovat příjem repliable datagram2 a datagram3 na stejném portu.

Pro minimalizaci požadavků na zdroje trackeru je tento protokol navržen tak, aby eliminoval jakýkoli požadavek na to, aby tracker ukládal mapování hashů klientů na ID připojení pro pozdější validaci. To je možné, protože paket žádosti o oznámení je odpovídatelný Datagram3 paket, takže obsahuje hash odesílatele.

Doporučená implementace je:

  • Definovat současnou epochu jako aktuální čas s rozlišením doby života spojení, epoch = now / lifetime.
  • Definovat kryptografickou hashovací funkci H(secret, clienthash, epoch), která generuje 8bajtový výstup.
  • Vygenerovat náhodnou konstantu secret použitou pro všechna spojení.
  • Pro connect odpovědi vygenerovat connection_id = H(secret, clienthash, epoch)
  • Pro announce požadavky validovat přijaté connection ID v současné epoše ověřením connection_id == H(secret, clienthash, epoch) || connection_id == H(secret, clienthash, epoch - 1)

Migration

Stávající klienti nepodporují UDP announce URL a ignorují je.

Stávající trackery nepodporují příjem odpověditelných nebo surových datagramů, tyto budou zahozeny.

Tento návrh je zcela volitelný. Ani klienti, ani trackery nejsou povinny jej kdykoli implementovat.

Rollout

První implementace se očekávají v ZzzOT a i2psnark. Budou použity pro testování a ověření tohoto návrhu.

Další implementace budou následovat podle potřeby po dokončení testování a ověření.