# 機能設計書 143-IPアドレス文字列化

## 概要

本ドキュメントは、libuvのネットワークユーティリティにおけるsockaddr構造体からIPアドレス文字列への変換機能 `uv_ip4_name()` / `uv_ip6_name()` / `uv_ip_name()` の設計仕様を定義する。

### 本機能の処理概要

`uv_ip4_name()`、`uv_ip6_name()`、`uv_ip_name()` は、バイナリ形式のIPアドレスを含むsockaddr構造体を受け取り、人間が読める文字列形式（"192.168.1.1"、"::1" 等）に変換する関数群である。

**業務上の目的・背景**：ネットワーク通信において、接続元・接続先のIPアドレスをログ出力やデバッグ情報として表示する必要がある。sockaddr構造体に格納されたバイナリ形式のアドレスを文字列に変換する機能は、ネットワークアプリケーションの可視化・デバッグに不可欠である。`uv_ip_name()` はアドレスファミリを自動判定するジェネリック版として提供される。

**機能の利用シーン**：TCP/UDPの `getsockname()`/`getpeername()` で取得したsockaddr構造体のアドレスを表示する場合、接続ログの出力、デバッグ時のアドレス情報表示などに使用される。

**主要な処理内容**：
1. sockaddr構造体からIPアドレスのバイナリデータを取得する
2. `uv_inet_ntop()` を呼び出してバイナリ→文字列変換を実行する
3. `uv_ip_name()` はsockaddr構造体のsa_familyフィールドでアドレスファミリを自動判定する

**関連システム・外部連携**：内部で `uv_inet_ntop()` を呼び出す（No.144 inet変換に対応）。

**権限による制御**：権限による実行可否の制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 29 | その他ユーティリティ | 主機能 | uv_ip4_name()/ip6_name()/ip_name()によるsockaddr→文字列変換のAPI定義 |

## 機能種別

データ変換処理（バイナリアドレス→文字列変換）

## 入力仕様

### 入力パラメータ

#### uv_ip4_name()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| src | const struct sockaddr_in* | Yes | IPv4アドレスを含むsockaddr_in構造体 | NULLの場合は未定義動作 |
| dst | char* | Yes | 変換結果の文字列格納先バッファ | 十分なサイズが必要（最低16バイト） |
| size | size_t | Yes | dstバッファのサイズ | 0の場合UV_ENOSPC |

#### uv_ip6_name()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| src | const struct sockaddr_in6* | Yes | IPv6アドレスを含むsockaddr_in6構造体 | NULLの場合は未定義動作 |
| dst | char* | Yes | 変換結果の文字列格納先バッファ | 十分なサイズが必要（最低46バイト） |
| size | size_t | Yes | dstバッファのサイズ | 0の場合UV_ENOSPC |

#### uv_ip_name()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| src | const struct sockaddr* | Yes | IPアドレスを含むsockaddr構造体 | NULLの場合は未定義動作 |
| dst | char* | Yes | 変換結果の文字列格納先バッファ | 十分なサイズが必要 |
| size | size_t | Yes | dstバッファのサイズ | 0の場合UV_ENOSPC |

### 入力データソース

呼び出し元から直接渡されるパラメータ。通常は `uv_tcp_getsockname()` や `uv_udp_getsockname()` 等の結果。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | 成功時0、失敗時はlibuvエラーコード |
| dst | char* | IPアドレス文字列（例: "192.168.1.1"、"::1"） |

### 出力先

呼び出し元が提供するバッファ（dst）に文字列が格納される。

## 処理フロー

### 処理シーケンス

```
[uv_ip4_name]
1. uv_inet_ntop(AF_INET, &src->sin_addr, dst, size) を呼び出す
   └─ 変換結果をそのまま返却

[uv_ip6_name]
1. uv_inet_ntop(AF_INET6, &src->sin6_addr, dst, size) を呼び出す
   └─ 変換結果をそのまま返却

[uv_ip_name]
1. src->sa_familyを確認
   ├─ AF_INET → uv_inet_ntop(AF_INET, ...) を呼び出す
   ├─ AF_INET6 → uv_inet_ntop(AF_INET6, ...) を呼び出す
   └─ その他 → UV_EAFNOSUPPORT を返却
```

### フローチャート

