|
Document of c-modernization-kit (porter) 1.0.0
|
porter は INI 形式のテキストファイルでサービスを定義します。 1 つの設定ファイルに定義できるサービス数に上限はありません (初期バッファ容量は 64 で、超過時は自動拡張されます)。
potrOpenServiceFromConfig() 呼び出し時にファイルを読み込み、指定した service_id のエントリを使用します。 以後はファイルを参照しないため、起動後にファイルを変更しても動作に影響はありません。 potrOpenService() を直接呼ぶ場合は設定ファイルを使用せず、PotrGlobalConfig / PotrServiceDef 構造体を直接渡します。
すべてのサービスに適用されるグローバル設定です。
| キー | 型 | デフォルト | 説明 |
|---|---|---|---|
| window_size | uint16 | 16 | スライディングウィンドウサイズ (2〜256) |
| max_payload | uint16 | 1,400 | DATA パケットのペイロード上限バイト数 (64〜65507) |
| max_message_size | uint32 | 65,535 | 1 回の potrSend で送信できる最大メッセージ長 (バイト)。フラグメント化により max_payload を超えるメッセージを送受信できる |
| send_queue_depth | uint32 | 1,024 | 非同期送信キューの最大エントリ数。メッセージがフラグメント化される場合、1 メッセージが複数エントリを占有する |
| udp_health_interval_ms | uint32 | 3,000 | UDP 通信種別の PING 送信間隔 (ms)。最終 DATA/PING 送信からの経過時間が本値を超えたら PING 送信。0 でヘルスチェック送信を無効化 |
| udp_health_timeout_ms | uint32 | 10,000 | UDP 通信種別の受信タイムアウト (ms)。RECEIVER 側が最終受信から本値を超えたら DISCONNECTED。0 でタイムアウト検知を無効化 |
| tcp_health_interval_ms | uint32 | 10,000 | TCP 通信種別の PING 送信間隔 (ms)。DATA 送信頻度に関わらず定期的に PING を送信。0 でヘルスチェック送信を無効化 |
| tcp_health_timeout_ms | uint32 | 31,000 | TCP 通信種別の PING 応答待機タイムアウト (ms)。SENDER 側が PING 応答を本値以内に受信できなければ DISCONNECTED。0 でタイムアウト検知を無効化 |
| reorder_timeout_ms | uint32 | 0 | 受信ウィンドウで欠番を検出してから NACK 送出 (通常モード) または DISCONNECTED 発行 (RAW モード) を遅延する時間 (ミリ秒)。マルチパスや近距離 WAN での追い越し吸収用。0 で即時 (デフォルト)。推奨値: LAN/マルチパス = 10〜30 ms、遠距離 WAN = 30〜100 ms |
ウィンドウサイズは再送可能な過去パケット数の上限です。 送信側ウィンドウが満杯になると最古エントリが evict (削除) されます。 evict 済みの通番を受信者が NACK で要求した場合、REJECT を返します。
通信の安定性を高めるには、往復遅延時間と送信レートに応じてウィンドウサイズを調整してください。
ペイロードエレメント 1 個分のデータサイズ上限です。 potrSend() で送信するデータがこのサイズを超える場合、複数のフラグメントに分割されます。
| 構成 | 推奨値 | 理由 |
|---|---|---|
| 単一パス・同一 LAN | 0 (無効) | 遅延変動が小さく追い越しはほぼ発生しない |
| マルチパス (2 経路以上) | 10〜30 ms | 経路差異で数 ms〜数十 ms の追い越しが起こりうる |
| 遠距離 WAN / 無線 LAN | 30〜100 ms | 遅延変動が大きく再順序付けが頻繁に発生する環境 |
multicast / broadcast の通常モードかつ reorder_timeout_ms > 0 の場合、複数の受信者が同一欠番を同時に NACK すると送信者への負荷が集中する (NACK implosion)。
これを回避するため、タイマー起動時に 100〜200% の範囲でランダムなジッタを自動付加します。
| 通信種別 | 実効タイムアウト |
|---|---|
| unicast (通常モード) | reorder_timeout_ms (固定) |
| multicast / broadcast (通常モード) | reorder_timeout_ms 〜 reorder_timeout_ms × 2 (ランダム分散) |
| *_raw (RAW モード全種別) | reorder_timeout_ms (固定、DISCONNECTED 発行用) |
| 設定 | 効果 |
|---|---|
| udp_health_interval_ms = 0 | 送信者が PING を送信しない。受信者はデータパケットが届いたときのみ最終受信時刻を更新する |
| udp_health_timeout_ms = 0 | 受信者がタイムアウト監視を行わない。DISCONNECTED は FIN / REJECT 受信時のみ発火する |
| 両方 0 | ヘルスチェック機能が完全に無効。CONNECTED / DISCONNECTED は FIN / REJECT のみで発火する |
| 設定 | 効果 |
|---|---|
| tcp_health_interval_ms = 0 | SENDER が PING を送信しない(ヘルスチェック無効) |
| tcp_health_timeout_ms = 0 | SENDER が PING 応答タイムアウトを監視しない |
| 両方 0 | TCP ヘルスチェック完全無効 |
UDP の udp_health_timeout_ms は RECEIVER 側の受信無音タイムアウトですが、 TCP の tcp_health_timeout_ms は SENDER 側の PING 応答待機タイムアウトです。 また TCP では DATA 送信頻度に関わらず tcp_health_interval_ms 周期で PING を送信します (UDP は DATA が流れていれば PING を省略)。
N には整数のサービス ID を指定します。
| キー | 型 | 必須 | 説明 |
|---|---|---|---|
| type | 文字列 | 必須 | unicast / multicast / broadcast / unicast_raw / multicast_raw / broadcast_raw / unicast_bidir / unicast_bidir_n1 / tcp / tcp_bidir |
| dst_port | uint16 | 必須 | 宛先ポート番号 (サービスの識別子) |
| src_addr | 文字列 | 条件付き | 通常は送信元 bind アドレスまたは受信側の送信元 IP フィルタ。unicast_bidir では SENDER・RECEIVER ともに省略可能 (各役割の省略時動作は後述) |
| src_port | uint16 | 省略可 | 送信者の送信元 bind ポート (0 = OS が自動選定) |
| health_interval_ms | uint32 | 省略可 | グローバルの udp_health_interval_ms または tcp_health_interval_ms をサービス単位でオーバーライドする |
| health_timeout_ms | uint32 | 省略可 | グローバルの udp_health_timeout_ms または tcp_health_timeout_ms をサービス単位でオーバーライドする |
| pack_wait_ms | uint32 | 省略可 | パッキング待機時間 (ミリ秒)。0 で即時送信 |
| encrypt_key | 文字列 | 省略可 | AES-256-GCM 事前共有鍵。以下の2形式を受け付ける: ① hex 鍵: 256 ビット (32 バイト) を 64 文字の 16 進数文字列で指定 ② パスフレーズ: 上記以外の任意の文字列を指定すると SHA-256 で 32 バイト鍵に変換する。省略時は暗号化なし |
| キー | 型 | 必須 | 説明 |
|---|---|---|---|
| dst_addr | 文字列 | 必須 | 送信者: 送信先アドレス。受信者: bind アドレス |
| キー | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
| multicast_group | 文字列 | 必須 | — | マルチキャストグループ IP アドレス (例: 224.0.0.1) |
| ttl | uint8 | 省略可 | 1 | マルチキャスト TTL |
RAW モードは通常モード (unicast / multicast / broadcast) と同一のアドレス・ポートフィールドを使用します。 追加の専用フィールドはありません。
通常モードとの差異:
| 項目 | 通常モード | RAW モード |
|---|---|---|
| 再送制御 | NACK ベース再送あり | 再送なし |
| ギャップ検出時 | NACK を返送して欠落パケットを待機 | 即 POTR_EVENT_DISCONNECTED を発行し、次の正規パケットで POTR_EVENT_CONNECTED |
| potrSend の動作 | flags 引数に従う (ノンブロッキング / ブロッキング) | 常にブロッキング送信 (POTR_SEND_BLOCKING 相当) |
| 通番 (seq_num) | 再送制御・ウィンドウ管理に使用 | AES ノンス生成用のみ (再送制御には使用しない) |
| ヘルスチェック | health_interval_ms / health_timeout_ms に従う | 同左 (制限なし) |
RAW モードでもスライディングウィンドウによる 順序整列 と セッション管理 は有効です。
unicast_bidir は常に 1:1 双方向通信 です。SENDER・RECEIVER の双方が独立して送受信・NACK・ヘルスチェックを行います。
| src 情報の指定 | SENDER の bind 動作 | RECEIVER の bind 動作 | 送信元フィルタ |
|---|---|---|---|
| src_addr + src_port 指定 | src_addr:src_port で bind | dst_addr:dst_port で bind | アドレス + ポート |
| src_addr のみ指定 | src_addr:エフェメラル で bind | dst_addr:dst_port で bind | アドレスのみ |
| src_addr 省略 (SENDER) | INADDR_ANY:src_port で bind (OS がアダプタを自動選択) | — | なし |
| src_addr 省略 (RECEIVER) | — | dst_addr:dst_port で bind し、最初の受信パケットから SENDER のアドレスを動的学習する | なし (学習後は学習アドレスから受信) |
| キー | 型 | 必須 | 説明 |
|---|---|---|---|
| src_addr | 文字列 | 省略可 | SENDER: 省略時は INADDR_ANY で bind し OS がアダプタを自動選択。RECEIVER: 省略時は SENDER アドレスを動的学習する |
| src_port | uint16 | 省略可 | SENDER の bind ポート。0 または省略でエフェメラルポートを使用し、RECEIVER がパケット受信後に動的学習する |
| dst_addr | 文字列 | 条件付き | SENDER: 送信先アドレス。RECEIVER: bind アドレス。省略時は INADDR_ANY で bind する |
| dst_port | uint16 | 必須 | SENDER: 送信先ポート (RECEIVER の bind ポート) |
unicast_bidir_n1 は N:1 双方向通信 です。サーバ (POTR_ROLE_RECEIVER) が複数クライアントを同時に受け入れます。クライアントは unicast_bidir (1:1) として接続します。
| キー | 型 | 必須 | 説明 |
|---|---|---|---|
| dst_addr | 文字列 | 省略可 | サーバの bind アドレス。省略時は INADDR_ANY で bind する |
| dst_port | uint16 | 必須 | サーバの受信ポート |
| src_port | uint16 | 省略可 | 送信元ポートフィルタ。0 または省略でフィルタなし (全クライアント受け入れ) |
| max_peers | uint32 | 省略可 | 最大同時接続クライアント数。既定値は 1024 |
| キー | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
| dst_addr | 文字列 | 必須 | — | SENDER: 接続先アドレス(ホスト名可)。RECEIVER: bind アドレス |
| dst_port | uint16 | 必須 | — | SENDER: 接続先ポート。RECEIVER: listen ポート |
| src_addr | 文字列 | 省略可 | — | SENDER: ローカル bind アドレス(省略で自動選択)。RECEIVER: 接続元 IP フィルタ(省略でフィルタなし) |
| src_port | uint16 | 省略可 | 0 | SENDER: ローカル bind ポート(0 または省略でエフェメラル)。RECEIVER: 接続元ポートフィルタ(0 または省略でフィルタなし) |
| reconnect_interval_ms | uint32 | 省略可 | 5,000 | SENDER の自動再接続間隔 (ms)。0 で自動再接続なし。RECEIVER では無視 |
| connect_timeout_ms | uint32 | 省略可 | 10,000 | SENDER の TCP 接続タイムアウト (ms)。0 で OS デフォルト。RECEIVER では無視 |
tcp / tcp_bidir では使用しないフィールド(記述しても無視)
| フィールド | UDP での用途 |
|---|---|
| multicast_group | マルチキャストグループ |
| ttl | マルチキャスト TTL |
| broadcast_addr | ブロードキャスト宛先 |
dst_addr 〜 dst_addr.3(最大 4 エントリ)に接続先アドレスを設定すると、 各エントリに対して独立した TCP 接続(path)が確立されます。 エントリが 1 つのみの場合は単一接続として動作します。
各 path[i] に独立して適用されます。
| src_addr | src_port | connect() 前の bind() 動作 |
|---|---|---|
| 未指定 | 0 または省略 | bind() しない |
| 未指定 | 指定 | INADDR_ANY:src_port で bind |
| 指定 | 0 または省略 | src_addr:0(エフェメラルポート)で bind |
| 指定 | 指定 | src_addr:src_port で bind |
各 path[i] の accept() 後に接続元を検証します。
| src_addr | src_port | フィルタ動作 |
|---|---|---|
| 未指定 | 0 または省略 | 全接続を受け付ける |
| 未指定 | 指定 | 接続元ポートが一致する接続のみ受け付ける |
| 指定 | 0 または省略 | 接続元 IP が一致する接続のみ受け付ける |
| 指定 | 指定 | 接続元 IP・ポート両方が一致する接続のみ受け付ける |
| キー | 型 | 必須 | 説明 |
|---|---|---|---|
| broadcast_addr | 文字列 | 必須 | 送信者: 送信先ブロードキャストアドレス (例: 192.168.1.255) |
encrypt_key を設定すると AES-256-GCM による暗号化・認証タグが有効になります。
| 項目 | 説明 |
|---|---|
| 形式① hex 鍵 | 256 ビット鍵を 16 進数文字列 (64 文字、英数字) で記述する |
| 形式② パスフレーズ | 64 文字 hex 以外の任意の文字列。SHA-256 ハッシュで 32 バイト鍵を自動導出する |
| 暗号化範囲 | DATA パケットのペイロード部分を AES-256-GCM で暗号化する。ヘッダー 36 バイトは平文 |
| AAD | ヘッダー 36 バイトを追加認証データ (AAD) として使用するため、ヘッダー改ざんも検知する |
| 認証タグ (DATA) | 16 バイトの GCM 認証タグを暗号文末尾に付与する。実効ペイロードが max_payload - 16 バイトに減少する |
| 認証タグ (その他) | PING / NACK / REJECT / FIN は平文ペイロードが 0 バイトだが、AAD (ヘッダー 36B) に対して 16 バイトの GCM 認証タグのみを付与する。ヘッダー改ざんを検知できる |
| 双方一致 | 送信者・受信者ともに同一の encrypt_key を設定すること |
| マルチキャスト | 受信者全員が同一の encrypt_key を持っていれば動作する |
GCM ノンス (12 バイト) は以下の構成です。
| フィールド | バイト | 内容 |
|---|---|---|
| session_id | 4 | 送信元の自セッション ID (ネットワークバイトオーダー) |
| flags | 2 | POTR_FLAG_ENCRYPTED を含む実際の送信フラグ値 (NBO) |
| seq_or_ack_num | 4 | DATA/PING/FIN は seq_num、NACK/REJECT は ack_num (NBO) |
| padding | 2 | 0x0000 固定 |
各パケット種別の flags 値 (例):
| パケット種別 | flags (16進) |
|---|---|
| DATA (暗号化あり) | 0x0021 (DATA | ENCRYPTED) |
| PING (暗号化あり) | 0x0024 (PING | ENCRYPTED) |
| NACK (暗号化あり) | 0x0022 (NACK | ENCRYPTED) |
| REJECT (暗号化あり) | 0x0028 (REJECT | ENCRYPTED) |
| FIN (暗号化あり) | 0x0030 (FIN | ENCRYPTED) |
src_addr・dst_addr には以下のいずれかを指定できます。
| 項目 | 仕様 |
|---|---|
| 解決タイミング | potrOpenServiceFromConfig() / potrOpenService() 呼び出し時に 1 回のみ解決する |
| 再解決 | プロセス生存中は再解決しない。DNS 更新後に接続できなくなった場合はプロセスを再起動する |
| 複数アドレス返却時 | 仕様上未定義。実装上は先頭アドレスを採用する |
| IPv6 | 非対応 |
| 送信者 | 受信者 | |
|---|---|---|
| bind アドレス | src_addr | dst_addr |
| bind ポート | src_port (0 = OS 自動) | dst_port |
| 送信先 | dst_addr:dst_port | — |
| 送信元フィルタ | — | src_addr |
受信者は dst_addr でソケットを bind するため、dst_addr は当該ホストの NIC に割り当てられているアドレスでなければなりません。
| Side A (SENDER) | Side B (RECEIVER) | |
|---|---|---|
| bind アドレス | src_addr | dst_addr |
| bind ポート | src_port(省略可、0 でエフェメラル) | dst_port |
| 送信先アドレス | dst_addr | src_addr(省略時は最初の受信パケットから動的学習) |
| 送信先ポート | dst_port | src_port(0 / 省略時は受信した送信元ポートを動的学習) |
| 送信元フィルタ | — | src_addr 指定時はアドレスを照合。省略時は動的学習後に学習済みアドレスを照合 |
| N:1 サーバ (unicast_bidir_n1) | クライアント (unicast_bidir) | |
|---|---|---|
| bind アドレス | dst_addr(省略時 INADDR_ANY) | src_addr |
| bind ポート | dst_port | src_port(省略可) |
| 送信先 | recvfrom で学習した各ピアの送信元 | dst_addr:dst_port |
| 送信元フィルタ | src_port 指定時のみポートで照合 | — |
| 最大接続数 | max_peers | — |
| 送信者 | 受信者 | |
|---|---|---|
| bind アドレス | INADDR_ANY | INADDR_ANY |
| bind ポート | src_port (0 = OS 自動) | dst_port |
| マルチキャスト設定 | IP_MULTICAST_IF = src_addr | グループ参加: src_addr (NIC 指定) |
| 送信先 | multicast_group:dst_port | — |
| 送信元フィルタ | — | src_addr |
| 送信者 | 受信者 | |
|---|---|---|
| bind アドレス | src_addr | INADDR_ANY |
| bind ポート | src_port (0 = OS 自動) | dst_port |
| ソケットオプション | SO_BROADCAST 有効 | SO_BROADCAST 有効 |
| 送信先 | broadcast_addr:dst_port | — |
| 送信元フィルタ | — | src_addr |
| SENDER | RECEIVER | |
|---|---|---|
| ソケット種別 | SOCK_STREAM | SOCK_STREAM |
| 動作 | connect(dst_addr, dst_port) | bind(dst_addr, dst_port) → listen() → accept() |
| listen ソケット | なし | あり(接続待機専用) |
| 接続ソケット | connect() の fd | accept() の fd |
RECEIVER が先に potrOpenServiceFromConfig() / potrOpenService() を呼んで listen() に入っている必要があります。
受信スレッドは通信種別とモードに応じて送信元を検査します。
一致しないパケットはアプリケーション層で破棄します。
| 用途 | 推奨する type |
|---|---|
| 双方向 1:1 通信 (相手アドレス既知) | unicast_bidir (src_addr あり) |
| RECEIVER が SENDER のアドレスを事前に知らない 1:1 | unicast_bidir (RECEIVER 側 src_addr 省略) |
| 複数クライアントを同時に受け入れる N:1 サーバ | unicast_bidir_n1 |
最大 4 経路を並列に設定できます。 各経路は独立した UDP ソケットを持ちます。
マルチパスを使用すると、DATA・PING・再送パケットがすべての経路へ同時送信されます。