# 機能設計書 46-TCPアドレス取得

## 概要

本ドキュメントは、libuv の `uv_tcp_getsockname()` および `uv_tcp_getpeername()` APIによりTCPソケットのローカルアドレスおよびリモートアドレスを取得する機能の設計を記述する。

### 本機能の処理概要

**業務上の目的・背景**：TCP接続において、自身がバインドしているアドレス（ローカルアドレス）や接続先のアドレス（リモートアドレス）を取得する必要がある場面は多い。ログ出力、アクセス制御、接続情報の表示、プロトコルネゴシエーション等で使用される。uv_tcp_getsockname()はローカルアドレスを、uv_tcp_getpeername()はリモートアドレスを取得する。

**機能の利用シーン**：サーバーが自身のリスニングアドレスを確認する場合、クライアントの接続元アドレスを取得してアクセスログに記録する場合、エフェメラルポート（ポート0指定時に割り当てられたポート）を確認する場合などに使用される。

**主要な処理内容**：
1. delayed_errorの確認
2. uv__getsockpeername()を介してgetsockname()/getpeername()システムコールを呼び出し
3. 結果をsockaddr構造体に格納して返却

**関連システム・外部連携**：OSのgetsockname()/getpeername()システムコールを使用する。

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

## 関連画面

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

## 機能種別

情報取得

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| handle | const uv_tcp_t* | Yes | TCPハンドル | - |
| name | struct sockaddr* | Yes | アドレスを格納するバッファ | 十分なサイズであること |
| namelen | int* | Yes | バッファサイズ（入力）/実際のアドレスサイズ（出力） | - |

### 入力データソース

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

## 出力仕様

### 出力データ

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

### 出力先

引数を通じて直接返却。

## 処理フロー

### 処理シーケンス

```
1. delayed_errorチェック
   └─ delayed_errorが設定されている場合はそのエラーを返す
2. uv__getsockpeername()呼び出し
   └─ getsockname()/getpeername()システムコールを呼び出し
3. 結果格納
   └─ name/namelenに結果を格納
```

### フローチャート

```mermaid
flowchart TD
    A[uv_tcp_getsockname/getpeername 呼び出し] --> B{delayed_error?}
    B -->|Yes| C[delayed_error返却]
    B -->|No| D[uv__getsockpeername呼び出し]
    D --> E[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-46-1 | delayed_error優先 | delayed_errorが設定されている場合はシステムコール前にエラーを返す | handle->delayed_error != 0 |
| BR-46-2 | 共通実装 | getsocknameとgetpeernameは同一のuv__getsockpeername()で実装される | 常時 |

### 計算ロジック

特になし。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| delayed_error | 遅延エラー | bind時のエラーが遅延されている場合 | バインド処理を確認する |
| UV_EBADF | FDエラー | ソケットが無効 | ハンドルの初期化状態を確認する |
| UV_ENOTCONN | 未接続エラー | getpeernameで未接続の場合 | 接続後に呼び出す |

### リトライ仕様

リトライは不要。

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

該当なし。

## パフォーマンス要件

同期的に即座に完了する軽量な操作。

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

取得したアドレス情報の取り扱いに注意。IPアドレスは個人情報に該当する場合がある。

## 備考

- getsocknameはバインド後のローカルアドレスを取得する。ポート0でバインドした場合、OSが割り当てたポート番号を確認できる。
- getpeernameは接続確立後のリモートアドレスを取得する。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | uv_tcp_getsockname()（631-633行目）とuv_tcp_getpeername()（634-636行目）のAPI宣言 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | tcp.c | `src/unix/tcp.c` | uv_tcp_getsockname()の実装（368-379行目） |
| 2-2 | tcp.c | `src/unix/tcp.c` | uv_tcp_getpeername()の実装（382-393行目） |

**主要処理フロー**:
1. **372-373行目**: delayed_errorチェック
2. **375-378行目**: uv__getsockpeername()にgetsockname関数ポインタを渡して呼び出し
3. **386-387行目**: delayed_errorチェック（getpeername版）
4. **389-392行目**: uv__getsockpeername()にgetpeername関数ポインタを渡して呼び出し

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

```
uv_tcp_getsockname() [src/unix/tcp.c:368]
    │
    ├─ handle->delayed_error チェック
    │
    └─ uv__getsockpeername() [src/unix/core.c]
           │
           └─ getsockname() [OS system call]

uv_tcp_getpeername() [src/unix/tcp.c:382]
    │
    ├─ handle->delayed_error チェック
    │
    └─ uv__getsockpeername() [src/unix/core.c]
           │
           └─ getpeername() [OS system call]
```

### データフロー図

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

const uv_tcp_t* handle   ──▶  uv_tcp_getsockname/peername ──▶  戻り値(0/エラー)
struct sockaddr* name     ──▶  ├ delayed_errorチェック          name (アドレス情報)
int* namelen              ──▶  └ getsockname/getpeername        namelen (サイズ)
```

### 関連ファイル一覧

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