Skip to content

Commit ab56a4f

Browse files
committed
Add ipv6 info to game server
1 parent a92b9ab commit ab56a4f

File tree

5 files changed

+96
-11
lines changed

5 files changed

+96
-11
lines changed

src/network/protocols/connect_to_server.cpp

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,20 @@
3131
#include "network/server.hpp"
3232
#include "network/stk_host.hpp"
3333
#include "network/stk_peer.hpp"
34+
#include "network/unix_ipv6.hpp"
3435
#include "online/xml_request.hpp"
3536
#include "states_screens/online/networking_lobby.hpp"
3637
#include "utils/time.hpp"
3738
#include "utils/log.hpp"
3839
#include "utils/string_utils.hpp"
3940
#include "utils/translation.hpp"
4041

42+
#ifdef WIN32
43+
# include <ws2tcpip.h>
44+
#else
45+
# include <netdb.h>
46+
#endif
47+
4148
#include <algorithm>
4249
// ============================================================================
4350
std::weak_ptr<bool> ConnectToServer::m_previous_unjoin;
@@ -84,8 +91,14 @@ void ConnectToServer::setup()
8491
Log::info("ConnectToServer", "SETUP");
8592
// In case of LAN or client-server we already have the server's
8693
// and our ip address, so we can immediately start requesting a connection.
87-
m_state = NetworkConfig::get()->isLAN() ?
88-
GOT_SERVER_ADDRESS : SET_PUBLIC_ADDRESS;
94+
if (NetworkConfig::get()->isLAN())
95+
{
96+
m_state = GOT_SERVER_ADDRESS;
97+
if (m_server->useIPV6Connection())
98+
setIPV6(1);
99+
}
100+
else
101+
m_state = SET_PUBLIC_ADDRESS;
89102
} // setup
90103

91104
// ----------------------------------------------------------------------------
@@ -211,6 +224,11 @@ void ConnectToServer::asynchronousUpdate()
211224
}
212225
servers.clear();
213226
}
227+
if (m_server->useIPV6Connection())
228+
{
229+
// Disable STUN if using ipv6 (check in setPublicAddress)
230+
setIPV6(1);
231+
}
214232
if (m_server->supportsEncryption())
215233
{
216234
STKHost::get()->setPublicAddress();
@@ -247,11 +265,19 @@ void ConnectToServer::asynchronousUpdate()
247265
// direct connection to server first, if failed than use the one
248266
// that has stun mapped, the first 8 seconds allow the server to
249267
// start the connect to peer protocol first before the port is
250-
// remapped
251-
if (tryConnect(2000, 4, true/*another_port*/))
252-
break;
253-
if (!tryConnect(2000, 11))
254-
m_state = DONE;
268+
// remapped. IPV6 has no stun so try once with any port
269+
if (isIPV6())
270+
{
271+
if (!tryConnect(2000, 15, true/*another_port*/, true/*ipv6*/))
272+
m_state = DONE;
273+
}
274+
else
275+
{
276+
if (tryConnect(2000, 4, true/*another_port*/))
277+
break;
278+
if (!tryConnect(2000, 11))
279+
m_state = DONE;
280+
}
255281
break;
256282
}
257283
case DONE:
@@ -337,7 +363,8 @@ int ConnectToServer::interceptCallback(ENetHost* host, ENetEvent* event)
337363
} // interceptCallback
338364

