forked from Mirrors/openclonk
Change (discovery) multicast to IPv6
We use ff02::1 as discovery multicast address. This "all nodes" multicast address is good enough for discovery in the local network as packets there are likely broadcasted over ethernet anyways.ipv6
parent
0137c5f929
commit
758e7ca41e
|
@ -356,6 +356,17 @@ void C4NetIO::HostAddress::SetHost(uint32_t v4addr)
|
|||
memset(&v4.sin_zero, 0, sizeof(v4.sin_zero));
|
||||
}
|
||||
|
||||
void C4NetIO::HostAddress::SetHost(const StdStrBuf &addr)
|
||||
{
|
||||
addrinfo hints = addrinfo();
|
||||
addrinfo *addresses = nullptr;
|
||||
if (getaddrinfo(addr.getData(), nullptr, &hints, &addresses) != 0)
|
||||
// GAI failed
|
||||
return;
|
||||
SetHost(addresses->ai_addr);
|
||||
freeaddrinfo(addresses);
|
||||
}
|
||||
|
||||
void C4NetIO::EndpointAddress::SetAddress(const StdStrBuf &addr)
|
||||
{
|
||||
Clear();
|
||||
|
@ -1767,7 +1778,7 @@ bool C4NetIOSimpleUDP::InitBroadcast(addr_t *pBroadcastAddr)
|
|||
if (fMultiCast) CloseBroadcast();
|
||||
|
||||
// broadcast addr valid?
|
||||
if (pBroadcastAddr->IsMulticast())
|
||||
if (!pBroadcastAddr->IsMulticast())
|
||||
{
|
||||
SetError("invalid broadcast address");
|
||||
return false;
|
||||
|
@ -1779,8 +1790,8 @@ bool C4NetIOSimpleUDP::InitBroadcast(addr_t *pBroadcastAddr)
|
|||
}
|
||||
|
||||
// set mc ttl to somewhat about "same net"
|
||||
int iTTL = 16;
|
||||
if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, reinterpret_cast<char*>(&iTTL), sizeof(iTTL)) == SOCKET_ERROR)
|
||||
int TTL = 16;
|
||||
if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, reinterpret_cast<char*>(&TTL), sizeof(TTL)) == SOCKET_ERROR)
|
||||
{
|
||||
SetError("could not set mc ttl", true);
|
||||
return false;
|
||||
|
@ -1788,11 +1799,12 @@ bool C4NetIOSimpleUDP::InitBroadcast(addr_t *pBroadcastAddr)
|
|||
|
||||
// set up multicast group information
|
||||
this->MCAddr = *pBroadcastAddr;
|
||||
MCGrpInfo.imr_multiaddr = static_cast<sockaddr_in*>(&MCAddr)->sin_addr;
|
||||
MCGrpInfo.imr_interface.s_addr = INADDR_ANY;
|
||||
MCGrpInfo.ipv6mr_multiaddr = static_cast<sockaddr_in6>(MCAddr).sin6_addr;
|
||||
// TODO: do multicast on all interfaces?
|
||||
MCGrpInfo.ipv6mr_interface = 0; // default interface
|
||||
|
||||
// join multicast group
|
||||
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
|
||||
if (setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
|
||||
reinterpret_cast<const char *>(&MCGrpInfo), sizeof(MCGrpInfo)) == SOCKET_ERROR)
|
||||
{
|
||||
SetError("could not join multicast group"); // to do: more error information
|
||||
|
@ -1854,10 +1866,10 @@ bool C4NetIOSimpleUDP::CloseBroadcast()
|
|||
if (!fMultiCast) return true;
|
||||
|
||||
// leave multicast group
|
||||
if (setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP,
|
||||
if (setsockopt(sock, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP,
|
||||
reinterpret_cast<const char *>(&MCGrpInfo), sizeof(MCGrpInfo)) == SOCKET_ERROR)
|
||||
{
|
||||
SetError("could not join multicast group"); // to do: more error information
|
||||
SetError("could not leave multicast group"); // to do: more error information
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2059,10 +2071,10 @@ enum C4NetIOSimpleUDP::WaitResult C4NetIOSimpleUDP::WaitForSocket(int iTimeout)
|
|||
bool C4NetIOSimpleUDP::SetMCLoopback(int fLoopback)
|
||||
{
|
||||
// enable/disable MC loopback
|
||||
setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, reinterpret_cast<char *>(&fLoopback), sizeof fLoopback);
|
||||
setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, reinterpret_cast<char *>(&fLoopback), sizeof fLoopback);
|
||||
// read result
|
||||
socklen_t iSize = sizeof(fLoopback);
|
||||
if (getsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, reinterpret_cast<char *>(&fLoopback), &iSize) == SOCKET_ERROR)
|
||||
if (getsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, reinterpret_cast<char *>(&fLoopback), &iSize) == SOCKET_ERROR)
|
||||
return false;
|
||||
fMCLoopback = !! fLoopback;
|
||||
return true;
|
||||
|
|
|
@ -193,8 +193,8 @@ public:
|
|||
|
||||
// conversions
|
||||
operator sockaddr() const { return gen; }
|
||||
/* operator sockaddr_in() const { assert(gen.sa_family == AF_INET); return v4; }
|
||||
operator sockaddr_in6() const { assert(gen.sa_family == AF_INET6); return v6; }*/
|
||||
operator sockaddr_in() const { assert(gen.sa_family == AF_INET); return v4; }
|
||||
operator sockaddr_in6() const { assert(gen.sa_family == AF_INET6); return v6; }
|
||||
|
||||
// StdCompiler
|
||||
void CompileFunc(StdCompiler *comp);
|
||||
|
@ -533,7 +533,7 @@ private:
|
|||
#endif
|
||||
|
||||
// multicast
|
||||
addr_t MCAddr; ip_mreq MCGrpInfo;
|
||||
addr_t MCAddr; ipv6_mreq MCGrpInfo;
|
||||
bool fMCLoopback;
|
||||
|
||||
// multibind
|
||||
|
|
|
@ -17,6 +17,17 @@
|
|||
#include "network/C4Network2Discover.h"
|
||||
|
||||
// *** C4Network2IODiscover
|
||||
//
|
||||
// Quick multicast discovery guide by Luchs:
|
||||
//
|
||||
// All engines in network mode join a multicast group (defined by C4NetDiscoveryAddress).
|
||||
//
|
||||
// Engines searching for a game ("client") send a single byte c = 3 to that multicast group. This
|
||||
// happens while on the network list on each refresh.
|
||||
//
|
||||
// Engines hosting a game (when going into the lobby) send a byte c = 4 plus their reference server
|
||||
// port to the multicast group. Additionally, they listen for the c = 3 bytes and will reply with
|
||||
// another multicast answer.
|
||||
|
||||
struct C4Network2IODiscoverReply
|
||||
{
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
const int C4NetMaxDiscover = 64;
|
||||
|
||||
const C4NetIO::HostAddress C4NetDiscoveryAddress = C4NetIO::HostAddress(0xef000000); // 239.0.0.0
|
||||
const C4NetIO::HostAddress C4NetDiscoveryAddress = C4NetIO::HostAddress(StdStrBuf("ff02::1"));
|
||||
|
||||
class C4Network2IODiscover : public C4NetIOSimpleUDP, private C4NetIO::CBClass
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue