6-bo‘lim
IPv6
IPv4 manzillari nima uchun tugadi, IPv6 yozuvi va qisqartirish qoidalari, manzil turlari va ikki stekli ishlash.
Ushbu bo‘lim mundarijasi
1981-yilda IPv4 ta'riflanganda to'rt milliard manzil cheksiz ko'p tuyulgan edi. O'sha paytda internetga ulangan kompyuterlar soni yuzlab edi.
Bugun har bir odamda bir necha qurilma bor.
Manzillar haqiqatan tugadi #
import ipaddress
v4 = ipaddress.IPv4Network("0.0.0.0/0")
v6 = ipaddress.IPv6Network("::/0")
print("IPv4 manzillari:", f"{v4.num_addresses:,}".replace(",", " "))
print("IPv6 manzillari:", f"{v6.num_addresses:.3e}")
print()
print("IPv4 - bitlar soni:", v4.max_prefixlen)
print("IPv6 - bitlar soni:", v6.max_prefixlen)
print("necha barobar ko'p:", f"2^{v6.max_prefixlen - v4.max_prefixlen}")
# Yer yuzidagi har kvadrat metrga nechta manzil to'g'ri keladi?
YER_YUZASI_M2 = 510_000_000 * 1_000_000 # 510 mln km2
print()
print("har kvadrat metrga:", f"{v6.num_addresses // YER_YUZASI_M2:.3e}")
IPv4 manzillari: 4 294 967 296
IPv6 manzillari: 3.403e+38
IPv4 - bitlar soni: 32
IPv6 - bitlar soni: 128
necha barobar ko'p: 2^96
har kvadrat metrga: 6.672e+23
Manzil uzunligi 32 bitdan 128 bitga o'tdi. Bu to'rt barobar emas - 2⁹⁶ barobar ko'p. Yer yuzining har kvadrat metriga 6,6×10²³ ta manzil to'g'ri keladi.
5 raqami 1970-yillarda boshqa tajriba protokoliga (*Internet
Stream Protocol*) berib yuborilgan edi.
Yangi versiya kelganda 5 band edi, shuning uchun u to'g'ridan- to'g'ri 6 raqamini oldi.
Yozuv va qisqartirish #
IPv6 manzil 128 bit - sakkizta guruh, har biri to'rtta o'n oltilik raqam. To'liq yozuv juda uzun, shuning uchun ikkita qisqartirish qoidasi bor:
- Guruh boshidagi nollar tashlab ketiladi:
0db8→db8. - Ketma-ket kelgan nol guruhlar
::bilan almashtiriladi - faqat bir marta.
import ipaddress
manzillar = [
"2001:0db8:0000:0000:0000:ff00:0042:8329",
"2001:db8::ff00:42:8329",
"fe80::1",
"::1",
"::",
]
for m in manzillar:
a = ipaddress.IPv6Address(m)
print("yozilgani :", m)
print("qisqargani:", a.compressed)
print("to'liq :", a.exploded)
print()
yozilgani : 2001:0db8:0000:0000:0000:ff00:0042:8329
qisqargani: 2001:db8::ff00:42:8329
to'liq : 2001:0db8:0000:0000:0000:ff00:0042:8329
yozilgani : 2001:db8::ff00:42:8329
qisqargani: 2001:db8::ff00:42:8329
to'liq : 2001:0db8:0000:0000:0000:ff00:0042:8329
yozilgani : fe80::1
qisqargani: fe80::1
to'liq : fe80:0000:0000:0000:0000:0000:0000:0001
yozilgani : ::1
qisqargani: ::1
to'liq : 0000:0000:0000:0000:0000:0000:0000:0001
yozilgani : ::
qisqargani: ::
to'liq : 0000:0000:0000:0000:0000:0000:0000:0000
Birinchi ikki manzil bir xil ekaniga e'tibor bering - ular shunchaki turlicha yozilgan.
:: faqat bir marta ishlatiladiAgar manzilda ikkita alohida nol guruhlari bo'lsa, ularning
faqat bittasini :: bilan qisqartirish mumkin.
Sabab oddiy: ikki marta ishlatilsa, qaysi :: nechta nolni
yashirayotganini aniqlab bo'lmaydi.
Shuning uchun 2001:0:0:1:0:0:0:1 ni 2001::1::1 deb yozib
bo'lmaydi - bu xato. To'g'risi: 2001:0:0:1::1.
Manzil turlari #
IPv6 da xususiy/ommaviy bo'linish boshqacha tashkil qilingan:
import ipaddress
manzillar = {
"2606:2800:220:1:248:1893:25c8:1946": "ommaviy sayt",
"fe80::215:5dff:feae:a236": "havola-mahalliy",
"fd00:1234::1": "noyob mahalliy (ichki)",
"ff02::1": "ko'p manzilli - shu havoladagi hamma",
"::1": "loopback",
}
for m, izoh in manzillar.items():
a = ipaddress.IPv6Address(m)
turlar = []
if a.is_loopback:
turlar.append("loopback")
if a.is_link_local:
turlar.append("havola-mahalliy")
if a.is_multicast:
turlar.append("ko'p manzilli")
if a.is_private:
turlar.append("xususiy")
if a.is_global:
turlar.append("global")
print(f"{m}")
print(f" izoh : {izoh}")
print(f" turi : {', '.join(turlar)}")
2606:2800:220:1:248:1893:25c8:1946
izoh : ommaviy sayt
turi : global
fe80::215:5dff:feae:a236
izoh : havola-mahalliy
turi : havola-mahalliy, xususiy
fd00:1234::1
izoh : noyob mahalliy (ichki)
turi : xususiy
ff02::1
izoh : ko'p manzilli - shu havoladagi hamma
turi : ko'p manzilli, global
::1
izoh : loopback
turi : loopback, xususiy
ff02::1 uchun "global" chiqdi - bunga ishonmangBu - kutubxonaning ichki qoidasi natijasi, protokol haqiqati emas.
Python da is_global shunchaki is_private ning teskarisi
sifatida hisoblanadi. ff02::1 esa xususiy diapazonlar
ro'yxatiga kiritilmagan - shuning uchun "global" chiqdi.
Aslida ff02:: bilan boshlanadigan manzillar havola
doirasidagi ko'p manzilli guruhdir: ular birinchi
marshrutizatordan nariga o'tmaydi.
Xulosa: kutubxona javobi bilan protokol qoidasi har doim ham bir xil emas. Shubha tug'ilsa - standartga qarang.
Asosiy turlar:
| Prefiks | Turi | IPv4 dagi o'xshashi |
|---|---|---|
2000::/3 | Global unicast | Ommaviy manzillar |
fc00::/7 | Noyob mahalliy | 10.x, 192.168.x |
fe80::/10 | Havola-mahalliy | 169.254.x |
ff00::/8 | Ko'p manzilli | Tarqatish o'rniga |
::1 | Loopback | 127.0.0.1 |
IPv4 da 192.168.1.255 ga yuborilgan paketni hamma oladi -
hatto qiziqmaganlar ham.
IPv6 da bundan voz kechildi. O'rniga ko'p manzilli guruhlar ishlatiladi:
| Manzil | Kim eshitadi |
|---|---|
ff02::1 | Havoladagi barcha qurilmalar |
ff02::2 | Faqat marshrutizatorlar |
Farqi shuki, qurilma o'zi qiziqadigan guruhga obuna bo'ladi. Qolganlari paketni umuman ko'rmaydi va ularning protsessori bekorga band bo'lmaydi.
IPv6 bilan dasturlash #
Soket kodi deyarli o'zgarmaydi - faqat oila AF_INET6 bo'ladi:
import socket
PORT = 9200
# AF_INET6 - IPv6 soketi. Manzil ::1 - IPv6 dagi loopback.
server = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(("::1", PORT))
server.listen(1)
mijoz = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
mijoz.connect(("::1", PORT))
ulanish, kim = server.accept()
mijoz.sendall("IPv6 orqali salom".encode())
print("server oldi:", ulanish.recv(1024).decode())
# IPv6 manzili to'rt elementli: (manzil, port, oqim, qamrov)
print("mijoz manzili elementlari:", len(mijoz.getsockname()))
print("manzil:", mijoz.getpeername()[0])
print("port :", mijoz.getpeername()[1])
mijoz.close()
ulanish.close()
server.close()
server oldi: IPv6 orqali salom
mijoz manzili elementlari: 4
manzil: ::1
port : 9200
Bitta farq bor: IPv4 da manzil ikki elementli (manzil, port),
IPv6 da esa to'rt elementli. Qo'shimcha ikkitasi oqim
belgisi va qamrov identifikatori uchun.
Aynan shuning uchun manzil[0] va manzil[1] deb yozgan kod
ikkala versiyada ham ishlaydi, manzil == (ip, port) deb
taqqoslagan kod esa IPv6 da buziladi.
Manzilni qo'lda yozish o'rniga getaddrinfo ishlatiladi - u
nom uchun mavjud barcha variantlarni qaytaradi:
| Yondashuv | Natija |
|---|---|
AF_INET qattiq yozilgan | Faqat IPv4 |
AF_INET6 qattiq yozilgan | Faqat IPv6 |
getaddrinfo + AF_UNSPEC | Ikkalasi ham |
Zamonaviy mijozlar Happy Eyeballs usulini qo'llaydi: IPv6 va IPv4 ga deyarli bir vaqtda ulanib ko'radi va qaysi biri tezroq javob bersa, o'shani ishlatadi.
Shu tufayli IPv6 sekin ishlayotgan tarmoqda ham sayt tez ochiladi.
O'tish nima uchun shuncha cho'zildi? #
IPv6 1998-yilda standart bo'lgan. 2012-yilda "World IPv6 Launch" o'tkazildi. Shunga qaramay bugun ham ko'p tarmoqlarda faqat IPv4 ishlaydi.
Sabab - ular bir-biri bilan gaplasha olmaydi:
| Muammo | Natija |
|---|---|
| IPv6 qurilma IPv4 serverga to'g'ridan-to'g'ri ulana olmaydi | Ikkalasi kerak |
| Eski qurilmalar IPv6 ni bilmaydi | Almashtirish qimmat |
| NAT IPv4 ni "yetarli" qilib qo'ydi | Shoshilishga sabab yo'q |
Uchinchi qator eng muhimi: NAT (10-bo'lim) muammoni yumshatdi va shu bilan o'tishni ham sekinlashtirdi.
Amaldagi yechim - ikki stek (dual stack): qurilmada ikkala protokol ham bir vaqtda ishlaydi va kerak bo'lganini tanlaydi.
- Manzil hajmi misolini ishga tushiring.
2001:0db8:0000:0000:0000:0000:0000:0001ni qo'lda qisqartiring, keyin tekshiring.2001:0:0:1:0:0:0:1ni to'g'ri qisqartiring.- Ikkita
::yozib ko'ring va qanday xato chiqqanini yozing. - Manzil turlari misoliga o'z manzilingizni qo'shing.
ip -6 addrbilan kompyuteringizdagi IPv6 manzillarni ko'ring.fe80::bilan boshlanadiganini toping - u nima uchun kerak?- IPv6 soket misolini ishga tushiring.
::1ni127.0.0.1ga almashtiring - qanday xato chiqdi?- IPv4 va IPv6 manzil kortejlari farqini tushuntiring.
Xulosa #
- IPv4 da 32 bit, IPv6 da 128 bit - 2⁹⁶ barobar ko'p manzil.
- IPv6 yozuvi sakkiz guruhdan iborat; nollar tashlanadi va
::bilan qisqartiriladi. ::manzilda faqat bir marta ishlatilishi mumkin.2000::/3- global,fc00::/7- ichki,fe80::/10- havola-mahalliy.- IPv6 da tarqatish yo'q - uning o'rnida ko'p manzilli guruhlar.
ff02::1- havoladagi hamma,ff02::2- faqat marshrutizatorlar.- Kutubxona bergan belgi (
is_global) protokol haqiqatiga har doim mos kelmaydi. - Soket kodi deyarli bir xil:
AF_INETo'rnigaAF_INET6. - IPv6 manzil korteji to'rt elementli, IPv4 niki - ikkita.
- Amalda ikki stek ishlatiladi; mijozlar Happy Eyeballs bilan tezrog'ini tanlaydi.
Keyingi bo'limda transport qatlamiga ko'tarilamiz va eng sodda protokoldan - UDP dan boshlaymiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.