---
title: 'Ağ Modelleri ve Protokoller'
source: 'https://academia.sh/tr/kurslar/ag-modelleri'
language: tr
updated: '2026-08-17T04:39:08+00:00'
license: 'CC BY-SA 4.0'
lessons: 18
outcomes:
    - 'OSI ve TCP/IP modellerini karşılaştırarak sorunları doğru katmana yerleştirir'
    - 'Alt ağ hesabı yapar ve adres planı tasarlar'
    - 'TCP ile UDP arasındaki seçimi uygulama gereksinimiyle gerekçelendirir'
---

# Ağ Modelleri ve Protokoller

Katmanlı ağ modelleri, IPv4 ve IPv6 adresleme, alt ağ tasarımı, adres dönüştürme ve taşıma katmanı protokolleri; tek bir kurumsal ağ planı üzerinden hesapla yürütülen bir kurs.

## Katmanlı Modeller

OSI'nin yedi katmanı, TCP/IP'nin dört katmanı, kapsülleme mekaniği ve katman başına veri birimi terimleri.

### OSI Modeli

Source: https://academia.sh/tr/kurslar/ag-modelleri/osi-modeli

Yedi katmanlı başvuru modelinin katman görevleri, hizmet–arayüz–protokol ayrımı ve bir arızanın doğru katmana yerleştirilmesi.

İnternet Nasıl Çalışır kursunda bir adres satırına yazılan isteğin uçtan uca yolculuğu
izlendi: ad çözümlendi, bağlantı kuruldu, istek gönderildi, yanıt çizildi. O anlatıda ağ
tek parça bir hizmet gibi görünüyordu — isteği verirsiniz, yanıt gelir.

Bu kurs o tek parçayı açar. Açmanın yolu, işi katmanlara bölmektir. Bir bilgisayardaki
uygulamanın verisini başka bir kıtadaki bilgisayara ulaştırmak; elektrik sinyali üretmek,
komşu cihazı adreslemek, ağlar arası yol seçmek, kaybolan parçaları yeniden göndermek ve
verinin anlamını korumak gibi birbirinden bağımsız sorunlar içerir. Bu dersin sorusu, bu
sorunların hangi ölçüte göre ayrıldığıdır.

#### Katmanlamanın Nedeni

Katmanlı tasarım, Programlama Temelleri kursundaki yukarıdan aşağı ayrıştırmanın ağ
alanındaki karşılığıdır: her katman, altındaki katmanın sunduğu hizmeti kullanır ve
üstündeki katmana daha soyut bir hizmet sunar. Bir katmanın **nasıl** çalıştığı, onu
kullanan katmanı ilgilendirmez.

Bu ayrımın somut kazancı, katmanların birbirinden bağımsız değiştirilebilmesidir. Bakır
kablo yerine fiber kullanmak, üzerinde çalışan hiçbir uygulamayı etkilemez; bir uygulama
protokolünü değiştirmek, altındaki yönlendirme mekanizmasına dokunmaz. Bir bilgisayar
kablosuz bağlantıdan kablolu bağlantıya geçtiğinde açık duran oturumların çoğu, üst
katmanlar bu değişikliği görmediği için etkilenmez.

Katmanlı bir mimaride üç kavram özenle ayrılır:

- **Hizmet (service):** Bir katmanın üstündeki katmana ne sunduğu. "Sıralı ve kayıpsız
  bir bayt akışı" bir hizmet tanımıdır.
- **Arayüz (interface):** Üstteki katmanın bu hizmete nasıl eriştiği. İşlev çağrıları,
  parametreler, veri aktarım biçimi.
- **Protokol (protocol):** Aynı katmanın iki ayrı makinedeki örneklerinin birbiriyle
  nasıl konuştuğu. Hizmeti gerçekleştirmenin iç meselesidir ve üstteki katmana kapalıdır.

Hizmet aynı kaldığı sürece protokol değiştirilebilir. Katmanlı modelin dayanıklılığı bu
sözden gelir.

#### Yedi Katman

**OSI başvuru modeli (Open Systems Interconnection reference model)**, ağ işlevlerini yedi
katmana ayırır. Aşağıdan yukarıya:

| No | Katman | Sorumluluk | Adresleme birimi |
|---|---|---|---|
| 7 | Uygulama (application) | Uygulamaya özgü alışveriş kuralları | Kaynak adı |
| 6 | Sunum (presentation) | Veri gösterimi, kodlama, şifreleme | — |
| 5 | Oturum (session) | Diyalog kurulumu, senkronizasyon, kurtarma | — |
| 4 | Taşıma (transport) | Uçtan uca güvenilirlik ve çoğullama | Bağlantı noktası |
| 3 | Ağ (network) | Ağlar arası adresleme ve yol seçimi | IP adresi |
| 2 | Veri bağlantısı (data link) | Komşu düğümler arası çerçeve iletimi | Donanım adresi |
| 1 | Fiziksel (physical) | Bitlerin sinyale dönüşmesi | — |

Katmanların sorumlulukları, tek bir ölçütle ayrılır: **bir sorunun kapsamı**.

**Fiziksel katman** yalnızca bir bitin nasıl aktarılacağıyla ilgilenir. Gerilim düzeyleri,
ışık darbeleri, radyo taşıyıcıları, konektör biçimleri ve zamanlama bu katmanın konusudur.
Bu katmanda "adres" yoktur; ortama konan sinyalin ne anlama geldiği bilinmez.

**Veri bağlantısı katmanı**, aynı fiziksel ortamı paylaşan cihazlar arasında iletim yapar.
Bit dizisine başlangıç ve bitiş sınırı koyar, hedef cihazı donanım adresiyle belirtir,
hata sezmek için bir denetim alanı ekler ve ortamı birden çok cihaz paylaşıyorsa erişimi
düzenler. Kapsamı tek bir bağlantıdır; bir sonraki cihazın ötesini görmez.

**Ağ katmanı**, birbirine komşu olmayan ağlar arasında iletim yapar. İki yeni görev
üstlenir: her uca ağdan bağımsız bir adres vermek ve bu adrese giden yolu seçmek.
Yönlendiriciler bu katmanda çalışır. Uçtan uca teslim güvencesi vermez; yalnızca "elimden
geleni yaparım" düzeyinde bir hizmettir.

**Taşıma katmanı**, iki uç arasındaki iletişimi uygulamaların kullanabileceği hâle
getirir. Aynı makinede çalışan birden çok uygulamayı bağlantı noktası numarasıyla ayırır
ve — protokole göre — kayıp, sıra bozulması ve yineleme sorunlarını üstlenir. Ağ katmanı
paketleri kaybedebilir; taşıma katmanı bunu üst katmandan gizleyebilir.

**Oturum katmanı**, iki uç arasındaki diyaloğu yapılandırır: hangi tarafın ne zaman
konuşacağı, kesintiden sonra hangi noktadan devam edileceği. **Sunum katmanı**, verinin
gösterimini düzenler: karakter kodlaması, bayt sırası, sıkıştırma ve şifreleme. Bu iki
katmanın işlevleri uygulamada çoğunlukla uygulama katmanının veya kütüphanelerin içinde
yer alır.

**Uygulama katmanı**, kullanıcı programının doğrudan kullandığı protokolleri barındırır.
Bir kaynağın nasıl isteneceği, bir postanın hangi biçimde iletileceği bu katmanın
konusudur.

#### Kurs Boyunca İzlenecek Ağ

Bu kursun tüm hesapları tek bir örnek üzerinden yürütülecektir: bir araştırma kurumunun
tek yerleşkeli ağı.

- Kurum, sağlayıcısından **tek bir genel adres** almıştır: `203.0.113.10`.
- İç ağda **özel bir blok** kullanılır: `192.168.10.0/24`.
- Bloğun bölümlere ayrılması, bu konudan sonraki derslerde adım adım tasarlanacaktır.
- İzlenecek istemci, yönetim bölümündeki `192.168.10.196` adresli makinedir; donanım
  adresi `00:00:5e:00:53:01`.
- Bu makinenin geçidi (default gateway) `192.168.10.193` adresli kurum
  yönlendiricisidir.
- İstemcinin dış dünyadaki hedefi, `198.51.100.20` adresli bir sunucudur.

Örnekteki `203.0.113.0/24`, `198.51.100.0/24` ve `192.0.2.0/24` blokları belgeleme için
ayrılmıştır; gerçek ağlarda görünmezler. Donanım adresleri de belgeleme amacıyla ayrılmış
`00:00:5e:00:53:xx` aralığından seçilmiştir. Bu seçim bilinçlidir: bir örnek adres, gerçek
bir sistemi işaret ediyorsa örnek olmaktan çıkar.

İstemci, `198.51.100.20` üzerindeki bir kaynağı istediğinde her katman kendi işini yapar:
uygulama katmanı isteği biçimlendirir, taşıma katmanı bunu bir bağlantıya oturtur, ağ
katmanı hedef adrese göre yolu seçer, veri bağlantısı katmanı çerçeveyi geçide ulaştırır,
fiziksel katman bitleri kabloya koyar. Bu adımların her biri sonraki derslerde tek tek
açılacaktır.

#### Bir Arızayı Katmana Yerleştirmek

Katmanlı modelin gündelik değeri, tanı sırasını belirlemesidir. Bir sorunun hangi katmanda
olduğu bilinmiyorsa, aşağıdan yukarıya doğru daraltma yapılır: alt katman çalışmıyorsa
üstündeki katmanların hepsi çalışmaz.

| Belirti | Sorumlu katman | Gerekçe |
|---|---|---|
| Arayüz bağlantı ışığı yanmıyor | Fiziksel | Sinyal taşınmıyor |
| Komşu cihazın donanım adresi çözümlenmiyor | Veri bağlantısı | Yerel ağda adres eşleme başarısız |
| Yerel ağ çalışıyor, dış adrese ulaşılmıyor | Ağ | Yol seçimi veya geçit tanımı hatalı |
| Adrese ulaşılıyor, bağlantı noktası yanıtsız | Taşıma | Hedefte dinleyen süreç veya filtreleme sorunu |
| Bağlantı kuruluyor, yanıt anlamsız | Sunum / uygulama | Kodlama veya protokol uyuşmazlığı |

Sıra tersine çevrildiğinde çok emek boşa gider: uygulama yapılandırmasında saatler
harcandıktan sonra kablonun takılı olmadığı görülebilir. Katmanlı tanı yöntemi, bu israfı
önlemek için sistemli bir daraltma önerir.

#### Modelin Sınırları

OSI bir **başvuru modelidir**; bir gerçekleştirim değildir. İnternet'te çalışan protokol
yığını bu modele göre tasarlanmamıştır ve ona tam olarak oturmaz. Modelin bilinen sınırları
açıkça söylenmelidir:

- Oturum ve sunum katmanları, ayrı katmanlar olarak çoğu yığında bulunmaz; işlevleri
  uygulama katmanına veya kütüphanelere dağılmıştır.
- Bazı protokoller birden çok katmanı birden ilgilendirir. Güvenli taşıma protokolleri
  taşıma ile uygulama arasında konumlanır; adres eşleme protokolleri ağ ve veri bağlantısı
  katmanlarını birlikte kullanır.
- Tünelleme kullanıldığında katman sırası tekrarlanır: bir ağ katmanı paketi, başka bir ağ
  katmanı paketinin yükü hâline gelebilir.

Bu sınırlara karşın model iki nedenle yaşamaya devam eder. Birincisi ortak sözlük sunar:
"üçüncü katman sorunu" ifadesi, ortak bir anlam taşır. İkincisi tanı sırası verir: sorunun
kapsamını daraltmanın sistemli bir yolunu tanımlar.

#### Özet

- Katmanlı tasarım, ağ işini kapsamına göre ayırır; her katman altındakinin hizmetini
  kullanır, üstündekine daha soyut bir hizmet sunar.
- Hizmet (ne sunulduğu), arayüz (nasıl erişildiği) ve protokol (eşler arasında nasıl
  konuşulduğu) ayrı kavramlardır; hizmet sabit kalarak protokol değiştirilebilir.
- OSI modeli yedi katman tanımlar: fiziksel, veri bağlantısı, ağ, taşıma, oturum, sunum,
  uygulama.
- Katmanlar arasındaki temel ayrım kapsamdır: bir bit, bir bağlantı, ağlar arası yol, uçtan
  uca oturum.
- Tanıda aşağıdan yukarıya daraltma yapılır; alt katman çalışmıyorsa üst katmanların hepsi
  çalışmaz.
- OSI bir başvuru modelidir; gerçekleştirilen yığınlar ona tam oturmaz, ancak ortak sözlük
  ve tanı sırası sağlar.

#### Sonraki Adım

Yedi katmanlı model bir tasarım sözlüğü verir; ancak İnternet'te çalışan yığın bu modele
göre kurulmamıştır. Sonraki ders, gerçekten gerçekleştirilen dört katmanlı TCP/IP
modelini ele alacak, iki modelin katmanlarını eşleyecek ve TCP/IP'nin merkezindeki tek
ortak katmanın neden bu kadar belirleyici olduğunu gösterecek.

### TCP/IP Modeli

Source: https://academia.sh/tr/kurslar/ag-modelleri/tcp-ip-modeli

Dört katmanlı pratik model, OSI ile eşlemesi, kum saati mimarisi ve uçtan uca ilkesinin tasarıma etkisi.

Önceki ders yedi katmanlı bir başvuru modelini tanıttı ve bu modelin gerçekleştirilen
yığınlara tam oturmadığını belirtti. İnternet'te çalışan yığın ayrı bir soydan gelir:
önce protokoller yazılmış, model sonradan onları betimlemek için tarif edilmiştir.

Bu dersin sorusu, o yığının nasıl bölündüğü ve bölünmenin hangi tasarım kararlarını
dayattığıdır. Sonuçta ortaya çıkan yapı, katman sayısıyla değil, ortadaki tek katmanın
tekliğiyle ayırt edilir.

#### Dört Katman

TCP/IP modeli dört katman tanımlar:

| No | Katman | Sorumluluk | Örnek protokol sınıfı |
|---|---|---|---|
| 4 | Uygulama (application) | Uygulamaya özgü alışveriş kuralları | Kaynak aktarımı, ad çözümleme, posta |
| 3 | Taşıma (transport) | Uçtan uca çoğullama ve isteğe bağlı güvenilirlik | TCP, UDP |
| 2 | İnternet (internet) | Ağlar arası adresleme ve yol seçimi | IP, ICMP |
| 1 | Bağlantı (link) | Tek bir ağ üzerinde çerçeve iletimi | Ethernet, kablosuz yerel ağ |

Modelin adı, iki merkezî protokolünden gelir: **IP (Internet Protocol)** ve **TCP
(Transmission Control Protocol)**. Adlandırma bir yanılgıya yol açabilir: taşıma
katmanında TCP'nin yanı sıra başka protokoller de vardır ve model bunları dışlamaz.

Modelin OSI'den ayrıldığı iki nokta belirgindir. Birincisi, OSI'nin fiziksel ve veri
bağlantısı katmanları burada tek bir **bağlantı katmanında** birleşir. Bu birleştirme
bilinçlidir: IP, altındaki ağ teknolojisinin ayrıntılarını bilmeme sözü verir, dolayısıyla
o ayrıntıların kaç katmana bölündüğü onu ilgilendirmez. İkincisi, OSI'nin oturum ve sunum
katmanları ayrı katman olarak yoktur; işlevleri uygulama katmanına bırakılmıştır.

#### İki Modelin Eşlenmesi

| OSI | TCP/IP | Not |
|---|---|---|
| 7 Uygulama | Uygulama | Doğrudan karşılık |
| 6 Sunum | Uygulama | Kodlama ve şifreleme uygulamaya veya kütüphaneye düşer |
| 5 Oturum | Uygulama | Diyalog yönetimi ayrı katman değil |
| 4 Taşıma | Taşıma | Doğrudan karşılık |
| 3 Ağ | İnternet | Doğrudan karşılık |
| 2 Veri bağlantısı | Bağlantı | Birleşme |
| 1 Fiziksel | Bağlantı | Birleşme |

Eşlemenin bozulduğu yerler bilinmelidir. Güvenli taşıma protokolleri, taşıma katmanının
akışını kullanır ve uygulama verisini şifreler; OSI sözlüğünde sunum katmanına, TCP/IP
sözlüğünde uygulama katmanına düşer. Adres eşleme protokolü, ağ katmanı adresinden
bağlantı katmanı adresine çeviri yapar ve iki katmana birden aittir. Tünelleme
kullanıldığında bir ağ katmanı paketi başka bir ağ katmanı paketinin yükü olur; katman
sırası tekrarlanır.

Bu nedenle katman numaralarının pratik değeri kesin sınıflandırma değil, ortak sözlüktür.
Bir sorunun "üçüncü katman sorunu" olduğunu söylemek, sorunun yol seçimiyle ilgili olduğunu
söylemenin kısa yoludur.

#### Kum Saati Mimarisi

TCP/IP yığınının ayırt edici özelliği katman sayısı değil, **katman başına protokol
çeşitliliğinin dağılımıdır**.

Bağlantı katmanında çok sayıda teknoloji vardır: kablolu yerel ağ, kablosuz yerel ağ,
hücresel bağlantı, uydu bağlantısı, noktadan noktaya seri hatlar. Uygulama katmanında da
sayısız protokol vardır. Ortada ise **tek bir protokol** durur: IP.

Bu yapı **kum saati (hourglass)** olarak adlandırılır: iki uçta genişlik, ortada dar bir
boğaz. Boğazın darlığı bir kısıtlama değil, mimarinin ta kendisidir. Ortada tek bir
protokol olduğu için:

- Yeni bir bağlantı teknolojisi, IP paketlerini taşımayı öğrendiği anda tüm uygulamalara
  açılır. Uygulamaların hiçbirinde değişiklik gerekmez.
- Yeni bir uygulama protokolü, IP üzerinde çalıştığı anda tüm bağlantı teknolojileri
  üzerinden erişilebilir olur. Ağ altyapısında değişiklik gerekmez.

Çarpım burada toplama dönüşür: $n$ bağlantı teknolojisi ve $m$ uygulama protokolü için
$n \times m$ uyarlama yazmak yerine, $n + m$ uyarlama yeter. Boğazın maliyeti ise IP'nin
kendisini değiştirmenin zorluğudur: dar boğaza dokunmak, iki uçtaki her şeyi ilgilendirir.
Adres genişliğini değiştirmenin neden onlarca yıla yayılan bir iş olduğu bu yapıdan
anlaşılır; bu konu IPv6 dersinde ele alınacaktır.

#### Uçtan Uca İlkesi

TCP/IP'nin ikinci belirleyici tasarım kararı, işlevlerin nerede gerçekleştirileceğiyle
ilgilidir. **Uçtan uca ilkesi (end-to-end principle)** şunu söyler: bir işlev, ancak uç
noktalar tarafından gerçekleştirilebiliyorsa ağın içine konmamalıdır.

Gerekçe bir doğruluk argümanıdır. Bir dosyanın hatasız aktarıldığından emin olmak isteyen
uygulama, bunu kendi başına doğrulamak zorundadır: ara düğümlerin her biri kendi
bağlantısında hata denetimi yapsa bile, düğüm içindeki bellek bozulması veya yazılım hatası
denetimlerin dışında kalır. Uçtaki doğrulama zorunlu olduğuna göre, aradaki doğrulamalar
doğruluk için gerekli değildir. Ara düğümlerdeki denetim yalnızca bir başarım
eniyilemesidir: hatalı çerçeveyi erken atmak, onu uca kadar taşıyıp orada attırmaktan
ucuzdur.

Bu ilkenin somut sonucu, IP'nin sunduğu hizmetin **elinden geleni yapan (best-effort)**
olmasıdır. IP paket kaybını, sıra bozulmasını ve yinelenmeyi engellemez. Bunları düzeltmek
isteyen, taşıma katmanında veya uygulamada düzeltir. Ağ katmanı basit tutulur; karmaşıklık
uçlara itilir.

Karşılığı da vardır. Ağ, üzerinde taşınan trafiğin ne olduğunu bilmediği için trafiğe özgü
güvenceler veremez. Gecikmeye duyarlı bir akışa öncelik vermek, ek düzenekler gerektirir.
Adres dönüştürme ve durum tutan ara kutular ise ilkeyi doğrudan zorlar; bu gerilim NAT ve
PAT dersinde ele alınacaktır.

#### Örnek Ağda Katmanların Karşılığı

Önceki derste tanıtılan kurumsal ağ üzerinde dört katmanın karşılığı şudur.
`192.168.10.196` adresli istemci, `198.51.100.20` adresli sunucudan bir kaynak istediğinde:

| Katman | Bu adımda ne yapılır | Kullanılan adres |
|---|---|---|
| Uygulama | İstek biçimlendirilir | Kaynağın adı |
| Taşıma | İstek bir bağlantıya oturtulur, sıra numarası verilir | Bağlantı noktası 49152 → 443 |
| İnternet | Hedef adrese göre yol seçilir | 192.168.10.196 → 198.51.100.20 |
| Bağlantı | Çerçeve geçide teslim edilir | 00:00:5e:00:53:01 → geçidin donanım adresi |

Dikkat edilmesi gereken ayrım şudur: **bağlantı katmanı adresleri her adımda değişir, ağ
katmanı adresleri değişmez.** İstemciden geçide giden çerçevede hedef donanım adresi
geçidindir; geçitten sağlayıcıya giden çerçevede hedef donanım adresi sağlayıcı
yönlendiricisinindir. Buna karşılık IP başlığındaki kaynak ve hedef adresleri yol boyunca
aynı kalır — bu kuralın istisnası, adres dönüştürmedir.

Bu ayrım, iki katmanın kapsam farkının doğrudan sonucudur: bağlantı katmanının kapsamı bir
bağlantı, ağ katmanının kapsamı uçtan uca yoldur.

#### Hangi Model Ne Zaman

İki model birbirinin rakibi değildir; farklı işler için kullanılır.

OSI modeli **öğretim ve tanı** için elverişlidir. Yedi katman, sorunun kapsamını daraltmak
isteyen bir kişiye daha ince bir ızgara verir; fiziksel katman ile veri bağlantısı
katmanının ayrılması, kablo arızasıyla adresleme arızasını ayırmayı kolaylaştırır.

TCP/IP modeli **gerçekleştirim** için doğru betimlemedir. Bir işletim sisteminin ağ yığını
bu dört katmana göre yapılandırılmıştır; soket arayüzü taşıma katmanının üstünde durur,
yönlendirme tablosu internet katmanındadır, arayüz sürücüleri bağlantı katmanındadır.

Bu kurs iki sözlüğü de kullanır: katman numaralarına atıf yapılırken OSI numaralandırması,
protokollerin yerleşimi anlatılırken TCP/IP bölümlemesi esas alınır.

#### Özet

- TCP/IP modeli dört katmandan oluşur: bağlantı, internet, taşıma, uygulama.
- OSI'nin fiziksel ve veri bağlantısı katmanları bağlantı katmanında birleşir; oturum ve
  sunum katmanları ayrı katman olarak yer almaz.
- Kum saati mimarisinde ortada tek bir protokol (IP) durur; bu darlık, $n \times m$
  uyarlama sorununu $n + m$'ye indirger, karşılığında IP'yi değiştirmeyi zorlaştırır.
- Uçtan uca ilkesine göre bir işlev uçlarda gerçekleştirilebiliyorsa ağın içine konmaz;
  IP'nin elinden geleni yapan hizmet sunması bu ilkenin sonucudur.
- Bir paketin yolculuğunda bağlantı katmanı adresleri her adımda değişir, ağ katmanı
  adresleri değişmez.
- OSI tanı ve öğretim için, TCP/IP gerçekleştirim betimlemesi için kullanılır.

#### Sonraki Adım

İki model de verinin katmanlar boyunca sarmalandığını söyler, ancak sarmalamanın
kendisinin bir maliyeti vardır: her katman kendi başlığını ekler ve bu başlıklar taşınan
veriden yer çalar. Sonraki ders kapsülleme mekaniğini bit düzeyinde ele alacak, bir IP
başlığını alan alan kuracak ve yüzde kaç yükün başlıklara gittiğini hesaplayacak.

### Kapsülleme ve Başlıklar

Source: https://academia.sh/tr/kurslar/ag-modelleri/kapsulleme-ve-basliklar

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.

Ö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 \times 4 = 20$ bayttır. **Parça ofseti** bayt değil 8 baytlık birim sayar; 13 bit ile
$8 \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.

```python
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 = 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.

### Çerçeve, Paket, Segment

Source: https://academia.sh/tr/kurslar/ag-modelleri/cerceve-paket-segment

Katman başına veri birimi terimleri, en büyük iletim birimi, en büyük segment boyu ve IPv4 parçalama hesabı.

Önceki ders 100 baytlık bir uygulama verisinin 158 baytlık bir çerçeveye dönüşünü izledi ve
yol boyunca üç ayrı ad kullandı: segment, datagram, çerçeve. Bu adlar gelişigüzel değildir;
her biri belirli bir katmanın veri birimini gösterir.

Adların kesinleştirilmesi terminolojik bir titizlikten ibaret değildir. Her katmanın kendi
boyut sınırı vardır ve bu sınırlar birbirini belirler. Bu dersin sorusu, bir verinin en
fazla ne kadar büyük olabileceği ve sınırı aştığında ne olduğudur.

#### Katman Başına Veri Birimi

Bir katmanın kendi başlığıyla birlikte oluşturduğu birime **protokol veri birimi (protocol
data unit)** denir. Katman başına adlandırma şöyledir:

| Katman | Birim adı | İçeriği |
|---|---|---|
| Uygulama | Veri / mesaj | Uygulamanın ürettiği bayt dizisi |
| Taşıma (TCP) | Segment | TCP başlığı + uygulama verisi |
| Taşıma (UDP) | Datagram | UDP başlığı + uygulama verisi |
| İnternet | Paket / datagram | IP başlığı + taşıma birimi |
| Bağlantı | Çerçeve (frame) | Bağlantı başlığı + IP paketi + kuyruk |
| Fiziksel | Bit / simge | Ortama konan sinyal |

İki ayrım özellikle karışır.

Birincisi, **segment ile datagram** ayrımıdır. TCP'nin birimi segmenttir; UDP'nin birimi
datagramdır. Ad farkı tesadüf değildir: segment, bir bayt akışından kesilmiş bir dilimdir
ve akış içindeki yeri sıra numarasıyla bilinir. Datagram ise kendi başına duran, sınırları
korunan bir mesajdır. Bu fark, taşıma katmanı konusunda ayrıntılı biçimde ele alınacaktır.

İkincisi, **paket** sözcüğünün iki anlamıdır. Dar anlamda paket, ağ katmanının birimidir.
Geniş anlamda, ağ üzerinde giden herhangi bir veri parçasını gösterir — "paket anahtarlama"
terimindeki kullanım budur. Bu kurs, ağ katmanı birimi için "paket" veya "datagram"
terimlerini kullanır; ölçüsüz kullanımdan kaçınmak için diğer katmanların birimleri kendi
adlarıyla anılır.

#### En Büyük İletim Birimi

**En büyük iletim birimi (maximum transmission unit, MTU)**, bir bağlantı katmanı
teknolojisinin tek bir çerçevede taşıyabileceği yükün üst sınırıdır. Ölçü, bağlantı
başlığını **içermez**: MTU, çerçevenin taşıyabileceği ağ katmanı paketinin boyudur.

Yaygın Ethernet gerçekleştiriminde bu sınır 1500 bayttır. Sınırın bir üst sınır olmasının
nedeni, ortamın paylaşılmasıdır: tek bir çerçeve ne kadar uzun sürerse, sıradaki cihazlar o
kadar bekler. Sınırın bir alt sınırının olmasının nedeni ise başlık yükünün küçük
çerçevelerde katlanılmaz hâle gelmesidir.

MTU değeri yol boyunca değişebilir. Bir tünel, kendi başlığı için yer ayırmak zorunda
olduğundan içindeki bağlantının MTU değerini düşürür. Yolun tamamında geçerli olan en küçük
değer, **yol MTU değeri (path MTU)** olarak adlandırılır.

#### En Büyük Segment Boyu

**En büyük segment boyu (maximum segment size, MSS)**, bir TCP segmentinin taşıyabileceği
uygulama verisinin üst sınırıdır. MTU'dan türetilir ve başlıklar düşülür:

$$
\text{MSS} = \text{MTU} - \text{IP başlığı} - \text{TCP başlığı}
$$

| Ortam | MTU | IP başlığı | TCP başlığı | MSS |
|---|---|---|---|---|
| Ethernet, IPv4 | 1500 | 20 | 20 | 1460 |
| Ethernet, IPv6 | 1500 | 40 | 20 | 1440 |
| Tünelli bağlantı | 1492 | 20 | 20 | 1452 |

UDP için karşılık gelen sınır $1500 - 20 - 8 = 1472$ bayttır; UDP başlığı 8 bayttır.

MSS, TCP bağlantısı kurulurken iki uç arasında bildirilir: her uç, kendi alabileceği en
büyük segment boyunu karşı tarafa söyler ve küçük olan geçerli olur. Bu bildirim, gönderen
tarafın parçalamaya düşmeden segment üretmesini sağlar.

Seçeneklerin kullanıldığı durumlarda TCP başlığı 20 baytı aşar ve MSS buna göre azalır.
Zaman damgası ve seçmeli onay gibi seçenekler etkinken kullanılabilir veri alanı daralır.

#### Parçalama

Bir IPv4 paketi, geçeceği bağlantının MTU değerinden büyükse **parçalanır
(fragmentation)**. Parçalama, IP başlığındaki üç alanla yürütülür:

- **Kimlik:** Aynı özgün datagramdan gelen tüm parçalarda aynıdır.
- **Parça devam ediyor bayrağı (MF):** Son parça dışındaki tüm parçalarda 1'dir.
- **Parça ofseti:** Bu parçanın yükünün, özgün yükün başından itibaren kaçıncı bayttan
  başladığını verir. Alan 13 bit olduğundan ofset **8 baytlık birimlerle** sayılır; bu
  yüzden son parça dışındaki her parçanın yükü 8'in katı olmak zorundadır.

Aşağıdaki program, verilen yük boyunu ve MTU değerini alıp parçaları hesaplar.

```python
def parcala(yuk_boyu: int, mtu: int, baslik: int = 20) -> None:
    """Bir IPv4 datagramının yükünü MTU sınırına göre parçalara böler."""
    parca_yuku = (mtu - baslik) // 8 * 8      # ofset 8 baytın katı olmalı
    ofset = 0
    kalan = yuk_boyu
    sira = 1
    while kalan > 0:
        bu_parca = min(parca_yuku, kalan)
        kalan -= bu_parca
        print(f"parça {sira}: yük={bu_parca:4d} bayt  "
              f"ofset alanı={ofset // 8:3d}  MF={1 if kalan else 0}  "
              f"datagram={bu_parca + baslik:4d} bayt")
        ofset += bu_parca
        sira += 1


