# 機能設計書 34-TCP/IPプロトコルスタック

## 概要

本ドキュメントは、FreeBSDカーネルにおけるIPv4/IPv6のTCP/UDP/ICMP等コアネットワークプロトコル実装の機能設計書である。

### 本機能の処理概要

FreeBSDのTCP/IPプロトコルスタックは、ネットワーク通信の基盤となるプロトコル群をカーネル空間で実装したものである。IPv4およびIPv6の完全なプロトコルスタックを提供し、TCP、UDP、ICMP/ICMPv6、IGMP、SCTP等の上位プロトコルをサポートする。

**業務上の目的・背景**：TCP/IPプロトコルスタックはあらゆるネットワーク通信の基盤であり、Webサーバ、データベース、メール、SSH等のネットワークサービスが動作するために不可欠である。FreeBSDは歴史的に高性能なTCP/IP実装で知られ、多くの商用製品の基盤となっている。

**機能の利用シーン**：全てのネットワーク通信（ソケットAPI経由のアプリケーション通信、カーネル内部のプロトコル処理、ルーティング、マルチキャスト、IPsec等）で暗黙的に使用される。bsdinstallインストーラでのネットワーク設定画面でも直接関連する。

**主要な処理内容**：
1. IPv4パケットの送受信処理（IP入力/出力/フォワーディング）
2. IPv6パケットの送受信処理（IPv6入力/出力/フォワーディング）
3. TCP接続管理（3ウェイハンドシェイク、輻輳制御、再送制御、ウィンドウ管理）
4. UDP データグラム送受信
5. ICMP/ICMPv6メッセージ処理（エコー応答、到達不能通知等）
6. マルチキャスト（IGMP/MLD）
7. PCB（Protocol Control Block）管理
8. ソケット層との連携
9. FIB（Forwarding Information Base）によるルーティングテーブル参照
10. TCP輻輳制御アルゴリズム（cubic, newreno等）

**関連システム・外部連携**：ネットワークインタフェース層（sys/net/）、ファイアウォール（IPFW, PF）、IPsec（sys/netipsec/）、ルーティング、ソケットAPI

**権限による制御**：RAWソケットの作成にはroot権限またはnet.inet.ip.portrange設定に基づく。1024番未満のポートへのバインドにはroot権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | ネットワークインターフェース選択画面 | 補助機能 | IPv4/IPv6対応状態の確認 |
| 8 | IPv4設定確認画面 | 主機能 | IPv4使用有無の確認およびDHCP/スタティック設定モード選択 |
| 9 | IPv4スタティック設定画面 | 主機能 | IPアドレス・サブネットマスク・デフォルトルータの手動入力・設定処理 |
| 10 | IPv6設定確認画面 | 主機能 | IPv6使用有無の確認およびSLAAC/スタティック設定モード選択 |
| 11 | IPv6スタティック設定画面 | 主機能 | IPv6アドレス・デフォルトルータの手動入力・設定処理 |
| 12 | DNS設定画面 | 補助機能 | IPv4/IPv6ネームサーバの区別・設定 |

## 機能種別

プロトコル処理（パケット送受信 / 接続管理 / ルーティング）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ソケットファミリー | int | Yes | AF_INET / AF_INET6 | 有効なアドレスファミリー |
| ソケットタイプ | int | Yes | SOCK_STREAM / SOCK_DGRAM / SOCK_RAW | 有効なソケットタイプ |
| プロトコル | int | Yes | IPPROTO_TCP / IPPROTO_UDP等 | 有効なプロトコル番号 |
| IPアドレス | struct sockaddr_in/in6 | Yes | 送受信先アドレス | 有効なIP形式 |
| ポート番号 | uint16 | Yes | 送受信先ポート | 0-65535 |

### 入力データソース

ソケットAPI（userland）、ネットワークインタフェース（受信パケット）、カーネル内部呼び出し

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 送信パケット | mbuf | ネットワークインタフェースへ出力されるIPパケット |
| 受信データ | mbuf | ソケットバッファに格納される受信データ |
| ICMPメッセージ | mbuf | エラー通知・エコー応答等 |
| 統計情報 | struct | sysctl経由で参照可能な各種統計カウンタ |

### 出力先

ネットワークインタフェース（送信）、ソケットバッファ（受信）、sysctl統計