339365
// ----------------------------------------------------------------------------
340-
bool ConnectToServer::tryConnect(int timeout, int retry, bool another_port)
366+
bool ConnectToServer::tryConnect(int timeout, int retry, bool another_port,
367+
bool ipv6)
341368
{
342369
m_retry_count = retry;
343370
ENetEvent event;
@@ -352,20 +379,51 @@ bool ConnectToServer::tryConnect(int timeout, int retry, bool another_port)
352379

353380
m_done_intecept = false;
354381
nw->getENetHost()->intercept = ConnectToServer::interceptCallback;
382+
383+
std::string connecting_address = m_server_address.toString();
384+
if (ipv6)
385+
{
386+
struct addrinfo hints;
387+
struct addrinfo* res = NULL;
388+
memset(&hints, 0, sizeof(hints));
389+
hints.ai_family = AF_INET6;
390+
hints.ai_socktype = SOCK_STREAM;
391+
if (getaddrinfo(m_server->getIPV6Address().c_str(),
392+
StringUtils::toString(m_server->getAddress().getPort()).c_str(),
393+
&hints, &res) != 0 || res == NULL)
394+
return false;
395+
for (const struct addrinfo* addr = res; addr != NULL;
396+
addr = addr->ai_next)
397+
{
398+
if (addr->ai_family == AF_INET6)
399+
{
400+
struct sockaddr_in6* ipv6 =
401+
(struct sockaddr_in6*)addr->ai_addr;
402+
ENetAddress addr = m_server_address.toEnetAddress();
403+
connecting_address = std::string("[") +
404+
m_server->getIPV6Address() + "]:" +
405+
StringUtils::toString(addr.port);
406+
addMappedAddress(&addr, ipv6);
407+
break;
408+
}
409+
}
410+
freeaddrinfo(res);
411+
}
412+
355413
while (--m_retry_count >= 0 && !ProtocolManager::lock()->isExiting())
356414
{
357415
ENetPeer* p = nw->connectTo(m_server_address);
358416
if (!p)
359417
break;
360418
Log::info("ConnectToServer", "Trying connecting to %s from port %d, "
361-
"retry remain: %d", m_server_address.toString().c_str(),
419+
"retry remain: %d", connecting_address.c_str(),
362420
nw->getENetHost()->address.port, m_retry_count);
363421
while (enet_host_service(nw->getENetHost(), &event, timeout) != 0)
364422
{
365423
if (event.type == ENET_EVENT_TYPE_CONNECT)
366424
{
367425
Log::info("ConnectToServer", "Connected to %s",
368-
m_server_address.toString().c_str());
426+
connecting_address.c_str());
369427
nw->getENetHost()->intercept = NULL;
370428
STKHost::get()->initClientNetwork(event, nw);
371429
m_state = DONE;

src/network/protocols/connect_to_server.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ class ConnectToServer : public Protocol
4949

5050
void getClientServerInfo();
5151
void registerWithSTKServer();
52-
bool tryConnect(int timeout, int retry, bool another_port = false);
52+
bool tryConnect(int timeout, int retry, bool another_port = false,
53+
bool ipv6 = false);
5354
static TransportAddress m_server_address;
5455
static int interceptCallback(ENetHost* host, ENetEvent* event);
5556
static int m_retry_count;

src/network/server.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Server::Server(const XMLNode& server_info) : m_supports_encrytion(true)
3636
{
3737
const XMLNode& xml = *server_info.getNode("server-info");
3838

39+
m_ipv6_connection = false;
3940
m_name = "";
4041
m_server_id = 0;
4142
m_current_players = 0;
@@ -57,6 +58,7 @@ Server::Server(const XMLNode& server_info) : m_supports_encrytion(true)
5758
xml.get("max_players", &m_max_players);
5859
xml.get("current_players", &m_current_players);
5960
xml.get("current_track", &m_current_track);
61+
xml.get("ipv6", &m_ipv6_address);
6062
uint32_t ip;
6163
xml.get("ip", &ip);
6264
m_address.setIP(ip);
@@ -170,6 +172,7 @@ Server::Server(unsigned server_id, const core::stringw &name, int max_players,
170172
bool game_started, const std::string& current_track)
171173
: m_supports_encrytion(false)
172174
{
175+
m_ipv6_connection = false;
173176
m_name = name;
174177
m_lower_case_name = StringUtils::toLowerCase(StringUtils::wideToUtf8(name));
175178
m_server_id = server_id;

src/network/server.hpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ class Server
5555

5656
std::string m_lower_case_player_names;
5757

58+
std::string m_ipv6_address;
59+
5860
uint32_t m_server_id;
5961
uint32_t m_server_owner;
6062

@@ -92,6 +94,8 @@ class Server
9294

9395
bool m_game_started;
9496

97+
bool m_ipv6_connection;
98+
9599
std::vector<std::tuple<
96100
/*rank*/int, core::stringw, /*scores*/double, /*playing time*/float
97101
> > m_players;
@@ -166,5 +170,19 @@ class Server
166170
Track* getCurrentTrack() const;
167171
// ------------------------------------------------------------------------
168172
const std::string& getCountryCode() const { return m_country_code; }
173+
// ------------------------------------------------------------------------
174+
void setIPV6Connection(bool val)
175+
{
176+
if (m_ipv6_address.empty())
177+
m_ipv6_connection = false;
178+
else
179+
m_ipv6_connection = val;
180+
}
181+
// ------------------------------------------------------------------------
182+
bool useIPV6Connection() const { return m_ipv6_connection; }
183+
// ------------------------------------------------------------------------
184+
void setIPV6Address(const std::string& addr) { m_ipv6_address = addr; }
185+
// ------------------------------------------------------------------------
186+
const std::string& getIPV6Address() const { return m_ipv6_address; }
169187
}; // Server
170188
#endif // HEADER_SERVER_HPP

src/network/unix_ipv6.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,11 @@ void removeDisconnectedMappedAddress()
157157
{
158158
} // removeDisconnectedMappedAddress
159159

160+
// ----------------------------------------------------------------------------
161+
void addMappedAddress(const ENetAddress* ea, const struct sockaddr_in6* in6)
162+
{
163+
} // addMappedAddress
164+
160165
#else
161166

162167
#include "network/unix_ipv6.hpp"

0 commit comments

Comments
 (0)