parcala(4000, mtu=1500)
```

Çıktı:

```
parça 1: yük=1480 bayt  ofset alanı=  0  MF=1  datagram=1500 bayt
parça 2: yük=1480 bayt  ofset alanı=185  MF=1  datagram=1500 bayt
parça 3: yük=1040 bayt  ofset alanı=370  MF=0  datagram=1060 bayt
```

Hesabın adımları izlenebilir. MTU 1500, IP başlığı 20 bayt olduğuna göre parça başına en
çok $1500 - 20 = 1480$ bayt yük taşınabilir; 1480 zaten 8'in katıdır. İlk parça 0. bayttan
başlar, ofset alanı 0'dır. İkinci parça 1480. bayttan başlar: $1480 / 8 = 185$. Üçüncü parça
2960. bayttan başlar: $2960 / 8 = 370$ ve kalan $4000 - 2960 = 1040$ baytı taşır.

Toplam taşınan yük $1480 + 1480 + 1040 = 4000$ bayttır, ancak tel üzerindeki toplam
$1500 + 1500 + 1060 = 4060$ bayta çıkmıştır: iki fazladan IP başlığı eklenmiştir.

Daha küçük bir MTU değeri, parça sayısını hızla artırır:

```
parcala(4000, mtu=576)
```

```
parça 1: yük= 552 bayt  ofset alanı=  0  MF=1  datagram= 572 bayt
parça 2: yük= 552 bayt  ofset alanı= 69  MF=1  datagram= 572 bayt
parça 3: yük= 552 bayt  ofset alanı=138  MF=1  datagram= 572 bayt
parça 4: yük= 552 bayt  ofset alanı=207  MF=1  datagram= 572 bayt
parça 5: yük= 552 bayt  ofset alanı=276  MF=1  datagram= 572 bayt
parça 6: yük= 552 bayt  ofset alanı=345  MF=1  datagram= 572 bayt
parça 7: yük= 552 bayt  ofset alanı=414  MF=1  datagram= 572 bayt
parça 8: yük= 136 bayt  ofset alanı=483  MF=0  datagram= 156 bayt
```

Burada $576 - 20 = 556$ değeri 8'in katı olmadığından parça yükü 552'ye yuvarlanmıştır.

#### Parçalamanın Maliyeti

Parçalama üç nedenle istenmez.

**Kayıp maliyeti çarpılır.** Parçalar ancak tümü ulaştığında birleştirilebilir. Sekiz
parçadan biri kaybolursa diğer yedisi de atılır ve özgün datagram yeniden gönderilmek
zorunda kalır. Bağımsız kayıp varsayımıyla, parça başına kayıp olasılığı $p$ ise $n$
parçalık bir datagramın ulaşma olasılığı $(1-p)^n$'dir; $p = 0{,}01$ ve $n = 8$ için bu
oran yaklaşık $0{,}923$'tür, yani datagram kaybı %7,7'ye çıkar.

**Birleştirme yükü alıcıya düşer.** Parçalar yol boyunca birleştirilmez; yalnızca son
hedefte birleştirilir. Alıcı, eksik parçaları beklerken bellek tutmak ve bir zaman aşımı
saymak zorundadır.

**Ara katmanların işi zorlaşır.** Yalnızca ilk parça taşıma katmanı başlığını taşır;
sonraki parçalarda bağlantı noktası numarası yoktur. Bağlantı noktasına göre karar veren
düzenekler, sonraki parçaları sınıflandıramaz.

Bu nedenle yaygın uygulama parçalamadan kaçınmaktır. Gönderen, IP başlığındaki
**parçalanmasın (DF)** bayrağını kurar; paket MTU'dan büyük bir bağlantıya geldiğinde
yönlendirici onu atar ve gönderene bir hata mesajı döndürür. Gönderen bu mesajdaki MTU
değerine göre segment boyunu küçültür. Bu döngüye **yol MTU keşfi (path MTU discovery)**
denir ve ICMP dersinde ayrıntılı olarak ele alınacaktır.

IPv6, parçalamayı yol üzerindeki yönlendiricilerden tamamen kaldırmıştır: bir paket
MTU'dan büyükse yönlendirici onu parçalamaz, atar ve bildirir. Parçalama gerekiyorsa
yalnızca gönderen uç yapar.

#### Örnek Ağda Sınırlar

Kurumsal ağdaki istemci, `198.51.100.20` adresine 3000 baytlık bir gövde göndermek
istediğinde ne olacağı bu derste kurulan hesapla belirlenir. TCP kullanılıyorsa parçalama
hiç yaşanmaz: taşıma katmanı gövdeyi kendisi böler ve $1460 + 1460 + 80$ baytlık üç segment
üretir. Her segment ayrı bir IP paketi olarak gider ve hiçbiri MTU'yu aşmaz.

UDP kullanılıyorsa durum başkadır: UDP gövdeyi bölmez, 3000 baytlık tek bir datagram üretir
ve bölme işi IP katmanına düşer. Bu, taşıma katmanı seçiminin ağ katmanı davranışını
doğrudan belirlediği somut bir örnektir.

#### Özet

- Her katmanın veri birimi ayrı adla anılır: segment (TCP), datagram (UDP ve IP), paket
  (IP), çerçeve (bağlantı katmanı).
- MTU, bir bağlantının tek çerçevede taşıyabileceği ağ katmanı paketinin üst sınırıdır ve
  bağlantı başlığını içermez.
- MSS, MTU'dan IP ve TCP başlıkları düşülerek bulunur: Ethernet ve IPv4 için 1460 bayt.
- Parçalama kimlik, parça devam ediyor bayrağı ve parça ofseti alanlarıyla yürütülür; ofset
  8 baytlık birimlerle sayıldığından son parça dışındaki yükler 8'in katı olmalıdır.
- 4000 baytlık bir yük 1500 baytlık MTU'da 1480 + 1480 + 1040 biçiminde üç parçaya bölünür;
  tel üzerindeki toplam 4060 bayta çıkar.
- Parçalama kayıp maliyetini çarpar; yaygın uygulama parçalanmasın bayrağı ve yol MTU keşfi
  ile ondan kaçınmaktır.

#### Sonraki Adım

Bu konu, verinin katmanlar arasındaki biçimini tanımladı. Sıradaki konu, bu biçimlerin
gerçekte nasıl taşındığına iner. İlk durak en alttaki adres düzeyidir: aynı kabloyu veya
aynı kablosuz hücreyi paylaşan cihazlar birbirini nasıl bulur, bir anahtar hangi çerçeveyi
nereye gönderir. Sonraki ders Ethernet çerçevesini ve donanım adreslerinin yapısını ele
alacak.

## Bağlantı ve Ağ Katmanı

Ethernet çerçevesinden IPv4 ve IPv6 adreslemeye, alt ağ tasarımından adres dönüştürmeye kadar yerel ağ ve yönlendirme mekaniği.

### Ethernet ve MAC Adresleri

Source: https://academia.sh/tr/kurslar/ag-modelleri/ethernet-ve-mac-adresleri

Ethernet çerçevesinin alanları, 48 bitlik donanım adresinin bit yapısı, yayın adresleri ve anahtarın adres öğrenme mekanizması.

Önceki konu, verinin katmanlar boyunca nasıl sarmalandığını tanımladı ve en dıştaki sargıya
çerçeve adını verdi. Çerçevenin içeriği ise henüz açılmadı: bir çerçeve hangi alanlardan
oluşur, üzerindeki adres ne anlama gelir?

Bu dersin sorusu, aynı fiziksel ortamı paylaşan cihazların birbirini nasıl bulduğudur.
Yanıt, ağ katmanı adreslerinden bağımsız, tamamen yerel bir adresleme düzeninde yatar.

#### Ethernet Çerçevesi

Bir Ethernet çerçevesi şu alanlardan oluşur:

| Alan | Boyut | İşlev |
|---|---|---|
| Hedef adresi | 6 bayt | Çerçeveyi alacak cihazın donanım adresi |
| Kaynak adresi | 6 bayt | Gönderen cihazın donanım adresi |
| Tür / uzunluk | 2 bayt | Yükün protokolü (`0x0800` IPv4, `0x86DD` IPv6, `0x0806` ARP) |
| Yük | 46–1500 bayt | Taşınan ağ katmanı paketi |
| Çerçeve denetim dizisi | 4 bayt | Döngüsel artıklık denetimi (CRC-32) |

Çerçeveden önce tel üzerine 7 baytlık bir eşitleme dizisi ve 1 baytlık çerçeve başlangıç
imi konur; çerçeveler arasında 12 bayt süresince ortam boş bırakılır. Bu 20 bayt çerçeveye
ait değildir, ancak tel üzerindeki zamanı tüketir.

Yükün **alt** sınırı 46 bayttır. Yük daha kısaysa dolgu (padding) eklenerek 46'ya
tamamlanır. Bu sınırın nedeni çarpışma sezmedir: bir çerçeve, tel üzerinde en uzak cihaza
ulaşıp geri dönecek kadar uzun sürmelidir; aksi hâlde gönderen, çarpışmayı fark etmeden
göndermeyi bitirir. Adresler ve tür alanıyla birlikte en küçük çerçeve
$6 + 6 + 2 + 46 + 4 = 64$ bayttır.

Yükün **üst** sınırı 1500 bayttır — önceki derste tanımlanan MTU değeri budur. Çerçevenin
kendi başlıkları bu sınırın dışındadır; en büyük çerçeve 1518 bayttır.

Çerçeve denetim dizisi, çerçevenin tamamı üzerinde hesaplanan bir döngüsel artıklık
denetimidir. IP başlığındaki sağlamadan farklı olarak yükü de kapsar ve bit hatalarını
belirgin biçimde daha güçlü sezer. Denetim başarısızsa çerçeve **sessizce atılır**; Ethernet
yeniden gönderme yapmaz. Kaybı fark etmek ve gidermek üst katmanların işidir.

#### MAC Adresinin Yapısı

**MAC adresi (media access control address)**, bir ağ arayüzünü fiziksel düzeyde
adresleyen 48 bitlik değerdir. İki nokta üst üste veya tire ile ayrılmış altı onaltılık
bayt olarak yazılır: `00:00:5e:00:53:01`.

Adres iki bölümden oluşur:

- **İlk 3 bayt:** Kuruluş benzersiz tanımlayıcısı (organizationally unique identifier).
  Arayüzü üreten kuruluşa tahsis edilir.
- **Son 3 bayt:** Kuruluşun kendi verdiği arayüz numarası.

İlk baytın en düşük iki biti ayrı anlam taşır ve adresi okurken ilk bakılacak yerdir:

| Bit | Ad | 0 ise | 1 ise |
|---|---|---|---|
| 0 (en düşük) | I/G | Tekil adres (tek arayüz) | Grup adresi (yayın veya çok noktaya gönderim) |
| 1 | U/L | Evrensel yönetimli (üretici verdi) | Yerel yönetimli (yerel olarak atandı) |

Aşağıdaki program bu iki biti çözer.

```python
def mac_coz(mac: str) -> None:
    baytlar = [int(x, 16) for x in mac.split(":")]
    ilk = baytlar[0]
    tur = "grup" if ilk & 0b1 else "tekil"
    kaynak = "yerel" if ilk & 0b10 else "evrensel"
    print(f"{mac}  ilk bayt={ilk:08b}  {tur:5s}  {kaynak}")


for adres in ("00:00:5e:00:53:01",      # örnek ağdaki istemci
              "00:00:5e:00:53:00",      # geçidin iç arayüzü
              "ff:ff:ff:ff:ff:ff",      # yayın
              "01:00:5e:00:00:01",      # IPv4 çok noktaya gönderim
              "33:33:00:00:00:01",      # IPv6 çok noktaya gönderim
              "02:00:5e:00:53:2f"):     # yerel yönetimli
    mac_coz(adres)
```

Çıktı:

```
00:00:5e:00:53:01  ilk bayt=00000000  tekil  evrensel
00:00:5e:00:53:00  ilk bayt=00000000  tekil  evrensel
ff:ff:ff:ff:ff:ff  ilk bayt=11111111  grup   yerel
01:00:5e:00:00:01  ilk bayt=00000001  grup   evrensel
33:33:00:00:00:01  ilk bayt=00110011  grup   yerel
02:00:5e:00:53:2f  ilk bayt=00000010  tekil  yerel
```

Maskeleme işlemleri, Bilgisayarlar Nasıl Çalışır kursundaki Bit Düzeyi İşlemler dersinde
tanıtılan yöntemin doğrudan uygulanmasıdır: `ilk & 0b1` en düşük biti, `ilk & 0b10` bir
sonraki biti yalıtır.

Üç adres sınıfı ayırt edilir. `ff:ff:ff:ff:ff:ff` **yayın (broadcast)** adresidir; yerel
ağdaki tüm arayüzler bu çerçeveyi işler. `01:00:5e:...` ile başlayan adresler IPv4 çok
noktaya gönderim, `33:33:...` ile başlayanlar IPv6 çok noktaya gönderim içindir; yalnızca
ilgili gruba katılmış arayüzler işler. Geri kalanlar tekil adreslerdir.

Yerel yönetimli adresler, üreticiden gelmeyen adreslerdir: sanal arayüzler, konteyner ağları
ve gizlilik için adres değiştiren kablosuz istemciler bu bloğu kullanır. `02:00:5e:00:53:2f`
adresinde ikinci bit kurulu olduğu için adres yereldir.

#### Adreslerin Kapsamı

MAC adresi **yerel** bir adrestir. Bir çerçeve yönlendiriciden geçtiğinde çerçeve tümüyle
yeniden kurulur: kaynak adresi yönlendiricinin çıkış arayüzü, hedef adresi ise bir sonraki
cihaz olur. Önceki konuda vurgulanan ayrım burada somutlaşır — bağlantı katmanı adresleri
her sekmede değişir, IP adresleri değişmez.

Bunun bir sonucu şudur: bir MAC adresi, yalnızca aynı yerel ağdaki cihazlar tarafından
görülebilir. Uzak bir sunucu, kendisine bağlanan istemcinin donanım adresini bilmez.

#### Anahtarın Adres Öğrenmesi

Bir **anahtar (switch)**, bağlantı katmanında çalışan ve çerçeveleri yalnızca gerekli
bağlantı noktasına ileten bir cihazdır. Hangi adresin hangi bağlantı noktasında olduğunu
önceden bilmez; **kaynak adreslerini gözleyerek** öğrenir.

Kural üç adımdadır:

1. Gelen çerçevenin **kaynak** adresi, geldiği bağlantı noktasıyla birlikte tabloya
   yazılır.
2. Çerçevenin **hedef** adresi tabloda varsa, çerçeve yalnızca o bağlantı noktasına
   iletilir.
3. Hedef adres tabloda yoksa veya bir grup adresiyse, çerçeve gelen bağlantı noktası
   dışındaki tüm bağlantı noktalarına gönderilir. Buna **taşırma (flooding)** denir.

Örnek ağdaki yönetim bölümünün anahtarında, istemci geçide ilk çerçevesini gönderdikten
sonra tablo şu hâle gelir:

| MAC adresi | Bağlantı noktası | Nasıl öğrenildi |
|---|---|---|
| `00:00:5e:00:53:01` | 4 | İstemcinin gönderdiği çerçevenin kaynak adresi |

Geçidin adresi henüz tabloda yoktur; istemcinin çerçevesi taşırma ile tüm bağlantı
noktalarına gider. Geçit yanıt verdiğinde onun adresi de öğrenilir:

| MAC adresi | Bağlantı noktası | Nasıl öğrenildi |
|---|---|---|
| `00:00:5e:00:53:01` | 4 | İstemcinin çerçevesi |
| `00:00:5e:00:53:00` | 1 | Geçidin yanıt çerçevesi |

Tablo girdileri bir yaşlanma süresi sonunda silinir; böylece bir cihaz başka bir bağlantı
noktasına taşındığında tablo kendini düzeltir.

Öğrenme yönteminin bir sonucu, iki adresin doğal olarak birlikte öğrenilememesidir: bir
cihaz hiç çerçeve göndermediyse anahtar onun yerini bilmez ve ona giden her çerçeve
taşırılır.

#### Çarpışma Alanı ve Yayın Alanı

İki kapsam kavramı ayrılmalıdır.

**Çarpışma alanı (collision domain)**, aynı anda gönderim yapıldığında çakışmanın
oluşabileceği cihaz kümesidir. Anahtarın her bağlantı noktası ayrı bir çarpışma alanıdır;
çift yönlü çalışan bir bağlantıda çarpışma hiç oluşmaz.

**Yayın alanı (broadcast domain)**, bir yayın çerçevesinin ulaştığı cihaz kümesidir. Anahtar
yayın çerçevelerini taşırdığı için yayın alanını bölmez. Yayın alanını bölen cihaz
yönlendiricidir: bir yönlendirici yayın çerçevelerini karşı tarafa geçirmez.

Bu ayrım, örnek ağın bölümlere ayrılmasının gerekçelerinden biridir. Tek bir yayın alanında
bulunan cihaz sayısı arttıkça, her yayın çerçevesinin oluşturduğu iş de artar: yüz cihazlık
bir yayın alanında bir yayın çerçevesi doksan dokuz gereksiz işleme yol açar. Kurumun
bölümlerini ayrı ağlara koymak, bu yükü sınırlar.

**Sanal yerel ağ (VLAN)** düzeneği, tek bir fiziksel anahtar üzerinde birden çok yayın alanı
tanımlamayı sağlar: her bağlantı noktası bir kimlikle etiketlenir ve farklı kimlikli
bağlantı noktaları arasında çerçeve geçmez. Örnek ağdaki bölümler, ayrı anahtarlar yerine
tek bir anahtar üzerinde bu yolla da ayrılabilir; adres planı her iki durumda da aynıdır.

#### Özet

- Ethernet çerçevesi hedef adresi, kaynak adresi, tür alanı, 46–1500 baytlık yük ve 4
  baytlık denetim dizisinden oluşur; en küçük çerçeve 64, en büyüğü 1518 bayttır.
- Denetim dizisi başarısızsa çerçeve sessizce atılır; kaybı gidermek üst katmanların işidir.
- MAC adresi 48 bittir; ilk baytın en düşük biti tekil/grup, bir sonraki bit evrensel/yerel
  ayrımını verir.
- `ff:ff:ff:ff:ff:ff` yayın adresidir; `01:00:5e:...` ve `33:33:...` önekleri çok noktaya
  gönderim içindir.
- Anahtar, gelen çerçevelerin kaynak adreslerini gözleyerek adres tablosunu öğrenir; hedefi
  bilinmeyen çerçeveleri taşırır.
- Anahtar çarpışma alanlarını böler, yayın alanını bölmez; yayın alanını bölen cihaz
  yönlendiricidir.

#### Sonraki Adım

Bir çerçeve göndermek için hedefin donanım adresi bilinmelidir. Oysa uygulamalar hedefi IP
adresiyle belirtir; istemci `192.168.10.193` adresine göndereceğini bilir, ama o adresin
hangi donanım adresine karşılık geldiğini bilmez. Sonraki ders, bu iki adres uzayı arasında
köprü kuran adres çözümleme protokolünü ve onun bıraktığı güvenlik açıklığını ele alacak.

### ARP

Source: https://academia.sh/tr/kurslar/ag-modelleri/arp

IP adresinden donanım adresine çözümleme, istek–yanıt döngüsü, önbellek davranışı, vekil ve ücretsiz kullanım biçimleri ile adres zehirlenmesi.

Önceki ders bir çerçevenin hedef alanına donanım adresi yazıldığını gösterdi. Oysa
uygulamalar hedefi IP adresiyle belirtir: örnek ağdaki istemci `198.51.100.20` adresine
gitmek ister, geçidinin `192.168.10.193` olduğunu bilir, ancak bu adreslerin hiçbirinin
donanım karşılığını bilmez.

İki adres uzayı arasında bir köprü gerekir. Bu dersin sorusu, o köprünün nasıl kurulduğu ve
kurulurken hangi varsayımların yapıldığıdır.

#### İki Adres Uzayı

IP adresi ile MAC adresi arasında hesaplanabilir bir ilişki **yoktur**. Biri ağ
yöneticisinin veya bir kiralama hizmetinin atadığı mantıksal bir addır; diğeri arayüzün
donanımına bağlı fiziksel bir addır. Aynı makine ağdan ağa taşındığında IP adresi değişir,
MAC adresi değişmez.

Eşleme hesaplanamadığına göre **sorulmalıdır**. **ARP (Address Resolution Protocol)** bu
soruyu soran protokoldür. Yöntem doğrudandır: yerel ağın tamamına "şu IP adresi kimde?"
diye yayın yapılır ve adresin sahibi yanıt verir.

ARP, IP'nin içinde taşınmaz; Ethernet çerçevesinde `0x0806` tür değeriyle doğrudan
taşınır. Bu, önceki konuda söylenen "bazı protokoller iki katmanı birden ilgilendirir"
saptamasının somut örneğidir: ARP mesajı bir ağ katmanı adresi taşır, ama ağ katmanı
başlığı kullanmaz.

#### Mesajın Alanları

ARP mesajı 28 bayttır ve dokuz alandan oluşur.

| Alan | Boyut | Örnek değer |
|---|---|---|
| Donanım türü | 2 bayt | `1` (Ethernet) |
| Protokol türü | 2 bayt | `0x0800` (IPv4) |
| Donanım adresi uzunluğu | 1 bayt | `6` |
| Protokol adresi uzunluğu | 1 bayt | `4` |
| İşlem | 2 bayt | `1` istek, `2` yanıt |
| Gönderen donanım adresi | 6 bayt | Soruyu soranın MAC adresi |
| Gönderen protokol adresi | 4 bayt | Soruyu soranın IP adresi |
| Hedef donanım adresi | 6 bayt | İstekte sıfır, yanıtta doludur |
| Hedef protokol adresi | 4 bayt | Sorulan IP adresi |

Uzunluk alanlarının varlığı, protokolün Ethernet ve IPv4 ile sınırlı olmadığını gösterir:
biçim, farklı adres genişliklerine sahip teknolojiler için tasarlanmıştır.

Aşağıdaki program, örnek ağdaki istemcinin geçidini sorduğu isteği ve gelen yanıtı kurar.

```python
import ipaddress
import struct

BICIM = "!HHBBH6s4s6s4s"


def mac_paketle(mac: str) -> bytes:
    return bytes(int(x, 16) for x in mac.split(":"))


def mac_yaz(ham: bytes) -> str:
    return ":".join(f"{b:02x}" for b in ham)


def arp_mesaji(islem: int, gonderen_mac: str, gonderen_ip: str,
               hedef_mac: str, hedef_ip: str) -> bytes:
    return struct.pack(
        BICIM,
        1,          # donanım türü: Ethernet
        0x0800,     # protokol türü: IPv4
        6,          # donanım adresi uzunluğu
        4,          # protokol adresi uzunluğu
        islem,      # 1 = istek, 2 = yanıt
        mac_paketle(gonderen_mac), ipaddress.ip_address(gonderen_ip).packed,
        mac_paketle(hedef_mac), ipaddress.ip_address(hedef_ip).packed,
    )


def arp_yaz(ham: bytes) -> None:
    a = struct.unpack(BICIM, ham)
    islem = {1: "istek", 2: "yanıt"}[a[4]]
    print(f"işlem={islem:5s} gönderen={mac_yaz(a[5])} / {ipaddress.ip_address(a[6])}"
          f"  hedef={mac_yaz(a[7])} / {ipaddress.ip_address(a[8])}")


istek = arp_mesaji(1, "00:00:5e:00:53:01", "192.168.10.196",
                   "00:00:00:00:00:00", "192.168.10.193")
yanit = arp_mesaji(2, "00:00:5e:00:53:00", "192.168.10.193",
                   "00:00:5e:00:53:01", "192.168.10.196")

