第一章部分内容
一、抓包
- 只抓包头。一般能抓到的每个包(称为“帧”更准确)的最大长度为1514字节,启用了Jumbo Frame(巨型帧)之后可达9000字节以上,而大多数时候我们只需要IP头或者TCP头就足够分析了。然而在Wireshark上可以这样抓包头:单击菜单栏上的Capture–>Options,然后在弹出的窗口上定义“Limit each packet to”的值。我一般设置80字节。这样TCP层、网络层和数据链路层的信息都可以包括在内
使用tcpdump 的“-s”选项可以限制抓包的字节。 - 只抓必要的包。服务器上的网络连接可能非常多,而我们只需要其中那个的一小部分。Wireshark的Capture Filter可以在抓包时过滤掉不需要的包。
用tcpdump 的host参数可抓与特定Ip通信的数据包。
三、过滤
很多时候,解决问题的过程就是层层过滤,直到找到关键包。前面已经介绍过抓包时候的Capture Filter功能了。其实在包抓下来之后,还可以进一步过滤。
ip.addr eq 10.192.11.11 && tcp.port eq 445
在页面输入该过滤表达式即可筛选IP为10.192.11.11 端口号为445的数据包。
1. 如果已知某个协议发生问题,可以用协议名称过滤一下。如果已知该域的验证协议是Kerberos,那么就在Filter框输入Kerberos作为关键字过滤。
2. IP地址加port号是最常用的过滤方式,除了手工输入表达式外,还可以右键单击感兴趣的包,选择Follow TCP/UDP Stream就可以自动过滤。
3. 用鼠标帮助过滤,右键选择Prepare a Filter->Selected,会在Filter框中自动生成过滤表达式。
从Wireshark看网络分层
分层结构直接显示
应用层DATA
传输层:Transmission Control Protocol
用到了TCP协议
我们可以看到Seq号和Ack号等一系列信息,他们用于网络包的排序、重传、流量控制等。真正负责设备间传输的是下面两层。
网络互连层(网络层)Internet Protocol
本层的主要任务是把TCP层传下来的数据加上目标地址和源地址。
网络接口层(数据链路层)
看到两个设备的MAC地址。
了解TCP参数。
Seq表示该数据段的序号。
TCP提供有序的传输,所以每个数据段都要标上一个序号,当接收方收到乱序的包时,有序号就可以重新排序。如果一数据段1的起始Seq是1,长度为1448(意味着包含1448个字节),那么数据段2的Seq号就是1449,一个Seq号的大小是根据上一个数据段的Seq号相加而来的。
Len:该数据段的长度。虽然有的包Len=0,但其实是有TCP头的,头部本身携带的信息很多。
Ack:确认号,接收方向发送方确认已经收到了哪个字节。
比如A发送了“Seq:x Len:y”的数据段给B,那么B回复的确认号就是x+y,TCP的确认是可以累积的。
除了这几个参数,TCP头还附带了很多标志位:
SYN:携带这个标志的包表示正在发起连接请求,因为连接是双向的,所以建立连接时,双方都发送一个SYN。
FIN:携带这个标志的包表示正在请求终止连接。双方都发送一个FIN。
RST:用于重置一个混乱的链接,或者拒绝一个无效的请求。
三次握手
客户端:“可以建立链接么?我的发送初始序列号是X,如果你答应就恢复ACK= K+1”
服务器“收到,ACK=X+1。我也想跟你建立链接,我的初始发送序号是Y,如果你答应链接就回复ACK=Y+1”
客户端“收到,ACK=Y+1”
关闭Relative Sequence Number后重看三次握手
重传的研究
发送方的发送窗口是受接收方的接收窗口和网络影响的,其中限制得更严的因素就起决定作用。接收窗口的影响方式非常简单,只要再包里用“Win=”告知发送方就可以了。而网络的影响方式非常复杂。
网络之所以能限制发送窗口,是因为它一口气收到太多数据时就会拥塞,拥塞的结果就是丢包,这是发送方最忌惮的。能导致网络拥塞的数据量称为拥塞点,发送方当然希望把发送窗口控制在拥塞点一下,这样就能避免拥塞了。但问题是连网络设备都不知道自己的拥塞点,即使知道了也无法通知发送方。这种情况下发送方如何避免触碰拥塞点呢?
方案1. 发送方知道自己的网卡带宽,能否以此推测该连接的拥塞点?
不能。因为发送方和接收方之间还有路由器和交换机,其中任何一个设备都可能是瓶颈。
方案2. 逐次增加发送量,直到网络发生拥塞,这样得到的最大发送量能定为该连接的拥塞点么?
网络就像马路一样,有的时候很堵,有的时候很空。所以拥塞点是一个随时改变的动态值,当前试探出的拥塞点不能代表未来。
拥塞窗口的维护
1. 连接刚刚建立的时候,发送方对网络情况一无所知。如果一口气发太多数据就可能遭遇拥塞,所以发送方把拥塞窗口的初始值定得很小。RFC的建议是2 3 4个MSS,具体视MSS的大小而定。
2. 如果发出去的包都得到确认,表明还没有达到拥塞点,可以增大拥塞窗口。由于这个阶段发生拥塞的概率很低,所以增速应该快一些。RFC建议的算法是每收到n个确认,可以把拥塞窗口增加n个MSS。比如发了2个包之后收到2个确认,拥塞窗口就增大到4,接下来发送4个包收到4个确认,拥塞窗口增大到8。这个过程的增速很快,但是由于基数低,传输速度还比较难,所以被称为慢启动过程。
3. 慢启动过程持续一段时间后,拥塞窗口达到一个较大的值,这时候传输速度比较快,触碰拥塞点的概率变大。RFC建议算法是每个往返时间增加1个MSS。从慢启动过渡到拥塞避免的临界窗口值很有讲究。
如果之前发生过拥塞,就把该拥塞点作为参考依据。如果从来没有拥塞过,就可以取相对较大的值,比如和最大接收窗口相等。
拥塞的后果:对发送方来说,就是发出去的包不像往常一样得到确认了。不过收不到确认也可能是网络延迟所致,所以发送方决定等待一段时间后再判断。假如迟迟收不到,就认定包已经丢失,只能重传了。这个过程称为超时重传。从发出原始包到重传该包的这段时间被称为RTO,RTO算法不在本章讨论。
重传之后拥塞窗口的调整
为了不给刚发生拥塞的网络雪上加霜,RFC建议把拥塞窗口降到1个MSS,然后再次进入慢启动过程。这次从慢启动过渡到拥塞避免的临界窗口值就有参考依据了。
超时重传的严重影响
RTO阶段没有传数据,浪费时间
拥塞窗口急剧减小,相当于接下来传得慢多了。
其他情况
有时候拥塞很轻微,只有少量的包丢失。还有些偶然因素,比如校验码不对,会导致单个丢包。这两种丢包症状和严重拥塞时不一样,因为后续有包能正常到达,当后续的包到达接收方时,接收方会发现其Seq号比期望的大,所以它每收到一个包就ACK一次期望的Swq号,以此提醒发送方重传。当发送方收到3个或以上重复确认时,就意识到相应的包已经丢了,从而立即重传它。这个过程称为快速重传。
为什么要凑满3个呢?因为网络包有时会乱序,乱序的包会触发重复的ACK,但为了乱序没必要重传。一般乱序的距离不会相差太大。