# 機能設計書 122-アドレス情報解放

## 概要

本ドキュメントは、libuvが提供するDNSアドレス情報解放機能 `uv_freeaddrinfo()` の設計仕様を記述する。`uv_getaddrinfo()` で取得したアドレス情報のメモリを解放するための機能である。

### 本機能の処理概要

**業務上の目的・背景**：`uv_getaddrinfo()` により取得された `struct addrinfo` のリンクリストは、OSのDNSリゾルバが内部で確保したメモリ上に配置されている。このメモリを適切に解放しないとメモリリークが発生するため、専用の解放関数が必要である。libuvは標準Cライブラリの `freeaddrinfo()` をラップする形で本APIを提供している。

**機能の利用シーン**：`uv_getaddrinfo()` のコールバックで取得したアドレス情報を使用し終わった後に呼び出す。TCP/UDP接続先のアドレス解決が完了し、接続処理を開始した後が典型的な呼び出しタイミングである。

**主要な処理内容**：
1. 引数のNULLチェック
2. NULLでない場合、システムの `freeaddrinfo()` を呼び出してメモリを解放

**関連システム・外部連携**：OSの `freeaddrinfo()` 関数を直接呼び出す。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 26 | DNS | 主機能 | uv_freeaddrinfo()による解決結果メモリ解放のAPI定義 |

## 機能種別

リソース解放処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ai | struct addrinfo* | No | 解放対象のアドレス情報。NULLの場合は何もしない | - |

### 入力データソース

`uv_getaddrinfo()` のコールバックで受け取った `req->addrinfo` ポインタ。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| なし | void | 戻り値なし |

### 出力先

なし（メモリ解放のみ）。

## 処理フロー

### 処理シーケンス

```
1. NULLチェック
   └─ ai == NULLの場合は即座にreturn
2. メモリ解放
   └─ freeaddrinfo(ai) を呼び出してアドレス情報のリンクリストを解放
```

### フローチャート

```mermaid
flowchart TD
    A[uv_freeaddrinfo呼び出し] --> B{ai != NULL?}
    B -->|No| C[何もせず返却]
    B -->|Yes| D[freeaddrinfo ai]
    D --> E[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-122-1 | NULLセーフ | NULLポインタが渡された場合は何もしない | ai == NULL |
| BR-122-2 | 一回限り解放 | 同じポインタを二度解放してはならない（未定義動作となる） | 常時 |

### 計算ロジック

なし。

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

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| なし | - | 本関数はエラーを返さない | - |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

O(n)の処理（nはリンクリストの要素数）。通常は非常に高速で、ブロッキングの懸念はない。

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

二重解放（double free）を防ぐために、解放後にポインタをNULLに設定することをユーザー側で推奨する。

## 備考

- `uv_getaddrinfo()` で同期呼び出し（cb=NULL）した場合も、`req->addrinfo` は本関数で解放する必要がある
- 本関数は単純なラッパーだが、クロスプラットフォームの一貫したAPIを提供するために存在する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | **1008行目**: `uv_freeaddrinfo()`の関数シグネチャ。`struct addrinfo*`を引数に取るvoid関数 |

**読解のコツ**: `struct addrinfo` はPOSIX標準の構造体であり、`<netdb.h>`で定義される。リンクリスト形式で、`ai_next`メンバで次のエントリを指す。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | getaddrinfo.c | `src/unix/getaddrinfo.c` | **225-228行目**: `uv_freeaddrinfo()`の実装。NULLチェック後にシステムの`freeaddrinfo()`を呼ぶだけの極めてシンプルな関数 |

**主要処理フロー**:
1. **226行目**: `if (ai)` NULLチェック
2. **227行目**: `freeaddrinfo(ai)` システム関数呼び出し

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

```
uv_freeaddrinfo() [src/unix/getaddrinfo.c:225]
    │
    └── freeaddrinfo() [libc]
            └── アドレス情報のリンクリスト全体を解放
```

### データフロー図

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

struct addrinfo* ai ──▶ uv_freeaddrinfo() ──▶ メモリ解放（戻り値なし）
                              │
                         freeaddrinfo()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | API宣言 |
| getaddrinfo.c | `src/unix/getaddrinfo.c` | ソース | Unix系プラットフォームの実装 |
| getaddrinfo.c | `src/win/getaddrinfo.c` | ソース | Windowsプラットフォームの実装 |