print("mesaj boyu:", len(istek), "bayt")
print(istek.hex())
arp_yaz(istek)
print(yanit.hex())
arp_yaz(yanit)
```

Çıktı:

```
mesaj boyu: 28 bayt
000108000604000100005e005301c0a80ac4000000000000c0a80ac1
işlem=istek gönderen=00:00:5e:00:53:01 / 192.168.10.196  hedef=00:00:00:00:00:00 / 192.168.10.193
000108000604000200005e005300c0a80ac100005e005301c0a80ac4
işlem=yanıt gönderen=00:00:5e:00:53:00 / 192.168.10.193  hedef=00:00:5e:00:53:01 / 192.168.10.196
```

İstek mesajındaki hedef donanım adresi alanı sıfırdır — sorunun kendisi budur. Yanıtta bu
alan dolar ve gönderen ile hedef rolleri yer değiştirir.

#### İstek ve Yanıtın Taşınması

Mesajın kendisi kadar, onu taşıyan çerçevenin adresleri de önemlidir:

| | ARP isteği | ARP yanıtı |
|---|---|---|
| Çerçeve kaynak adresi | `00:00:5e:00:53:01` | `00:00:5e:00:53:00` |
| Çerçeve hedef adresi | `ff:ff:ff:ff:ff:ff` | `00:00:5e:00:53:01` |
| Ulaştığı cihazlar | Yayın alanının tamamı | Yalnız soruyu soran |

İstek yayınla gider, çünkü sorulan adresin hangi cihazda olduğu bilinmemektedir. Yanıt ise
tekil adrese gider: yanıtlayan, isteğin içindeki gönderen alanlarından soru sahibinin her
iki adresini de öğrenmiştir.

Bu asimetrinin bir yan etkisi vardır: yayın alanındaki her cihaz isteği görür ve isterse
gönderenin eşlemesini kendi önbelleğine yazar. Bu davranış, ilerideki bölümde ele alınacak
güvenlik sorununun temelidir.

#### Yerel mi Uzak mı

Bir paket gönderilmeden önce verilen ilk karar, hedefin aynı ağda olup olmadığıdır. Karar,
hedef adresin kendi ağ maskesiyle karşılaştırılmasıyla verilir; maske aritmetiği Alt Ağlara
Bölme dersinde kurulacaktır. Kararın sonucu, **hangi adresin çözümleneceğini** belirler:

| Hedef | Aynı ağda mı | ARP ile sorulan adres | Çerçevenin hedef MAC adresi |
|---|---|---|---|
| `192.168.10.200` | Evet | `192.168.10.200` | Hedefin kendi MAC adresi |
| `198.51.100.20` | Hayır | `192.168.10.193` (geçit) | Geçidin MAC adresi |

İkinci satır, ağ mekaniğinin en sık yanlış anlaşılan noktasıdır. Uzak bir hedefe giden
pakette **IP hedef adresi uzak sunucudur, MAC hedef adresi geçittir.** İki adres farklı
cihazları gösterir ve bu bir tutarsızlık değildir: IP adresi uçtan uca hedefi, MAC adresi
bir sonraki sekmeyi belirtir.

Uzak sunucunun MAC adresi hiçbir zaman sorulmaz. Sorulamaz da: ARP isteği yayınla gider ve
yayın yönlendiriciyi geçmez.

#### ARP Önbelleği

Her çözümleme için yayın yapmak pahalı olacağından, sonuçlar bir **önbellekte** tutulur.
Örnek ağdaki istemcinin önbelleği, geçidiyle konuştuktan ve aynı bölümdeki bir yazıcıya
eriştikten sonra şu içeriğe sahiptir:

| IP adresi | MAC adresi | Durum |
|---|---|---|
| `192.168.10.193` | `00:00:5e:00:53:00` | Ulaşılabilir |
| `192.168.10.210` | `00:00:5e:00:53:04` | Ulaşılabilir |
| `192.168.10.205` | — | Eksik (yanıt beklenmekte) |

Girdiler kalıcı değildir. Bir süre kullanılmayan girdi silinir; silinme, bir cihazın ağ
kartı değiştiğinde veya adres başka bir cihaza geçtiğinde eşlemenin kendini düzeltmesini
sağlar. Girdi silindikten sonraki ilk gönderim yeniden çözümleme başlatır ve o gönderim
biraz gecikir.

Önbellek durumunu okumak için kullanılan komutlar ve çıktı biçimleri işletim sistemine göre
değişir. Değişmeyen içerik, yukarıdaki tabloda gösterilen üç bilgidir: protokol adresi,
donanım adresi ve girdinin durumu.

#### Ücretsiz ve Vekil Kullanım

**Ücretsiz ARP (gratuitous ARP)**, bir cihazın kendi adresini kimse sormadan duyurmasıdır:
hedef protokol adresi kendi adresi olan bir istek yayınlanır. Üç işe yarar. Adres
çakışmasını sezdirir — yanıt gelirse aynı adres başka bir cihazdadır. Yedek bir cihaz
devralma sırasında adresi üstlendiğini duyurur ve anahtarların tablolarını tazeler. Bir
arayüz açıldığında komşuların eski eşlemelerini günceller.

**Vekil ARP (proxy ARP)**, bir yönlendiricinin kendisine ait olmayan bir adres için yanıt
vermesidir. Sorulan adres uzaktaysa yönlendirici kendi MAC adresini verir ve trafiği
üstlenir. Ağ maskesi hatalı yapılandırılmış istemcileri çalışır durumda tutar; ancak
sorunun kendisini gizlediği ve önbelleklerde birbirinin aynı çok sayıda girdi ürettiği için
tanıyı zorlaştırır.

#### ARP Zehirlenmesi

ARP'nin tasarımında kimlik doğrulama yoktur. Yanıtı kimin gönderdiği denetlenmez; hatta
istenmemiş bir yanıt bile birçok gerçekleştirimde önbelleğe yazılır. Bunun sonucu **ARP
zehirlenmesi (ARP poisoning)** adı verilen saldırıdır.

Aynı yayın alanındaki bir cihaz, `192.168.10.193` adresinin kendi MAC adresinde olduğunu
bildiren yanıtlar gönderirse, komşularının önbellekleri bozulur ve geçide gitmesi gereken
trafik saldırgana yönlenir. Saldırgan trafiği geçide ileterek bağlantıyı ayakta tutabilir;
bu durumda kullanıcı hiçbir kesinti görmez.

Açığın kaynağı bir gerçekleştirim hatası değil, protokolün tasarım varsayımıdır: aynı yerel
ağdaki cihazlar güvenilir kabul edilmiştir. Karşı önlemler bu yüzden ARP'nin dışındadır:

- Yayın alanlarını küçültmek ve güvenilmeyen cihazları ayrı ağlara koymak.
- Anahtar üzerinde ARP denetimi: bir bağlantı noktasından yalnızca o cihaza atanmış
  adreslerin duyurulmasına izin vermek.
- Kritik eşlemeleri sabitlemek.
- Uçtan uca şifreleme ve kimlik doğrulama kullanmak: trafiği dinleyen bir aracı, içeriği
  okuyamaz veya değiştiremez.

Son madde, uçtan uca ilkesinin bir uygulamasıdır: ağın içindeki bir katmanın güvenlik sözü
veremediği durumda, sözün uçlarda verilmesi gerekir.

#### IPv6'daki Karşılığı

IPv6, ARP'yi kullanmaz. Karşılık gelen işlev **komşu keşfi (neighbor discovery)** adıyla
ICMPv6'nın içine taşınmıştır ve yayın yerine çok noktaya gönderim kullanır: soru, yalnızca
sorulan adresle ilgili çok noktaya gönderim grubuna iletilir. Bu, yayın alanındaki her
cihazın her soruyu işlemesini önler. Komşu keşfi ayrıca adres çakışması sınaması ve
yönlendirici duyurusu gibi işlevleri de üstlenir; bunlar IPv6 dersinde ele alınacaktır.

#### Özet

- IP adresi ile MAC adresi arasında hesaplanabilir bir ilişki yoktur; eşleme ARP ile
  sorulur.
- ARP isteği yayınla gider, yanıt tekil adrese döner; mesaj 28 bayttır ve IP başlığı
  kullanmaz.
- Hedef aynı ağdaysa hedefin kendi adresi, değilse geçidin adresi çözümlenir; uzak hedefe
  giden pakette IP hedefi sunucu, MAC hedefi geçittir.
- Çözümleme sonuçları süreli bir önbellekte tutulur; süre dolduğunda eşleme kendini
  düzeltir.
- Ücretsiz ARP adres duyurusu ve çakışma sınaması için, vekil ARP başka bir ağın adresini
  üstlenmek için kullanılır.
- ARP'de kimlik doğrulama yoktur; zehirlenmeye karşı önlemler yayın alanını küçültmek,
  anahtar düzeyinde denetim ve uçtan uca şifrelemedir.

#### Sonraki Adım

Buraya kadar IP adresleri bir etiket gibi kullanıldı: `192.168.10.196` yazıldı, anlamı
sorgulanmadı. Oysa bu sayının içinde bir yapı vardır — bir bölümü ağı, bir bölümü o ağdaki
düğümü gösterir. Sonraki ders IPv4 adresinin bit yapısını, ağ ile düğüm bölümlerinin
ayrımını ve özel amaçlar için ayrılmış blokları ele alacak.

### IPv4 Adresleme

Source: https://academia.sh/tr/kurslar/ag-modelleri/ipv4-adresleme

32 bitlik adresin yapısı, ağ ve düğüm bölümlerinin ayrımı, sınıflı adreslemenin mirası ve özel amaçlar için ayrılmış bloklar.

Önceki iki ders IP adreslerini bir etiket gibi kullandı: `192.168.10.196` yazıldı, hangi
cihazı gösterdiği söylendi, ama sayının kendisi çözümlenmedi. Oysa bu sayının içinde
yönlendirmenin dayandığı bir yapı vardır.

Bu dersin sorusu, o yapının ne olduğudur: 32 bitin hangi bölümü ağı, hangi bölümü o ağdaki
düğümü gösterir ve bu bölünme kim tarafından belirlenir?

#### Adresin Yapısı

Bir IPv4 adresi **32 bitlik işaretsiz bir tam sayıdır**. Okunabilirlik için dört bayta
bölünüp her bayt ondalık yazılır ve aralarına nokta konur — buna **noktalı ondalık gösterim**
denir. Gösterim bir kolaylıktır; adresin kendisi bir bit dizisidir.

```python
import ipaddress

adres = ipaddress.ip_address("192.168.10.196")
print("tam sayı  :", int(adres))
print("ikilik    :", format(int(adres), "032b"))
print("bayt bayt :", " ".join(f"{b:08b}" for b in adres.packed))
print("onaltılık :", adres.packed.hex())
```

```
tam sayı  : 3232238276
ikilik    : 11000000101010000000101011000100
bayt bayt : 11000000 10101000 00001010 11000100
onaltılık : c0a80ac4
```

Dört baytın karşılıkları doğrudan okunur: `11000000` = 192, `10101000` = 168, `00001010` =
10, `11000100` = 196. Taban dönüşümleri, Bilgisayarlar Nasıl Çalışır kursundaki İkilik Sayı
Sistemi ve Onaltılık ve Sekizlik Tabanlar derslerinde kurulan yöntemin doğrudan
uygulanmasıdır.

Toplam adres sayısı $2^{32} = 4\,294\,967\,296$'dır. Bu sayının, dünyadaki uca bağlı cihaz
sayısı karşısında yetersiz kalması, bu kursta ele alınan birçok mekanizmanın — adres
dönüştürme, değişken uzunluklu alt ağlar, IPv6 — varlık nedenidir.

#### Ağ ve Düğüm Bölümü

Adres tek parça bir kimlik değildir; **iki bölüme** ayrılır:

- **Ağ bölümü (network portion):** Soldaki bitler. Adresin hangi ağa ait olduğunu söyler.
  Aynı ağdaki tüm adreslerde aynıdır.
- **Düğüm bölümü (host portion):** Sağdaki bitler. Adresi o ağ içinde ayırt eder.

Bölünme noktası **önek uzunluğu (prefix length)** ile belirtilir ve adresin sonuna eğik
çizgiyle yazılır: `192.168.10.196/24` gösteriminde soldaki 24 bit ağı, kalan 8 bit düğümü
belirtir.

| Gösterim | Ağ bölümü | Düğüm bölümü |
|---|---|---|
| `192.168.10.196/24` | `11000000 10101000 00001010` | `11000100` |
| `192.168.10.196/27` | `11000000 10101000 00001010 110` | `00100` |

Aynı adres, farklı önek uzunluklarıyla farklı ağlara ait olur. Bu, çok önemli bir sonuç
doğurur: **bir adres tek başına eksik bilgidir.** Bir arayüzü yapılandırmak için adres ve
önek uzunluğu birlikte verilmelidir; ikisinden biri eksikse hangi hedeflerin yerel olduğu
belirlenemez.

Bölünmenin yönlendirmedeki karşılığı doğrudandır. Yönlendiriciler tek tek düğümleri değil,
**ağları** bilir. Yönlendirme tablosundaki bir satır, bir önek ile bir sonraki sekmeyi
eşler; tablo satır sayısı düğüm sayısıyla değil, ağ sayısıyla orantılıdır. Adresleri
hiyerarşik dağıtmanın nedeni budur.

#### Sınıflı Adreslemenin Mirası

IPv4 adresleri başlangıçta **sınıflara** ayrılmıştı: ağ ile düğüm arasındaki sınır, adresin
ilk bitlerine bakılarak belirlenirdi.

| Sınıf | İlk bitler | Adres aralığı | Ağ bölümü | Ağ başına düğüm |
|---|---|---|---|---|
| A | `0` | 0.0.0.0 – 127.255.255.255 | 8 bit | 16 777 214 |
| B | `10` | 128.0.0.0 – 191.255.255.255 | 16 bit | 65 534 |
| C | `110` | 192.0.0.0 – 223.255.255.255 | 24 bit | 254 |
| D | `1110` | 224.0.0.0 – 239.255.255.255 | Çok noktaya gönderim | — |
| E | `1111` | 240.0.0.0 – 255.255.255.255 | Ayrılmış | — |

Bu düzenin iki kusuru vardı. Birincisi, sınırın yalnızca üç değer alabilmesi adres israfına
yol açıyordu: 300 düğümlük bir kuruluşa C sınıfı yetmez, B sınıfı verildiğinde 65 234 adres
boşa gider. İkincisi, yönlendirme tablolarının boyutu denetlenemiyordu: her ağ ayrı bir
satır gerektiriyor, satırlar birleştirilemiyordu.

Çözüm, sınırı adresten bağımsız kılmaktı. **Sınıfsız alanlar arası yönlendirme (classless
inter-domain routing, CIDR)** ile önek uzunluğu adresle birlikte açıkça taşınır ve 0 ile 32
arasında herhangi bir değer alabilir. Sınıflar artık adres tahsisinde kullanılmaz; ancak
bıraktıkları izler sürer — bazı araçların varsayılan maske önerileri ve bazı belgelerdeki
"C sınıfı ağ" ifadesi bu mirastandır.

Bu kurs sınıfsız gösterimi esas alır. Sınıf adları yalnızca tarihsel bağlam için anılır.

#### Özel Amaçlı Bloklar

Adres uzayının bir bölümü, genel İnternet'te yönlendirilmemek üzere ayrılmıştır.

| Blok | Amaç | Genel İnternet'te yönlendirilir mi |
|---|---|---|
| `10.0.0.0/8` | Özel kullanım | Hayır |
| `172.16.0.0/12` | Özel kullanım | Hayır |
| `192.168.0.0/16` | Özel kullanım | Hayır |
| `127.0.0.0/8` | Geri döngü (kendi makinesi) | Hayır |
| `169.254.0.0/16` | Yerel bağlantı (adres alınamadığında) | Hayır |
| `100.64.0.0/10` | Sağlayıcı düzeyi adres dönüştürme | Hayır |
| `224.0.0.0/4` | Çok noktaya gönderim | Koşullu |
| `255.255.255.255` | Sınırlı yayın | Hayır |
| `192.0.2.0/24`, `198.51.100.0/24`, `203.0.113.0/24` | Belgeleme | Hayır |

Üç **özel kullanım (private use)** bloğu, kurum içi ağlarda serbestçe kullanılabilir. Farklı
kurumlar aynı özel adresleri aynı anda kullanabilir; çakışma olmaz, çünkü bu adresler
kurumun dışına çıkmaz. Dışarıya çıkış, adres dönüştürme ile sağlanır ve NAT ve PAT dersinin
konusudur.

**Geri döngü (loopback)** bloğu makinenin kendisini gösterir; bu bloğa gönderilen paket
hiçbir zaman ağ arayüzüne ulaşmaz. **Yerel bağlantı (link-local)** bloğu, bir arayüz adres
alamadığında kendi kendine seçtiği geçici adres içindir; bu adresle yalnızca aynı ağdaki
diğer cihazlara erişilir.

Belgeleme blokları, bu kursta genel adres gerektiren tüm örneklerde kullanılır. Kurumun dış
adresi `203.0.113.10`, hedef sunucu `198.51.100.20` bu bloklardandır.

```python
import ipaddress

for metin in ("10.0.0.1", "127.0.0.1", "169.254.7.3", "224.0.0.251",
              "192.168.10.196", "198.51.100.20"):
    a = ipaddress.ip_address(metin)
    print(f"{metin:16s} özel={str(a.is_private):5s} geri_döngü={str(a.is_loopback):5s} "
          f"yerel_bağlantı={str(a.is_link_local):5s} çok_noktalı={a.is_multicast}")
```

```
10.0.0.1         özel=True  geri_döngü=False yerel_bağlantı=False çok_noktalı=False
127.0.0.1        özel=True  geri_döngü=True  yerel_bağlantı=False çok_noktalı=False
169.254.7.3      özel=True  geri_döngü=False yerel_bağlantı=True  çok_noktalı=False
224.0.0.251      özel=False geri_döngü=False yerel_bağlantı=False çok_noktalı=True
192.168.10.196   özel=True  geri_döngü=False yerel_bağlantı=False çok_noktalı=False
198.51.100.20    özel=True  geri_döngü=False yerel_bağlantı=False çok_noktalı=False
```

Son satır dikkat ister: `198.51.100.20` bir belgeleme adresidir, özel kullanım bloğunda
değildir; buna karşın `is_private` özelliği doğru döner. Kütüphanenin bu özelliği "özel
kullanım bloğunda mı" değil, "genel İnternet'te yönlendirilebilir mi" sorusunu yanıtlar.
Bir kütüphane işlevinin adı ile anlamı arasındaki bu tür farklar, belgelenmiş anlamın
okunmasını zorunlu kılar.

#### Adres Kime Aittir

Bir IP adresi makineye değil, **arayüze** aittir. İki arayüzü olan bir makinenin iki adresi
vardır; aynı arayüze birden çok adres de atanabilir. Yönlendiriciler bu kuralın en açık
örneğidir: örnek ağdaki kurum yönlendiricisinin iç arayüzü `192.168.10.193`, dış arayüzü
`203.0.113.10` adresini taşır ve bu iki adres farklı ağlara aittir.

Bu ayrım tanıda işe yarar. "Sunucuya ulaşamıyorum" ifadesi eksiktir; sunucunun hangi
arayüzüne ulaşılamadığı sorulmalıdır. Bir arayüz üzerinden erişilebilen bir makine, başka
bir arayüzü üzerinden erişilemez durumda olabilir.

#### Örnek Ağın Bloğu

Kurumun iç ağı `192.168.10.0/24` bloğunu kullanır. Seçimin gerekçeleri şunlardır:

- Blok özel kullanım aralığındadır; sağlayıcıdan tahsis gerektirmez.
- 24 bitlik önek, 8 bitlik düğüm bölümü bırakır: $2^8 = 256$ adres.
- Bu 256 adresin ikisi ayrılmıştır — en küçüğü ağın kendisini, en büyüğü yayın adresini
  gösterir — geriye 254 kullanılabilir adres kalır.

Kurumun bölümlerinde toplam 182 düğüm bulunmaktadır: misafir kablosuz ağında 100,
laboratuvarda 50, yönetimde 20, sunucu odasında 10 ve yönlendiriciler arasındaki noktadan
noktaya bağlantıda 2. Sayı 254'ten küçük olduğuna göre blok yeterlidir — ancak bölümler tek
bir yayın alanında toplanamaz.

Neden toplanamayacağı önceki derste görülmüştü: yayın alanı büyüdükçe her yayın çerçevesinin
maliyeti artar ve bölümler arasında hiçbir erişim denetimi kurulamaz. Bloğun bölümlere
ayrılması gerekir.

#### Özet

- IPv4 adresi 32 bitlik bir tam sayıdır; noktalı ondalık gösterim yalnızca okunabilirlik
  içindir.
- Adres ağ ve düğüm bölümlerine ayrılır; sınır önek uzunluğuyla belirtilir ve adresin
  kendisinden okunamaz.
- Önek uzunluğu olmadan bir adres eksik bilgidir; hangi hedeflerin yerel olduğu
  belirlenemez.
- Sınıflı adresleme sınırı üç değere hapsediyor ve israfa yol açıyordu; CIDR ile önek
  uzunluğu 0–32 arasında serbest bırakıldı.
- Özel kullanım, geri döngü, yerel bağlantı, çok noktaya gönderim ve belgeleme blokları
  genel İnternet'te yönlendirilmez.
- Adres makineye değil arayüze aittir; bir makinenin birden çok adresi olabilir.

#### Sonraki Adım

`192.168.10.0/24` bloğu, kurumun bölümlerine tek parça hâlinde verilemez. Bloğun her
bölüme ayrı bir ağ düşecek biçimde kesilmesi gerekir ve kesme işlemi düğüm bölümünden bit
ödünç alarak yapılır. Sonraki ders maske aritmetiğini kuracak, ağ ve yayın adreslerinin
nasıl hesaplandığını gösterecek ve bloğu eşit parçalara bölen ilk planı çıkaracak.

### Alt Ağlara Bölme

Source: https://academia.sh/tr/kurslar/ag-modelleri/alt-aglara-bolme

Ağ maskesi aritmetiği, ağ ve yayın adreslerinin hesabı, bit ödünç alma ve örnek bloğun eşit alt ağlara bölünmesi.

Önceki ders `192.168.10.0/24` bloğunun kurumun 182 düğümü için sayıca yeterli olduğunu,
ancak bölümlerin tek bir yayın alanında toplanamayacağını gösterdi. Blok kesilmelidir.

Kesme işleminin adı **alt ağlara bölme (subnetting)**dir ve tek bir düzeneğe dayanır: düğüm
bölümünden bit ödünç alıp ağ bölümüne eklemek. Bu dersin sorusu, bu ödünç almanın
aritmetiğidir.

#### Ağ Maskesi

**Ağ maskesi (network mask)**, adresin hangi bitlerinin ağ bölümüne ait olduğunu gösteren 32
bitlik bir örüntüdür: ağ bitleri 1, düğüm bitleri 0'dır. Maskede 1'ler her zaman soldadır ve
kesintisizdir; `255.255.0.255` gibi bir örüntü geçerli bir maske değildir.

Önek uzunluğu ile maske aynı bilgiyi iki ayrı biçimde taşır:

| Önek | Maske | Düğüm biti | Blok başına adres |
|---|---|---|---|
| /24 | 255.255.255.0 | 8 | 256 |
| /25 | 255.255.255.128 | 7 | 128 |
| /26 | 255.255.255.192 | 6 | 64 |
| /27 | 255.255.255.224 | 5 | 32 |
| /28 | 255.255.255.240 | 4 | 16 |
| /29 | 255.255.255.248 | 3 | 8 |
| /30 | 255.255.255.252 | 2 | 4 |

Son sütun $2^{32 - \text{önek}}$ ile hesaplanır. Önek bir bit uzadığında blok yarıya iner —
bu ikilik ilişki, plan yaparken tek tek hesap yapmayı gereksiz kılar.

#### Ağ ve Yayın Adresleri

Bir adresin ait olduğu ağ, adres ile maskenin **bit düzeyinde VE** işlemine sokulmasıyla
bulunur. İşlem, Bilgisayarlar Nasıl Çalışır kursundaki Bit Düzeyi İşlemler dersinde
tanıtılan maskeleme kalıbının doğrudan uygulanmasıdır: maskenin 0 olduğu bitler silinir, 1
olduğu bitler korunur.

Yayın adresi ise düğüm bitlerinin tümü 1 yapılarak bulunur. Bunun için maskenin tersi olan
**joker maske (wildcard mask)** kullanılır ve VEYA işlemine sokulur.

$$
\text{ağ} = \text{adres} \mathbin{\&} \text{maske}, \qquad
\text{yayın} = \text{ağ} \mathbin{|} \lnot\text{maske}
$$

`192.168.10.196` adresi ve `255.255.255.192` maskesi için:

```python
import ipaddress

adres = ipaddress.ip_address("192.168.10.196")
maske = ipaddress.ip_address("255.255.255.192")
ag = ipaddress.ip_address(int(adres) & int(maske))
joker = ipaddress.ip_address(int(maske) ^ 0xFFFFFFFF)
yayin = ipaddress.ip_address(int(ag) | int(joker))

print("adres :", format(int(adres), "032b"), adres)
print("maske :", format(int(maske), "032b"), maske)
print("ağ    :", format(int(ag), "032b"), ag)
print("joker :", format(int(joker), "032b"), joker)
print("yayın :", format(int(yayin), "032b"), yayin)
```

```
adres : 11000000101010000000101011000100 192.168.10.196
maske : 11111111111111111111111111000000 255.255.255.192
ağ    : 11000000101010000000101011000000 192.168.10.192
joker : 00000000000000000000000000111111 0.0.0.63
yayın : 11000000101010000000101011111111 192.168.10.255
```

Son iki bit dışında ağ bölümü korunmuştur: `11000100` baytının üst altı biti `110001`, düğüm
bitleri ise `00`'dır. Ağ adresi `192.168.10.192`, yayın adresi `192.168.10.255`, aradaki 62
adres kullanılabilir düğüm adresleridir.

#### Kullanılabilir Düğüm Sayısı

Her ağda iki adres ayrılmıştır: düğüm bitlerinin tümü 0 olan adres **ağın kendisini**, tümü
1 olan adres **yayın adresini** gösterir. Hiçbiri bir arayüze atanamaz. Kullanılabilir düğüm
sayısı:

$$
N = 2^{32 - p} - 2
$$

| Önek | Toplam adres | Kullanılabilir düğüm |
|---|---|---|
| /24 | 256 | 254 |
| /25 | 128 | 126 |
| /26 | 64 | 62 |
| /27 | 32 | 30 |
| /28 | 16 | 14 |
| /29 | 8 | 6 |
| /30 | 4 | 2 |

Noktadan noktaya bağlantılarda `/31` öneki de kullanılabilir: iki cihazın doğrudan
bağlandığı bir hatta yayın adresine gerek olmadığı için her iki adres de atanabilir. Bu
kurs, örnek planında daha yaygın olan `/30` seçimini kullanır.

Ters yönde hesap, plan yaparken kullanılan hesaptır: $N$ düğüm için gereken önek uzunluğu,
$2^{32-p} - 2 \ge N$ eşitsizliğini sağlayan en büyük $p$'dir.

| Gereken düğüm | En küçük yeterli blok | Kullanılabilir | Boşa giden |
|---|---|---|---|
| 2 | /30 | 2 | 0 |
| 10 | /28 | 14 | 4 |
| 20 | /27 | 30 | 10 |
| 50 | /26 | 62 | 12 |
| 100 | /25 | 126 | 26 |

#### Bit Ödünç Almak

Bir bloğu bölmek, düğüm bölümünden bit ödünç alıp ağ bölümüne eklemektir. Ödünç alınan her
bit alt ağ sayısını iki katına çıkarır, blok boyunu yarıya indirir:

| Ödünç alınan bit | Yeni önek | Alt ağ sayısı | Alt ağ başına düğüm |
|---|---|---|---|
| 0 | /24 | 1 | 254 |
| 1 | /25 | 2 | 126 |
| 2 | /26 | 4 | 62 |
| 3 | /27 | 8 | 30 |
| 4 | /28 | 16 | 14 |

Alt ağ sayısı $2^k$, alt ağ başına düğüm sayısı $2^{8-k} - 2$'dir; çarpımları hiçbir zaman
254'e ulaşmaz, çünkü her alt ağ kendi ağ ve yayın adresini harcar. Bölme, adres kaybı
karşılığında ayrım kazandırır.

Alt ağların **başlangıç adresleri**, blok boyunun katlarıdır. `/26` bölmesinde blok boyu 64
olduğundan başlangıçlar 0, 64, 128, 192'dir. Bu artış miktarına **blok adımı** denir ve
maskenin son sıfırdan farklı baytından okunur: `255.255.255.192` maskesinde $256 - 192 = 64$.

#### Örnek Bloğu Dörde Bölmek

Kurumun dört bölümü ve bir noktadan noktaya bağlantısı vardır. İlk deneme, bloğu eşit dört
parçaya bölmektir.

```python
import ipaddress

blok = ipaddress.ip_network("192.168.10.0/24")
for alt in blok.subnets(new_prefix=26):
    dugumler = list(alt.hosts())
    print(f"{str(alt):18s} maske={alt.netmask:15s} ağ={str(alt.network_address):15s} "
          f"ilk={str(dugumler[0]):15s} son={str(dugumler[-1]):15s} "
          f"yayın={str(alt.broadcast_address):15s} n={len(dugumler)}")
