标签:sockets tcp networking c-3 linux
我们正在尝试实现基于Moxa UC-7112-LX嵌入式计算机(uClinux OS)的软件.我们使用Cinteron MC52i GSM调制解调器(常规GPRS服务)和standart pppd连接到Internet.
连接之后,一切似乎都很好. Ping实用程序正在工作,我程序中的Socket函数也正常工作.但是一段时间后,ppp连接以一种非常特殊的方式断开.这些是这种情况的症状:
>当我使用某些主机名作为参数调用ping实用程序时,系统能够解析其IP,并开始发送ICMP数据包,但没有响应.我正在尝试使用不同的Web资源名称,以使系统无法缓存其地址或其他内容.无论我选择什么,系统都能正确解析IP,但无法获得任何ping响应.
>我的应用程序中的connect()和write()函数没有错误返回,但是当涉及到read()时,该函数将errno设置为ECONNRESET(对等连接重置).该程序使用标准套接字功能(TCP协议)
> ppp链接显示为正在运行(ifconfig ppp0)
因此,我遇到的情况是:该链接足以维持DNS解析服务(UDP是否正常工作?),但不足以运行TCP连接并接收ping回显…
这种情况不会一直出现.有时,系统可以正常工作数天而没有任何问题.每当问题出现时,简单的重置就可以解决所有问题.
我知道我们使用的系统非常陌生,这里描述的情况可能与一些错误的tcp堆栈或pppd实现有关.考虑到系统是由制造商预先配置的,我没有任何选择来重建/更改OS固件.
我仍然希望有人在任何类似Linux的系统上都看到过类似的情况.有什么方法可以测试为什么DNS名称解析在其他网络设备无法正常工作的情况下起作用?是否可以使用某些pppd设置删除这种连接状态?
编辑:
首先,我想解决IP地址本地缓存的可能性.我没有dig实用程序,也不知道如何检查哪个主机将结果提供给getaddrinfo().不过,我仍然确定不会缓存地址,因为我试图对完全随机的URL执行ping操作.同样,由于GPRS响应时间较慢,因此没有必要使用时间测量工具来查看ping需要1-2秒或更长时间才能解析IP,然后再开始发送数据包.此外,ncsd,BIND或任何dns服务器不在计算机上本地运行.我了解您可能不会将其视为证据,但这就是我提供的系统上可用的实用程序集.
我想提供一些有关互联网连接操作的其他信息.
正常连接状态
系统加载时的rc脚本将另一个脚本作为后台进程运行:
sh /etc/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选项(所以我看不出它为什么损坏了).持久性似乎也不起作用,所以我来到了上面的连接脚本. 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地址,但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在我的系统上不可用,route提供了与上述相同的信息.
但是我无法对192.168.254.254进行ping操作,即使一切都按预期工作: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的内部网络,直接到达目标,在目标地址处“循环”,只是不应该这样).
我还要指出,我可以ping DNS服务器,但traceroute并不能一直进行下去.
您可能会注意到有eth0和eth1设备.它们与案件无关. eth1未连接且eth0已连接到局域网而无法访问互联网.
连接状态错误
因此,一段时间过去了,正在出现的情况出现了.除了DNS服务器(和对等体,我从DNS的traceroute结果获得的地址)之外,我无法ping通任何其他东西,并且无法通过tcp与远程主机通信. DNS解析正常
网络工具提供与正常状态下相同的输出.我有一个相同的不可pinging的对等体(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()之后是Connection关闭…当telnet调用read()时.实际服务器未收到任何传入连接.为什么’connect()’正常返回(无法从主机获得握手响应!)超出了我的知识范围.
当然,相同的telnet测试在正常状态下也可以正常工作.
注意:
由于系统的嵌入式特性,我没有在serverfault原因上发布此内容.据我所知,serverfault处理的是更常规的系统(例如运行“普通” linux的x86).我只是希望stackoverflow有更多的嵌入式专家来了解我的Moxa这样的系统.
解决方法:
问:如何在其他协议似乎已关闭的情况下运行DNS名称解析?
答:您的本地DNS解析器(除了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链路上实现较小的负载减少).
如果您怀疑已缓存的答案,请对其他一些DNS名称进行挖掘以查看其是否也可以解析.
>如果随机DNS名称继续解析,而您仍无法建立与特定主机的TCP连接,则在进行此调查后编辑问题时,值得注意.
>如果无法解析随机DNS名称,则表明存在诸如默认路由丢失或ppp连接断开的情况.
其他诊断信息
如果您发现我遇到的最后一种情况,则需要进行一些IP和ppp级别的调试,然后才能进一步隔离.正如有人提到的那样,tcpdump在这一点上非常有价值,但是听起来您没有它.
我假设您未建立与DNS服务器相同IP地址的TCP连接.此时有很多可能性…如果您仍然可以解析随机DNS名称,但是TCP连接失败,则可能是您看到的问题在ppp连接的另一端,即内核路由缓存(其中包含一些TCP状态信息(例如MSS)变得混乱不堪,对于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.
故障排除步骤:
>开始出现问题时,请首先检查是否可以ping通访问服务器上的pppX地址.
>如果您无法ping通另一端的pppX的IP地址,那么除了uCLinux机器上的缓存响应之外,DNS极不可能被其他任何方式解析.
>如果可以ping通pppX,请尝试ping通TCP对等方的IP地址和DNS的IP地址(如果不在本地主机上).除非涉及防火墙,否则您必须能够对其执行ping操作才能成功ping通.
>如果可以ping通pppX的ip地址,但不能ping通TCP对等方的ip地址,请检查路由表以查看默认路由是否仍指向ppp0
>如果默认路由指向ppp0,请检查是否仍可以ping默认路由的ip地址.
>如果您可以ping您的默认路由,并且可以ping您要连接的远程主机,请检查内核的路由缓存以获取远程TCP主机的IP地址….寻找任何奇怪或可疑的东西
>如果您可以ping通远程TCP主机(并且您需要执行约200 ping操作以确保… tcp对明显的数据包丢失很敏感,而GPRS则是有损的),请尝试成功建立telnet< remote_host" < remote_port>.如果两者都成功,那么是时候开始在软件内部寻找线索了.
如果仍然无法解决问题,请在返回时包括上述命令的输出…以及如何启动ppp连接.
标签:sockets,tcp,networking,c-3,linux 来源: https://codeday.me/bug/20191101/1987431.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。