# 機能設計書 47-TCPリセットクローズ

## 概要

本ドキュメントは、libuv の `uv_tcp_close_reset()` APIによりRSTパケットを送信してTCP接続をクローズする機能の設計を記述する。

### 本機能の処理概要

**業務上の目的・背景**：通常のTCP接続終了（FIN/ACK）では、TIME_WAIT状態が発生し、一定時間ポートが再利用できなくなる。uv_tcp_close_reset()はSO_LINGERオプションをl_onoff=1, l_linger=0に設定してRSTパケットを送信し、TCP接続を即座に切断する。これにより、TIME_WAIT状態を回避し、即座にリソースを解放できる。不正なクライアントの切断やアプリケーション異常時のクリーンアップに使用される。

**機能の利用シーン**：不正な接続の強制切断、サーバーシャットダウン時のリソース即時解放、テスト環境でのポート再利用、プロキシサーバーでのアップストリーム接続エラー時の処理に使用される。

**主要な処理内容**：
1. ストリームがシャットダウン中でないことを確認
2. SO_LINGERオプションを設定（l_onoff=1, l_linger=0）
3. uv_close()を呼び出してハンドルをクローズ

**関連システム・外部連携**：OSのソケットオプション（SO_LINGER）とclose()システムコールを使用する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 18 | TCP | 主機能 | uv_tcp_close_reset()によるRSTパケット送信クローズのAPI定義 |

## 機能種別

リソース管理（接続切断）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| handle | uv_tcp_t* | Yes | クローズ対象のTCPハンドル | シャットダウン中でないこと |
| close_cb | uv_close_cb | No | クローズ完了時のコールバック | NULL可 |

### 入力データソース

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

## 出力仕様

### 出力データ

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

### 出力先

コールバック関数への非同期通知。

## 処理フロー

### 処理シーケンス

```
1. シャットダウン状態チェック
   └─ uv__is_stream_shutting()でシャットダウン中かチェック → UV_EINVAL
2. FD取得
   └─ uv__stream_fd()でソケットFDを取得
3. SO_LINGER設定
   └─ setsockopt(SO_LINGER, {l_onoff=1, l_linger=0})
4. EINVAL特殊処理
   └─ Solaris/illumos/macOSではEINVALを無視（既にシャットダウン済みの可能性）
5. uv_close()呼び出し
   └─ ハンドルをクローズしてRSTパケットを送信
```

### フローチャート

```mermaid
flowchart TD
    A[uv_tcp_close_reset 呼び出し] --> B{ストリームシャットダウン中?}
    B -->|Yes| C[UV_EINVAL返却]
    B -->|No| D[FD取得]
    D --> E[setsockopt SO_LINGER設定]
    E --> F{setsockopt成功?}
    F -->|成功| G[uv_close呼び出し]
    F -->|EINVAL| H[errno=0にリセット]
    F -->|その他エラー| I[エラー返却]
    H --> G
    G --> J[0 を返す]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-47-1 | シャットダウン中禁止 | ストリームがシャットダウン処理中の場合はUV_EINVALを返す | uv__is_stream_shutting()がtrue |
| BR-47-2 | SO_LINGER設定 | l_onoff=1, l_linger=0でRSTパケット送信を強制する | 常時 |
| BR-47-3 | EINVAL許容 | Solaris/illumos/macOSではsetsockoptのEINVALを許容する | errno == EINVAL |

### 計算ロジック

特になし。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EINVAL | 状態エラー | ストリームがシャットダウン中 | シャットダウン完了後に呼び出す |
| UV__ERR(errno) | システムエラー | setsockopt()が失敗（EINVAL以外） | ソケットの状態を確認する |

### リトライ仕様

リトライは不要。

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

該当なし。

## パフォーマンス要件

即座に実行される。RSTパケットによりTIME_WAIT状態を回避できるため、ポートの即時再利用が可能。

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

RSTパケットによる切断は、通常のFIN/ACKによるグレースフルシャットダウンとは異なり、相手側にデータ損失を通知する。意図しないデータ損失が発生する可能性がある。

## 備考

- SO_LINGERを0に設定すると、close()時にRSTパケットが送信される。これは通常のFIN/ACKハンドシェイクをスキップする。
- Solaris, illumos, macOSでは既にシャットダウンされたソケットに対してsetsockopt(SO_LINGER)がEINVALを返す場合があるため、このエラーは無視される。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | uv_tcp_close_reset()のAPI宣言（637行目） |

**読解のコツ**: この関数はuv_close()のTCP特化版で、SO_LINGERを設定してからクローズする。struct lingerの構造を理解しておくとよい。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | tcp.c | `src/unix/tcp.c` | uv_tcp_close_reset()の実装（396-418行目） |

**主要処理フロー**:
1. **398行目**: struct linger l = { 1, 0 } の初期化（l_onoff=1, l_linger=0）
2. **401-402行目**: uv__is_stream_shutting()チェック → UV_EINVAL
3. **404行目**: uv__stream_fd()でFD取得
4. **405-414行目**: setsockopt(SO_LINGER)。EINVAL時は特殊処理（409-410行目）
5. **416行目**: uv_close()呼び出し

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

```
uv_tcp_close_reset() [src/unix/tcp.c:396]
    │
    ├─ uv__is_stream_shutting() [src/unix/stream.c]
    │
    ├─ uv__stream_fd() [マクロ]
    │
    ├─ setsockopt(SO_LINGER) [OS system call]
    │
    └─ uv_close() [src/uv-common.c]
```

### データフロー図

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

uv_tcp_t* handle      ──▶  uv_tcp_close_reset()       ──▶  戻り値(0/エラー)
uv_close_cb close_cb  ──▶  ├ シャットダウンチェック
                           ├ SO_LINGER設定(1,0)
                           └ uv_close()              ──▶  close_cb(handle)
                                                            (非同期コールバック)
```

### 関連ファイル一覧

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