İçeriğe geç
academia.sh

Ders 03 / 18

Kapsülleme ve Başlıklar

Verinin katmanlar boyunca sarmalanması, IPv4 başlığının alanları, başlık sağlaması hesabı ve başlık yükünün verim üzerindeki etkisi.

İçindekiler

Önceki iki ders katmanların sorumluluklarını ayırdı. Katmanlar arasındaki alışverişin somut biçimi ise henüz açılmadı: bir katman, üstündeki katmandan aldığı veriyi tam olarak ne yapar?

Yanıt tek kelimeyle verilebilir: sarmalar. Her katman, üstünden gelen veriye kendi denetim bilgisini ekleyip altındaki katmana teslim eder. Bu dersin sorusu, bu sarmalamanın alan alan neye benzediği ve kaça mal olduğudur.

Kapsülleme

Kapsülleme (encapsulation), bir katmanın üstünden aldığı veriyi kendi başlığıyla sararak alt katmana vermesidir. Üst katmandan gelen veri, alt katman için anlamsız bir bayt dizisidir — yük (payload) olarak adlandırılır. Alt katman yükün içeriğini yorumlamaz; yalnızca taşır.

192.168.10.196 adresli istemcinin 100 baytlık bir uygulama isteği gönderdiğini varsayalım. Sarmalama aşağı doğru şöyle ilerler:

Katman Eklenen başlık Sonuçtaki boyut Birimin adı
Uygulama 100 bayt Veri
Taşıma (TCP) 20 bayt 120 bayt Segment
İnternet (IPv4) 20 bayt 140 bayt Datagram
Bağlantı (Ethernet) 14 bayt başlık + 4 bayt kuyruk 158 bayt Çerçeve

Alıcıda süreç tersine işler. Kapsülleme çözme (decapsulation) her katmanda kendi başlığını okuyup çıkarır ve kalan yükü üst katmana verir. Bu simetri, katmanlı modelin gerçekleştirimdeki karşılığıdır: gönderen tarafta bir yığın, alıcı tarafta aynanın öbür yüzü.

Bağlantı katmanının eklediği 4 baytlık kuyruk, başlık değil kuyruk (trailer) olarak adlandırılır: çerçeve denetim dizisi, üzerinde hesaplandığı verinin sonunda bulunmalıdır.

Katman Nereye Teslim Edeceğini Nasıl Bilir

Kapsülleme çözerken her katman, yükü hangi üst katman protokolüne vereceğine karar vermek zorundadır. Bu karar için her başlıkta bir çoğullama anahtarı bulunur:

Katman Alan Örnek değer Anlamı
Ethernet Tür (EtherType) 0x0800 Yük bir IPv4 datagramıdır
Ethernet Tür 0x86DD Yük bir IPv6 datagramıdır
Ethernet Tür 0x0806 Yük bir adres eşleme mesajıdır
IPv4 Protokol 6 Yük bir TCP segmentidir
IPv4 Protokol 17 Yük bir UDP datagramıdır
IPv4 Protokol 1 Yük bir ICMP mesajıdır
TCP / UDP Hedef bağlantı noktası 443 Yükü alacak yerel uygulama

Bu zincir olmadan kapsülleme çözme mümkün olmazdı: alıcı, elindeki bayt dizisinin ne olduğunu ancak bir önceki başlığın söylediği kadar bilir.

IPv4 Başlığı

IPv4 başlığı seçeneksiz hâlde 20 bayttır ve 32 bitlik beş sözcükten oluşur:

Bit aralığı Alan Genişlik İşlev
0–3 Sürüm 4 bit IPv4 için 4
4–7 Başlık uzunluğu (IHL) 4 bit 32 bitlik sözcük sayısı, en az 5
8–15 Hizmet türü 8 bit Öncelik ve tıkanıklık bildirimi
16–31 Toplam uzunluk 16 bit Başlık dahil datagram boyu
32–47 Kimlik 16 bit Parçaların hangi datagrama ait olduğu
48–50 Bayraklar 3 bit Parçalanmasın / parça devam ediyor
51–63 Parça ofseti 13 bit Yükün başlangıç konumu (8 baytlık birim)
64–71 Yaşam süresi (TTL) 8 bit Kalan sekme hakkı
72–79 Protokol 8 bit Yükün türü
80–95 Başlık sağlaması 16 bit Yalnız başlık üzerinde hata sezme
96–127 Kaynak adresi 32 bit Gönderen
128–159 Hedef adresi 32 bit Alıcı

