如何解决DNS名称parsing在其他协议似乎closures时运行?

我们正试图实施一个基于Moxa UC-7112-LXembedded式计算机(uClinux OS)的软件。 我们使用Cinteron MC52i GSM调制解调器(普通GPRS服务)和标准的pppd连接到互联网。

一切似乎都很好,就在连接之后。 Ping实用程序正在工作,我的程序中的Socket函数也正常工作。 但是在一段时间后,ppp连接以非常特殊的方式进行了破解。 这是这种情况的症状:

  • 当我用一些主机名称作为参数调用ping实用程序时,系统能够parsing它的IP并开始发送ICMP数据包,但是没有响应。 我正在尝试不同的Web资源名称,以便系统不能将其地址caching或什么。 无论我select什么,系统正确parsingIP,但不能得到任何ping响应。
  • connect()write()函数在我的应用程序中没有错误返回,但是当涉及到read()函数返回时,errno设置为ECONNRESET (由对等方重置连接)。 该程序使用标准套接字函数(TCP协议)
  • ppp链接显示为正在运行( ifconfig ppp0

所以,我的情况是:这个链接足以维护DNSparsing服务(UDP正在工作?),但不足以运行TCP连接并接收ping回声。

这种情况一直没有出现。 有时系统可以正常工作几天而没有任何问题。 每当出现问题,简单的重置就可以解决所有问题。

我知道我们使用的系统是非常奇特的,这里描述的情况可能与一些错误的tcp堆栈或pppd实现有关。 考虑到系统是由制造商预先configuration的,我没有任何选项来重build/更改OS固件。

不过,我希望有人看到类似linux系统的情况。 有什么办法来testing为什么DNS名称parsing正在工作,而其他networking的东西没有? 是否有可能删除这种连接状态与一些PPPD设置?

编辑:

首先,我想解决本地cachingIP地址的可能性。 我没有dig实用程序,我不知道如何检查哪个主机给getaddrinfo()结果。 不过,我敢肯定,地址不caching,因为我试图ping完全随机的url。 此外,由于GPRS响应时间较慢,因此在开始发送数据包之前,无需使用时间测量实用程序查看ping需要1-2秒或更长时间来parsingIP。 此外, ncsdBIND或任何DNS服务器不在本地运行。 我明白,你可能不会看到这个证据,但这是我的系统上提供的实用工具集。

我想提供一些关于互联网连接操作的更多信息。

正常连接状态

系统加载的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实现不支持日志文件选项(所以我不明白为什么它被打破)。 坚持似乎没有工作,所以我来到上面的连接脚本。 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 PtP: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 addrPtp总是相同的: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在我的系统上不可用,路由给出与上面相同的信息。

但是我永远无法ping通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是对等的地址。 这种地址在任何情况下都是可以ping通的(见下文)。 我不知道为什么traceroute输出的结构是这样的(数据包从ISP的内部networking到目的地,在目的地址的“循环” – 它不应该是这样的)。

另外我想说明的是,我可以ping通DNS服务器,但是traceroute并不是一路走来的。

您可能会注意到有eth0和eth1设备。 他们与案件无关。 eth1没有连接,eth0连接到lan没有互联网接入。

连接状态不好

所以,过了一段时间,问题就出现了。 我不能ping任何东西,但DNS服务器(和peer,我从traceroute得到的DNS地址),并不能通过TCP与远程主机通信。 DNSparsing正在工作

networking实用程序提供与正常状态相同的输出。 我有同样的不可思议的同行 (从ifconfig结果192.168.254.254),路由表是相同的:

 # ifconfig ppp0 ppp0 Link encap:Point-Point Protocol inet addr:172.22.22.109 PtP: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脚本没有循环(脚本在makehift日志中没有新logging)。

这里ping到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 ### 

***线可能看起来像麻烦,但即时获得相同的traceroute为正常情况下的DNS

ping到172.16.4.210也可以正常工作。

现在到TCP。 我在PC上启动了一个简单的echo服务器,并尝试通过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()就像在我的自定义应用程序之后是closures连接…当telnet调用read() 。 实际的服务器没有收到任何传入的连接。 为什么'connect()'正常返回(它不能得到主机的握手响应!)超出了我的知识范围。

在正常状态下,同样的telnettesting也能正常工作。

注意:

我没有发布在我的系统的embedded性的serverfault原因。 服务器故障据我所知处理更传统的系统(如x86运行“正常”的Linux)。 我只是希望stackoverflow有更多的embedded式专家知道像我的Moxa这样的系统。

:如何让DNS名称解析运行,而其他协议似乎关闭?

:您的本地DNS解析器( bind是除了ncsd之外的另一种可能性) 可能会缓存第一个响应。 dig会告诉你你从哪里得到的回应:

 [mpenning@Bucksnort ~]$ dig cisco.com ; <<>> DiG 9.6-ESV-R4 <<>> +all cisco.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 22106 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0 ;; QUESTION SECTION: ;cisco.com. IN A ;; ANSWER SECTION: cisco.com. 86367 IN A 198.133.219.25 ;; AUTHORITY SECTION: cisco.com. 86367 IN NS ns2.cisco.com. cisco.com. 86367 IN NS ns1.cisco.com. ;; Query time: 1 msec <----------------------- 1msec is usually cached ;; SERVER: 127.0.0.1#53(127.0.0.1) <--------------- Answered by localhost ;; WHEN: Wed Dec 7 04:41:21 2011 ;; MSG SIZE rcvd: 79 [mpenning@Bucksnort ~]$ 

如果你从127.0.0.1得到一个非常快(低毫秒)的答案,那么你很可能从同一个DNS名称的先前查询中得到一个本地缓存的答案(并且人们常常使用缓存DNS在ppp连接上的解析器,以减少连接时间,以及在ppp链路上实现小的负载减少)。

如果您怀疑缓存的答案,请dig其他一些DNS名称以查看是否可以解析。

  • 如果随机的DNS名称继续解析,并且仍然无法与某个主机建立TCP连接,则在调查后编辑问题时,值得注意。
  • 如果随机的DNS名称不能解析,那么这表示类似于缺省路由的丢失或者ppp连接断开。

其他诊断信息

如果您发现自己处于我描述的最后一种情况,则需要进行一些IP和ppp级别的调试,然后才能进一步隔离。 正如有人提到的那样, tcpdump在这一点上是非常有价值的,但是这听起来像你没有可用的。

我假设你没有建立到你的DNS服务器的同一个IP地址的TCP连接。 在这一点上有很多可能性…如果仍然可以解析随机的DNS名称,但是TCP连接失败,则可能是因为您看到的问题位于ppp连接的另一端,即内核路由缓存其中包含像MSS一样的TCP状态信息)正在变得混乱,你有太多的tcp丢包,或任何数量的东西。

