diff --git a/src/config_parser.c b/src/config_parser.c index 14b2ed60..bb25f844 100644 --- a/src/config_parser.c +++ b/src/config_parser.c @@ -10,6 +10,8 @@ #include #include "../lib/platform_compat.h" #include +#include +#include "transport_layer/etcp_connections.h" #ifndef _WIN32 #include #include @@ -379,7 +381,15 @@ static int parse_global(const char *key, const char *value, struct global_config return 0; } if (strcmp(key, "bbr_max_cwnd") == 0) { - global->bbr_max_cwnd = atoi(value); + char* end; + errno = 0; + long parsed = strtol(value, &end, 10); + if (errno || end == value || *end || parsed < INFLIGHT_LIM_MIN || parsed > INT_MAX) { + DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "%s:%d: invalid bbr_max_cwnd '%s'; expected %u..%d bytes", + filename, line_num, value, INFLIGHT_LIM_MIN, INT_MAX); + return -1; + } + global->bbr_max_cwnd = (int)parsed; return 0; } if (strcmp(key, "auto_sockets") == 0) { @@ -1121,7 +1131,12 @@ struct utun_config* parse_config_from_buf(const char *buf, size_t len, const cha continue; } switch (cur_section) { - case SECTION_GLOBAL: parse_global(key, value, &cfg->global, filename, line_num); break; + case SECTION_GLOBAL: + if (parse_global(key, value, &cfg->global, filename, line_num) < 0) { + DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "%s:%d: invalid global option %s=%s", filename, line_num, key, value); + goto error; + } + break; case SECTION_SERVER: if (cur_server) parse_server(key, value, cur_server, filename, line_num); break; case SECTION_CLIENT: if (cur_client) parse_client(key, value, cur_client, cfg->servers, filename, line_num); break; case SECTION_ROUTING: if (strcmp(key, "route_subnet") == 0) add_route_entry(&cfg->route_subnets, value); else if (strcmp(key, "my_subnet") == 0) add_route_entry(&cfg->my_subnets, value); else DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "%s:%d: Unknown routing option '%s'", filename, line_num, key); break; diff --git a/src/transport_layer/etcp.c b/src/transport_layer/etcp.c index 26dde4cd..f692929a 100644 --- a/src/transport_layer/etcp.c +++ b/src/transport_layer/etcp.c @@ -291,6 +291,11 @@ struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance, char* n etcp->inflight_pool = memory_pool_init(sizeof(struct INFLIGHT_PACKET), "inflight_pool"); etcp->io_pool = memory_pool_init(sizeof(struct ETCP_FRAGMENT), "io_pool"); etcp->max_inflight = (uint32_t)instance->config->global.bbr_max_cwnd; + if (instance->config->global.bbr_max_cwnd < INFLIGHT_LIM_MIN) { + DEBUG_WARN(DEBUG_CATEGORY_ETCP, "ETCP config cwnd=%d raised to minimum %u bytes", + instance->config->global.bbr_max_cwnd, INFLIGHT_LIM_MIN); + etcp->max_inflight = INFLIGHT_LIM_MIN; + } etcp->optimal_inflight=100000; etcp->initialized=0; etcp->links_up=0; @@ -950,9 +955,9 @@ static void input_queue_try_resume(struct ETCP_CONN* etcp) {// при ACK // Recalculates connection-level optimal_inflight and resumes input_queue if room opened up. void etcp_conn_on_inflight_lim_changed(struct ETCP_CONN* etcp) { if (!etcp || etcp->state == 2) return; - uint32_t sum = 0; + uint64_t sum = 0; for (struct ETCP_LINK* tl = etcp->links; tl; tl = tl->next) sum += tl->inflight_lim_bytes; - etcp->optimal_inflight = sum; + etcp->optimal_inflight = sum > UINT32_MAX ? UINT32_MAX : (uint32_t)sum; etcp_conn_wake_sender(etcp); }