Ana içeriğe geç

Bölüm 18:Kapsülleme ve Başlıklar

11 dakikalık okumaGüncelleme:

Ağlar'a “Sen”i Katmak yazısının parçası: adres çubuğuna yazdığın tek bir isteğin peşinden bakırla fiberin fiziğine kadar inen uzun bir teknik yolculuk.

Tüm bölümler
  1. Giriş
  2. Adres Çubuğundan İsteğe
  3. Paket Anahtarlamalı Yol
  4. İsimden Adrese
  5. Önbellek, Tazelik ve Güven
  6. Port Numarası ve Soket
  7. Bağlantısız Taşıma: UDP
  8. Üç Adımlı El Sıkışma
  9. Simetrik Şifreleme
  10. Açık Anahtarlı Kriptografi
  11. TLS El Sıkışması
  12. Sertifika Zinciri
  13. HTTP Mesajının Anatomisi
  14. Durum, Çerez ve Oturum
  15. HTTP/2'den HTTP/3'e
  16. İçerik Dağıtım Ağları
  17. Diğer Uygulama Protokolleri
  18. Katmanlı Mimari
  19. Kapsülleme ve Başlıklar
  20. Paket Yakalama ve Çözümleme
  21. Ağ Arayüz Kartı
  22. Fiziksel Adresleme
  23. Hata Sezme ve CRC
  24. Adres Çözümleme: ARP
  25. Anahtarlama ve Ortam Erişimi
  26. Ağ Topolojileri
  27. Sanal Yerel Ağlar
  28. Kablosuz Erişim: 802.11
  29. Radyo Kanalı ve Kapasite
  30. Kablosuz Ağ Güvenliği
  31. Hücresel Ağlar
  32. Spektrum ve Kuşaklar
  33. Hareketlilik ve Aktarma
  34. Adres Kiralama: DHCP
  35. Adresin Anatomisi
  36. Adres Tükenmesi ve IPv6
  37. Yönlendirici Mimarisi
  38. Kuyruk Yönetimi
  39. Cihaz Yapılandırma
  40. Yönlendirme Protokolleri
  41. Kontrol Düzlemi ve SDN
  42. Ağ İzleme ve Yönetimi
  43. Alanlar Arası Yönlendirme
  44. Adres Çevirisi
  45. Ara Kutular
  46. Tünelleme ve IPsec
  47. Güvenlik Duvarları
  48. Operatör ve Metro Ağları
  49. Bitten Sinyale
  50. Çoklama Teknikleri
  51. İletim Ortamları
  52. Kablo Sonlandırma
  53. Fiber Optik İletim
  54. Bakır Erişim Ağı: DSL
  55. Pasif Optik Ağlar
  56. Kablo Erişim Ağları
  57. Denizaltı Kabloları
  58. Veri Merkezi Ağları
  59. Kapsülleme Çözme
  60. Güvenilir Aktarım
  61. Tıkanıklık Denetimi
  62. Trafik Çözümleme
  63. Gecikme Bütçesi
  64. Son Söz

Katmanların birbirine ne sözü verdiğini kurduk. Söylemediğim şey, komşuya tam olarak neyin uzatıldığıydı.

Uzatılan şey çıplak veri değil. Her katman kendisine geleni bir zarfa koyup uzatıyor, ve o zarfın adı başlık. Peki zarfın içinde kaç zarf var?

Dört basamak, tek yük

Uygulama katmanı elindeki mesajı taşımaya veriyor ve taşıma onu hiç açmıyor. İçindeki baytların ne anlama geldiğine bakmadan başına kendi başlığını ekliyor; ortaya bir segment çıkıyor.

Ağ katmanı aynı işi bir basamak aşağıda tekrarlıyor. Aldığı segmentin tamamını, taşımanın az önce yazdığı başlık dahil, tek parça yük sayıyor. Kendi başlığını onun da önüne ekliyor: datagram. Son basamak bağ katmanı; o da datagramı olduğu gibi alıp sarıyor ve ortaya çerçeve çıkıyor.

