# 機能設計書 48-UDP初期化

## 概要

本ドキュメントは、libuv の `uv_udp_init()` および `uv_udp_init_ex()` APIによりUDPハンドルを初期化する機能の設計を記述する。

### 本機能の処理概要

**業務上の目的・背景**：UDPプロトコルによるデータグラム通信を行うために、まずUDPハンドルを初期化する必要がある。uv_udp_init()はデフォルト設定での初期化を行い、uv_udp_init_ex()はアドレスファミリの事前指定やrecvmmsgの使用指定などの拡張オプション付きで初期化する。TCPとは異なりコネクションレスのため、データ構造も異なる。

**機能の利用シーン**：DNSリゾルバ、VoIPアプリケーション、ゲームサーバー、ログ収集、マルチキャスト通信、IoTデバイスとの通信など、UDPベースの通信を開始する前に必ず呼び出される。

**主要な処理内容**：
1. フラグからアドレスファミリとextraフラグを分離
2. アドレスファミリの検証（AF_INET, AF_INET6, AF_UNSPEC）
3. ハンドル基盤の初期化（uv__handle_init）
4. I/Oウォッチャーの初期化
5. 送受信キューの初期化
6. アドレスファミリ指定時のソケット即時作成
7. UV_UDP_RECVMMSGフラグの設定（_ex版）

**関連システム・外部連携**：OSのソケットAPI（socket()）を使用してSOCK_DGRAMソケットを作成する。

**権限による制御**：特別な権限制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 21 | UDP | 主機能 | uv_udp_init()/uv_udp_init_ex()によるUDPハンドル初期化のAPI定義 |
| 35 | ネットワーク | 補助機能 | UDPソケット初期化のサンプル解説 |

## 機能種別

リソース初期化

## 入力仕様

### 入力パラメータ

#### uv_udp_init()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| loop | uv_loop_t* | Yes | イベントループ | 初期化済みであること |
| handle | uv_udp_t* | Yes | 初期化対象のUDPハンドル | - |

#### uv_udp_init_ex()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| loop | uv_loop_t* | Yes | イベントループ | 初期化済みであること |
| handle | uv_udp_t* | Yes | 初期化対象のUDPハンドル | - |
| flags | unsigned int | Yes | 下位8ビット: アドレスファミリ、上位ビット: UV_UDP_RECVMMSG等 | domain: AF_INET/AF_INET6/AF_UNSPEC、extra: UV_UDP_RECVMMSGのみ |

### 入力データソース

アプリケーションから直接呼び出される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | 成功時0、失敗時負のエラーコード |

### 出力先

戻り値として直接返却。初期化されたハンドルは以降のUDP操作で使用される。

## 処理フロー

### 処理シーケンス

```
1. uv_udp_init()の場合
   └─ uv_udp_init_ex(loop, handle, AF_UNSPEC)を呼び出す
2. フラグ解析
   ├─ domain = flags & 0xFF（アドレスファミリ）
   └─ extra_flags = flags & ~0xFF（拡張フラグ）
3. バリデーション
   ├─ domain: AF_INET, AF_INET6, AF_UNSPECのいずれか
   └─ extra_flags: UV_UDP_RECVMMSGのみ許可
4. uv__udp_init_ex()呼び出し（プラットフォーム固有）
   ├─ ソケット作成（domain != AF_UNSPECの場合）
   ├─ uv__handle_init()でハンドル基盤初期化
   ├─ alloc_cb, recv_cb = NULL
   ├─ send_queue_size, send_queue_count = 0
   ├─ I/Oウォッチャー初期化（uv__io_init）
   └─ 送受信キュー初期化（uv__queue_init）
5. RECVMMSGフラグ設定
   └─ extra_flags & UV_UDP_RECVMMSG → UV_HANDLE_UDP_RECVMMSG設定
```

### フローチャート

