Slide 1

Slide 1 text

Chap. 17 & 18 Transmission Control Protocol  詳解TCP/IP Vol.1 プロトコル @utsushiiro

Slide 2

Slide 2 text

TCPの特徴 TCPは「コネクション指向」の信頼性のある「バイトストリーム サービス」を提供する (RFC793) コネクション指向 TCPを利用する2つのアプリケーショ ンは, 通信を行う際に相互にTCPコ ネクションを確立する必要がある(相 手の存在を確認する). TCPにはブロードキャストやマルチ キャストというコンセプトは適用でき ない. バイトストリームサービス 2つのアプリケーション間では, 8bitのバイ トストリームが確立される. また, TCPによって自動的に挿入されるレ コードマーカーはなく, バイトの内容を変換 しない. これらの解釈は、上の層によって行 われる(※). ※ UNIXのファイルの取り扱いに似てる

Slide 3

Slide 3 text

TCPによる信頼性の確保 TCPでは以下の方法を持って信頼性を確保する ▣ 送信に対する一定時間内の確認応答を待つ ▣ ヘッダとデータでチェックサムを利用 ▣ データの順序を正してアプリケーションに渡す ▣ 重複したデータを破棄 ▣ データはTCPによって通信に最適なサイズに分割 ▣ フロー制御を行う

Slide 4

Slide 4 text

TCPヘッダ (RFC793)

Slide 5

Slide 5 text

TCPヘッダ ▣ 送信元・先ポート番号 □ IPヘッダの送信元・先IPアドレスと合わせて コネクションを一意に特定する ▣ シーケンス番号 □ コネクションを流れるデータの識別子 ▣ 確認応答番号 □ 受け取ったデータのシーケンス番号 + 1 そのデータまで受け取ったことを知らせる ▣ ヘッダ長 ※ ヘッダ長がUDPになくTCPにはあるのは  ヘッダにオプションフィールドがあり, 長さが可変のため

Slide 6

Slide 6 text

TCPヘッダ ▣ ウィンドウサイズ □ フロー制御用 (Chap. 24 Sec. 4) ▣ チェックサム □ データの破損を検出 ▣ 緊急ポインタ □ URGフラグ有効時に使用 (Chap. 24 Sec. 8) ▣ オプションフィールド □ 主要なものにMSSオプション(後述)

Slide 7

Slide 7 text

TCPヘッダ ▣ フラグビット □ URG (Urgent ) ■ 緊急ポインタが有効 (Chap. 20 Sec. 8) □ ACK (Acknowledgement) ■ 確認応答番号が有効 □ PSH (Push) ■ このフラグのついたデータを上位プロトコルに すぐに渡す(Chap. 20 Sec. 5) □ RST (Reset) ■ コネクションをリセットする □ SYN (Synchronize) ■ コネクション確立時のシーケンス番号の同期を行う □ FIN (Fin) ■ データの送信が終了

Slide 8

Slide 8 text

TCPヘッダ □ NS (Nonce Sum):RFC3540 ■ ECN関連のやり取りを保護するためのnonce □ CWR (Congestion Window Reduced):RFC3168 ■ ECEを受け取り輻輳ウィンドウを小さくしたことを伝える □ ECE (ECN-Echo):RFC3168 ■ 通信相手からのネットワークが輻輳していることを伝える  これらは, IPヘッダのECNと共にに使われる  ECN:Explicit Congestion Notification

Slide 9

Slide 9 text

TCPヘッダ ▣ 先頭にポート番号がある理由 ICMPエラーにおいては, IPデータグラムのIPヘッダの後続 8byteを返すが, これにポート番号を入れるため. (Chap. 6 参照) TCPはICMPエラーを受け取ると, どのコネクションがエラー を起こしているかを判断できる.

Slide 10

Slide 10 text

チェックサム これまでの章で出てきたプロトコルでのチェックサム ▣ IP, ICMP, IGMP, UDP ▣ UDP以外は必須 ▣ IPはIPヘッダのみだが, 他はIPヘッダの直後から □ UDP, TCPは疑似ヘッダを利用 いずれもチェックサムがエラーの場合は, “単に”破棄する チェックサムがエラー, つまりデータに破損があり ポート番号やIPアドレスが壊れているかもしれないため 送り元 等にエラーを通知しない(できない)

Slide 11

Slide 11 text

コネクションの確立 TCPでは最初に3 way handshakeによって コネクションを確立する SYN_SENT ESTABLISHED ESTABLISHED SYN_RCVD LISTEN

