Bagaimana MTU adalah 65535 di UDP tetapi ethernet tidak memungkinkan ukuran bingkai lebih dari 1500 byte

11

Saya menggunakan ethernet cepat 100 Mbps, yang ukuran frame-nya kurang dari 1500 byte (1472 byte untuk payload sesuai buku teks saya). Dalam hal itu, saya dapat mengirim dan menerima paket UDP ukuran pesan 65507 byte, yang berarti ukuran paket itu 65507 + 20 (IP Header) + 8 (Header UDP) = 65535.

Jika ukuran payload frame itu sendiri maksimum 1472 byte (sesuai buku teks saya), bagaimana ukuran paket IP bisa lebih besar daripada yang di sini adalah 65535?

Saya menggunakan kode pengirim sebagai

char buffer[100000];
for (int i = 1; i < 100000; i++)
{
    int len = send (socket_id, buffer, i);
    printf("%d\n", len);
}

Kode penerima sebagai

while (len = recv (socket_id, buffer, 100000))
{
     printf("%d\n". len);
}

Saya mengamati bahwa send returns -1pada i > 65507dan recvmencetak atau menerima paket maximum of length 65507.

sysadmin1138
sumber

Jawaban:

11

Datagram UDP tidak ada hubungannya dengan ukuran MTU, Anda dapat membuatnya sebesar yang Anda inginkan hingga 64K, maksimum yang disebutkan di atas. Anda bahkan dapat mengirim salah satunya di seluruh paket selama Anda menggunakan bingkai jumbo dengan ukuran lebih besar dari datagram besar.

Namun frame jumbo harus didukung oleh semua peralatan yang akan dilewati frame dan ini menjadi masalah. Untuk tujuan praktis, frame Ethernet adalah ukuran tranport yang paling umum, MTU untuk ini adalah sekitar 1500 byte, saya akan mengatakan 1500 maju, tetapi tidak selalu. Ketika Anda membuat datagram UDP lebih besar dari MTU yang mendasarinya (yang seperti ditunjukkan paling sering berupa ethernet), maka ia akan diam-diam dipecah menjadi sejumlah frame 1500 byte. Jika Anda tcpdump traffic ini, Anda akan melihat sejumlah paket rusak pada batas MTU yang akan memiliki lebih banyak flag fragmen yang ditetapkan bersama dengan nomor fragmen. Paket pertama akan memiliki nomor fragmen 0 dan lebih banyak fragmen yang ditetapkan dan yang terakhir akan memiliki nomor fragmen non-nol dan lebih banyak fragmen tidak ditetapkan.

Jadi mengapa peduli? Detail implementasi sebenarnya penting. Fragmentasi dapat merusak kinerja dalam jaringan bukan masalah besar lagi tetapi harus diperhatikan. Jika ukuran datagram besar itu digunakan maka jika ada fragmen yang hilang, seluruh datagram perlu dikirim ulang. Sama-sama pada volume tinggi dan saat ini ini adalah volume yang dapat dicapai dengan sempurna, maka kesalahan hubungan frame pada pemasangan kembali dimungkinkan. Mungkin juga ada masalah mendapatkan paket UDP terfragmentasi untuk melintasi konfigurasi firewall perusahaan di mana penyeimbang beban menyebarkan paket keluar, jika satu fragmen berada di satu firewall dan yang lain pada yang berbeda maka lalu lintas akan turun karena tidak lengkap.

Jadi jangan membuat datagram UDP lebih besar dari ukuran fragmen MTU kecuali jika Anda harus dan jika Anda harus menentukan bahwa infrastruktur yang dikomunikasikan adalah dekat (subnet close yang sama) di mana titik jumbo frame kemungkinan akan menjadi pilihan yang baik.

Martyn A
sumber
Informasi bagus tentang 'lebih banyak bendera fragmen'. Apakah itu bendera di header UDP atau di header IP?
John Jesus
Catatan: Beberapa OS TIDAK akan mengirimkan UDP jika data akan terfragmentasi. IE Linux doc,By default, Linux UDP does path MTU (Maximum Transmission Unit) discovery. This means the kernel will keep track of the MTU to a specific target IP address and return EMSGSIZE when a UDP packet write exceeds it.
Rahly
2

