Add IPv6 LAN server discovery
Broadcasting to windows doesn't work as the windows firewall seems to block all IPv6 multicast
This commit is contained in:
parent
9132fba714
commit
e18bcd62e6
@ -815,6 +815,9 @@ namespace UserConfigParams
|
|||||||
PARAM_PREFIX BoolUserConfigParam m_race_chat
|
PARAM_PREFIX BoolUserConfigParam m_race_chat
|
||||||
PARAM_DEFAULT(BoolUserConfigParam(true, "race-chat",
|
PARAM_DEFAULT(BoolUserConfigParam(true, "race-chat",
|
||||||
&m_network_group, "Enable chatting during races."));
|
&m_network_group, "Enable chatting during races."));
|
||||||
|
PARAM_PREFIX BoolUserConfigParam m_ipv6_lan
|
||||||
|
PARAM_DEFAULT(BoolUserConfigParam(true, "ipv6-lan",
|
||||||
|
&m_network_group, "Enable IPv6 LAN server discovery."));
|
||||||
PARAM_PREFIX IntUserConfigParam m_max_players
|
PARAM_PREFIX IntUserConfigParam m_max_players
|
||||||
PARAM_DEFAULT(IntUserConfigParam(8, "max-players",
|
PARAM_DEFAULT(IntUserConfigParam(8, "max-players",
|
||||||
&m_network_group, "Maximum number of players on the server "
|
&m_network_group, "Maximum number of players on the server "
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "network/protocol_manager.hpp"
|
#include "network/protocol_manager.hpp"
|
||||||
#include "network/servers_manager.hpp"
|
#include "network/servers_manager.hpp"
|
||||||
#include "network/server.hpp"
|
#include "network/server.hpp"
|
||||||
|
#include "network/socket_address.hpp"
|
||||||
#include "network/stk_ipv6.hpp"
|
#include "network/stk_ipv6.hpp"
|
||||||
#include "network/stk_host.hpp"
|
#include "network/stk_host.hpp"
|
||||||
#include "network/stk_peer.hpp"
|
#include "network/stk_peer.hpp"
|
||||||
@ -155,7 +156,7 @@ void ConnectToServer::getClientServerInfo()
|
|||||||
m_server->setPrivatePort(port);
|
m_server->setPrivatePort(port);
|
||||||
if (server_ipv6_socket)
|
if (server_ipv6_socket)
|
||||||
{
|
{
|
||||||
m_server->setIPV6Address("::1");
|
m_server->setIPV6Address(SocketAddress("::1", port));
|
||||||
m_server->setIPV6Connection(true);
|
m_server->setIPV6Connection(true);
|
||||||
}
|
}
|
||||||
if (server_id != 0)
|
if (server_id != 0)
|
||||||
@ -409,38 +410,47 @@ bool ConnectToServer::tryConnect(int timeout, int retry, bool another_port,
|
|||||||
|
|
||||||
if (ipv6)
|
if (ipv6)
|
||||||
{
|
{
|
||||||
struct addrinfo hints;
|
|
||||||
struct addrinfo* res = NULL;
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
|
||||||
hints.ai_family = AF_UNSPEC;
|
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
|
||||||
std::string addr_string = m_server->getIPV6Address();
|
|
||||||
std::string port =
|
|
||||||
StringUtils::toString(m_server_address.getPort());
|
|
||||||
// Convert to a NAT64 address from IPv4
|
// Convert to a NAT64 address from IPv4
|
||||||
if (!m_server->useIPV6Connection() &&
|
if (!m_server->useIPV6Connection() &&
|
||||||
NetworkConfig::get()->getIPType() == NetworkConfig::IP_V6_NAT64)
|
NetworkConfig::get()->getIPType() == NetworkConfig::IP_V6_NAT64)
|
||||||
{
|
{
|
||||||
|
struct addrinfo hints;
|
||||||
|
struct addrinfo* res = NULL;
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
// From IPv4
|
// From IPv4
|
||||||
addr_string = m_server_address.toString(false/*show_port*/);
|
std::string addr_string =
|
||||||
|
m_server_address.toString(false/*show_port*/);
|
||||||
addr_string = NetworkConfig::get()->getNAT64Prefix() + addr_string;
|
addr_string = NetworkConfig::get()->getNAT64Prefix() + addr_string;
|
||||||
}
|
std::string port =
|
||||||
if (getaddrinfo_compat(addr_string.c_str(), port.c_str(),
|
StringUtils::toString(m_server_address.getPort());
|
||||||
&hints, &res) != 0 || res == NULL)
|
if (getaddrinfo_compat(addr_string.c_str(), port.c_str(),
|
||||||
return false;
|
&hints, &res) != 0 || res == NULL)
|
||||||
for (const struct addrinfo* addr = res; addr != NULL;
|
return false;
|
||||||
addr = addr->ai_next)
|
for (const struct addrinfo* addr = res; addr != NULL;
|
||||||
{
|
addr = addr->ai_next)
|
||||||
if (addr->ai_family == AF_INET6)
|
|
||||||
{
|
{
|
||||||
struct sockaddr_in6* ipv6_sock =
|
if (addr->ai_family == AF_INET6)
|
||||||
(struct sockaddr_in6*)addr->ai_addr;
|
{
|
||||||
ENetAddress en_addr = m_server_address.toEnetAddress();
|
struct sockaddr_in6* ipv6_sock =
|
||||||
addMappedAddress(&en_addr, ipv6_sock);
|
(struct sockaddr_in6*)addr->ai_addr;
|
||||||
break;
|
ENetAddress en_addr = m_server_address.toEnetAddress();
|
||||||
|
addMappedAddress(&en_addr, ipv6_sock);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
freeaddrinfo(res);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SocketAddress* sa = m_server->getIPV6Address();
|
||||||
|
if (!sa)
|
||||||
|
return false;
|
||||||
|
ENetAddress en_addr = m_server_address.toEnetAddress();
|
||||||
|
struct sockaddr_in6* in6 = (struct sockaddr_in6*)sa->getSockaddr();
|
||||||
|
addMappedAddress(&en_addr, in6);
|
||||||
}
|
}
|
||||||
freeaddrinfo(res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (--m_retry_count >= 0 && !ProtocolManager::lock()->isExiting())
|
while (--m_retry_count >= 0 && !ProtocolManager::lock()->isExiting())
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "online/online_profile.hpp"
|
#include "online/online_profile.hpp"
|
||||||
#include "online/profile_manager.hpp"
|
#include "online/profile_manager.hpp"
|
||||||
#include "network/network_config.hpp"
|
#include "network/network_config.hpp"
|
||||||
|
#include "network/socket_address.hpp"
|
||||||
#include "tracks/track_manager.hpp"
|
#include "tracks/track_manager.hpp"
|
||||||
#include "utils/constants.hpp"
|
#include "utils/constants.hpp"
|
||||||
#include "utils/string_utils.hpp"
|
#include "utils/string_utils.hpp"
|
||||||
@ -58,13 +59,16 @@ Server::Server(const XMLNode& server_info) : m_supports_encrytion(true)
|
|||||||
xml.get("max_players", &m_max_players);
|
xml.get("max_players", &m_max_players);
|
||||||
xml.get("current_players", &m_current_players);
|
xml.get("current_players", &m_current_players);
|
||||||
xml.get("current_track", &m_current_track);
|
xml.get("current_track", &m_current_track);
|
||||||
xml.get("ipv6", &m_ipv6_address);
|
|
||||||
uint32_t ip;
|
uint32_t ip;
|
||||||
xml.get("ip", &ip);
|
xml.get("ip", &ip);
|
||||||
m_address.setIP(ip);
|
m_address.setIP(ip);
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
xml.get("port", &port);
|
xml.get("port", &port);
|
||||||
m_address.setPort(port);
|
m_address.setPort(port);
|
||||||
|
std::string ipv6_address;
|
||||||
|
xml.get("ipv6", &ipv6_address);
|
||||||
|
if (!ipv6_address.empty())
|
||||||
|
m_ipv6_address.reset(new SocketAddress(ipv6_address, port));
|
||||||
xml.get("private_port", &m_private_port);
|
xml.get("private_port", &m_private_port);
|
||||||
xml.get("password", &m_password_protected);
|
xml.get("password", &m_password_protected);
|
||||||
xml.get("game_started", &m_game_started);
|
xml.get("game_started", &m_game_started);
|
||||||
@ -213,3 +217,9 @@ bool Server::searchByName(const std::string& lower_case_word)
|
|||||||
}
|
}
|
||||||
return server_name_found;
|
return server_name_found;
|
||||||
} // searchByName
|
} // searchByName
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void Server::setIPV6Address(const SocketAddress& addr)
|
||||||
|
{
|
||||||
|
m_ipv6_address.reset(new SocketAddress(addr));
|
||||||
|
} // setIPV6Address
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
class Track;
|
class Track;
|
||||||
class XMLNode;
|
class XMLNode;
|
||||||
|
class SocketAddress;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \ingroup online
|
* \ingroup online
|
||||||
@ -55,7 +56,11 @@ protected:
|
|||||||
|
|
||||||
std::string m_lower_case_player_names;
|
std::string m_lower_case_player_names;
|
||||||
|
|
||||||
std::string m_ipv6_address;
|
/** We need to use full socket address structure instead of string to hold
|
||||||
|
* it, because for local link address the scope id matters for
|
||||||
|
* multicasting.
|
||||||
|
*/
|
||||||
|
std::unique_ptr<SocketAddress> m_ipv6_address;
|
||||||
|
|
||||||
uint32_t m_server_id;
|
uint32_t m_server_id;
|
||||||
uint32_t m_server_owner;
|
uint32_t m_server_owner;
|
||||||
@ -173,7 +178,7 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void setIPV6Connection(bool val)
|
void setIPV6Connection(bool val)
|
||||||
{
|
{
|
||||||
if (m_ipv6_address.empty())
|
if (!m_ipv6_address)
|
||||||
m_ipv6_connection = false;
|
m_ipv6_connection = false;
|
||||||
else
|
else
|
||||||
m_ipv6_connection = val;
|
m_ipv6_connection = val;
|
||||||
@ -181,8 +186,13 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
bool useIPV6Connection() const { return m_ipv6_connection; }
|
bool useIPV6Connection() const { return m_ipv6_connection; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void setIPV6Address(const std::string& addr) { m_ipv6_address = addr; }
|
void setIPV6Address(const SocketAddress& addr);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
const std::string& getIPV6Address() const { return m_ipv6_address; }
|
SocketAddress* getIPV6Address() const
|
||||||
|
{
|
||||||
|
if (!m_ipv6_address)
|
||||||
|
return NULL;
|
||||||
|
return m_ipv6_address.get();
|
||||||
|
}
|
||||||
}; // Server
|
}; // Server
|
||||||
#endif // HEADER_SERVER_HPP
|
#endif // HEADER_SERVER_HPP
|
||||||
|
@ -25,7 +25,9 @@
|
|||||||
#include "network/network_config.hpp"
|
#include "network/network_config.hpp"
|
||||||
#include "network/network_string.hpp"
|
#include "network/network_string.hpp"
|
||||||
#include "network/server.hpp"
|
#include "network/server.hpp"
|
||||||
|
#include "network/socket_address.hpp"
|
||||||
#include "network/stk_host.hpp"
|
#include "network/stk_host.hpp"
|
||||||
|
#include "network/stk_ipv6.hpp"
|
||||||
#include "online/xml_request.hpp"
|
#include "online/xml_request.hpp"
|
||||||
#include "online/request_manager.hpp"
|
#include "online/request_manager.hpp"
|
||||||
#include "utils/translation.hpp"
|
#include "utils/translation.hpp"
|
||||||
@ -33,6 +35,7 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
@ -42,6 +45,7 @@
|
|||||||
# include <iphlpapi.h>
|
# include <iphlpapi.h>
|
||||||
#else
|
#else
|
||||||
# include <ifaddrs.h>
|
# include <ifaddrs.h>
|
||||||
|
# include <net/if.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const int64_t SERVER_REFRESH_INTERVAL = 5000;
|
const int64_t SERVER_REFRESH_INTERVAL = 5000;
|
||||||
@ -158,8 +162,9 @@ std::shared_ptr<Online::XMLRequest> ServersManager::getLANRefreshRequest() const
|
|||||||
ENetAddress addr;
|
ENetAddress addr;
|
||||||
addr.host = STKHost::HOST_ANY;
|
addr.host = STKHost::HOST_ANY;
|
||||||
addr.port = STKHost::PORT_ANY;
|
addr.port = STKHost::PORT_ANY;
|
||||||
|
setIPv6Socket(UserConfigParams::m_ipv6_lan ? 1 : 0);
|
||||||
Network *broadcast = new Network(1, 1, 0, 0, &addr);
|
Network *broadcast = new Network(1, 1, 0, 0, &addr);
|
||||||
const std::vector<TransportAddress> &all_bcast =
|
const std::vector<SocketAddress> &all_bcast =
|
||||||
ServersManager::get()->getBroadcastAddresses();
|
ServersManager::get()->getBroadcastAddresses();
|
||||||
for (auto &bcast_addr : all_bcast)
|
for (auto &bcast_addr : all_bcast)
|
||||||
{
|
{
|
||||||
@ -187,7 +192,7 @@ std::shared_ptr<Online::XMLRequest> ServersManager::getLANRefreshRequest() const
|
|||||||
std::map<irr::core::stringw, std::shared_ptr<Server> > servers_now;
|
std::map<irr::core::stringw, std::shared_ptr<Server> > servers_now;
|
||||||
while (StkTime::getMonoTimeMs() - start_time < DURATION)
|
while (StkTime::getMonoTimeMs() - start_time < DURATION)
|
||||||
{
|
{
|
||||||
TransportAddress sender;
|
SocketAddress sender;
|
||||||
int len = broadcast->receiveRawPacket(buffer, LEN, &sender, 1);
|
int len = broadcast->receiveRawPacket(buffer, LEN, &sender, 1);
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
{
|
{
|
||||||
@ -219,13 +224,20 @@ std::shared_ptr<Online::XMLRequest> ServersManager::getLANRefreshRequest() const
|
|||||||
{
|
{
|
||||||
(void)e;
|
(void)e;
|
||||||
}
|
}
|
||||||
servers_now.insert(std::make_pair(name,
|
auto server = std::make_shared<Server>(cur_server_id++,
|
||||||
std::make_shared<Server>(cur_server_id++, name,
|
name, max_players, players, difficulty, mode,
|
||||||
max_players, players, difficulty, mode, sender,
|
TransportAddress(sender.getIP(), sender.getPort()),
|
||||||
password == 1, game_started == 1, current_track)));
|
password == 1, game_started == 1, current_track);
|
||||||
|
if (sender.isIPv6())
|
||||||
|
{
|
||||||
|
server->setIPV6Address(sender);
|
||||||
|
server->setIPV6Connection(true);
|
||||||
|
}
|
||||||
|
servers_now.insert(std::make_pair(name, server));
|
||||||
//all_servers.[name] = servers_now.back();
|
//all_servers.[name] = servers_now.back();
|
||||||
} // if received_data
|
} // if received_data
|
||||||
} // while still waiting
|
} // while still waiting
|
||||||
|
setIPv6Socket(0);
|
||||||
m_success = true;
|
m_success = true;
|
||||||
ServersManager::get()->setLanServers(servers_now);
|
ServersManager::get()->setLanServers(servers_now);
|
||||||
delete broadcast;
|
delete broadcast;
|
||||||
@ -370,14 +382,14 @@ void ServersManager::setDefaultBroadcastAddresses()
|
|||||||
* to be created.
|
* to be created.
|
||||||
* \param len Number of bits to be or'ed.
|
* \param len Number of bits to be or'ed.
|
||||||
*/
|
*/
|
||||||
void ServersManager::addAllBroadcastAddresses(const TransportAddress &a, int len)
|
void ServersManager::addAllBroadcastAddresses(const SocketAddress &a, int len)
|
||||||
{
|
{
|
||||||
// Try different broadcast addresses - by masking on
|
// Try different broadcast addresses - by masking on
|
||||||
// byte boundaries
|
// byte boundaries
|
||||||
while (len > 0)
|
while (len > 0)
|
||||||
{
|
{
|
||||||
unsigned int mask = (1 << len) - 1;
|
unsigned int mask = (1 << len) - 1;
|
||||||
TransportAddress bcast(a.getIP() | mask,
|
SocketAddress bcast(a.getIP() | mask,
|
||||||
stk_config->m_server_discovery_port);
|
stk_config->m_server_discovery_port);
|
||||||
Log::info("Broadcast", "address %s length %d mask %x --> %s",
|
Log::info("Broadcast", "address %s length %d mask %x --> %s",
|
||||||
a.toString().c_str(),
|
a.toString().c_str(),
|
||||||
@ -403,59 +415,32 @@ void ServersManager::addAllBroadcastAddresses(const TransportAddress &a, int len
|
|||||||
void ServersManager::updateBroadcastAddresses()
|
void ServersManager::updateBroadcastAddresses()
|
||||||
{
|
{
|
||||||
m_broadcast_address.clear();
|
m_broadcast_address.clear();
|
||||||
|
std::vector<SocketAddress> result;
|
||||||
#ifdef WIN32
|
#ifndef WIN32
|
||||||
IP_ADAPTER_ADDRESSES *addresses;
|
|
||||||
int count = 100, return_code;
|
|
||||||
|
|
||||||
int iteration = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
addresses = new IP_ADAPTER_ADDRESSES[count];
|
|
||||||
ULONG buf_len = sizeof(IP_ADAPTER_ADDRESSES)*count;
|
|
||||||
long flags = 0;
|
|
||||||
return_code = GetAdaptersAddresses(AF_INET, flags, NULL, addresses,
|
|
||||||
&buf_len);
|
|
||||||
iteration++;
|
|
||||||
} while (return_code == ERROR_BUFFER_OVERFLOW && iteration<10);
|
|
||||||
|
|
||||||
if (return_code == ERROR_BUFFER_OVERFLOW)
|
|
||||||
{
|
|
||||||
Log::warn("ServerManager", "Can not get broadcast addresses.");
|
|
||||||
setDefaultBroadcastAddresses();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IP_ADAPTER_ADDRESSES *p = addresses; p; p = p->Next)
|
|
||||||
{
|
|
||||||
// Check all operational IP4 adapters
|
|
||||||
if (p->OperStatus == IfOperStatusUp &&
|
|
||||||
p->FirstUnicastAddress->Address.lpSockaddr->sa_family == AF_INET)
|
|
||||||
{
|
|
||||||
const sockaddr_in *sa = (sockaddr_in*)p->FirstUnicastAddress->Address.lpSockaddr;
|
|
||||||
// Use sa->sin_addr.S_un.S_addr and htonl?
|
|
||||||
TransportAddress ta(sa->sin_addr.S_un.S_un_b.s_b1,
|
|
||||||
sa->sin_addr.S_un.S_un_b.s_b2,
|
|
||||||
sa->sin_addr.S_un.S_un_b.s_b3,
|
|
||||||
sa->sin_addr.S_un.S_un_b.s_b4);
|
|
||||||
int len = 32 - p->FirstUnicastAddress->OnLinkPrefixLength;
|
|
||||||
addAllBroadcastAddresses(ta, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
struct ifaddrs *addresses, *p;
|
struct ifaddrs *addresses, *p;
|
||||||
|
|
||||||
if (getifaddrs(&addresses) == -1)
|
if (getifaddrs(&addresses) == -1)
|
||||||
{
|
{
|
||||||
Log::warn("ServerManager", "Error in getifaddrs");
|
Log::warn("SocketAddress", "Error in getifaddrs");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
std::set<uint32_t> used_scope_id;
|
||||||
for (p = addresses; p; p = p->ifa_next)
|
for (p = addresses; p; p = p->ifa_next)
|
||||||
{
|
{
|
||||||
if (p->ifa_addr != NULL && p->ifa_addr->sa_family == AF_INET)
|
SocketAddress socket_address;
|
||||||
|
if (p->ifa_addr == NULL)
|
||||||
|
continue;
|
||||||
|
if (p->ifa_addr->sa_family == AF_INET)
|
||||||
{
|
{
|
||||||
struct sockaddr_in *sa = (struct sockaddr_in *) p->ifa_addr;
|
struct sockaddr_in *sa = (struct sockaddr_in *) p->ifa_addr;
|
||||||
TransportAddress ta(htonl(sa->sin_addr.s_addr), 0);
|
uint32_t addr = htonl(sa->sin_addr.s_addr);
|
||||||
|
|
||||||
|
// Skip 169.254.*.* local link address
|
||||||
|
if (((addr >> 24) & 0xff) == 169 &&
|
||||||
|
((addr >> 16) & 0xff) == 254)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SocketAddress saddr(addr, 0);
|
||||||
uint32_t u = ((sockaddr_in*)(p->ifa_netmask))->sin_addr.s_addr;
|
uint32_t u = ((sockaddr_in*)(p->ifa_netmask))->sin_addr.s_addr;
|
||||||
// Convert mask to #bits: SWAT algorithm
|
// Convert mask to #bits: SWAT algorithm
|
||||||
u = u - ((u >> 1) & 0x55555555);
|
u = u - ((u >> 1) & 0x55555555);
|
||||||
@ -464,18 +449,108 @@ void ServersManager::updateBroadcastAddresses()
|
|||||||
|
|
||||||
Log::debug("ServerManager",
|
Log::debug("ServerManager",
|
||||||
"Interface: %s\tAddress: %s\tmask: %x\n", p->ifa_name,
|
"Interface: %s\tAddress: %s\tmask: %x\n", p->ifa_name,
|
||||||
ta.toString().c_str(), u);
|
saddr.toString().c_str(), u);
|
||||||
addAllBroadcastAddresses(ta, u);
|
addAllBroadcastAddresses(saddr, u);
|
||||||
|
}
|
||||||
|
else if (p->ifa_addr->sa_family == AF_INET6)
|
||||||
|
{
|
||||||
|
uint32_t idx = if_nametoindex(p->ifa_name);
|
||||||
|
if (used_scope_id.find(idx) != used_scope_id.end())
|
||||||
|
continue;
|
||||||
|
used_scope_id.insert(idx);
|
||||||
|
SocketAddress socket_address("ff02::1",
|
||||||
|
stk_config->m_server_discovery_port);
|
||||||
|
sockaddr_in6* in6 = (sockaddr_in6*)socket_address.getSockaddr();
|
||||||
|
in6->sin6_scope_id = idx;
|
||||||
|
m_broadcast_address.push_back(socket_address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
freeifaddrs(addresses);
|
freeifaddrs(addresses);
|
||||||
|
#else
|
||||||
|
// From docs from microsoft it recommends 15k size
|
||||||
|
const int WORKING_BUFFER_SIZE = 15000;
|
||||||
|
PIP_ADAPTER_ADDRESSES paddr = NULL;
|
||||||
|
unsigned long len = WORKING_BUFFER_SIZE;
|
||||||
|
int return_code = 0;
|
||||||
|
int iteration = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
paddr = (IP_ADAPTER_ADDRESSES*)malloc(len);
|
||||||
|
if (paddr == NULL)
|
||||||
|
return;
|
||||||
|
long flags = 0;
|
||||||
|
return_code = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, paddr,
|
||||||
|
&len);
|
||||||
|
if (return_code == ERROR_BUFFER_OVERFLOW)
|
||||||
|
{
|
||||||
|
free(paddr);
|
||||||
|
paddr = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
iteration++;
|
||||||
|
} while ((return_code == ERROR_BUFFER_OVERFLOW) && (iteration < 10));
|
||||||
|
|
||||||
|
if (return_code == ERROR_BUFFER_OVERFLOW)
|
||||||
|
{
|
||||||
|
Log::warn("ServerManager", "Can not get broadcast addresses.");
|
||||||
|
setDefaultBroadcastAddresses();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IP_ADAPTER_ADDRESSES *p = paddr; p; p = p->Next)
|
||||||
|
{
|
||||||
|
if (p->OperStatus != IfOperStatusUp)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
std::set<uint32_t> used_scope_id;
|
||||||
|
for (PIP_ADAPTER_UNICAST_ADDRESS unicast = p->FirstUnicastAddress;
|
||||||
|
unicast != NULL; unicast = unicast->Next)
|
||||||
|
{
|
||||||
|
SocketAddress socket_address;
|
||||||
|
if (unicast->Address.lpSockaddr->sa_family == AF_INET)
|
||||||
|
{
|
||||||
|
const sockaddr_in *sa =
|
||||||
|
(const sockaddr_in*)unicast->Address.lpSockaddr;
|
||||||
|
|
||||||
|
// Skip 169.254.*.* local link address
|
||||||
|
if (sa->sin_addr.S_un.S_un_b.s_b1 == 169 &&
|
||||||
|
sa->sin_addr.S_un.S_un_b.s_b2 == 254)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Use sa->sin_addr.S_un.S_addr and htonl?
|
||||||
|
SocketAddress ta(sa->sin_addr.S_un.S_un_b.s_b1,
|
||||||
|
sa->sin_addr.S_un.S_un_b.s_b2,
|
||||||
|
sa->sin_addr.S_un.S_un_b.s_b3,
|
||||||
|
sa->sin_addr.S_un.S_un_b.s_b4);
|
||||||
|
int len = 32 - unicast->OnLinkPrefixLength;
|
||||||
|
addAllBroadcastAddresses(ta, len);
|
||||||
|
}
|
||||||
|
if (unicast->Address.lpSockaddr->sa_family == AF_INET6)
|
||||||
|
{
|
||||||
|
sockaddr_in6* in6 =
|
||||||
|
(sockaddr_in6*)unicast->Address.lpSockaddr;
|
||||||
|
const uint32_t scope_id = in6->sin6_scope_id;
|
||||||
|
if (used_scope_id.find(scope_id) !=
|
||||||
|
used_scope_id.end())
|
||||||
|
continue;
|
||||||
|
used_scope_id.insert(scope_id);
|
||||||
|
SocketAddress socket_address("ff02::1",
|
||||||
|
stk_config->m_server_discovery_port);
|
||||||
|
in6 = (sockaddr_in6*)socket_address.getSockaddr();
|
||||||
|
in6->sin6_scope_id = scope_id;
|
||||||
|
m_broadcast_address.push_back(socket_address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(paddr);
|
||||||
#endif
|
#endif
|
||||||
} // updateBroadcastAddresses
|
} // updateBroadcastAddresses
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Returns a list of all possible broadcast addresses on this machine.
|
/** Returns a list of all possible broadcast addresses on this machine.
|
||||||
*/
|
*/
|
||||||
const std::vector<TransportAddress>& ServersManager::getBroadcastAddresses()
|
const std::vector<SocketAddress>& ServersManager::getBroadcastAddresses()
|
||||||
{
|
{
|
||||||
if (m_broadcast_address.empty())
|
if (m_broadcast_address.empty())
|
||||||
{
|
{
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
namespace Online { class XMLRequest; }
|
namespace Online { class XMLRequest; }
|
||||||
class Server;
|
class Server;
|
||||||
class TransportAddress;
|
class SocketAddress;
|
||||||
class XMLNode;
|
class XMLNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,7 +43,7 @@ private:
|
|||||||
std::vector<std::shared_ptr<Server> > m_servers;
|
std::vector<std::shared_ptr<Server> > m_servers;
|
||||||
|
|
||||||
/** List of broadcast addresses to use. */
|
/** List of broadcast addresses to use. */
|
||||||
std::vector<TransportAddress> m_broadcast_address;
|
std::vector<SocketAddress> m_broadcast_address;
|
||||||
|
|
||||||
std::atomic<int64_t> m_last_load_time;
|
std::atomic<int64_t> m_last_load_time;
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ private:
|
|||||||
std::shared_ptr<Server> >& servers);
|
std::shared_ptr<Server> >& servers);
|
||||||
|
|
||||||
void setDefaultBroadcastAddresses();
|
void setDefaultBroadcastAddresses();
|
||||||
void addAllBroadcastAddresses(const TransportAddress &a, int len);
|
void addAllBroadcastAddresses(const SocketAddress &a, int len);
|
||||||
void updateBroadcastAddresses();
|
void updateBroadcastAddresses();
|
||||||
public:
|
public:
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@ -80,7 +80,7 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
bool listUpdated() const { return m_list_updated; }
|
bool listUpdated() const { return m_list_updated; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
const std::vector<TransportAddress>& getBroadcastAddresses();
|
const std::vector<SocketAddress>& getBroadcastAddresses();
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
|
@ -878,13 +878,8 @@ void STKHost::mainLoop()
|
|||||||
{
|
{
|
||||||
TransportAddress address(0, stk_config->m_server_discovery_port);
|
TransportAddress address(0, stk_config->m_server_discovery_port);
|
||||||
ENetAddress eaddr = address.toEnetAddress();
|
ENetAddress eaddr = address.toEnetAddress();
|
||||||
bool socket_ipv6 = isIPv6Socket() == 1 ? true : false;
|
|
||||||
if (socket_ipv6)
|
|
||||||
setIPv6Socket(0);
|
|
||||||
// direct_socket use IPv4 only atm
|
// direct_socket use IPv4 only atm
|
||||||
direct_socket = new Network(1, 1, 0, 0, &eaddr);
|
direct_socket = new Network(1, 1, 0, 0, &eaddr);
|
||||||
if (socket_ipv6)
|
|
||||||
setIPv6Socket(1);
|
|
||||||
if (direct_socket->getENetHost() == NULL)
|
if (direct_socket->getENetHost() == NULL)
|
||||||
{
|
{
|
||||||
Log::warn("STKHost", "No direct socket available, this "
|
Log::warn("STKHost", "No direct socket available, this "
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "network/network_config.hpp"
|
#include "network/network_config.hpp"
|
||||||
#include "network/server.hpp"
|
#include "network/server.hpp"
|
||||||
#include "network/server_config.hpp"
|
#include "network/server_config.hpp"
|
||||||
|
#include "network/socket_address.hpp"
|
||||||
#include "network/stk_host.hpp"
|
#include "network/stk_host.hpp"
|
||||||
#include "online/online_profile.hpp"
|
#include "online/online_profile.hpp"
|
||||||
#include "states_screens/state_manager.hpp"
|
#include "states_screens/state_manager.hpp"
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "network/network_config.hpp"
|
#include "network/network_config.hpp"
|
||||||
#include "network/server.hpp"
|
#include "network/server.hpp"
|
||||||
#include "network/server_config.hpp"
|
#include "network/server_config.hpp"
|
||||||
|
#include "network/socket_address.hpp"
|
||||||
#include "network/stk_host.hpp"
|
#include "network/stk_host.hpp"
|
||||||
#include "network/stk_peer.hpp"
|
#include "network/stk_peer.hpp"
|
||||||
#include "online/request_manager.hpp"
|
#include "online/request_manager.hpp"
|
||||||
|
@ -347,7 +347,9 @@ void ServerSelection::eventCallback(GUIEngine::Widget* widget,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
if (!m_servers[selected_index]->getIPV6Address().empty())
|
// Lan server is set IPv6 during broadcasting
|
||||||
|
if (NetworkConfig::get()->isWAN() &&
|
||||||
|
m_servers[selected_index]->getIPV6Address())
|
||||||
m_servers[selected_index]->setIPV6Connection(m_ipv6->getState());
|
m_servers[selected_index]->setIPV6Connection(m_ipv6->getState());
|
||||||
#endif
|
#endif
|
||||||
new ServerInfoDialog(m_servers[selected_index]);
|
new ServerInfoDialog(m_servers[selected_index]);
|
||||||
@ -436,7 +438,7 @@ void ServerSelection::copyFromServersManager()
|
|||||||
m_servers.erase(std::remove_if(m_servers.begin(), m_servers.end(),
|
m_servers.erase(std::remove_if(m_servers.begin(), m_servers.end(),
|
||||||
[this](const std::shared_ptr<Server>& a)->bool
|
[this](const std::shared_ptr<Server>& a)->bool
|
||||||
{
|
{
|
||||||
if (m_ipv6->getState() && a->getIPV6Address().empty())
|
if (m_ipv6->getState() && !a->getIPV6Address())
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}), m_servers.end());
|
}), m_servers.end());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user