# 機能設計書 55-UDPアドレス取得

## 概要

本ドキュメントは、libuvにおけるUDPアドレス取得機能（`uv_udp_getsockname()` / `uv_udp_getpeername()`）の設計仕様を記述する。UDPソケットに関連付けられたローカルアドレスおよびリモートアドレスを取得する。

### 本機能の処理概要

**業務上の目的・背景**：UDPソケットのバインドアドレスや接続先アドレスを動的に取得する必要がある場面は多い。例えば、ポート0でバインドして自動割り当てされたポート番号を確認する場合や、接続済みUDPソケットのリモートアドレスを取得する場合に使用される。

**機能の利用シーン**：
- 自動割り当てされたポート番号の確認
- ログやデバッグ目的でのアドレス情報取得
- 接続済みUDPソケットのリモートアドレス確認
- ネットワーク監視やステータス表示

**主要な処理内容**：
1. getsockname: ハンドルに関連付けられたローカルアドレス（バインドアドレス）を取得
2. getpeername: 接続済みUDPソケットのリモートアドレスを取得
3. 内部的にはuv__getsockpeername()を通じてOSのgetsockname()/getpeername()を呼び出す

**関連システム・外部連携**：OSのソケットAPI（getsockname(), getpeername()）。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 21 | UDP | 主機能 | uv_udp_getsockname()/uv_udp_getpeername()によるアドレス取得のAPI定義 |

## 機能種別

情報取得 / ソケット照会

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| handle | const uv_udp_t* | Yes | UDPハンドル | 有効なハンドルであること |
| name | struct sockaddr* | Yes | アドレス格納先バッファ | NULLでないこと |
| namelen | int* | Yes | バッファサイズ（入出力） | 入力時は十分なサイズ、出力時は実サイズ |

### 入力データソース

ハンドルに関連付けられたOSソケット。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | 成功時は0、失敗時は負のエラーコード |
| name | struct sockaddr* | 取得されたアドレス情報 |
| namelen | int* | 実際のアドレスサイズ |

### 出力先

呼び出し元に提供されたバッファにアドレス情報が書き込まれる。

## 処理フロー

### 処理シーケンス

```
1. ハンドルからI/OウォッチャーのFDを取得
2. FDが有効でなければエラー
3. OS APIを呼び出し
   ├─ getsockname: getsockname(fd, name, namelen)
   └─ getpeername: getpeername(fd, name, namelen)
4. 結果を返却
```

### フローチャート

```mermaid
flowchart TD
    A[uv_udp_getsockname/getpeername] --> B[uv__getsockpeername]
    B --> C{FD有効?}
    C -->|No| D[UV_EINVAL返却]
    C -->|Yes| E[getsockname/getpeername呼び出し]
    E -->|成功| F[0返却]
    E -->|失敗| G[UV__ERR errno返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-55-01 | FD必須 | ソケットFDが関連付けられていない場合はエラー | 常時 |
| BR-55-02 | バッファサイズ | namelenは入力時にバッファサイズを指定し、出力時に実サイズが設定される | 常時 |
| BR-55-03 | getpeername制約 | uv_udp_connect()で接続されていない場合はgetpeernameはエラーを返す | getpeername使用時 |

### 計算ロジック

特になし。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EINVAL | パラメータ不正 | FDが無効 | ハンドルを正しく初期化してバインドする |
| UV_EBADF | 無効なFD | ソケットがクローズ済み | 有効なハンドルを使用する |
| UV_ENOTCONN | 未接続 | getpeernameで接続されていない場合 | uv_udp_connect()で接続する |

### リトライ仕様

リトライは不要。

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

該当なし。

## パフォーマンス要件

同期処理。OS APIの呼び出し時間のみ。

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

アドレス情報はセンシティブなデータとなりうるため、ログ出力時には注意が必要。

## 備考

- namelenにsizeof(struct sockaddr_storage)以上のサイズを指定することを推奨
- IPv4の場合はsizeof(struct sockaddr_in)、IPv6の場合はsizeof(struct sockaddr_in6)のサイズが返される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | **L755-760行目**: uv_udp_getpeername()/uv_udp_getsockname()のAPI宣言 |
| 1-2 | udp.c (unix) | `src/unix/udp.c` | **L1280-1298行目**: Unix実装。uv__getsockpeername()を呼び出す |
| 1-3 | udp.c (win) | `src/win/udp.c` | **L34-55行目**: Windows実装。同様にuv__getsockpeername()を呼び出す |

#### Step 2: 共通処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | core.c (unix) | `src/unix/core.c` | uv__getsockpeername()の実装。FD取得とOS API呼び出し |

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

```
uv_udp_getsockname(handle, name, namelen)
    └─ uv__getsockpeername(handle, getsockname, name, namelen)
           └─ getsockname(fd, name, namelen)  [システムコール]

uv_udp_getpeername(handle, name, namelen)
    └─ uv__getsockpeername(handle, getpeername, name, namelen)
           └─ getpeername(fd, name, namelen)  [システムコール]
```

### データフロー図

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

handle ──────────▶ uv__getsockpeername() ──────▶ name (sockaddr)
                         │                          namelen (実サイズ)
                   getsockname() or
                   getpeername()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | API宣言 |
| udp.c (unix) | `src/unix/udp.c` | ソース | Unix版ラッパー |
| udp.c (win) | `src/win/udp.c` | ソース | Windows版ラッパー |
| core.c (unix) | `src/unix/core.c` | ソース | uv__getsockpeername()共通実装 |