## 処理フロー

### 処理シーケンス

```
1. [受信パス] ネットワークインタフェースからパケット受信
   └─ ether_demux() → ip_input() / ip6_input()
2. IPヘッダの検証（チェックサム、バージョン、長さ等）
3. ルーティングテーブル参照（ローカル宛/フォワーディング判定）
4. 上位プロトコルへの配送
   ├─ TCP: tcp_input() → PCB検索 → 状態機械処理
   ├─ UDP: udp_input() → PCB検索 → ソケットバッファ格納
   └─ ICMP: icmp_input() → メッセージタイプ別処理
5. [送信パス] ソケットAPI経由でデータ送信
   └─ sosend() → tcp_output()/udp_output() → ip_output() → if_output()
```

### フローチャート

```mermaid
flowchart TD
    A[パケット受信] --> B[ip_input / ip6_input]
    B --> C{宛先判定}
    C -->|ローカル| D{プロトコル判定}
    C -->|フォワード| E[ip_forward]
    D -->|TCP| F[tcp_input]
    D -->|UDP| G[udp_input]
    D -->|ICMP| H[icmp_input]
    F --> I[TCP状態機械]
    I --> J[ソケットバッファ格納]
    G --> J
    H --> K[ICMP応答/通知]
    E --> L[ip_output]

    M[アプリケーション送信] --> N[sosend]
    N --> O{プロトコル}
    O -->|TCP| P[tcp_output]
    O -->|UDP| Q[udp_output]
    P --> R[ip_output / ip6_output]
    Q --> R
    R --> S[ネットワークインタフェース出力]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-34-01 | TCP状態遷移 | RFC 793に基づくTCP状態遷移（LISTEN→SYN_RCVD→ESTABLISHED等） | TCP接続時 |
| BR-34-02 | 輻輳制御 | 輻輳ウィンドウ制御によるフロー制御（cubic, newreno等選択可能） | TCP送信時 |
| BR-34-03 | IPフラグメンテーション | MTUを超えるパケットのフラグメント化/再構築 | パケット送受信時 |
| BR-34-04 | PMTU Discovery | Path MTU Discoveryによる最適MTUの検出 | TCP接続時 |

### 計算ロジック

TCPチェックサム: IPv4疑似ヘッダを含む16ビットワンズコンプリメントサム。in_cksum.cで実装。

## データベース操作仕様

該当なし（カーネル内部データ構造のみ）

### 操作別データベース影響一覧

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ECONNREFUSED | 接続拒否 | TCP RST受信 | 宛先サービスの確認 |
| ENETUNREACH | ネットワーク到達不能 | ルーティング不可 | ルーティング設定確認 |
| ETIMEDOUT | タイムアウト | TCP再送回数超過 | ネットワーク接続確認 |
| EADDRINUSE | アドレス使用中 | bind時にポート競合 | 使用ポートの確認 |

### リトライ仕様

TCPは自動再送機構を持つ。再送タイムアウト（RTO）は指数バックオフで増加し、最大再送回数はnet.inet.tcp.keepinit等のsysctlで制御。

## トランザクション仕様

TCP接続は3ウェイハンドシェイクで確立し、4ウェイハンドシェイク（またはRST）で切断する。各方向のデータストリームは独立にシーケンス番号で管理される。

## パフォーマンス要件

FreeBSDのTCP/IPスタックは高スループット・低遅延を目標として設計されている。TOE (TCP Offload Engine)、TSO (TCP Segmentation Offload)、LRO (Large Receive Offload)等のハードウェアオフロード機能をサポートする。

## セキュリティ考慮事項

- SYN flood攻撃対策（SYN cookies、SYN cache）
- TCP sequence number randomization
- IPsecとの統合（sys/netipsec/）
- rawソケットの権限制御（PRIV_NETINET_RAW）
- ポート番号範囲の制御（net.inet.ip.portrange.*）

## 備考

FreeBSDのTCP/IPスタックはBSD由来の参照実装として広く知られ、多くの商用OS・ネットワーク機器に採用されている。RACK/BBR等の最新輻輳制御アルゴリズムもサポートされている。

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | in.h | `sys/netinet/in.h` | struct sockaddr_in、IPPROTO_*定数 |
| 1-2 | in_pcb.h | `sys/netinet/in_pcb.h` | struct inpcb（Protocol Control Block）- 接続管理の中核 |
| 1-3 | tcp_var.h | `sys/netinet/tcp_var.h` | struct tcpcb（TCP制御ブロック）- TCP状態管理 |

**読解のコツ**: PCB（Protocol Control Block）がTCP/IPスタックの中心的なデータ構造であり、各接続の状態を保持する。inpcbがIP層、tcpcbがTCP層の情報を管理する。

#### Step 2: IP層の入出力を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ip_input.c | `sys/netinet/ip_input.c` | ip_input()関数 - IPv4パケット受信処理 |
| 2-2 | ip_output.c | `sys/netinet/ip_output.c` | ip_output()関数 - IPv4パケット送信処理 |
| 2-3 | in_fib.c | `sys/netinet/in_fib.c` | FIBルーティングテーブル参照 |

#### Step 3: TCP層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | tcp_input.c | `sys/netinet/tcp_input.c` | tcp_input() - TCP受信処理・状態遷移 |
| 3-2 | tcp_output.c | `sys/netinet/tcp_output.c` | tcp_output() - TCP送信処理 |
| 3-3 | tcp_usrreq.c | `sys/netinet/tcp_usrreq.c` | ソケットAPI連携 |

#### Step 4: UDP/ICMP層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | udp_usrreq.c | `sys/netinet/udp_usrreq.c` | UDP送受信処理 |
| 4-2 | ip_icmp.c | `sys/netinet/ip_icmp.c` | ICMPメッセージ処理 |

### プログラム呼び出し階層図

```
[受信パス]
ether_demux()
    +-- ip_input() [ip_input.c]
        +-- ip_forward() (フォワーディング)
        +-- tcp_input() [tcp_input.c]
        |   +-- tcp_do_segment() - TCP状態機械
        +-- udp_input() [udp_usrreq.c]
        +-- icmp_input() [ip_icmp.c]

