Send a broadcast in case of lan connection for wan server

This commit is contained in:
Benau 2018-03-07 00:51:59 +08:00
parent 177c7b147c
commit 269c9318e5
8 changed files with 57 additions and 35 deletions

View File

@ -119,12 +119,7 @@ void ConnectToServer::asynchronousUpdate()
Log::info("ConnectToServer", "Server's address known");
m_state = REQUESTING_CONNECTION;
auto request_connection =
std::make_shared<RequestConnection>(m_server,
(!NetworkConfig::m_disable_lan &&
m_server_address.getIP() ==
STKHost::get()->getPublicAddress().getIP()) ||
(NetworkConfig::get()->isLAN() ||
STKHost::get()->isClientServer()));
std::make_shared<RequestConnection>(m_server);
request_connection->requestStart();
m_current_protocol = request_connection;
// Reset timer for next usage
@ -346,7 +341,7 @@ void ConnectToServer::waitingAloha(bool is_wan)
sender.toString().c_str());
if (!is_wan)
{
if (sender.isPublicAddressLAN())
if (sender.isPublicAddressLocalhost())
sender.setIP(0x7f000001); // 127.0.0.1
}
m_server_address.copy(sender);

View File

@ -25,18 +25,18 @@
#include "network/server.hpp"
#include "network/stk_host.hpp"
#include "online/xml_request.hpp"
#include "utils/string_utils.hpp"
using namespace Online;
/** Constructor. Stores the server id.
* \param server Server to be joined.
*/
RequestConnection::RequestConnection(std::shared_ptr<Server> server, bool lan)
RequestConnection::RequestConnection(std::shared_ptr<Server> server)
: Protocol(PROTOCOL_SILENT)
{
m_server = server;
m_request = NULL;
m_lan = lan;
} // RequestConnection
// ----------------------------------------------------------------------------
@ -62,7 +62,11 @@ void RequestConnection::asynchronousUpdate()
{
case NONE:
{
if (m_lan)
if ((!NetworkConfig::m_disable_lan &&
m_server->getAddress().getIP() ==
STKHost::get()->getPublicAddress().getIP()) ||
(NetworkConfig::get()->isLAN() ||
STKHost::get()->isClientServer()))
{
if (NetworkConfig::get()->isWAN())
{
@ -88,16 +92,28 @@ void RequestConnection::asynchronousUpdate()
}
NetworkConfig::get()->setServerIdFile("");
}
BareNetworkString message(std::string("connection-request"));
// Even for real lan server the port is guaranteed to be
// the discovery port as the server info for lan is always
// sent from the discovery port
std::string str_msg("connection-request");
BareNetworkString message(str_msg +
(STKHost::get()->isClientServer() ? "-localhost" :
StringUtils::toString(m_server->getPrivatePort())));
TransportAddress server_addr;
server_addr.setIP(m_server->getAddress().getIP());
if (!NetworkConfig::m_disable_lan &&
m_server->getAddress().getIP() ==
STKHost::get()->getPublicAddress().getIP() &&
!STKHost::get()->isClientServer())
{
// If use lan connection in wan server, send a broadcast
server_addr.setIP(0xffffffff);
}
else
{
server_addr.setIP(m_server->getAddress().getIP());
}
// Direct socket always listens on server discovery port
server_addr.setPort(NetworkConfig::get()
->getServerDiscoveryPort());
STKHost::get()->sendRawPacket(message, server_addr);
NetworkConfig::get()->setDirectConnect(false);
m_state = DONE;
}
else

View File

@ -26,12 +26,9 @@ protected:
/** State of this connection. */
STATE m_state;
/** If lan connection is used which send a request to direct socket. */
bool m_lan;
public:
// ------------------------------------------------------------------------
RequestConnection(std::shared_ptr<Server> server, bool lan);
RequestConnection(std::shared_ptr<Server> server);
virtual ~RequestConnection();
virtual void setup() OVERRIDE;
virtual void asynchronousUpdate() OVERRIDE;

View File

@ -60,15 +60,12 @@ protected:
/** The score/rating given */
float m_satisfaction_score;
/** True if this server is on the LAN, false otherwise. */
bool m_is_lan;
/** The public ip address and port of this server. */
TransportAddress m_address;
/** This is the private port of the server. This is used if a WAN game
* is started, but one client is discovered on the same LAN, so a direct
* connection using the private port is possible. */
* connection using the private port with a broadcast is possible. */
uint16_t m_private_port;
RaceManager::MinorRaceModeType m_minor_mode;
@ -102,6 +99,8 @@ public:
* the user id in STK addon server of the server owner. */
const uint32_t getHostId() const { return m_host_id; }
// ------------------------------------------------------------------------
uint16_t getPrivatePort() const { return m_private_port; }
// ------------------------------------------------------------------------
/** Returns the maximum number of players allowed on this server. */
const int getMaxPlayers() const { return m_max_players; }
// ------------------------------------------------------------------------

View File

@ -157,18 +157,18 @@ Online::XMLRequest* ServersManager::getLANRefreshRequest() const
{
TransportAddress sender;
int len = broadcast->receiveRawPacket(buffer, LEN, &sender, 1);
if(len>0)
if (len > 0)
{
BareNetworkString s(buffer, len);
irr::core::stringw name;
// bytes_read is the number of bytes read
uint8_t bytes_read = s.decodeStringW(&name);
s.decodeStringW(&name);
uint8_t max_players = s.getUInt8();
uint8_t players = s.getUInt8();
uint32_t my_ip = s.getUInt32();
uint16_t my_port = s.getUInt16();
uint16_t port = s.getUInt16();
uint8_t difficulty = s.getUInt8();
uint8_t mode = s.getUInt8();
sender.setPort(port);
servers_now.emplace_back(std::make_shared<Server>
(cur_server_id++, name, max_players, players,
difficulty, mode, sender));

View File

@ -839,6 +839,9 @@ void STKHost::handleDirectSocketRequest(Network* direct_socket)
BareNetworkString message(buffer, len);
std::string command;
message.decodeString(&command);
const std::string connection_cmd = std::string("connection-request") +
StringUtils::toString(m_private_port);
const std::string connection_cmd_localhost("connection-request-localhost");
if (command == "stk-server")
{
@ -857,19 +860,18 @@ void STKHost::handleDirectSocketRequest(Network* direct_socket)
s.encodeString(name);
s.addUInt8(NetworkConfig::get()->getMaxPlayers());
s.addUInt8(0); // FIXME: current number of connected players
s.addUInt32(sender.getIP());
s.addUInt16(sender.getPort());
s.addUInt16(m_private_port);
s.addUInt8((uint8_t)race_manager->getDifficulty());
s.addUInt8((uint8_t)
NetworkConfig::get()->getServerGameMode(race_manager->getMinorMode(),
race_manager->getMajorMode()));
direct_socket->sendRawPacket(s, sender);
} // if message is server-requested
else if (command == "connection-request")
else if (command == connection_cmd)
{
// In case of a LAN connection, we only allow connections from
// a LAN address (192.168*, ..., and 127.*).
if (!sender.isLAN() && !sender.isPublicAddressLAN() &&
if (!sender.isLAN() && !sender.isPublicAddressLocalhost() &&
!NetworkConfig::get()->isPublicServer())
{
Log::error("STKHost", "Client trying to connect from '%s'",
@ -879,6 +881,19 @@ void STKHost::handleDirectSocketRequest(Network* direct_socket)
}
std::make_shared<ConnectToPeer>(sender)->requestStart();
}
else if (command == connection_cmd_localhost)
{
if (sender.getIP() == 0x7f000001)
{
std::make_shared<ConnectToPeer>(sender)->requestStart();
}
else
{
Log::error("STKHost", "Client trying to connect from '%s'",
sender.toString().c_str());
Log::error("STKHost", "which is not localhost - rejected.");
}
}
else
Log::info("STKHost", "Received unknown command '%s'",
std::string(buffer, len).c_str());

View File

@ -48,7 +48,7 @@ bool TransportAddress::isLAN() const
// ----------------------------------------------------------------------------
/** Returns this IP address is localhost (127.0.0.1).
*/
bool TransportAddress::isPublicAddressLAN() const
bool TransportAddress::isPublicAddressLocalhost() const
{
#ifndef WIN32
char buffer[2048] = {};
@ -127,7 +127,7 @@ bool TransportAddress::isPublicAddressLAN() const
delete[] table;
return false;
#endif
} // isLAN
} // isPublicAddressLocalhost
// ----------------------------------------------------------------------------
/** Unit testing. Test various LAN patterns to verify that isLAN() works as

View File

@ -89,7 +89,7 @@ private:
} // TransportAddress(const TransportAddress&)
public:
// ------------------------------------------------------------------------
bool isPublicAddressLAN() const;
bool isPublicAddressLocalhost() const;
// ------------------------------------------------------------------------
bool isLAN() const;
// ------------------------------------------------------------------------