```

```
192.168.10.0/26    maske=255.255.255.192 ağ=192.168.10.0    ilk=192.168.10.1    son=192.168.10.62   yayın=192.168.10.63   n=62
192.168.10.64/26   maske=255.255.255.192 ağ=192.168.10.64   ilk=192.168.10.65   son=192.168.10.126  yayın=192.168.10.127  n=62
192.168.10.128/26  maske=255.255.255.192 ağ=192.168.10.128  ilk=192.168.10.129  son=192.168.10.190  yayın=192.168.10.191  n=62
192.168.10.192/26  maske=255.255.255.192 ağ=192.168.10.192  ilk=192.168.10.193  son=192.168.10.254  yayın=192.168.10.255  n=62
```

Bu tablo, elle yapılan hesabın denetimidir. Aynı sonuç kâğıt üzerinde de çıkarılabilir: blok
adımı 64, başlangıçlar 0/64/128/192, her bloğun yayın adresi bir sonraki başlangıcın bir
eksiğidir.

Planı gereksinimlerle karşılaştıralım:

| Bölüm | Gereken düğüm | Ayrılan blok | Kullanılabilir | Sonuç |
|---|---|---|---|---|
| Misafir kablosuz | 100 | `192.168.10.0/26` | 62 | Yetersiz |
| Laboratuvar | 50 | `192.168.10.64/26` | 62 | Yeterli, 12 boş |
| Yönetim | 20 | `192.168.10.128/26` | 62 | Yeterli, 42 boş |
| Sunucu | 10 | `192.168.10.192/26` | 62 | Yeterli, 52 boş |
| Noktadan noktaya bağlantı | 2 | — | — | Blok kalmadı |

Plan iki noktada başarısızdır. Misafir ağı 100 düğüm ister, 62 adres alır. Noktadan noktaya
bağlantıya verilecek blok kalmamıştır. Buna karşılık sunucu ağında 52 adres boş durmaktadır.

#### Eşit Bölmenin Zorunlu Kusuru

Başarısızlığın nedeni bir hesap hatası değil, yöntemin kendisidir. Eşit bölmede **tüm alt
ağlar en büyük gereksinime göre boyutlanmak zorundadır**. En büyük bölüm 100 düğüm
istiyorsa her alt ağ en az `/25` olmalıdır; `/25` blokları ise `/24` içine yalnızca iki tane
sığar.

Gereken toplam adres, eşit bölmede $5 \times 128 = 640$'tır. Elde 256 adres vardır. Oysa
bölümlerin gerçek toplam gereksinimi 182'dir. Aradaki fark tamamen yöntemden kaynaklanır.

Sorunun kaynağı tek bir varsayımdır: **tüm alt ağların aynı maskeyi taşıması gerektiği.**
Bu varsayım CIDR ile birlikte ortadan kalkmıştır ve kaldırıldığında plan sığar.

#### Bir Adres Hangi Alt Ağa Düşer

Alt ağ planı kurulduktan sonra sık sorulan soru, verilen bir adresin hangi alt ağa ait
olduğudur. Yanıt, adresin plandaki her maskeyle VE'lenip sonucun ağ adresiyle
karşılaştırılmasıyla bulunur.

Aynı adres, farklı maskelerle farklı ağlara düşer:

| Adres | Maske | Ağ adresi | Yayın adresi |
|---|---|---|---|
| `192.168.10.196` | /24 | `192.168.10.0` | `192.168.10.255` |
| `192.168.10.196` | /25 | `192.168.10.128` | `192.168.10.255` |
| `192.168.10.196` | /26 | `192.168.10.192` | `192.168.10.255` |
| `192.168.10.196` | /27 | `192.168.10.192` | `192.168.10.223` |
| `192.168.10.196` | /28 | `192.168.10.192` | `192.168.10.207` |

Tablo, önceki derste söylenen saptamanın sayısal karşılığıdır: adres tek başına eksik
bilgidir. Bir istemcinin maskesi yanlış yapılandırılmışsa, yerel olan hedefleri uzak veya
uzak olan hedefleri yerel sanar. İlk durumda trafiği gereksiz yere geçide gönderir; ikinci
durumda hiç ulaşamayacağı bir adres için ARP isteği yayınlar ve yanıt alamaz.

#### Özet

- Ağ maskesi, adresin ağ bitlerini 1 ile işaretleyen 32 bitlik örüntüdür; 1'ler soldadır ve
  kesintisizdir.
- Ağ adresi adres ile maskenin VE'lenmesiyle, yayın adresi ağ ile joker maskenin
  VEYA'lanmasıyla bulunur.
- Her alt ağda iki adres ayrılmıştır; kullanılabilir düğüm sayısı $2^{32-p} - 2$'dir.
- Ödünç alınan her bit alt ağ sayısını ikiye katlar, alt ağ boyunu yarıya indirir; blok
  adımı, 256 ile maskenin son anlamlı baytının farkıdır.
- `192.168.10.0/24` bloğunu dört eşit `/26` parçasına bölmek misafir ağını karşılamaz ve
  bağlantı ağına yer bırakmaz; eşit bölmede gereken toplam 640 adrestir.
- Eşit bölmenin kusuru, tüm alt ağların en büyük gereksinime göre boyutlanmak zorunda
  olmasıdır.

#### Sonraki Adım

Tüm alt ağların aynı maskeyi taşıması bir zorunluluk değildir. Her bölüme kendi
gereksinimine göre bir maske verilirse, aynı `192.168.10.0/24` bloğu beş ağın hepsini
karşılar ve geriye artan adres bile kalır. Sonraki ders bu planı adım adım kuracak, her
bölümün ağ ve yayın adreslerini hesaplayacak ve planın çakışmasız olduğunu sınayacak.

### Değişken Uzunluklu Alt Ağlar

Source: https://academia.sh/tr/kurslar/ag-modelleri/degisken-uzunluklu-alt-aglar

Farklı maskelerle bölme yöntemi, hizalama kuralı, örnek kurumsal planın kurulması ve çakışma sınaması ile yol özetleme.

Önceki ders eşit bölmenin `192.168.10.0/24` bloğunu kurumun gereksinimlerine
yetiştiremediğini gösterdi: yöntem 640 adres istiyordu, elde 256 vardı. Kusurun kaynağı tüm
alt ağların aynı maskeyi taşıması zorunluluğuydu.

CIDR bu zorunluluğu kaldırır. **Değişken uzunluklu alt ağ maskesi (variable length subnet
mask, VLSM)** yaklaşımında her alt ağ kendi gereksinimine göre boyutlanır. Bu dersin sorusu,
bu bölmenin hangi kurala göre yapılacağı ve sonucun nasıl sınanacağıdır.

#### Hizalama Kuralı

Değişken bölmede yalnızca tek bir kısıtlama vardır: **bir alt ağın başlangıç adresi, kendi
boyutunun katı olmalıdır.**

Kural bir düzenleme tercihi değil, maske aritmetiğinin zorunlu sonucudur. Bir `/27` bloğunun
son beş biti düğüm bitidir ve ağ adresinde hepsi sıfır olmalıdır; bu ancak adresin 32'nin
katı olmasıyla sağlanır. `192.168.10.200/27` gösterimi geçerli bir ağ tanımlamaz, çünkü 200
sayısı 32'nin katı değildir — bu adres `192.168.10.192/27` ağının içindeki bir düğümdür.

| Önek | Blok boyu | Geçerli başlangıçlar (son bayt) |
|---|---|---|
| /25 | 128 | 0, 128 |
| /26 | 64 | 0, 64, 128, 192 |
| /27 | 32 | 0, 32, 64, …, 224 |
| /28 | 16 | 0, 16, 32, …, 240 |
| /30 | 4 | 0, 4, 8, …, 252 |

Kuralın planlamadaki sonucu şudur: **büyük bloklar önce yerleştirilmelidir.** Küçük bloklar
önce yerleştirilirse, sonraki büyük blok kendi hizasına atlamak zorunda kalır ve arada
kullanılamayan bir boşluk bırakır.

#### Planın Kurulması

Yöntem üç adımdır:

1. Bölümleri düğüm gereksinimine göre **azalan** sırala.
2. Her bölüm için $2^{32-p} - 2 \ge N$ eşitsizliğini sağlayan en uzun öneki seç.
3. Blokları sırayla, hizalamaya uyarak yerleştir.

Kurumun gereksinimleri sıralanmış hâlde: misafir kablosuz 100, laboratuvar 50, yönetim 20,
sunucu 10, noktadan noktaya bağlantı 2 düğüm.

**Misafir kablosuz, 100 düğüm.** $2^7 - 2 = 126 \ge 100$ olduğundan `/25` yeterlidir; `/26`
yalnızca 62 verir. Blok `192.168.10.0/25`, aralık `.1` – `.126`, yayın `.127`.

**Laboratuvar, 50 düğüm.** `/26` 62 düğüm verir. Sıradaki hizalı adres 128'dir. Blok
`192.168.10.128/26`, aralık `.129` – `.190`, yayın `.191`.

**Yönetim, 20 düğüm.** `/27` 30 düğüm verir. Sıradaki hizalı adres 192'dir. Blok
`192.168.10.192/27`, aralık `.193` – `.222`, yayın `.223`.

**Sunucu, 10 düğüm.** `/28` 14 düğüm verir. Sıradaki hizalı adres 224'tür. Blok
`192.168.10.224/28`, aralık `.225` – `.238`, yayın `.239`.

**Noktadan noktaya bağlantı, 2 düğüm.** `/30` tam olarak 2 düğüm verir. Sıradaki hizalı
adres 240'tır. Blok `192.168.10.240/30`, aralık `.241` – `.242`, yayın `.243`.

#### Planın Doğrulanması

Elle yapılan hesap, programla sınanmalıdır. Aşağıdaki program yöntemi kodlar ve planı
üretir.

```python
import ipaddress
import math

BLOK = ipaddress.ip_network("192.168.10.0/24")
IHTIYAC = [
    ("Misafir kablosuz", 100),
    ("Laboratuvar", 50),
    ("Yönetim", 20),
    ("Sunucu", 10),
    ("Bağlantı", 2),
]


def gereken_onek(dugum: int) -> int:
    """dugum adet kullanılabilir adres için en uzun yeterli önek."""
    return 32 - math.ceil(math.log2(dugum + 2))


def vlsm_plani(blok: ipaddress.IPv4Network,
               ihtiyac: list[tuple[str, int]]) -> list[tuple]:
    sirali = sorted(ihtiyac, key=lambda k: k[1], reverse=True)
    imlec = int(blok.network_address)
    plan = []
    for ad, dugum in sirali:
        onek = gereken_onek(dugum)
        boyut = 2 ** (32 - onek)
        if imlec % boyut:                       # hizalama: blok kendi boyuna oturmalı
            imlec += boyut - (imlec % boyut)
        alt = ipaddress.ip_network((imlec, onek))
        if not alt.subnet_of(blok):
            raise ValueError(f"{ad} için yer kalmadı")
        plan.append((ad, dugum, alt))
        imlec += boyut
    return plan


plan = vlsm_plani(BLOK, IHTIYAC)
print(f"{'Bölüm':18s} {'İhtiyaç':>7s}  {'Blok':<19s} {'Maske':<16s} "
      f"{'Yayın':<15s} {'Aralık':<31s} {'Boş':>4s}")
for ad, dugum, alt in plan:
    d = list(alt.hosts())
    aralik = f"{d[0]} - {d[-1]}"
    print(f"{ad:18s} {dugum:7d}  {str(alt):<19s} {str(alt.netmask):<16s} "
          f"{str(alt.broadcast_address):<15s} {aralik:<31s} {len(d) - dugum:4d}")

kullanilan = sum(alt.num_addresses for _, _, alt in plan)
print(f"\nkullanılan adres: {kullanilan} / {BLOK.num_addresses}  "
      f"artan: {BLOK.num_addresses - kullanilan}")

aglar = [alt for _, _, alt in plan]
for i in range(len(aglar)):
    for j in range(i + 1, len(aglar)):
        assert not aglar[i].overlaps(aglar[j]), (aglar[i], aglar[j])
print("çakışma sınaması: geçti")
```

Çıktı:

```
Bölüm              İhtiyaç  Blok                Maske            Yayın           Aralık                           Boş
Misafir kablosuz       100  192.168.10.0/25     255.255.255.128  192.168.10.127  192.168.10.1 - 192.168.10.126     26
Laboratuvar             50  192.168.10.128/26   255.255.255.192  192.168.10.191  192.168.10.129 - 192.168.10.190   12
Yönetim                 20  192.168.10.192/27   255.255.255.224  192.168.10.223  192.168.10.193 - 192.168.10.222   10
Sunucu                  10  192.168.10.224/28   255.255.255.240  192.168.10.239  192.168.10.225 - 192.168.10.238    4
Bağlantı                 2  192.168.10.240/30   255.255.255.252  192.168.10.243  192.168.10.241 - 192.168.10.242    0

kullanılan adres: 244 / 256  artan: 12
çakışma sınaması: geçti
```

Elle yapılan hesabın tamamı doğrulanmıştır. Eşit bölmenin 640 adres istediği yerde değişken
bölme 244 adresle yetinmiş, geriye 12 adres bırakmıştır.

`gereken_onek` işlevindeki `dugum + 2` terimi, her ağın ağ ve yayın adreslerini harcadığı
gerçeğini kodlar. `math.ceil(math.log2(...))` çağrısı, gereken düğüm sayısını üstüne
yuvarlar: 102 için $\lceil \log_2 102 \rceil = 7$ ve önek $32 - 7 = 25$ çıkar.

Çakışma sınaması bir formalite değildir. Elle kurulan planlarda en sık yapılan hata, bir
bloğun bir öncekinin içine düşmesidir; `overlaps` çağrısı bu hatayı sessiz kalmadan
yakalar.

#### Kesinleşen Plan

Kurs boyunca kullanılacak plan budur:

| Bölüm | Blok | Maske | Geçit | Kullanılabilir aralık | Yayın |
|---|---|---|---|---|---|
| Misafir kablosuz | `192.168.10.0/25` | 255.255.255.128 | `.1` | `.1` – `.126` | `.127` |
| Laboratuvar | `192.168.10.128/26` | 255.255.255.192 | `.129` | `.129` – `.190` | `.191` |
| Yönetim | `192.168.10.192/27` | 255.255.255.224 | `.193` | `.193` – `.222` | `.223` |
| Sunucu | `192.168.10.224/28` | 255.255.255.240 | `.225` | `.225` – `.238` | `.239` |
| Bağlantı | `192.168.10.240/30` | 255.255.255.252 | — | `.241` – `.242` | `.243` |

Her bölümde ilk kullanılabilir adres yönlendirici arayüzüne ayrılmıştır. Kursun ilk
dersinde tanıtılan istemci `192.168.10.196` yönetim ağındadır ve geçidi `192.168.10.193`
adresidir — plan bu iki değeri doğrular.

Artan 12 adres `192.168.10.244` ile `192.168.10.255` arasındadır ve üç `/30` bloğuna
karşılık gelir: `.244/30`, `.248/30`, `.252/30`. Bunlar ileride eklenecek noktadan noktaya
bağlantılar için kullanılabilir.

#### Sıralamanın Etkisi

Bölümler artan sırada yerleştirilseydi ne olurdu? En küçük blok başa konur, sonrakiler
hizalanmak için ileri atlar:

| Sıra | Bölüm | Blok | Atlanan boşluk |
|---|---|---|---|
| Artan | Bağlantı | `192.168.10.0/30` | — |
| Artan | Sunucu | `192.168.10.16/28` | `.4` – `.15` (12 adres) |
| Artan | Yönetim | `192.168.10.32/27` | — |
| Artan | Laboratuvar | `192.168.10.64/26` | — |
| Artan | Misafir | `192.168.10.128/25` | — |

Plan yine sığar, ancak artan 12 adres bu kez bloğun **ortasında**, Bağlantı ile Sunucu
ağlarının arasında kalır. Boşluğu hizalama yaratır: bir `/28` yalnızca 16'nın katında
başlayabildiği için Sunucu `.4`'ten değil `.16`'dan başlar. Azalan sıralamada bu atlama hiç
gerekmez; her blok kendisinden büyük blokların hemen ardından başlar ve bu yüzden zaten
hizalıdır, kalan 12 adres de planın **sonunda** toplanır. İki sıralamada da boşluk tek bir
CIDR bloğu değildir (`.4/30` + `.8/29` ile `.244/30` + `.248/29`); fark boşluğun yeridir.

Ortadaki boşluk, iki ağın arasına sıkışmış bir hizalama artığıdır; sondaki boşluk ise
planın kesintisiz bittiği yerde, sonraki alt ağların sırayla ekleneceği yerde durur. Bu,
Bilgisayarlar Nasıl Çalışır kursundaki Bellek Düzeni dersinde ayırıcılar bağlamında
tanıtılan parçalanma sorununun adres uzayındaki karşılığıdır.

#### Yol Özetleme

Değişken bölmenin ikinci kazancı yönlendirme tablosundadır. Bitişik ve hizalı alt ağlar,
tek bir önekte **özetlenebilir (route summarization)**.

Kurumun beş alt ağı `192.168.10.0/24` bloğunun içindedir. Sağlayıcı yönlendiricisinin bu
beş ağı ayrı ayrı bilmesine gerek yoktur; tek bir satır yeter:

```
192.168.10.0/24  ->  203.0.113.10
```

Özetleme, hizalama kuralının doğrudan sonucudur. Dört bitişik `/24` bloğu — `192.168.8.0`,
`192.168.9.0`, `192.168.10.0`, `192.168.11.0` — tek bir `192.168.8.0/22` önekiyle anılabilir,
çünkü dördü de dördün katı olan bir üçüncü sekizliden — burada 8'den — başlayan hizalı bir
dörtlü oluşturur. Aynı dörtlü `192.168.9.0` ile başlasaydı özetlenemezdi: 9 dördün katı
değildir.

Özetlemenin kazancı doğrudandır: yönlendirme tablosundaki satır sayısı azalır, arama ucuzlar
ve iç ağdaki bir değişiklik dış tabloları etkilemez. Adreslerin hiyerarşik dağıtılmasının
gerekçesi budur.

#### Planın Belgelenmesi

Bir adres planı, yalnızca hesaplandığı anda değil, sonraki her değişiklikte kullanılır.
Belgelenmesi gereken alanlar şunlardır: bölüm adı, blok, maske, geçit adresi, statik
atamalar için ayrılan aralık, dinamik dağıtıma bırakılan aralık ve büyüme payı.

Büyüme payı özellikle gözden kaçar. Yukarıdaki planda misafir ağının 26, laboratuvarın 12,
yönetimin 10 boş adresi vardır; sunucu ağında yalnızca 4 boş adres kalmıştır. Sunucu sayısı
15'e çıkarsa `/28` yetmez ve blok yeniden boyutlandırılmalıdır. Planı kuran kişi, hangi
bölümün hangi eşikte taşacağını baştan not etmelidir.

#### Özet

- Değişken uzunluklu bölmede her alt ağ kendi gereksinimine göre boyutlanır; tek kısıt,
  başlangıç adresinin blok boyunun katı olmasıdır.
- Yöntem üç adımdır: gereksinimleri azalan sırala, her biri için en uzun yeterli öneki seç,
  hizalamaya uyarak yerleştir.
- Kurumun beş ağı `192.168.10.0/24` içine 244 adres kullanarak sığar; eşit bölme aynı iş
  için 640 adres isterdi.
- Azalan sıralama artan boşluğu bloğun sonunda ve bitişik bırakır; artan sıralama boşluğu
  ortada parçalar.
- Bitişik ve hizalı alt ağlar tek bir önekte özetlenebilir; beş alt ağ dışarıya
  `192.168.10.0/24` olarak duyurulur.
- Plan belgelenirken büyüme payı da yazılmalıdır; örnek planda en dar pay 4 adresle sunucu
  ağındadır.

#### Sonraki Adım

Bu plan 32 bitlik adres uzayının kıtlığıyla baş etmenin bir yoludur: özel adresler kullanmak
ve onları özenle bölmek. Kıtlığın kendisini ortadan kaldıran başka bir yol daha vardır —
adres uzayını genişletmek. Sonraki ders 128 bitlik adresleri, yazım kurallarını, arayüzlerin
adreslerini kendi kendine kurmasını ve iki sürümün bir arada çalışma yöntemlerini ele
alacak.

### IPv6

Source: https://academia.sh/tr/kurslar/ag-modelleri/ipv6

128 bitlik adresin yazım kuralları, adres türleri, otomatik yapılandırma, başlık farkları ve iki sürümün bir arada çalışması.

Önceki iki ders 32 bitlik adres uzayının kıtlığıyla baş etme yöntemlerini kurdu: özel
adresleri özenle bölmek, her bölüme gerektiği kadar vermek. Bu yöntemler kıtlığı yönetir,
ortadan kaldırmaz.

Kıtlığın kendisine yönelen çözüm adres uzayını genişletmektir. Bu dersin sorusu, adres
genişliğini dört katına çıkarmanın hangi kararları beraberinde getirdiğidir — çünkü adres
genişliği, önceki konuda tanıtılan kum saatinin boğazındadır ve ona dokunmak her şeyi
etkiler.

#### 128 Bit

IPv6 adresi 128 bittir. Toplam adres sayısı $2^{128}$, yani yaklaşık $3{,}4 \times 10^{38}$
olur. Karşılaştırma için: IPv4'ün $2^{32}$ adresi, IPv6'nın uzayının $2^{96}$'da biridir.

Genişliğin böyle abartılı seçilmesi, adres sayısını en üst düzeye çıkarmak için değildir.
Amaç **hiyerarşik dağıtımı rahatlatmaktır**: adresler bol olduğunda her düzeye cömert
bloklar verilebilir, blokların bitişik kalması sağlanabilir ve önekler özetlenebilir.
IPv4'te adresleri sıkıştırma çabası, yönlendirme tablolarının parçalanmasına yol açmıştı.

Bunun görünür sonucu, düğüm barındıran IPv6 alt ağlarının **`/64`** olmasıdır. Bir alt
ağdaki düğüm sayısı ne olursa olsun — iki cihaz da olsa — 64 bitlik düğüm bölümü verilir.
Kuralın dışında kalan tek yer, otomatik yapılandırmaya gerek duymayan yönlendirici
bağlantılarıdır: iki yönlendirici arasındaki noktadan noktaya bağlantıda `/127` gibi daha
dar önekler ayrıca tanımlanmıştır. IPv4
alışkanlığıyla bakıldığında bu savurganlıktır; IPv6 tasarımında ise otomatik yapılandırmanın
ön koşuludur.

#### Yazım Kuralları

Adres, iki nokta üst üste ile ayrılmış sekiz onaltılık dörtlü olarak yazılır. Üç kısaltma
kuralı vardır:

1. Her dörtlüdeki baştaki sıfırlar atılabilir: `0db8` → `db8`, `0000` → `0`.
2. Ardışık sıfır dörtlüleri `::` ile tek seferde atılabilir.
3. `::` bir adreste **en çok bir kez** kullanılabilir; iki kez kullanılsaydı hangi
   boşluğun kaç dörtlü olduğu belirsiz kalırdı.

```python
import ipaddress

for metin in ("2001:0db8:0010:0003:0000:0000:0000:0001",
              "fe80:0000:0000:0000:0200:5eff:fe00:5301",
              "ff02:0000:0000:0000:0000:0000:0000:0001",
              "0000:0000:0000:0000:0000:0000:0000:0001",
              "2001:0db8:0000:0000:0001:0000:0000:0001"):
    a = ipaddress.ip_address(metin)
    print(f"{metin} -> {a.compressed}")
```

```
2001:0db8:0010:0003:0000:0000:0000:0001 -> 2001:db8:10:3::1
fe80:0000:0000:0000:0200:5eff:fe00:5301 -> fe80::200:5eff:fe00:5301
ff02:0000:0000:0000:0000:0000:0000:0001 -> ff02::1
0000:0000:0000:0000:0000:0000:0000:0001 -> ::1
2001:0db8:0000:0000:0001:0000:0000:0001 -> 2001:db8::1:0:0:1
```

Son satır üçüncü kuralı gösterir: adreste iki ayrı sıfır dizisi vardır, yalnızca **uzun
olan** sıkıştırılmıştır. Kısa olan `0:0` biçiminde yazılmak zorundadır. Eşit uzunlukta iki
dizi varsa soldaki sıkıştırılır.

Bağlantı noktası numarasıyla birlikte yazıldığında adres köşeli parantez içine alınır:
`[2001:db8:10:3::1]:443`. Aksi hâlde son iki nokta üst üstenin adrese mi bağlantı noktasına
mı ait olduğu ayırt edilemez.

#### Adres Türleri

IPv6'da **yayın adresi yoktur**. Yayının işlevi çok noktaya gönderimle karşılanır; bu,
"herkese sor" yerine "ilgilenenlere sor" davranışı sağlar ve gereksiz işlemeyi azaltır.

| Önek | Tür | Kapsam |
|---|---|---|
| `2000::/3` | Genel tekil adres | Genel İnternet |
| `fe80::/10` | Yerel bağlantı | Yalnız aynı bağlantı |
| `fc00::/7` | Benzersiz yerel adres | Kurum içi |
| `ff00::/8` | Çok noktaya gönderim | Öneke gömülü |
| `::1/128` | Geri döngü | Makinenin kendisi |
| `::/128` | Belirsiz adres | Kaynak alanında "adresim yok" |
| `2001:db8::/32` | Belgeleme | Yönlendirilmez |

**Yerel bağlantı adresi** her IPv6 arayüzünde bulunur ve zorunludur; genel adres olmasa bile
vardır. Yönlendirici duyuruları ve komşu keşfi bu adresler üzerinden yürür. Adres yalnızca
bir bağlantı içinde anlamlı olduğundan, aynı yerel bağlantı adresi farklı arayüzlerde
tekrarlanabilir; bu yüzden kullanılırken arayüz belirtilir.

**Benzersiz yerel adres**, IPv4'teki özel kullanım bloklarının karşılığıdır: kurum içinde
kullanılır, genel İnternet'te yönlendirilmez.

Çok noktaya gönderim adreslerinde önek, kapsamı da taşır. `ff02::1` bağlantı kapsamındaki
tüm düğümleri, `ff02::2` bağlantı kapsamındaki tüm yönlendiricileri gösterir.

**İstenen düğüm çok noktaya gönderim adresi (solicited-node multicast)**, ARP'nin yayın
sorununu çözen düzenektir: `ff02::1:ff00:0/104` önekine hedef adresin son 24 biti eklenir.
Komşu keşfi sorusu bu adrese gönderilir ve yalnızca son 24 biti eşleşen az sayıda arayüz
mesajı işler. Yayın alanındaki her cihazın her soruyu işlemesi böylece önlenir.

#### Otomatik Yapılandırma

IPv6 arayüzleri, sunucu olmadan adres kurabilir. **Durumsuz otomatik yapılandırma
(stateless address autoconfiguration, SLAAC)** dört adımdır:

1. Arayüz, kendine bir **yerel bağlantı adresi** üretir (`fe80::` öneki + arayüz
   tanımlayıcısı).
2. **Yinelenen adres sınaması (duplicate address detection)** yapar: ürettiği adresin
   istenen düğüm grubuna bir komşu isteği gönderir. Yanıt gelirse adres kullanımdadır.
3. `ff02::2` adresine bir **yönlendirici isteği** gönderir. Yönlendirici, bağlantıda
   kullanılan `/64` öneki içeren bir **yönlendirici duyurusu** ile yanıtlar.
4. Arayüz, duyurulan öneki kendi arayüz tanımlayıcısıyla birleştirerek genel adresini kurar.

Arayüz tanımlayıcısını üretmenin bir yolu **EUI-64** dönüşümüdür: 48 bitlik MAC adresinin
ortasına `ff:fe` eklenir ve evrensel/yerel biti ters çevrilir.

```python
import ipaddress


def eui64(mac: str) -> str:
    b = [int(x, 16) for x in mac.split(":")]
    b[0] ^= 0x02                       # evrensel/yerel biti ters çevrilir
    ham = bytes(b[:3] + [0xFF, 0xFE] + b[3:])
    return ":".join(ham[i:i + 2].hex() for i in range(0, 8, 2))


arayuz = eui64("00:00:5e:00:53:01")
print("arayüz tanımlayıcısı:", arayuz)
print("yerel bağlantı adresi:", ipaddress.ip_address("fe80::" + arayuz))
print("genel adres          :", ipaddress.ip_address("2001:db8:10:3:" + arayuz))
```

```
arayüz tanımlayıcısı: 0200:5eff:fe00:5301
yerel bağlantı adresi: fe80::200:5eff:fe00:5301
genel adres          : 2001:db8:10:3:200:5eff:fe00:5301
```

Örnek ağdaki istemcinin MAC adresi `00:00:5e:00:53:01` idi; ilk baytın ikinci biti ters
çevrilerek `02` olmuş, ortaya `ff:fe` eklenmiştir. `/64` alt ağ zorunluluğunun nedeni burada
görülür: arayüz tanımlayıcısı 64 bittir.

EUI-64 dönüşümünün bir mahremiyet sorunu vardır: adres, donanım adresini içerdiği için
makine ağdan ağa taşınsa bile izlenebilir. Bu nedenle uçlar çoğunlukla arayüz tanımlayıcısını
rastgele üretir ve süreli olarak değiştirir. Sunucular ise sabit ve okunabilir tanımlayıcılar
kullanır — `2001:db8:10:4::20` gibi elle atanmış adresler yaygındır.

SLAAC ad sunucusu bilgisi taşımaz. Bu bilgi ya yönlendirici duyurusunun bir seçeneğiyle ya
da IPv6 için tanımlanmış durumsuz kiralama protokolüyle verilir.

#### Başlık Farkları

IPv6 başlığı 40 bayt sabittir; IPv4'ün 20 baytlık başlığından büyüktür, ancak alan sayısı
azdır ve değişken uzunluk yoktur.

| Değişiklik | Gerekçe |
|---|---|
| Başlık sağlaması kaldırıldı | Bağlantı katmanı ve taşıma katmanı zaten denetliyor; her sekmede yeniden hesap gereksiz |
| Yönlendiricide parçalama kaldırıldı | Parçalama maliyeti uçlara itildi; ara düğüm paketi atar ve bildirir |
| Başlık uzunluğu sabitlendi | İşleme boru hattı yalınlaşır |
| Seçenekler ek başlıklara taşındı | Zincir hâlinde eklenir, ana başlığı şişirmez |
| En küçük MTU 1280 bayta yükseltildi | Yol MTU keşfi gereksinimi azalır |

Sağlamanın kaldırılması, uçtan uca ilkesinin doğrudan uygulanmasıdır: ara düğümde yapılan
denetim doğruluk için gerekli değildi, yalnızca maliyet ekliyordu.

#### Örnek Ağın IPv6 Planı

Kurum, sağlayıcısından `2001:db8:10::/48` tahsisi almıştır. Bu tahsis 65 536 adet `/64` alt
ağ içerir; kurumun beş ağı için fazlasıyla yeterlidir.

```python
import ipaddress

tahsis = ipaddress.ip_network("2001:db8:10::/48")
plan = {
    "Misafir kablosuz": "2001:db8:10:1::/64",
    "Laboratuvar": "2001:db8:10:2::/64",
    "Yönetim": "2001:db8:10:3::/64",
    "Sunucu": "2001:db8:10:4::/64",
    "Bağlantı": "2001:db8:10:ffff::/64",
}
print("tahsis:", tahsis, "— içindeki /64 sayısı:", 2 ** (64 - tahsis.prefixlen))
for ad, cidr in plan.items():
    net = ipaddress.ip_network(cidr)
    print(f"{ad:18s} {str(net):24s} tahsisin içinde={net.subnet_of(tahsis)}")
