diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 73e52bf4d..f11a57b00 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -1287,8 +1287,18 @@ namespace llarp // override ip and port as needed if (_ourAddress) { - if (not Net().IsBogon(ai.ip)) - throw std::runtime_error{"cannot override public ip, it is already set"}; + const auto ai_ip = ai.IP(); + const auto override_ip = _ourAddress->getIP(); + + auto ai_ip_str = var::visit([](auto&& ip) { return ip.ToString(); }, ai_ip); + auto override_ip_str = var::visit([](auto&& ip) { return ip.ToString(); }, override_ip); + + if ((not Net().IsBogonIP(ai_ip)) and (not Net().IsBogonIP(override_ip)) + and ai_ip != override_ip) + throw std::runtime_error{ + "Lokinet is bound to public IP '{}', but public-ip is set to '{}'. Either fix the " + "[router]:public-ip setting or set a bind address in the [bind] section of the " + "config."_format(ai_ip_str, override_ip_str)}; ai.fromSockAddr(*_ourAddress); } if (RouterContact::BlockBogons && Net().IsBogon(ai.ip)) diff --git a/test/config/test_llarp_config_values.cpp b/test/config/test_llarp_config_values.cpp index 242f5d14d..8276cc59c 100644 --- a/test/config/test_llarp_config_values.cpp +++ b/test/config/test_llarp_config_values.cpp @@ -160,6 +160,26 @@ inbound=127.0.0.1:443 )"; REQUIRE_THROWS(make_config(env, ini_str)); } + SECTION("public ip provided but no bind section") + { + std::string_view ini_str = R"( +[router] +public-ip=1.1.1.1 +public-port=443 +)"; + REQUIRE_NOTHROW(run_config_test(env, ini_str)); + } + SECTION("public ip provided with ip in bind section") + { + std::string_view ini_str = R"( +[router] +public-ip=1.1.1.1 +public-port=443 +[bind] +1.1.1.1=443 +)"; + REQUIRE_NOTHROW(run_config_test(env, ini_str)); + } } TEST_CASE("service node bind section on nat network", "[config]") @@ -212,6 +232,7 @@ inbound=0.0.0.0:443 )"; REQUIRE_THROWS(run_config_test(env, ini_str)); } + } TEST_CASE("service node bind section with multiple public ip", "[config]") @@ -226,7 +247,7 @@ TEST_CASE("service node bind section with multiple public ip", "[config]") std::string_view ini_str = ""; REQUIRE_NOTHROW(run_config_test(env, ini_str)); } - SECTION("with old style wildcard for inbound and no public ip") + SECTION("with old style wildcard for inbound and no public ip, fails") { std::string_view ini_str = R"( [bind] @@ -261,7 +282,7 @@ public-port=443 inbound=0.0.0.0:443 )"; - REQUIRE_THROWS(run_config_test(env, ini_str)); + REQUIRE_NOTHROW(run_config_test(env, ini_str)); } SECTION("with wildcard via inbound directive secondary public ip given") { @@ -273,7 +294,7 @@ public-port=443 inbound=0.0.0.0:443 )"; - REQUIRE_THROWS(run_config_test(env, ini_str)); + REQUIRE_NOTHROW(run_config_test(env, ini_str)); } SECTION("with bind via interface name") {