TCPにおけるシーケンス番号
cf. RFC9293 3.4 Sequence Numbers
シーケンス番号とは、TCPで送られるデータの各オクテットに付けられた連番のことである。 これにより、受信者はそれぞれのオクテットを正しく受信できたことを送信者に伝えることができる。 この、「データ(の一部)を正しく受信できた」という応答を確認応答(acknowledgement)と呼ぶ。
なお、シーケンス番号は必ずしも0から始まるわけではなく、ランダムに生成される(cf. RFC9293 3.4.1 Initial Sequence Number Selection)。 これは、同じ相手と短時間で複数のコネクションを使ってデータを送った際、再送された前のコネクションに属するセグメントが遅れて届く場合があるからである。 異なるシーケンス番号範囲を使っていればこのようなセグメントを正しく拒絶することができる。
TCPセグメントにおけるシーケンス番号
TCPセグメント内という文脈においてシーケンス番号は、上記のシーケンス番号と少し定義が異なる。 といっても、データに付けられた連番という本質には変わりはない。
TCPセグメント内でのシーケンス番号は、「セグメントヘッダ中のシーケンス番号フィールドの値」のことである。 では、TCPセグメントヘッダ内でシーケンス番号フィールドの値は何かというと、
Sequence Number: 32 bits The sequence number of the first data octet in this segment (except when the SYN flag is set). If SYN is set, the sequence number is the initial sequence number (ISN) and the first data octet is ISN+1.
基本的には「セグメント内の最初のオクテットのシーケンス番号」である。 基本的と書いているのは、SYNフラグがセットされている時には「初期シーケンス番号(ISN)」を指すからである。
以降では、「シーケンス番号」と書いたときには「データに付けられた連番」のことを指し、「シーケンス番号フィールド値」と書いたときには「セグメント内の最初のオクテットのシーケンス番号」のことを指すこととする。
以上をまとめると、セグメントのシーケンス番号フィールド値がX
の時、そのセグメント中の最初のオクテットはデータ全体で見た場合X-ISN
オクテット目(0始まりではなく1始まり)となるということである。
TCPにおける確認応答番号
確認応答番号は、確認応答においてどのオクテットを正常に受信できたかを示すための番号である。
より詳細には、「確認応答のセグメントのヘッダ中の確認応答番号フィールドの値」のことを指す。 確認応答番号フィールドの値は、
Acknowledgment Number: 32 bits If the ACK control bit is set, this field contains the value of the next sequence number the sender of the segment is expecting to receive. Once a connection is established, this is always sent.
「その確認応答を送った受信者が次に受信するべきオクテットのシーケンス番号」である。
つまり、確認応答番号としてX
を送った場合には、シーケンス番号X-1
までの全てのオクテットを正しく受信することができたということを意味する。
SYN・FINフラグの考え方
通常のデータが入ったセグメントだけなら、上記の定義だけでシーケンス番号・確認応答番号を考えることができる。 しかし、SYNフラグやFINフラグが入ったセグメントにおいては、少し特殊な考え方をする必要がある。
それは、以下の引用のように「SYNフラグやFINフラグもシーケンス番号を割り当てられる」というものである。
We have taken advantage of the numbering scheme to protect certain control information as well. This is achieved by implicitly including some control flags in the sequence space so they can be retransmitted and acknowledged without confusion (i.e., one and only one copy of the control will be acted upon). Control information is not physically carried in the segment data space. Consequently, we must adopt rules for implicitly assigning sequence numbers to control. The SYN and FIN are the only controls requiring this protection, and these controls are used only at connection opening and closing. For sequence number purposes, the SYN is considered to occur before the first actual data octet of the segment in which it occurs, while the FIN is considered to occur after the last actual data octet in a segment in which it occurs. The segment length (SEG.LEN) includes both data and sequence space-occupying controls. When a SYN is present, then SEG.SEQ is the sequence number of the SYN.
cf. RFC9392 3.4. Sequence Numbers
これはつまり、データの最初のオクテットの直前にSYNの分、データの最後のオクテットの直後にFINの分のシーケンス番号が割り当てられているということである。
もちろんSYN・FINフラグが立っているからといって実際に送るデータのサイズが増えるわけではないので、これはあくまでもシーケンス番号空間の中で特別な扱いをしているだけである。
それでは実際に何オクテット分を占めているかというと、どちらも1オクテットとなる。
FIN A control bit (finis) occupying one sequence number, which indicates that the sender will send no more data or control occupying sequence space.
SYN A control bit in the incoming segment, occupying one sequence number, used at the initiation of a connection to indicate where the sequence numbering will start.