Мы пытаемся внедрить программное обеспечение на базе встроенного компьютера Moxa UC-7112-LX (ОС uClinux).Мы используем GSM-модем Cinteron MC52i (обычная услуга GPRS) и стандартный pppd для подключения к Интернету.
Все выглядит нормально, сразу после подключения.Утилита Ping работает, функции Socket в моей программе тоже работают нормально.Однако через некоторое время соединение ppp обрывается очень своеобразно.Вот признаки этой ситуации:
- Когда я вызываю утилиту ping с именем хоста в качестве параметра, система может определить свой IP-адрес и начинает отправлять ICMP-пакеты, но не получает ответа.Я пробую разные имена веб-ресурсов, чтобы система не могла кэшировать их адреса или что-то в этом роде.Что бы я ни выбрал, система правильно разрешает IP, но не может получить отклик от ping. Функции
connect()
и write()
в моем приложении не возвращают ошибки, но когда дело доходит до read()
, функция возвращаетс errno, установленным в ECONNRESET
(сброс соединения по пиру).Программа использует стандартные функции сокетов (протокол TCP) - ссылка ppp показана как работающая (
ifconfig ppp0
)
Итак, у меня такая ситуация: ссылка хорошаядостаточно для поддержки службы разрешения DNS (UDP работает?), но НЕ достаточно хорош для запуска TCP-соединения и получения эхо-сигналов пинга ...
Ситуация не появляется постоянно.Иногда система может работать без проблем в течение нескольких дней.Всякий раз, когда возникает проблема, простой сброс решает все.
Я знаю, что система, которую мы используем, довольно экзотична, и описанная здесь ситуация может быть связана с некоторой ошибочной реализацией стека tcp или реализации pppd.Учитывая, что система предварительно сконфигурирована производителем, у меня нет никаких вариантов перестроить / изменить прошивку ОС.
Тем не менее, я надеюсь, что кто-то видел подобную ситуацию в любой Linux-подобной системе.Есть ли способ проверить, почему разрешение имен DNS работает, а другие сетевые компоненты - нет?Можно ли удалить такое состояние соединения с некоторыми настройками pppd?
Редактировать:
Прежде всего, я хотел бы рассмотреть возможность локального кэшированияIP-адреса.У меня нет утилиты dig
, и я не знаю, как проверить, какой хост дает результат getaddrinfo()
.Тем не менее я уверен, что адреса не кэшируются, потому что я пытаюсь пропинговать абсолютно случайные URL.Также, учитывая медленное время отклика GPRS, необязательно иметь утилиту измерения времени, чтобы увидеть, что ping требуется 1-2 секунды или более для разрешения IP перед началом отправки пакетов.Кроме того, ncsd
, BIND
или любые DNS-серверы не работают локально на машине.Я понимаю, что вы, возможно, не считаете это доказательством, но это то, что я привел набор утилит, доступный в моей системе.
Я хотел бы дать некоторую дополнительную информацию о работе подключения к Интернету.1037 * Нормальное состояние соединения
Сценарий rc
при загрузке системы запускает другой сценарий в качестве фонового процесса:
sh /etc/connect &
Сценарий connect
выглядит следующим образом:
#!/bin/sh
echo First connect attempt > /etc/ppp/conn.info
while true
do
date >> /etc/ppp/conn.info
pppd call mts
echo Reconnecting... >> /etc/ppp/conn.info
done
Причина, по которой я сделал цикл, проста: соединение сохраняется в течение нескольких часов, а после этого оно всегда разрывается.К сожалению, моя реализация pppd
не поддерживает опцию logfile (поэтому я не могу понять, почему она не работает). persist , похоже, тоже не работает, поэтому я пришел к скрипту подключения выше.Параметры pppd:
/dev/ttyM0 115200 crtscts
connect 'chat -f /etc/ppp/peers/mts.chat'
noauth
user mts
password mts
noipdefault
usepeerdns
defaultroute
ifconfig ppp0
дает:
ppp0 Link encap:Point-Point Protocol
inet addr:172.22.22.109 P-t-P:192.168.254.254 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:34 errors:0 dropped:0 overruns:0 frame:0
TX packets:36 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:3
RX bytes:3130 (3.0 KiB) TX bytes:2250 (2.1 KiB)
И вот тут-то и начинает становиться странно.Всякий раз, когда я подключаюсь, я получаю другое значение inet addr
, но P-t-p
всегда одинаково: 192.168.254.254.Это тот же адрес, который отображается в записи шлюза по умолчанию, как указано в netstat -rn
:
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
192.168.254.254 0.0.0.0 255.255.255.255 UH 0 0 0 ppp0
192.168.4.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
192.168.15.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
192.168.0.0 192.168.15.1 255.255.0.0 UG 0 0 0 eth0
0.0.0.0 192.168.254.254 0.0.0.0 UG 0 0 0 ppp0
route -Cevn
в моей системе недоступно, маршрут дает ту же информацию, что и выше.
Но я никогда не смогу пропинговать 192.168.254.254, даже когда все работает как положено: tcp соединение, ping, DNS и т. Д. Вот результат traceroute:
traceroute to kernel.org (149.20.4.69), 30 hops max, 40 byte packets
1 172.16.4.210 (172.16.4.210) 528.765 ms 545.269 ms 616.67 ms
2 172.16.4.226 (172.16.4.226) 563.034 ms 526.176 ms 537.07 ms
3 10.250.85.161 (10.250.85.161) 572.805 ms 564.073 ms 556.766 ms
4 172.31.250.9 (172.31.250.9) 556.513 ms 563.383 ms 580.724 ms
5 172.31.250.10 (172.31.250.10) 518.15 ms 526.403 ms 537.574 ms
6 pub2.kernel.org (149.20.4.69) 538.058 ms 514.222 ms 538.575 ms
7 pub2.kernel.org (149.20.4.69) 537.531 ms 538.52 ms 537.556 ms
8 pub2.kernel.org (149.20.4.69) 568.695 ms 523.099 ms 570.983 ms
9 pub2.kernel.org (149.20.4.69) 526.511 ms 534.583 ms 537.994 ms
##### traceroute loops here - why?? #######
Итак, я могу предположить, что 172.16.4.210 - это адрес партнера.Такой адрес является проверяемым в любом случае (см. Ниже).Я понятия не имею, почему структура вывода traceroute такова (пакеты приходят из внутренней сети ISP прямо к месту назначения, «зацикливаются» по адресу назначения - просто не должно быть так).
Также хотелось бы отметить, что я могу пропинговать DNS-сервер, но traceroute не доходит до него.
Вы можете заметить, что существуют устройства eth0 и eth1.Они не имеют отношения к делу.eth1 не подключен, а eth0 подключен к локальной сети без доступа к Интернету.
Плохое состояние соединения
Итак, проходит некоторое время и возникает рассматриваемая ситуация.Я не могу пропинговать ничего, кроме DNS-сервера (и однорангового узла, адрес для которого я получаю из результата traceroute для DNS) и не могу связаться с удаленным хостом через tcp.Разрешение DNS является рабочим
Сетевые утилиты выдают тот же вывод, что и в обычном состоянии.У меня есть такой же unpeable peer (192.168.254.254 из результата ifconfig), таблица маршрутизации такая же:
# ifconfig ppp0
ppp0 Link encap:Point-Point Protocol
inet addr:172.22.22.109 P-t-P:192.168.254.254 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:297 errors:0 dropped:0 overruns:0 frame:0
TX packets:424 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:3
RX bytes:33706 (32.9 KiB) TX bytes:27451 (26.8 KiB)
# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.254.254 * 255.255.255.255 UH 0 0 0 ppp0
192.168.4.0 * 255.255.255.0 U 0 0 0 eth1
192.168.15.0 * 255.255.255.0 U 0 0 0 eth0
192.168.0.0 192.168.15.1 255.255.0.0 UG 0 0 0 eth0
default 192.168.254.254 0.0.0.0 UG 0 0 0 ppp0
Обратите внимание, что исходное соединение ppp (которое я использовал для обеспечениявыход из нормальное состояние) сохраняется.Мой сценарий / etc / connect не зациклился (не было новой записи во временном журнале, который создает сценарий).
Здесь идет пинг с DNS-сервером:
# cat /etc/resolv.conf
#search moxa.com
nameserver 213.87.0.1
nameserver 213.87.1.1
# ping 213.87.0.1
PING 213.87.0.1 (213.87.0.1): 56 data bytes
64 bytes from 213.87.0.1: icmp_seq=0 ttl=59 time=559.8 ms
64 bytes from 213.87.0.1: icmp_seq=1 ttl=59 time=509.9 ms
64 bytes from 213.87.0.1: icmp_seq=2 ttl=59 time=559.8 ms
И traceroute:
# traceroute 213.87.0.1
traceroute to 213.87.0.1 (213.87.0.1), 30 hops max, 40 byte packets
1 172.16.4.210 (172.16.4.210) 542.449 ms 572.858 ms 595.681 ms
2 172.16.4.214 (172.16.4.214) 590.392 ms 565.887 ms 676.919 ms
3 * * *
4 217.8.237.62 (217.8.237.62) 603.1 ms 569.078 ms 553.723 ms
5 * * *
6 * * *
## and so on ###
***
строки могут выглядеть как проблемы, но я получаю ту же трассировку для этого DNS в нормальной ситуации
ping на 172.16.4.210 также работает нормально.
Теперь к TCP.Я запустил простой эхо-сервер на своем ПК и попытался подключиться к нему через telnet (фактический IP-адрес не отображается):
# telnet XXX.XXX.XXX.XXX 9060
Trying XXX.XXX.XXX.XXX(25635)...
Connected to XXX.XXX.XXX.XXX.
Escape character is '^]'.
aaabbbccc
Connection closed by foreign host.
Так вот что здесь произошло.Успешно connect()
, как и в моем пользовательском приложении, следует Соединение закрыто ... , когда telnet вызывает read()
.Фактический сервер не получил никакого входящего соединения.Почему «connect ()» возвращался нормально (он не мог получить ответ от рукопожатия от хоста!) Вне моей компетенции.
Конечно же, тот же тест telnet работает нормально в нормальном состоянии.
Примечание:
Я не публиковал это по причине ошибки сервера из-за встроенной природы моей системы.Насколько я понимаю, serverfault имеет дело с более традиционными системами (например, с x86, работающими под «обычным» linux).Я просто надеюсь, что в stackoverflow есть больше экспертов по встраиванию, которые знают такие системы, как мой Moxa.