Надежный UDP - PullRequest
       23

Надежный UDP

3 голосов
/ 13 апреля 2009

Как я могу разработать модуль ядра Linux, чтобы сделать UDP надежным? Это мое задание в колледже, и я не знаю, как поступить. Как изменить поведение UDP по умолчанию в ядре Linux, загрузив новый модуль ядра? а как программировать такой модуль ядра?

Ответы [ 15 ]

15 голосов
/ 13 апреля 2009

Надежный UDP не то же самое, что просто использование TCP. Есть ряд отличий, но наиболее распространенным является то, что вы гарантированно всегда получаете полное UDP-сообщение или не получаете его вообще. Принимая во внимание, что не только возможно, но и очень распространено получать частичные сообщения TCP.

Так как это всего лишь домашнее задание, я бы предложил просто реализовать одно отправленное сообщение, дождаться подтверждения, отправить следующую процедуру сообщения с тайм-аутом. Если истекло время ожидания, повторите отправку сообщения несколько раз, прежде чем объявить ошибку. Да, это будет медленнее, чем необходимо. Существует множество методов для повышения пропускной способности, но для вашего назначения есть вероятность, что вам не нужно их использовать.

10 голосов
/ 13 апреля 2009

На самом деле - это надежный UDP, он называется RUDP , и он был изобретен для Plan 9. Однако на самом деле в этом нет никакого смысла, просто используйте TCP.

Редактировать: Также, UDT может быть полезным. Он основан на UDP, но надежен.

5 голосов
/ 31 марта 2010

Те, кто постоянно говорит беднягу «просто использовать TCP», игнорируют, что есть веские причины, по которым надёжная реализация UDP будет использоваться поверх TCP - и это не семантика дейтаграмм (которую очень просто поместить поверх TCP)

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

Это часто используется для широковещательной передачи данных, обмена данными внутри кластерной системы и т. Д.

3 голосов
/ 14 апреля 2009

Я думаю, вопрос о том, как сделать UDP надежным, может быть неправильным. UDP ненадежен более или менее по определению - ipso facto. Вы не добьетесь успеха, делая реализацию протокола на стороне ОС более «надежной».

Очень многие приложения, использующие UDP, используют его, потому что им нужна природа с малыми издержками и низкой задержкой гораздо больше, чем точная надежность TCP. Но почти все эти приложения все еще нуждаются в некотором механизме для проверки сквозного приема определенных типов сообщений и, возможно, даже повторной сборки и / или первоначального рукопожатия. Подумайте о SIP в VoIP телефонии, например; Латентное трехстороннее рукопожатие TCP и очень постепенный контроль перегрузки не совсем приемлемы для приличного времени установления вызова или QoS, но определенно необходим некоторый способ подтверждения сообщений (для этого и нужны предварительные ответы, в терминологии SIP). Или различные протоколы, используемые в онлайн-играх - одна и та же основная идея.

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

3 голосов
/ 13 апреля 2009

Методы для надежной передачи данных все вместе известны как «ARQ», что означает «Автоматический запрос повторения».

Это слишком многословный предмет, чтобы объяснять здесь, но страницы википедии - хорошее место для начала, но немного больше, чем это. Я рекомендую вам взять один из учебников по компьютерным сетям (например, Таненбаум или Куросе / Росс) и идти оттуда. Если вы считаете, что этого достаточно для вашего задания, внедрите базовый ARQ «останови и жди» и забудь о более продвинутых схемах ARQ, они требуют много дополнительных работ.

У меня нет опыта разработки модулей ядра Linux, но если вы выберете одну из более продвинутых схем ARQ, я не удивлюсь, если реализация механизма ARQ окажется более трудоемкой, чем упаковка в качестве модуля ядра .

Удачи с заданием.

3 голосов
/ 13 апреля 2009

Я часто использую UDP, и главная проблема «надежности», которую я в конечном итоге вижу, это потерянные пакеты (особенно в фрагментированных IP-пакетах). Вероятно, вы могли бы сделать 90% того, что нужно сделать, не допуская фрагментации (добавив слой, который разбивает дейтаграммы на куски размера IP), и обнаружив рецепт и запросив повторную отправку утерянных «кусков».

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

Существует сетевое топологическое решение. Просто расположите все так, чтобы не было никаких коллизий (источник потерянных пакетов # 1 в локальной сети). Вот что мы делаем, где я работаю, чтобы сделать UDP надежным:

  • Поместите один клиент и сервер в выделенный канал Ethernet (возможно, коммутатор между ними, но не в других системах в их частной локальной сети).
  • Поддерживать строгий протокол обмена данными между клиентом и сервером в локальной сети UDP. Серверу никогда не разрешается говорить, кроме как в ответ клиенту.
  • Отключите весь посторонний сетевой мусор в этом соединении UDP (Netbios и т. Д.).
  • Сделать записи ARP на обоих концах статичными (чтобы ARP не вмешивался раз в 10 минут).

(Примечание: последний особенно важен. Во многих системах IP-пакеты, которые вызывают запрос ARP, просто выбрасываются, а не отправляются после разрешения ARP).

3 голосов
/ 13 апреля 2009

Наложение TCP поверх UDP, как это уже делает TCP. «Надежный UDP» - оксюморон. Он не предназначен, чтобы быть таким.

2 голосов
/ 13 апреля 2009

Если вам абсолютно необходим протокол транспортного уровня, основанный на сообщениях, где вы можете отключить некоторые функции надежности TCP, такие как блокировка заголовка, проверьте SCTP . У API даже есть « режим UDP », который маскирует базовые соединения.

Это все еще в стадии разработки, поэтому вы не можете ожидать, что пользователи получат его, но если вам это нужно только для компьютеров, которые вы обслуживаете, все должно быть в порядке. Он реализован в различных вариантах Unix , хотя FreeBSD - это то место, где происходит большая часть разработки. YMMV.

1 голос
/ 14 апреля 2009

Если честно, мне интересно, если это вопрос с подвохом. Для связи требуется две стороны, и абсолютно ничего, что вы делаете, не может гарантировать, что отправитель знает (или заботится) о том, что вы хотите, чтобы он повторно отправил пакет, если вы уже не установили протокол для передачи этого желания. Если сам UDP может сделать это, я сильно подозреваю, что ядро ​​его уже поддерживает.

То, что у вас осталось, это определение и реализация модуля, который реализует новый протокол. В этом нет ничего плохого, другие уже дали вам предложения, и я уверен, что вы можете использовать реализацию UDP для обработки фактической передачи пакетов. Но просто помните, что это реализация нового протокола, а не просто скручивание UDP, чтобы получить новые функциональные возможности.

1 голос
/ 14 апреля 2009

Я не уверен, что существует простой способ изменить поведение существующего кода UDP через новый модуль.

Что было бы проще - это взять код UDP (net / ipv4 / udp.c) и создать новый модуль с новым номером протокола IP, а также изменить этот код для реализации вашего надежного протокола UDP. Вам нужно будет переименовать все внешние символы, чтобы имена не конфликтовали с существующими символами, выяснить, где он регистрирует номер протокола (17) и изменить его, а затем обновить Makefile, чтобы создать новый модуль и, возможно, поместить запись в Kconfig.

Загляните в / etc / protocol, чтобы узнать, какие идентификаторы протокола уже выделены.

Edit: похоже, что udp.c не может быть собран как модуль. Вам нужно будет взглянуть на некоторые другие протоколы (например, ipip.c или ip_gre.c), чтобы узнать, как превратить ваш код в модуль.

...