# 機能設計書 74-TCPソケット

## 概要

本ドキュメントは、BunのTCPソケット機能（Bun.listen、Bun.connect）の機能設計を記述する。TCPソケットは、低レベルのTCP通信を行うためのAPIを提供し、サーバーとクライアントの両方をサポートする。

### 本機能の処理概要

BunのTCPソケットAPIは、非同期イベント駆動型のTCP通信機能を提供する。Bun.listenでサーバーを起動し、Bun.connectでクライアント接続を行う。TLS（SSL）にも対応し、安全な通信が可能。

**業務上の目的・背景**：HTTPより低レベルの通信が必要な場面、カスタムプロトコルの実装、データベース接続、IoTデバイスとの通信など、TCPレベルの制御が必要なユースケースで使用される。Node.jsのnet/tlsモジュールの代替として、より高性能な実装を提供する。

**機能の利用シーン**：
- カスタムプロトコルサーバーの実装
- データベースクライアントの実装
- リアルタイム通信システム
- プロキシサーバーの構築
- IoTデバイスとの通信

**主要な処理内容**：
1. Bun.listenでTCPサーバーを起動（ポートバインド）
2. Bun.connectでTCPクライアント接続を確立
3. イベントハンドラ（onOpen, onData, onClose等）でデータ処理
4. socket.write()でデータ送信
5. TLS/SSLによる暗号化通信（オプション）

**関連システム・外部連携**：uWebSockets（uws）ライブラリを内部で使用。OSのネットワークスタック、TLS/SSL証明書と連携。

**権限による制御**：ポート1024未満はroot/管理者権限が必要。ファイアウォール設定に依存。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | コマンドライン/API経由での利用（画面なし） |

## 機能種別

ネットワーク通信 / 非同期I/O

## 入力仕様

### Bun.listen入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| hostname | string | No | バインドするホスト名 | デフォルト: 0.0.0.0 |
| port | number | Yes* | リッスンするポート番号 | 0-65535 |
| unix | string | Yes* | Unixソケットパス | hostname/portと排他 |
| socket | object | Yes | イベントハンドラ | 必須コールバック含む |
| tls | object | No | TLS設定 | 証明書/キー等 |
| data | any | No | ソケットに関連付けるデータ | - |

### Bun.connect入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| hostname | string | Yes* | 接続先ホスト名 | - |
| port | number | Yes* | 接続先ポート番号 | 0-65535 |
| unix | string | Yes* | Unixソケットパス | hostname/portと排他 |
| socket | object | Yes | イベントハンドラ | 必須コールバック含む |
| tls | object/boolean | No | TLS設定 | true or 詳細設定 |

### ソケットイベントハンドラ

| ハンドラ名 | 説明 | 引数 |
|-----------|------|------|
| onOpen | 接続確立時 | (socket) |
| onData | データ受信時 | (socket, data) |
| onClose | 接続終了時 | (socket) |
| onWritable | 書き込み可能時 | (socket) |
| onTimeout | タイムアウト時 | (socket) |
| onError | エラー発生時 | (socket, error) |
| onConnectError | 接続エラー時 | (socket, error) |
| onEnd | 相手がFIN送信時 | (socket) |
| onHandshake | TLSハンドシェイク完了時 | (socket, success, verifyError) |

### 入力データソース

API呼び出し時の引数として直接指定。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Listener | object | サーバーオブジェクト（Bun.listen） |
| Socket | object | ソケットオブジェクト（Bun.connect） |

### Socketオブジェクトメソッド

| メソッド | 説明 |
|---------|------|
| write(data) | データを送信 |
| end(data?) | FINを送信して接続終了 |
| close() | 即座に接続を閉じる |
| shutdown() | 書き込みを終了 |
| flush() | バッファをフラッシュ |
| pause() | データ受信を一時停止 |
| resume() | データ受信を再開 |
| ref() | イベントループ参照を保持 |
| unref() | イベントループ参照を解除 |

### 出力先

コールバック関数への引数として渡される。

## 処理フロー

### 処理シーケンス（サーバー）

```
1. Bun.listen()呼び出し
   └─ オプション検証、SocketConfig生成
2. SocketContextの作成
   └─ uws.SocketContextを初期化
3. ポートバインド
   └─ uws.ListenSocketを生成
4. 接続待機
   └─ イベントループで非同期に待機
5. クライアント接続時
   └─ onOpenコールバック呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[Bun.listen/connect] --> B[オプション検証]
    B --> C{TLS?}
    C -->|Yes| D[SSL Context作成]
    C -->|No| E[SocketContext作成]
    D --> E
    E --> F{listen/connect?}
    F -->|listen| G[ポートバインド]
    F -->|connect| H[接続開始]
    G --> I[接続待機]
    I --> J[onOpen]
    H --> J
    J --> K[データ送受信ループ]
    K --> L{データ受信?}
    L -->|Yes| M[onData]
    M --> K
    L -->|close| N[onClose]
    K --> O{送信?}
    O -->|Yes| P[socket.write]
    P --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-74-01 | ポート/Unixソケット排他 | hostname/portとunixは同時指定不可 | 常時 |
| BR-74-02 | TLSハンドシェイク | TLS接続時はハンドシェイク完了後にonOpen | tls指定時 |
| BR-74-03 | ハーフオープン | allowHalfOpen=trueで片方向クローズを許可 | オプション指定時 |
| BR-74-04 | バイナリタイプ | binaryType設定でデータ形式を指定 | 常時 |

### 計算ロジック

なし

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

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

なし（データベース操作を行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| EADDRINUSE | SystemError | ポートが使用中 | 別ポートを使用 |
| ECONNREFUSED | SystemError | 接続拒否 | サーバー状態を確認 |
| ETIMEDOUT | SystemError | 接続タイムアウト | ネットワークを確認 |
| InvalidArguments | TypeError | 不正な引数 | 引数を修正 |
| SSL_ERROR | Error | TLSエラー | 証明書を確認 |

### リトライ仕様

API側でのリトライ機能なし（呼び出し側で制御）

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

なし

## パフォーマンス要件

- uWebSocketsベースの高性能実装
- 非同期IOでメインスレッド非ブロック
- 大量同時接続をサポート

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

- TLS/SSL暗号化をサポート
- 証明書検証の設定が可能
- ALPNプロトコルネゴシエーション対応

## 備考

- Windowsでは名前付きパイプもサポート
- IPv4/IPv6両対応
- keepAlive設定でコネクション維持

---

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

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

### 推奨読解順序

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

ソケット関連の型定義と設定構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Handlers.zig | `src/bun.js/api/bun/socket/Handlers.zig` | イベントハンドラ構造（1-33行目） |
| 1-2 | Listener.zig | `src/bun.js/api/bun/socket/Listener.zig` | UnixOrHost union型（38-76行目） |

**読解のコツ**: HandlersにはonOpen、onData等のJSコールバック値が格納される。UnixOrHostでUnixソケット/TCP/FDを区別。

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

Bun.listenとBun.connectの実装。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Listener.zig | `src/bun.js/api/bun/socket/Listener.zig` | listen関数（101行目以降） |
| 2-2 | socket.zig | `src/bun.js/api/bun/socket.zig` | NewSocket型定義（41行目以降） |

**主要処理フロー**:
1. **101-121行目**: listen関数 - オプション検証、SocketConfig生成
2. **109行目**: SocketConfig.fromJSでJSオプションをパース
3. **119-120行目**: SSL設定の取得

#### Step 3: ソケット本体を理解する

NewSocket型によるTCP/TLSソケット実装。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | socket.zig | `src/bun.js/api/bun/socket.zig` | NewSocket構造体（41-150行目） |

**主要処理フロー**:
- **55-76行目**: ソケット状態フィールド
- **111-139行目**: doConnect関数 - 接続処理

#### Step 4: TLS処理を理解する

TLS/SSLの処理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | socket.zig | `src/bun.js/api/bun/socket.zig` | selectALPNCallback（17-33行目） |
| 4-2 | tls_socket_functions.zig | `src/bun.js/api/bun/socket/tls_socket_functions.zig` | TLS固有関数 |

**主要処理フロー**:
- **17-33行目**: ALPNプロトコル選択コールバック

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

```
Bun.listen(opts)
    │
    ├─ SocketConfig.fromJS()
    │      └─ Handlers.fromJS()
    │
    ├─ uws.SocketContext作成
    │      └─ SSL設定（TLS時）
    │
    └─ Listener作成
           ├─ uws.ListenSocket
           └─ 接続待機

Bun.connect(opts)
    │
    ├─ SocketConfig.fromJS()
    │
    └─ NewSocket.doConnect()
           ├─ Socket.connectAnon() [TCP]
           ├─ Socket.connectUnixAnon() [Unix]
           └─ Socket.fromFd() [FD]

接続確立後:
Socket
    ├─ onOpen → Handlers.callOpenHandler()
    ├─ onData → Handlers.callDataHandler()
    ├─ write() → Socket.write()
    └─ close() → Socket.close()
```

### データフロー図

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

Bun.listen(opts)   ───▶  SocketConfig.fromJS()
                         ├─ オプション検証
                         └─ Handlers生成
                                │
                                ▼
                         Listener作成              ───▶   Listener object
                         └─ ポートバインド

クライアント接続    ───▶  onOpen callback
                         └─ Socket作成            ───▶   Socket object

受信データ         ───▶  onData callback
                         └─ データ処理

socket.write(data) ───▶  送信処理               ───▶   ネットワーク送信
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| socket.zig | `src/bun.js/api/bun/socket.zig` | ソース | ソケット本体、NewSocket型 |
| Listener.zig | `src/bun.js/api/bun/socket/Listener.zig` | ソース | サーバーリスナー |
| Handlers.zig | `src/bun.js/api/bun/socket/Handlers.zig` | ソース | イベントハンドラ管理 |
| SocketAddress.zig | `src/bun.js/api/bun/socket/SocketAddress.zig` | ソース | アドレス表現 |
| tls_socket_functions.zig | `src/bun.js/api/bun/socket/tls_socket_functions.zig` | ソース | TLS固有関数 |
| us_socket_t.zig | `src/deps/uws/us_socket_t.zig` | ソース | uwsソケット型 |
| net.ts | `src/js/node/net.ts` | ソース | Node.js net互換レイヤー |
