# 機能設計書 53-UDP同期送信試行

## 概要

本ドキュメントは、libuvにおけるUDP同期送信試行機能（`uv_udp_try_send()` / `uv_udp_try_send2()`）の設計仕様を記述する。キューイングなしで同期的にUDPデータグラムの送信を試行する。

### 本機能の処理概要

**業務上の目的・背景**：低レイテンシが要求される通信シナリオでは、非同期送信のキューイングオーバーヘッドを避けたい場合がある。本機能は、送信キューが空の場合にのみ即座に送信を試行し、送信バッファフルの場合はUV_EAGAINを返すことで、呼び出し側に制御を委ねる。`uv_udp_try_send2()`は複数メッセージの一括送信をサポートする拡張版である。

**機能の利用シーン**：
- 低レイテンシが求められるリアルタイム通信
- 送信可能な場合のみ送信を行うポーリングベースの設計
- 複数の小さなメッセージを一括送信する場合（try_send2）
- キューイングオーバーヘッドを避けたいパフォーマンス最適化

**主要な処理内容**：
1. 入力パラメータの検証
2. 送信キューが空であることの確認（空でなければUV_EAGAIN）
3. 必要に応じた遅延バインドの実行
4. sendmsg()/sendmmsg()による同期的な送信
5. 送信バイト数またはエラーコードの返却

**関連システム・外部連携**：OSのソケットAPI（sendmsg/sendmmsg）と直接連携。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 21 | UDP | 主機能 | uv_udp_try_send()/uv_udp_try_send2()による同期的UDP送信試行のAPI定義 |

## 機能種別

データ送信 / 同期I/O

## 入力仕様

### 入力パラメータ

#### uv_udp_try_send()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| handle | uv_udp_t* | Yes | UDPハンドル | handle->typeがUV_UDPであること |
| bufs | const uv_buf_t[] | Yes | 送信データバッファ配列 | nbufs >= 1 |
| nbufs | unsigned int | Yes | バッファ数 | 1以上 |
| addr | const struct sockaddr* | 条件付き | 送信先アドレス | 接続済みの場合はNULL |

#### uv_udp_try_send2()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| handle | uv_udp_t* | Yes | UDPハンドル | FDが有効であること |
| count | unsigned int | Yes | 送信メッセージ数 | 1以上 |
| bufs | uv_buf_t*[] | Yes | バッファ配列の配列 | countと同サイズ |
| nbufs | unsigned int[] | Yes | 各メッセージのバッファ数 | countと同サイズ |
| addrs | struct sockaddr*[] | Yes | 送信先アドレス配列 | countと同サイズ |
| flags | unsigned int | Yes | フラグ | 0のみ許可 |

### 入力データソース

アプリケーションから直接渡される送信データバッファと送信先アドレス。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 (try_send) | int | 成功時は送信バイト数、失敗時は負のエラーコード |
| 戻り値 (try_send2) | int | 成功時は送信メッセージ数、失敗時は負のエラーコード |

### 出力先

送信データはOSのソケットを通じてネットワークに即座に送出される。

## 処理フロー

### 処理シーケンス

```
[uv_udp_try_send]
1. 事前チェック (uv__udp_check_before_send)
   └─ 接続状態/アドレス整合性チェック
2. nbufsが1未満ならUV_EINVAL
3. 送信キューが空でなければUV_EAGAIN
4. addr指定時は遅延バインド実行
5. uv__udp_sendmsg1()で同期送信
6. 成功時は送信バイト数を返却

[uv_udp_try_send2]
1. countが1未満ならUV_EINVAL
2. flagsが0でなければUV_EINVAL
3. 送信キューが空でなければUV_EAGAIN
4. uv__udp_try_send2() → uv__udp_sendmsgv()で一括送信
5. 成功時は送信メッセージ数を返却
```

### フローチャート