```

```
tahsis: 2001:db8:10::/48 — içindeki /64 sayısı: 65536
Misafir kablosuz   2001:db8:10:1::/64       tahsisin içinde=True
Laboratuvar        2001:db8:10:2::/64       tahsisin içinde=True
Yönetim            2001:db8:10:3::/64       tahsisin içinde=True
Sunucu             2001:db8:10:4::/64       tahsisin içinde=True
Bağlantı           2001:db8:10:ffff::/64    tahsisin içinde=True
```

İki planın karşıtlığı öğreticidir. IPv4 planında her bit sayıldı, boş adresler tek tek not
edildi, büyüme payı bir kısıt oldu. IPv6 planında düğüm sayısı hiç hesaba girmedi; tek
karar, hangi alt ağ numarasının hangi bölüme verileceğiydi. Alt ağ numaraları okunabilirlik
için seçilmiştir — noktadan noktaya bağlantıya `ffff` verilmesi, tahsisin sonundan
başlamak gibi bir düzen tercihidir.

#### İki Sürümün Bir Arada Çalışması

IPv4 ve IPv6 birbiriyle **doğrudan konuşmaz**: farklı adres genişlikleri, farklı başlıklar,
farklı komşu keşfi. Bir arada çalışma için üç yaklaşım vardır.

**Çift yığın (dual stack):** Uçlar ve yönlendiriciler her iki protokolü de çalıştırır. Bir
hedefe hangi sürümle gidileceğine ad çözümlemesinin sonucu karar verir. En yalın yöntemdir;
maliyeti her şeyin iki kez yapılandırılması ve iki kez denetlenmesidir.

**Tünelleme:** IPv6 paketi, IPv4 paketinin yükü olarak taşınır. Aradaki ağ IPv6 bilmiyorsa
kullanılır. Tünel başlığı MTU'yu düşürür; önceki konuda ele alınan parçalama ve yol MTU
sorunları bu yüzden tünellerde sık görülür.

**Çeviri:** Bir ara düğüm IPv6 adreslerini IPv4 adreslerine dönüştürür. Uçtan uca
saydamlığı bozar ve sonraki derste ele alınacak adres dönüştürme sorunlarını devralır.

Bir uç her iki sürüme de sahipse hangisini seçeceği bir sıralama kuralına bağlıdır; genel
eğilim IPv6'yı önce denemek ve başarısız olursa IPv4'e dönmektir. Bu davranış, IPv6 yolunda
sessiz bir arıza olduğunda gecikmeyi artırabilir.

#### Özet

- IPv6 adresi 128 bittir; genişliğin amacı adres sayısını artırmaktan çok hiyerarşik
  dağıtımı ve önek özetlemeyi rahatlatmaktır.
- Düğüm barındıran alt ağlar `/64`'tür; 64 bitlik arayüz tanımlayıcısı otomatik yapılandırmanın ön
  koşuludur.
- Yazımda baştaki sıfırlar atılır ve en uzun sıfır dizisi `::` ile bir kez sıkıştırılır.
- Yayın adresi yoktur; işlevi çok noktaya gönderim ve istenen düğüm grubu ile karşılanır.
- Durumsuz otomatik yapılandırma yerel bağlantı adresi üretme, yinelenen adres sınaması,
  yönlendirici duyurusu ve önek birleştirme adımlarından oluşur.
- Başlıkta sağlama ve yönlendiricide parçalama kaldırılmıştır; iki sürüm çift yığın,
  tünelleme veya çeviri ile bir arada çalışır.

#### Sonraki Adım

Bu derste "yönlendirici paketi atar ve bildirir" ifadesi birkaç kez geçti. Bildirimin
kendisi de bir protokoldür ve yalnızca hata haberciliği yapmaz: erişilebilirlik sınaması,
yol keşfi ve MTU bildirimi de onun üzerinden yürür. Sonraki ders bu denetim mesajlarını,
yaşam süresi alanının nasıl bir yol izleme aracına dönüştüğünü ve mesajların engellenmesinin
neden sessiz arızalara yol açtığını ele alacak.

### ICMP

Source: https://academia.sh/tr/kurslar/ag-modelleri/icmp

Denetim mesajlarının biçimi, yankı sınaması, yaşam süresi alanının yol izlemeye dönüşmesi, yol MTU keşfi ve mesajların engellenmesinin sonuçları.

Önceki derslerde birkaç kez "yönlendirici paketi atar ve bildirir" denildi: yaşam süresi
tükendiğinde, hedef ağa yol bulunamadığında, paket MTU'dan büyük olduğunda. Bu bildirimlerin
nasıl yapıldığı henüz açılmadı.

IP'nin kendisi hiçbir geri bildirim vermez; elinden geleni yapan bir teslim hizmetidir. Geri
bildirim ayrı bir protokolün işidir. Bu dersin sorusu, o protokolün ne söylediği ve
söyleyemediğinde ne olduğudur.

#### Denetim Mesajlarının Yeri

**ICMP (Internet Control Message Protocol)**, IP paketlerinin taşınması sırasında oluşan
durumları bildiren protokoldür. IP başlığındaki protokol alanında `1` değeriyle taşınır —
yani IP'nin yükü olarak gider, ancak taşıma katmanı protokolü değildir.

Konumu bir tuhaflık gibi görünür: IP'nin denetim protokolü, IP'nin içinde taşınmaktadır.
Gerekçe pratiktir; ICMP mesajının da yönlendirilmesi gerekir ve yönlendirmeyi yapan
düzenek zaten IP'dir.

ICMP'nin sınırları açıkça bilinmelidir:

- Bir ICMP mesajının ulaşacağının **güvencesi yoktur**; kendisi de kaybolabilir.
- Bir ICMP mesajı kaybolduğunda **ikinci bir mesaj üretilmez**; hata bildirimi için hata
  bildirimi yapılmaz.
- ICMP mesajları hata **düzeltmez**; yalnızca haber verir. Ne yapılacağına uç karar verir.

#### Mesajın Biçimi

Her ICMP mesajı 8 baytlık bir başlıkla başlar:

| Alan | Boyut | İşlev |
|---|---|---|
| Tür | 1 bayt | Mesajın sınıfı |
| Kod | 1 bayt | Sınıf içindeki ayrıntı |
| Sağlama | 2 bayt | Mesajın tamamı üzerinde |
| Değişken alan | 4 bayt | Türe göre anlam kazanır |

Hata bildiren mesajlarda gövde, **hataya yol açan paketin IP başlığını ve yükünün ilk
baytlarını** taşır. Bu ayrıntı önemlidir: uç, gelen hata mesajını kendi hangi bağlantısına
ait olduğunu ancak bu kopya sayesinde eşleştirebilir. Kopyada taşıma katmanı başlığının ilk
baytları da bulunduğundan bağlantı noktası numaraları da okunabilir.

Yankı mesajlarında değişken alan, kimlik ve sıra numarası olarak kullanılır:

```python
import struct


def saglama(veri: bytes) -> int:
    if len(veri) % 2:
        veri += b"\x00"
    toplam = 0
    for i in range(0, len(veri), 2):
        toplam += (veri[i] << 8) + veri[i + 1]
    while toplam >> 16:
        toplam = (toplam & 0xFFFF) + (toplam >> 16)
    return ~toplam & 0xFFFF


def yanki_istegi(kimlik: int, sira: int, yuk: bytes) -> bytes:
    govde = struct.pack("!BBHHH", 8, 0, 0, kimlik, sira) + yuk
    c = saglama(govde)
    return govde[:2] + struct.pack("!H", c) + govde[4:]


mesaj = yanki_istegi(kimlik=0x1234, sira=1, yuk=bytes(range(32)))
print("mesaj boyu :", len(mesaj), "bayt")
print("başlık     :", mesaj[:8].hex())
print("sağlama    :", hex(struct.unpack("!H", mesaj[2:4])[0]))
print("denetim    :", saglama(mesaj))

tur, kod, _, kimlik, sira = struct.unpack("!BBHHH", mesaj[:8])
print(f"tür={tur} kod={kod} kimlik={hex(kimlik)} sıra={sira} yük={len(mesaj) - 8} bayt")
```

```
mesaj boyu : 40 bayt
başlık     : 0800f4c912340001
sağlama    : 0xf4c9
denetim    : 0
tür=8 kod=0 kimlik=0x1234 sıra=1 yük=32 bayt
```

Sağlama yöntemi, kapsülleme dersinde IPv4 başlığı için kurulanla aynıdır; farkı, ICMP'de
başlığın yanı sıra yükü de kapsamasıdır. Doğrulama yine sıfır vermelidir.

#### Mesaj Türleri

| Tür | Kod | Anlamı | Ne zaman üretilir |
|---|---|---|---|
| 0 | 0 | Yankı yanıtı | Yankı isteğine karşılık |
| 3 | 0 | Ağa ulaşılamıyor | Hedef ağa yol yok |
| 3 | 1 | Düğüme ulaşılamıyor | Yerel ağda hedef yanıtsız |
| 3 | 3 | Bağlantı noktasına ulaşılamıyor | Hedefte dinleyen süreç yok |
| 3 | 4 | Parçalama gerekli, engellenmiş | Paket MTU'dan büyük ve DF kurulu |
| 8 | 0 | Yankı isteği | Erişilebilirlik sınaması |
| 11 | 0 | Yaşam süresi aşıldı | TTL sıfıra indi |
| 11 | 1 | Birleştirme süresi aşıldı | Parçalar zamanında toplanamadı |
| 12 | 0 | Başlık hatası | Alanlardan biri tutarsız |

Tür 3, kod 4 ayrı bir öneme sahiptir: mesaj, kabul edilebilir MTU değerini de taşır ve yol
MTU keşfinin dayanağıdır.

#### Yankı Sınaması

**Yankı isteği (echo request)** ve **yankı yanıtı (echo reply)** çifti, bir adresin
erişilebilirliğini sınamak için kullanılır. Gönderen bir kimlik ve artan bir sıra numarası
koyar; yanıt aynı değerleri geri döndürür. Böylece hangi yanıtın hangi isteğe ait olduğu
eşleştirilir ve gidiş–dönüş süresi ölçülür.

Sınamanın ne kanıtladığı ve kanıtlamadığı ayrılmalıdır.

**Yanıt geldiyse** şunlar doğrudur: iki yönde de yol vardır, hedef arayüz etkindir, IP
katmanı çalışmaktadır.

**Yanıt gelmediyse** şunların hiçbiri kesin değildir. Hedef kapalı olabilir; hedef açık ama
yankı isteklerini yanıtlamıyor olabilir; yol üzerindeki bir filtre isteği veya yanıtı atmış
olabilir. Yanıtsızlık, hedefin çalışmadığı anlamına gelmez.

Bir bağlantı noktasının hizmet verip vermediği yankı sınamasıyla anlaşılmaz. Yankı, IP
düzeyinde bir sınamadır; taşıma katmanı ve uygulama katmanı hakkında bilgi vermez. Yankı
yanıtı veren bir sunucunun uygulaması durmuş olabilir.

#### Yaşam Süresi ve Yol İzleme

IP başlığındaki **yaşam süresi (time to live, TTL)** alanı, paketin geçebileceği yönlendirici
sayısını sınırlar. Her yönlendirici alanı bir azaltır; sıfıra indiğinde paketi atar ve
gönderene tür 11 mesajı yollar.

Alanın asıl amacı, yönlendirme döngülerinde paketlerin sonsuza dek dolaşmasını önlemektir.
Ancak alan, bambaşka bir amaca da hizmet eder: **yol izleme**.

Yöntem şudur. Hedefe önce TTL değeri 1 olan bir paket gönderilir; ilk yönlendirici onu atar
ve kendini bildirir. Sonra TTL değeri 2 olan bir paket gönderilir; ikinci yönlendirici
bildirir. Değer birer birer artırılarak yolun her adımı sırayla ortaya çıkar. Hedefe
ulaşıldığında gelen mesaj tür 11 değil, ya yankı yanıtı ya da bağlantı noktasına
ulaşılamıyor bildirimidir; bu, dizinin sonunu belirtir.

Örnek ağdaki istemciden `198.51.100.20` adresine giden yolun topolojisi bilindiğine göre,
izlemenin hangi adımları üreteceği doğrudan çıkarılabilir:

| TTL | Yanıt veren | Rolü | Yanıt türü |
|---|---|---|---|
| 1 | `192.168.10.193` | Kurum yönlendiricisi, yönetim arayüzü | Tür 11 |
| 2 | `203.0.113.1` | Sağlayıcı kenar yönlendiricisi | Tür 11 |
| 3 | `198.51.100.1` | Hedef ağın kenar yönlendiricisi | Tür 11 |
| 4 | `198.51.100.20` | Hedef uç | Tür 0 veya tür 3 kod 3 |

Yol izleme sonuçları okunurken üç sınır bilinmelidir. Yolun her adımı yanıt vermek zorunda
değildir; yanıt vermeyen bir adım boş görünür ve bu, oradan geçilmediği anlamına gelmez.
Gidiş yolu görülür, dönüş yolu görülmez; iki yön farklı olabilir. Ölçülen süreler, ara
yönlendiricinin hata mesajı üretme önceliğine bağlıdır ve o noktadaki gerçek gecikmeyi
göstermeyebilir.

#### Yol MTU Keşfi

Çerçeve, Paket, Segment dersinde parçalamadan kaçınmanın yolu tanımlanmıştı: parçalanmasın
bayrağını kurmak ve gelen bildirime göre segment boyunu küçültmek. Bildirim, ICMP tür 3 kod
4 mesajıdır.

Döngü şöyle işler. Gönderen, kendi bağlantısının MTU değerine göre paket üretir. Yol
üzerindeki bir bağlantının MTU değeri daha küçükse, o yönlendirici paketi atar ve kabul
edebileceği MTU değerini bildirir. Gönderen, bu değere göre segment boyunu düşürür ve
yeniden gönderir. Süreç, paketler geçmeye başlayana kadar sürer.

Yöntemin zayıf noktası, ICMP mesajının kendisine bağımlı olmasıdır. Mesaj yol üzerinde
engellenirse gönderen hiçbir şey öğrenemez: paketleri atılmaya devam eder, ancak nedeni
bilmez. Bu duruma **kara delik (black hole)** denir ve tipik belirtisi şudur — küçük
istekler çalışır, büyük veri aktarımı takılır. Yankı sınaması başarılıdır, bağlantı kurulur,
ilk birkaç bayt gider, sonra akış durur.

Tanısı, MTU'nun elle küçültülmesiyle konur: segment boyu sınırlandığında aktarım düzeliyorsa
sorun yol MTU keşfindedir.

#### ICMP'yi Engellemenin Bedeli

ICMP mesajları, ağ hakkında bilgi verdiği için sık sık toptan engellenir. Bu, birkaç somut
arıza üretir:

- **Tür 3 kod 4 engellenirse** yol MTU keşfi çalışmaz; kara delik oluşur.
- **Tür 3 kod 3 engellenirse** kapalı bir bağlantı noktasına yapılan bağlantı denemesi
  anında reddedilmek yerine zaman aşımına uğrar; bekleme süreleri uzar.
- **Tür 11 engellenirse** yol izleme çalışmaz ve yönlendirme döngüleri görünmez olur.
- **Tür 8 ve 0 engellenirse** erişilebilirlik sınaması yapılamaz; tanı kör noktalarla
  yürütülür.

Ölçülü yaklaşım, toptan engelleme yerine tür bazlı seçim yapmaktır: hata bildirimleri
geçirilir, dışarıdan gelen yankı isteklerine verilen yanıt gerekiyorsa sınırlandırılır.
Herhangi bir seçimde tür 3 kod 4 geçirilmelidir; onsuz aktarımlar sessizce bozulur.

#### ICMPv6'nın Genişletilmiş Rolü

IPv6'da ICMP'nin kapsamı belirgin biçimde genişler. ARP dersinde belirtildiği gibi komşu
keşfi ICMPv6 içindedir; ayrıca yönlendirici isteği ve duyurusu, yinelenen adres sınaması ve
çok noktaya gönderim grubu yönetimi de bu protokol üzerinden yürür.

Bunun doğrudan bir sonucu vardır: **ICMPv6 toptan engellenirse IPv6 çalışmaz.** IPv4'te
ICMP'yi kapatmak tanıyı zorlaştırır; IPv6'da temel işlevleri durdurur. Adres kurulamaz,
komşular çözümlenemez, yönlendirici bulunamaz.

#### Özet

- ICMP, IP'nin yükü olarak taşınan denetim protokolüdür; hata düzeltmez, yalnızca bildirir
  ve kendi ulaşımının güvencesi yoktur.
- Hata mesajları, hataya yol açan paketin başlığını taşır; uç, mesajı bu kopya sayesinde
  kendi bağlantısıyla eşleştirir.
- Yankı sınaması IP düzeyinde erişilebilirliği gösterir; yanıtsızlık hedefin çalışmadığı
  anlamına gelmez ve bir hizmetin varlığını kanıtlamaz.
- Yaşam süresi alanı, artırılarak gönderilen paketlerle yolun adımlarını sırayla ortaya
  çıkarır; gidiş yolu görülür, dönüş yolu görülmez.
- Yol MTU keşfi tür 3 kod 4 mesajına bağımlıdır; mesaj engellenirse küçük isteklerin
  çalıştığı, büyük aktarımların takıldığı kara delik oluşur.
- ICMPv6, komşu keşfi ve yönlendirici duyurusunu da üstlenir; toptan engellenmesi IPv6'yı
  çalışmaz hâle getirir.

#### Sonraki Adım

Buraya kadar örnek ağdaki her adresin elle atandığı varsayıldı. Yüz cihazlık misafir
ağında bu varsayım sürdürülemez: her cihaza adres, maske, geçit ve ad sunucusu bilgisini tek
tek girmek olanaksızdır. Sonraki ders adreslerin kiralanma sürecini, kiralamanın dört
adımını ve alt ağ planının bu sürece nasıl döküleceğini ele alacak.

### DHCP

Source: https://academia.sh/tr/kurslar/ag-modelleri/dhcp

Dinamik adres kiralamanın dört adımı, kira süresi ve yenileme eşikleri, örnek plandan havuz çıkarımı ve aktarım aracısının rolü.

Önceki dersler örnek ağdaki her adresin elle atandığını varsaydı. Sunucu odasındaki on
makine için bu varsayım sürdürülebilir; misafir kablosuz ağındaki yüz cihaz için değildir.
Her cihaza adres, maske, geçit ve ad sunucusu bilgisini tek tek girmek olanaksızdır.

Bu dersin sorusu, bir cihazın ağa bağlandığı anda bu dört bilgiyi nereden alacağıdır. Yanıt
bir tavuk–yumurta sorunuyla başlar: cihazın bilgiyi isteyebilmesi için bir adresi olması
gerekir, ama adresi olmadığı için istemektedir.

#### Adressiz Konuşmak

Sorun, bağlantı katmanı üzerinden çözülür. Cihaz kendi adresi yerine **belirsiz adres**
`0.0.0.0` kullanır ve hedef olarak **sınırlı yayın adresi** `255.255.255.255` yazar. Çerçeve
düzeyinde hedef, yayın adresi `ff:ff:ff:ff:ff:ff` olur. Bu yayın, yayın alanındaki tüm
cihazlara ulaşır; içlerinden yapılandırma dağıtan olan yanıt verir.

**DHCP (Dynamic Host Configuration Protocol)**, bu alışverişi yürüten protokoldür. UDP
üzerinde çalışır; istemci 68, sunucu 67 numaralı bağlantı noktasını kullanır. Taşıma
katmanının seçimi zorunludur: bağlantı kurulumu gerektiren bir protokol, adres yokken
kullanılamaz.

#### Dört Adım

Kiralama dört mesajla tamamlanır.

| Adım | Mesaj | Yön | Adresleme | Taşıdığı bilgi |
|---|---|---|---|---|
| 1 | Keşif (discover) | İstemci → Yayın | `0.0.0.0` → `255.255.255.255` | İstemcinin donanım adresi, işlem kimliği |
| 2 | Teklif (offer) | Sunucu → İstemci | Sunucu adresi → Yayın veya tekil | Önerilen adres, maske, geçit, kira süresi |
| 3 | İstek (request) | İstemci → Yayın | `0.0.0.0` → `255.255.255.255` | Kabul edilen teklif ve sunucunun kimliği |
| 4 | Onay (acknowledge) | Sunucu → İstemci | Sunucu adresi → Yayın veya tekil | Kiralamanın kesinleşmesi ve seçenekler |

Üçüncü adımın **neden yayınla** gönderildiği ilk bakışta anlaşılmaz: istemci hangi sunucudan
teklif aldığını bilmektedir. Gerekçe, birden çok sunucunun bulunabilmesidir. İstek yayınla
gittiğinde, teklifi kabul edilmeyen sunucular da bunu görür ve ayırdıkları adresi geri
bırakır. Yayın olmasaydı bu adresler bir kira süresi boyunca boşuna tutulurdu.

İkinci adımda istemcinin henüz adresi olmadığı için sunucunun yanıtı bir tuhaflık içerir:
yanıt, henüz atanmamış bir adrese gönderilmelidir. Gerçekleştirimler bunu iki yolla çözer —
ya yanıtı yayınla gönderir ya da istemcinin donanım adresine doğrudan çerçeve kurar.
İstemci, hangi yolu tercih ettiğini keşif mesajındaki bir bayrakla bildirir.

#### Seçenekler

Kiralamanın asıl değeri, adresle birlikte gelen yapılandırma bilgisidir. Bunlar **seçenek
(option)** alanlarında taşınır:

| Seçenek | Taşıdığı bilgi | Örnek ağdaki değeri (yönetim bölümü) |
|---|---|---|
| Alt ağ maskesi | Ağ/düğüm sınırı | `255.255.255.224` |
| Yönlendirici | Varsayılan geçit | `192.168.10.193` |
| Ad sunucusu | Çözümleyici adresleri | `192.168.10.226` |
| Alan adı | Arama son eki | Kurumun iç alan adı |
| Kira süresi | Geçerlilik | Saniye cinsinden |
| Sunucu kimliği | Kiralamayı veren | Sunucunun adresi |
| Yenileme eşikleri | T1 ve T2 | Kira süresinin oranları |

Maskenin bu listede olması, Alt Ağlara Bölme dersindeki saptamayı hatırlatır: adres tek
başına eksik bilgidir. Kiralama, adresi maskesiyle birlikte teslim eder.

#### Kira Süresi ve Yenileme

Adres kalıcı olarak verilmez, **kiralanır (lease)**. Sürenin sonunda kiralama düşer ve adres
havuza döner. Süreli olmasının nedeni, ağa bir kez bağlanıp giden cihazların adresleri
süresiz tutmasını önlemektir.

İstemci süreyi beklemez; iki eşikte yenileme dener:

| Eşik | Zamanlama | Davranış |
|---|---|---|
| T1 | Kira süresinin %50'si | Kiralamayı veren sunucuya doğrudan yenileme isteği |
| T2 | Kira süresinin %87,5'i | Herhangi bir sunucuya yayınla yeniden bağlanma isteği |
| Bitiş | %100 | Adres bırakılır, süreç baştan başlar |

Sekiz saatlik bir kirada T1 dört saatte, T2 yedi saatte gelir. Yenileme başarılıysa süre
sıfırdan başlar ve adres değişmez. Bu yüzden bir cihaz, kira süresi kısa olsa bile
çoğunlukla aynı adresi korur.

Kira süresi seçimi bir ödünleşimdir. Kısa süre, ayrılan adreslerin havuza hızla dönmesini
sağlar ve yoğun bir misafir ağında havuz tükenmesini önler; karşılığında yenileme trafiği
artar. Uzun süre trafiği azaltır; karşılığında ayrılan adresler uzun süre bloke kalır ve
yapılandırma değişiklikleri geç yayılır.

#### Örnek Ağın Havuzları

Değişken Uzunluklu Alt Ağlar dersinde kesinleşen plan, kiralama yapılandırmasına
dönüştürülmelidir. Her alt ağda adresler üçe ayrılır: yönlendiriciye ayrılan ilk adres, elle
atama için ayrılan bir aralık, geri kalanı dinamik havuz.

```python
import ipaddress

# (bölüm, blok, elle atama için ayrılan adres sayısı, dinamik istemci beklentisi)
BOLUMLER = [
    ("Misafir kablosuz", "192.168.10.0/25", 9, 100),
    ("Laboratuvar", "192.168.10.128/26", 5, 45),
    ("Yönetim", "192.168.10.192/27", 9, 11),
    ("Sunucu", "192.168.10.224/28", 13, 0),
    ("Bağlantı", "192.168.10.240/30", 1, 0),
]

for ad, cidr, ayrilan, beklenen in BOLUMLER:
    net = ipaddress.ip_network(cidr)
    d = list(net.hosts())
    yonlendirici = d[0]
    ayrilmis = d[1:1 + ayrilan]
    havuz = d[1 + ayrilan:]
    ayrilmis_metin = (f"{ayrilmis[0]}-{ayrilmis[-1]}" if ayrilmis else "yok")
    havuz_metin = (f"{havuz[0]}-{havuz[-1]} ({len(havuz)})" if havuz else "yok")
    print(f"{ad:18s} {cidr:20s} yönlendirici={str(yonlendirici):15s} "
          f"elle={ayrilmis_metin:31s} havuz={havuz_metin:35s} "
          f"pay={len(havuz) - beklenen if havuz else 0}")
