proper autodetect of ifname and ifaddr

pull/1256/head
Jeff Becker 4 years ago
parent 6aa79b7ca9
commit e33a1a2e0f
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -195,10 +195,27 @@ namespace llarp
m_mapAddr = arg;
});
conf.defineOption<std::string>(
"network", "ifaddr", false, "", [this](std::string arg) { m_ifaddr = arg; });
conf.defineOption<std::string>(
"network", "ifname", false, "", [this](std::string arg) { m_ifname = arg; });
conf.defineOption<std::string>("network", "ifaddr", false, "", [this](std::string arg) {
if (arg.empty())
{
const auto maybe = llarp::FindFreeRange();
if (not maybe.has_value())
throw std::invalid_argument("cannot determine free ip range");
arg = maybe.value();
}
m_ifaddr = arg;
});
conf.defineOption<std::string>("network", "ifname", false, "", [this](std::string arg) {
if (arg.empty())
{
const auto maybe = llarp::FindFreeTun();
if (not maybe.has_value())
throw std::invalid_argument("cannot determine free interface name");
arg = maybe.value();
}
m_ifname = arg;
});
conf.defineOption<std::string>(
"network", "blacklist-snode", false, true, "", [this](std::string arg) {

@ -109,8 +109,8 @@ namespace llarp
{
if (conf.m_reachable)
{
m_PublishIntroSet = true;
LogInfo(Name(), " setting to be reachable by default");
m_PublishIntroSet = true;
LogInfo(Name(), " setting to be reachable by default");
}
else
{
@ -252,9 +252,6 @@ namespace llarp
}
std::string ifname = conf.m_ifname;
if (ifname.empty())
ifname = FindFreeTun();
if (tunif)
{
if (ifname.length() >= sizeof(tunif->ifname))
@ -267,9 +264,6 @@ namespace llarp
}
std::string ifaddr = conf.m_ifaddr;
if (ifaddr.empty())
ifaddr = FindFreeRange();
if (tunif)
{
std::string addr;

@ -344,10 +344,13 @@ llarp_getifaddr(const char* ifname, int af, struct sockaddr* addr)
#else
if (!strcmp(ifname, "lo") || !strcmp(ifname, "lo0"))
{
sockaddr_in* lo = (sockaddr_in*)addr;
lo->sin_family = af;
lo->sin_port = 0;
inet_pton(af, "127.0.0.1", &lo->sin_addr);
if (addr)
{
sockaddr_in* lo = (sockaddr_in*)addr;
lo->sin_family = af;
lo->sin_port = 0;
inet_pton(af, "127.0.0.1", &lo->sin_addr);
}
return true;
}
if (!getifaddrs(&ifa))
@ -367,13 +370,16 @@ llarp_getifaddr(const char* ifname, int af, struct sockaddr* addr)
// if(!a.isPrivate())
//{
// llarp::LogInfo(__FILE__, "found ", ifname, " af: ", af);
memcpy(addr, i->ifa_addr, sl);
if (af == AF_INET6)
if (addr)
{
// set scope id
auto* ip6addr = (sockaddr_in6*)addr;
ip6addr->sin6_scope_id = if_nametoindex(ifname);
ip6addr->sin6_flowinfo = 0;
memcpy(addr, i->ifa_addr, sl);
if (af == AF_INET6)
{
// set scope id
auto* ip6addr = (sockaddr_in6*)addr;
ip6addr->sin6_scope_id = if_nametoindex(ifname);
ip6addr->sin6_flowinfo = 0;
}
}
found = true;
break;
@ -436,7 +442,7 @@ namespace llarp
}
// TODO: ipv6?
std::string
std::optional<std::string>
FindFreeRange()
{
std::vector<IPRange> currentRanges;
@ -505,43 +511,26 @@ namespace llarp
return loaddr.ToString() + "/24";
++oct;
}
LogError(
"cannot autodetect any free ip ranges on your system for use, please "
"configure this manually");
return "";
return std::nullopt;
}
std::string
std::optional<std::string>
FindFreeTun()
{
uint8_t num = 0;
int num = 0;
while (num < 255)
{
std::stringstream ifname_ss;
ifname_ss << "lokitun" << num;
std::string iftestname = ifname_ss.str();
struct sockaddr addr;
bool found = llarp_getifaddr(iftestname.c_str(), AF_INET, &addr);
bool found = llarp_getifaddr(iftestname.c_str(), AF_INET, nullptr);
if (!found)
{
llarp::LogDebug("Detected " + iftestname + " is available for use, configuring as such");
break;
return iftestname;
}
num++;
}
if (num == 255)
{
llarp::LogError("Could not find any free lokitun interface names");
return "";
}
// include lokitun prefix to communicate result is valid
#if defined(ANDROID) || defined(RPI)
char buff[IFNAMSIZ + 1] = {0};
snprintf(buff, sizeof(buff), "lokitun%u", num);
return buff;
#else
return "lokitun" + std::to_string(num);
#endif
return std::nullopt;
}
bool

@ -168,11 +168,11 @@ namespace llarp
GetBestNetIF(std::string& ifname, int af = AF_INET);
/// look at adapter ranges and find a free one
std::string
std::optional<std::string>
FindFreeRange();
/// look at adapter names and find a free one
std::string
std::optional<std::string>
FindFreeTun();
/// get network interface address for network interface with ifname

Loading…
Cancel
Save