Ana içeriğe geç

Bölüm 72: Eşten Eşe ve Protokol Tasarımı

10 dakikalık okumaGüncelleme:

Ağlar'a “Sen”i Katmak kitabının bir bölümü: adres çubuğuna yazdığın tek bir isteğin peşinden bakırla fiberin fiziğine inip karşı taraftan geri dönen uzun bir teknik yolculuk.

Kısım 10: Uygulamayı Kendin Kurmak (Bölüm 71-72)

Tüm bölümler
  1. Giriş
  2. Adres Çubuğundan İsteğe
  3. Paket Anahtarlamalı Yol
  4. İsimden Adrese
  5. DNS Kayıtları
  6. Önbellek, Tazelik ve Güven
  7. Port Numarası ve Soket
  8. Bağlantısız Taşıma: UDP
  9. Üç Adımlı El Sıkışma
  10. Simetrik Şifreleme
  11. Açık Anahtarlı Kriptografi
  12. TLS El Sıkışması
  13. Sertifika Zinciri
  14. HTTP Mesajının Anatomisi
  15. Durum, Çerez ve Oturum
  16. HTTP/2'den HTTP/3'e
  17. İçerik Dağıtım Ağları
  18. Diğer Uygulama Protokolleri
  19. Katmanlı Mimari
  20. Hizmet ve Protokol
  21. Encapsulation ve Başlıklar
  22. Paket Yakalama ve Çözümleme
  23. Ağ Interface Kartı
  24. Fiziksel Adresleme
  25. Hata Sezme ve CRC
  26. Adres Çözümleme: ARP
  27. Ortam Erişimi: CSMA/CD
  28. Switch'ler
  29. Ağ Topolojileri
  30. Sanal Yerel Ağlar
  31. Kablosuz Erişim: 802.11
  32. Radyo Kanalı ve Kapasite
  33. Kablosuz Ağ Güvenliği
  34. Hücresel Ağlar
  35. Spektrum ve Kuşaklar
  36. Hareketlilik ve Aktarma
  37. Adres Kiralama: DHCP
  38. Adresin Anatomisi
  39. Adres Tükenmesi ve IPv6
  40. Router Mimarisi
  41. Kuyruk Yönetimi
  42. Cihaz Yapılandırma
  43. Routing Protokolleri
  44. Kontrol Düzlemi ve SDN
  45. Ağ İzleme ve Yönetimi
  46. Alanlar Arası Routing
  47. Adres Çevirisi
  48. Ara Kutular
  49. Tünelleme ve IPsec
  50. Firewall'lar
  51. Ağ Saldırıları
  52. Operatör ve Metro Ağları
  53. Bitten Sinyale
  54. Sembol Hızı ve Kanal Kapasitesi
  55. Multiplexing Teknikleri
  56. İletim Ortamları
  57. Bakır Kablo Sonlandırma
  58. Fiber Sonlandırma
  59. Fiber Optik İletim
  60. Bakır Erişim Ağı: DSL
  61. DSL'de Hız ve Mesafe
  62. Pasif Optik Ağlar
  63. Kablo Erişim Ağları
  64. Kablo Modem ve CMTS
  65. Denizaltı Kabloları
  66. Veri Merkezi Ağları
  67. Encapsulation Çözme
  68. Güvenilir Aktarım
  69. Tıkanıklık Denetimi
  70. Trafik Çözümleme
  71. Gecikme Bütçesi
  72. Soket Programlama
  73. Eşten Eşe ve Protokol Tasarımı
  74. Uyarlanır Video Akışı
  75. Gerçek Zamanlı Ses ve Görüntü
  76. Kablosuz Sensör Ağlarının Mimarisi
  77. Sensör Ağlarında Ortam Erişimi
  78. Sensör Ağlarında Yönlendirme ve IP
  79. Zaman Eşitleme ve Konum Bulma
  80. Sensör Ağı Uygulamaları
  81. Mobil Kablosuz Sensör Ağları
  82. Son Söz

O zaman her istemci aynı zamanda sunucu olurdu. Bir dosyayı indiren makine, elindeki parçaları başkalarına dağıtmaya da başlardı. Bu fikrin adı eşten eşe (peer-to-peer, kısaca P2P) ve internetin trafiğinde bir dönem en büyük payı o taşıdı.

Bu bölüm iki soruyu birlikte ele alıyor. Birincisi mimari: yük bir merkezde mi durmalı, katılan herkese mi dağılmalı? İkincisi tasarım: kendi uygulamanın protokolünü yazacaksan hangi kararları vermen gerekiyor? İkisi aynı yerde buluşuyor, çünkü mimari de bir tasarım kararı.

Önce hesap. Aynı dosyayı bin kişiye göndermek, tek sunucuyla ne kadar sürer ve eşler yardım ederse ne kadar?

İki mimari

Kitap boyunca izlediğin yol istemci-sunucu mimarisiydi. Sunucu hep açık, adresi sabit ve bütün istekler ona geliyor. İstemciler birbirini tanımıyor ve birbirleriyle hiç konuşmuyor. Talep artınca sunucu tarafı büyüyor: 65. bölümdeki veri merkezleri ve 16. bölümdeki kenar sunucuları bu büyümenin hâli.

Eşten eşe mimaride sabit bir merkez yok ya da çok az iş yapıyor. Eşler sıradan uç makineler: evdeki bilgisayarlar, telefonlar. Açılıp kapanıyorlar, adresleri değişiyor, çoğu 46. bölümdeki bir adres çeviricinin arkasında. Buna karşılık bir güçleri var: sisteme katılan her yeni eş hem talep hem kapasite getiriyor. İndiren aynı zamanda yüklüyor.

İkisinin arasında karma çözümler de var ve bugün en yaygını onlar. 74. bölümde göreceğin görüntülü görüşmelerde iki tarayıcıyı birbirine bir sunucu tanıştırıyor, ses ve görüntü ise mümkünse doğrudan eşler arasında akıyor.

Dağıtım süresinin hesabı

Boyu F olan bir dosyayı N eşe dağıtmak istiyorsun. Sunucunun yükleme hızı U. Hesabı sade tutmak için bütün eşleri eş hızlı sayalım: her biri u hızında yüklüyor, d hızında indiriyor. Aşağıdaki iki alt sınır, Kurose ve Ross’un ders kitabındaki akışkan modelden geliyor.

Tek sunucuyla. Sunucu N kopyanın her birini kendisi göndermek zorunda: N·F bit, U hızında. Ayrıca hiçbir eş dosyayı kendi indirme hızından hızlı alamaz:

D(istemci-sunucu) ≥ max( N·F / U ,  F / d )

Eşler yardım ederse. Sunucu dosyayı en az bir kez göndermek zorunda, eşler yine kendi indirme hızıyla sınırlı. Ama toplam N·F bitlik yükü artık sunucu ile bütün eşlerin yükleme hızı birlikte taşıyor:

D(eşten eşe) ≥ max( F / U ,  F / d ,  N·F / (U + N·u) )

Somut sayılarla bakalım. Dosya 1 GB, yani 8 Gbit. Sunucunun yükleme hızı 1 Gbit/s. Her eş 20 Mbit/s yüklüyor, 100 Mbit/s indiriyor.

Eş sayısıTek sunucuylaEşler yardım ederse
1080 s80 s
100800 s267 s
1.0008.000 s (2 saat 13 dakika)381 s
10.00080.000 s (22 saat)398 s

