feat: Go转C
This commit is contained in:
223
c/cmd/kcpserver.c
Normal file
223
c/cmd/kcpserver.c
Normal file
@@ -0,0 +1,223 @@
|
||||
#include "cli_parse.h"
|
||||
#include "server_kcp_hub.h"
|
||||
#include "server_udp_relay.h"
|
||||
|
||||
static void kcpserver_usage(FILE *out) {
|
||||
fprintf(out, "usage: kcpserver [-mode hub|relay] [-listen addr] [-bind-device dev]\n");
|
||||
fprintf(out, " [-latency-log path] [-kcp-ts-debug-log path]\n");
|
||||
fprintf(out, " [-kcp-session-stats-log path] [-kcp-session-stats-interval 100ms]\n");
|
||||
fprintf(out, " [-relay-remote addr] [-relay-listen addr] [-relay-peer addr]\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
const char *mode = "hub";
|
||||
const char *listen_addr = ":9002";
|
||||
const char *bind_device = "";
|
||||
const char *latency_log_path = "";
|
||||
const char *packet_log_path = "";
|
||||
const char *stats_log_path = "";
|
||||
const char *stats_interval_raw = "";
|
||||
const char *relay_listen_alias = "";
|
||||
const char *relay_remote_addr = "";
|
||||
const char *relay_peer_alias = "";
|
||||
int stats_interval_ms = KCP_DEFAULT_STATS_INTERVAL_MS;
|
||||
int i;
|
||||
int rc = 1;
|
||||
|
||||
latency_logger_t *latency_logger = NULL;
|
||||
kcp_packet_debug_logger_t *packet_logger = NULL;
|
||||
kcp_session_stats_logger_t *stats_logger = NULL;
|
||||
kcp_listener_t *listener = NULL;
|
||||
kcp_hub_t *hub = NULL;
|
||||
udp_relay_t *relay = NULL;
|
||||
|
||||
for (i = 1; i < argc; ++i) {
|
||||
const char *value = NULL;
|
||||
int handled;
|
||||
|
||||
if ((handled = cli_parse_value_flag(argc, argv, &i, argv[i], "-mode", &value)) < 0) {
|
||||
fprintf(stderr, "kcpserver: flag -mode requires a value\n");
|
||||
return 1;
|
||||
} else if (handled) {
|
||||
mode = value;
|
||||
continue;
|
||||
}
|
||||
if ((handled = cli_parse_value_flag(argc, argv, &i, argv[i], "-listen", &value)) < 0) {
|
||||
fprintf(stderr, "kcpserver: flag -listen requires a value\n");
|
||||
return 1;
|
||||
} else if (handled) {
|
||||
listen_addr = value;
|
||||
continue;
|
||||
}
|
||||
if ((handled = cli_parse_value_flag(argc, argv, &i, argv[i], "-bind-device", &value)) < 0) {
|
||||
fprintf(stderr, "kcpserver: flag -bind-device requires a value\n");
|
||||
return 1;
|
||||
} else if (handled) {
|
||||
bind_device = value;
|
||||
continue;
|
||||
}
|
||||
if ((handled = cli_parse_value_flag(argc, argv, &i, argv[i], "-latency-log", &value)) < 0) {
|
||||
fprintf(stderr, "kcpserver: flag -latency-log requires a value\n");
|
||||
return 1;
|
||||
} else if (handled) {
|
||||
latency_log_path = value;
|
||||
continue;
|
||||
}
|
||||
if ((handled = cli_parse_value_flag(argc, argv, &i, argv[i], "-kcp-ts-debug-log", &value)) < 0) {
|
||||
fprintf(stderr, "kcpserver: flag -kcp-ts-debug-log requires a value\n");
|
||||
return 1;
|
||||
} else if (handled) {
|
||||
packet_log_path = value;
|
||||
continue;
|
||||
}
|
||||
if ((handled = cli_parse_value_flag(argc, argv, &i, argv[i], "-kcp-session-stats-log", &value)) < 0) {
|
||||
fprintf(stderr, "kcpserver: flag -kcp-session-stats-log requires a value\n");
|
||||
return 1;
|
||||
} else if (handled) {
|
||||
stats_log_path = value;
|
||||
continue;
|
||||
}
|
||||
if ((handled = cli_parse_value_flag(argc, argv, &i, argv[i], "-kcp-session-stats-interval", &value)) < 0) {
|
||||
fprintf(stderr, "kcpserver: flag -kcp-session-stats-interval requires a value\n");
|
||||
return 1;
|
||||
} else if (handled) {
|
||||
stats_interval_raw = value;
|
||||
continue;
|
||||
}
|
||||
if ((handled = cli_parse_value_flag(argc, argv, &i, argv[i], "-relay-listen", &value)) < 0) {
|
||||
fprintf(stderr, "kcpserver: flag -relay-listen requires a value\n");
|
||||
return 1;
|
||||
} else if (handled) {
|
||||
relay_listen_alias = value;
|
||||
continue;
|
||||
}
|
||||
if ((handled = cli_parse_value_flag(argc, argv, &i, argv[i], "-relay-remote", &value)) < 0) {
|
||||
fprintf(stderr, "kcpserver: flag -relay-remote requires a value\n");
|
||||
return 1;
|
||||
} else if (handled) {
|
||||
relay_remote_addr = value;
|
||||
continue;
|
||||
}
|
||||
if ((handled = cli_parse_value_flag(argc, argv, &i, argv[i], "-relay-peer", &value)) < 0) {
|
||||
fprintf(stderr, "kcpserver: flag -relay-peer requires a value\n");
|
||||
return 1;
|
||||
} else if (handled) {
|
||||
relay_peer_alias = value;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
|
||||
kcpserver_usage(stdout);
|
||||
return 0;
|
||||
}
|
||||
fprintf(stderr, "kcpserver: unknown argument %s\n", argv[i]);
|
||||
kcpserver_usage(stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (kcp_session_stats_parse_interval_ms(stats_interval_raw, &stats_interval_ms) != 0) {
|
||||
fprintf(stderr, "kcpserver: invalid -kcp-session-stats-interval value %s\n", stats_interval_raw);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (relay_peer_alias[0] != '\0' && relay_remote_addr[0] != '\0' && strcmp(relay_peer_alias, relay_remote_addr) != 0) {
|
||||
fprintf(stderr, "kcpserver: flags -relay-remote and -relay-peer must match when both are set\n");
|
||||
return 1;
|
||||
}
|
||||
if (relay_remote_addr[0] == '\0' && relay_peer_alias[0] != '\0') {
|
||||
relay_remote_addr = relay_peer_alias;
|
||||
}
|
||||
if (relay_peer_alias[0] != '\0') {
|
||||
fprintf(stderr, "warning: flag -relay-peer is deprecated; use -relay-remote instead\n");
|
||||
}
|
||||
if (relay_listen_alias[0] != '\0') {
|
||||
if (strcmp(mode, "relay") != 0) {
|
||||
fprintf(stderr, "kcpserver: flag -relay-listen may only be used in relay mode\n");
|
||||
return 1;
|
||||
}
|
||||
if (listen_addr[0] != '\0' && strcmp(listen_addr, ":9002") != 0 && strcmp(listen_addr, relay_listen_alias) != 0) {
|
||||
fprintf(stderr, "kcpserver: flags -listen and -relay-listen must match when both are set in relay mode\n");
|
||||
return 1;
|
||||
}
|
||||
listen_addr = relay_listen_alias;
|
||||
fprintf(stderr, "warning: flag -relay-listen is deprecated; use -listen with -mode=relay instead\n");
|
||||
}
|
||||
|
||||
if (strcmp(mode, "hub") == 0) {
|
||||
if (relay_remote_addr[0] != '\0') {
|
||||
fprintf(stderr, "kcpserver: flag -relay-remote may only be used in relay mode\n");
|
||||
return 1;
|
||||
}
|
||||
if (latency_log_path[0] != '\0') {
|
||||
latency_logger = latencylog_open_jsonl(latency_log_path);
|
||||
if (latency_logger == NULL) {
|
||||
fprintf(stderr, "kcpserver: open latency logger %s failed\n", latency_log_path);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (packet_log_path[0] != '\0') {
|
||||
packet_logger = kcp_packet_debug_open_jsonl(packet_log_path);
|
||||
if (packet_logger == NULL) {
|
||||
fprintf(stderr, "kcpserver: open packet debug logger %s failed\n", packet_log_path);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (stats_log_path[0] != '\0') {
|
||||
stats_logger = kcp_session_stats_open_jsonl(stats_log_path);
|
||||
if (stats_logger == NULL) {
|
||||
fprintf(stderr, "kcpserver: open session stats logger %s failed\n", stats_log_path);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
listener = kcp_listener_listen(listen_addr, bind_device, packet_logger, OMNI_NODE_ROLE_SERVER, "hub");
|
||||
if (listener == NULL) {
|
||||
fprintf(stderr, "kcpserver: listen on %s failed\n", listen_addr);
|
||||
goto cleanup;
|
||||
}
|
||||
hub = kcp_hub_new(latency_logger, stats_logger, stats_interval_ms);
|
||||
if (hub == NULL) {
|
||||
fprintf(stderr, "kcpserver: create hub failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
fprintf(stderr, "kcp hub listening on %s\n", listen_addr);
|
||||
if (kcp_hub_serve_listener(hub, listener) != 0) {
|
||||
fprintf(stderr, "kcpserver: serve listener failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
rc = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (strcmp(mode, "relay") == 0) {
|
||||
if (bind_device[0] != '\0') {
|
||||
fprintf(stderr, "kcpserver: flag -bind-device is not supported in relay mode\n");
|
||||
return 1;
|
||||
}
|
||||
if (relay_remote_addr[0] == '\0') {
|
||||
fprintf(stderr, "kcpserver: flag -relay-remote is required in relay mode\n");
|
||||
return 1;
|
||||
}
|
||||
relay = udp_relay_open(listen_addr, relay_remote_addr);
|
||||
if (relay == NULL) {
|
||||
fprintf(stderr, "kcpserver: open udp relay %s -> %s failed\n", listen_addr, relay_remote_addr);
|
||||
goto cleanup;
|
||||
}
|
||||
fprintf(stderr, "udp relay listening on %s and forwarding to %s\n", listen_addr, relay_remote_addr);
|
||||
if (udp_relay_serve(relay) != 0) {
|
||||
fprintf(stderr, "kcpserver: udp relay stopped with error\n");
|
||||
goto cleanup;
|
||||
}
|
||||
rc = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
fprintf(stderr, "kcpserver: unsupported -mode=%s; want hub or relay\n", mode);
|
||||
|
||||
cleanup:
|
||||
udp_relay_free(relay);
|
||||
kcp_hub_free(hub);
|
||||
kcp_listener_free(listener);
|
||||
kcp_session_stats_close(stats_logger);
|
||||
kcp_packet_debug_close(packet_logger);
|
||||
latencylog_close(latency_logger);
|
||||
return rc;
|
||||
}
|
||||
Reference in New Issue
Block a user