forked from Mirrors/openclonk
Fix host connections on link-local IPv6 addresses
Link-local IPv6 addresses are valid on all interfaces and thus need an interface specifier / scope id, e.g. fe80::1%eth0. This commit adds scope ids for initial host connections only. While not optimal, this is probably enough in practise as the link-local addresses are likely only important when there is no internet connectivity. In this case, connecting clients directly is less of an advantage.ipv6
parent
5d803d3be3
commit
0137c5f929
|
@ -244,6 +244,16 @@ bool C4NetIO::HostAddress::IsLoopback() const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool C4NetIO::HostAddress::IsLocal() const
|
||||
{
|
||||
if (gen.sa_family == AF_INET6)
|
||||
return IN6_IS_ADDR_LINKLOCAL(&v6.sin6_addr) != 0;
|
||||
// We don't really care about local 169.256.0.0/16 addresses here as users will either have a
|
||||
// router doing DHCP (which will prevent usage of these addresses) or have a network that
|
||||
// doesn't care about IP and IPv6 link-local addresses will work.
|
||||
return false;
|
||||
}
|
||||
|
||||
void C4NetIO::HostAddress::SetScopeId(int scopeId)
|
||||
{
|
||||
if (gen.sa_family != AF_INET6) return;
|
||||
|
|
|
@ -111,6 +111,7 @@ public:
|
|||
bool IsNull() const;
|
||||
bool IsMulticast() const;
|
||||
bool IsLoopback() const;
|
||||
bool IsLocal() const;
|
||||
// bool IsBroadcast() const;
|
||||
|
||||
StdStrBuf ToString(int flags = 0) const;
|
||||
|
|
|
@ -310,9 +310,25 @@ C4Network2::InitResult C4Network2::InitClient(const class C4Network2Address *pAd
|
|||
for (int i = 0; i < iAddrCount; i++)
|
||||
if (!pAddrs[i].isIPNull())
|
||||
{
|
||||
auto addr = pAddrs[i].getAddr();
|
||||
std::vector<C4NetIO::addr_t> addrs;
|
||||
if (addr.IsLocal())
|
||||
{
|
||||
// Local IPv6 addresses need a scope id.
|
||||
for (auto& id : Clients.GetLocal()->getInterfaceIDs())
|
||||
{
|
||||
addr.SetScopeId(id);
|
||||
addrs.push_back(addr);
|
||||
}
|
||||
}
|
||||
else
|
||||
addrs.push_back(addr);
|
||||
// connection
|
||||
if (!NetIO.Connect(pAddrs[i].getAddr(), pAddrs[i].getProtocol(), HostCore, szPassword))
|
||||
continue;
|
||||
int cnt = 0;
|
||||
for (auto& a : addrs)
|
||||
if (NetIO.Connect(a, pAddrs[i].getProtocol(), HostCore, szPassword))
|
||||
cnt++;
|
||||
if (cnt == 0) continue;
|
||||
// format for message
|
||||
if (strAddresses.getLength())
|
||||
strAddresses.Append(", ");
|
||||
|
|
|
@ -231,6 +231,8 @@ void C4Network2Client::AddLocalAddrs(int16_t iPortTCP, int16_t iPortUDP)
|
|||
addr.SetPort(iPortUDP);
|
||||
AddAddr(C4Network2Address(addr, P_UDP), false);
|
||||
}
|
||||
if (addr.GetScopeId())
|
||||
InterfaceIDs.insert(addr.GetScopeId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -257,6 +259,8 @@ void C4Network2Client::AddLocalAddrs(int16_t iPortTCP, int16_t iPortUDP)
|
|||
addr.SetPort(iPortUDP);
|
||||
AddAddr(C4Network2Address(addr, P_UDP), false);
|
||||
}
|
||||
if (addr.GetScopeId())
|
||||
InterfaceIDs.insert(addr.GetScopeId());
|
||||
}
|
||||
}
|
||||
freeifaddrs(addrs);
|
||||
|
|
|
@ -57,6 +57,9 @@ protected:
|
|||
int32_t AddrAttempts[C4ClientMaxAddr];
|
||||
int32_t iAddrCnt;
|
||||
|
||||
// interface ids
|
||||
std::set<int> InterfaceIDs;
|
||||
|
||||
// status
|
||||
C4Network2ClientStatus eStatus;
|
||||
|
||||
|
@ -88,6 +91,8 @@ public:
|
|||
int32_t getAddrCnt() const { return iAddrCnt; }
|
||||
const C4Network2Address &getAddr(int32_t i) const { return Addr[i]; }
|
||||
|
||||
const std::set<int> &getInterfaceIDs() const { return InterfaceIDs; }
|
||||
|
||||
C4Network2ClientStatus getStatus() const { return eStatus; }
|
||||
bool hasJoinData() const { return getStatus() != NCS_Joining; }
|
||||
bool isChasing() const { return getStatus() == NCS_Chasing; }
|
||||
|
|
Loading…
Reference in New Issue