uygulama   [ mesaj ]
taşıma     [ TCP | mesaj ]                       ->  segment
ağ         [ IP  | TCP | mesaj ]                 ->  datagram
bağ        [ ETH | IP  | TCP | mesaj | FCS ]     ->  çerçeve

Kargo şirketine dönersek, her basamak yalnızca kendi etiketini yazar. Bir öncekinin etiketi artık paketin parçasıdır.

Aynı merdiveni baytlarla izlemek istersen:

Aynı yük, dört kat zarf
uygulamataşımabağmesaj · 1.460 bayt1.460 baytTCPmesaj · değişmedisegment · 1.480 baytIPTCPmesaj · değişmedidatagram · 1.500 baytETHIPTCPmesaj · değişmediFCSçerçeve · 1.518 bayttelde 8 bayt önsöz + 12 bayt boşluk → 1.538 bayt · verinin payı %94,9
Uygulama yalnızca mesajı görüyor. Tarayıcının sokete yazdığı şey 1.460 baytlık düz veri. Bu noktada hiçbir başlık yok; aşağıdaki üç satırda değişmeden kalacak olan yük bu.
  1. Uygulama yalnızca mesajı görüyor. Tarayıcının sokete yazdığı şey 1.460 baytlık düz veri. Bu noktada hiçbir başlık yok; aşağıdaki üç satırda değişmeden kalacak olan yük bu.
  2. Taşıma 20 bayt ekliyor: segment. TCP başlığı mesajın önüne geçiyor. İçine bakmıyor, açmıyor, yorumlamıyor — mesajın tamamı onun için tek parça yük. Toplam 1.480 bayt.
  3. Ağ 20 bayt daha ekliyor: datagram. IP başlığı bu kez TCP başlığını da yük sayıyor. (N)-PDU = (N−1)-SDU denklemi tam burada işliyor: bir üstün paketi, bir altın ham verisi. Toplam 1.500 bayt.
  4. Bağ hem baştan hem sondan sarıyor: çerçeve. Ethernet 14 baytlık başlığı öne, 4 baytlık FCS sağlamasını sona koyuyor. Sondan yazan tek katman bu. Toplam 1.518 bayt.
  5. Telde fatura biraz daha kabarıyor. Çerçevenin önüne 8 baytlık önsöz, arkasına 12 baytlık boşluk giriyor. Kanalda harcanan 1.538 baytın 1.460'ı veri: %94,9. Kutular ölçekli değil — gerçek oranda TCP başlığı bu genişliğin yedide biri kadar olurdu.

Son satırdaki FCS dikkatini çekmiş olmalı. Çerçeve hem başlıkla hem kuyrukla sarılıyor; sondan yazan tek katman bağ katmanı.

Her başlık, onu ekleyen katmanın kendi hizmetini kurmak için ihtiyaç duyduğu alanları taşıyor. Üstteki katman o alanları hiç görmüyor. Alttaki katman görüyor ama anlamlarını bilmiyor. Kapsülleme dediğimiz şey tam olarak bu.

Başlıkta tam olarak ne var?

Seçenek taşımayan bir TCP başlığı 20 bayt. Başlık sabit değil; içinde head len adında bir alan var ve başlığın kendi uzunluğunu bildiriyor, çünkü seçeneklerle uzayabiliyor. Yük kısmı da değişken uzunlukta; uygulamanın sokete yazdığı kadar.

Seçeneksiz IPv4 başlığı da 20 bayt. İkisi birlikte her yükün üstüne 40 baytlık sabit bir zarf bindiriyor.

IPv4 başlığını tahmin etmeye gerek yok; RFC 791 alanları bit bit sayıyor. Başlık 32 bitlik satırlar hâlinde okunur ve seçeneksiz hâli tam beş satırdır:

bitalanboyne yapıyor
0Sürüm4 bitIPv4 için değeri 4; alıcı başlığı okumadan önce buna bakar
4IHL4 bitbaşlığın kendi uzunluğu, 32 bitlik kelime cinsinden
8DSCP6 bitpaketin hangi hizmet sınıfına ait olduğu
14ECN2 bityol üstünde tıkanıklık görülüp görülmediği
16Toplam Uzunluk16 bitbaşlık dahil bütün datagram
32Kimlik16 bitaynı datagramdan doğan parçaları eşleştirir
48Bayraklar3 bitayrılmış · DF (bölme) · MF (arkadan parça var)
51Parça Ofseti13 bitparçanın özgün yükteki yeri, 8 baytlık birimle
64TTL8 bither yönlendiricide bir azalır, sıfırlanınca paket ölür
72Protokol8 bityükün sahibi: 1 ICMP, 6 TCP, 17 UDP
80Başlık Sağlaması16 bityalnızca başlığı korur, yükü değil
96Kaynak Adres32 bitgönderenin IP adresi
128Hedef Adres32 bitalıcının IP adresi
160Seçenekler0-40 baytyalnızca IHL beşten büyükse vardır

Dört alan ilk okumada kolayca kayıyor, oysa dördü de kitabın başka bölümlerinde karşına çıkacak.

IHL başlığın uzunluğunu bayt değil, 32 bitlik kelime cinsinden verir. Seçeneksiz başlıkta değeri 5’tir: 5 × 4 = 20 bayt. Alan 4 bit olduğu için en büyük değeri 15, yani başlığın tavanı 60 bayt. Seçeneklere ayrılabilecek yer bu yüzden 40 baytla sınırlı — bu bir tasarım tercihi değil, dört bitin matematiği.

DSCP ve ECN aslında tek bir 8 bitlik alandan bölündü. Eski adı Hizmet Türü’ydü; RFC 2474 üstteki altı biti hizmet sınıfına, RFC 3168 alttaki iki biti tıkanıklık bildirimine ayırdı. İlki paket zamanlamada, ikincisi tıkanıklık denetiminde işe yarıyor. İkisi de aynı bayttan çıkıyor.

Bayraklardaki DF biti “bu paketi bölme” demek. Bölmesi gereken bir yönlendirici DF bitini görürse paketi düşürüp gönderene bir ICMP mesajıyla haber verir ve o mesajın içinde bir sonraki atlamanın MTU’sunu yazar. Gönderen böylece yol boyunca sığacak en büyük boyu adım adım öğrenir; yöntemin adı yol MTU keşfi. O ICMP mesajları bir güvenlik duvarı tarafından susturulursa yöntem sessizce çöker; sahadaki hâlini tünelleri kurarken adım adım izleyeceğiz.

Başlık sağlaması yalnızca başlığı korur, yükü değil. Sebep basit: TTL her atlamada değiştiği için sağlamanın da her yönlendiricide yeniden hesaplanması gerekiyor, ve yükü de kapsasaydı bu hesap her atlamada bütün paket üstünde yapılacaktı. IPv6 alanı tamamen kaldırarak aynı sorunu kökünden çözdü.

Protokol alanı küçük ama işi büyük: yükün hangi üst katman protokolüne ait olduğunu söylüyor, TCP mi UDP mi.

Çerçevenin alanları da sırayla belli; boyları toplandığında zarfın maliyeti çıkıyor:

alanboyne yapıyor
önsöz8 baytalıcıyı çerçevenin başına kilitler
hedef adres6 baytçerçeveyi kimin alacağını söyler
kaynak adres6 baytgönderenin aynı biçimdeki adresi
tür alanı2 baytiçerideki protokolü söyler
veri46-1.500 baytdatagram buraya girer
FCS4 baytçerçevenin kuyruğu

Bu iki adresin nasıl kurulduğunu burada kasten boş bırakıyorum. Alanların genişliğini biliyorsun; içlerindeki değerin ne anlama geldiğini 21. bölümde dolduracağız.

