From 841abffaf5bd3c65227275a6f9702dd01ae43558 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Thu, 21 Jul 2022 17:47:27 -0300 Subject: [PATCH] Make outbound wildcard default to inbound IP outbound=:1234 outbound=0.0.0.0:1234 outbound= outbound=0.0.0.0 now all default to use the inbound= IP. (If multiple inbound= IPs are given, we raise an exception to abort startup). Only applies to routers (since clients don't have inbound IPs), and eliminates potential weird edge cases with local system IP and routing shenanigans. --- llarp/config/config.cpp | 30 ++++++++++++++++++++++++------ llarp/router/router.cpp | 22 ++++++++++++++-------- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index a1f15456f..90be0b1ee 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -936,7 +936,8 @@ namespace llarp "IP and/or port to listen on for incoming connections.", "", "If IP is omitted then lokinet will search for a local network interface with a", - "public IP address and use that IP. If port is omitted then lokinet defaults to 1090.", + "public IP address and use that IP (and will exit with an error if no such IP is found", + "on the system). If port is omitted then lokinet defaults to 1090.", "", "Examples:", " inbound=15.5.29.5:443", @@ -957,19 +958,36 @@ namespace llarp "bind", "outbound", MultiValue, - Comment{ + params.isRelay ? Comment{ + "IP and/or port to use for outbound socket connections to other lokinet routers.", + "", + "If no outbound bind IP is configured, or the 0.0.0.0 wildcard IP is given, then", + "lokinet will bind to the same IP being used for inbound connections (either an", + "explicit inbound= provided IP, or the default). If no port is given, or port is", + "given as 0, then a random high port will be used.", + "", + "If using multiple inbound= addresses then you *must* provide an explicit oubound= IP.", + "", + "Examples:", + " outbound=1.2.3.4:5678", + " outbound=:9000", + " outbound=8.9.10.11", + "", + "The second example binds on the default incoming IP using port 9000; the third", + "example binds on the given IP address using a random high port.", + } : Comment{ "IP and/or port to use for outbound socket connections to lokinet routers.", "", - "If no outbound bind IP is configured then lokinet will use a wildcard address to use", - "any available local IP. If no port is given, or port is given as 0, then a random", - "high port will be used.", + "If no outbound bind IP is configured then lokinet will use a wildcard IP address", + "(equivalent to specifying 0.0.0.0). If no port is given then a random high port", + "will be used.", "", "Examples:", " outbound=1.2.3.4:5678", " outbound=:9000", " outbound=8.9.10.11", "", - "The second example binds an outbound socket on all interfaces; the third example", + "The second example binds on the wildcard address using port 9000; the third example", "binds on the given IP address using a random high port.", }, [this, net_ptr, parse_addr_for_link](const std::string& arg) { diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 2c017c9d9..e50ad8e05 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -1645,7 +1645,7 @@ namespace llarp if (addrs.empty()) addrs.emplace_back(Net().Wildcard()); - for (auto bind_addr : addrs) + for (auto& bind_addr : addrs) { auto link = iwp::NewOutboundLink( m_keyManager, @@ -1671,13 +1671,19 @@ namespace llarp const auto& net = Net(); - // try to use a public address if we have one set on our inbound links - _linkManager.ForEachInboundLink([&bind_addr, &net](const auto& link) { - if (not net.IsBogon(bind_addr)) - return; - if (auto addr = link->LocalSocketAddr(); not net.IsBogon(addr)) - bind_addr.setIP(addr.getIP()); - }); + // If outbound is set to wildcard and we have just one inbound, then bind to the inbound IP; + // if you have more than one inbound you have to be explicit about your outbound. + if (net.IsWildcardAddress(bind_addr.getIP())) + { + bool multiple = false; + _linkManager.ForEachInboundLink([&bind_addr, &multiple](const auto& link) { + if (multiple) + throw std::runtime_error{ + "outbound= IP address must be specified when using multiple inbound= addresses"}; + multiple = true; + bind_addr.setIP(link->LocalSocketAddr().getIP()); + }); + } link->Bind(this, bind_addr);