TCP Fast Open tcpdump抓包分析

前文介绍了TCP Fast Open的原理和使用,这次用tcpdump工具将TCP消息抓一下,看看是具体怎样实现的。

首先要了解一下IP报头和TCP报头的格式,这样才能根据协议对应报头内容:
TCPIP报头
接下来我们看一下第一次连接的时候的抓包内容:
抓包命令:

tcpdump -i lo tcp port 5555 -Xnn

SYN+空Cookie:

16:38:18.614264 IP 127.0.0.1.52868 > 127.0.0.1.5555: Flags [S], seq 2089549908, win 43690, options [mss 65495,sackOK,TS val 49428115 ecr 0,nop,wscale 7,tfo  cookiereq,nop,nop], length 0
        0x0000:  4500 0040 									4:版本 | 5:IP报文长度,5*32=5*4字节=5*2个4位16进制=10个4位16进制 | 00服务类型 | 0040:总长度64个字节=32个4位16进制
						   36c7 4000 						36c7:标识,IP报头的序列号 | 010:0未使用,1允许分段,0没有更多分段在传输 | 后面的0表示偏移,这里偏移是0
									 4006 05ef 				40:生存时间 | 06:TCP协议 | 05ef:报头校验和
											   7f00 0001	7f00 0001:源IP地址7f.00.00.01=127.0.0.1
        0x0010:  7f00 0001 									7f00 0001:目的IP地址7f.00.00.01=127.0.0.1 | ***因为IP报头长度是10个4位16进制,所以到此,IP报头结束,下面是TCP报头
		-------------------------------------------------------------------------------------------------------------------------------------------------------
						   ce84 15b3 						ce84:源端口52868 | 15b3:目的端口5555
									 7c8c 0054 				7c8c 0054:请求端序列号
											   0000 0000	0000 0000:请求端确认号0
        0x0020:  b002 aaaa 									b:数据偏移,TCP头部长度,10*32字节=10*2个4位16进制=20个4位16进制,刚好到结束,也就是该消息没有数据 | 保留6位0 | 
															000010:URG(0),ACK(0),PSH(0),RST(0),SYN(1),FIN(0) | aaaa:窗口43690
						   fe34 0000 						fe34:校验和 | 0000:紧急指针
						             0204 ffd7 				02:TCP选项,kind=2 最大报文段长度(MSS)选项 | 04:length=4 | ffd7:最大报文段长度65495(mss)
											   0402 080a  	04:TCP选项,kind=4 选择性确认(Selective Acknowledgment,SACK)选项 | 02:length=2 |
															08:TCP选项,kind=8 时间戳选项 |  0a:length=10 也就是后面8个字节都是属于这个选项的
        0x0030:  02f2 3693 									02f2 3693:时间戳值
						   0000 0000 						0000 0000:时间戳回显应答
									 0103 0307 				01:空操作,一般用于填充4字节整数倍 | 
															03:TCP选项,kind=3 窗口扩大因子选项:假设TCP头部中的接收通告窗口大小是N,窗口扩大因子(移位数)是M,那么TCP报文段的实际接收通告窗口大小是N*2M,或者说N左移M位。|
															03:length=3 | 07:位移数,也就是上面的M,那么实际通告窗口大小就是aaaa*2*7
											   2202 0101  	22:kind=22 fto选项 | 02:length | 0101:nop,nop,fto的cookie值一定要后面加上个nopnop,而实际cookie的长度是length-2,参考 https://tools.ietf.org/html/rfc7413#section-4.1.2

SYN+ACK+Cookie