Lapisan IP akan memecah-pecah paket Anda di ujung pengiriman, dan kemudian memasang kembali di sisi penerima, sebelum meneruskannya ke UDP. Dari lapisan UDP, Anda tidak dapat mengatakan bahwa paket tersebut telah terfragmentasi. Jika Anda menggunakan alat penangkap paket seperti Wireshark , Anda harus dapat melihat bahwa komputer Anda menerima paket IP yang terbatas pada MTU.

Jeff
sumber
1

Ternyata memungkinkan TCP / IP stack untuk memecah-mecah paket seperlunya jauh lebih rendah daripada mengirim paket individual.

geekosaurus
sumber
1
Apakah maksud Anda TCP / IP memecah-mecah dan menyusun kembali sendiri? Jika ya, lalu mengapa orang mengatakan sepanjang waktu bahwa kode Anda harus diurus kembali pada bagian penerima. Saya tidak mengamati fragmentasi seperti sekarang, tetapi telah melihat banyak forum yang mengatakan ini dan bahkan orang menerimanya.
Bagi kita yang model OSI tertantang, bisakah Anda menambahkan sedikit lebih detail untuk jawaban Anda?
Robert Harvey
Saya menjadi sedikit cerdik karena saya tidak tahu apakah ini pekerjaan rumah atau bukan. Ini adalah tradeoff: karena UDP tidak membuat jaminan pengiriman, jika ada fragmen paket yang dijatuhkan, seluruh paket akan hilang. Jika Anda ingin transportasi yang andal di atas UDP, Anda perlu menangani semua ini sendiri; tetapi jika Anda melakukan (katakanlah) protokol streaming (atau NFS lebih dari UDP, yang mengambil jalur seperti streaming) itu lebih rendah untuk menjatuhkan paket-paket itu atau mentransmisikan kembali paket yang lebih besar setelah penundaan agak lama jika diperlukan. Anda perlu menyeimbangkan kebutuhan Anda dengan fitur protokol dan overhead protokol.
geekosaur
1

UDP tidak tahu apa-apa tentang MTU. Paket UDP dapat memiliki ukuran dari 8 hingga 65535 byte. Lapisan protokol di bawah UDP dapat mengirim paket dengan ukuran tertentu atau akan menolak untuk mengirim paket dengan kesalahan jika terlalu besar.

Lapisan di bawah UDP biasanya IP, baik IPv4 atau IPv6. Dan paket IP dapat memiliki ukuran mulai dari 20 (IPv4) / 40 (IPv6) hingga 65535 byte, itu sama dengan maksimum UDP. Namun, IP mendukung mekanisme yang disebut fragmentasi . Jika sebuah paket IP berukuran lebih besar dari yang dapat diangkut oleh lapisan di bawah ini, IP dapat membagi satu paket menjadi beberapa paket yang disebut fragmen. Setiap fragmen sebenarnya adalah paket IP sendiri (memiliki header IP sendiri) dan juga dikirim sendiri ke tujuan; itu adalah tugas tujuan untuk mengumpulkan semua fragmen dan membangun kembali paket lengkap dari mereka sebelum meneruskan data yang diterima pada lapisan berikutnya yang lebih tinggi (misalnya UDP).

Protokol Ethernet hanya dapat mengangkut frame dengan muatan antara 46 dan 1500 byte (ada pengecualian tapi itu di luar cakupan balasan ini). Jika data payload kurang dari 46 byte, itu padded untuk menjadi 46 byte. Jika data payload melebihi 1500 byte, antarmuka akan menolak untuk menerimanya. Jika itu terjadi, itu tergantung pada lapisan IP untuk sekarang memutuskan untuk memecah-mecah paket, sehingga tidak ada fragmen yang lebih besar dari 1500 byte atau melaporkan kesalahan ke lapisan yang lebih tinggi berikutnya jika fragmentasi telah dinonaktifkan atau dilarang untuk koneksi khusus ini.

