From 6de7db4765334096a3ac39149cf5016e8ba12c8d Mon Sep 17 00:00:00 2001 From: James Osborne Date: Fri, 15 May 2026 15:06:32 -0400 Subject: [PATCH] Add IP stack port remapping --- src/IPStackSimulator.cc | 21 ++++++++++++++++++--- src/ServerState.cc | 17 +++++++++++++++++ src/ServerState.hh | 1 + 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/IPStackSimulator.cc b/src/IPStackSimulator.cc index 492f849e..0cd1793e 100644 --- a/src/IPStackSimulator.cc +++ b/src/IPStackSimulator.cc @@ -1356,9 +1356,24 @@ asio::awaitable IPStackSimulator::open_server_connection( string conn_str = this->str_for_tcp_connection(c, conn); // Figure out which logical port the connection should go to - auto port_config_it = this->state->number_to_port_config.find(conn->server_port); + uint16_t effective_server_port = conn->server_port; + auto remap_it = this->state->ip_stack_port_remap.find(effective_server_port); + if (remap_it != this->state->ip_stack_port_remap.end()) { + this->log.info_f( + "Remapping IP stack TCP destination port {} to {} for connection {}", + effective_server_port, + remap_it->second, + conn_str); + effective_server_port = remap_it->second; + } + + auto port_config_it = this->state->number_to_port_config.find(effective_server_port); if (port_config_it == this->state->number_to_port_config.end()) { - this->log.error_f("TCP connection {} is to undefined port {}", conn_str, conn->server_port); + this->log.error_f( + "TCP connection {} is to undefined port {} after remap from {}", + conn_str, + effective_server_port, + conn->server_port); co_await this->close_tcp_connection(c, conn); co_return; } @@ -1371,7 +1386,7 @@ asio::awaitable IPStackSimulator::open_server_connection( co_await this->close_tcp_connection(c, conn); co_return; } else { - this->state->game_server->connect_channel(conn->server_channel, conn->server_port, port_config->behavior); + this->state->game_server->connect_channel(conn->server_channel, effective_server_port, port_config->behavior); this->log.info_f("Connected TCP connection {} to game server", conn_str); } } diff --git a/src/ServerState.cc b/src/ServerState.cc index 71052f2d..0069aa7f 100644 --- a/src/ServerState.cc +++ b/src/ServerState.cc @@ -737,6 +737,23 @@ void ServerState::load_config_early() { } this->set_port_configuration(parse_port_configuration(this->config_json->at("PortConfiguration"))); + + this->ip_stack_port_remap.clear(); + try { + for (const auto& item : this->config_json->at("IPStackPortRemap").as_dict()) { + uint64_t from_port = stoull(item.first, nullptr, 0); + uint64_t to_port = item.second->as_int(); + + if (from_port > 0xFFFF || to_port > 0xFFFF) { + throw runtime_error("IPStackPortRemap port number is out of range"); + } + + this->ip_stack_port_remap.emplace( + static_cast(from_port), + static_cast(to_port)); + } + } catch (const out_of_range&) { + } try { auto spec = this->parse_port_spec(this->config_json->at("DNSServerPort")); this->dns_server_addr = std::move(spec.first); diff --git a/src/ServerState.hh b/src/ServerState.hh index 78c5a4c7..f2540f04 100644 --- a/src/ServerState.hh +++ b/src/ServerState.hh @@ -112,6 +112,7 @@ struct ServerState : public std::enable_shared_from_this { std::string name; std::unordered_map> name_to_port_config; std::unordered_map> number_to_port_config; + std::unordered_map ip_stack_port_remap; std::string username; std::string dns_server_addr; uint16_t dns_server_port = 0;