Adresler, tür alanı ve FCS birlikte 18 bayt tutuyor. Önsöz (preamble) hariç azami sade çerçeve bu yüzden 1.518 bayt. Araya 4 baytlık bir 802.1Q etiketi girerse tavan 1.522 bayta çıkıyor; etiketin ilk iki baytı 0x8100 tür tanımlayıcısını taşır ve o tanımlayıcıyı bilmeyen bir istasyon çerçeveyi bilinmeyen tür sanıp atar.

Ethernet Type II çerçevesinin alan şeridi: 6 baytlık hedef ve kaynak adres, 2 baytlık EtherType alanı, 46-1500 baytlık veri alanı ve 4 baytlık CRC; şeridin toplamı 64 ile 1518 bayt arasında.

Tür alanı (EtherType) 0x0800 ise içeride IP var, 0x0806 ise ARP. FCS’nin içine yazılan değer ise bir CRC-32 sağlaması; hesabın kendisi ilerideki bir bölümün işi.

Her zarf bir sonrakini nasıl gösteriyor?

Kapsüllemenin asıl inceliği zarfları sarmakta değil, açarken hangi sırayla açılacağını bilmekte. Alıcıya gelen şey bir bayt dizisi. Nerede bittiğini, içinde ne olduğunu ve sonraki başlığın hangi protokole ait olduğunu ona kimse söylemiyor — bunların hepsi zarfın kendi içinde yazılı.

Her başlığın içinde, bir sonraki başlığın kim olduğunu söyleyen bir alan var. Bu alanlar bir zincir kuruyor ve zincir, bayt dizisini adım adım çözüyor:

bulunduğun başlıkişaretçi alanıdeğersonraki başlık
Ethernettür alanı0x0800IPv4
Ethernettür alanı0x0806ARP
Ethernettür alanı0x86DDIPv6
Ethernettür alanı0x8100VLAN etiketi, sonra yeniden tür alanı
IPv4 / IPv6protokol1 / 58ICMP
IPv4 / IPv6protokol6TCP
IPv4 / IPv6protokol17UDP
IPv4 / IPv6protokol47GRE tüneli
IPv4 / IPv6protokol50IPsec ESP
TCP / UDPhedef port443TLS, ardından HTTP
TCP / UDPhedef port53DNS

Zincirin bu kadar sıradan görünmesi aldatıcı. Bu üç alan, yığının tamamının değiştirilebilir olmasını sağlayan şey. Ethernet, içinde IP taşıdığını bilmiyor; yalnızca 0x0800 diye bir sayı taşıyor ve o sayının anlamını bir tabloya bırakıyor. IPv6 ortaya çıktığında Ethernet’in tek bir satırı bile değişmedi; tabloya yeni bir sayı eklendi. Katmanları gerçekten ayıran şey, başlıkta bir isim değil bir numara taşımaktır.

Zarfları açmanın adı kapsülleme çözme ve sarmanın tam tersi sırayla yürüyor. Alıcı kartı çerçeveyi alıyor, FCS’yi yeniden hesaplayıp yazandan farklı çıkarsa çerçeveyi sessizce atıyor. Sağlamsa 14 baytlık başlığı çıkarıp kalanı IP’ye uzatıyor. IP kendi başlığını doğruluyor, hedef adres kendisiyse başlığı çıkarıp protokol alanının gösterdiği yere — diyelim TCP’ye — uzatıyor. TCP checksum’ı denetliyor, hedef porta bakıp doğru sokete bırakıyor. Her kat kendi zarfını açıyor, kendi denetimini yapıyor ve bir üstteki katmanın zarfına hiç dokunmuyor.

Kapsüllemeyi tek cümleye indirmek gerekirse: her katman, bir üstündekinin verdiği her şeyi anlamsız bir yük sayar; ne olduğunu yalnızca bir sayıyla not eder ve o sayıyı okumayı karşı taraftaki eşine bırakır.

