当其他协议似乎已关闭时,如何解析DNS名称解析?

时间:2011-12-07 03:31:51

标签: c linux sockets networking tcp

我们正在尝试实施基于Moxa UC-7112-LX嵌入式计算机(uClinux OS)的软件。我们使用Cinteron MC52i GSM调制解调器(常规GPRS服务)和标准pppd连接到互联网。

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

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

所以,我的情况是:链接是否足以维护DNS解析服务(UDP正在工作?)但不足以运行TCP连接并接收ping回声......

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

我知道我们使用的系统很奇特,这里描述的情况可能与某些错误的tcp堆栈或pppd实现有关。考虑到系统是由制造商预先配置的,我没有任何重建/更改操作系统固件的选项。

我仍然希望有人在任何类似Linux的系统上看到过类似的情况。有没有办法测试为什么DNS名称解析工作,而其他网络的东西没有?是否可以使用某些pppd设置删除此类连接状态?

修改

首先,我想解决本地缓存IP地址的可能性。我没有dig实用程序,我不知道如何检查哪个主机将结果提供给getaddrinfo()。我仍然确定地址没有被缓存,因为我试图ping完全随机的URL。另外,由于GPRS响应时间较慢,因此在开始发送数据包之前,没有必要使用时间测量实用程序来确定ping需要1-2秒或更长时间来解析IP。此外,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的实现不支持 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在我的系统上不可用,路由提供与上面相同的信息。

但是我永远不能ping 192.168.254.254,即使一切按预期工作:tcp连接,ping,DNS等。以下是traceroute的结果:< / p>

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的内部网络直到目的地,&#39;循环&#39;在目标地址 - 它不应该是这样的)。

另外我想说明我可以ping DNS服务器,但是traceroute不会一直到它。

您可能会注意到有eth0和eth1设备。他们与案件无关。 eth1未连接且eth0连接到没有Internet访问的LAN。

连接状态不佳

所以,一段时间过去了,问题就出现了。除了DNS服务器(和对等端,我从DNS的traceroute得到的地址)我无法ping通任何东西,并且无法通过tcp与远程主机通信。 DNS解析 正在运行

网络实用程序提供与正常状态相同的输出。我有相同的unpingable peer (来自ifconfig结果的192.168.254.254),路由表是相同的:

# 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脚本没有循环(脚本在临时日志中没有新记录)。

此处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 ###

***行可能看起来很麻烦,但我在正常情况下为该DNS获取相同的traceroute

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()一样,当telnet名为read()时,连接已关闭... 。实际的服务器没有收到任何传入连接。为什么&#39; connect()&#39;正常返回(它无法从主机获得握手响应!)超出了我的知识范围。

同样的telnet测试在正常状态下运行正常。

注意:

我没有在我的系统的嵌入式特性的serverfault原因上发布这个。据我所知,serverfault处理更传统的系统(比如x86正在运行&#39; normal&#39; linux)。我只是希望stackoverflow有更多的嵌入式专家知道像我的Moxa这样的系统。

2 个答案:

答案 0 :(得分:5)

:如果其他协议似乎已关闭,我怎样才能解析DNS名称解析?

A :您的本地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名称查询中得到一个本地缓存的答案(这对于人们在ppp连接上使用缓存DNS解析器来减少连接时间,并在ppp链路上实现小的负载减少。)

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

  • 如果随机DNS名称继续解析且您仍然无法与某个主机建立TCP连接,则在调查后编辑问题时,这是值得注意的。
  • 如果随机DNS名称无法解析,则表明您的默认路由丢失或ppp连接断开。

其他诊断信息

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

我假设您没有与DNS服务器的同一IP地址建立TCP连接。此时有很多可能性...如果您仍然可以解析随机DNS名称,但TCP连接失败,则您可能看到的问题是在ppp连接的另一端,即内核路由缓存(它保存了一些像TCP 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地址,那么除了您的uCLinux计算机上的缓存响应之外,您的DNS不太可能得到解决。
    • 如果您可以ping pppX,请尝试ping TCP对等方的IP地址和DNS的IP地址(如果它不在localhost上)。除非涉及防火墙,否则您必须能够成功ping才能使其中任何一个工作。
  2. 如果您ping的{​​{1}}的IP地址但不能pppX您的TCP对等IP地址,请检查路由表以查看您的默认路由是否仍然指向out ping

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

  4. 如果您可以ppp0使用默认路由,并且可以ping您尝试连接的远程主机,请检查内核的路由缓存中是否有远程TCP的IP地址主持人....寻找奇怪或可疑的东西

  5. 如果您可以 ping远程TCP主机(您需要做大约200 ping才能确定... pings是对显着的数据包丢失和GPRS敏感是众所周知的有害的),尝试成功tcp。如果两者都成功,那么现在是时候开始查看软件内部的线索了。

  6. 如果您仍然无法解决发生的事情,请在返回时包括上述命令的输出...以及如何开始telnet <remote_host> <remote_port>连接。

答案 1 :(得分:-1)

Ping不应该是最终用户应用程序的一部分(参见注释),并且任何程序都不应该依赖ping来运行。最好ping可能会告诉我们远程运行TCP / IP堆栈的一部分。看我的论点here

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

注意:例外情况是您正在为网络人员编写网络监控应用程序。

相关问题