Fragmentasi umumnya harus dihindari, seperti

  • adalah pemborosan sumber daya di sisi pengirim.
  • itu membuang sumber daya di sisi penerima.
  • ini meningkatkan overhead protokol untuk jumlah data payload yang sama.
  • jika satu fragmen hilang, seluruh paket hilang.
  • jika satu fragmen rusak, seluruh paket rusak.
  • dalam hal pengiriman ulang, semua fragmen harus dikirim ulang.

Itu sebabnya TCP secara cerdas mengadopsi ukuran frame-nya sehingga paket-paket tidak pernah memerlukan IP untuk memecah-mecahnya. Ini dapat dilakukan dengan melarang IP ke paket fragmen dan jika IP melaporkan bahwa paket terlalu besar untuk dikirim, TCP mengurangi ukuran frame dan mencoba lagi, sampai tidak ada kesalahan yang dilaporkan lagi.

Namun, untuk UDP, ini akan menjadi tugas aplikasi itu sendiri, karena UDP adalah protokol "bodoh", itu tidak memiliki logika manajemen sendiri, yang membuatnya sangat fleksibel, cepat, dan sederhana.

Satu-satunya ukuran UDP yang dapat Anda andalkan untuk selalu dapat dipindahkan adalah 576 minus 8 byte Header UDP dan minus 20 (v4) / 40 (v6) byte header IP, karena standar IP mengharuskan setiap host IP untuk dapat menerima paket IP dengan ukuran total 576 byte. Implementasi protokol Anda tidak akan sesuai standar jika tidak dapat menerima paket dengan ukuran setidaknya itu. Perhatikan, bagaimanapun, bahwa standar tidak mengatakan 576 tanpa fragmentasi, sehingga bahkan paket IP 576 byte dapat terfragmentasi antara dua host.

Satu-satunya ukuran paket yang dapat Anda andalkan untuk diangkut tanpa fragmentasi adalah 24 byte untuk IPv4 dan 56 byte IPv6, karena header IP terkecil untuk sebuah fragmen adalah 20/48 byte (v4 / v6) dan sebuah fragmen harus memiliki setidaknya 4/8 data payload byte (v4 / v6). Jadi sistem transportasi di bawah lapisan IP yang tidak dapat mengangkut setidaknya paket ukuran tesis, tidak dapat digunakan untuk mengangkut lalu lintas IP.

Dan sebelum ada yang berkomentar bahwa header IPv6 hanya memiliki 40 byte: Itu benar tetapi, tidak seperti header IPv4, header IPv6 standar tidak memiliki bidang header untuk fragmentasi. Jika sebuah paket harus difragmentasi, maka header ekstensi fragmentasi harus ditambahkan di bawah header dasar IPv6 dan header ekstensi ini panjangnya 8 byte. Juga tidak seperti IPv4, offset fragmentasi dalam IPv6 dihitung dalam 8 byte dan bukan 4 byte, sehingga sebuah fragmen hanya dapat membawa muatan yang merupakan kelipatan 8 byte dalam kasus IPv6.

Mecki
sumber
0

Untuk menjawab pertanyaan Anda, "Jika ukuran payload frame itu sendiri maksimum 1472 bytes (sesuai buku teks saya), bagaimana ukuran paket IP lebih besar dari yang di sini adalah 65535?"

Ini karena fitur pembongkaran yang disebut UFO. (UDP Fragmentation Offload). Silakan merujuk ke tautan ini .

Anda dapat memverifikasi dan mengaktifkan fitur pembongkaran via ethtool -k ethX dan ethtool -K ethX.

Nehal Dattani
sumber
0

Jika Anda memantau frame keluar, ada kemungkinan adaptor jaringan Anda mendukung pembongkaran segmentasi, dan itu diaktifkan. Dengan segmentasi offloading diaktifkan, kartu jaringan itu sendiri menangani segmentasi paket / frame ke ukuran yang sesuai, daripada tumpukan jaringan. Ini membebaskan CPU di komputer untuk melakukan tugas-tugas lain, meningkatkan kinerja. Di linux, "ethtool -k [perangkat]" akan menampilkan flag offload.

Andrew Bowers
sumber