```

```
Misafir kablosuz   192.168.10.0/25      yönlendirici=192.168.10.1    elle=192.168.10.2-192.168.10.10      havuz=192.168.10.11-192.168.10.126 (116)  pay=16
Laboratuvar        192.168.10.128/26    yönlendirici=192.168.10.129  elle=192.168.10.130-192.168.10.134   havuz=192.168.10.135-192.168.10.190 (56)  pay=11
Yönetim            192.168.10.192/27    yönlendirici=192.168.10.193  elle=192.168.10.194-192.168.10.202   havuz=192.168.10.203-192.168.10.222 (20)  pay=9
Sunucu             192.168.10.224/28    yönlendirici=192.168.10.225  elle=192.168.10.226-192.168.10.238   havuz=yok                                 pay=0
Bağlantı           192.168.10.240/30    yönlendirici=192.168.10.241  elle=192.168.10.242-192.168.10.242   havuz=yok                                 pay=0
```

Sunucu ve bağlantı ağlarında dinamik havuz yoktur; sunucuların adresleri değişmemelidir ve
noktadan noktaya bağlantının iki ucu yönlendiricidir.

Havuz payları anlamlıdır. Misafir ağında beklenen 100 cihaz için 116 adres vardır; 16
adreslik pay, aynı anda beklenenden fazla cihazın bağlanmasını karşılar. Kira süresi bu ağda
kısa tutulmalıdır: gelip geçen cihazların adresleri havuza çabuk dönmelidir.

#### Ayrılmış Adres ve Sabit Kiralama

Elle atama aralığı, kiralama sunucusunun hiç dokunmadığı adreslerdir. Ancak bir cihaza
sabit adres vermenin ikinci bir yolu daha vardır: **sabit kiralama (reservation)**. Sunucu,
belirli bir donanım adresine her zaman aynı IP adresini verir.

Kursun izlediği istemci bu yolla yapılandırılmıştır:

| Donanım adresi | Verilen adres | Yöntem |
|---|---|---|
| `00:00:5e:00:53:01` | `192.168.10.196` | Sabit kiralama |

İki yöntem arasındaki fark yönetimseldir. Elle atamada yapılandırma cihazın üzerindedir;
maske veya geçit değiştiğinde her cihaza tek tek gidilmelidir. Sabit kiralamada yapılandırma
merkezdedir; cihaz adresini yine kiralamayla alır, ancak her zaman aynısını alır. Ağ
genelinde bir seçenek değiştiğinde tek yerde değişir.

Sabit kiralamanın dayandığı donanım adresi, gizlilik için adresini değiştiren cihazlarda
sabit kalmayabilir. Bu durumda kiralama tutmaz ve cihaz havuzdan adres alır.

#### Aktarım Aracısı

Keşif mesajı yayınla gider, yayın ise yönlendiriciyi geçmez. Örnek ağın beş alt ağı vardır;
her birine ayrı bir kiralama sunucusu koymak gereksiz bir yönetim yüküdür.

Çözüm **aktarım aracısıdır (relay agent)**. Yönlendirici, kendi arayüzüne gelen yayını
yakalar, merkezî sunucuya tekil bir paket olarak iletir ve mesaja hangi arayüzden geldiğini
belirten bir alan ekler. Sunucu bu alana bakarak hangi havuzdan adres vereceğine karar
verir.

Örnek ağda sunucu odasındaki `192.168.10.226` adresi hem ad çözümleme hem kiralama hizmeti
veriyorsa, yönlendiricinin her iç arayüzünde aktarım tanımlanır. Yönetim bölümündeki bir
istemcinin keşif mesajı, arayüz alanında `192.168.10.193` bilgisiyle sunucuya ulaşır ve
sunucu yönetim havuzundan adres verir.

#### Arıza Kalıpları

**Yetkisiz kiralama sunucusu.** Yayın alanına eklenen bir cihaz kiralama teklifleri
gönderiyorsa, istemciler ilk gelen teklifi kabul eder. Yanlış geçit veya yanlış ad sunucusu
dağıtılabilir. Karşı önlem anahtar düzeyindedir: kiralama yanıtlarının yalnızca belirlenmiş
bağlantı noktalarından gelmesine izin verilir.

**Havuz tükenmesi.** Havuzdaki tüm adresler kiralanmışsa yeni istemciler adres alamaz.
Belirti, bazı cihazların çalışıp bazılarının çalışmamasıdır. Ölçü, havuz doluluğunu
izlemek ve kira süresini talebe göre ayarlamaktır.

**Yerel bağlantı adresine düşme.** Adres alamayan bir arayüz `169.254.0.0/16` bloğundan
kendine adres seçer. Bir cihazın bu blokta adres taşıması, kiralamanın başarısız olduğunun
doğrudan işaretidir: sunucu erişilemez, aktarım tanımlı değil veya havuz tükenmiştir.

**Adres çakışması.** Elle atanan bir adres havuz aralığının içindeyse, aynı adres bir de
kiralanabilir. Planı yaparken elle atama aralığının havuzun dışında tutulması bu yüzdendir.

#### Özet

- İstemci adresi olmadan konuşur: kaynak `0.0.0.0`, hedef `255.255.255.255`; protokol UDP
  üzerinde 67 ve 68 numaralı bağlantı noktalarını kullanır.
- Kiralama dört mesajla tamamlanır; üçüncü adım yayınla gider ki kabul edilmeyen teklifleri
  veren sunucular adresleri geri bıraksın.
- Adresle birlikte maske, geçit, ad sunucusu ve kira süresi de teslim edilir.
- Yenileme kira süresinin %50 ve %87,5 eşiklerinde denenir; başarılı yenilemede adres
  değişmez.
- Örnek planda misafir havuzu 116, laboratuvar 56, yönetim 20 adrestir; sunucu ve bağlantı
  ağlarında dinamik havuz yoktur.
- Yayın yönlendiriciyi geçmediğinden çok alt ağlı ağlarda aktarım aracısı kullanılır;
  `169.254.0.0/16` bloğundan adres, kiralamanın başarısız olduğunu gösterir.

#### Sonraki Adım

Örnek ağdaki tüm cihazlar artık adres sahibidir; ancak bu adreslerin hepsi özel kullanım
bloğundandır ve genel İnternet'te yönlendirilmez. Kurumun elinde tek bir genel adres vardır:
`203.0.113.10`. Sonraki ders, yüzlerce özel adresin tek bir genel adres üzerinden dışarı
nasıl çıktığını, çevrim tablosunun nasıl tutulduğunu ve bu düzeneğin uçtan uca bağlantıya ne
yaptığını ele alacak.

### NAT ve PAT

Source: https://academia.sh/tr/kurslar/ag-modelleri/nat-ve-pat

Adres dönüştürme türleri, çevrim tablosunun beş bileşenli anahtarı, kapasite hesabı ve uçtan uca bağlantının bozulması.

Örnek ağdaki tüm cihazlar artık adres sahibidir. Ancak bu adreslerin tümü
`192.168.10.0/24` bloğundandır ve o blok genel İnternet'te yönlendirilmez: kaynak adresi
`192.168.10.196` olan bir paket sağlayıcının yönlendiricisine ulaşsa bile, dönüş paketinin
geri getirilebileceği bir yol yoktur.

Kurumun elinde tek bir genel adres vardır: `203.0.113.10`. Bu dersin sorusu, 182 iç
adresin tek bir genel adres üzerinden dışarı nasıl çıkabildiğidir.

#### Üç Dönüştürme Türü

**Adres dönüştürme (network address translation, NAT)**, bir paketin başlığındaki adresleri
geçiş sırasında değiştirmektir. Üç biçimi ayrılır.

| Tür | Eşleme | Kaç genel adres | Dışarıdan bağlantı |
|---|---|---|---|
| Statik NAT | Bire bir, sabit | İç düğüm sayısı kadar | Kurulabilir |
| Dinamik NAT | Bire bir, havuzdan | Eşzamanlı düğüm sayısı kadar | Kurulamaz |
| Bağlantı noktalı dönüştürme (PAT) | Çoktan bire | Tek adres yeter | Yalnız tanımlıysa |

**Statik NAT**, bir iç adresi bir genel adrese kalıcı olarak bağlar. Dışarıdan erişilmesi
gereken bir sunucu için kullanılır.

**Dinamik NAT**, bir genel adres havuzundan geçici eşleme kurar. Havuz tükendiğinde yeni
düğümler dışarı çıkamaz. Kurumun tek genel adresi olduğundan bu tür örnek ağa uygun
değildir.

**Bağlantı noktalı dönüştürme (port address translation, PAT)**, adresle birlikte kaynak
bağlantı noktası numarasını da değiştirerek çok sayıda iç düğümü tek bir genel adrese
sığdırır. Örnek ağın kullandığı yöntem budur. Yaygın adlandırmada "NAT" denildiğinde
çoğunlukla bu tür kastedilir.

#### Çevrim Tablosu

Dönüştürmeyi yapan cihaz, hangi dönüş paketinin hangi iç düğüme ait olduğunu bilmek zorundadır.
Bunun için bir **çevrim tablosu** tutar. Tablonun anahtarı beş bileşenlidir: kaynak adresi,
kaynak bağlantı noktası, hedef adresi, hedef bağlantı noktası ve protokol.

```python
DIS_ADRES = "203.0.113.10"


class Pat:
    """Bağlantı noktası çevirisi yapan bir çevrim tablosu."""

    def __init__(self, dis_adres: str, ilk_bnk: int = 61000) -> None:
        self.dis_adres = dis_adres
        self.sonraki = ilk_bnk
        self.ileri: dict[tuple, tuple] = {}     # iç anahtar -> dış anahtar
        self.geri: dict[tuple, tuple] = {}      # dış anahtar -> iç anahtar

    def disari(self, ic_ip: str, ic_bnk: int,
               hedef_ip: str, hedef_bnk: int) -> tuple[str, int]:
        anahtar = (ic_ip, ic_bnk, hedef_ip, hedef_bnk)
        if anahtar not in self.ileri:
            self.sonraki += 1
            dis = (self.dis_adres, self.sonraki)
            self.ileri[anahtar] = dis
            self.geri[(dis[0], dis[1], hedef_ip, hedef_bnk)] = (ic_ip, ic_bnk)
        return self.ileri[anahtar]

    def iceri(self, dis_ip: str, dis_bnk: int,
              kaynak_ip: str, kaynak_bnk: int) -> tuple[str, int] | None:
        return self.geri.get((dis_ip, dis_bnk, kaynak_ip, kaynak_bnk))


pat = Pat(DIS_ADRES)
akislar = [
    ("192.168.10.196", 49152, "198.51.100.20", 443),
    ("192.168.10.197", 49152, "198.51.100.20", 443),
    ("192.168.10.196", 49153, "198.51.100.20", 443),
    ("192.168.10.60", 51000, "198.51.100.20", 80),
]

print(f"{'iç kaynak':22s} {'dış kaynak':22s} {'hedef'}")
for ic_ip, ic_bnk, h_ip, h_bnk in akislar:
    d_ip, d_bnk = pat.disari(ic_ip, ic_bnk, h_ip, h_bnk)
    print(f"{ic_ip + ':' + str(ic_bnk):22s} {d_ip + ':' + str(d_bnk):22s} "
          f"{h_ip + ':' + str(h_bnk)}")

print()
print("dönüş paketi 203.0.113.10:61001 <- 198.51.100.20:443 ->",
      pat.iceri("203.0.113.10", 61001, "198.51.100.20", 443))
print("dönüş paketi 203.0.113.10:61003 <- 198.51.100.20:443 ->",
      pat.iceri("203.0.113.10", 61003, "198.51.100.20", 443))
print("istenmemiş paket 203.0.113.10:61999 <- 198.51.100.20:443 ->",
      pat.iceri("203.0.113.10", 61999, "198.51.100.20", 443))
```

Çıktı:

```
iç kaynak              dış kaynak             hedef
192.168.10.196:49152   203.0.113.10:61001     198.51.100.20:443
192.168.10.197:49152   203.0.113.10:61002     198.51.100.20:443
192.168.10.196:49153   203.0.113.10:61003     198.51.100.20:443
192.168.10.60:51000    203.0.113.10:61004     198.51.100.20:80

dönüş paketi 203.0.113.10:61001 <- 198.51.100.20:443 -> ('192.168.10.196', 49152)
dönüş paketi 203.0.113.10:61003 <- 198.51.100.20:443 -> ('192.168.10.196', 49153)
istenmemiş paket 203.0.113.10:61999 <- 198.51.100.20:443 -> None
```

İkinci satır, dönüştürmenin neden gerekli olduğunu gösterir: iki farklı iç düğüm aynı
kaynak bağlantı noktası numarasını (49152) kullanmıştır. Numaralar değiştirilmeseydi dönüş
paketleri ayırt edilemezdi.

Son satır, dönüştürmenin en belirgin yan etkisidir: tabloda karşılığı olmayan bir paket
düşürülür. Dışarıdan gelen, içeriden başlatılmamış hiçbir bağlantı içeri geçemez.

#### Değişen Alanlar

Bir paket dönüştürülürken yalnızca adres alanları değişmez. IP başlığındaki kaynak adresi ve
taşıma başlığındaki kaynak bağlantı noktası değiştiğine göre, bunları kapsayan sağlamalar da
yeniden hesaplanmalıdır.

| Alan | Giden pakette | Dönen pakette |
|---|---|---|
| IP kaynak adresi | İç adres → genel adres | Değişmez |
| IP hedef adresi | Değişmez | Genel adres → iç adres |
| Taşıma kaynak bağlantı noktası | İç numara → çevrilmiş numara | Değişmez |
| Taşıma hedef bağlantı noktası | Değişmez | Çevrilmiş numara → iç numara |
| IP başlık sağlaması | Yeniden hesaplanır | Yeniden hesaplanır |
| Taşıma sağlaması | Yeniden hesaplanır | Yeniden hesaplanır |

Taşıma sağlamasının da değişmesinin nedeni, TCP ve UDP sağlamalarının IP adreslerini içeren
bir sözde başlık üzerinden hesaplanmasıdır. Bu ayrıntı, adres dönüştürmenin katman ihlali
olduğunu somutlaştırır: ağ katmanında çalışan bir cihaz, taşıma katmanı başlığını
değiştirmek zorundadır.

Aynı nedenle, taşıma başlığını okuyamayan bir dönüştürücü çalışamaz. Uçtan uca şifrelenmiş
bir taşıma katmanı, dönüştürmeyi olanaksız kılar.

#### Kapasite Sınırı

Tek bir genel adres üzerinden yapılabilecek eşzamanlı çevrim sayısı, kullanılabilir bağlantı
noktası numarasıyla sınırlıdır.

```python
kullanilabilir = 65535 - 1024 + 1
print("kullanılabilir bağlantı noktası:", kullanilabilir)
for n in (182, 1000, 4000):
    print(f"{n:5d} istemci -> istemci başına eşzamanlı akış: {kullanilabilir // n}")
```

```
kullanılabilir bağlantı noktası: 64512
  182 istemci -> istemci başına eşzamanlı akış: 354
 1000 istemci -> istemci başına eşzamanlı akış: 64
 4000 istemci -> istemci başına eşzamanlı akış: 16
```

Örnek ağın 182 düğümü için istemci başına 354 eşzamanlı akış düşer; bu bol bir paydır.
Ancak sayı düğüm sayısıyla ters orantılıdır ve bin düğümde 64'e iner. Sayfa başına onlarca
bağlantı açan uygulamalar bu sınırı zorlar.

Hesap kötümserdir: çevrim anahtarı hedefi de içerdiğinden, farklı hedeflere giden akışlar
aynı çevrilmiş numarayı paylaşabilir. Yine de sınırın varlığı gerçektir ve büyük ağlarda
birden çok genel adres kullanılmasının nedeni budur.

İkinci bir sınır bellektedir: her akış için bir tablo girdisi tutulur. Girdiler süreli
tutulur ve zaman aşımına uğrar — bu, dönüştürmenin en görünür yan etkilerinden birini
doğurur.

#### Uçtan Uca Bağlantının Bozulması

TCP/IP Modeli dersinde tanıtılan uçtan uca ilkesi, ağın içine durum konmamasını söyler.
Adres dönüştürme bu ilkeyi doğrudan ihlal eder: çevrim tablosu, ağın ortasında tutulan bir
durumdur. Sonuçları sıralanabilir.

**Dışarıdan bağlantı kurulamaz.** İçeriden başlatılmamış bir akışın tabloda karşılığı
yoktur. İçerideki bir cihazın dışarıdan erişilebilir olması için elle bir kural yazılması
gerekir — **bağlantı noktası yönlendirme (port forwarding)**. Örnek ağdaki iç sunucu
`192.168.10.226` dışarıya açılacaksa, `203.0.113.10:443` adresine gelen trafiğin ona
iletileceği bir kural tanımlanır.

**Boşta kalan akışlar kopar.** Tablo girdileri zaman aşımıyla silindiğinde, uzun süre veri
akmayan bir bağlantının dönüş yolu kaybolur. İki uç bağlantının açık olduğunu sanır, ancak
paketler geçmez. Uygulamalar bunu düzenli **canlı tutma** paketleriyle önler; TCP dersinde
bu düzenek ayrıntılandırılacaktır.

**Eşler doğrudan buluşamaz.** İki uç da dönüştürmenin arkasındaysa, hiçbiri diğerine
bağlanamaz. Çözüm, her iki ucun da dışarıdaki ortak bir sunucuya bağlanıp kendi dış adres ve
bağlantı noktasını öğrenmesi, sonra eşzamanlı olarak birbirine paket göndermesidir. Bu
yöntem ancak dönüştürücünün eşleme davranışı öngörülebilirse çalışır; çalışmadığında trafik
bir aktarma sunucusu üzerinden taşınır ve gecikme artar.

**İç istemci kendi dış adresine ulaşamayabilir.** İçeriden `203.0.113.10:443` adresine
bağlanmaya çalışan bir cihazın paketi, dönüştürücüye kendi iç arayüzünden gelir ve geri
dönmesi gerekir. Bu davranış **firkete (hairpinning)** olarak adlandırılır ve her
gerçekleştirimde desteklenmez. Belirtisi tipiktir: bir hizmet dışarıdan çalışır, aynı ağın
içinden çalışmaz.

#### Dönüştürme Bir Güvenlik Düzeneği Değildir

Dışarıdan bağlantı kurulamaması güvenlik gibi görünür, ancak dönüştürme bir güvenlik
düzeneği olarak tasarlanmamıştır ve öyle sayılmamalıdır.

Erişim engeli bir yan etkidir, bir politika değildir. İçeriden başlatılan her akış dışarıya
açılır; kötü amaçlı bir yazılım içeriden bağlantı kurarak engeli aşar. Ayrıca dönüştürme,
geçen trafiğin içeriğine bakmaz; izin verilen bir akış içinde ne taşındığını denetlemez.

Erişim politikası, açıkça yazılmış filtreleme kurallarıyla kurulur. Adres dönüştürme adres
kıtlığını çözer; erişim denetimi ayrı bir işin adıdır.

#### Sağlayıcı Düzeyi Dönüştürme

Adres kıtlığı sağlayıcı düzeyinde de yaşandığında, dönüştürme bir kat daha uygulanır:
abonelere genel adres yerine `100.64.0.0/10` bloğundan adres verilir ve çıkış sağlayıcının
genel adresleri üzerinden yapılır. Buna **sağlayıcı düzeyi adres dönüştürme (carrier-grade
NAT)** denir.

İki kat dönüştürmenin altında bağlantı noktası yönlendirme abone tarafından
tanımlanamaz, eşler arası buluşma daha sık başarısız olur ve bir dış adresi çok sayıda abone
paylaştığı için adres tabanlı tanı anlamını yitirir.

IPv6, bu katmanların hiçbirine gerek bırakmaz: her uca genel adres verilebildiğinde çevrim
tablosu da gereksizleşir. Önceki derste anlatılan geçiş yöntemlerinin gerekçelerinden biri
budur.

#### Özet

- Özel kullanım adresleri genel İnternet'te yönlendirilmez; dışarı çıkış adres
  dönüştürmeyle sağlanır.
- Statik dönüştürme bire bir ve kalıcı, dinamik dönüştürme havuzdan geçici, bağlantı
  noktalı dönüştürme çoktan biredir.
- Çevrim tablosunun anahtarı beş bileşenlidir; farklı iç düğümler aynı kaynak bağlantı
  noktasını kullansa bile dönüş paketleri ayırt edilir.
- Adres ve bağlantı noktası değiştiği için hem IP hem taşıma sağlaması yeniden hesaplanır;
  bu, dönüştürmenin katman ihlali olduğunun kanıtıdır.
- Tek genel adreste 64 512 bağlantı noktası vardır; 182 düğüm için düğüm başına 354, bin
  düğüm için 64 eşzamanlı akış düşer.
- Dönüştürme uçtan uca bağlantıyı bozar: dışarıdan bağlantı kurulamaz, boşta akışlar kopar,
  eşler doğrudan buluşamaz. Bir güvenlik düzeneği değildir.

#### Sonraki Adım

Bu konu boyunca "bağlantı noktası" terimi tanımlanmadan kullanıldı: çevrim tablosunun
anahtarında, kiralama protokolünün 67 ve 68 numaralarında, hedef sunucunun 443'ünde. Bu
numaraların ne olduğu ve bir işletim sisteminin gelen bir segmenti hangi uygulamaya
vereceğine nasıl karar verdiği taşıma katmanının konusudur. Sonraki ders bağlantı
noktalarını, soket kavramını ve bir bağlantıyı benzersiz kılan dörtlüyü ele alacak.

## Taşıma Katmanı

Bağlantı noktaları ve soketler, TCP'nin güvenilirlik mekanizmaları, tıkanıklık denetimi, UDP ve gecikme–verim hesabı.

### Bağlantı Noktaları ve Soketler

Source: https://academia.sh/tr/kurslar/ag-modelleri/baglanti-noktalari-ve-soketler

Uygulama uç noktalarının adreslenmesi, bağlantı noktası aralıkları, bir bağlantıyı benzersiz kılan dörtlü ve dinleyen soket ile bağlantı soketi ayrımı.

Önceki konu boyunca "bağlantı noktası" terimi tanımlanmadan kullanıldı: çevrim tablosunun
anahtarında, kiralama protokolünün 67 ve 68 numaralarında, hedef sunucunun 443'ünde.

Terimin tanımlanma yeri taşıma katmanıdır. Ağ katmanı bir paketi doğru **makineye** ulaştırır
ve orada durur; oysa bir makinede aynı anda onlarca program ağ kullanır. Bu dersin sorusu,
gelen bir segmentin hangi programa verileceğine nasıl karar verildiğidir.

#### Çoğullama

Bir makinede aynı anda birden çok ağ akışı bulunur: bir tarayıcı birkaç sunucuyla konuşur,
bir posta istemcisi arka planda çalışır, bir yedekleme aracı veri gönderir. Hepsinin IP
adresi aynıdır.

Taşıma katmanının ilk görevi bu akışları ayırmaktır. Ayrım için başlığa iki alan konur:
**kaynak bağlantı noktası** ve **hedef bağlantı noktası**. Her biri 16 bittir; değer aralığı
$0$ ile $65\,535$ arasındadır.

Gelen bir segmentin doğru akışa verilmesine **çoğullama çözme (demultiplexing)**, giden
segmentlerin tek bir ağ katmanı akışına bindirilmesine **çoğullama (multiplexing)** denir.
Kapsülleme dersinde tanıtılan çoğullama anahtarları zincirinin son halkası budur: Ethernet
tür alanı IP'ye, IP protokol alanı TCP'ye, TCP bağlantı noktası numarası uygulamaya götürür.

#### Numara Aralıkları

Numaralar üç aralığa bölünmüştür:

| Aralık | Ad | Kullanım |
|---|---|---|
| 0–1023 | İyi bilinen (well-known) | Standartlaşmış hizmetler; atanması yetki gerektirir |
| 1024–49151 | Kayıtlı (registered) | Belirli uygulamalara kaydedilmiş numaralar |
| 49152–65535 | Dinamik / geçici (ephemeral) | İstemcilerin kaynak numarası olarak kullandığı aralık |

İlk aralıktaki numaralar, çoğu işletim sisteminde ayrıcalıklı yetki olmadan bağlanamaz. Bu
kısıt bir güvenlik önlemidir: ayrıcalıksız bir programın standart bir hizmetin numarasını
ele geçirip yerine geçmesi engellenir.

Bazı yerleşik numaralar:

| Numara | Protokol | Hizmet |
|---|---|---|
| 22 | TCP | Güvenli kabuk |
| 53 | UDP ve TCP | Ad çözümleme |
| 67, 68 | UDP | Adres kiralama (sunucu, istemci) |
| 80 | TCP | Kaynak aktarımı |
| 443 | TCP ve UDP | Güvenli kaynak aktarımı |

Numaraların protokolden bağımsız olduğuna dikkat edilmelidir: TCP 443 ile UDP 443 **ayrı
uç noktalardır**. Aynı makinede biri bir uygulamaya, diğeri başka bir uygulamaya ait
olabilir. İki ayrı ad uzayı vardır.

Numaralar bir sözleşmedir, bir zorunluluk değil. Bir hizmet başka bir numarada da
çalıştırılabilir; bu durumda istemcinin numarayı açıkça bilmesi gerekir.

#### Bağlantıyı Benzersiz Kılan Dörtlü

Tek başına bağlantı noktası numarası, bir akışı belirlemeye yetmez. Bir sunucunun 443
numarasına aynı anda binlerce istemci bağlanır ve hepsi aynı hedef numarayı kullanır.

Bir TCP bağlantısını benzersiz kılan **dörtlüdür**:

$$
(\text{kaynak adresi},\ \text{kaynak bağlantı noktası},\ \text{hedef adresi},\ \text{hedef bağlantı noktası})
$$

Protokol de hesaba katıldığında beşli olur; NAT ve PAT dersindeki çevrim tablosunun anahtarı
bu beşliydi.

**Soket (socket)**, bir uçtaki adres ve bağlantı noktası çiftidir; işletim sistemi
düzeyinde ise bu uç noktayı temsil eden nesnedir. İki soket bir bağlantı oluşturur.

Aşağıdaki program aynı dinleyen uç noktaya iki bağlantı kurar ve dörtlüleri iki taraftan da
yazdırır.

```python
import socket
import threading
import time


def sunucu(hazir: threading.Event, kap: dict) -> None:
    dinleyen = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    dinleyen.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    dinleyen.bind(("127.0.0.1", 9101))
    dinleyen.listen(5)
    kap["dinleyen"] = dinleyen.getsockname()
    hazir.set()
    for _ in range(2):
        baglanti, karsi = dinleyen.accept()
        kap.setdefault("baglantilar", []).append((baglanti.getsockname(), karsi))
        baglanti.close()
    dinleyen.close()


hazir = threading.Event()
kap: dict = {}
threading.Thread(target=sunucu, args=(hazir, kap), daemon=True).start()
hazir.wait()
print("dinleyen uç nokta:", kap["dinleyen"])

for i in range(2):
    istemci = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    istemci.connect(("127.0.0.1", 9101))
    print(f"istemci {i + 1}: yerel={istemci.getsockname()} uzak={istemci.getpeername()}")
    istemci.close()

time.sleep(0.2)
for yerel, karsi in kap["baglantilar"]:
    print(f"sunucu tarafı: yerel={yerel} karşı={karsi}")
