2013-08-27 1 views
1

Примечания: Я не спрашиваю, как использовать многоадресную рассылку или трансляцию для всей сессии, только для рукопожатияTCP с использованием многоадресной рассылки для инициализации только

мне было интересно ли идея у меня был может быть реализована в программе Linux без каких-либо изменений в ядре. Или, если действительно необходимо изменить ядро, я хотел бы знать, какие файлы нужно отредактировать.

Основная идея: «клиент» отправляет пакет TCP SYN на широковещательный или многоадресный адрес, затем вызывает accept() или эквивалент, чтобы открыть отдельный файловый дескриптор для каждого SYN-ACK, который он возвращает.

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

+1

Многоадресная рассылка не может использоваться с TCP. – Barmar

+0

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

+1

Адреса многоадресной рассылки с TCP не разрешены, это спецификация Интернета. – Barmar

ответ

2

Multicast TCP несовместим со спецификацией TCP. RFC 1122 section 4.2.3.10 говорит:

A TCP implementation MUST reject as an error a local OPEN call for an invalid remote IP address (e.g., a broadcast or multicast address).

An incoming SYN with an invalid source address must be ignored either by TCP or by the IP layer (see Section 3.2.1.3).

A TCP implementation MUST silently discard an incoming SYN segment that is addressed to a broadcast or multicast address.

Основная проблема заключается в том, что адрес источника ответа SYN-ACK должен совпадать с адресом получателя исходного пакета SYN - это то, как ответы совпадают с первоначальным запросом подключения (в дополнение к сопоставлению адреса назначения с исходным адресом источника и номерам портов). Но чтобы переключиться на одноадресную рассылку после рукопожатия, вам нужно знать реальный адрес сервера.

Вы могли бы, я полагаю, улучшить протокол, чтобы добавить параметр TCP, который содержит этот адрес. Или вы можете сказать, что когда SYN отправляется в группу многоадресной рассылки, исходный адрес ответа игнорируется при сопоставлении - это будет означать, что только номера портов однозначно определяют запрос группового соединения. Если вы заинтересованы в этом, возможно, вам стоит написать спецификацию для него и предложить его IETF в качестве расширения протокола.

Но уже существуют протоколы, используемые для поиска серверов в сети, таких как Bonjour. Серверы также могут быть указаны в DNS или Active Directory. Ваша идея не звучит так, как будто она выполняет все, что еще не доступно.

0

Сделать TCP несколькими клиентами - нетривиальная задача! Вот некоторые из причин. Во-первых, если есть несколько приемников, то как вы отслеживаете, какую скорость передачи использовать для кого. Во-вторых, если несколько приемников пропускают набор пакетов, как вы повторно передаете эти пакеты. В-третьих, если ресиверы рекламируют данный буфер приемника (aka flow-control), который вы выбираете, выбираете ли вы самый маленький буфер, который рекламируете, и пусть другие страдают ИЛИ вы выбираете среднее значение, и пусть пострадают только некоторые из получателей. Наконец, TCP ориентирован на соединение, поэтому даже если вы взломаете ядро ​​для этого, обычные вызовы сокетов, такие как send()/recv(), не будут знать, от какого клиента отправлять или получать. Вы можете попробовать использовать sendto()/recvfrom(), но на сегодняшний день ядро ​​обычно игнорирует адреса в этих вызовах.

Вы могли бы быть лучше строить на прикладном уровне наложения поверх TCP

+0

Попробуйте прочитать фактический вопрос: я специально упомянул о наличии отдельного подключения для каждого полученного пакета SYN + ACK –

+0

Я стою исправлен - спасибо! Я, вероятно, пошатнулся некоторыми ответами! Как уже отмечалось, реализация TCP в ядре не позволит вам передавать многоадресный адрес для вызова connect(). Таким образом, вам наверняка придется изменить ядро. Вы можете просматривать файлы TCP здесь: http://lxr.free-electrons.com/source/net/ipv4/. –

+0

Btw, я быстро закодировал TCP-клиент и передал многоадресный адрес для вызова connect(). Я получил следующую ошибку: «Не удалось подключиться [семейство адресов не поддерживается семейством протоколов]». Вышеприведенная ошибка возникла из функции tcp_v4_connect() здесь: http://lxr.free-electrons.com/source/net/ipv4/tcp_ipv4.c#L142 –

1

Это, безусловно, потребует значительных изменений ядра. Это также полностью несовместимо с TCP RFC, поэтому вы бы не использовали TCP.

Какие файлы следует отредактировать? Файлы реализации ядра TCP. Но сначала вам нужно хорошо понять, как работает TCP в Linux, что выходит за рамки того, что может предоставить ответ Stackoverflow.

Однако почему бы не пойти на более простое решение?
Используя многоадресную рассылку UDP, отправьте сообщение всем потенциальным партнерам. Каждый ответит через UDP своим IP-адресом и номером порта. затем откройте регулярные TCP-подключения ко всем из них.