```mermaid
flowchart TD
    A[uv_udp_init / _ex 呼び出し] --> B{domain有効?}
    B -->|No| C[UV_EINVAL返却]
    B -->|Yes| D{extra_flags有効?}
    D -->|No| C
    D -->|Yes| E[uv__udp_init_ex呼び出し]
    E --> F{domain != AF_UNSPEC?}
    F -->|Yes| G[uv__socket でソケット作成]
    F -->|No| H[fd = -1]
    G --> I[ハンドル初期化]
    H --> I
    I --> J{UV_UDP_RECVMMSG?}
    J -->|Yes| K[UV_HANDLE_UDP_RECVMMSG設定]
    J -->|No| L[0 を返す]
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-48-1 | デフォルト初期化 | uv_udp_init()はAF_UNSPECでuv_udp_init_ex()を呼び出す | uv_udp_init()呼び出し時 |
| BR-48-2 | フラグ分離 | 下位8ビットがアドレスファミリ、上位ビットが拡張フラグ | 常時 |
| BR-48-3 | ソケット遅延作成 | domain=AF_UNSPEC時はソケットを作成せず、初回バインド/送信時に作成 | domain == AF_UNSPEC |
| BR-48-4 | recvmmsg有効化 | UV_UDP_RECVMMSGフラグでrecvmmsgの使用を指定できる | flags & UV_UDP_RECVMMSG |

### 計算ロジック

- domain = flags & 0xFF
- extra_flags = flags & ~0xFF

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EINVAL | バリデーションエラー | アドレスファミリが不正、または不正なフラグ | 正しいフラグを指定する |
| UV_EMFILE | リソースエラー | ソケット作成時にFD上限に達した | 不要なFDを閉じる |

### リトライ仕様

リトライは不要。

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

該当なし。

## パフォーマンス要件

同期的に即座に完了する軽量な操作。ソケット作成がある場合はシステムコールのオーバーヘッドが生じる。

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

特になし。

## 備考

- uv_udp_init()はAF_UNSPECを使用するため、ソケットは最初のバインドや送信操作まで作成されない（遅延作成）。
- UV_UDP_RECVMMSGフラグはLinux, FreeBSD, macOSで使用可能。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | uv_udp_s構造体（721-734行目）。send_queue_size, send_queue_count, UV_UDP_PRIVATE_FIELDSを含む |
| 1-2 | uv.h | `include/uv.h` | uv_udp_flags列挙型（656-711行目）。UV_UDP_IPV6ONLY, UV_UDP_REUSEADDR, UV_UDP_RECVMMSG等 |
| 1-3 | uv.h | `include/uv.h` | uv_udp_init()/uv_udp_init_ex()のAPI宣言（744-745行目） |

**読解のコツ**: uv_udp_sはuv_handle_tのサブクラスだが、uv_stream_tとは異なる継承系統。UV_UDP_PRIVATE_FIELDSにプラットフォーム固有のフィールドが含まれる。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | uv-common.c | `src/uv-common.c` | uv_udp_init()（370-372行目）とuv_udp_init_ex()（345-367行目）の実装 |

**主要処理フロー**:
1. **351-352行目**: domain = flags & 0xFF でアドレスファミリ抽出
2. **356-358行目**: extra_flags = flags & ~0xFF で拡張フラグ抽出、UV_UDP_RECVMMSGのみ許可
3. **360行目**: uv__udp_init_ex()呼び出し
4. **362-364行目**: UV_UDP_RECVMMSGフラグ設定

#### Step 3: プラットフォーム固有実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | udp.c | `src/unix/udp.c` | uv__udp_init_ex()（938-961行目）。ハンドル初期化とオプショナルなソケット作成 |

**主要処理フロー**:
- **944行目**: fd = -1 で初期化
- **945-948行目**: domain != AF_UNSPEC時にuv__socket(domain, SOCK_DGRAM, 0)でソケット作成
- **951行目**: uv__handle_init()でハンドル基盤初期化（UV_UDP型）
- **952-958行目**: 各フィールドの初期化（alloc_cb, recv_cb, send_queue_size等）

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

```
uv_udp_init() [src/uv-common.c:370]
    │
    └─ uv_udp_init_ex() [src/uv-common.c:345]
           │
           └─ uv__udp_init_ex() [src/unix/udp.c:938]
                  │
                  ├─ uv__socket() [src/unix/core.c] (domain != AF_UNSPEC時)
                  │
                  ├─ uv__handle_init() [src/uv-common.h]
                  │
                  ├─ uv__io_init() [src/unix/core.c]
                  │
                  └─ uv__queue_init() [src/queue.h] x2
```

### データフロー図

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

uv_loop_t* loop       ──▶  uv_udp_init_ex()          ──▶  戻り値(0/エラー)
uv_udp_t* handle      ──▶  ├ フラグ解析
unsigned int flags     ──▶  ├ ソケット作成(任意)
                            ├ ハンドル初期化
                            └ キュー初期化           ──▶  初期化済みhandle
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言、uv_udp_s構造体、uv_udp_flags列挙型 |
| uv-common.c | `src/uv-common.c` | ソース | uv_udp_init()/uv_udp_init_ex()共通実装 |
| udp.c (unix) | `src/unix/udp.c` | ソース | uv__udp_init_ex() Unix実装 |
| udp.c (win) | `src/win/udp.c` | ソース | Windows固有の初期化実装 |
| core.c | `src/unix/core.c` | ソース | uv__socket(), uv__io_init()の実装 |
