Get the public IP from the lobby if not using STUN.
Follow-up to 1a8de6d2b8
. This makes it again possible to host without
STUN via the lobby.
The lobby bot will answer the host "Register" command with the external
IP. This is only sent to the host, avoiding IP leakage.
There is a small window in which a client might try to join and the
public IP isn't up, and the request goes through, but that seems rather
unlikely to be a problem in practice.
Refs #5913
Differential Revision: https://code.wildfiregames.com/D3490
This was SVN commit r24858.
This commit is contained in:
parent
c009eae0a5
commit
d078df0b85
@ -129,7 +129,7 @@ GameListQuery::GameListQuery(const glooxwrapper::Tag* tag)
|
|||||||
if (!tag || tag->name() != "query" || tag->xmlns() != XMLNS_GAMELIST)
|
if (!tag || tag->name() != "query" || tag->xmlns() != XMLNS_GAMELIST)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const glooxwrapper::Tag* c = tag->findTag_clone("query/game");
|
const glooxwrapper::Tag* c = tag->findTag_clone("query/command");
|
||||||
if (c)
|
if (c)
|
||||||
m_Command = c->cdata();
|
m_Command = c->cdata();
|
||||||
glooxwrapper::Tag::free(c);
|
glooxwrapper::Tag::free(c);
|
||||||
|
@ -430,8 +430,6 @@ void XmppClient::SendIqRegisterGame(const ScriptInterface& scriptInterface, JS::
|
|||||||
GameListQuery* g = new GameListQuery();
|
GameListQuery* g = new GameListQuery();
|
||||||
g->m_Command = "register";
|
g->m_Command = "register";
|
||||||
glooxwrapper::Tag* game = glooxwrapper::Tag::allocate("game");
|
glooxwrapper::Tag* game = glooxwrapper::Tag::allocate("game");
|
||||||
// Add a fake ip which will be overwritten by the ip stamp XMPP module on the server.
|
|
||||||
game->addAttribute("ip", "fake");
|
|
||||||
|
|
||||||
// Iterate through all the properties reported and add them to the stanza.
|
// Iterate through all the properties reported and add them to the stanza.
|
||||||
std::vector<std::string> properties;
|
std::vector<std::string> properties;
|
||||||
@ -861,6 +859,23 @@ bool XmppClient::handleIq(const glooxwrapper::IQ& iq)
|
|||||||
}
|
}
|
||||||
if (gq)
|
if (gq)
|
||||||
{
|
{
|
||||||
|
if (iq.from().full() == m_xpartamuppId && gq->m_Command == "register" && g_NetServer && !g_NetServer->GetUseSTUN())
|
||||||
|
{
|
||||||
|
if (gq->m_GameList.empty())
|
||||||
|
{
|
||||||
|
LOGWARNING("XmppClient: Received empty game list in response to Game Register");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
std::string publicIP = gq->m_GameList.front()->findAttribute("ip").to_string();
|
||||||
|
if (publicIP.empty())
|
||||||
|
{
|
||||||
|
LOGWARNING("XmppClient: Received game with no IP in response to Game Register");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
g_NetServer->SetConnectionData(publicIP, g_NetServer->GetPublicPort(), false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
for (const glooxwrapper::Tag* const& t : m_GameList)
|
for (const glooxwrapper::Tag* const& t : m_GameList)
|
||||||
glooxwrapper::Tag::free(t);
|
glooxwrapper::Tag::free(t);
|
||||||
m_GameList.clear();
|
m_GameList.clear();
|
||||||
|
@ -371,11 +371,6 @@ bool STUNRequestAndResponse(ENetHost& transactionHost)
|
|||||||
ParseStunResponse(buffer);
|
ParseStunResponse(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StunClient::GetPublicIp(CStr8& ip, u16 port)
|
|
||||||
{
|
|
||||||
return FindStunEndpointHost(ip, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StunClient::FindStunEndpointHost(CStr8& ip, u16& port)
|
bool StunClient::FindStunEndpointHost(CStr8& ip, u16& port)
|
||||||
{
|
{
|
||||||
ENetAddress hostAddr{ENET_HOST_ANY, static_cast<u16>(port)};
|
ENetAddress hostAddr{ENET_HOST_ANY, static_cast<u16>(port)};
|
||||||
|
@ -40,8 +40,6 @@ bool FindStunEndpointHost(CStr8& ip, u16& port);
|
|||||||
bool FindStunEndpointJoin(ENetHost& transactionHost, StunClient::StunEndpoint& stunEndpoint);
|
bool FindStunEndpointJoin(ENetHost& transactionHost, StunClient::StunEndpoint& stunEndpoint);
|
||||||
|
|
||||||
void SendHolePunchingMessages(ENetHost& enetClient, const std::string& serverAddress, u16 serverPort);
|
void SendHolePunchingMessages(ENetHost& enetClient, const std::string& serverAddress, u16 serverPort);
|
||||||
|
|
||||||
bool GetPublicIp(CStr8& ip, u16 port);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // STUNCLIENT_H
|
#endif // STUNCLIENT_H
|
||||||
|
@ -88,22 +88,15 @@ void JSI_Network::StartNetworkHost(ScriptInterface::CmptPrivate* pCmptPrivate, c
|
|||||||
bool hasLobby = !!g_XmppClient;
|
bool hasLobby = !!g_XmppClient;
|
||||||
g_NetServer = new CNetServer(hasLobby);
|
g_NetServer = new CNetServer(hasLobby);
|
||||||
// In lobby, we send our public ip and port on request to the players, who want to connect.
|
// In lobby, we send our public ip and port on request to the players, who want to connect.
|
||||||
// In both cases we need to ping stun server to get our public ip. If we want to host via stun,
|
// In either case we need to know our public IP. If using STUN, we'll use that,
|
||||||
// we need port as well.
|
// otherwise, the lobby's reponse to the game registration stanza will tell us our public IP.
|
||||||
if (hasLobby)
|
if (hasLobby)
|
||||||
{
|
{
|
||||||
CStr ip;
|
CStr ip;
|
||||||
if (!useSTUN)
|
if (!useSTUN)
|
||||||
{
|
// Don't store IP - the lobby bot will send it later.
|
||||||
if (!StunClient::GetPublicIp(ip, serverPort))
|
// (if a client tries to connect before it's setup, they'll be disconnected)
|
||||||
{
|
g_NetServer->SetConnectionData("", serverPort, false);
|
||||||
ScriptRequest rq(pCmptPrivate->pScriptInterface);
|
|
||||||
ScriptException::Raise(rq, "Failed to get public ip.");
|
|
||||||
SAFE_DELETE(g_NetServer);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
g_NetServer->SetConnectionData(ip, serverPort, false);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
u16 port = serverPort;
|
u16 port = serverPort;
|
||||||
|
Loading…
Reference in New Issue
Block a user