まとめ
- 受信したシーケンス番号に + (受信データ長) したものを ACK 番号に入れて返す
- 受信した ACK 番号を次のシーケンス番号とする
実験
nc と tcpdump を使って、シーケンス番号と ACK 番号の増え方を観察してみます。
サーバ側
nc -l <port> で、指定したポートで接続を待ちます。
$ nc -l 50000
クライアント側
tcpdump
-i でキャプチャするインターフェースを指定し、-w でファイルに出力します。
$ tcpdump -i wlp2s0 -w dump.pcap
nc
nc をクライアントとして用いる場合、nc <IP> <port> でサーバの IP と port を指定します。
$ nc 192.168.179.6 50000
データ送信
クライアント側で適当に何か入力してデータを送信し、その後接続を切ります。
$ nc 192.168.179.6 50000
hello
hogehoge
^C
$
サーバに送ったデータが表示され、接続が切れていました。
$ nc -l 50000
hello
hogehoge
$
tcpdump 結果
キャプチャ停止後に、-r コマンドでキャプチャしたファイルを読み込みます。-S でシーケンス番号を絶対番号で表示し、 port 50000 により、50000 番ポートの通信のみを抽出します。
$ tcpdump -r dump.pcap -S port 50000
reading from file dump.pcap, link-type EN10MB (Ethernet)
22:44:27.574365 IP 192.168.179.5.48882 > 192.168.179.6.50000: Flags [S], seq 3931966036, win 29200, options [mss 1460,sackOK,TS val 4212938433 ecr 0,nop,wscale 7], length 0
22:44:27.579376 IP 192.168.179.6.50000 > 192.168.179.5.48882: Flags [S.], seq 792281538, ack 3931966037, win 28960, options [mss 1460,sackOK,TS val 1020480106 ecr 4212938433,nop,wscale 7], length 0
22:44:27.579462 IP 192.168.179.5.48882 > 192.168.179.6.50000: Flags [.], ack 792281539, win 229, options [nop,nop,TS val 4212938435 ecr 1020480106], length 0
22:44:29.079095 IP 192.168.179.5.48882 > 192.168.179.6.50000: Flags [P.], seq 3931966037:3931966043, ack 792281539, win 229, options [nop,nop,TS val 4212938809 ecr 1020480106], length 6
22:44:29.092398 IP 192.168.179.6.50000 > 192.168.179.5.48882: Flags [.], ack 3931966043, win 227, options [nop,nop,TS val 1020480484 ecr 4212938809], length 0
22:44:45.468223 IP 192.168.179.5.48882 > 192.168.179.6.50000: Flags [P.], seq 3931966043:3931966052, ack 792281539, win 229, options [nop,nop,TS val 4212942907 ecr 1020480484], length 9
22:44:45.524994 IP 192.168.179.6.50000 > 192.168.179.5.48882: Flags [.], ack 3931966052, win 227, options [nop,nop,TS val 1020484579 ecr 4212942907], length 0
22:44:46.858640 IP 192.168.179.5.48882 > 192.168.179.6.50000: Flags [F.], seq 3931966052, ack 792281539, win 229, options [nop,nop,TS val 4212943254 ecr 1020484579], length 0
22:44:46.866443 IP 192.168.179.6.50000 > 192.168.179.5.48882: Flags [F.], seq 792281539, ack 3931966053, win 227, options [nop,nop,TS val 1020484927 ecr 4212943254], length 0
22:44:46.866553 IP 192.168.179.5.48882 > 192.168.179.6.50000: Flags [.], ack 792281540, win 229, options [nop,nop,TS val 4212943256 ecr 1020484927], length 0
解析
3-way handshake
クライアント側のポートは 48882 のよう。Flags の [S] が SYN, [.] が ACK です。
はじめの 3 行で SYN -> SYN/ACK -> ACK の 3-way handshake が見えます。
22:44:27.574365 IP 192.168.179.5.48882 > 192.168.179.6.50000: Flags [S], seq 3931966036, win 29200, options [mss 1460,sackOK,TS val 4212938433 ecr 0,nop,wscale 7], length 0
22:44:27.579376 IP 192.168.179.6.50000 > 192.168.179.5.48882: Flags [S.], seq 792281538, ack 3931966037, win 28960, options [mss 1460,sackOK,TS val 1020480106 ecr 4212938433,nop,wscale 7], length 0
22:44:27.579462 IP 192.168.179.5.48882 > 192.168.179.6.50000: Flags [.], ack 792281539, win 229, options [nop,nop,TS val 4212938435 ecr 1020480106], length 0
これから、
- 受信したシーケンス番号に + 1 したものを ACK 番号に入れて返す
- 受信した ACK 番号が次のシーケンス番号になる
ことが分かります。
flag | seq | ack | |
---|---|---|---|
Client -> Server | SYN | 3931966036 | 0 |
Server -> Client | SYN/ACK | 792281538 | 3931966037 (3931966036 + 1) |
Client -> Server | ACK | 3931966037 | 792281539 (792281538 + 1) |
データ送信
以下 4 行が "hello" と "hogehoge" を送信した際のキャプチャ。
22:44:29.079095 IP 192.168.179.5.48882 > 192.168.179.6.50000: Flags [P.], seq 3931966037:3931966043, ack 792281539, win 229, options [nop,nop,TS val 4212938809 ecr 1020480106], length 6
22:44:29.092398 IP 192.168.179.6.50000 > 192.168.179.5.48882: Flags [.], ack 3931966043, win 227, options [nop,nop,TS val 1020480484 ecr 4212938809], length 0
22:44:45.468223 IP 192.168.179.5.48882 > 192.168.179.6.50000: Flags [P.], seq 3931966043:3931966052, ack 792281539, win 229, options [nop,nop,TS val 4212942907 ecr 1020480484], length 9
22:44:45.524994 IP 192.168.179.6.50000 > 192.168.179.5.48882: Flags [.], ack 3931966052, win 227, options [nop,nop,TS val 1020484579 ecr 4212942907], length 0
これより、
- 受信したシーケンス番号に + (受信データ長) したものを ACK 番号に入れて返す
- 受信した ACK 番号が次のシーケンス番号になる
ことが分かります。
flag | seq | ack | |
---|---|---|---|
Client -> Server | PUSH/ACK | 3931966037 | 792281539 |
Server -> Client | ACK | 792281539 | 3931966043 (3931966037 + 6) |
Client -> Server | PUSH/ACK | 3931966043 | 792281539 |
Client -> Server | ACK | 792281539 | 3931966052 (3931966043 + 9) |
コネクション切断
FIN -> FIN/ACK -> ACK の流れで、受信したシーケンス番号 + 1 が ACK 番号となるのは接続開始時と同様です。
22:44:46.858640 IP 192.168.179.5.48882 > 192.168.179.6.50000: Flags [F.], seq 3931966052, ack 792281539, win 229, options [nop,nop,TS val 4212943254 ecr 1020484579], length 0
22:44:46.866443 IP 192.168.179.6.50000 > 192.168.179.5.48882: Flags [F.], seq 792281539, ack 3931966053, win 227, options [nop,nop,TS val 1020484927 ecr 4212943254], length 0
22:44:46.866553 IP 192.168.179.5.48882 > 192.168.179.6.50000: Flags [.], ack 792281540, win 229, options [nop,nop,TS val 4212943256 ecr 1020484927], length 0