Понимание протокола UDP
Практически все уже знакомы с TCP как с транспортным протоколом. Не так много, однако, так хорошо разбираются в UDP, как в транспортном протоколе. Это по уважительной причине. Почти каждый фрагмент данных, будь то приложение, сеанс или другой уровень, передается через надежный старый TCP. Это напоминает мне еще одну вещь, которую я довольно часто слышу от людей: «Да, вы знаете, TCP гарантированно туда попадет». Это утверждение, на самом деле, совершенно неверно.
TCP или протокол управления передачей ориентированы только на соединение. Однако UDP или протокол пользовательских дейтаграмм не требуют установления соединения. Что это означает? Что ж, если вы читали мои статьи о TCP, то заметили, что в заголовок TCP включено очень много метрик. Те же самые показатели, например: порядковый номер TCP, номер подтверждения, делают его ориентированным на соединение. Наконец, стандартная длина заголовка TCP составляет двадцать байтов, а для UDP — восемь.
Чем отличается UDP?
Точнее, наш протокол UDP имеет длину всего восемь байтов. Это на двенадцать байт меньше, чем TCP. Из-за этого UDP намного быстрее, так как нужно передать меньше. Дополнительные двенадцать байт могут показаться не такими уж большими, но умножьте их на тысячи пакетов, и вы быстро заметите разницу в своей сети. Вы спросите, если посмотреть, что заголовок UDP намного меньше, как именно он выглядит? Хороший вопрос! Ниже приведена схема того, как выглядит заголовок UDP.
_____________________________________________________
Двухбайтовый номер исходного порта | Двухбайтовый номер порта назначения
_____________________________________________________
Длина двухбайтового пакета UDP | Два байта контрольной суммы UDP
_____________________________________________________
Данные, если есть
Таким образом, из вышеизложенного мы можем видеть, что отсутствие дополнительных двенадцати байтов служебной информации в заголовке UDP действительно имеет существенное значение. Это могло бы объяснить отсутствие «ориентированности на соединение» для UDP. Вы можете заметить, что у нас также есть контрольная сумма в заголовке для UDP. Я хотел бы воспользоваться этим временем, чтобы указать, что все четыре основных протокола; IP, TCP, UDP, ICMP имеют контрольные суммы. Во всех четырех основных протоколах контрольная сумма будет охватывать заголовок протокола и любые данные, если они есть. Одна из последних вещей, которые я хотел бы упомянуть о UDP и его контрольной сумме, это то, что его использование не является обязательным. По сути, его не нужно использовать, тогда как в TCP, ICMP и IP он нужен.
Это гарантировано? Черт возьми нет!
Что ж, теперь, зная, что UDP на самом деле не предлагает никаких гарантий доставки, не говоря уже о каких-либо встроенных метриках для него, зачем вам его использовать? Имея это в виду, разработчик, он же программист, обычно решает, какой транспортный протокол он хочет использовать при разработке нового приложения или протокола другого уровня. Вполне могут быть случаи, когда учитываются скорость и размер пакета. Если эти факторы будут учитываться разработчиком, то есть вероятность, что он выберет UDP в качестве своего транспортного протокола.
Хмммм, все это хорошо и здорово, но действительно ли какой-либо прикладной уровень или другие протоколы используют UDP? Отличный вопрос, и ответ - да. Существует довольно много приложений, использующих UDP для транспорта. Одним из самых известных для большинства является DNS или система доменных имен. Подавляющая часть трафика, генерируемого DNS, на самом деле передается с использованием UDP. Кстати, DNS — это один из тех протоколов, которые фактически используют как UDP, так и DNS. При этом большая часть активности DNS на самом деле представляет собой DNS-запросы и ответы. Они, как только что упоминалось, передаются через UDP.
Увидим ли мы когда-нибудь UDP-пакет!
Хорошо видно, как я чувствую ваше желание проникнуть в внутренности UDP, как насчет того, чтобы мы посмотрели на пакет UDP и прошлись по различным полям, описанным выше на моей эффектной диаграмме.
02:00:04.079943 192.168.1.100.53 > 192.168.1.200.57746: [udp sum ok] 60865 FormErr% [0q] 0/0/0 (12) (DF) (ttl 253, id 9987, len 40)
0x0000 4500 0028 2703 4000 fd11 619a c0a8 0164 E..('[email protected]…a…..
0x0010 c0a8 01c8 0035 e192 0014 ba83 edc1 8091 …..5……….
0x0020 0000 0000 0000 0000 0000 0000 0000 …………..
Теперь, если вы читали все мои статьи, вы поймете, что есть отличный ресурс для просмотра пакетов. Если у вас его нет, перейдите сюда и загрузите проспект TCP/IP и tcpdump. Он находится в разделе «Дополнительные ресурсы». Имея этот документ на руках, мы теперь готовы перемещаться по содержимому пакетов байт за байтом.
Один из способов быстро сориентироваться в пакете — перейти к адресу назначения в заголовке IP. Он находится в строке 0x0010 и представляет собой следующие четыре байта информации; c0a8 01c8. Мы знаем, что если в нашем IP-заголовке нет параметров, то протокол, следующий за IP-заголовком (в данном случае UDP), о чем свидетельствует 11 в шестнадцатеричном формате. Число 11 видно в первой строке 0x00 и в следующем «fd11». Использование некоторых метрик заголовка IP позволит вам быстро сориентироваться, где начинается следующий протокол.
Таким образом, первый байт нашего UDP-заголовка находится по адресу 0035 в строке 0x0010. В загруженной нами шпаргалке по TCP/IP указано, что первые два байта заголовка UDP относятся к исходному порту. Что ж, если мы преобразуем наше шестнадцатеричное значение 0035, мы увидим, что оно действительно соответствует исходному порту, указанному выше в пакете, то есть порту 53.
Все идет нормально? Теперь после исходного порта следующие два байта предназначены для порта назначения, о чем свидетельствуют шестнадцатеричные значения e192 или, как мне следует представить для ясности, 0xe192. Как только мы преобразуем его в десятичное число, мы увидим, что он действительно соответствует порту назначения в пакете, вставленном выше.
Отлично, мы хорошо продвигаемся по заголовку UDP! Далее следует длина пакета UDP, представленная шестнадцатеричным значением 0x0014, которое преобразуется в 20 в десятичном виде. Так и должно быть. Далее идет значение контрольной суммы UDP, и ему назначается два байта, как и всем предыдущим метрикам, которые мы видели до сих пор, то есть: номер исходного порта, номер порта назначения и длина пакета UDP. Значение контрольной суммы в этом случае равно 0xba83. На самом деле мы не видим это значение в заголовке пакета, но так оно и должно быть. Просто имейте в виду, что это то место, где его можно найти.
Что ж, теперь видно, что это конец заголовка UDP, следующий сразу после него, где будут данные прикладного уровня. В данном случае это будет информация DNS. В протоколе UDP есть гораздо больше, чем только это, но я бы посоветовал вам продолжить чтение с вашей стороны, чтобы улучшить свои знания об этом недооцененном протоколе. Как всегда, я искренне надеюсь, что это было полезно для вас, и я всегда рад комментариям.