```mermaid
flowchart TD
    A[uv_ip_name 呼び出し] --> B{src->sa_family}
    B -->|AF_INET| C[uv_inet_ntop AF_INET で変換]
    B -->|AF_INET6| D[uv_inet_ntop AF_INET6 で変換]
    B -->|その他| E[UV_EAFNOSUPPORT を返却]
    C --> F[結果を返却]
    D --> F
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-143-01 | バッファサイズ確認 | バッファサイズが不足する場合UV_ENOSPCを返す | dst sizeが出力文字列長未満の場合 |
| BR-143-02 | アドレスファミリ判定 | uv_ip_name()はsa_familyでIPv4/IPv6を自動判定 | 常時 |
| BR-143-03 | IPv6短縮表記 | IPv6アドレスは::による短縮表記で出力される | 連続する0グループが存在する場合 |

### 計算ロジック

IPv4: 各オクテットを10進数でドット区切り。IPv6: 16ビットグループを16進数でコロン区切り、最長ゼロ連続を::で短縮。

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

該当なし（データベース操作は行わない）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_ENOSPC | バッファ不足 | dstバッファサイズが変換結果より小さい | 十分なサイズのバッファを用意する（IPv4:16, IPv6:46） |
| UV_EAFNOSUPPORT | 非サポート | uv_ip_name()でAF_INET/AF_INET6以外が指定された | IPv4またはIPv6のsockaddrを使用する |

### リトライ仕様

リトライは不要。

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

該当なし。

## パフォーマンス要件

O(1)定数時間（IPv4）。IPv6はアドレス内容に依存するがO(1)とみなせる。メモリアロケーションなし。

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

- バッファサイズが適切に検証され、バッファオーバーフローは発生しない
- 出力文字列にセキュリティ上のリスクはない

## 備考

- `uv_ip4_name()` と `uv_ip6_name()` は `uv_inet_ntop()` への単純なラッパー
- `uv_ip_name()` はアドレスファミリ自動判定のジェネリック版
- IPv4の最大文字列長は15文字（+NULL終端で16バイト）
- IPv6の最大文字列長は45文字（+NULL終端で46バイト）

---

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

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

### 推奨読解順序

#### Step 1: API宣言を確認する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | 3関数のAPI宣言（L1783-1785） |

**読解のコツ**: uv_ip4_name/uv_ip6_nameは型固定、uv_ip_nameは汎用sockaddr*を受け取るジェネリック版。

#### Step 2: 共通実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | uv-common.c | `src/uv-common.c` | 3関数の実装 |

**主要処理フロー**:
1. **300-302行目**: `uv_ip4_name()` - `uv_inet_ntop(AF_INET, &src->sin_addr, dst, size)` を直接呼び出す1行のラッパー
2. **305-307行目**: `uv_ip6_name()` - `uv_inet_ntop(AF_INET6, &src->sin6_addr, dst, size)` を直接呼び出す1行のラッパー
3. **310-321行目**: `uv_ip_name()` - `src->sa_family` でswitch文によりAF_INET/AF_INET6を判定し、それぞれの `uv_inet_ntop()` に委譲。デフォルトケースは `UV_EAFNOSUPPORT` を返す

#### Step 3: inet_ntop変換の下位層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | inet.c | `src/inet.c` | uv_inet_ntop() の実装 |

**主要処理フロー**:
- **35-45行目**: `uv_inet_ntop()` - AF_INETならinet_ntop4()、AF_INET6ならinet_ntop6()を呼び出す
- **48-59行目**: `inet_ntop4()` - snprintfで "%u.%u.%u.%u" 形式に変換
- **62-143行目**: `inet_ntop6()` - 最長ゼロ連続を::で短縮する複雑なフォーマット処理

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

```
uv_ip4_name(src, dst, size)              [公開API - src/uv-common.c L300]
    └─ uv_inet_ntop(AF_INET, ...)        [公開API - src/inet.c L35]
         └─ inet_ntop4(src, dst, size)    [内部関数 - src/inet.c L48]

uv_ip6_name(src, dst, size)              [公開API - src/uv-common.c L305]
    └─ uv_inet_ntop(AF_INET6, ...)       [公開API - src/inet.c L35]
         └─ inet_ntop6(src, dst, size)    [内部関数 - src/inet.c L62]

uv_ip_name(src, dst, size)               [公開API - src/uv-common.c L310]
    ├─ AF_INET  → uv_inet_ntop(AF_INET, ...)
    ├─ AF_INET6 → uv_inet_ntop(AF_INET6, ...)
    └─ default  → UV_EAFNOSUPPORT
```

### データフロー図

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

sockaddr_in*/in6*/sockaddr* ──▶ uv_ip_name()          ──▶ char* dst (文字列)
size_t size ───────────────▶   └─ uv_inet_ntop()         int 戻り値
                                    ├─ inet_ntop4()
                                    └─ inet_ntop6()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言 (L1783-1785) |
| uv-common.c | `src/uv-common.c` | ソース | uv_ip4_name()/uv_ip6_name()/uv_ip_name() 実装 (L300-321) |
| inet.c | `src/inet.c` | ソース | uv_inet_ntop() および内部変換関数 (L35-143) |