16:38:18.614275 IP 127.0.0.1.5555 > 127.0.0.1.52868: Flags [S.], seq 2825442661, ack 2089549909, win 43690, options [mss 65495,sackOK,TS val 49428115 ecr 49428115,nop,wscale 7,tfo  cookie 32faf79caff51cde,nop,nop], length 0
        0x0000:  4500 0048 									4:版本 | 5:IP报文长度,5*32=5*4字节=5*2个4位16进制=10个4位16进制 | 00服务类型 | 0048:总长度72个字节=36个4位16进制
						   0000 4000 						0000:标识,IP报头的序列号 | 010:0未使用,1允许分段,0没有更多分段在传输 | 后面的0表示偏移,这里偏移是0
									 4006 3cae 				40:生存时间 | 06:TCP协议 | 3cae:报头校验和
											   7f00 0001  	7f00 0001:源IP地址7f.00.00.01=127.0.0.1
        0x0010:  7f00 0001 									7f00 0001:目的IP地址7f.00.00.01=127.0.0.1
		-------------------------------------------------------------------------------------------------------------------------------------------------------
						   15b3 ce84 						15b3:源端口5555 | ce84:目的端口52868
								     a868 d565 				a868 d565:响应端序列号
											   7c8c 0055  	7c8c 0055:响应端确认号
        0x0020:  d012 aaaa 									d:数据偏移,TCP头部长度,13*32字节=13*2个4位16进制=26个4位16进制,刚好到结束,也就是该消息没有数据 | 保留6位0 | 
															010010:URG(0),ACK(1),PSH(0),RST(0),SYN(1),FIN(0) | aaaa:窗口43690
						   fe3c 0000 						fe30:校验和 | 0000:紧急指针
									 0204 ffd7 				02:TCP选项,kind=2 最大报文段长度(MSS)选项 | 04:length=4 | ffd7:最大报文段长度65495(mss)
											   0402 080a  	04:TCP选项,kind=4 选择性确认(Selective Acknowledgment,SACK)选项 | 02:length=2 |
															08:TCP选项,kind=8 时间戳选项 |  0a:length=10 也就是后面8个字节都是属于这个选项的
        0x0030:  02f2 3693 									02f2 3693:时间戳值
						   02f2 3693 						02f2 3693:时间戳回显应答
									 0103 0307 				01:空操作,一般用于填充4字节整数倍 | 
															03:TCP选项,kind=3 窗口扩大因子选项:假设TCP头部中的接收通告窗口大小是N,窗口扩大因子(移位数)是M,那么TCP报文段的实际接收通告窗口大小是N*2M,或者说N左移M位。|
															03:length=3 | 07:位移数,也就是上面的M,那么实际通告窗口大小就是aaaa*2*7
											   220a 32fa  	22:kind=22 fto选项 | 0a:length | 
        0x0040:  f79c aff5 									
						   1cde 0101                      	32fa f79c aff5 1cde: cookie | 0101 :nop,nop

ACK+Data,这里发送的数据是"Hello, tcp fast open"

16:38:18.614284 IP 127.0.0.1.52868 > 127.0.0.1.5555: Flags [P.], seq 1:21, ack 1, win 342, options [nop,nop,TS val 49428115 ecr 49428115], length 20
        0x0000:  4500 0048 									4:版本 | 5:IP报文长度,5*32=5*4字节=5*2个4位16进制=10个4位16进制 | 00服务类型 | 0048:总长度72个字节=26个4位16进制
						   36c8 4000 						36c8:标识,IP报头的序列号,比第一次发送的序列号+1 | 010:0未使用,1允许分段,0没有更多分段在传输 | 后面的0表示偏移,这里偏移是0
									 4006 05e6 				40:生存时间 | 06:TCP协议 | 05e6:报头校验和
											   7f00 0001	7f00 0001:源IP地址7f.00.00.01=127.0.0.1
        0x0010:  7f00 0001 									7f00 0001:目的IP地址7f.00.00.01=127.0.0.1
		-------------------------------------------------------------------------------------------------------------------------------------------------------
						   ce84 15b3 						ce84:源端口52868 | 15b3:目的端口5555
									 7c8c 0055 				7c8c 0055:请求端序列号
											   a868 d566 	a868 d566:请求端确认序列号
        0x0020:  8018 0156 									8:数据偏移,TCP头部长度,8*32字节=8*2个4位16进制=16个4位16进制 | 保留6位0 | 
															011000:URG(0),ACK(1),PSH(1)表示含有数据,RST(0),SYN(0),FIN(0) | 0156:窗口342
						   fe3c 0000 						fe3c:校验和 | 0000:紧急指针
									 0101 080a 				01:空操作,一般用于填充4字节整数倍 | 01:空操作,一般用于填充4字节整数倍 | 08:TCP选项,kind=8 时间戳选项 |  0a:length=10 也就是后面8个字节都是属于这个选项的
											   02f2 3693 	02f2 3693:时间戳值
        0x0030:  02f2 3693 									02f2 3693:时间戳回显应答
						   4865 6c6c 						Hell
									 6f2c 2074 				o,.t
											   6370 2066  	cp.f
        0x0040:  6173 7420 6f70 656e                      	ast.open