İlk sütun eş sayısıyla doğrusal büyüyor: on kat izleyici, on kat bekleme. İkinci sütun ise neredeyse yerinde sayıyor ve eş sayısı ne kadar artarsa artsın 400 saniyenin altında kalıyor. O tavan, dosyanın bir eşin yükleme hızıyla gönderilme süresi: 8 Gbit bölü 20 Mbit/s. Sisteme katılan her eş kendi payını getirdiği için talep ile kapasite birlikte büyüyor. Buna kendiliğinden ölçeklenme deniyor.

Hesabın dayandığı varsayımlar iyimser: her eş tam hızla yüklüyor, kimse ortadan kaybolmuyor, parçalar kusursuz dağıtılıyor. Gerçek sistemler bu alt sınıra ulaşmıyor ama eğrinin şekli aynı kalıyor. Bir ayrıntı da önemli. Ev hatlarında yükleme hızı indirmeden çok daha küçük; 59. ve 62. bölümde bu asimetriyi görmüştün. Eşten eşe sistemin bütün kapasitesi tam da bu dar yönden geliyor.

BitTorrent: parça, nadirlik, karşılıklılık

Hesaptaki “kusursuz dağıtım” varsayımına pratikte yaklaşmak için tasarlanmış en bilinen protokol BitTorrent. Bram Cohen 2001’de yayımladı; 2003’te yazdığı kısa makale, protokolün neden çalıştığını bir iktisat problemi olarak anlatıyor.

Dosya eşit boyda parçalara bölünüyor. Cohen’in makalesinde tipik parça 250 KB, bugün birkaç megabayta kadar çıkabiliyor. Her parçanın özeti, indirmeye başlamadan önce alınan küçük bir üst veri dosyasında duruyor. Bir eşten gelen parça özetiyle tutmuyorsa atılıyor; bozuk ya da sahte parça dağıtan eş hemen fark ediliyor. İstekler ise parçanın kendisi için değil, 16 KB’lık alt parçalar için yapılıyor. Aynı anda birkaç istek yolda tutuluyor, böylece bir parçanın farklı alt parçaları farklı eşlerden gelebiliyor.

Hangi parçanın önce isteneceği, sistemin sağlığını belirleyen karar. Kural önce en nadiri: eş, komşularında en az kopyası bulunan parçayı öncelikle istiyor. Nadir parçalar böylece hızla çoğalıyor ve dosyanın tamamını taşıyan eşler ayrıldığında bile hiçbir parça kaybolmuyor. Yarım kalmış bir parçayı bitirmek her şeyden önce geliyor. Sonuna gelindiğinde ise kalan alt parçalar birden çok eşten aynı anda isteniyor ki son baytlar tek bir yavaş eşi beklemesin.

Geriye teşvik sorusu kalıyor: kimse yüklemek zorunda değilken herkes neden yüklesin? Cevap karşılıklılık (tit-for-tat). Her eş, kendisine en hızlı yükleyen dört komşusuna yükleme yapıyor ve bu seçimi her 10 saniyede yeniliyor. Geri kalanlara kapısı kapalı; bunun adı choke. Bir de her 30 saniyede bir, rastgele seçilen bir eşe karşılık beklemeden kapıyı açıyor. Bu iyimser açılış iki işe yarıyor: elinde henüz hiçbir parça olmayan yeni gelen başlayabiliyor, eş de daha iyi bir komşuyu tesadüfen keşfedebiliyor. Bir dakika boyunca tek parça göndermeyen komşu ise “beni yüzüstü bıraktı” sayılıyor ve sıradan yükleme listesinden çıkıyor.

DerinleşmeKarşılıklılık gerçekten herkesi dürüst tutuyor mu?

Tit-for-tat, oyun kuramındaki tutsak ikilemi deneylerinden geliyor: ilk hamlede iş birliği yap, sonra karşındakinin son hamlesini tekrarla. BitTorrent’teki iyimser açılış, “ilk hamlede iş birliği” kuralının ta kendisi.

