Document of c-modernization-kit (porter) 1.0.0
Loading...
Searching...
No Matches
config.c
Go to the documentation of this file.
1
13
14#include <ctype.h>
15#include <inttypes.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19
20#include <porter_const.h>
21#include <porter_type.h>
22
24#include "../infra/potrLog.h"
25#include "config.h"
26
28#define CONFIG_LINE_MAX 256
29
31#define CONFIG_SECTION_MAX 64
32
34#define CONFIG_KEY_MAX 64
35
37#define CONFIG_VAL_MAX 128
38
39/* 読み取り専用で設定ファイルを開く。失敗時は NULL を返す。 */
40static FILE *open_config_file_read(const char *path)
41{
42 FILE *fp = NULL;
43
44 if (path == NULL)
45 {
46 return NULL;
47 }
48
49#ifndef _WIN32
50 fp = fopen(path, "r");
51#else /* _WIN32 */
52 if (fopen_s(&fp, path, "r") != 0)
53 {
54 return NULL;
55 }
56#endif /* _WIN32 */
57
58 return fp;
59}
60
61/* src を dst に切り詰めコピーする。 */
62static void copy_cstr_trunc(char *dst, size_t dst_size, const char *src)
63{
64 size_t len;
65
66 if (dst == NULL || dst_size == 0)
67 {
68 return;
69 }
70
71 if (src == NULL)
72 {
73 dst[0] = '\0';
74 return;
75 }
76
77 len = strlen(src);
78 if (len >= dst_size)
79 {
80 len = dst_size - 1;
81 }
82
83 memcpy(dst, src, len);
84 dst[len] = '\0';
85}
86
87/* 文字列の先頭・末尾の空白を除去して buf に格納する */
88static void trim(const char *src, char *buf, size_t buf_size)
89{
90 const char *start;
91 const char *end;
92 size_t len;
93
94 if (src == NULL || buf == NULL || buf_size == 0)
95 {
96 return;
97 }
98
99 start = src;
100 while (*start != '\0' && isspace((unsigned char)*start))
101 {
102 start++;
103 }
104
105 end = src + strlen(src) - 1;
106 while (end >= start && isspace((unsigned char)*end))
107 {
108 end--;
109 }
110
111 len = (size_t)(end - start + 1);
112 if (len >= buf_size)
113 {
114 len = buf_size - 1;
115 }
116
117 memcpy(buf, start, len);
118 buf[len] = '\0';
119}
120
121/* "key = value" 行を解析して key_out, val_out に格納する。成功時は 1 を返す。 */
122static int parse_kv(const char *line, char *key_out, size_t key_size,
123 char *val_out, size_t val_size)
124{
125 const char *eq;
126 char key_raw[CONFIG_KEY_MAX];
127 size_t key_len;
128
129 eq = strchr(line, '=');
130 if (eq == NULL)
131 {
132 return 0;
133 }
134
135 key_len = (size_t)(eq - line);
136 if (key_len >= CONFIG_KEY_MAX)
137 {
138 return 0;
139 }
140 memcpy(key_raw, line, key_len);
141 key_raw[key_len] = '\0';
142
143 trim(key_raw, key_out, key_size);
144 trim(eq + 1, val_out, val_size);
145
146 return 1;
147}
148
160int config_load_global(const char *config_path, PotrGlobalConfig *global)
161{
162 FILE *fp;
163 char line[CONFIG_LINE_MAX];
164 char section[CONFIG_SECTION_MAX];
165 char key[CONFIG_KEY_MAX];
166 char val[CONFIG_VAL_MAX];
167 int in_global;
168
169 if (config_path == NULL || global == NULL)
170 {
171 return POTR_ERROR;
172 }
173
174 /* デフォルト値で初期化 */
175 global->window_size = (uint16_t)POTR_DEFAULT_WINDOW_SIZE;
176 global->max_payload = (uint16_t)POTR_DEFAULT_MAX_PAYLOAD;
179 global->reorder_timeout_ms = 0U;
180 global->max_message_size = (uint32_t)POTR_MAX_MESSAGE_SIZE;
181 global->send_queue_depth = (uint32_t)POTR_SEND_QUEUE_DEPTH;
182 global->tcp_health_interval_ms = 10000U;
183 global->tcp_health_timeout_ms = 31000U;
184
185 fp = open_config_file_read(config_path);
186 if (fp == NULL)
187 {
188 return POTR_ERROR;
189 }
190
191 section[0] = '\0';
192 in_global = 0;
193
194 while (fgets(line, sizeof(line), fp) != NULL)
195 {
196 char trimmed[CONFIG_LINE_MAX];
197 trim(line, trimmed, sizeof(trimmed));
198
199 /* 空行・コメント行をスキップ */
200 if (trimmed[0] == '\0' || trimmed[0] == '#' || trimmed[0] == ';')
201 {
202 continue;
203 }
204
205 /* セクションヘッダー */
206 if (trimmed[0] == '[')
207 {
208 char *close = strchr(trimmed, ']');
209 if (close != NULL)
210 {
211 size_t sec_len = (size_t)(close - trimmed - 1);
212 if (sec_len >= CONFIG_SECTION_MAX)
213 {
214 sec_len = CONFIG_SECTION_MAX - 1;
215 }
216 memcpy(section, trimmed + 1, sec_len);
217 section[sec_len] = '\0';
218 if (strcmp(section, "global") == 0)
219 {
220 in_global = 1;
221 }
222 else
223 {
224 in_global = 0;
225 }
226 }
227 continue;
228 }
229
230 if (!in_global)
231 {
232 continue;
233 }
234
235 if (!parse_kv(trimmed, key, sizeof(key), val, sizeof(val)))
236 {
237 continue;
238 }
239
240 if (strcmp(key, "window_size") == 0)
241 {
242 global->window_size = (uint16_t)atoi(val);
243 }
244 else if (strcmp(key, "max_payload") == 0)
245 {
246 global->max_payload = (uint16_t)atoi(val);
247 }
248 else if (strcmp(key, "health_interval_ms") == 0 ||
249 strcmp(key, "udp_health_interval_ms") == 0)
250 {
251 /* 旧キー health_interval_ms は UDP 用として継続サポート */
252 global->health_interval_ms = (uint32_t)atoi(val);
253 }
254 else if (strcmp(key, "health_timeout_ms") == 0 ||
255 strcmp(key, "udp_health_timeout_ms") == 0)
256 {
257 global->health_timeout_ms = (uint32_t)atoi(val);
258 }
259 else if (strcmp(key, "tcp_health_interval_ms") == 0)
260 {
261 global->tcp_health_interval_ms = (uint32_t)atoi(val);
262 }
263 else if (strcmp(key, "tcp_health_timeout_ms") == 0)
264 {
265 global->tcp_health_timeout_ms = (uint32_t)atoi(val);
266 }
267 else if (strcmp(key, "reorder_timeout_ms") == 0)
268 {
269 global->reorder_timeout_ms = (uint32_t)atoi(val);
270 }
271 else if (strcmp(key, "max_message_size") == 0)
272 {
273 global->max_message_size = (uint32_t)atoi(val);
274 }
275 else if (strcmp(key, "send_queue_depth") == 0)
276 {
277 global->send_queue_depth = (uint32_t)atoi(val);
278 }
279 }
280
282 "config loaded: window_size=%u max_payload=%u "
283 "max_message_size=%u send_queue_depth=%u "
284 "udp_health=%u/%u tcp_health=%u/%u reorder_timeout_ms=%u",
285 (unsigned)global->window_size, (unsigned)global->max_payload,
286 (unsigned)global->max_message_size, (unsigned)global->send_queue_depth,
287 (unsigned)global->health_interval_ms, (unsigned)global->health_timeout_ms,
288 (unsigned)global->tcp_health_interval_ms, (unsigned)global->tcp_health_timeout_ms,
289 (unsigned)global->reorder_timeout_ms);
290
291 fclose(fp);
292 return POTR_SUCCESS;
293}
294
295/* service セクションの 1 エントリ分を current に読み込む共通処理 */
296static void apply_service_kv(const char *key, const char *val,
297 PotrServiceDef *current)
298{
299 if (strcmp(key, "type") == 0)
300 {
301 if (strcmp(val, "unicast_raw") == 0)
302 {
303 current->type = POTR_TYPE_UNICAST_RAW;
304 }
305 else if (strcmp(val, "multicast_raw") == 0)
306 {
307 current->type = POTR_TYPE_MULTICAST_RAW;
308 }
309 else if (strcmp(val, "broadcast_raw") == 0)
310 {
311 current->type = POTR_TYPE_BROADCAST_RAW;
312 }
313 else if (strcmp(val, "unicast") == 0)
314 {
315 current->type = POTR_TYPE_UNICAST;
316 }
317 else if (strcmp(val, "multicast") == 0)
318 {
319 current->type = POTR_TYPE_MULTICAST;
320 }
321 else if (strcmp(val, "broadcast") == 0)
322 {
323 current->type = POTR_TYPE_BROADCAST;
324 }
325 else if (strcmp(val, "unicast_bidir") == 0)
326 {
327 current->type = POTR_TYPE_UNICAST_BIDIR;
328 }
329 else if (strcmp(val, "unicast_bidir_n1") == 0)
330 {
332 }
333 else if (strcmp(val, "tcp") == 0)
334 {
335 current->type = POTR_TYPE_TCP;
336 }
337 else if (strcmp(val, "tcp_bidir") == 0)
338 {
339 current->type = POTR_TYPE_TCP_BIDIR;
340 }
341 }
342 else if (strcmp(key, "dst_port") == 0)
343 {
344 current->dst_port = (uint16_t)atoi(val);
345 }
346 else if (strcmp(key, "src_port") == 0)
347 {
348 current->src_port = (uint16_t)atoi(val);
349 }
350 else if (strcmp(key, "multicast_group") == 0)
351 {
353 sizeof(current->multicast_group),
354 val);
355 }
356 else if (strcmp(key, "ttl") == 0)
357 {
358 current->ttl = (uint8_t)atoi(val);
359 }
360 else if (strcmp(key, "broadcast_addr") == 0)
361 {
363 sizeof(current->broadcast_addr),
364 val);
365 }
366 else if (strncmp(key, "src_addr", 8) == 0)
367 {
368 int idx;
369 /* "src_addr1"〜"src_addr4" のみ有効。それ以外は無視。 */
370 if (key[8] < '1' || key[8] > '4' || key[9] != '\0')
371 {
372 return;
373 }
374 idx = key[8] - '1'; /* 0〜3 */
375 copy_cstr_trunc(current->src_addr[idx], POTR_MAX_ADDR_LEN, val);
376 }
377 else if (strncmp(key, "dst_addr", 8) == 0)
378 {
379 int idx;
380 if (key[8] < '1' || key[8] > '4' || key[9] != '\0')
381 {
382 return;
383 }
384 idx = key[8] - '1';
385 copy_cstr_trunc(current->dst_addr[idx], POTR_MAX_ADDR_LEN, val);
386 }
387 else if (strcmp(key, "pack_wait_ms") == 0)
388 {
389 current->pack_wait_ms = (uint32_t)atoi(val);
390 }
391 else if (strcmp(key, "max_peers") == 0)
392 {
393 int v = atoi(val);
394 if (v > 0)
395 {
396 current->max_peers = (uint32_t)v;
397 }
398 }
399 else if (strcmp(key, "health_interval_ms") == 0)
400 {
401 current->health_interval_ms = (uint32_t)atoi(val);
402 }
403 else if (strcmp(key, "health_timeout_ms") == 0)
404 {
405 current->health_timeout_ms = (uint32_t)atoi(val);
406 }
407 else if (strcmp(key, "reconnect_interval_ms") == 0)
408 {
409 current->reconnect_interval_ms = (uint32_t)atoi(val);
410 }
411 else if (strcmp(key, "connect_timeout_ms") == 0)
412 {
413 int v = atoi(val);
414 if (v >= 0)
415 {
416 current->connect_timeout_ms = (uint32_t)v;
417 }
418 }
419 else if (strcmp(key, "encrypt_key") == 0)
420 {
421 size_t hex_len = strlen(val);
422 int i;
423 int is_hex = 1;
424
425 /* 64 文字かつ全桁 hex 文字かを検査する */
426 if (hex_len == POTR_CRYPTO_KEY_SIZE * 2U)
427 {
428 for (i = 0; i < (int)(POTR_CRYPTO_KEY_SIZE * 2U); i++)
429 {
430 if (!isxdigit((unsigned char)val[i]))
431 {
432 is_hex = 0;
433 break;
434 }
435 }
436 }
437 else
438 {
439 is_hex = 0;
440 }
441
442 if (is_hex)
443 {
444 /* 64 文字 hex 文字列 → 32 バイトバイナリキーに変換 */
445 for (i = 0; i < (int)POTR_CRYPTO_KEY_SIZE; i++)
446 {
447 char byte_str[3];
448 char *endp;
449 unsigned long byte_val;
450
451 byte_str[0] = val[i * 2];
452 byte_str[1] = val[i * 2 + 1];
453 byte_str[2] = '\0';
454
455 byte_val = strtoul(byte_str, &endp, 16);
456 current->encrypt_key[i] = (uint8_t)byte_val;
457 }
458 current->encrypt_enabled = 1;
460 "config: encrypt_key loaded as hex key (service_id=%" PRId64 ")",
461 current->service_id);
462 }
463 else if (hex_len > 0)
464 {
465 /* パスフレーズ → SHA-256 で 32 バイトキーを導出する */
467 (const uint8_t *)val, hex_len) == 0)
468 {
469 current->encrypt_enabled = 1;
471 "config: encrypt_key treated as passphrase (SHA-256, service_id=%" PRId64 ")",
472 current->service_id);
473 }
474 else
475 {
476 memset(current->encrypt_key, 0, sizeof(current->encrypt_key));
477 current->encrypt_enabled = 0;
479 "config: encrypt_key passphrase hashing failed (service_id=%" PRId64 ")",
480 current->service_id);
481 }
482 }
483 else
484 {
485 /* 空文字列は無効 */
486 memset(current->encrypt_key, 0, sizeof(current->encrypt_key));
487 current->encrypt_enabled = 0;
489 "config: encrypt_key is empty, ignored (service_id=%" PRId64 ")",
490 current->service_id);
491 }
492 }
493}
494
508int config_load_service(const char *config_path, int64_t service_id,
509 PotrServiceDef *def)
510{
511 FILE *fp;
512 char line[CONFIG_LINE_MAX];
513 char key[CONFIG_KEY_MAX];
514 char val[CONFIG_VAL_MAX];
515 int in_target; /* 目的のサービスセクション内かどうか */
516 int found;
517
518 if (config_path == NULL || def == NULL)
519 {
520 return POTR_ERROR;
521 }
522
523 fp = open_config_file_read(config_path);
524 if (fp == NULL)
525 {
526 return POTR_ERROR;
527 }
528
529 in_target = 0;
530 found = 0;
531
532 while (fgets(line, sizeof(line), fp) != NULL)
533 {
534 char trimmed[CONFIG_LINE_MAX];
535 trim(line, trimmed, sizeof(trimmed));
536
537 if (trimmed[0] == '\0' || trimmed[0] == '#' || trimmed[0] == ';')
538 {
539 continue;
540 }
541
542 if (trimmed[0] == '[')
543 {
544 char section[CONFIG_SECTION_MAX];
545 char *close;
546 size_t sec_len;
547
548 /* 目的セクションを読み込み済みなら終了 */
549 if (in_target)
550 {
551 break;
552 }
553
554 close = strchr(trimmed, ']');
555 if (close != NULL)
556 {
557 sec_len = (size_t)(close - trimmed - 1);
558 if (sec_len >= CONFIG_SECTION_MAX)
559 {
560 sec_len = CONFIG_SECTION_MAX - 1;
561 }
562 memcpy(section, trimmed + 1, sec_len);
563 section[sec_len] = '\0';
564
565 /* [service.<id>] の <id> が service_id と一致するか判定 */
566 if (strncmp(section, "service.", 8) == 0 &&
567 strtoll(section + 8, NULL, 10) == service_id)
568 {
569 memset(def, 0, sizeof(*def));
570 def->ttl = (uint8_t)POTR_DEFAULT_TTL;
572 def->max_peers = 1024U; /* N:1 モードのデフォルト最大ピア数 */
573 def->service_id = service_id;
574 def->health_interval_ms = 0U; /* 0 = グローバル値を使用 */
575 def->health_timeout_ms = 0U;
578 in_target = 1;
579 found = 1;
580 }
581 }
582 continue;
583 }
584
585 if (!in_target)
586 {
587 continue;
588 }
589
590 if (!parse_kv(trimmed, key, sizeof(key), val, sizeof(val)))
591 {
592 continue;
593 }
594
595 apply_service_kv(key, val, def);
596 }
597
598 fclose(fp);
599 if (found)
600 {
602 "service loaded: service_id=%" PRId64 " type=%d "
603 "src_addr1=%s dst_addr1=%s dst_port=%u src_port=%u",
604 def->service_id, (int)def->type,
605 def->src_addr[0], def->dst_addr[0],
606 (unsigned)def->dst_port, (unsigned)def->src_port);
607 return POTR_SUCCESS;
608 }
609 else
610 {
611 return POTR_ERROR;
612 }
613}
614
628int config_list_service_ids(const char *config_path, int64_t **ids_out, int *count_out)
629{
630 FILE *fp;
631 char line[CONFIG_LINE_MAX];
632 int64_t *ids;
633 int capacity;
634 int count;
635
636 if (config_path == NULL || ids_out == NULL || count_out == NULL)
637 {
638 return POTR_ERROR;
639 }
640
641 fp = open_config_file_read(config_path);
642 if (fp == NULL)
643 {
644 return POTR_ERROR;
645 }
646
647 capacity = (int)POTR_MAX_SERVICES;
648 count = 0;
649 ids = (int64_t *)malloc((size_t)capacity * sizeof(int64_t));
650 if (ids == NULL)
651 {
652 fclose(fp);
653 return POTR_ERROR;
654 }
655
656 while (fgets(line, sizeof(line), fp) != NULL)
657 {
658 char trimmed[CONFIG_LINE_MAX];
659 trim(line, trimmed, sizeof(trimmed));
660
661 if (trimmed[0] != '[')
662 {
663 continue;
664 }
665
666 {
667 char *close = strchr(trimmed, ']');
668 char section[CONFIG_SECTION_MAX];
669 size_t sec_len;
670
671 if (close == NULL)
672 {
673 continue;
674 }
675 sec_len = (size_t)(close - trimmed - 1);
676 if (sec_len >= CONFIG_SECTION_MAX)
677 {
678 sec_len = CONFIG_SECTION_MAX - 1;
679 }
680 memcpy(section, trimmed + 1, sec_len);
681 section[sec_len] = '\0';
682
683 if (strncmp(section, "service.", 8) != 0)
684 {
685 continue;
686 }
687
688 if (count >= capacity)
689 {
690 int new_cap = capacity * 2;
691 int64_t *new_ids = (int64_t *)realloc(ids, (size_t)new_cap * sizeof(int64_t));
692 if (new_ids == NULL)
693 {
694 free(ids);
695 fclose(fp);
696 return POTR_ERROR;
697 }
698 ids = new_ids;
699 capacity = new_cap;
700 }
701
702 ids[count++] = strtoll(section + 8, NULL, 10);
703 }
704 }
705
706 fclose(fp);
707 *ids_out = ids;
708 *count_out = count;
709 return POTR_SUCCESS;
710}
int config_list_service_ids(const char *config_path, int64_t **ids_out, int *count_out)
設定ファイルに登録されているすべてのサービス ID を列挙します。
Definition config.c:628
int config_load_service(const char *config_path, int64_t service_id, PotrServiceDef *def)
設定ファイルから指定サービスの定義を読み込みます。
Definition config.c:508
static void copy_cstr_trunc(char *dst, size_t dst_size, const char *src)
Definition config.c:62
static void trim(const char *src, char *buf, size_t buf_size)
Definition config.c:88
#define CONFIG_LINE_MAX
設定ファイル 1 行の最大長。
Definition config.c:28
static int parse_kv(const char *line, char *key_out, size_t key_size, char *val_out, size_t val_size)
Definition config.c:122
static FILE * open_config_file_read(const char *path)
Definition config.c:40
#define CONFIG_KEY_MAX
キー名の最大長。
Definition config.c:34
#define CONFIG_VAL_MAX
値文字列の最大長。
Definition config.c:37
#define CONFIG_SECTION_MAX
セクション名の最大長。
Definition config.c:31
static void apply_service_kv(const char *key, const char *val, PotrServiceDef *current)
Definition config.c:296
int config_load_global(const char *config_path, PotrGlobalConfig *global)
設定ファイルから [global] セクションを読み込みます。
Definition config.c:160
設定ファイル解析モジュールの内部ヘッダー。
データ暗号化・復号モジュールの内部ヘッダー。
int potr_passphrase_to_key(uint8_t *key, const uint8_t *passphrase, size_t passphrase_len)
任意のパスフレーズを SHA-256 ハッシュにより AES-256 鍵に変換します。
#define POTR_CRYPTO_KEY_SIZE
AES-256-GCM 鍵サイズ (バイト)。設定ファイルの encrypt_key に 64 文字 hex で指定する。
#define POTR_DEFAULT_PACK_WAIT_MS
デフォルトパッキング待ち時間 (ミリ秒)。0 = 即時送信。
#define POTR_DEFAULT_MAX_PAYLOAD
デフォルト最大ペイロード長 (バイト)。
#define POTR_DEFAULT_HEALTH_TIMEOUT_MS
デフォルトヘルスチェックタイムアウト (ミリ秒)。0 = 無効。
#define POTR_DEFAULT_HEALTH_INTERVAL_MS
デフォルトヘルスチェック送信間隔 (ミリ秒)。0 = 無効。
#define POTR_DEFAULT_TTL
デフォルトマルチキャスト TTL。
#define POTR_DEFAULT_WINDOW_SIZE
デフォルトウィンドウサイズ (パケット数)。
#define POTR_DEFAULT_RECONNECT_INTERVAL_MS
SENDER 自動再接続間隔のデフォルト (ミリ秒)。TCP 通信種別 (POTR_TYPE_TCP / POTR_TYPE_TCP_BIDIR) のみ有効。
#define POTR_DEFAULT_CONNECT_TIMEOUT_MS
SENDER TCP 接続タイムアウトのデフォルト (ミリ秒)。0 = OS デフォルト。TCP 通信種別のみ有効。
#define POTR_SEND_QUEUE_DEPTH
非同期送信キューの最大エントリ数のデフォルト値。設定ファイルの send_queue_depth で変更可能。メッセージがフラグメント化される場合、1 メッセージが複数エントリを占有する。
#define POTR_MAX_MESSAGE_SIZE
1 回の potrSend で送信できる最大メッセージ長 (バイト) のデフォルト値。設定ファイルの max_message_size で変更可能。フラグメント化により max_payload を超える...
#define POTR_MAX_ADDR_LEN
アドレス文字列の最大長 (バイト、終端 NUL を含む)。
#define POTR_MAX_SERVICES
config_list_service_ids() の初期バッファ容量。サービス数がこれを超えた場合は realloc で自動拡張する。
#define POTR_SUCCESS
成功の戻り値を表す定数。
#define POTR_ERROR
失敗の戻り値を表す定数。
通信ライブラリの定数ファイル。
通信ライブラリの型定義ファイル。
@ POTR_TRACE_INFO
情報。TRACE_LV_INFO (3) と同値。
@ POTR_TRACE_VERBOSE
詳細情報 (デバッグ)。TRACE_LV_VERBOSE (4) と同値。
@ POTR_TRACE_WARNING
警告。回復可能な異常を記録。TRACE_LV_WARNING (2) と同値。
@ POTR_TYPE_BROADCAST_RAW
1:N 通信 RAW モード (UDP ブロードキャスト)。
Definition porter_type.h:88
@ POTR_TYPE_BROADCAST
1:N 通信 (UDP ブロードキャスト)。
Definition porter_type.h:92
@ POTR_TYPE_UNICAST_BIDIR_N1
N:1 双方向通信 (UDP ユニキャスト)。
Definition porter_type.h:96
@ POTR_TYPE_UNICAST
1:1 通信 (UDP ユニキャスト)。
Definition porter_type.h:90
@ POTR_TYPE_MULTICAST_RAW
1:N 通信 RAW モード (UDP マルチキャスト)。
Definition porter_type.h:87
@ POTR_TYPE_TCP_BIDIR
TCP 双方向通信 (両端が potrSend 可)。
@ POTR_TYPE_TCP
TCP ユニキャスト通信 (単方向: SENDER のみ potrSend 可)。
Definition porter_type.h:98
@ POTR_TYPE_UNICAST_RAW
1:1 通信 RAW モード (UDP ユニキャスト)。
Definition porter_type.h:86
@ POTR_TYPE_UNICAST_BIDIR
双方向 1:1 通信 (UDP ユニキャスト)。
Definition porter_type.h:94
@ POTR_TYPE_MULTICAST
1:N 通信 (UDP マルチキャスト)。
Definition porter_type.h:91
porter 内部ログマクロ定義ヘッダー。
#define POTR_LOG(level,...)
porter 内部ログ出力マクロ。
Definition potrLog.h:68
グローバル設定。
uint32_t tcp_health_interval_ms
TCP 通信種別の PING 送信間隔 (ミリ秒)。DATA 送信頻度に関わらず定期的に PING を送信。0 = 無効。設定ファイルキー: tcp_health_interval_ms。
uint16_t window_size
スライディングウィンドウサイズ (パケット数)。
uint32_t reorder_timeout_ms
受信ウィンドウ欠番検出後、NACK または切断を遅延する時間 (ミリ秒)。マルチパスや近距離 WAN での追い越し吸収用。0 = 即時 (デフォルト)。推奨値: LAN/マルチパス=10〜30 ms、遠...
uint32_t send_queue_depth
非同期送信キューの最大エントリ数。デフォルト: POTR_SEND_QUEUE_DEPTH。
uint32_t tcp_health_timeout_ms
TCP 通信種別の PING 応答待機タイムアウト (ミリ秒)。SENDER 側で使用。0 = 無効。設定ファイルキー: tcp_health_timeout_ms。
uint16_t max_payload
最大ペイロード長 (バイト)。
uint32_t health_interval_ms
UDP 通信種別の PING 送信間隔 (ミリ秒)。最終 DATA/PING 送信から本値が経過したら PING 送信。0 = 無効。設定ファイルキー: udp_health_interval_ms。
uint32_t health_timeout_ms
UDP 通信種別の受信タイムアウト (ミリ秒)。RECEIVER 側で使用。0 = 無効。設定ファイルキー: udp_health_timeout_ms。
uint32_t max_message_size
1 回の potrSend で送信できる最大メッセージ長 (バイト)。デフォルト: POTR_MAX_MESSAGE_SIZE。
サービス定義。
uint16_t src_port
送信者の送信元 bind ポート番号。0 = OS 自動選定。(全通信種別で省略可)
uint32_t health_interval_ms
グローバルの udp/tcp_health_interval_ms をサービス単位で上書きする。0 = グローバル値を使用。
uint8_t ttl
マルチキャスト TTL。(multicast のみ)
int encrypt_enabled
非 0 のとき暗号化有効。設定ファイルに有効な encrypt_key が存在するときに 1 に設定される。
uint16_t dst_port
宛先ポート番号。サービスの識別子。受信者の bind ポート / 送信者の送信先ポート。(全通信種別で必須)
char src_addr[POTR_MAX_PATH][POTR_MAX_ADDR_LEN]
送信元アドレス [0]=src_addr1 〜 [3]=src_addr4。送信者は bind / 送信インターフェース、受信者は送信元フィルタ。(全通信種別で必須)
char multicast_group[POTR_MAX_ADDR_LEN]
マルチキャストグループアドレス。(multicast のみ)
PotrType type
通信種別。
int64_t service_id
サービス ID。
uint32_t pack_wait_ms
パッキング待ち時間 (ミリ秒)。最初の送信要求からこの時間だけ待ち合わせ、複数メッセージを 1 パケットにまとめる。0 = 即時送信 (パッキング待ちなし)。パケット容量が満杯になった場合はタイマーを無...
uint32_t connect_timeout_ms
SENDER TCP 接続タイムアウト (ms)。0 = OS デフォルト。デフォルト: POTR_DEFAULT_CONNECT_TIMEOUT_MS。
char dst_addr[POTR_MAX_PATH][POTR_MAX_ADDR_LEN]
宛先アドレス [0]=dst_addr1 〜 [3]=dst_addr4。送信者は送信先、受信者は bind アドレス。(unicast のみ)
uint32_t max_peers
N:1 モード時の最大同時接続ピア数。省略時: 1024。1:1 モードでは無視される。
char broadcast_addr[POTR_MAX_ADDR_LEN]
ブロードキャスト宛先アドレス。省略時は 255.255.255.255。(broadcast のみ)
uint8_t encrypt_key[POTR_CRYPTO_KEY_SIZE]
AES-256-GCM 事前共有鍵 (32 バイト)。encrypt_enabled が 0 の場合は未使用。
uint32_t reconnect_interval_ms
SENDER 自動再接続間隔 (ms)。0 = 再接続なし。デフォルト: POTR_DEFAULT_RECONNECT_INTERVAL_MS。
uint32_t health_timeout_ms
グローバルの udp/tcp_health_timeout_ms をサービス単位で上書きする。0 = グローバル値を使用。