断开请求后,看下一次请求的情况(由于很多内容是一样的,这里就不再详细解析了,只解析一些关键的数据):
SYN+Cookie+Data

16:38:28.615169 IP 127.0.0.1.52870 > 127.0.0.1.5555: Flags [S], seq 1871838175:1871838195, win 43690, options [mss 65495,sackOK,TS val 49430615 ecr 0,nop,wscale 7,tfo  cookie 32faf79caff51cde,nop,nop], length 20
        0x0000:  4500 005c bb88 4000 4006 8111 7f00 0001  E..\..@.@.......
        0x0010:  7f00 0001 
		-------------------------------------------------------------------------------------------------------------------------------------------------------
						   ce86 15b3 						
									 6f91 fbdf 				6f91 fbdf:请求端序列号1871838175
											   0000 0000  ........o.......
        0x0020:  d002 aaaa fe50 0000 0204 ffd7 0402 080a  .....P..........
		-------------------------------------------------------------------------------------------------------------------------------------------------------
        0x0030:  02f2 4057 									02f2 4057:时间戳值
						   0000 0000 						0000 0000:时间戳回显应答
									 0103 0307 				01:空操作,一般用于填充4字节整数倍 | 
															03:TCP选项,kind=3 窗口扩大因子选项:假设TCP头部中的接收通告窗口大小是N,窗口扩大因子(移位数)是M,那么TCP报文段的实际接收通告窗口大小是N*2M,或者说N左移M位。|
															03:length=3 | 07:位移数,也就是上面的M,那么实际通告窗口大小就是aaaa*2*7
											   220a 32fa  	22:kind=22 fto选项 | 0a:length | 32fa
        0x0040:  f79c aff5 1cde 0101 						f79c aff5 1cde : cookie | 0101: nop, nop
									 4865 6c6c 6f2c 2074  	Hello,.t
        0x0050:  6370 2066 6173 7420 6f70 656e            	cp.fast.open

SYN+ACK

16:38:28.615198 IP 127.0.0.1.5555 > 127.0.0.1.52870: Flags [S.], seq 2175465761, ack 1871838196, win 43690, options [mss 65495,sackOK,TS val 49430615 ecr 49430615,nop,wscale 7], length 0
        0x0000:  4500 003c 0000 4000 4006 3cba 7f00 0001 
        0x0010:  7f00 0001 
		-------------------------------------------------------------------------------------------------------------------------------------------------------
						   15b3 ce86 
									 81aa f921 				81aa f921:请求端序列号2175465761
											   6f91 fbf4 	6f91 fbf4:请求端确认号1871838196 = 1871838175 + 21
        0x0020:  a012 aaaa 									a:数据偏移,TCP头部长度,10*32字节=10*2个4位16进制=20个4位16进制,刚好到结束,也就是该消息没有数据 | 保留6位0 | 
															010010:URG(0),ACK(1),PSH(0),RST(0),SYN(1),FIN(0) | aaaa:窗口43690
						   fe30 0000 0204 ffd7 0402 080a  .....0..........
        0x0030:  02f2 4057 02f2 4057 0103 0307            ..@W..@W....

ACK

16:38:28.615198 IP 127.0.0.1.5555 > 127.0.0.1.52870: Flags [S.], seq 2175465761, ack 1871838196, win 43690, options [mss 65495,sackOK,TS val 49430615 ecr 49430615,nop,wscale 7], length 0
        0x0000:  4500 003c 0000 4000 4006 3cba 7f00 0001 
        0x0010:  7f00 0001 
		-------------------------------------------------------------------------------------------------------------------------------------------------------
						   15b3 ce86 
									 81aa f921 				81aa f921:请求端序列号2175465761
											   6f91 fbf4 	6f91 fbf4:请求端确认号1871838196 = 1871838175 + 21
        0x0020:  a012 aaaa 									a:数据偏移,TCP头部长度,10*32字节=10*2个4位16进制=20个4位16进制,刚好到结束,也就是该消息没有数据 | 保留6位0 | 
															010010:URG(0),ACK(1),PSH(0),RST(0),SYN(1),FIN(0) | aaaa:窗口43690
						   fe30 0000 0204 ffd7 0402 080a  .....0..........
        0x0030:  02f2 4057 02f2 4057 0103 0307            ..@W..@W....

看完这些内容,整个TFO的流程会更加清晰。

猜你喜欢

转载自blog.csdn.net/wyb_robin/article/details/107130275