Yük hatta sığmazsa?

Bir bağlantı üzerinden gidebilecek en büyük çerçevenin veri alanına MTU deniyor. Ethernet’te 1.500 bayt. Bu bir ağ katmanı kararı değil, bağ katmanı kararı: değeri ikinci katmanda hangi protokolün çalıştığına göre değişiyor. Yol boyunca tek bir sabit değer yok.

Sayı yükseltilebilir de. Bir anahtar bugün 9.720 bayta kadar jumbo çerçeve taşıyabiliyor; aynı veriyi altı kat daha az çerçeveyle göndermek, çerçeve başına düşen 18 baytlık zarfı altı kat fazla verinin üstüne yaymak demek. Yine de bu yetenek standart dışı ve yerelde kalıyor. Sebebi yolun kendisinde. Bir yol, üstündeki en dar bağlantı kadar geniştir, ve yol üstündeki tek bir port jumbo çerçeveyi tanımıyorsa onu sessizce düşürüyor. Uçların birlikte büyütmeyi pazarlık edeceği bir mekanizma da yok; MTU her bağlantının kendi kararı. Büyük MTU bu yüzden ancak kapalı alanlarda işe yarıyor: veri merkezinin içi, depolama ağı, iki yönlendirici arasındaki tek bir hat. Oralarda iki uç da aynı yönetimin elinde.

Geriye kalanı hesaplamak kolay. 1.500 baytlık veri alanından IP başlığının 20 baytını ve TCP başlığının 20 baytını düşünce elde 1.460 bayt kalıyor. SYN paketiyle pazarlığa açılan en büyük segment boyunun tipik değeri de tam olarak bu.

Peki yük bu sınırı aşarsa? IPv4 datagramı bölüyor; işlemin adı parçalama. Her parça kendi başına tam bir IP datagramı ve kendi başlığını taşıyor.

Somut bir örnek kuralım. 2.048 baytlık bir datagramın yükü 2.028 bayt. MTU’su 1.500 olan bir bağlantıya girdiğinde ikiye ayrılıyor:

parça 1:  veri 1.480 bayt · ofset 0    · MF=1 · toplam uzunluk 1.500
parça 2:  veri   548 bayt · ofset 185  · MF=0 · toplam uzunluk   568

Parçaları birbirine bağlayan üç alan var ve üçü de IP başlığında duruyor. Kimlik, iki parçanın aynı datagramdan doğduğunu söylüyor. Bayrak alanındaki MF biti arkadan başka parça gelip gelmediğini bildiriyor. Ofset ise parçanın özgün veri alanındaki yerini veriyor, o da bayt cinsinden değil, 64 bitin yani 8 baytın katları cinsinden. 1.480’i sekize bölünce 185 çıkıyor. Son parça hariç her parçanın verisi bu yüzden sekizin katı olmak zorunda.

Bir ayrıntı daha: TCP başlığı yalnızca ilk parçada duruyor. IP bölerken yükün içine bakmıyor; ikinci parça onun için sıradan bir bayt dizisi.

Parçaları birleştiren tek yer hedef uç sistem. Bedeli şu: bir parça yol boyunca yalnızca küçülebiliyor. IPv6 bu işi sabit başlıktan çıkardı; 40 baytlık başlıkta ne parçalama var ne checksum, amaç yönlendiricide işlemeyi hızlandırmak. Gerekirse parçalama ayrı bir uzatma başlığına iniyor.

Bir terim notu da düşeyim. OSI belgelerinde bu işleme segmentation, TCP/IP belgelerinde fragmentation deniyor. İkisi aynı şeyi anlatıyor.

Zarfın bedeli ne kadar?

Tel üstünde bir yükün taşıdığı toplam zarf 58 bayt: 20 TCP, 20 IP, 18 Ethernet.

