Genel Bakış
Bu spesifikasyon, I2P’de UDP bittorrent duyurularının protokolünü belgeler. I2P’de bittorrent’in genel spesifikasyonu için, BitTorrent over I2P bölümüne bakın. Bu spesifikasyonun geliştirilmesine ilişkin arka plan ve ek bilgi için, Proposal 160 bölümüne bakın.
Tasarım
Bu teklif, Datagrams belgesinde tanımlandığı şekliyle repliable datagram2, repliable datagram3 ve ham datagramları kullanır. Datagram2 ve Datagram3, Proposal 163 belgesinde tanımlanan repliable datagramların yeni varyantlarıdır. Datagram2, tekrar saldırısı direnci ve çevrimdışı imza desteği ekler. Datagram3, eski datagram formatından daha küçüktür ancak kimlik doğrulama özelliği yoktur.
BEP 15
Referans olarak, BEP 15 ’te tanımlanan mesaj akışı aşağıdaki gibidir:
Client Tracker
Connect Req. ------------->
<-------------- Connect Resp.
Announce Req. ------------->
<-------------- Announce Resp.
Announce Req. ------------->
<-------------- Announce Resp.
Bağlantı aşaması, IP adresi sahtekarlığını önlemek için gereklidir. Tracker, istemcinin sonraki duyurularda kullandığı bir bağlantı kimliği döndürür. Bu bağlantı kimliği varsayılan olarak istemcide bir dakika, tracker’da ise iki dakika sonra sona erer.
I2P, mevcut UDP özellikli istemci kod tabanlarında benimsenme kolaylığı, verimlilik ve aşağıda tartışılan güvenlik nedenleri için BEP 15 ile aynı mesaj akışını kullanacaktır:
Client Tracker
Connect Req. -------------> (Repliable Datagram2)
<-------------- Connect Resp. (Raw)
Announce Req. -------------> (Repliable Datagram3)
<-------------- Announce Resp. (Raw)
Announce Req. -------------> (Repliable Datagram3)
<-------------- Announce Resp. (Raw)
...
Bu, streaming (TCP) duyurularına göre potansiyel olarak büyük bir bant genişliği tasarrufu sağlar. Datagram2, streaming SYN ile yaklaşık aynı boyutta olsa da, ham yanıt streaming SYN ACK’dan çok daha küçüktür. Sonraki istekler Datagram3 kullanır ve sonraki yanıtlar hamdır.
Duyuru istekleri Datagram3 şeklindedir, böylece tracker’ın bağlantı ID’lerinden duyuru hedefine veya hash’e kadar büyük bir eşleme tablosunu sürdürmesi gerekmez. Bunun yerine, tracker bağlantı ID’lerini gönderen hash’inden, mevcut zaman damgasından (belirli bir aralığa dayalı) ve gizli bir değerden kriptografik olarak üretebilir. Bir duyuru isteği alındığında, tracker bağlantı ID’sini doğrular ve ardından Datagram3 gönderen hash’ini gönderim hedefi olarak kullanır.
Bağlantı Ömrü
BEP 15 , bağlantı ID’sinin istemcide bir dakika, tracker’da iki dakika sonra sona erdiğini belirtir. Bu yapılandırılabilir değildir. Bu durum, istemciler tüm duyurularını bir dakikalık pencere içinde toplu olarak yapmadığı sürece potansiyel verimlilik kazançlarını sınırlar. i2psnark şu anda duyuruları toplu yapmıyor; trafik patlamalarını önlemek için bunları dağıtıyor. Güçlü kullanıcıların aynı anda binlerce torrent çalıştırdığı bildiriliyor ve bu kadar çok duyuruyu bir dakikaya sıkıştırmak gerçekçi değil.
Burada, bağlantı yanıtını isteğe bağlı bir bağlantı ömrü alanı eklemek için genişletmeyi öneriyoruz. Mevcut değilse varsayılan değer bir dakikadır. Aksi takdirde, saniye cinsinden belirtilen ömür istemci tarafından kullanılacak ve tracker, bağlantı ID’sini bir dakika daha fazla süreyle koruyacaktır.
BEP 15 ile Uyumluluk
Bu tasarım, mevcut istemciler ve tracker’larda gerekli değişiklikleri sınırlamak için BEP 15 ile mümkün olduğunca uyumluluk sağlar.
Tek gerekli değişiklik, announce yanıtındaki peer bilgilerinin formatıdır. Connect yanıtına lifetime alanının eklenmesi zorunlu değildir ancak yukarıda açıklandığı gibi verimlilik için şiddetle önerilir.
Güvenlik Analizi
Bir UDP duyuru protokolünün önemli bir hedefi adres sahteciliğini önlemektir. İstemci gerçekten var olmalı ve gerçek bir leaseSet paketlemelidir. Connect Response’u almak için gelen tunnel’lara sahip olmalıdır. Bu tunnel’lar sıfır atlama olabilir ve anında oluşturulabilir, ancak bu yaratıcıyı açığa çıkarır. Bu protokol bu hedefi gerçekleştirir.
Sorunlar
- Bu protokol blinded destinations’ı desteklemez, ancak desteklemek için genişletilebilir. Aşağıya bakınız.
Spesifikasyon
Protokoller ve Portlar
Repliable Datagram2, I2CP protokol 19’u kullanır; repliable Datagram3, I2CP protokol 20’yi kullanır; ham datagramlar I2CP protokol 18’i kullanır. İstekler Datagram2 veya Datagram3 olabilir. Yanıtlar her zaman hamdır. I2CP protokol 17 kullanan eski repliable datagram (“Datagram1”) formatı istekler veya yanıtlar için kullanılmamalıdır; bunlar istek/yanıt portlarında alınırsa bırakılmalıdır. Datagram1 protokol 17’nin hala DHT protokolü için kullanıldığını unutmayın.
İstekler, duyuru URL’sinden I2CP “to port” kullanır; aşağıya bakın. İstek “from port” istemci tarafından seçilir, ancak sıfır olmayan ve DHT tarafından kullanılanlardan farklı bir port olmalıdır, böylece yanıtlar kolayca sınıflandırılabilir. Tracker’lar yanlış portta alınan istekleri reddetmelidir.
Yanıtlar, istekten gelen I2CP “to port” değerini kullanır. İsteğin “from port” değeri, istekten gelen “to port” değeridir.
Duyuru URL’si
Announce URL formatı BEP 15
’te belirtilmemiştir, ancak clearnet’te olduğu gibi, UDP announce URL’leri udp://host:port/path formatındadır. Path yok sayılır ve boş olabilir, ancak clearnet’te tipik olarak /announce‘dir. :port kısmı her zaman mevcut olmalıdır, ancak :port kısmı atlanırsa, varsayılan I2CP portu olan 6969’u kullanın, çünkü bu clearnet’te yaygın porttur. Ayrıca &a=b&c=d şeklinde cgi parametreleri eklenebilir, bunlar işlenebilir ve announce isteğinde sağlanabilir, bkz. BEP 41
. Parametre veya path yoksa, sondaki / de atlanabilir, BEP 41
‘de ima edildiği gibi.
Datagram Formatları
Tüm değerler ağ bayt sıralamasında (big endian) gönderilir. Paketlerin tam olarak belirli bir boyutta olmasını beklemeyin. Gelecekteki uzantılar paketlerin boyutunu artırabilir.
Bağlantı İsteği
İstemciden tracker’a. 16 bayt. Yanıtlanabilir Datagram2 olmalıdır. BEP 15 ’teki ile aynı. Değişiklik yok.
| 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 |
Tracker’dan istemciye. 16 veya 18 bayt. Ham olmalı. Aşağıda belirtilenler dışında BEP 15 ile aynı.
| 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 |
Lifetime alanı isteğe bağlıdır ve connection_id istemci yaşam süresini saniye cinsinden belirtir. Varsayılan değer 60’tır ve belirtilirse minimum değer 60’tır. Maksimum değer 65535 veya yaklaşık 18 saattir. Tracker, connection_id’yi istemci yaşam süresinden 60 saniye daha fazla süreyle korumalıdır.
Duyuru İsteği
İstemciden tracker’a. Minimum 98 bayt. Yanıtlanabilir Datagram3 olmalı. Aşağıda belirtilen durumlar dışında BEP 15 ile aynı.
connection_id, bağlantı yanıtında alınan değerdir.
| 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, unused in I2P |
| 88 | 32-bit integer | key | |
| 92 | 32-bit integer | num_want | -1 // default |
| 96 | 16-bit integer | port | // must be same as I2CP from port |
| 98 | varies | options | optional // As specified in BEP 41 |
- key göz ardı edilir
- IP adresi kullanılmaz
- port muhtemelen göz ardı edilir ancak I2CP from port ile aynı olmalıdır
- Seçenekler bölümü, mevcutsa, BEP 41 ‘de tanımlandığı gibidir
Yanıt, istek “from port” olarak alınan I2CP “to port"una gönderilmelidir. Duyuru isteğindeki portu kullanmayın.
Duyuru Yanıtı
Tracker’dan istemciye. Minimum 20 bayt. Ham veri olmalıdır. Aşağıda belirtilenler dışında BEP 15 ile aynıdır.
| 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 |
- 6-byte IPv4+port veya 18-byte IPv6+port yerine, SHA-256 ikili peer hash’leri ile 32-byte’ın katları şeklinde “kompakt yanıtlar” döndürürüz. TCP kompakt yanıtlarında olduğu gibi, bir port dahil etmeyiz.
Yanıt, istek “from port"u olarak alınan I2CP “to port"una gönderilmelidir. Duyuru isteğindeki portu kullanmayın.
I2P datagramları yaklaşık 64 KB’lık çok büyük bir maksimum boyuta sahiptir; ancak güvenilir teslimat için 4 KB’dan büyük datagramlardan kaçınılmalıdır. Bant genişliği verimliliği için, tracker’lar muhtemelen maksimum peer sayısını yaklaşık 50 ile sınırlamalıdır; bu da çeşitli katmanlardaki overhead öncesi yaklaşık 1600 baytlık bir pakete karşılık gelir ve parçalanma sonrası iki tunnel mesajı yük sınırı içinde olmalıdır.
BEP 15’te olduğu gibi, takip edecek peer adreslerinin (BEP 15 için IP/port, burada hash’ler) sayısını içeren bir sayım bulunmaz. BEP 15’te düşünülmemiş olsa da, peer bilgisinin tamamlandığını ve bazı ek verilerin takip ettiğini belirtmek için tamamı sıfırlardan oluşan bir peer-sonu işaretçisi tanımlanabilir.
Gelecekte genişletmenin mümkün olması için, istemciler 32-baytlık tamamı sıfır olan hash’i ve onu takip eden herhangi bir veriyi görmezden gelmelidir. Tracker’lar tamamı sıfır olan hash’den gelen duyuruları reddetmelidir, ancak bu hash zaten Java router’lar tarafından yasaklanmıştır.
Kazıma
BEP 15 ’ten scrape isteği/yanıtı bu spesifikasyon tarafından gerekli değildir, ancak istenirse uygulanabilir, herhangi bir değişiklik gerekmez. İstemci önce bir bağlantı kimliği edinmelidir. Scrape isteği her zaman yanıtlanabilir Datagram3’tür. Scrape yanıtı her zaman ham’dır.
Hata Yanıtı
Tracker’dan istemciye. Minimum 8 bayt (mesaj boşsa). Ham olmalıdır. BEP 15 ’teki ile aynı. Değişiklik yok.
| Offset | Size | Name | Value |
|---|---|---|---|
| 0 | 32-bit integer | action | 3 // error |
| 4 | 32-bit integer | transaction_id | |
| 8 | string | message |
Uzantı bitleri veya sürüm alanı dahil edilmez. İstemciler ve tracker’lar paketlerin belirli bir boyutta olduğunu varsaymamalıdır. Bu şekilde, uyumluluğu bozmadan ek alanlar eklenebilir. Gerekirse BEP 41 ‘de tanımlanan uzantı formatı önerilir.
Bağlantı yanıtı, isteğe bağlı bir bağlantı kimliği ömrü eklemek için değiştirildi.
Blinded destination desteği gerekiyorsa, announce isteğinin sonuna blinded 35-byte adresini ekleyebiliriz veya BEP 41 formatını kullanarak yanıtlarda blinded hash’leri isteyebiliriz (parametreler henüz belirlenmedi). Blinded 35-byte peer adreslerinin kümesi, tamamen sıfır olan 32-byte hash’ten sonra announce yanıtının sonuna eklenebilir.
Uygulama Kılavuzları
Entegre olmayan, I2CP olmayan istemciler ve tracker’lar için zorlukların tartışılması için yukarıdaki tasarım bölümüne bakın.
İstemciler
Belirli bir tracker hostname için, istemci HTTP URL’leri yerine UDP’yi tercih etmeli ve her ikisine birden announce yapmamalıdır.
Mevcut BEP 15 desteğine sahip istemciler yalnızca küçük değişiklikler gerektirecektir.
Bir istemci DHT veya diğer datagram protokollerini destekliyorsa, muhtemelen istek “kaynak portu” olarak farklı bir port seçmelidir, böylece yanıtlar o porta geri gelir ve DHT mesajları ile karışmaz. İstemci sadece yanıt olarak ham datagramlar alır. Tracker’lar istemciye asla yanıtlanabilir bir datagram2 göndermez.
Varsayılan opentracker listesine sahip istemciler, bilinen opentracker’ların UDP’yi desteklediği bilindiğinde UDP URL’lerini eklemek için listeyi güncellemelidir.
İstemciler isteklerin yeniden iletimini uygulayabilir veya uygulamayabilir. Yeniden iletimler, eğer uygulanırsa, en az 15 saniye başlangıç zaman aşımı kullanmalı ve her yeniden iletim için zaman aşımını ikiye katlamalıdır (üstel geri çekilme).
İstemciler bir hata yanıtı aldıktan sonra geri çekilmelidir.
Takipçiler
Mevcut BEP 15 desteğine sahip tracker’lar yalnızca küçük değişiklikler gerektirecektir. Bu spesifikasyon 2014 önerisinden farklıdır, çünkü tracker aynı port üzerinde repliable datagram2 ve datagram3 alımını desteklemek zorundadır.
Tracker kaynak gereksinimlerini minimize etmek için, bu protokol tracker’ın daha sonra doğrulama için istemci hash’lerinin bağlantı kimliklerine eşlemelerini saklaması gerekliliğini ortadan kaldırmak üzere tasarlanmıştır. Bu mümkündür çünkü announce isteği paketi yanıtlanabilir bir Datagram3 paketidir, dolayısıyla gönderenin hash’ini içerir.
Önerilen bir uygulama şudur:
- Mevcut epoch’u bağlantı ömrü çözünürlüğü ile mevcut zaman olarak tanımla,
epoch = now / lifetime. - 8 byte çıktı üreten bir kriptografik hash fonksiyonu
H(secret, clienthash, epoch)tanımla. - Tüm bağlantılar için kullanılan rastgele sabit secret’ı üret.
- Connect yanıtları için,
connection_id = H(secret, clienthash, epoch)üret - Announce istekleri için, mevcut epoch’ta alınan connection ID’yi
connection_id == H(secret, clienthash, epoch) || connection_id == H(secret, clienthash, epoch - 1)doğrulayarak geçerli kıl
Referanslar
- [BEP15] BEP 15 - UDP Tracker Protocol
- [BEP41] BEP 41 - UDP Tracker Protocol Extensions
- [DATAGRAMS] Datagrams Spesifikasyonu
- [Prop160] Öneri 160 - UDP Trackers
- [Prop163] Öneri 163 - Datagram2/Datagram3
- [SAMv3] SAM v3 API
- [SPEC] I2P üzerinde BitTorrent