Як MTU становить 65535 в UDP, але Ethernet не дозволяє розміру кадру більше 1500 байт


11

Я використовую швидку Ethernet мережею 100 Мбіт / с, розмір кадру менше 1500 байт (1472 байти для корисного навантаження відповідно до мого підручника). У цьому мені вдалося надіслати та отримати UDP-пакет з розміром 65507 байт, що означає розмір пакета 65507 + 20 (IP-заголовок) + 8 (UDP-заголовок) = 65535.

Якщо розмір корисної навантаження кадру становить максимум 1472 байти (відповідно до мого підручника), то як розмір пакета IP може бути більшим за розмір 65535?

Я використовував код відправника як

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

Код одержувача як

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

Я помітив, що send returns -1на i > 65507і recvроздруковує або отримує пакет maximum of length 65507.

Відповіді:


11

Даніграми UDP мають мало спільного з розміром MTU, ви можете зробити їх такими ж великими, як вам подобається, до 64K максимум, про який було сказано вище. Ви можете навіть надіслати один з них у цілому пакеті, доки не використовуєте джомбові кадри розміром, більшим за велику дейтаграму.

Однак рамки джамбо повинні підтримуватися всім обладнанням, через яке кадр буде переданий, і це проблема. Для практичних цілей кадри Ethernet - це найпоширеніший розмір транспорту, MTU для них - це близько 1500 байт, я скажу 1500, що йде вперед, але це не завжди. Коли ви створите дейтаграму UDP, що перевищує основний MTU (який, як зазначено, найчастіше є Ethernet), він буде непомітно розбитий на кількість 1500 байт кадрів. Якщо tcpdump цей трафік, ви побачите кількість пакетів, порушених на кордоні MTU, у яких буде встановлено більше прапорців фрагментів разом із номером фрагмента. Перший пакет матиме число фрагментів 0 і більше набір фрагментів, а останній матиме ненульове число фрагмента, а більше фрагментів не встановлено.

То чому піклуватися? Детальна інформація про реально важливе значення Фрагментація може зашкодити продуктивності в мережі вже не велика проблема, але вона повинна бути обізнана. Якщо величезний розмір дейтаграми, який він використав, тоді, якщо будь-який фрагмент буде втрачено, цілі дейтаграми потрібно буде повторити. Так само при великих обсягах і сьогодні це цілком досяжні обсяги, тоді можлива неправильна асоціація кадрів при повторній збірці. Також можуть виникнути проблеми з отриманням фрагментованих пакетів UDP для проходження конфігурацій корпоративного брандмауера, де балансири навантажень поширюють пакети, якщо один фрагмент знаходиться на одному брандмауері, а інший - на іншому, то трафік втрачається як неповний.

Тому не створюйте дейтаграми UDP, що перевищують фрагментацію розміру MTU, якщо вам не доведеться, і якщо вам потрібно вказати, що інфраструктура, що передається між ними, близька (одна і та ж підмережа закрита), в якій точці перемикання кадрів, ймовірно, буде хорошим варіантом.


Хороша інформація про "прапор більше фрагментів". Це прапор у заголовку UDP або в заголовку IP?
Іван Ісус

Примітка: Деякі ОС НЕ передають UDP, якщо дані будуть фрагментовані. 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.
Ралі,

2

IP-шар буде фрагментувати ваш пакет на кінці відправки, а потім знову зібрати його на кінці прийому, перш ніж передавати його до UDP. Із шару UDP ви не можете дійсно сказати, що пакет роздроблений. Якщо ви використовуєте інструмент захоплення пакетів, наприклад Wireshark , ви повинні бачити, що ваш комп'ютер отримує IP-пакети, обмежені MTU.


1

Виявляється, що дозволити TCP / IP стеку фрагментувати пакети за потребою набагато нижче, ніж надсилання окремих пакетів.


1
Ви маєте на увазі, що TCP / IP фрагментує та перекомпонує? Якщо так, то чому люди весь час говорять про те, що ваш код повинен піклуватися про його збірку на кінці приймача. Я не спостерігав фрагментації, як зараз, але бачив багато форумів, які говорять про це, і навіть люди приймають це.

Для тих із нас, хто ставить під сумнів модель OSI, ви можете додати трохи детальніше до своєї відповіді?
Роберт Харві

Я був трохи кегей, бо не можу сказати, чи це домашнє завдання чи ні. Це компроміс: оскільки UDP не надає гарантій доставки, якщо будь-який фрагмент пакету буде скинутий, весь пакет втрачається. Якщо ви хочете отримати надійний транспорт на вершині UDP, вам потрібно впоратися з усім цим самостійно; але якщо ви робите (скажімо) протоколи потокового потоку (або NFS через UDP, який пройшов потокоподібну траєкторію), нижчі накладні витрати або просто відкинути ці пакети, або повторно передати більший пакет після тривалої затримки, якщо потрібно. Потрібно збалансувати свої потреби в порівнянні з функціями протоколу та накладними витратами на протокол.
geekosaur

1