2007’de yayımlanan bir çalışma, bu düzenin stratejik bir istemciye karşı sağlam olmadığını gösterdi. Araştırmacıların yazdığı BitTyrant, her komşuya karşılık almaya yetecek en düşük hızla yüklüyor ve artan kapasiteyi daha fazla komşuya dağıtıyordu. Gerçek sürülerde 1 Mbit/s hattaki bir istemci için ortanca hız kazancı %70 oldu. Aynı çalışma ikinci bir şey daha gösterdi: herkes böyle davranırsa sürünün ortalama performansı düşüyor.

Tasarım dersi şu: teşvik mekanizması herkesin dürüst olmasını değil, dürüst olmamanın pahalı olmasını hedefler. BitTorrent’in düzeni bunu çoğu zaman sağlıyor ama kusursuz sağlamıyor.

Merkezsiz dizin: DHT

Parçaları kimin taşıdığını nereden öğreniyorsun? İlk kuşak P2P sistemleri bu soruya iki uç cevap verdi. 1999’da açılan Napster, hangi kullanıcıda hangi şarkının olduğunu merkezi bir dizinde tutuyordu. Dosyalar kullanıcılar arasında gidiyordu ama arama merkezdeydi; mahkeme kararıyla o merkez kapanınca, Temmuz 2001’de, bütün sistem durdu. 2000’de çıkan Gnutella ise merkezi tamamen kaldırdı. Her arama komşulara, onlardan da onların komşularına yayılıyor ve bir yaşam süresi (TTL) dolunca duruyordu. Tek bir kapanma noktası yoktu ama her arama ağı sel gibi basıyordu.

Üçüncü yol dağıtık hash tablosu (distributed hash table, DHT). Bugün BitTorrent’in izleyicisiz çalışan hâli, 2002’de yayımlanan Kademlia tasarımını kullanıyor.

Fikir şu. Hem düğümlerin kimlikleri hem aranan anahtarlar aynı 160 bitlik sayı uzayında. Bir anahtar, kimliği o anahtara “en yakın” düğümlerde saklanıyor. Kademlia yakınlığı XOR ile ölçüyor: iki kimliği bit bit XOR’la, çıkan sayı aradaki uzaklık. Dört bitlik bir örnek:

Kimlik AKimlik BA XOR BUzaklık
0110011100011
0110010000102
0110111010008

Soldan ilk farklı bit, uzaklığın büyüklüğünü belirliyor. En anlamlı bitte ayrışan iki kimlik birbirine en uzak olanlar.

Her düğüm, uzaklığın her büyüklük basamağı için en fazla k tane komşu tutuyor; makalede k = 20. Bu listelere k-bucket deniyor. Bir düğüm bir anahtarı ararken elindeki en yakın üç düğüme aynı anda soruyor, her cevapla hedefe en az bir bit daha yaklaşıyor ve kimse daha yakın birini söyleyemeyince duruyor. Adım sayısı düğüm sayısının logaritmasıyla büyüyor: 16 milyon düğümlük bir ağda bile en kötü durumda 24 adım.

Bir tasarım ayrıntısı da çok şey anlatıyor. Kova dolduğunda Kademlia yeni geleni değil, eskiyi tutuyor; eski düğüm hâlâ cevap veriyorsa yeni aday reddediliyor. Gerekçe ölçüme dayanıyor: uzun süredir ayakta olan bir düğümün bir saat daha ayakta kalma olasılığı, yeni gelenden yüksek. Aynı kural saldırganın sahte düğümlerle bir kovayı doldurmasını da zorlaştırıyor.

Bu yapının BitTorrent’teki karşılığı Mainline DHT ve 2013’teki ölçümler aynı anda 16 ile 28 milyon arasında düğüm gösteriyordu. Bir magnet bağlantısının asıl taşıdığı şey dosyanın özeti; eşleri bulmak için bu ağa soruluyor. Artık “dosya nerede?” diye değil, “şu içeriği kim taşıyor?” diye aranıyor. Ad, içeriğin kendisinden türetiliyor.

