2016-04-20 6 views
0

Обновление вопроса: В дополнение к этой проблеме, похоже, наше клиентское/серверное приложение с использованием механизма Linux PLPMTUD становится слишком большим путь MTU. Кто-нибудь видел это, т. Е. Фактический путь MTU равен 1500, но getsockopt w TCP_MAXSEG, возвращающий MTU: s конечных точек, в нашем случае 3000? Я попытался превратить GRO, GSO и ​​TSO с ethtool, но ошибка сохраняется. Обычный пинг управляет только пропуском пакетов 1472 байта или меньше. Также стоит упомянуть, что PLPMTUD отлично работает для меньшего MTU: s. Например, w конечных точек в 1500 MTU и один интерфейс промежуточного маршрутизатора, установленного, например, 1200 MTU, ядро ​​TCP проверяет и сообщает правильные TCP_MAXSEG (1200 - заголовки).TCP_MAXSEG неточный? (Был ли: путь к Linux MTU-зондирование не работает на accept(): ed socket при запросе с помощью setsockopt())

Я использую обнаружение MTU пути пакета определения уровня пакетов, совместимого с RFC4821, в приложении. В принципе, клиент делает setsockopt на сокет TCP:

setsockopt (FD, SOL_IP, IP_MTU_DISCOVER, & SOPT, SizeOf (SOPT)) со значением параметра установлено значение IP_PMTUDISC_PROBE. Функция setsockopt не возвращает ошибку.

Клиент отправляет большие tcp-пакеты на сервер отбрасывания, а MTU пути откалиброван в ядре Linux - tcpdump показывает пакеты tcp с переданным набором DF-бит, размер пакета зависит от того, пока ядро ​​не знает путь MTU. Тем не менее, чтобы заставить это работать в другом направлении (слушающий сервер принимает: соединение с клиентами, отправку данных и калибровку PMTU в направлении от сервера к клиенту), я должен установить глобальную опцию для обнаружения tcp path mtu,/proc/sys/нетто/ipv4/tcp_mtu_probing. Если я этого не сделаю, сервер будет тупо продолжать отправлять слишком большие пакеты, которые отбрасываются промежуточным маршрутизатором без отправки ICMP. Обе конечные точки имеют MTU, установленный на 3000, в то время как промежуточные переходы имеют MTU 1500.

Надеюсь, у кого-то есть идея, что пойдет не так. Если вам нужна дополнительная информация, дайте мне знать, и я отредактирую вопрос. Проблемы существуют как на ядре Linux 4.2.0, так и на 3.19.0, оба являются исходными ядрами Kubuntu LTS. (x86/x86-64)

Я также устанавливаю одну и ту же опцию сокета на стороне сервера, на всех принимаем: ed сокеты перед отправкой данных в обратном направлении.

+0

Попробуйте установить опцию сокета в гнездо для прослушивания вместо принятых сокетов. Он будет унаследован ими. Установка его на приемные сокеты может быть слишком запоздалой, так как соединение квитирования уже произошло, согласование окон и т. Д. – EJP

+0

@EJP: Хорошая идея, но я пробовал это раньше, но безуспешно. –

+0

Похоже, что у вас есть промежуточный маршрутизатор, который ломает правильное обнаружение MTU пути, и поэтому неудивительно, что обнаружение MTU пути не работает, если вы не разрешаете обходные пути. В чем тайна? Исправьте промежуточный маршрутизатор, жалуясь на того, кто его администрирует. –

ответ

0

FWIW, я нашел обходные пути/решения проблем, сделаю больше испытаний, но вкратце опишу свои выводы здесь, если это поможет кому-то другому.

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

Вторая проблема неправильного пути mtu, возвращаемого getsockopt TCP_MAXSEG, была исправлена, ожидая TCP ACK отправленных данных TCP, также используя getsockopt (tcp_info.tcpi_unacked). Таким образом, я могу быть уверен, что тестирование закончилось, прежде чем я получу TCP_MAXSEG.

Наконец, в марте 2015 года был добавлен набор исправлений для улучшения точности отслеживания mtu пути, скомпилированного с ядром mainline Linux. Без этих исправлений зондирование очень неточно. Патчсет является частью ядер 4.1.y и далее.