Slide 12

Slide 12 text

コネクションの確立 1. [ A ] A側の初期seq番号(ISN)をseq番号に指定し  1 SYNを設定して送る SYN_SENT LISTEN SYN_RCVD seq_num : ISN(A) flags:SYN A B

Slide 13

Slide 13 text

コネクションの確立 2. [ B ] B側のISNをseq番号に指定し, ISN+1をack番号とし 1 SYN+ACKを設定して応答する SYN_SENT SYN_RCVD seq_num : ISN(B) ack_num:ISN(A) + 1 flags:SYN, ACK ESTABLISHED A B

Slide 14

Slide 14 text

コネクションの確立 3. [ A ] Bから送られてきたseq番号(B側のISN)に  1 +1したものをack番号として  1 ACKを設定して応答する ESTABLISHED SYN_RCVD ESTABLISHED ack_num : ISN(B) + 1 flags:ACK B A

Slide 15

Slide 15 text

コネクションの確立 ▣ アクティブオープン 最初のSYNを送る側は アクティブオープンを実行したと言う ▣ パッシブオープン SYNを受け取り, SYNを送った側は パッシブオープンを実行したと言う ▣ ISNは各々が乱数を用いて決定する

Slide 16

Slide 16 text

TCPコネクションの確立 (実践) ----- クライアント側 ----- [Host_A in ~] >> ifconfig en0 inet en0: flags=8863 mtu 1500 inet 192.168.11.2 netmask 0xffffff00 broadcast 192.168.11.255 ----- サーバ側 ----- [Host_B in ~] >> ifconfig en1 inet en1: flags=8863 mtu 1500 inet 192.168.11.7 netmask 0xffffff00 broadcast 192.168.11.255 Macを使用 TCPの振る舞いをtelnet & nc & tcpdumpで観測する

Slide 17

Slide 17 text

TCPコネクションの確立 (実践) [Host_B in ~] >> nc -lk 60000 # 60000番でListen [Host_B in ~] >> netstat -a -p tcp | grep 60000 tcp4 0 0 *.60000 *.* LISTEN [Host_A in ~] >> telnet 192.168.11.7 60000 # サーバに接続 Trying 192.168.11.7... Connected to 192.168.11.7. Escape character is '^]'. [Host_B in ~] >> netstat -a -p tcp | grep 60000 tcp4 0 0 192.168.11.7.60000 192.168.11.2.52162 ESTABLISHED tcp4 0 0 *.60000 *.* LISTEN

Slide 18

Slide 18 text

TCPコネクションの確立 (実践) # 見やすいように整形済み # -i : インタフェース指定 -S : seqをそのまま表示 [Host_A in ~] >> tcpdump port 60000 -S -i en0 02:24:15.752057 IP 192.168.11.2.52162 > 192.168.11.7.60000: Flags [S], seq 3415559350, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1905379548 ecr 0,sackOK,eol], length 0 02:24:15.756467 IP 192.168.11.7.60000 > 192.168.11.2.52162: Flags [S.], seq 3789677825, ack 3415559351, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 2248889040 ecr 1905379548,sackOK,eol], length 0 02:24:15.756566 IP 192.168.11.2.52162 > 192.168.11.7.60000: Flags [.], ack 3789677826, win 4117, options [nop,nop,TS val 1905379552 ecr 2248889040], length 0

Slide 19

Slide 19 text

コネクションの終了 TCPでは互いに独立してコネクションを切断する FIN_WAIT_1 TIME_WAIT CLOSED LAST_ACK CLOSE_WAIT FIN_WAIT_2

Slide 20

Slide 20 text

コネクションの終了 1. [ A ] 送るデータのseq番号NEXT(A)をseq番号に指定し 受け取ったデータのB側のseq番号LAST(B)に+1したものを ack番号に指定し, FIN, ACKを設定して送る FIN_WAIT_1 LISTEN SYN_RCVD seq_num : NEXT(A) ack_num:LAST(B) + 1 flags:FIN, ACK A B

Slide 21

Slide 21 text

コネクションの終了 2. [ B ] NEXT(A)をack番号とし, ACKを設定して応答する これによってA→BはCLOSEDに SYN_SENT SYN_RCVD ack_num:NEXT(A) + 1 flags: ACK ESTABLISHED B A

Slide 22

Slide 22 text