NAT’ın arkasındaki eş

Eşlerin çoğu evden bağlanıyor ve 46. bölümdeki adres çeviricisi dışarıdan başlatılan bağlantıları içeri almıyor. Bu yüzden BitTorrent’te dışarıya bağlantı kurabilen ama içeriden bağlantı kabul edemeyen eşler de çalışıyor; yalnızca daha az komşu bulabiliyorlar. İki NAT’ın arkasındaki eşlerin birbirine nasıl ulaştığını, yani delik açmayı, 46. bölümde görmüştün.

Eşten eşe trafiğin ikinci bir sorunu daha vardı. Ev modemlerinin tamponları gönderim hızına göre çok büyük; birkaç saniyelik paketi tutabiliyorlar. Arka planda yükleme yapan bir istemci bu tamponu dolduruyor ve aynı hattaki bir görüntülü görüşme saniyelerce gecikmeye başlıyor. 40. bölümdeki bufferbloat bu durumun genel adı.

BitTorrent’in cevabı kendi taşımasını yazmak oldu. uTP, UDP üstünde çalışan ve tıkanıklığı kayıptan değil gecikmeden anlayan bir protokol. Tek yönlü gecikme artmaya başladığı anda hızını düşürüyor. Arkasındaki algoritma 2012’de LEDBAT adıyla RFC 6817 oldu ve hedefi, kendi yarattığı kuyruk gecikmesini 100 milisaniyenin altında tutmak. 68. bölümdeki tıkanıklık denetimleri adil payını almaya çalışıyordu. Bu ise kasten geri çekilen, yalnızca kimsenin kullanmadığı kapasiteyi alan bir taşıma.

Bir protokol tasarlarken verilen kararlar

Şimdi kendi uygulamanı tasarladığını düşün. Kitaptaki her protokol, şimdiye kadar gördüklerin de sonraki bölümlerde göreceklerin de, aşağıdaki kararları bir biçimde veriyor:

KararSeçeneklerKitaptaki örnekler
mimariistemci-sunucu, eşten eşe, karmaweb ile BitTorrent; görüntülü görüşme karma
taşımaTCP, UDP, QUICbütünlük, zamanlama ve hız istekleri (17. bölüm)
mesaj biçimimetin ya da ikiliHTTP/1.1 ve SMTP metin; DNS, TLS ve HTTP/2 ikili
çerçevelemeayraç, uzunluk öneki, kendini anlatan gövde71. bölüm
durumdurumsuz ya da oturumluHTTP durumsuz, oturumu çerez taşıyor (14. bölüm)
etkileşimistek-yanıt, sunucunun itmesi, yayın-aboneHTTP istek-yanıt; WebSocket iter; MQTT yayın-abone (77. bölüm)
adlandırmayere göre ya da içeriğe göreURL yer söyler, BitTorrent içeriğin özetini ad yapar
genişletmesürüm alanı, uzantı noktalarıTLS uzantıları, HTTP başlıkları
güvenlikbaştan mı sonradan mıTLS kendi başına bir katman; QUIC şifrelemeyi içine aldı (15. bölüm)

Bu kararların çoğu bir ödünleşim. Metin biçimli bir protokol okunaklı ve nc ile elle konuşulabilir; ikili biçim daha sıkı ve ayrıştırması daha az hataya açık. Durumsuz bir sunucu kolay ölçeklenir ama her isteğin kendini tanıtması gerekir. Sunucunun itmesi gecikmeyi düşürür ama açık bağlantı tutmanın bedelini sunucuya yükler. Web’de itmenin yaygın yolu WebSocket: sıradan bir HTTP isteğiyle başlayıp iki yönlü, açık kalan bir kanala dönüşen bağlantı.