```

Çıktı:

```
dinleyen uç nokta: ('127.0.0.1', 9101)
istemci 1: yerel=('127.0.0.1', 53044) uzak=('127.0.0.1', 9101)
istemci 2: yerel=('127.0.0.1', 53045) uzak=('127.0.0.1', 9101)
sunucu tarafı: yerel=('127.0.0.1', 9101) karşı=('127.0.0.1', 53044)
sunucu tarafı: yerel=('127.0.0.1', 9101) karşı=('127.0.0.1', 53045)
```

Geçici bağlantı noktası numaraları (`53044`, `53045`) **her çalıştırmada değişir**; işletim
sistemi bunları geçici aralıktan seçer. Değişmeyen, iki bağlantının farklı numaralar almış
olmasıdır. Dörtlüler:

| Bağlantı | Kaynak | Hedef |
|---|---|---|
| 1 | `127.0.0.1:53044` | `127.0.0.1:9101` |
| 2 | `127.0.0.1:53045` | `127.0.0.1:9101` |

Üç bileşen ortaktır, yalnızca kaynak bağlantı noktası farklıdır — ayrımı sağlayan budur.

#### Dinleyen Soket ve Bağlantı Soketi

Çıktıda dikkat çeken bir ayrıntı vardır: sunucu tarafında `9101` numarası hem dinleyen
sokette hem de iki bağlantı soketinde görünür. Bu bir çakışma değildir, çünkü iki tür soket
ayrı anahtarlarla aranır.

| Soket türü | Anahtar | Görevi |
|---|---|---|
| Dinleyen soket | (yerel adres, yerel bağlantı noktası) | Yeni bağlantı isteklerini karşılar |
| Bağlantı soketi | Dörtlünün tamamı | Kurulmuş bir bağlantının verisini taşır |

Gelen bir segment için işletim sistemi önce **tam dörtlü** eşleşmesi arar; bulamazsa ve
segment yeni bağlantı isteğiyse dinleyen sokete yöneltir. Bu ikili arama, tek bir dinleyen
soketin sınırsız sayıda bağlantıya kaynaklık edebilmesini sağlar.

Aynı ayrım, bir sunucunun eşzamanlı kapasitesinin neden bağlantı noktası sayısıyla sınırlı
olmadığını açıklar. Sunucunun numarası tek bir değerde sabittir; farklılaşan, istemci
tarafının adresi ve numarasıdır.

İstemci tarafında ise sınır gerçektir: tek bir istemci makinenin tek bir hedefe kurabileceği
eşzamanlı bağlantı sayısı, geçici aralıktaki numara sayısıyla sınırlıdır. Bu, NAT ve PAT
dersinde hesaplanan kapasite sınırının aynısıdır.

#### Örnek Ağdaki Uç Noktalar

Kursun izlediği akış, dörtlü olarak şöyle yazılır:

| Konum | Kaynak | Hedef |
|---|---|---|
| İstemcide | `192.168.10.196:49152` | `198.51.100.20:443` |
| Dönüştürmeden sonra | `203.0.113.10:61001` | `198.51.100.20:443` |
| Sunucuda görülen | `203.0.113.10:61001` | `198.51.100.20:443` |

Sunucu, istemcinin gerçek adresini ve numarasını hiçbir zaman görmez. Dönüştürme, dörtlünün
iki bileşenini değiştirmiştir ve bu değişiklik iki uç için de görünmezdir.

İç ağda kalan bir akış ise dönüştürmeye uğramaz. Yönetim bölümündeki istemcinin sunucu
odasındaki `192.168.10.226` adresine yaptığı bir istek şu dörtlüyle gider ve yol boyunca
değişmez:

```
192.168.10.196:49160  ->  192.168.10.226:443
```

#### Bağlanma Hataları

Bir uygulamanın bir numaraya bağlanması iki nedenle başarısız olur.

**Numara kullanımda.** Aynı adres ve numara çiftine bağlı başka bir dinleyen soket vardır.
Bir sunucu programı yeniden başlatıldığında bu hata sık görülür; nedeni önceki bağlantıların
kapanış sürecini tamamlamamış olmasıdır. Bu davranışın ayrıntısı TCP dersinde ele
alınacaktır. Yukarıdaki programdaki `SO_REUSEADDR` seçeneği, tam olarak bu durumu aşmak
içindir.

**Yetki yetersiz.** 1024'ün altındaki bir numaraya ayrıcalıksız bir süreç bağlanamaz.

Bağlanırken verilen adres de anlamlıdır. `127.0.0.1` adresine bağlanan bir soket yalnızca
aynı makineden erişilebilir; tüm arayüzleri temsil eden `0.0.0.0` adresine bağlanan soket
ağdan da erişilebilir. Yerel geliştirme sırasında çalışan bir hizmetin ağdan erişilememesi
çoğunlukla bu ayrımdan kaynaklanır.

#### Özet

- Taşıma katmanı, aynı makinedeki akışları 16 bitlik bağlantı noktası numaralarıyla ayırır.
- Numaralar üç aralığa bölünür: iyi bilinen (0–1023), kayıtlı (1024–49151), geçici
  (49152–65535).
- TCP ve UDP numaraları ayrı ad uzaylarıdır; aynı numara iki protokolde iki ayrı uç nokta
  demektir.
- Bir bağlantıyı benzersiz kılan dörtlüdür: kaynak adresi, kaynak numarası, hedef adresi,
  hedef numarası.
- Dinleyen soket yalnızca yerel çiftle, bağlantı soketi dörtlünün tamamıyla aranır; bu
  yüzden tek bir dinleyen soket sınırsız bağlantıya kaynaklık eder.
- Bir sokete bağlanırken verilen adres erişim kapsamını belirler: `127.0.0.1` yalnız yerel,
  `0.0.0.0` tüm arayüzler.

#### Sonraki Adım

Dörtlü, bir akışı adlandırır; akışın güvenilir olacağını söylemez. Ağ katmanı paket
kaybedebilir, sırayı bozabilir, aynı paketi iki kez teslim edebilir. Sonraki ders bu üç
sorunu birden çözen protokolü — el sıkışmasını, sıra numaralarını, yeniden iletimi ve akış
denetimini — ele alacak.

### TCP

Source: https://academia.sh/tr/kurslar/ag-modelleri/tcp

Üç aşamalı el sıkışma, sıra ve onay numaraları, yeniden iletim zamanlayıcısının hesabı, akış denetimi ve bağlantı durum makinesi.

Önceki ders bir akışı adlandıran dörtlüyü kurdu. Adlandırma, akışın güvenilir olacağını
söylemez: ağ katmanı paket kaybedebilir, sırayı bozabilir, aynı paketi iki kez teslim
edebilir ve alıcıyı işleyebileceğinden hızlı besleyebilir.

**TCP (Transmission Control Protocol)** bu dört sorunu birden üstlenir ve uygulamaya tek bir
soyutlama sunar: sıralı, kayıpsız, yinelemesiz bir bayt akışı. Bu dersin sorusu, bu sözün
hangi düzeneklerle tutulduğudur.

#### Verilen Sözler

| Söz | Nasıl tutulur |
|---|---|
| Teslim | Onaylanmayan veri yeniden gönderilir |
| Sıra | Her bayta sıra numarası verilir, alıcı yeniden sıralar |
| Yinelemesizlik | Aynı sıra numarasındaki ikinci kopya atılır |
| Akış denetimi | Alıcı, kabul edebileceği bayt sayısını bildirir |
| Bütünlük | Sağlama, sözde başlıkla birlikte hesaplanır |

Söz verilmeyen şeyler de bilinmelidir. TCP **mesaj sınırı korumaz**: uygulamanın üç ayrı
yazma çağrısı, karşı tarafta tek bir okumada birleşmiş olarak gelebilir. Gecikme üst sınırı
vermez; kayıp durumunda yeniden iletim, gecikmeyi belirgin biçimde artırır. Karşı tarafın
veriyi işlediğini de garanti etmez; onay, verinin taşıma katmanı arabelleğine ulaştığını
gösterir.

#### Başlık

TCP başlığı seçeneksiz hâlde 20 bayttır.

| Alan | Boyut | İşlev |
|---|---|---|
| Kaynak bağlantı noktası | 2 bayt | Gönderen uç nokta |
| Hedef bağlantı noktası | 2 bayt | Alıcı uç nokta |
| Sıra numarası | 4 bayt | Bu segmentin ilk baytının akıştaki konumu |
| Onay numarası | 4 bayt | Beklenen bir sonraki baytın numarası |
| Veri ofseti | 4 bit | Başlık uzunluğu (32 bitlik sözcük) |
| Bayraklar | 8 bit | SYN, ACK, FIN, RST, PSH, URG ve tıkanıklık bitleri |
| Pencere | 2 bayt | Alıcının kabul edebileceği bayt sayısı |
| Sağlama | 2 bayt | Başlık, yük ve sözde başlık üzerinde |
| İvedi işaretçi | 2 bayt | URG bayrağıyla birlikte anlamlı |
| Seçenekler | 0–40 bayt | MSS, pencere ölçeği, zaman damgası, seçmeli onay |

Sağlamanın **sözde başlık** üzerinde hesaplanması, kaynak ve hedef IP adreslerinin de hesaba
katılması demektir. Amaç, yanlış makineye teslim edilmiş bir segmentin sezilmesidir. Bunun
yan etkisi, NAT ve PAT dersinde görüldüğü gibi adres dönüştürücünün sağlamayı yeniden
hesaplamak zorunda kalmasıdır.

#### Üç Aşamalı El Sıkışma

Bağlantı, veri gönderilmeden önce kurulur. Kurulum üç segment alır:

| Adım | Yön | Bayraklar | Taşıdığı |
|---|---|---|---|
| 1 | İstemci → Sunucu | SYN | İstemcinin başlangıç sıra numarası, MSS ve seçenekler |
| 2 | Sunucu → İstemci | SYN + ACK | Sunucunun başlangıç sıra numarası, istemcininkinin onayı |
| 3 | İstemci → Sunucu | ACK | Sunucunun sıra numarasının onayı |

Üç adımın gerekliliği bakışımlıdır: **her iki yön de ayrı ayrı kurulur.** TCP çift yönlüdür;
her yönün kendi sıra numarası dizisi vardır. İstemci kendi numarasını bildirir ve onaylatır,
sunucu da aynısını yapar. İki bakışımlı alışverişten biri (sunucunun onayı ile kendi
bildirimi) tek segmentte birleştirildiği için toplam üç segment olur.

**Başlangıç sıra numarası** sıfır değil, rastgele seçilir. Gerekçe iki katlıdır. Eski bir
bağlantının geciken segmentleri, aynı dörtlüyle kurulan yeni bir bağlantıya karışmamalıdır.
İkincisi güvenliktir: numara tahmin edilebilirse, dışarıdan bir taraf akışa geçerli görünen
segmentler enjekte edebilir.

El sıkışma bir gidiş–dönüş süresi maliyeti getirir. Veri gönderilmeden önce en az bir tam
tur beklenir; bu maliyet, kısa alışverişlerde toplam sürenin büyük bölümünü oluşturabilir.

#### Sıra ve Onay Numaraları

TCP sıra numarasını segmente değil **bayta** verir. Bir segmentin sıra numarası, taşıdığı
ilk baytın akıştaki konumudur.

Başlangıç numarası 1000 ve MSS 1460 olan bir akış:

| Segment | Sıra numarası | Kapsadığı aralık |
|---|---|---|
| 1 | 1000 | 1000 – 2459 |
| 2 | 2460 | 2460 – 3919 |
| 3 | 3920 | 3920 – 5379 |
| 4 | 5380 | 5380 – 6839 |

Onay numarası, **beklenen bir sonraki baytın** numarasıdır ve **birikimlidir**: 6840 onayı,
6839'a kadar her şeyin alındığı anlamına gelir.

Birikimli onayın bir sonucu vardır. İkinci segment kaybolur, üçüncü ve dördüncü ulaşırsa,
alıcı onay numarasını 2460'ta tutmak zorundadır — çünkü 2460'tan itibaren bir boşluk vardır.
Üçüncü ve dördüncü segmentleri aldığını bildiremez.

Bu eksiklik **seçmeli onay (selective acknowledgement)** seçeneğiyle giderilir: alıcı, aldığı
kesintisiz aralıkları ayrıca listeler. Gönderen böylece yalnızca gerçekten eksik olan
segmenti yeniden gönderir; seçenek olmadığında boşluktan sonraki her şeyi yeniden göndermek
zorunda kalabilir.

El sıkışmadaki SYN ve kapanıştaki FIN bayrakları birer sıra numarası tüketir. Veri
taşımasalar da onaylanmaları gerekir; sıra numarası tüketmeleri bunu sağlar.

#### Yeniden İletim

Gönderilen her segment, onaylanana kadar bir arabellekte saklanır. Onay gelmezse segment
yeniden gönderilir. Ne kadar bekleneceğine **yeniden iletim zaman aşımı (retransmission
timeout, RTO)** karar verir.

Sabit bir süre seçilemez: aynı bağlantı üzerinde gidiş–dönüş süresi yol boyunca değişir. Süre
çok kısa seçilirse gereksiz yeniden iletim yapılır ve ağ zaten sıkışıkken daha da yüklenir;
çok uzun seçilirse kayıp geç fark edilir ve verim düşer.

Çözüm, ölçülen gidiş–dönüş sürelerinden yürüyen bir tahmin üretmektir:

$$
\text{SRTT} \leftarrow (1-\alpha)\,\text{SRTT} + \alpha R
$$

$$
\text{RTTVAR} \leftarrow (1-\beta)\,\text{RTTVAR} + \beta \lvert \text{SRTT} - R \rvert
$$

$$
\text{RTO} = \text{SRTT} + 4 \cdot \text{RTTVAR}
$$

Burada $R$ son ölçüm, $\alpha = 1/8$ ve $\beta = 1/4$'tür. İkinci terim, sürenin **değişkenliğini**
hesaba katar: kararlı bir yolda RTO ölçüme yaklaşır, dalgalı bir yolda ondan uzaklaşır.

```python
ALFA, BETA, K = 1 / 8, 1 / 4, 4

olcumler = [100.0, 104.0, 96.0, 180.0, 102.0, 98.0]   # ms

srtt = olcumler[0]
rttvar = olcumler[0] / 2
rto = srtt + K * rttvar
print(f"{'ölçüm':>8s} {'SRTT':>8s} {'RTTVAR':>8s} {'RTO':>8s}")
print(f"{olcumler[0]:8.2f} {srtt:8.2f} {rttvar:8.2f} {rto:8.2f}")

for r in olcumler[1:]:
    rttvar = (1 - BETA) * rttvar + BETA * abs(srtt - r)
    srtt = (1 - ALFA) * srtt + ALFA * r
    rto = srtt + K * rttvar
    print(f"{r:8.2f} {srtt:8.2f} {rttvar:8.2f} {rto:8.2f}")
```

```
   ölçüm     SRTT   RTTVAR      RTO
  100.00   100.00    50.00   300.00
  104.00   100.50    38.50   254.50
   96.00    99.94    30.00   219.94
  180.00   109.95    42.52   280.01
  102.00   108.95    33.87   244.44
   98.00   107.58    28.14   220.15
```

Dördüncü satırdaki 180 ms'lik sıçrama tek başına ortalamayı 110 ms'ye taşımış, değişkenliği
ise 30'dan 42,5'e çıkarmıştır; RTO 220 ms'den 280 ms'ye yükselir. Sonraki kararlı ölçümlerle
değer yeniden iner.

Zaman aşımı gerçekleştiğinde RTO **ikiye katlanır** ve segment yeniden gönderilir. Ard arda
zaman aşımlarında süre üstel olarak büyür. Bu davranış, ağın yanıt vermediği durumda
yeniden iletim trafiğinin sorunu ağırlaştırmasını önler.

Zaman aşımını beklemenin pahalı olduğu durumlar için ikinci bir düzenek vardır. Alıcı,
sıradan sonraki bir segment aldığında aynı onay numarasını tekrarlar; gönderen aynı onayı
üç kez alırsa zaman aşımını beklemeden segmenti yeniden gönderir. Buna **hızlı yeniden
iletim (fast retransmit)** denir ve sonraki dersteki tıkanıklık davranışıyla birlikte
işler.

#### Akış Denetimi

Gönderen, alıcının işleyebileceğinden hızlı gönderirse alıcının arabelleği taşar ve veri
atılır. **Akış denetimi (flow control)** bunu önler: alıcı, her onayda kabul edebileceği
bayt sayısını bildirir. Bu değere **alma penceresi (receive window)** denir.

Gönderenin onaysız gönderebileceği veri miktarı pencereyi aşamaz. Bunun doğrudan bir verim
sonucu vardır:

$$
\text{en çok verim} = \frac{\text{pencere}}{\text{RTT}}
$$

```python
for pencere, rtt in ((65535, 0.020), (65535, 0.100), (262144, 0.100)):
    print(f"pencere {pencere:7d} bayt, RTT {rtt*1000:5.0f} ms -> en çok {pencere*8/rtt/1e6:8.2f} Mb/s")
```

```
pencere   65535 bayt, RTT    20 ms -> en çok    26.21 Mb/s
pencere   65535 bayt, RTT   100 ms -> en çok     5.24 Mb/s
pencere  262144 bayt, RTT   100 ms -> en çok    20.97 Mb/s
```

Pencere alanı 16 bittir; en büyük değeri 65 535 bayttır. Yüksek gecikmeli bir yolda bu değer
verimi 5 Mb/s'ye hapseder — bağlantının kapasitesi ne olursa olsun. Sorun **pencere ölçeği
seçeneğiyle** çözülür: el sıkışmada bir kaydırma miktarı bildirilir ve pencere değeri
$2^k$ ile çarpılır. En büyük kaydırma 14'tür ve pencereyi bir gibabaytın az altına taşır.

Alıcı arabelleği dolduğunda pencere sıfır bildirilir ve gönderen durur. Alıcı yer açtığında
bir pencere güncellemesi gönderir; bu güncelleme kaybolursa bağlantı kilitlenir. Gönderen
bunu önlemek için düzenli olarak tek baytlık **yoklama** segmentleri yollar.

Akış denetimi yalnızca **alıcının** kapasitesini gözetir. Yolun kapasitesi ayrı bir sorundur
ve sonraki dersin konusudur.

#### Durum Makinesi

Bir TCP uç noktası, tanımlı durumlar arasında geçiş yapar.

| Durum | Anlamı |
|---|---|
| CLOSED | Bağlantı yok |
| LISTEN | Sunucu, gelen istekleri bekliyor |
| SYN-SENT | İstemci SYN gönderdi, yanıt bekliyor |
| SYN-RECEIVED | Sunucu SYN aldı, SYN+ACK gönderdi |
| ESTABLISHED | Veri alışverişi yapılabilir |
| FIN-WAIT-1 / FIN-WAIT-2 | Kapatmayı başlatan tarafın bekleyişi |
| CLOSE-WAIT | Karşı taraf kapattı, yerel uygulama henüz kapatmadı |
| LAST-ACK | Son onay bekleniyor |
| TIME-WAIT | Kapanış tamamlandı, gecikmiş segmentler bekleniyor |

Kapanış, kurulumun aksine **dört segment** alır ve iki yön ayrı ayrı kapatılır. Bir taraf
FIN gönderdiğinde yalnızca kendi göndereceği verinin bittiğini bildirir; karşı taraf veri
göndermeye devam edebilir. Bu duruma **yarı kapalı** denir.

`CLOSE-WAIT` durumunda uzun süre kalan bağlantılar bir uygulama hatasının imzasıdır: karşı
taraf kapatmış, yerel uygulama soketi kapatmayı unutmuştur.

`TIME-WAIT` durumu, kapatmayı başlatan tarafta bir süre boyunca tutulur. İki nedeni vardır.
Son onay kaybolursa karşı taraf FIN'i yineler ve onun yanıtlanabilmesi için durumun ayakta
kalması gerekir. İkincisi, bu bağlantıya ait geciken segmentlerin, aynı dörtlüyle kurulacak
yeni bir bağlantıya karışmasını önlemektir.

Bir sunucu yeniden başlatıldığında "adres kullanımda" hatası alması bu durumdan kaynaklanır;
önceki derste geçen `SO_REUSEADDR` seçeneği bu kısıtı gevşetir.

**RST** bayrağı ayrı bir yol izler: bağlantıyı el sıkışmadan, anında sonlandırır. Kapalı bir
bağlantı noktasına gelen segmente ve durumu bozulmuş bağlantılara verilen yanıt budur.

#### Özet

- TCP sıralı, kayıpsız, yinelemesiz bir bayt akışı sunar; mesaj sınırı korumaz ve gecikme
  üst sınırı vermez.
- El sıkışma üç segmenttir çünkü iki yön ayrı kurulur; başlangıç sıra numarası eski
  segmentlerin karışmasını ve enjeksiyonu önlemek için rastgele seçilir.
- Sıra numarası bayta verilir; onay birikimlidir ve boşluk oluştuğunda ilerleyemez, seçmeli
  onay bu eksiği giderir.
- RTO, yürüyen ortalama ve değişkenlikten hesaplanır; zaman aşımında ikiye katlanır, üç
  yinelenen onay hızlı yeniden iletimi tetikler.
- Alma penceresi verimi $\text{pencere}/\text{RTT}$ ile sınırlar; 65 535 bayt ve 100 ms'de
  bu sınır 5,24 Mb/s'dir ve pencere ölçeği seçeneğiyle aşılır.
- Kapanış dört segmenttir ve yönler ayrı kapatılır; `TIME-WAIT`, kaybolan son onay ve
  geciken segmentler için tutulur.

#### Sonraki Adım

Akış denetimi alıcının kapasitesini korur; yolun kapasitesi hakkında hiçbir şey söylemez.
Alıcı bir megabaytlık pencere bildiriyorsa, gönderen bunu ağ ne durumda olursa olsun
dolduracaktır. Sonraki ders, gönderenin ağın kapasitesini nasıl tahmin ettiğini, kaybı bir
sinyal olarak nasıl okuduğunu ve pencerenin verim üzerindeki etkisini hesapla ele alacak.

### Tıkanıklık Denetimi

Source: https://academia.sh/tr/kurslar/ag-modelleri/tikaniklik-denetimi

Tıkanıklık penceresi, yavaş başlangıç ve toplamalı artış–çarpımsal azalış, kaybın sinyal olarak okunması ve kayıp oranının verimle ilişkisi.

Önceki dersin akış denetimi alıcının kapasitesini korur. Alıcı bir megabaytlık pencere
bildiriyorsa, gönderen bu miktarı onaysız gönderme hakkını elde eder — yol boyunca ne olduğu
hesaba katılmadan.

Yol, o kadar veriyi kaldıramayabilir. Yönlendiricilerin kuyrukları dolar, paketler atılır,
atılan paketler yeniden gönderilir ve yeniden gönderimler kuyrukları daha da doldurur. Bu
dersin sorusu, gönderenin göremediği bir kapasiteyi nasıl tahmin edebileceğidir.

#### Tıkanıklık

**Tıkanıklık (congestion)**, bir bağlantıya gelen trafiğin o bağlantının kapasitesini
aşmasıdır. Yönlendirici fazla paketleri kuyruğa alır; kuyruk dolduğunda atmaya başlar.

Denetimsiz bırakıldığında bir geri besleme döngüsü oluşur. Atılan paketler yeniden
gönderilir, yeniden gönderimler yükü artırır, yük arttıkça daha çok paket atılır. Sonuçta
bağlantı üzerinden geçen **yararlı** veri miktarı, yük artmasına karşın düşer. Bu duruma
**tıkanıklık çöküşü (congestion collapse)** denir.

Sorunun zorluğu bilgi eksikliğidir. Gönderen ne yolun kapasitesini bilir ne de aynı yolu
kimlerin paylaştığını. Elindeki tek bilgi kendi gönderdiği segmentlerin başına gelenlerdir.
Bu nedenle tıkanıklık denetimi bir **ölçüm ve uyum** döngüsüdür: gönderen hızını artırır,
ağın tepkisini gözler, tepkiye göre ayarlar.

#### Tıkanıklık Penceresi

Gönderen, alma penceresine ek olarak ikinci bir sınır tutar: **tıkanıklık penceresi
(congestion window, cwnd)**. Bu değer karşı taraftan gelmez; gönderenin kendi tahminidir.

Onaysız gönderilebilecek veri miktarı ikisinin küçüğüdür:

$$
\text{etkin pencere} = \min(\text{cwnd},\ \text{rwnd})
$$

Ayrım anlamlıdır. Alma penceresi **alıcıyı**, tıkanıklık penceresi **ağı** korur. Bir aktarım
yavaşsa hangisinin sınırladığı sorulmalıdır: alıcı arabelleği küçükse alma penceresi, yol
sıkışıksa tıkanıklık penceresi darboğazdır.

#### Yavaş Başlangıç

Bağlantı kurulduğunda yolun kapasitesi hakkında hiçbir bilgi yoktur. Başlangıç değeri küçük
seçilir ve **her onayla** artırılır. Bir tur boyunca pencere kadar segment onaylandığından
pencere her turda ikiye katlanır.

```python
MSS = 1460

cwnd = 1
for tur in range(1, 12):
    print(f"tur {tur:2d}: cwnd={cwnd:5d} MSS = {cwnd * MSS / 1024:8.1f} KiB")
    cwnd *= 2
```

```
tur  1: cwnd=    1 MSS =      1.4 KiB
tur  2: cwnd=    2 MSS =      2.9 KiB
tur  3: cwnd=    4 MSS =      5.7 KiB
tur  4: cwnd=    8 MSS =     11.4 KiB
tur  5: cwnd=   16 MSS =     22.8 KiB
tur  6: cwnd=   32 MSS =     45.6 KiB
tur  7: cwnd=   64 MSS =     91.2 KiB
tur  8: cwnd=  128 MSS =    182.5 KiB
tur  9: cwnd=  256 MSS =    365.0 KiB
tur 10: cwnd=  512 MSS =    730.0 KiB
tur 11: cwnd= 1024 MSS =   1460.0 KiB
```

Evrenin adı yanıltıcıdır: büyüme **üsteldir** ve hızlıdır. "Yavaş" sözcüğü, kapasiteye
doğrudan sıçramak yerine küçükten başlanmasını anlatır.

Üstel büyüme, bir eşiğe kadar sürer. **Yavaş başlangıç eşiği (slow start threshold)**
aşıldığında veya bir kayıp sezildiğinde evre değişir.

#### Toplamalı Artış, Çarpımsal Azalış

Eşikten sonraki evre **tıkanıklıktan kaçınmadır (congestion avoidance)** ve büyüme
doğrusaldır: her turda pencereye bir MSS eklenir.

Kayıp sezildiğinde pencere **çarpımsal** olarak düşürülür — yaygın davranış yarıya
indirmektir. İki kuralın birlikte adı **toplamalı artış, çarpımsal azalış (additive
increase, multiplicative decrease, AIMD)**tir.

Bakışımsızlık bilinçlidir. Artış yavaş olduğu için kapasite aşımı sınırlı kalır; azalış
hızlı olduğu için tıkanıklık çabuk hafifler. Aynı yolu paylaşan akışlar bu kural altında
paylarını dengeler: fazla alan akış kayıptan daha çok etkilenir ve payı düşer.

Bakışımsızlığın bedeli, yüksek kapasiteli ve yüksek gecikmeli yollarda görülür.

```python
import math

MSS = 1460
bdp = 1000e6 * 0.100 / 8
hedef = bdp / MSS
print(f"bant genişliği-gecikme çarpımı: {bdp/1e6:.1f} MB = {hedef:.0f} MSS")
tur_ustel = math.ceil(math.log2(hedef))
print(f"üstel artışla: {tur_ustel} tur = {tur_ustel * 100} ms")
tur_dogrusal = round(hedef / 2)
print(f"doğrusal artışla (yarıdan): {tur_dogrusal} tur = {tur_dogrusal * 100 / 1000:.1f} s")
```

```
bant genişliği-gecikme çarpımı: 12.5 MB = 8562 MSS
üstel artışla: 14 tur = 1400 ms
doğrusal artışla (yarıdan): 4281 tur = 428.1 s
```

1 Gb/s kapasiteli, 100 ms gecikmeli bir yolda pencerenin kapasiteye ulaşması, yukarıdaki
hesabın varsaydığı gibi tek bir MSS'ten başlandığında üstel evrede 1,4 saniye alır; bugün
yaygın olan on MSS'lik başlangıç penceresi bu süreyi dört tur kısaltır, bir saniyeye
indirir. Tek bir kayıp pencereyi yarıya indirirse, doğrusal artışla geri tırmanmak
yedi dakikadan uzun sürer. Bu ölçekteki yollarda klasik AIMD davranışı kapasiteyi
kullanamaz; sonraki bölümde ele alınan yaklaşımların gerekçesi budur.

#### Kaybın Sinyal Olarak Okunması

Klasik tıkanıklık denetimi, paket kaybını tıkanıklık göstergesi sayar. Varsayım şudur:
kablolu bir yolda bit hatası seyrektir, dolayısıyla kaybın nedeni büyük olasılıkla dolu bir
kuyruktur.

Varsayımın geçerli olmadığı durumlar vardır. Kablosuz bağlantılarda paket kaybı girişim veya
sinyal zayıflığından kaynaklanabilir; bu durumda pencereyi yarıya indirmek sorunu çözmez,
yalnızca verimi düşürür. Aynı biçimde, geçici bir yol değişikliğinden kaynaklanan sıra
bozulması yinelenen onaylar üretir ve gereksiz bir azaltmayı tetikleyebilir.

Kaybın oluşmasını beklemeden tıkanıklığı bildirmenin bir yolu vardır: **açık tıkanıklık
bildirimi (explicit congestion notification)**. Kuyruğu dolmaya başlayan yönlendirici paketi
atmak yerine IP başlığındaki iki biti işaretler; alıcı bunu onayında geri bildirir ve
gönderen paket kaybetmeden hızını azaltır. Yöntemin çalışması için yol üzerindeki
düğümlerin ve her iki ucun desteklemesi gerekir.

Üçüncü bir yaklaşım, kaybı hiç beklemeden **gecikmedeki artışı** sinyal olarak okumaktır:
kuyruklar dolmaya başladığında gidiş–dönüş süresi yükselir. Gecikme tabanlı yöntemler
kuyrukları boş tutar ve gecikmeyi düşük tutar; ancak kayıp tabanlı akışlarla aynı yolu
paylaştıklarında pay kaybederler, çünkü diğerleri kuyruk dolana kadar geri çekilmez.

#### Hızlı Yeniden İletim ve Hızlı Kurtarma

Kayıp iki yolla sezilir ve tepki farklıdır.

| Sezme yolu | Anlamı | Tepki |
|---|---|---|
| Zaman aşımı | Ağdan hiç haber yok | Pencere en küçük değere iner, yavaş başlangıca dönülür |
| Üç yinelenen onay | Sonraki segmentler ulaşıyor | Pencere yarıya iner, tıkanıklıktan kaçınma sürer |

Ayrımın gerekçesi bilgi miktarıdır. Yinelenen onay geliyorsa, yol tümüyle kopmamış demektir:
sonraki segmentler alıcıya ulaşmaktadır. Bu durumda sıfırdan başlamak gereksizdir; pencere
yarıya indirilip akış sürdürülür. Buna **hızlı kurtarma (fast recovery)** denir.

Zaman aşımında ise hiçbir onay gelmemiştir; yolun durumu bilinmez ve baştan ölçmek gerekir.

#### Kayıp Oranı ve Verim

Kayıp tabanlı bir akışın uzun dönemli verimi, kayıp oranına ve gidiş–dönüş süresine bağlıdır.
Testere dişi biçimli pencere davranışının ortalaması alınarak şu yaklaşım elde edilir:

$$
\text{verim} \approx \frac{\text{MSS}}{\text{RTT}} \cdot \sqrt{\frac{3}{2p}}
$$

```python
import math

MSS = 1460
for p in (1e-2, 1e-3, 1e-4, 1e-5, 1e-6):
    v = MSS * math.sqrt(1.5) / (0.100 * math.sqrt(p))
    print(f"p={p:.0e} -> {v * 8 / 1e6:8.2f} Mb/s")