コネクションの終了 3. [ B ] 送るデータのseq番号NEXT(B)をseq番号に指定し 受け取ったデータのA側のseq番号LAST(A)に+1したものを ack番号に指定し, FIN, ACKを設定して送る SYN_SENT SYN_RCVD seq_num : NEXT(B) ack_num:LAST(A) + 1 flags:FIN, ACK ESTABLISHED B A ハーフクローズを利用しなければ, LAST(A) = NEXT(A)

Slide 23

Slide 23 text

コネクションの終了 4. [ A ] NEXT(B)をack番号とし, ACKを設定して応答する これによってB→AはCLOSEDに SYN_SENT LISTEN SYN_RCVD ack_num : NEXT(B) + 1 flags:ACK B A

Slide 24

Slide 24 text

ハーフクローズ TCPコネクションは全二重通信であり, 各方向がそれぞれ独立的に終了する必要がある. FINの受信は, その方向からのデータがこれ以上流れていない ことを意味するだけ. 片方が終了しても, もう片方がデータを送ることができる. この状態をハーフクローズと呼ぶ

Slide 25

Slide 25 text

ハーフクローズ アプリケーション:write アプリケーション:read データ データのack

Slide 26

Slide 26 text

TCPコネクションの終了 (実践) # 先程のtelnetの続き [Host_A in ~] >> telnet 192.168.11.7 60000 Trying 192.168.11.7... Connected to 192.168.11.7. Escape character is '^]'. ^] telnet> quit # サーバから切断 Connection closed.

Slide 27

Slide 27 text

TCPコネクションの終了 (実践) # 先程のtcpdumpの続き 03:14:15.155841 IP 192.168.11.2.52162 > 192.168.11.7.60000: Flags [F.], seq 3415559351, ack 3789677826, win 4117, options [nop,nop,TS val 1908370916 ecr 2248889041], length 0 03:14:15.157615 IP 192.168.11.7.60000 > 192.168.11.2.52162: Flags [.], ack 3415559352, win 4117, options [nop,nop,TS val 2251886412 ecr 1908370916], length 0 03:14:15.158176 IP 192.168.11.7.60000 > 192.168.11.2.52162: Flags [F.], seq 3789677826, ack 3415559352, win 4117, options [nop,nop,TS val 2251886412 ecr 1908370916], length 0 03:14:15.158483 IP 192.168.11.2.52162 > 192.168.11.7.60000: Flags [.], ack 3789677827, win 4117, options [nop,nop,TS val 1908371012 ecr 2251886412], length 0

Slide 28

Slide 28 text

TCP状態遷移 ダイアグラム TCPコネクションの状 態は右図のようなダイ アグラムで表現され る. (RFC793 Fig. 6) TCB:  Transmission  Controll  Block

Slide 29

Slide 29 text

SYN_SENT ESTABLISHED ESTABLISHED SYN_RCVD LISTEN 確立の状態遷移

Slide 30

Slide 30 text

FIN_WAIT_1 TIME_WAIT CLOSED LAST_ACK CLOSE_WAIT FIN_WAIT_2 終了の状態遷移

Slide 31

Slide 31 text

状態遷移ダイアグラム [Host_A in ~] >> netstat -p tcp Active Internet connections Proto Recv-Q Send-Q Local Address Foreign Address (state) tcp4 0 0 192.168.11.2.52693 d.v.dropbox.com.https ESTABLISHED tcp4 0 0 192.168.11.2.52661 th-in-f189.1e100.https ESTABLISHED tcp4 0 0 localhost.60484 localhost.52660 ESTABLISHED tcp4 0 0 localhost.52660 localhost.60484 ESTABLISHED tcp4 0 0 192.168.11.2.52623 ec2-52-201-32-18.https CLOSE_WAIT tcp4 31 0 192.168.11.2.52620 162.125.80.3.https CLOSE_WAIT tcp4 0 0 192.168.11.2.52576 d.v.dropbox.com.https LAST_ACK tcp4 0 0 localhost.60484 localhost.52347 ESTABLISHED ・・・ netstatのstateはこのダイアグラム(RFC793)の各state

Slide 32

Slide 32 text

TCPコネクションのリセット TCPヘッダのRSTフラグは主にソケットに 正しくないパケットが到着した時に送られる ▣ 存在しないポートへのコネクション要求 (実践) □ UDPではICMPポート到達不可 ▣ 通信途中で相手ホストが強制終了し再起動 その後, そのコネクションにデータを送信した場合 ソケット:  送信元・先IPアドレス & ポート番号の組み合わせ  元々RFC793で使われ, ネットワークのAPI名に

Slide 33

Slide 33 text

