Почему нельзя применять мышление TCP к UDP

  • Почему нельзя применять мышление TCP к UDP

Почему нельзя применять мышление TCP к UDP?

Структурные различия

Заголовок TCP
Заголовок UDP

В TCP существует множество концепций: установление соединения, использование ресурсов, передача данных, надежная передача, повторная передача на основе кумулятивных подтверждений, повторная передача по тайм-ауту, контрольная сумма, управление потоком, управление перегрузкой, максимальный размер сегмента, выборочные подтверждения, опция масштабирования окна TCP, временные метки TCP, принудительная доставка данных, завершение соединения.

UDP практически не обладает ни одной из вышеперечисленных возможностей; он лишь немного превосходит канальный уровень по части возможности различать назначение на прикладном уровне. Достаточная простота UDP означает достаточную гибкость.

Если это может произойти, то это обязательно произойдет

Закон Мерфи:

Если существует более одного способа сделать что-либо, и один из них ведет к катастрофе, то кто-нибудь обязательно выберет именно этот способ.

Обычно говорят, что UDP подходит для сценариев, таких как игры/голос/видео, где небольшое количество потерянных пакетов не влияет на работу бизнеса. Почему UDP подходит для этих сценариев? Тот факт, что он может использоваться в них, не означает, что он является оптимальным решением. Безусловно, существуют проблемы, которые TCP не может решить, из-за чего эти сервисы выбирают простой по функционалу протокол UDP. Утверждение о том, что потерянные пакеты не влияют на бизнес, если расширить его, означает, что протокол TCP беспокоится о потерянных пакетах, а UDP — нет; UDP больше заботит реальное время/непрерывность. Особенность UDP в том, что ему не важны те факторы, которые важны для TCP, и именно эти факторы влияют на реальное время.

В плане реализации кода UDP требует только создания сокета и привязки к порту, после чего можно начинать прием и передачу. Обычно, когда сокет отработан, порт также освобождается.

Таким образом, я могу использовать UDP следующим образом:

  1. Отправлять случайные пакеты на любые порты любых IP-адресов, чтобы увидеть, на каком порту будет ответ.
  2. А отправляет пакет запроса со своего порта A на порт B Б; Б отправляет пакет ответа со своего порта C на порт D А.
  3. А отправляет пакет запроса со своего порта A на порт B Б; Б поручает В отправить пакет ответа со своего порта C на порт D А.
  4. А отправляет пакет запроса со своего порта A на порт B Б, но изменяет исходный IP пакета на IP В; Б отправит пакет ответа В.
  5. Стороны договариваются использовать по 10 UDP-портов каждая для одновременного приема и отправки.

Эти методы, конечно, не сработают в TCP, но в протоколе UDP, если это можно сделать, то кто-то обязательно это сделает. Поэтому накладывание некоторых принципов мышления TCP на UDP — это идеализм; реальная ситуация часто не может быть полностью перечислена нами.

Пакеты UDP очень просты, их использование очень гибко; изначально нет понятия “соединение”, нужно определять UDP-соединение самостоятельно. Попробовав несколько методов определения, нельзя полностью точно достичь оценки намерения направления соединения. В этот момент нужно принять некоторую устойчивость к ошибкам; ведь изначально не существует определения UDP-соединения, и когда у сторон определения UDP-соединения не совпадают, это неизбежно приведет к тому, что поведение будет отличаться от ожидаемого.

UDP с точки зрения клиента

Такие службы, как голос/видео, часто испытывают потерю пакетов, но разные способы потери пакетов оказывают разное влияние на работу бизнеса. Например, если потеря 30% пакетов происходит равномерно или все пакеты теряются в определенный период времени, это оказывает заметно разное влияние на восприятие пользователем. Очевидно, мы надеемся на более равномерную потерю пакетов. Но в UDP нет методов предотвращения потери пакетов с помощью управления потоком, однако существуют методы управления тем, как происходят потери. Хотя коммуникация по UDP часто описывается как “best effort” (尽力而为), разные способы “усердия” приводят к разным результатам.

UDP с точки зрения поставщика услуг

В случае TCP-атаки клиенту требуются определенные затраты на создание соединения и его поддержание; то есть злоумышленнику приходится платить определенную цену. А при UDP-атаке цена, которую платит злоумышленник, намного меньше. Если цель злоумышленника — израсходовать пропускную способность сервиса, UDP — отличный способ. Например, сервис купил 100 ГБ неограниченного трафика, его производительность только 10 МБ в секунду, но скорость приема 1 ГБ в секунду, тогда 90% трафика запросов бесполезно, но этот трафик не бесплатен. Сервис должен избегать возникновения такой ситуации.

UDP с точки зрения оператора связи

Для завершения одной коммуникации требуется несколько терминалов и коммуникационных каналов. Внимание всегда приковано к серверу и клиенту, но на самом деле перспективы оператора связи также важны. При DDoS-атаках мы часто заботимся о потреблении ресурсов на стороне сервера, но на самом деле ресурсы оператора связи также ограничены. Сервер просто не отвечает на запросы, но прием трафика уже потребил пропускную способность, только этот ресурс обычно принадлежит оператору связи. В стресс-тестировании мы часто используем показатель “коэффициент потери пакетов”; этот показатель выражает потерю пакетов во всей цепочке коммуникации, а не только на стороне сервера. Оператор связи тоже теряет пакеты. С точки зрения оператора, сервис купил только 1 МБ/с пропускной способности, но клиент отправляет со скоростью 1 ГБ/с; ни одной из сторон не нужно платить за потраченный трафик, именно оператор несет эту цену полосы пропускания. Поэтому оператор обязательно найдет способ заблокировать такой трафик, то есть QoS для UDP. В TCP есть управление перегрузкой, но в UDP оператор может контролировать трафик с помощью потери пакетов. В реальной ситуации операторы действуют еще более просто и грубо, напрямую блокируя трафик портов, используемых в течение долгого времени, то есть блокировку UDP-портов. В реальных тестах звонков WeChat было обнаружено, что за каждый звонок клиент использует несколько портов, и один UDP-порт будет общаться с шестью UDP-портами одного и того же сервера; предполагается, что это сделано именно для противодействия блокировке портов оператором.

Заключение

Гибкость UDP выражается в том, что при достижении одной цели у него есть множество способов реализации, и все они легальны. Пока в итоге может быть реализована стабильная коммуникация, независимо от того, насколько реализация отличается от TCP, это “существует, значит разумно”. Следовательно, мы не можем полностью накладывать концепции TCP на UDP. Даже если для проектирования продукта создано новое определение UDP-соединения, следует ожидать и допускать наличие ошибок. Ведь “допущение ошибок” — это основная функция UDP; это преимущество UDP, а не его недостаток, это ключевая способность протокола, выбранная сервисом добровольно, а не вынужденно принимаемый недостаток.

Дополнительное чтение