```

```
p=1e-02 ->     1.43 Mb/s
p=1e-03 ->     4.52 Mb/s
p=1e-04 ->    14.31 Mb/s
p=1e-05 ->    45.24 Mb/s
p=1e-06 ->   143.05 Mb/s
```

İki sonuç okunur. Birincisi, verim kayıp oranının **kareköküyle ters orantılıdır**: kaybı
yüz kat azaltmak verimi yalnızca on kat artırır. İkincisi, verim gidiş–dönüş süresiyle ters
orantılıdır — uzak bir sunucudan aynı kayıp oranında daha düşük verim alınır.

Bu ilişki, aynı yolu paylaşan iki akıştan gecikmesi düşük olanın daha çok pay almasını da
açıklar. Kısa gidiş–dönüş süresi, penceresini daha sık artırma fırsatı verir.

Formül bir yaklaşımdır ve sınırları vardır: yalnızca kayıp tabanlı davranış için, uzun
süreli ve kararlı akışlarda geçerlidir. Kısa aktarımlar çoğunlukla yavaş başlangıç evresini
bile bitiremez.

#### Arabellek Şişkinliği

Yönlendirici arabelleklerinin büyük tutulması, paket kaybını azaltır ama kuyruk gecikmesini
artırır. Denetim algoritması kaybı bekliyorsa, arabellek dolana kadar hızını artırmaya devam
eder; sonuçta kayıp azalmış, gecikme artmıştır. Bu duruma **arabellek şişkinliği (bufferbloat)**
denir.

Belirtisi tanıdıktır: büyük bir aktarım sürerken aynı bağlantı üzerindeki etkileşimli
kullanımın yanıt süresi belirgin biçimde uzar. Nedeni kapasite yetersizliği değil, sıradaki
paketlerin dolu bir kuyruğun arkasında beklemesidir.

Karşı önlem arabellek küçültmek değil, kuyruğu **etkin biçimde yönetmektir**: kuyruk beklemesi
bir eşiği aştığında paketleri erkenden atmak veya işaretlemek. Böylece gönderene sinyal,
kuyruk tamamen dolmadan verilir.

#### Adalet

Aynı darboğazı paylaşan akışların kapasiteyi nasıl bölüştüğü ayrı bir ölçüttür. AIMD, eşit
gidiş–dönüş süreli akışlar arasında dengeye yakınsar. Süreler farklıysa denge bozulur; kısa
süreli akış daha çok pay alır.

Bir uygulamanın çok sayıda eşzamanlı bağlantı açması da payını artırır: her bağlantı ayrı
bir AIMD döngüsü çalıştırır. Bu, tıkanıklık denetiminin bir uygulama tarafından aşılmasının
en yalın yoludur ve tek bir bağlantı üzerinde çoğullama yapan uygulama protokollerinin
tasarım gerekçelerinden biridir.

#### Özet

- Tıkanıklık, bir bağlantıya gelen trafiğin kapasitesini aşmasıdır; denetimsiz bırakıldığında
  yeniden iletimler yükü artırarak çöküşe yol açar.
- Gönderen iki pencere tutar; onaysız gönderilebilecek miktar tıkanıklık ve alma
  pencerelerinin küçüğüdür.
- Yavaş başlangıçta pencere her turda ikiye katlanır; eşikten sonra turda bir MSS artar ve
  kayıpta çarpımsal olarak azalır.
- 1 Gb/s ve 100 ms'lik bir yolda kapasiteye üstel evrede — tek MSS'lik başlangıçla — 1,4
  saniyede ulaşılır, doğrusal evrede yarıdan tırmanmak 428 saniye sürer.
- Kayıp tabanlı verim $\text{MSS}/\text{RTT} \cdot \sqrt{3/2p}$ ile yaklaşık verilir; verim
  kayıp oranının kareköküyle ve gidiş–dönüş süresiyle ters orantılıdır.
- Zaman aşımı yavaş başlangıca döndürür, üç yinelenen onay yalnızca pencereyi yarıya indirir;
  büyük arabellekler kaybı azaltıp gecikmeyi artırır.

#### Sonraki Adım

TCP'nin sunduğu güvenceler ücretsiz değildir: el sıkışma bir tur, kayıp durumunda yeniden
iletim ek turlar, sıralı teslim ise bekleme getirir. Her uygulama bu bedeli ödemek zorunda
değildir. Sonraki ders, hiçbir güvence vermeyen taşıma protokolünü ve bu yalınlığın hangi
uygulamalarda doğru seçim olduğunu ele alacak.

### UDP

Source: https://academia.sh/tr/kurslar/ag-modelleri/udp

Sekiz baytlık başlık, datagram sınırının korunması, güvencesiz iletimin uygun olduğu uygulamalar ve uygulama katmanında güvenilirlik kurma.

Önceki iki ders TCP'nin güvencelerini ve bunların bedelini kurdu: el sıkışma bir tur, kayıp
durumunda yeniden iletim ek turlar, sıralı teslim ise bekleme.

Bu bedel her uygulama için gerekli değildir; bazıları için doğrudan zararlıdır. Bu dersin
sorusu, hiçbir güvence vermeyen bir taşıma protokolünün ne işe yaradığı ve hangi
gereksinimlerde doğru seçim olduğudur.

#### Sekiz Baytlık Başlık

**UDP (User Datagram Protocol)** başlığı 8 bayttır:

| Alan | Boyut | İşlev |
|---|---|---|
| Kaynak bağlantı noktası | 2 bayt | Gönderen uç nokta; kullanılmıyorsa sıfır |
| Hedef bağlantı noktası | 2 bayt | Alıcı uç nokta |
| Uzunluk | 2 bayt | Başlık dahil datagram boyu |
| Sağlama | 2 bayt | Başlık, yük ve sözde başlık üzerinde |

TCP'nin 20 baytlık başlığındaki alanların çoğu burada yoktur: sıra numarası, onay numarası,
pencere, bayraklar. Yokluklarının nedeni, karşılık gelen düzeneklerin de olmamasıdır.

Sağlama alanı IPv4'te isteğe bağlıdır; sıfır bırakılırsa denetim yapılmaz. IPv6'da
zorunludur, çünkü ağ katmanında başlık sağlaması kaldırılmıştır ve tek denetim taşıma
katmanında kalmıştır.

#### Verilmeyen Sözler

| TCP'nin sözü | UDP |
|---|---|
| Teslim güvencesi | Yok — kaybolan datagram yeniden gönderilmez |
| Sıra | Yok — datagramlar gönderim sırasından farklı gelebilir |
| Yinelemesizlik | Yok — aynı datagram iki kez teslim edilebilir |
| Akış denetimi | Yok — alıcının kapasitesi gözetilmez |
| Tıkanıklık denetimi | Yok — ağın durumu gözetilmez |
| Bağlantı durumu | Yok — el sıkışma ve kapanış yoktur |

Bu liste eksiklik listesi gibi okunmamalıdır. Her satır aynı zamanda bir maliyetin
kaldırılmasıdır: durum tutulmaz, tur beklenmez, gecikmiş veri için sıra bekletilmez.

#### Datagram Sınırı

UDP'nin verdiği tek yapısal söz, **mesaj sınırının korunmasıdır**. Gönderilen her datagram,
alıcıda tek bir okuma işleminde ve aynı boyutla teslim edilir. TCP'de böyle bir söz yoktur:
akış, baytların kesintisiz bir dizisidir ve gönderim çağrılarının sınırları kaybolur.

Aşağıdaki program aynı üç mesajı iki protokolle gönderir ve alınanları yazdırır.

```python
import socket
import threading
import time

MESAJLAR = [b"ALFA", b"BRAVO", b"CHARLIE"]


def tcp_sunucu(alinan: list, hazir: threading.Event) -> None:
    d = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    d.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    d.bind(("127.0.0.1", 9201))
    d.listen(1)
    hazir.set()
    baglanti, _ = d.accept()
    time.sleep(0.3)                       # üç gönderim de arabellekte birikir
    while True:
        parca = baglanti.recv(4096)
        if not parca:
            break
        alinan.append(parca)
    baglanti.close()
    d.close()


def udp_sunucu(alinan: list, hazir: threading.Event) -> None:
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.bind(("127.0.0.1", 9202))
    hazir.set()
    for _ in range(len(MESAJLAR)):
        veri, _ = s.recvfrom(4096)
        alinan.append(veri)
    s.close()


tcp_alinan: list = []
hazir = threading.Event()
threading.Thread(target=tcp_sunucu, args=(tcp_alinan, hazir), daemon=True).start()
hazir.wait()
istemci = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
istemci.connect(("127.0.0.1", 9201))
for m in MESAJLAR:
    istemci.send(m)
time.sleep(0.5)
istemci.close()
time.sleep(0.3)
print("TCP  gönderilen:", MESAJLAR)
print("TCP  okunan    :", tcp_alinan)

udp_alinan: list = []
hazir2 = threading.Event()
threading.Thread(target=udp_sunucu, args=(udp_alinan, hazir2), daemon=True).start()
hazir2.wait()
u = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for m in MESAJLAR:
    u.sendto(m, ("127.0.0.1", 9202))
time.sleep(0.5)
u.close()
print("UDP  gönderilen:", MESAJLAR)
print("UDP  okunan    :", udp_alinan)
```

Çıktı:

```
TCP  gönderilen: [b'ALFA', b'BRAVO', b'CHARLIE']
TCP  okunan    : [b'ALFABRAVOCHARLIE']
UDP  gönderilen: [b'ALFA', b'BRAVO', b'CHARLIE']
UDP  okunan    : [b'ALFA', b'BRAVO', b'CHARLIE']
```

TCP tarafında üç gönderim tek bir okumada birleşmiştir. Bu birleşme **garanti değildir**;
zamanlamaya göre iki veya üç ayrı okumada da gelebilirdi. Garanti olan, sınırların
korunmayacağıdır: TCP üzerinde mesaj taşıyan bir uygulama, mesaj sınırını kendisi
kodlamalıdır — sabit uzunluk, uzunluk öneki veya ayraç kullanarak.

UDP tarafında üç datagram üç ayrı okumada gelmiştir ve bu **garantidir**. Alıcının okuma
arabelleği datagramdan küçükse datagram kırpılır; kalan bölümü kaybolur.

#### Ne Zaman Seçilir

Seçim ölçütü, uygulamanın **geciken veriye ne yaptığıdır**.

| Uygulama sınıfı | Seçim | Gerekçe |
|---|---|---|
| Dosya aktarımı | TCP | Her bayt gerekli; sıra ve bütünlük zorunlu |
| Ad çözümleme | UDP | Tek istek–tek yanıt; el sıkışma turu maliyetin çoğu olur |
| Adres kiralama | UDP | Adres yokken bağlantı kurulamaz |
| Gerçek zamanlı ses ve görüntü | UDP | Geciken çerçeve değersizdir; yeniden iletim zarar verir |
| Etkileşimli oyun durumu | UDP | Eski konum bilgisi yenisiyle geçersizleşir |
| Sürekli ölçüm gönderimi | UDP | Tek bir örneğin kaybı önemsiz |
| Yayın ve çok noktaya gönderim | UDP | TCP çoklu alıcıyı desteklemez |

Gerçek zamanlı akış satırı, seçimin özünü gösterir. Bir ses çerçevesi 200 ms geç ulaşırsa
çalınacağı an geçmiştir; onu yeniden istemek yalnızca ağı yorar. Kayıp çerçevenin yerine
sessizlik veya kestirim koymak, geciken çerçeveyi beklemekten iyidir.

#### Sıra Başı Engellemesi

TCP'nin sıralı teslim sözünün ikinci bir bedeli vardır. Alıcı, akıştaki bir boşluğu
doldurmadan sonraki verileri uygulamaya veremez — elinde olsalar bile. Bir segment
kaybolduğunda, arkasından ulaşan segmentler arabellekte bekletilir. Buna **sıra başı
engellemesi (head-of-line blocking)** denir.

Tek bir akış taşıyan bir bağlantıda bu doğru davranıştır. Ancak tek bir TCP bağlantısı
üzerinde birbirinden bağımsız birden çok mantıksal akış taşınıyorsa, bir akıştaki kayıp
diğerlerini de bekletir — aralarında hiçbir bağımlılık olmamasına karşın.

UDP'de bu engelleme yoktur, çünkü sıra sözü de yoktur. Bağımsız akışları çoğullayan
protokollerin UDP üzerine kurulmasının nedenlerinden biri budur: sıra ve güvenilirlik
akış başına yönetilir, akışlar birbirini bekletmez.

#### Güvenilirliği Uygulamada Kurmak

UDP seçmek, güvenilirlikten vazgeçmek anlamına gelmez; onu **gerektiği kadar** kurmak
anlamına gelir. Uygulama katmanında sık kurulan parçalar şunlardır:

- **Yeniden deneme ve zaman aşımı.** Ad çözümlemedeki tipik kalıp: yanıt gelmezse aynı sorgu
  yinelenir, birkaç denemeden sonra başka bir sunucuya geçilir.
- **Sıra numarası.** Datagramlara numara konarak kayıp ve sıra bozulması sezilir; hangi
  eksiğin telafi edileceğine uygulama karar verir.
- **Seçmeli yeniden iletim.** Yalnızca hâlâ değerli olan veriler yeniden istenir.
- **Hız denetimi.** Tıkanıklık denetimi olmadığından, sürekli veri gönderen bir uygulama
  kendi hız sınırını kendisi koymalıdır.

Son madde ihmal edilmemelidir. Denetimsiz bir UDP akışı, aynı yolu paylaşan TCP akışlarını
geri çekilmeye zorlar ve payını haksız biçimde büyütür; ağın tamamı için de tıkanıklık
riski doğurur.

Bu parçaların tümü kuruluyorsa TCP'yi yeniden yazmak gibi görünür. Fark, **hangi
parçaların** kurulduğudur: uygulama, kendi verisinin hangi bölümünün gecikince değersizleştiğini
bilir; TCP bilemez.

#### Boyut ve Parçalama

UDP gövdeyi bölmez. Uygulama 3000 baytlık bir datagram gönderirse, bölme işi IP katmanına
düşer ve Çerçeve, Paket, Segment dersindeki parçalama maliyeti doğar: parçalardan biri
kaybolursa datagramın tamamı kaybolur.

Bu yüzden UDP kullanan protokoller datagram boyunu yol MTU'sunun altında tutar. Ethernet ve
IPv4 için sınır $1500 - 20 - 8 = 1472$ bayttır; tünel bulunma olasılığına karşı daha güvenli
bir eşik seçmek yaygın bir uygulamadır.

#### Kaynak Adresi Sahteciliği

UDP'de el sıkışma olmadığından, gönderenin adresi hiçbir aşamada doğrulanmaz. Kaynak adresi
başkasına ait gösterilen bir datagram, yanıtın o adrese gitmesine yol açar.

Bunun ölçek sorunu, yanıtın istekten büyük olduğu protokollerde ortaya çıkar: küçük bir
istek, hedefe büyük bir yanıt yönlendirir ve trafik çarpılarak yansıtılır. Karşı önlemler
protokolün dışındadır:

- **Kaynak adresi doğrulaması.** Ağ operatörü, kendi ağından çıkan paketlerin kaynak
  adreslerinin o ağa ait olduğunu denetler. Sahte kaynaklı paket ağdan çıkamaz.
- **Yanıt hızı sınırlaması.** Aynı kaynağa verilen yanıt sayısı sınırlanır.
- **Sorgu doğrulama.** Sunucu, büyük yanıt vermeden önce isteğin gerçekten o adresten
  geldiğini küçük bir alışverişle sınar.

TCP'de aynı sahtecilik daha zordur: el sıkışmanın ikinci adımındaki sıra numarasını görmek
gerekir ve numara rastgele seçilir. TCP dersinde belirtilen rastgelelik gereksiniminin
gerekçelerinden biri budur.

#### Özet

- UDP başlığı 8 bayttır; sıra, onay, pencere ve bayrak alanları yoktur çünkü karşılık gelen
  düzenekler de yoktur.
- Teslim, sıra, yinelemesizlik, akış ve tıkanıklık denetimi güvenceleri verilmez; karşılığında
  durum tutulmaz ve tur beklenmez.
- UDP mesaj sınırını korur; TCP korumaz — TCP üzerinde mesaj taşıyan uygulama sınırı kendisi
  kodlamalıdır.
- Seçim ölçütü, geciken verinin uygulama için hâlâ değerli olup olmadığıdır.
- Sıra başı engellemesi, bağımsız akışların tek bir TCP bağlantısında birbirini bekletmesine
  yol açar; UDP'de bu engelleme yoktur.
- Uygulama katmanında yeniden deneme, sıra numarası ve hız denetimi kurulabilir; hız
  denetimi ihmal edilirse akış paylaşımı bozulur.

#### Sonraki Adım

İki protokolün de verimi aynı fiziksel gerçeklere çarpar: bir bit tel üzerine konması zaman
alır, ışık sonlu hızda ilerler, kuyruklar bekletir. Sonraki ders bu bileşenleri ayırarak
gecikmenin nereden geldiğini, bant genişliği ile gecikmenin çarpımının neden bir kapasite
ölçüsü olduğunu ve bir aktarımın süresini belirleyenin çoğu zaman bant genişliği olmadığını
hesapla gösterecek.

### Gecikme ve Verim

Source: https://academia.sh/tr/kurslar/ag-modelleri/gecikme-ve-verim

Gecikmenin dört bileşeni, bant genişliği–gecikme çarpımı, pencere boyutlandırma ve bir aktarım süresinin bileşenlerine ayrılması.

Önceki iki ders taşıma protokollerinin verimi nasıl sınırladığını gösterdi: pencere, kayıp
oranı, tıkanıklık davranışı. Bu sınırların altında daha temel bir katman vardır — bir bitin
tel üzerine konması zaman alır ve sinyal sonlu hızda ilerler.

Bu dersin sorusu, "bağlantım 100 Mb/s" cümlesinin bir aktarımın süresi hakkında ne
söylediği ve ne söylemediğidir. Yanıt çoğu durumda beklenenden farklıdır: süreyi belirleyen
çoğunlukla bant genişliği değildir.

#### Gecikmenin Dört Bileşeni

Bir paketin bir bağlantıyı geçmesi dört bileşenden oluşur.

**İletim süresi (transmission delay)**, paketin tüm bitlerinin tel üzerine konması için
geçen süredir. Paket boyu ile bağlantı hızının oranıdır:

$$
d_{\text{iletim}} = \frac{L}{R}
$$

```python
for hiz in (10e6, 100e6, 1e9, 10e9):
    print(f"{hiz/1e6:8.0f} Mb/s -> {1500*8/hiz*1e6:8.2f} us")
```

```
      10 Mb/s ->  1200.00 us
     100 Mb/s ->   120.00 us
    1000 Mb/s ->    12.00 us
   10000 Mb/s ->     1.20 us
```

**Yayılım süresi (propagation delay)**, sinyalin mesafeyi kat etmesi için geçen süredir.
Mesafe ile ortamdaki yayılım hızının oranıdır ve paket boyundan **bağımsızdır**. Fiber
içinde hız yaklaşık $2 \times 10^8$ m/s'dir.

```python
for km in (1, 100, 1000, 10000):
    print(f"{km:6d} km -> {km*1000/2e8*1000:8.3f} ms")
```

```
     1 km ->    0.005 ms
   100 km ->    0.500 ms
  1000 km ->    5.000 ms
 10000 km ->   50.000 ms
```

**Kuyruk gecikmesi (queuing delay)**, paketin yönlendiricide sırasını beklemesidir. Tek
değişken bileşendir: yük arttıkça büyür ve kapasiteye yaklaşıldığında hızla artar. Arabellek
şişkinliğinin gecikme üzerindeki etkisi bu bileşende görülür.

**İşleme gecikmesi (processing delay)**, başlığın okunması ve yönlendirme kararının
verilmesi için geçen süredir; diğerlerinin yanında küçük kalır.

İki bileşenin ölçek farkı belirleyicidir. 1 Gb/s'lik bir bağlantıda 1500 baytlık bir paketin
iletimi 12 mikrosaniye sürerken, aynı paketin bin kilometre gitmesi 5 milisaniye sürer —
dört yüz katı. **Uzun mesafede süreyi belirleyen bant genişliği değil, ışığın hızıdır.**
Bant genişliğini artırmak iletim süresini kısaltır; yayılım süresine dokunamaz.

#### Gidiş–Dönüş Süresi

**Gidiş–dönüş süresi (round-trip time, RTT)**, bir paketin hedefe gidip yanıtın dönmesi
için geçen toplam süredir. İki yöndeki tüm bileşenlerin toplamıdır.

Ölçülen değer, iki uç arasındaki coğrafi mesafenin altına inemez. Bin kilometrelik bir yol,
gidiş–dönüşte en az 10 ms yayılım süresi gerektirir; ara yönlendiriciler ve kuyruklar bunu
artırır. Bir ölçümde bu alt sınırın altına düşen değer, hedefin sanılan yerde olmadığını
gösterir.

RTT, taşıma katmanının her düzeneğinin ölçü birimidir: el sıkışma bir RTT, pencere
güncellemesi bir RTT, tıkanıklık penceresinin her artışı bir RTT alır.

#### Bant Genişliği–Gecikme Çarpımı

**Bant genişliği–gecikme çarpımı (bandwidth-delay product, BDP)**, yol üzerinde aynı anda
"uçuşta" olabilecek veri miktarıdır:

$$
\text{BDP} = R \times \text{RTT}
$$

Ölçü, yolun bir boru gibi düşünülmesinden gelir: bant genişliği borunun kesiti, gidiş–dönüş
süresi uzunluğudur; çarpım borunun hacmidir.

```python
for mbps, rtt in ((100, 0.040), (100, 0.100), (1000, 0.040), (1000, 0.100)):
    bdp = mbps*1e6*rtt/8
    print(f"{mbps:5d} Mb/s x {rtt*1000:5.0f} ms = {bdp:12.0f} bayt = "
          f"{bdp/1024:9.2f} KiB = {bdp/1460:8.1f} MSS")
```

```
  100 Mb/s x    40 ms =       500000 bayt =    488.28 KiB =    342.5 MSS
  100 Mb/s x   100 ms =      1250000 bayt =   1220.70 KiB =    856.2 MSS
 1000 Mb/s x    40 ms =      5000000 bayt =   4882.81 KiB =   3424.7 MSS
 1000 Mb/s x   100 ms =     12500000 bayt =  12207.03 KiB =   8561.6 MSS
```

BDP'nin doğrudan bir sonucu vardır: **pencere BDP'den küçükse bağlantı boş kalır.** Gönderen
pencereyi doldurur, onay bekler, bu süre boyunca hiçbir şey göndermez. Verim, TCP dersinde
kurulan bağıntıyla sınırlanır.

Gereken pencere boyutu ve pencere ölçeği doğrudan hesaplanır:

| Hedef verim | RTT | Gereken pencere | Gereken ölçek |
|---|---|---|---|
| 100 Mb/s | 40 ms | 488,3 KiB | 3 |
| 500 Mb/s | 100 ms | 6103,5 KiB | 7 |

Ölçeksiz en büyük pencere 65 535 bayttır; her iki satır da onu aşar. Yüksek kapasiteli
yollarda pencere ölçeği seçeneği bir eniyileme değil, zorunluluktur.

#### Bir Aktarımın Bileşenleri

Örnek ağdaki istemcinin `198.51.100.20` adresinden 2 MiB'lik bir kaynak aldığını
varsayalım. Dış bağlantı 100 Mb/s, sunucuya gidiş–dönüş süresi 40 ms, MSS 1460 bayt,
başlangıç tıkanıklık penceresi 10 MSS.

```python
MSS = 1460
BOYUT = 2 * 1024 * 1024
HIZ = 100e6
RTT = 0.040
bdp_mss = HIZ * RTT / 8 / MSS

cwnd = 10
gonderilen = 0
tur = 0
while gonderilen < BOYUT and cwnd < bdp_mss:
    tur += 1
    bu_tur = cwnd * MSS
    gonderilen += bu_tur
    print(f"tur {tur}: cwnd={cwnd:4d} MSS, bu turda {bu_tur:7d} bayt, "
          f"toplam {gonderilen:8d} bayt")
    cwnd *= 2

kalan = BOYUT - gonderilen
toplam = RTT + tur * RTT + kalan * 8 / HIZ
print(f"el sıkışma {RTT*1000:.0f} ms + yavaş başlangıç {tur*RTT*1000:.0f} ms + "
      f"kalan {kalan*8/HIZ*1000:.1f} ms = {toplam*1000:.0f} ms")
print(f"salt iletim süresi olsaydı: {BOYUT*8/HIZ*1000:.0f} ms")
print(f"gerçekleşen ortalama verim: {BOYUT*8/toplam/1e6:.1f} Mb/s")
```

```
tur 1: cwnd=  10 MSS, bu turda   14600 bayt, toplam    14600 bayt
tur 2: cwnd=  20 MSS, bu turda   29200 bayt, toplam    43800 bayt
tur 3: cwnd=  40 MSS, bu turda   58400 bayt, toplam   102200 bayt
tur 4: cwnd=  80 MSS, bu turda  116800 bayt, toplam   219000 bayt
tur 5: cwnd= 160 MSS, bu turda  233600 bayt, toplam   452600 bayt
tur 6: cwnd= 320 MSS, bu turda  467200 bayt, toplam   919800 bayt
el sıkışma 40 ms + yavaş başlangıç 240 ms + kalan 94.2 ms = 374 ms
salt iletim süresi olsaydı: 168 ms
gerçekleşen ortalama verim: 44.8 Mb/s
```

Sonuç okunmaya değer. Salt iletim 168 ms sürerdi; gerçekleşen süre 374 ms'dir. Aradaki
farkın tamamı gecikme kaynaklıdır: bir tur el sıkışma, altı tur pencere büyütme. Ortalama
verim, bağlantı kapasitesinin yarısının altında kalmıştır.

Bu bir model hesabıdır; kayıp, ad çözümleme ve güvenli taşıma el sıkışması hesaba
katılmamıştır. Her biri en az bir tur daha ekler. Modelin gösterdiği şey mutlak süre değil,
**bileşenlerin oranıdır**.

#### Küçük Aktarımlarda Belirleyici Olan

Aktarım küçüldükçe gecikmenin payı büyür.

```python
HIZ = 100e6            # önceki örnekle aynı bağlantı
RTT = 0.040

kucuk = 20 * 1024
print(f"salt iletim: {kucuk*8/HIZ*1000:.2f} ms; "
      f"el sıkışma+ilk yanıt: {2*RTT*1000:.0f} ms")
print(f"gecikmenin payı: {2*RTT/(2*RTT + kucuk*8/HIZ)*100:.1f} %")
```

```
salt iletim: 1.64 ms; el sıkışma+ilk yanıt: 80 ms
gecikmenin payı: 98.0 %
```

20 KiB'lik bir kaynak için sürenin %98'i beklemeyle geçer. Bant genişliğini ikiye katlamak
1,64 ms'yi 0,82 ms'ye indirir ve toplamda fark edilmez; gidiş–dönüş süresini yarıya indirmek
ise toplam süreyi neredeyse yarıya indirir.

Bu asimetri, birçok tasarım kararının gerekçesidir: içeriği kullanıcıya coğrafi olarak
yakın tutmak, tur sayısını azaltmak, bağlantıları yeniden kullanmak. Hepsi gecikmeye
yöneliktir, bant genişliğine değil.

#### Verim ile Bant Genişliği Aynı Şey Değildir

Üç terim ayrılmalıdır.

| Terim | Tanımı | Ölçülür mü |
|---|---|---|
| Bant genişliği | Bağlantının kuramsal üst sınırı | Genellikle bildirilir |
| Verim (throughput) | Belirli bir akışta gerçekleşen hız | Ölçülür |
| İyi verim (goodput) | Uygulamaya ulaşan yararlı veri hızı | Başlık ve yeniden iletim düşülür |

Üçü arasındaki fark, bu kurs boyunca kurulan her düzenekten pay alır: başlık yükü, yeniden
iletim, pencere sınırı, tıkanıklık davranışı, parçalama.

Bir aktarımın yavaş olduğu söylendiğinde sorulacak sorular sırayla şunlardır. Darboğaz alma
penceresi mi, tıkanıklık penceresi mi? Kayıp oranı nedir? Gidiş–dönüş süresi beklenenin
üstünde mi? Yol MTU keşfi çalışıyor mu? Her sorunun yanıtı, bu kursun bir dersinde
kurulmuştur.

#### Özet

- Gecikme dört bileşenden oluşur: iletim, yayılım, kuyruk ve işleme. Yalnızca iletim süresi
  bant genişliğine bağlıdır.
- Uzun mesafede süreyi yayılım belirler: 1 Gb/s'de 1500 baytlık paketin iletimi 12 µs,
  bin kilometrelik yayılımı 5 ms sürer.
- Bant genişliği–gecikme çarpımı, yolda aynı anda uçuşta olabilecek veri miktarıdır; pencere
  bundan küçükse bağlantı boş kalır.
- 100 Mb/s ve 40 ms için BDP 488 KiB'dir; ölçeksiz en büyük pencere 64 KiB olduğundan
  pencere ölçeği zorunludur.
- 2 MiB'lik bir aktarımda salt iletim 168 ms, el sıkışma ve yavaş başlangıçla birlikte
  374 ms sürer; ortalama verim kapasitenin yarısının altında kalır.
- Küçük aktarımlarda sürenin neredeyse tamamı beklemedir; bant genişliğini artırmak fark
  yaratmaz, gidiş–dönüş süresini kısaltmak yaratır.

#### Kurs Kapanışı

Bu kurs tek bir örnek üzerinden yürüdü: `192.168.10.0/24` bloğuna sahip bir kurumun ağı ve o
ağdaki `192.168.10.196` adresli istemcinin dış dünyaya gönderdiği bir paket.

Katmanlı modeller, paketin hangi sorunları hangi sırayla çözdüğünü tanımladı ve bir arızayı
doğru katmana yerleştirmenin yolunu verdi. Kapsülleme, verinin katman katman sarmalanmasını
ve bu sarmalamanın maliyetini gösterdi.

Bağlantı ve ağ katmanı konusu adres planını kurdu. Eşit bölmenin 640 adres istediği yerde
değişken uzunluklu bölme aynı işi 244 adresle yaptı; plan, kiralama havuzlarına ve dış
çıkış için çevrim tablosuna dönüştü. Aynı ağ IPv6 ile yeniden adreslendiğinde adres sayımı
hiç yapılmadı — kıtlığın ortadan kalkması, planlama işini de değiştirmişti.

Taşıma katmanı konusu, bu paketin bir akışın parçası olduğunu gösterdi. Dörtlü akışı
adlandırdı; TCP güvenilirlik sözünü sıra numaraları, yeniden iletim ve pencerelerle tuttu;
tıkanıklık denetimi görünmeyen bir kapasiteyi ölçüm ve uyumla tahmin etti; UDP bu sözlerin
hangi durumlarda gereksiz olduğunu gösterdi. Son ders, tüm bu düzeneklerin altındaki fiziksel
sınırları ayırdı.

Kursun kazanımları buluşur: bir sorunu doğru katmana yerleştirmek, bir adres planı tasarlayıp
sınamak ve bir uygulamanın gereksinimine göre taşıma protokolü seçmek. Üçü de aynı alışkanlığa
dayanır — bir davranışı, onu üreten düzeneğe kadar izlemek.

Bir sonraki kurs olan Uygulama Katmanı Protokolleri, buradaki taşıma soyutlamasının üstünde
çalışan protokolleri ele alır: HTTP sürümlerinin tasarım farkları ve bunların sıra başı
engellemesiyle ilişkisi, güvenli taşıma el sıkışmasının ek turları ve sertifika zincirinin
doğrulanması, gerçek zamanlı iletişim için protokol seçimi. Bu kursta hesaplanan gecikme
bütçesi, oradaki her tasarım kararının ölçütü olacaktır.