TCPコネクションのリセット コネクションの通常の終了 (FIN)  すべてのデータが送られたあとにFINが送られ  データの消失がない. 正規リリースとも呼ばれる. コネクションの中断 (RST)  その時点のすべてのキュー(バッファ)データは破棄され  直ちにRSTが送られる. 中断リリースとも呼ばれる.  

Slide 34

Slide 34 text

TCPコネクションのリセット (実践) [Host_A in ~] >> telnet 192.168.11.7 60001 # Listenしてないポートへ接続要求 Trying 192.168.11.7... telnet: connect to address 192.168.11.7: Connection refused telnet: Unable to connect to remote host [Host_A in ~] >> tcpdump port 60001 -S -i en0 16:05:19.648152 IP 192.168.11.2.58560 > 192.168.11.7.60001: Flags [S], seq 3231406047, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1944503241 ecr 0,sackOK,eol], length 0 16:05:19.649798 IP 192.168.11.7.60001 > 192.168.11.2.58560: Flags [R.], seq 0, ack 3231406048, win 0, length 0

Slide 35

Slide 35 text

TCPコネクションのタイムアウト コネクションが確立できない場合の理由の一つに 通信が混雑してパケットがロスしたり 相手のホストがダウンしていることがある 規定の間隔をあけ, 規定の回数だけ接続を試みる

Slide 36

Slide 36 text

TCPコネクションのタイムアウト タイムアウト時の再送間隔(Linux):  kernelのinclude/net/tcp.hに  RTO(Retransmission Time Out)の定義  135〜140行目 SYNの再送回数(Linux):  kernel paramaterのnet.ipv4.tcp_syn_retries >> cat /etc/centos-release CentOS release 6.8 (Final) >> sysctl -a | grep tcp_syn_retries net.ipv4.tcp_syn_retries = 5 Mac(OSX)はわからなかった

Slide 37

Slide 37 text

TCPコネクションのタイムアウト (実践) [Host_A in ~] >> telnet 192.168.11.7 60000 # サーバのinterfaceを停止させたあと接続 Trying 192.168.11.7… 1# この↑場合は arpキャッシュが存在する必要あり telnet: connect to address 192.168.11.7: Operation timed out telnet: Unable to connect to remote host [Host_A in ~] >> tcpdump port 60001 -S -i en0 16:49:11.605727 IP 192.168.11.2.59964 > 192.168.11.7.60000: Flags [S], seq 118460038, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1947118980 ecr 0,sackOK,eol], length 0 16:49:12.607293 IP 192.168.11.2.59964 > 192.168.11.7.60000: Flags [S], seq 118460038, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1947119980 ecr 0,sackOK,eol], length 0

Slide 38

Slide 38 text

TCPコネクションのタイムアウト (実践) 16:49:13.610450 IP 192.168.11.2.59964 > 192.168.11.7.60000: # 先程のtcpdumpの続き Flags [S], seq 118460038, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1947120980 ecr 0,sackOK,eol], length 0 16:49:14.611601 IP 192.168.11.2.59964 > 192.168.11.7.60000: Flags [S], seq 118460038, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1947121980 ecr 0,sackOK,eol], length 0 16:49:15.612865 IP 192.168.11.2.59964 > 192.168.11.7.60000: Flags [S], seq 118460038, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1947122980 ecr 0,sackOK,eol], length 0 16:49:16.613307 IP 192.168.11.2.59964 > 192.168.11.7.60000: Flags [S], seq 118460038, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1947123980 ecr 0,sackOK,eol], length 0 16:49:18.614999 IP 192.168.11.2.59964 > 192.168.11.7.60000: Flags [S], seq 118460038, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1947125980 ecr 0,sackOK,eol], length 0

Slide 39

Slide 39 text

TCPヘッダオプション 最大40バイトまで 32bitの倍数になるように調整 → パディングとしてnop(No-Operation)が入る ▣ RFC 793:End of Options List ▣ RFC 793:No-Operation ▣ RFC 793:Maximum Segment Size ▣ RFC 1323:WSOPT (Window Scale Option) ▣ RFC 2018:SACK (Selective ACKnowledgement) □ SACK Permitted と SACKがある ▣ RFC 1323:TSOPT (Time Stamp Option)

Slide 40

Slide 40 text

TCPヘッダオプション # 3 way handshakeのSYNパケット 02:24:15.752057 IP 192.168.11.2.52162 > 192.168.11.7.60000: Flags [S], seq 3415559350, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1905379548 ecr 0,sackOK,eol], length 0   MSS  WSOPT  TSOPT  SACK Permmitted End of Option List TCPヘッダオプションはtcpdumpの options[〜]にカンマ区切りで記述される