1.460 baytlık dolu bir yükle çerçeve 1.518 bayta çıkıyor ve zarfın payı %3,8 oluyor. Şimdi yükü küçült. İstek satırı ve başlıklarla kurulan sade bir HTTP isteği 480 bayt tutsun. Aynı 58 bayt ekleniyor, toplam 538 bayt, zarfın payı %10,8. Zarf hiç değişmedi. Yük küçüldükçe oransal olarak şişti.

Uç vakayı da görelim. Yüksüz bir ACK, 20 baytlık TCP başlığı ile 20 baytlık IP başlığından ibaret: 40 baytlık bir datagram. Ethernet veri alanının alt sınırı 46 bayt olduğu için aradaki fark dolgu ile kapatılıyor ve çerçeve 64 bayta çıkıyor. Telden geçen her şey zarf.

O dolgu baytları ağ katmanına kadar çıkıyor. Onları ayıklayan şey IP başlığındaki uzunluk alanı.

Kanalın ödediği fatura çerçeve boyuyla değil toplamla ölçülüyor. 1.500 baytlık veri taşıyan bir çerçevenin kanal maliyeti, önsöz ve çerçeveler arası boşluk dahil, 1.538 bayt. Yükün payı %97,5. 10 Mbit/s’lik bir hatta bu saniyede 812 çerçeve demek. Aynı hatta asgari boy çerçeveler saniyede 14.880 adet geçiyor ve yalnızca 5.475.840 bit veri taşıyor: kanalın %54,7’si.

Ek yükün bit karşılığı da sabit: 64 bit önsöz, 96 bit iki adres, 16 bit tür alanı, 32 bit FCS. 10 Mbit/s’te çerçeveler arası boşluk 9,6 µs, yani 96 bit süresi. Toplamı 304 bit süresi.

Küçük çerçevenin bir yararı da var. Bozulan bir çerçevede yeniden gönderilecek bit sayısı daha az. Çoklama ile tek bağlantıya sığdırılan istekler de aynı hesabın içinde; zarf yok olmuyor, yalnızca daha çok yükün üstüne yayılıyor.

Bütün bunları kendi makinende görebilirsin:

ip link show
sudo tcpdump -n -e -c 5 'tcp port 443'

İlk komut her arayüzün yanına mtu 1500 yazacak. İkincisi her satırın başında çerçevenin kaynak ve hedef adresini, ethertype IPv4 (0x0800) etiketini ve çerçevenin bayt cinsinden boyunu dökecek. Windows tarafında aynı değeri netsh interface ipv4 show subinterfaces komutu veriyor.

Özet

Peki, ne öğrendik?

  • Kapsülleme dört basamaklı bir merdiven: mesaj segmente, segment datagrama, datagram çerçeveye giriyor ve her basamak bir öncekinin tamamını yük sayıyor.
  • Her başlık kendi katmanının işi için var: üstteki alanları görmüyor, alttaki anlamlarını bilmiyor, ve sondan kuyruk ekleyen tek katman bağ katmanı.
  • IPv4 başlığı beş satır, on üç alandır: IHL başlığın tavanını 60 bayta kilitler, DSCP ile ECN aynı bayttan bölünmüştür, DF biti yol MTU keşfini başlatır ve checksum yalnızca başlığı korur.
  • Bağlayıcı alanlar zinciri kuruyor: çerçevedeki tür alanı, IP’deki Protokol ve taşımadaki port numarası yükü doğru üst katmana yönlendiriyor.
  • MTU aşılırsa datagram bölünüyor: Kimlik, Bayrak ve Ofset parçaları birbirine bağlıyor, birleştirmeyi ise yalnızca hedef uç yapıyor.

Zarfları saydık, alanlarını adlandırdık, bedelini hesapladık. Ama buraya kadar hepsi anlatı olarak kaldı. Zarflar gerçekten orada mı, bunu kendi gözünle görebilir misin?

19. bölüme devam et: Paket Yakalama ve Çözümleme