85294


# 背景

[パケットキャプチャの教科書](https://www.sbcr.jp/product/4797390711/) を読んで、TCPについて勉強しています。

TCPの接続終了フェーズでは、FIN/ACKパケットを送ることが分かりました。

[code]

          TCP A                                                TCP B
    
      1.  ESTABLISHED                                          ESTABLISHED
    
      2.  (Close)
          FIN-WAIT-1  --> <SEQ=100><ACK=300><CTL=FIN,ACK>  --> CLOSE-WAIT
    
      3.  FIN-WAIT-2  <-- <SEQ=300><ACK=101><CTL=ACK>      <-- CLOSE-WAIT
    
      4.                                                       (Close)
          TIME-WAIT   <-- <SEQ=300><ACK=101><CTL=FIN,ACK>  <-- LAST-ACK
    
      5.  TIME-WAIT   --> <SEQ=101><ACK=301><CTL=ACK>      --> CLOSED
    
      6.  (2 MSL)
          CLOSED
    
                             Normal Close Sequence
    
                                   Figure 13.
    
[/code]

<https://datatracker.ietf.org/doc/html/rfc793#section-3.5> 引用

# 質問

なぜFINパケットでなくFIN/ACKパケットを送る必要があるのでしょうか？  
TCPの接続フェーズではSYNパケットを送りますが、それと同様にFINパケットのみ送るのが自然だと思いました。

# 参考

<https://kawasin73.hatenablog.com/entry/2019/08/31/153809#fn:1>

# 回答を受けた上での補足

ACKフラグについて、少し勘違いしていました。  
送信側のパケットにもACKフラグを付けることを、理解していませんでした。  
[Transmission Control Protocol -
Wikipedia](https://ja.wikipedia.org/wiki/Transmission_Control_Protocol)のACKフラグの説明を見て、理解しました。

> 確認応答番号フィールドが有効であることを示す。最初のSYNパケットを除く以降の全パケットでこのフラグをセットする。


CC BY-SA 4.0
2021-12-23T01:43:18.137
85286
2021-12-26T15:11:06.410
2021-12-26T15:11:06.410
19524
19524
question
tcp
TCPの接続終了フェーズでは、なぜFINパケットでなくFIN/ACKパケットを最初に送るのですか？


TCPの接続確立の際は、最初にSYNだけというのは理解されている通りです。  
そして、その後は最後までACKを付け続けるルールと理解すれば、FINだからといってACKのがあることに違和感はないかと。


CC BY-SA 4.0
2021-12-23T03:48:47.000
85289
2021-12-23T03:48:47.000
2238
85286
answer


> なぜFINパケットでなくFIN/ACKパケットを送る必要があるのでしょうか？

FIN/ACK送る必要がある, 訳ではなく, たまたま観測したパケットがそういう環境だったのでしょう  
別に, FIN => FIN/ACK => ACK でも構わないはず  
(FINに対し いきなり RST 送りつける OS もある(今もそうなのか不明))

> TCPの接続フェーズではSYNパケットを送りますが、それと同様にFINパケットのみ送るのが自然だと思いました。

同じ 3ウェイ・ハンドシェイクという意味かもだけど, 状況が異なるので自然ではありません

  * フロー制御行ってるので, connection後のパケットでは大抵 ACK付けるはず  
(ACK付けないパケットは, 受信した分を(未だ)受け付けない, ようなもの)

  * 片方だけ connection閉じて(送信のみとか受信のみとか), 少しの間維持する場合もある。このとき片側で FIN/ACKのみ使用して, その後もパケット受け付け(あるいは送りつけ)行うことも


CC BY-SA 4.0
2021-12-23T05:57:02.683
85294
2021-12-23T05:57:02.683
43025
85286
answer


[TCP/IP
プロトコルスタックを自作した方のブログで言及](https://kawasin73.hatenablog.com/entry/2019/08/31/153809)されていました。

[3.9 Event Processing の SEGMENT
ARRIVES](https://datatracker.ietf.org/doc/html/rfc793#page-72)には

[code]

        fifth check the ACK field,
    
          if the ACK bit is off drop the segment and return
    
    ～～～
    
        eighth, check the FIN bit,
    
          Do not process the FIN if the state is CLOSED, LISTEN or SYN-SENT
          since the SEG.SEQ cannot be validated; drop the segment and
          return.
    
[/code]

となっていて、`FIN`パケットには`ACK`も含めておかないと、step 8に到達する前のstep 5で破棄されてしまうそうです。


CC BY-SA 4.0
2021-12-23T11:40:43.337
85303
2021-12-23T11:40:43.337
4236
85286
answer