Protocol Control Blocks -- TCP/IP Illustrated Volume 2

とりあえず読み始めるが、なにせ1000ページ超の本なのでまっすぐ読んでいくにはかなり無理がある。ので基本的にはINTROだけ熟読して、あとは興味の赴くままに徒然なるままに芋づる式読本メソッドでいくつもり。
で、早速ブロックダイアグラムを見ていてすぐに気になったのがudb, tcb などのPCBというやつ。なんで双方向リストなの? ソートしてるの? ねえねえ、とかすごく気になってきたのでまずはここ(p.713-)から。

22.1 Intro

PCB(Protocol Control Block)はプロトコル層(OSIモデルでいうネットワーク&トランスポート層)のデータ構造で、TCPおよびUDPソケットの情報を格納している。Internetプロトコルに関してはデータ構造としてこれと、TCP Control blockというのがあるらしい。UDPはエンドポイント情報だけあればよいので UDP Control Blockなんてものは無い。
PCBはローカル、リモート(foreign)それぞれのアドレス、ポート、ヘッダプロトタイプ(?)、オプション、あとルーティングテーブルの情報を持っているらしい(ソケット構造体もでは?)。
一方でTCP Control Block (TCBと略してないのは前述の小文字のtcbとややこしいからかな?)はステート情報:両方向のシーケンス番号とか、ウィンドウサイズとか、再送タイマとかをもっている。
この章で説明するのはInternet PCB。TCP Control Blockは後で(つまりUDPメインで)。

PCBまわり概要
  • socket()とかaccept()すると、ソケット層(OSIモデルでは、、、何になるんだろう?TCPならセッションだろうけど、、、)がfile構造体とsocket構造体を生成。file構造体のタイプとして DTYPE_SOCKETを、socket構造体のタイプはエンドがUDPTCPかに応じてSOCK_DGRAM or SOCK_STREAMに設定。
  • 次にプロトコル層をコール。UDPだったらInternet PCB(inpcb構造体)を作り、socket構造体のso_pcbをこれにリンク。逆にibpcbのinp_socketにsocket構造体をリンク
  • TCPの場合はUDPとおなじ処理の後にtcpcb構造体を作り、inpcb.inp_ppcb, tcpcb.t_inpcbで相互リンク。UDPの場合inpcb.inp_ppcbはNULLになる。
  • inpcbのアドレス・ポート情報が設定される。一瞬「ローカルっているの?」と思ってしまったけど、当然ながらマルチIFもありえるし127.0.0.1とかもあるから。かな。
  • inpcbはinp_next, inp_prevで双方向リンクされる(そう!ここが知りたい)。UDP, TCPそれぞれにグローバルな先頭をあらわす構造体がある(udb, tcb)。このグローバル構造体はinp_next, inp_prev, inp_port の3フィールドのみ有効。portは次のエフェメラルポート(ephemeralは短命なの意味で、要はウェルノウンじゃない一時的に割り当てられるポートのこと。ダイナミックとも言う)の値を示している。

このInternet PCB、利用されるのはTCP, UDP, raw IPのみ。IP, ICMP, IGMPは別。
rawIPについては32章(この章終わったら、次の目標点はTCPかこれ)。

PCBを確保/開放する関数はin_pcballoc(), in_pcbdetach()
というところで次から実際のコードに特攻するっぽい。乞うご期待。

22.2 Code Introduction

ファイル

PCB周りのファイルはCファイル、ヘッダファイルの1つずつ(単純)。

ファイル名 説明
netinet/in_pcb.h ヘッダ
netinet/in_pcb.c 実装ファイル
グローバル
zeroin_addr struct in_addr 32-bitのオールゼロアドレス
統計情報とか

BSDカーネルmalloc()はM_SOCKETとかM_PCBとかM_BUFとかの定数で種類を指定して確保してるそうな。なのでこれらをvmstat -m で見たりできるそうな。ちなみに netstat -m とするとmbufsの統計情報がわかるらしい。ナマい。
当然PCBはM_PCBで確保。

22.3 inpcb構造体

後で書く


GraphVizの練習がてら後から図を追加する予定。
ていうかこういうの面白いやっぱり。