```mermaid
flowchart TD
    A[uv_udp_try_send呼び出し] --> B[uv__udp_check_before_send]
    B -->|エラー| Z1[エラーコード返却]
    B -->|OK| C{nbufs >= 1?}
    C -->|No| Z2[UV_EINVAL]
    C -->|Yes| D{送信キュー空?}
    D -->|No| Z3[UV_EAGAIN]
    D -->|Yes| E{addr指定あり?}
    E -->|Yes| F[遅延バインド]
    E -->|No| G[sendmsg呼び出し]
    F --> G
    G -->|成功| H[送信バイト数返却]
    G -->|失敗| I[エラーコード返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-53-01 | キュー空制約 | 送信キューが空でない場合はUV_EAGAINを返す | 常時 |
| BR-53-02 | 同期送信 | コールバックなしで即座に結果が返る | 常時 |
| BR-53-03 | try_send2フラグ制約 | flagsは0のみ許可される | uv_udp_try_send2()使用時 |
| BR-53-04 | バッチ送信 | try_send2ではsendmmsg()で一括送信を試行 | Linux/FreeBSD/macOS |

### 計算ロジック

try_sendの戻り値: `uv__count_bufs(bufs, nbufs)` - 全バッファの合計バイト数

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

該当なし（インメモリ操作のみ）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EINVAL | パラメータ不正 | nbufs < 1 / count < 1 / flags != 0 / FD無効 | パラメータを修正 |
| UV_EAGAIN | 再試行 | 送信キュー非空またはソケットバッファフル | 後で再試行するかuv_udp_send()を使用 |
| UV_EISCONN | 接続済み | 接続済みソケットにaddr指定 | addrにNULLを渡す |
| UV_EDESTADDRREQ | 宛先必須 | 未接続ソケットにaddr未指定 | addrを指定する |

### リトライ仕様

UV_EAGAIN返却時は、アプリケーション側でタイミングを見て再試行する。自動リトライは行わない。

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

該当なし。

## パフォーマンス要件

- 同期処理のため、sendmsg()/sendmmsg()の実行時間で完了
- キューイングオーバーヘッドなし
- try_send2でsendmmsg()を使用する場合、システムコール回数を大幅に削減

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

- uv_udp_send()と同様、送信先アドレスの検証はアプリケーション側の責任

## 備考

- uv_udp_try_send()は成功時にバイト数を返し、uv_udp_try_send2()は成功時にメッセージ数を返す点に注意
- try_send2のaddrs配列の各要素はNULL可（接続済みソケットの場合）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | **L782-791行目**: uv_udp_try_send()/uv_udp_try_send2()のAPI宣言 |

**読解のコツ**: try_send2のパラメータは配列の配列構造であり、複数メッセージの一括送信を表現している。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | uv-common.c | `src/uv-common.c` | **L503-514行目**: uv_udp_try_send() - check_before_sendの後にuv__udp_try_sendを呼び出し |
| 2-2 | uv-common.c | `src/uv-common.c` | **L517-533行目**: uv_udp_try_send2() - count/flags検証後にuv__udp_try_send2呼び出し |

**主要処理フロー**:
1. **L509-511行目**: addrlen検証
2. **L523-524行目**: count < 1チェック
3. **L526-527行目**: flags != 0チェック
4. **L529-530行目**: send_queue_count > 0チェック

#### Step 3: プラットフォーム固有の実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | udp.c (unix) | `src/unix/udp.c` | **L713-740行目**: uv__udp_try_send() - 同期sendmsg呼び出し |
| 3-2 | udp.c (unix) | `src/unix/udp.c` | **L1515-1527行目**: uv__udp_try_send2() - sendmsgv経由の一括送信 |
| 3-3 | udp.c (unix) | `src/unix/udp.c` | **L1367-1392行目**: uv__udp_sendmsg1() - 単一sendmsg実装 |

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

```
uv_udp_try_send(handle, bufs, nbufs, addr)
    ├─ uv__udp_check_before_send(handle, addr)
    └─ uv__udp_try_send(handle, bufs, nbufs, addr, addrlen)
           ├─ uv__udp_maybe_deferred_bind()
           └─ uv__udp_sendmsg1(fd, bufs, nbufs, addr)
                  └─ sendmsg()

uv_udp_try_send2(handle, count, bufs, nbufs, addrs, flags)
    └─ uv__udp_try_send2(handle, count, bufs, nbufs, addrs)
           └─ uv__udp_sendmsgv(fd, count, bufs, nbufs, addrs)
                  ├─ sendmmsg()  [Linux/FreeBSD/macOS]
                  └─ uv__udp_sendmsg1()  [フォールバック]
```

### データフロー図

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

bufs[] ──────────▶ uv_udp_try_send() ──────▶ 送信バイト数 or エラーコード
addr                    │
                        └─ sendmsg()  ──────▶ ネットワーク送出
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | 公開API宣言 |
| uv-common.c | `src/uv-common.c` | ソース | 共通入力チェックとエントリーポイント |
| udp.c (unix) | `src/unix/udp.c` | ソース | Unix系の同期送信実装 |
| udp.c (win) | `src/win/udp.c` | ソース | Windows版の同期送信実装 |
