トランスポート層
| 項目 | 値 |
|---|---|
| トランスポート | TCP(永続接続) |
| デフォルトポート | 5225 |
| ソケットオプション | TCP_NODELAY有効 — Nagleアルゴリズムによる遅延なしで小さいパケットも即座に送信 |
| TLS | 任意 — サーバーに証明書が設定されていれば、ストリーム全体が片方向TLS(サーバー認証)で包まれる |
| エンコーディング | 固定長バイナリフィールド + UTF-8のキー。整数はビッグエンディアン(ネットワークバイトオーダー) |
| フレーム終端 | \nバイト1つ。\rの処理はなし |
| 空フレーム | 単独の\n(op位置が\n)はキープアライブとして黙って無視される |
| 最大フレームサイズ | 192バイト — opを含み\nを除く(超過 → E line_too_long後に接続終了) |
| パイプライニング | 可能 — レスポンスはリクエストと異なる順序で届くことがある |
| アイドルタイムアウト | なし — サーバーは静かな接続を自ら閉じることはない |
| フレーム進行時間 | opの最初の1 byteからfixed headerとLFまで最大5秒。部分送信でconnectionを無限占有できない |
接続確立の順序
- TCP接続
- サーバーがTLSを有効にしている場合はTLSハンドシェイク — TLSサーバーに平文で接続すると この段階で切断される
- 認証ハンドシェイクを1回
- 以降はロックプロトコルのフレーム交換
フレーミングのルール
すべてのメッセージは1フレーム = 1行です。
[ op: 1バイト ][ opごとの固定ヘッダー ][ 可変長ボディ ] \n受信側はopを見て、先に固定ヘッダーをバイト数分読み取り、その後で初めて\nを探す 必要があります。固定ヘッダーはバイナリであり、値として0x0A(\n)を含みうるためです (例: lease=10 → 0A)。\nの走査は末尾のキー/テキスト部分にのみ適用されます。
| 方向 | op | 固定ヘッダー |
|---|---|---|
| クライアント → サーバー | A | 10 bytes (wait:u8 + lease:u8 + owner:u64 BE) |
| クライアント → サーバー | R | 8 bytes (token:u64 BE) |
| サーバー → クライアント | A | 16 bytes (token:u64 BE + owner:u64 BE) |
| サーバー → クライアント | T · B | 8 bytes (owner:u64 BE) |
| サーバー → クライアント | R · N | 8 bytes (token:u64 BE) |
| サーバー → クライアント | M · L · E | 0 bytes (address/reason UTF-8 text) |
frameが192 bytesを超えるかmalformedなら、サーバーは可能な場合Eをflushした後に接続を閉じます。クライアントもmalformed・oversized・未知op・相関不能なEをconnection-fatalとして扱います。このsessionで1 byteでも送信されたacquireは自動再試行せず、確定応答がなければIndeterminateです。
用語
- フレーム — 連続したバイトストリーム(TCP)を「1つのメッセージ」として区切る単位。 このプロトコルでは、
\nで終わる1行が1フレームです。 - ビッグエンディアン — 整数の最上位バイトを先に書き込むバイト順序。ネットワーク プロトコルの標準であるため、ネットワークバイトオーダーとも呼ばれます。
- パイプライニング — 前のレスポンスを待たずに次のリクエストを送ること。往復 レイテンシを重ねることでスループットが上がります。
- キープアライブ — 接続がまだ生きていることを知らせるために定期的に送る、意味を 持たない信号。ここでは空フレーム(
\n)がその役割を担います。