UDP нічого не знає про MTU. Пакети UDP можуть мати будь-який розмір від 8 до 65535 байт. Рівні протоколів нижче UDP або можуть надсилати пакет певного розміру, або відмовлятимуть надсилати цей пакет з помилкою, якщо він занадто великий.

Шаром нижче UDP зазвичай є IP, або IPv4, або IPv6. І IP-пакет може мати будь-який розмір від 20 (IPv4) / 40 (IPv6) до 65535 байт, це той самий максимум, що і UDP. Однак IP підтримує механізм, який називається фрагментація . Якщо IP-пакет має більші розміри, ніж те, що може перенести шар нижче, IP може розділити один пакет на кілька пакетів, званих фрагментами. Кожен фрагмент насправді є власним пакетом IP (має власний IP-заголовок), а також самостійно надсилається до місця призначення; Тоді завдання призначення зібрати всі фрагменти і відновити повний пакет з них перед передачею отриманих даних на наступний більш високий рівень (наприклад, UDP).

Протокол Ethernet може транспортувати лише кадри з корисним навантаженням між 46 і 1500 байтами (є винятки, але це виходить за межі цієї відповіді). Якщо дані про корисне навантаження менше 46 байт, вони додані до 46 байт. Якщо дані корисної навантаження перевищують 1500 байт, інтерфейс відмовиться приймати їх. Якщо це трапиться, зараз вирішуватиметься будь-який фрагмент пакету, щоб жоден фрагмент не перевищував 1500 байт або повідомляв про помилку на наступному більш високому шарі, якщо фрагментація була вимкнена або заборонена для цього конкретного з'єднання.

Фрагментації, як правило, слід уникати, як

  • - це відходи ресурсів на стороні відправника.
  • він витрачає ресурси на стороні приймача.
  • це збільшує накладні витрати протоколу на стільки ж даних корисного навантаження.
  • якщо один фрагмент втрачено, втрачається весь пакет.
  • якщо один фрагмент пошкоджений, весь пакет зіпсований.
  • у разі повторного надсилання всі фрагменти повинні бути відреаговані.

Ось чому TCP інтелектуально приймає розмір кадру, щоб пакети ніколи не потребували IP для їх фрагментації. Це можна зробити, заборонивши IP для фрагментації пакетів, і якщо IP повідомляє, що пакет занадто великий, щоб його надсилати, TCP зменшує розмір кадру та намагається повторити, поки більше не повідомляється про помилку.

Для UDP, однак, це було б завданням самої програми, оскільки UDP - це "німий" протокол, він не має власної логіки управління, що робить його дуже гнучким, швидким та простим.

Єдиний розмір UDP, на який можна розраховувати, щоб він завжди передавався, це 576 мінус 8 байт заголовка UDP і мінус 20 (v4) / 40 (v6) байт IP-заголовка, оскільки стандарт IP вимагає, щоб кожен IP-хост міг отримувати IP-пакети з загальний розмір 576 байт. Ваша реалізація протоколу не була б стандартною відповідності, якщо вона не може приймати пакети принаймні такого розміру. Однак зауважте, що стандарт не каже 576 без фрагментації, тому навіть IP-пакет 576 байт може роздроблено між двома хостами.

Єдиний розмір пакета, на який ви можете розраховувати, що він може бути переносним без фрагментації, - це 24 байти для IPv4 і 56 байт IPv6, оскільки найменші заголовки IP для фрагмента - 20/48 байт (v4 / v6), а фрагмент повинен мати не менше 4/8 дані про корисне навантаження в байтах (v4 / v6). Таким чином, транспортна система нижче рівня IP, яка не може транспортувати принаймні пакети розмірів тез, не може використовуватися для транспортування IP-трафіку.

І перш ніж хтось коментує, що заголовок IPv6 містить лише 40 байт: Це правильно, але, на відміну від заголовка IPv4, стандартний заголовок IPv6 не має заголовкових полів для фрагментації. Якщо пакет має бути фрагментований, то слід заголовку розширення фрагментації додати нижче базового заголовка IPv6, а цей заголовок розширення становить 8 байт. Також, на відміну від IPv4, зсуви фрагментації в IPv6 рахуються в 8 байтах, а не в 4 байтових одиницях, таким чином, фрагмент може нести корисне навантаження, кратне 8 байтам у випадку IPv6.


0

Щоб відповісти на ваше запитання, "Якщо розмір корисної навантаження кадру становить максимум 1472 байти (відповідно до мого підручника), то як розмір пакета IP може бути більшим, ніж розмір 65535?"

Це пов'язано з функцією розвантаження під назвою UFO. (UDP Fragmentation Offload). Перейдіть за цим посиланням.

Ви можете перевірити та переключити функції розвантаження через ethtool -k ethX та ethtool -K ethX відповідно.


0

Якщо ви контролюєте вихідні кадри, можливо, ваш мережевий адаптер підтримує вивантаження сегментації, і це ввімкнено. Якщо ввімкнено вивантаження сегментації, мережева карта сама обробляє сегментацію пакета / кадру на відповідний розмір, а не мережевий стек. Це звільняє процесор у комп’ютері для виконання інших завдань, покращуючи продуктивність. У Linux "ethtool -k [device]" відображатиме прапори вивантаження.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.