Üç alan özellikle dikkat ister. Başlık uzunluğu, sözcük sayısıdır: değeri 5 ise başlık 5×4=205 \times 4 = 20 bayttır. Parça ofseti bayt değil 8 baytlık birim sayar; 13 bit ile 8×8191=655288 \times 8191 = 65\,528 bayta kadar konum gösterilebilir. Başlık sağlaması yalnızca başlığı korur, yükü korumaz — yükün bütünlüğü üst katmanın işidir.

Başlığı Bit Düzeyinde Kurmak

Alanların bit hizalaması, Bilgisayarlar Nasıl Çalışır kursundaki Bit Düzeyi İşlemler dersinde tanıtılan kaydırma ve maskeleme işlemleriyle kurulur. Sürüm ve başlık uzunluğu aynı bayta sığdırılır: sürüm dört bit sola kaydırılır, uzunluk ile birleştirilir.

Aşağıdaki program, örnek ağdaki istemciden 198.51.100.20 adresine giden boş bir TCP segmentinin IPv4 başlığını kurar ve geri okur.

import ipaddress
import struct


def baslik_saglamasi(veri: bytes) -> int:
    """16 bitlik sözcüklerin bire tümleyen toplamının tümleyeni."""
    toplam = 0
    for i in range(0, len(veri), 2):
        toplam += (veri[i] << 8) + veri[i + 1]
    while toplam >> 16:                       # taşan biti geri ekle
        toplam = (toplam & 0xFFFF) + (toplam >> 16)
    return ~toplam & 0xFFFF


def ipv4_baslik(kaynak: str, hedef: str, toplam_uzunluk: int,
                kimlik: int, ttl: int, protokol: int) -> bytes:
    surum_ihl = (4 << 4) | 5                  # sürüm 4, başlık 5 sözcük = 20 bayt
    bayrak_ofset = (0b010 << 13) | 0          # parçalanmasın (DF), ofset 0
    ham = struct.pack(
        "!BBHHHBBH4s4s",
        surum_ihl, 0, toplam_uzunluk, kimlik, bayrak_ofset, ttl, protokol, 0,
        ipaddress.ip_address(kaynak).packed,
        ipaddress.ip_address(hedef).packed,
    )
    c = baslik_saglamasi(ham)
    return ham[:10] + struct.pack("!H", c) + ham[12:]


baslik = ipv4_baslik("192.168.10.196", "198.51.100.20",
                     toplam_uzunluk=40, kimlik=7238, ttl=64, protokol=6)

print(baslik.hex())
print("uzunluk:", len(baslik), "bayt")
print("sağlama denetimi:", baslik_saglamasi(baslik))

alan = struct.unpack("!BBHHHBBH4s4s", baslik)
print("sürüm       :", alan[0] >> 4)
print("başlık boyu :", (alan[0] & 0x0F) * 4, "bayt")
print("toplam boy  :", alan[2], "bayt")
print("kimlik      :", alan[3])
print("bayraklar   :", format(alan[4] >> 13, "03b"))
print("parça ofseti:", alan[4] & 0x1FFF)
print("TTL         :", alan[5])
print("protokol    :", alan[6])
print("sağlama     :", hex(alan[7]))
print("kaynak      :", ipaddress.ip_address(alan[8]))
print("hedef       :", ipaddress.ip_address(alan[9]))

Çıktı:

450000281c464000400628d6c0a80ac4c6336414
uzunluk: 20 bayt
sağlama denetimi: 0
sürüm       : 4
başlık boyu : 20 bayt
toplam boy  : 40 bayt
kimlik      : 7238
bayraklar   : 010
parça ofseti: 0
TTL         : 64
protokol    : 6
sağlama     : 0x28d6
kaynak      : 192.168.10.196
hedef       : 198.51.100.20

struct biçim dizesindeki ! öneki ağ bayt sırasını, yani büyük uçlu düzeni seçer. Bilgisayarlar Nasıl Çalışır kursundaki Bayt Sırası dersinde tanıtılan bu düzen, protokol başlıklarında zorunludur: gönderen ve alıcı makinelerin iç bayt sıraları farklı olabilir, tel üzerindeki sıra ise tektir.