Slide 41

Slide 41 text

Maximum Segment Size (MSS ) MSSはTCPが相手に送る1つのTCPデータの最大値 コネクション確立時に互いにMSSオプションによってそれぞれ のMSSを通知する (SYNパケットのみにMSSオプションは付加できる) 多くの場合はEthernetのMTU 1500バイトからIPヘッダと TCPヘッダの20+20バイトを引いた1460バイト IPフラグメンテーション回避はMSSを調整するよりも パスMTUディスカバリを用いて行われる(MTUを調整する)

Slide 42

Slide 42 text

Maximum Segment Size (MSS ) [Host_A in ~] >> ifconfig en0 inet en0: flags=8863 mtu 1500 [Host_B in ~] >> ifconfig en1 inet en1: flags=8863 mtu 1500 # 3 way handshakeのSYNパケット 02:24:15.752057 IP 192.168.11.2.52162 > 192.168.11.7.60000: Flags [S], seq 3415559350, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1905379548 ecr 0,sackOK,eol], length 0 02:24:15.756467 IP 192.168.11.7.60000 > 192.168.11.2.52162: Flags [S.], seq 3789677825, ack 3415559351, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 2248889040 ecr 1905379548,sackOK,eol], length 0

Slide 43

Slide 43 text

Window Scale Option ▣ windowフィールドの値を指定値分だけbitシフトする 値の範囲は0〜14 TCPヘッダのwindowフィールドは16bit → パケットが往復する間に64kのデータしか送れない → RTTが0.1secならスループットは約5Mbps このオプションを利用するとwindowの最大サイズが 約1Gbpsになる

Slide 44

Slide 44 text

Window Scale Option # 3 way handshakeのSYNパケット 02:24:15.752057 IP 192.168.11.2.52162 > 192.168.11.7.60000: Flags [S], seq 3415559350, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1905379548 ecr 0,sackOK,eol], length 0 65535 >> 5 = 2097152

Slide 45

Slide 45 text

Selective Acknowledgement ▣ 選択確認応答に用いる SACK Permitted:  3way handshake時に  SACKを使用できるかを  知らせる SACK:  ack番号を送る

Slide 46

Slide 46 text

Selective Acknowledgement ( 例 ) 1, 2, …. ,8パケットのうち4と7を損失した場合 ▣ SACKなし 1, 2, 3の確認応答だけ返す → 4〜8を再送 ▣ SACKあり 1, 2, 3, 5, 6, 8の確認応答を返す → 4と8のみ再送 5,6,8はSACKで返す

Slide 47

Slide 47 text

Time Stamp Option ▣ RTT値の算出に利用する TCPの再送時間はRTTを利用するが, 通常これはwindowサ イズごとに1パケットだけサンプリングして算出する → WSOPTによりwidowサイズが大きくなり   RTTの精度が悪くなる このオプションを利用することにより いつでもRTTを算出できるようになる

Slide 48

Slide 48 text

Time Stamp Option # 3 way handshakeのSYNパケット 02:24:15.752057 IP 192.168.11.2.52162 > 192.168.11.7.60000: Flags [S], seq 3415559350, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1905379548 ecr 0,sackOK,eol], length 0

Slide 49

Slide 49 text

Time Stamp Option ▣ PAWS (Protection Against Wrapped Sequence) に使用する 通信の高速化に伴い, Gbpsの速度においてはシーケンス番 号がわずか数十秒程度で一巡してしまい一意に識別できなく なるおそれがある そこでPAWSではシーケンス番号とタイムスタンプを 使うことで一意に識別する

Slide 50

Slide 50 text

最近?の話題 TCP Fast Open (RFC 7413, SPDY)  3 way handshake時にデータ送信を行う  初回接続時にTFO cookieをキャッシュ  次回接続時からSYNの段階からデータを送る  (接続の情報はTFO cookieでわかる) QUIC ( Quick UDP Internet Connections)  HTTPS on TCP では3 way handshakeに加えて  TLSのネゴシエーションもあって接続に時間がかかる  → そこまで含めてより良い通信方式をつくろう (POSTDの翻訳記事)

Slide 51

Slide 51 text

Reference & Credits ▣ W. Richard Stevens. 1993. TCP/IP Illustrated (Vol. 1): The Protocols. Addison-Wesley Longman Publishing Co., Inc., Boston, MA, USA. ▣ Presentation template by SlidesCarnival