[送信パス]
sosend() (ソケット層)
    +-- tcp_usr_send() [tcp_usrreq.c]
    |   +-- tcp_output() [tcp_output.c]
    |       +-- ip_output() [ip_output.c]
    +-- udp_send() [udp_usrreq.c]
        +-- ip_output() [ip_output.c]
            +-- if_output() (ネットワークインタフェース)
```

### データフロー図

```
[入力]                     [処理]                          [出力]

NIC受信パケット ──────> ip_input() ──> プロトコル判定
                              |
                         tcp_input() / udp_input()
                              |
                         PCB検索 ──> ソケットバッファ ──> アプリケーション

アプリケーション ──────> sosend() ──> tcp/udp_output()
                              |
                         ip_output() ──> ルーティング ──> if_output()
                              |
                         NIC送信パケット
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ip_input.c | `sys/netinet/ip_input.c` | ソース | IPv4入力処理 |
| ip_output.c | `sys/netinet/ip_output.c` | ソース | IPv4出力処理 |
| tcp_input.c | `sys/netinet/tcp_input.c` | ソース | TCP入力処理 |
| tcp_output.c | `sys/netinet/tcp_output.c` | ソース | TCP出力処理 |
| tcp_usrreq.c | `sys/netinet/tcp_usrreq.c` | ソース | TCPソケットインタフェース |
| udp_usrreq.c | `sys/netinet/udp_usrreq.c` | ソース | UDPソケットインタフェース |
| ip_icmp.c | `sys/netinet/ip_icmp.c` | ソース | ICMP処理 |
| in_pcb.c | `sys/netinet/in_pcb.c` | ソース | PCB管理 |
| in_pcb.h | `sys/netinet/in_pcb.h` | ヘッダ | PCB構造体定義 |
| in_fib.c | `sys/netinet/in_fib.c` | ソース | FIBルーティング参照 |
| in_cksum.c | `sys/netinet/in_cksum.c` | ソース | チェックサム計算 |
| in_proto.c | `sys/netinet/in_proto.c` | ソース | プロトコルスイッチ定義 |
| igmp.c | `sys/netinet/igmp.c` | ソース | IGMPマルチキャスト |
| in_mcast.c | `sys/netinet/in_mcast.c` | ソース | マルチキャスト管理 |
| cc/ | `sys/netinet/cc/` | ディレクトリ | 輻輳制御アルゴリズム群 |