Onaltılık çıktının ilk baytı 45’tir: yüksek yarım bayt 4 sürümü, düşük yarım bayt 5 başlık uzunluğunu verir. Sonraki iki bayt 0028, yani 40 — toplam uzunluk. 4000 değerinin ilk üç biti 010, “parçalanmasın” bayrağıdır.

Başlık Sağlaması

Sağlama, 16 bitlik sözcüklerin bire tümleyen toplamının tümleyenidir. Hesaplama sırasında sağlama alanının kendisi sıfır kabul edilir. while toplam >> 16 döngüsü, 16 biti taşan kısmı toplamın altına geri ekler; bu adım bire tümleyen aritmetiğinin gereğidir.

Doğrulamanın zarafeti şuradadır: alıcı, sağlama alanı dolu başlık üzerinde aynı hesabı yaptığında sıfır elde etmelidir. Yukarıdaki çıktıda sağlama denetimi: 0 satırı bunu gösterir. Bu sayede alıcının ayrı bir karşılaştırma yapmasına gerek kalmaz.

Yöntemin gücü sınırlıdır: sözcük sırası değişirse toplam değişmez, dolayısıyla bu hata sezilemez. Bilinçli değişikliklere karşı hiçbir koruma sağlamaz. Yine de ucuzdur ve TTL her sekmede değiştiği için sağlamanın her yönlendiricide yeniden hesaplanması gerekir — maliyetin düşük tutulması bir tasarım koşuludur.

Başlık Yükünün Oranı

Her başlık, taşınabilecek veriden yer çalar. Yük oranı (overhead), bu payın büyüklüğünü verir. Ethernet çerçevesinin 18 baytlık sabit maliyeti (14 başlık + 4 kuyruk), IPv4’ün 20 baytı ve TCP’nin 20 baytı toplanınca 58 bayt eder.

Uygulama verisi Çerçeve boyu Verim oranı
100 bayt 158 bayt %63,29
500 bayt 558 bayt %89,61
1460 bayt 1518 bayt %96,18

Oran, veri boyu büyüdükçe hızla iyileşir. Bu, ağ programlamasındaki temel bir kuralın sayısal gerekçesidir: küçük yazma işlemlerini biriktirip tek seferde göndermek, aynı veriyi parça parça göndermekten belirgin biçimde verimlidir.

Tel üzerindeki gerçek maliyet biraz daha yüksektir. Ethernet, her çerçeveden önce 8 baytlık bir eşitleme dizisi ve çerçeveler arasında 12 baytlık bir boşluk gerektirir. 1460 baytlık veri için tel üzerindeki toplam 1460+58+20=15381460 + 58 + 20 = 1538 bayttır; verim oranı %94,93’e düşer.

Özet

  • Kapsülleme, her katmanın üstünden aldığı veriyi kendi başlığıyla sarıp alt katmana vermesidir; alıcıda süreç simetrik biçimde tersine işler.
  • Her başlıkta bir çoğullama anahtarı bulunur: Ethernet’te tür alanı, IP’de protokol alanı, taşıma katmanında bağlantı noktası numarası.
  • Seçeneksiz IPv4 başlığı 20 bayttır; başlık uzunluğu 32 bitlik sözcük, parça ofseti ise 8 baytlık birim sayar.
  • Başlık sağlaması 16 bitlik sözcüklerin bire tümleyen toplamının tümleyenidir; dolu başlık üzerinde yeniden hesaplandığında sıfır vermelidir.
  • Sağlama yalnızca başlığı korur, yükü korumaz ve sözcük sırası değişikliklerini sezemez.
  • Başlık yükü 58 bayttır; 100 baytlık veride verim %63,29, 1460 baytlık veride %96,18’dir.

Sonraki Adım

Bu derste “segment”, “datagram” ve “çerçeve” adları geçti ve her biri belirli bir katmanın veri birimini gösterdi. Bu terimler gündelik konuşmada birbirinin yerine kullanılır, oysa aralarındaki fark boyut sınırlarını belirler. Sonraki ders katman başına veri birimi terimlerini kesinleştirecek, en büyük iletim biriminin ne olduğunu tanımlayacak ve 4000 baytlık bir yükün 1500 baytlık bir ortamdan nasıl geçtiğini parça parça hesaplayacak.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat