# 機能設計書 73-net

## 概要

本ドキュメントは、Nim標準ライブラリのnetモジュールの機能設計について記載する。本モジュールは高レベルのクロスプラットフォームソケットインターフェースを提供し、TCP/UDP通信およびSSL/TLS暗号化通信をサポートする。

### 本機能の処理概要

netモジュールは、ブロッキングソケットを使用したネットワーク通信のための高レベルAPIを提供する。TCP/UDPソケットの作成、接続、データ送受信、サーバー構築などの機能を実装している。SSL/TLSによる暗号化通信もサポートしている。

**業務上の目的・背景**：ネットワークアプリケーション開発において、低レベルのソケットAPIを直接使用することは複雑でエラーが発生しやすい。本モジュールは、nativesocketsモジュールを基盤として、より使いやすい高レベルのインターフェースを提供する。IPv4/IPv6両方をサポートし、クロスプラットフォーム（Windows/POSIX）で動作する。

**機能の利用シーン**：
- TCPクライアント/サーバーアプリケーションの開発
- UDPベースの通信プログラム
- HTTPSなどのSSL/TLS暗号化通信
- IPアドレスの解析・変換
- ネットワークツールの開発

**主要な処理内容**：
1. ソケットの作成と初期化（newSocket）
2. サーバーへの接続（connect）
3. サーバーソケットのバインドとリッスン（bindAddr、listen）
4. クライアント接続の受け入れ（accept、acceptAddr）
5. データの送受信（send、recv）
6. SSL/TLSコンテキストの管理（newContext、wrapSocket）
7. IPアドレスの解析（parseIpAddress）

**関連システム・外部連携**：nativesocketsモジュール、opensslモジュール（SSL使用時）と連携する。

**権限による制御**：OSレベルのソケット権限に依存。特権ポート（1024未満）へのバインドには管理者権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本モジュールはGUI/画面を持たないライブラリ機能 |

## 機能種別

ネットワーク通信 / ソケット操作 / 暗号化通信

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| domain | Domain | No | アドレスファミリー（AF_INET/AF_INET6） | デフォルト: AF_INET |
| sockType | SockType | No | ソケットタイプ（SOCK_STREAM/SOCK_DGRAM） | デフォルト: SOCK_STREAM |
| protocol | Protocol | No | プロトコル（IPPROTO_TCP/IPPROTO_UDP） | デフォルト: IPPROTO_TCP |
| buffered | bool | No | バッファリング有効化 | デフォルト: true |
| address | string | Yes | 接続先アドレス | 有効なホスト名またはIPアドレス |
| port | Port | Yes | ポート番号 | 0-65535 |

### 入力データソース

- ホスト名/IPアドレス文字列
- ポート番号
- SSL証明書ファイル（SSL使用時）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Socket | ref SocketImpl | ソケットオブジェクト |
| IpAddress | object | パース済みIPアドレス |
| SslContext | ref object | SSLコンテキスト |

### 出力先

- ネットワーク経由でのデータ送信
- ソケットオブジェクト経由でのデータ受信

## 処理フロー

### 処理シーケンス

```
1. ソケット作成（newSocket）
   └─ createNativeSocket呼び出し、Socketオブジェクト初期化
2. クライアント接続（connect）
   └─ getAddrInfo → nativesockets.connect
3. サーバー構築
   ├─ bindAddr: アドレスとポートをバインド
   ├─ listen: 接続待機開始
   └─ accept/acceptAddr: クライアント接続受け入れ
4. データ送受信
   ├─ send: データ送信
   └─ recv: データ受信（バッファリング対応）
5. SSL/TLS（オプション）
   ├─ newContext: SSLコンテキスト作成
   ├─ wrapSocket: ソケットをSSLでラップ
   └─ SSLハンドシェイク
6. ソケットクローズ（close）
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[newSocket]
    B --> C{用途}
    C -->|クライアント| D[connect]
    C -->|サーバー| E[bindAddr]
    D --> F[send/recv]
    E --> G[listen]
    G --> H[accept]
    H --> I[クライアントSocket取得]
    I --> F
    F --> J{SSL?}
    J -->|Yes| K[newContext]
    K --> L[wrapSocket]
    L --> M[SSLハンドシェイク]
    M --> N[暗号化通信]
    J -->|No| O[平文通信]
    N --> P[close]
    O --> P
    P --> Q[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-73-01 | バッファサイズ | デフォルトバッファサイズは4000バイト | buffered=true時 |
| BR-73-02 | SSL必須フラグ | SSL機能は-d:sslコンパイルフラグが必要 | SSL使用時 |
| BR-73-03 | 証明書検証 | Windows以外ではCA証明書の自動検索 | SSL検証有効時 |
| BR-73-04 | SafeDisconn | 切断エラーを安全に無視するフラグ | flagsに指定時 |

### 計算ロジック

IPアドレス解析（parseIpAddress）:
- `:`を含む → IPv6としてパース
- それ以外 → IPv4としてパース
- RFC 6943準拠の厳密なIPv4形式のみ許可

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | 本モジュールはデータベース操作を行わない |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| OSError | システムエラー | ソケット操作失敗 | osLastError()で詳細取得 |
| SslError | SSL/TLSエラー | 暗号化処理失敗 | ERR_error_string()で詳細取得 |
| TimeoutError | タイムアウト | 接続/受信タイムアウト | タイムアウト値を調整 |
| ValueError | 値エラー | 無効なIPアドレス形式 | 入力値を検証 |

### リトライ仕様

- SafeDisconnフラグ使用時、切断エラーで自動的にacceptを再試行
- SSL_MODE_AUTO_RETRYでSSL読み書きを自動リトライ

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

本モジュールはネットワーク通信を行うものであり、データベーストランザクション管理は行わない。

## パフォーマンス要件

- バッファリングによる効率的なデータ読み取り
- poll/selectによるタイムアウト制御
- TCP_NODELAYオプションによるNagleアルゴリズム無効化

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

- SSL/TLS暗号化通信のサポート
- 証明書検証（CVerifyPeer/CVerifyPeerUseEnvVars）
- SNI（Server Name Indication）サポート
- 現代的な暗号スイート（CiphersIntermediate/CiphersModern）
- PSK（Pre-Shared Key）認証サポート

## 備考

- 非同期ソケットにはasyncnetモジュールを使用
- Windows環境ではcacert.pemファイルが必要
- nimDisableCertificateValidation定義で証明書検証を無効化可能

---

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

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

### 推奨読解順序

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

まず、ソケットとSSLコンテキストのデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | net.nim | `lib/pure/net.nim` | SocketImpl型（157-175行目）: ソケットの内部構造 |
| 1-2 | net.nim | `lib/pure/net.nim` | IpAddress型（199-206行目）: IPアドレスの表現 |
| 1-3 | net.nim | `lib/pure/net.nim` | SslContext型（129-132行目）: SSLコンテキスト |
| 1-4 | net.nim | `lib/pure/net.nim` | SOBool列挙型（178-180行目）: ソケットオプション |

**読解のコツ**: SocketImplはwhen defineSslで条件コンパイルされるSSL関連フィールドを持つ。defineSslは-d:sslフラグで有効化される。

#### Step 2: ソケット作成を理解する

ソケットの生成処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | net.nim | `lib/pure/net.nim` | newSocket関数（265-281行目）: 既存ハンドルからの作成 |
| 2-2 | net.nim | `lib/pure/net.nim` | newSocket関数（298-311行目）: 新規ソケット作成 |

**主要処理フロー**:
1. **292-296行目**: createNativeSocketでOSソケットを作成
2. **270-278行目**: Socketオブジェクトを初期化
3. **280-281行目**: macOSではSO_NOSIGPIPEを設定

#### Step 3: 接続とサーバー構築を理解する

クライアント接続とサーバー構築の流れを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | net.nim | `lib/pure/net.nim` | bindAddr関数（1018-1038行目）: アドレスバインド |
| 3-2 | net.nim | `lib/pure/net.nim` | listen関数（1009-1016行目）: 接続待機 |
| 3-3 | net.nim | `lib/pure/net.nim` | acceptAddr関数（1040-1084行目）: 接続受け入れ |

**主要処理フロー**:
- **1032-1038行目**: getAddrInfoでアドレス解決、bindAddrでバインド
- **1015行目**: nativesockets.listenを呼び出し
- **1062-1084行目**: accept処理、SSL対応含む

#### Step 4: SSL/TLSを理解する

SSL/TLS暗号化通信の処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | net.nim | `lib/pure/net.nim` | newContext関数（624-734行目）: SSLコンテキスト作成 |
| 4-2 | net.nim | `lib/pure/net.nim` | wrapSocket関数（809-831行目）: ソケットのSSLラッピング |
| 4-3 | net.nim | `lib/pure/net.nim` | wrapConnectedSocket関数（856-887行目）: 接続済みソケットのラッピング |

**主要処理フロー**:
- **657-691行目**: TLSメソッド選択、暗号スイート設定
- **821-830行目**: SSL_newでハンドル作成、SSL_set_fdで関連付け
- **871-887行目**: SSL_connect/SSL_acceptでハンドシェイク

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

```
newSocket(domain, sockType, protocol)
    │
    └─ createNativeSocket() [nativesockets]
           │
           └─ Socket object creation

connect(socket, address, port)
    │
    ├─ getAddrInfo() [nativesockets]
    │
    └─ nativesockets.connect()

SSL Setup:
newContext(protVersion, verifyMode, certFile, keyFile)
    │
    ├─ SSL_CTX_new()
    │
    ├─ SSL_CTX_set_cipher_list()
    │
    └─ loadCertificates()

wrapSocket(ctx, socket)
    │
    ├─ SSL_new()
    │
    └─ SSL_set_fd()
```

### データフロー図

```
[クライアント]                [処理]                    [サーバー]

newSocket() ─────────────────────────────────────────▶ newSocket()
                                                       │
connect(addr, port) ◀─────────────────────────────────┤ bindAddr(port)
                                                       │
                                                       listen()
                                                       │
                    ◀──── TCP 3-way handshake ────────┤ accept()
                                                       │
send(data) ──────────────────────────────────────────▶ recv()
                                                       │
recv() ◀──────────────────────────────────────────────┤ send(response)
                                                       │
close() ──────────────────────────────────────────────┤ close()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| net.nim | `lib/pure/net.nim` | ソース | 高レベルソケットインターフェース |
| nativesockets.nim | `lib/pure/nativesockets.nim` | ソース | 低レベルソケット操作 |
| openssl.nim | `lib/wrappers/openssl.nim` | ソース | OpenSSLラッパー |
| ssl_config.nim | `lib/pure/ssl_config.nim` | ソース | SSL設定定数 |
| ssl_certs.nim | `lib/pure/ssl_certs.nim` | ソース | CA証明書検索 |