Tabloda en çok hafife alınan satır genişletme. Bir protokolün ilk sürümü, ikincisinin nasıl ekleneceğini baştan düşünmediyse ikinci sürüm hiç gelmeyebilir. 15. bölümde yol üstündeki kutuların tanımadıkları alanları gördüklerinde bağlantıyı düşürdüğünü, bu yüzden yeni protokollerin eski protokol kılığına girmek zorunda kaldığını görmüştün. Bu kemikleşmeye karşı bulunan çare ilginç: GREASE (RFC 8701). İstemciler uzantı listelerine anlamsız, rastgele değerler ekliyor. Tanımadığı değeri görünce çöken bir sunucu, gerçek bir yeni uzantı gelmeden önce ortaya çıkıyor. Uzantı noktası kullanıldıkça paslanmıyor.

Derinleşme"Kabul ettiğinde hoşgörülü ol" ilkesi neden sorgulanıyor?

Jon Postel 1980’de IP ve TCP’nin erken belirtimlerine bir cümle koydu: gönderdiğinde tutucu, kabul ettiğinde hoşgörülü ol. Yani standarda harfiyen uyan paketler üret, ama karşıdan gelen kusurlu paketi anlamı açıksa kabul et. Bu sağlamlık ilkesi kırk yıl boyunca internet mühendisliğinin atasözü oldu.

2023’te internet mimarisini gözeten kurul IAB, RFC 9413 ile bu ilkenin bedelini yazdı. Belgenin ilk taslaklarının adı açık sözlüydü: sağlamlık ilkesinin zararlı sonuçları. Mekanizma şöyle işliyor. Hoşgörülü bir alıcı kusurlu bir göndericiyi sessizce kabul ediyor. Kusur hiç düzeltilmiyor, çünkü kimse şikâyet etmiyor. Zamanla o kusurlu davranış fiilî standarda dönüşüyor ve sonraki her yazılım onu da kabul etmek zorunda kalıyor. Belirtim ile gerçek davranış arasındaki mesafe açıldıkça güvenlik açıkları o mesafede yaşıyor. İki ayrıştırıcının aynı mesajı farklı okuması, istek kaçakçılığı gibi saldırıların kaynağı.

RFC 9413’ün önerisi hoşgörüyü tamamen bırakmak değil. Protokolü etkin biçimde bakımda tutmak: beklenmedik durumları gizlemek yerine görünür kılmak, geçici toleransları kalıcı hâle getirmemek. Kitabın bu sayfasına kadar gördüğün protokollerin çoğu da gerçekten böyle yaşıyor. Yayımlandıkları günden sonra onlarca yıl boyunca yeni RFC’lerle yamalanıyorlar.

Özet

  • Eşten eşe mimaride talep ile kapasite birlikte büyür: bin eşe 1 GB dağıtmak tek sunucuyla 2 saati aşarken eşlerin yardımıyla 7 dakikanın altına iner.
  • BitTorrent dosyayı özetli parçalara böler: önce en nadir parçayı ister, bozuk parçayı özetinden yakalar.
  • Teşvik karşılıklılıkla kurulur: en hızlı dört komşuya yükle, her 10 saniyede yenile, her 30 saniyede bir yabancıya şans ver.
  • DHT merkezi dizini ortadan kaldırır: Kademlia XOR uzaklığıyla her aramayı log N adımda bitirir ve ad olarak içeriğin özetini kullanır.
  • Protokol tasarımı bir kararlar dizisidir: mimari, taşıma, biçim, çerçeveleme, durum, etkileşim, adlandırma, genişletme ve güvenlik. En çok hafife alınanı genişletme.

BitTorrent’te parçaların hangi sırayla geldiği önemsizdi; dosya ancak tamamlanınca açılıyor. Film izlerken ise sıra her şey: şu an oynayan saniyenin ardından bir sonraki saniye gelmek zorunda. İnerken oynayan bir videonun kaç megabitle ineceğine kim karar veriyor?

73. bölüme devam et: Uyarlanır Video Akışı