我们假设你的拓扑是这样的:

  10.1.1.2/30 10.1.1.1/30 [ppp0] [pppX] uCLinux----------------------Accessserver---->[To the reset of the network] 

当您启动您的PPP连接时,请记下您的IP地址和默认网关的地址:

 ip link show ppp0 # display the link status of your ppp0 intf (is it up?) ip addr show ppp0 # display the IP address of your ppp0 interface ip route show # display your routing table route -Cevn # display the kernel's routing cache 

如果您没有将iproute2软件包作为发行版的一部分( iproute2提供ip实用程序),则可以找到类似的结果:

 ifconfig ppp0 # display link status and addresses on ppp0 netstat -rn # display routing table route -Cevn # display kernel routing table 

对于那些使用iproute2实用程序(几乎每个人都是这些天), ifconfig已被弃用,并由ip命令取代; 但是,如果你有一个较老的2.2或2.4系统,你可能仍然需要使用ifconfig

故障排除步骤

  1. 当您遇到问题时,请先检查您是否可以在访问服务器上ping pppX的地址。

    • 如果你不能ping通另一端的pppX的IP地址,那么你的DNS就不太可能被你的uCLinux机器上缓存的响应以外的任何东西解决。
    • 如果可以ping pppX ,则尝试ping TCP对等体的IP地址和DNS的IP地址(如果不在localhost )。 除非涉及防火墙,否则您必须能够成功ping才能使其工作。
  2. 如果你能pingpppX的IP地址,但是你不能ping你的TCP对等体的IP地址,请检查你的路由表,看你的默认路由是否仍然指出ppp0

  3. 如果您的默认路由通过ppp0指向,请检查您是否仍可以ping通默认路由的ip地址。

  4. 如果您可以ping您的默认路由,并且您能连接您尝试连接的远程主机,检查内核的路由缓存为远程TCP主机的IP地址….寻找任何奇怪或可疑

  5. 如果你可以 ping远程TCP主机(你需要做大约200个pings来确保… tcp对重要的数据包丢失敏感,而GPRS是非常有损的),请尝试成功telnet <remote_host> <remote_port> 。 如果两者都成功,那么现在是时候开始寻找你的软件内部线索。

如果仍然无法解决发生的情况,请在返回时包括上述命令的输出以及如何启动ppp连接。

Ping不应该是最终用户应用程序的一部分(见注),并且程序不应该依赖ping来运行。 最多ping可能会告诉我们一部分TCP / IP堆栈正在远程运行。 在这里看到我的论点。

OP描述的问题似乎不成问题。 所有网络连接失败,解析器可能会或可能不会使用网络,而ping不是真的有帮助。 我猜测OP可以检查调制解调器是否连接,如果不连接。

编辑:伪代码

 do until success try connect "foobar.com" try write data read response catch not success endtry catch error 'modem down - reconnect not success end try loop 

注意:如果您正在为网络人员编写网络监控应用程序,则会出现这种情况。