Only allow LAN connections for LAN servers (previously anyone with
the IP address could connect, even from the outside). Added new --public-server command line option to enable public WAN server.
This commit is contained in:
parent
8bd3e35c7b
commit
79ad569542
@ -573,6 +573,7 @@ void cmdLineHelp()
|
|||||||
// " (so n=1 means all Ais will be the test ai)\n"
|
// " (so n=1 means all Ais will be the test ai)\n"
|
||||||
// "
|
// "
|
||||||
" --server=name Start a server (not a playing client).\n"
|
" --server=name Start a server (not a playing client).\n"
|
||||||
|
" --public-server Allow direct connection to the server (without stk server)\n"
|
||||||
" --lan-server=name Start a LAN server (not a playing client).\n"
|
" --lan-server=name Start a LAN server (not a playing client).\n"
|
||||||
" --server-password= Sets a password for a server (both client&server).\n"
|
" --server-password= Sets a password for a server (both client&server).\n"
|
||||||
" --connect-now=ip Connect to a server with IP known now (in format x.x.x.x:xxx(port)).\n"
|
" --connect-now=ip Connect to a server with IP known now (in format x.x.x.x:xxx(port)).\n"
|
||||||
@ -987,6 +988,10 @@ int handleCmdLine()
|
|||||||
NetworkConfig::get()->setClientPort(n);
|
NetworkConfig::get()->setClientPort(n);
|
||||||
NetworkConfig::get()->setServerPort(n);
|
NetworkConfig::get()->setServerPort(n);
|
||||||
}
|
}
|
||||||
|
if (CommandLine::has("--public-server"))
|
||||||
|
{
|
||||||
|
NetworkConfig::get()->setIsPublicServer();
|
||||||
|
}
|
||||||
if (CommandLine::has("--connect-now", &s))
|
if (CommandLine::has("--connect-now", &s))
|
||||||
{
|
{
|
||||||
TransportAddress ip(s);
|
TransportAddress ip(s);
|
||||||
@ -1926,6 +1931,8 @@ void runUnitTests()
|
|||||||
GraphicsRestrictions::unitTesting();
|
GraphicsRestrictions::unitTesting();
|
||||||
Log::info("UnitTest", "NetworkString");
|
Log::info("UnitTest", "NetworkString");
|
||||||
NetworkString::unitTesting();
|
NetworkString::unitTesting();
|
||||||
|
Log::info("UnitTest", "TransportAddress");
|
||||||
|
TransportAddress::unitTesting();
|
||||||
|
|
||||||
Log::info("UnitTest", "Easter detection");
|
Log::info("UnitTest", "Easter detection");
|
||||||
// Test easter mode: in 2015 Easter is 5th of April - check with 0 days
|
// Test easter mode: in 2015 Easter is 5th of April - check with 0 days
|
||||||
|
@ -37,6 +37,7 @@ NetworkConfig::NetworkConfig()
|
|||||||
{
|
{
|
||||||
m_network_type = NETWORK_NONE;
|
m_network_type = NETWORK_NONE;
|
||||||
m_is_server = false;
|
m_is_server = false;
|
||||||
|
m_is_public_server = false;
|
||||||
m_max_players = 4;
|
m_max_players = 4;
|
||||||
m_is_registered = false;
|
m_is_registered = false;
|
||||||
m_server_name = "";
|
m_server_name = "";
|
||||||
|
@ -34,11 +34,18 @@ private:
|
|||||||
static NetworkConfig *m_network_config;
|
static NetworkConfig *m_network_config;
|
||||||
|
|
||||||
enum NetworkType
|
enum NetworkType
|
||||||
{ NETWORK_NONE, NETWORK_WAN, NETWORK_LAN };
|
{
|
||||||
|
NETWORK_NONE, NETWORK_WAN, NETWORK_LAN
|
||||||
|
};
|
||||||
|
|
||||||
/** Keeps the type of network connection: none (yet), LAN or WAN. */
|
/** Keeps the type of network connection: none (yet), LAN or WAN. */
|
||||||
NetworkType m_network_type;
|
NetworkType m_network_type;
|
||||||
|
|
||||||
|
/** If set it allows clients to connect directly to this server without
|
||||||
|
* using the stk server in between. It requires obviously that this
|
||||||
|
* server is accessible (through the firewall) from the outside. */
|
||||||
|
bool m_is_public_server;
|
||||||
|
|
||||||
/** True if this host is a server, false otherwise. */
|
/** True if this host is a server, false otherwise. */
|
||||||
bool m_is_server;
|
bool m_is_server;
|
||||||
|
|
||||||
@ -79,7 +86,7 @@ public:
|
|||||||
/** Singleton get, which creates this object if necessary. */
|
/** Singleton get, which creates this object if necessary. */
|
||||||
static NetworkConfig *get()
|
static NetworkConfig *get()
|
||||||
{
|
{
|
||||||
if(!m_network_config)
|
if (!m_network_config)
|
||||||
m_network_config = new NetworkConfig();
|
m_network_config = new NetworkConfig();
|
||||||
return m_network_config;
|
return m_network_config;
|
||||||
} // get
|
} // get
|
||||||
@ -102,19 +109,19 @@ public:
|
|||||||
} // setServerDiscoveryPort
|
} // setServerDiscoveryPort
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Sets the port on which this server listens. */
|
/** Sets the port on which this server listens. */
|
||||||
void setServerPort(uint16_t port) { m_server_port = port; }
|
void setServerPort(uint16_t port) { m_server_port = port; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Sets the port on which a client listens for server connection. */
|
/** Sets the port on which a client listens for server connection. */
|
||||||
void setClientPort(uint16_t port) { m_client_port = port; }
|
void setClientPort(uint16_t port) { m_client_port = port; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns the port on which this server listenes. */
|
/** Returns the port on which this server listenes. */
|
||||||
uint16_t getServerPort() const { return m_server_port; }
|
uint16_t getServerPort() const { return m_server_port; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns the port for LAN server discovery. */
|
/** Returns the port for LAN server discovery. */
|
||||||
uint16_t getServerDiscoveryPort() const { return m_server_discovery_port; }
|
uint16_t getServerDiscoveryPort() const { return m_server_discovery_port; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns the port on which a client listens for server connections. */
|
/** Returns the port on which a client listens for server connections. */
|
||||||
uint16_t getClientPort() const { return m_client_port; }
|
uint16_t getClientPort() const { return m_client_port; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Sets the password for a server. */
|
/** Sets the password for a server. */
|
||||||
void setPassword(const std::string &password) { m_password = password; }
|
void setPassword(const std::string &password) { m_password = password; }
|
||||||
@ -122,6 +129,12 @@ public:
|
|||||||
/** Returns the password. */
|
/** Returns the password. */
|
||||||
const std::string& getPassword() const { return m_password; }
|
const std::string& getPassword() const { return m_password; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
/** Sets that this server can be contacted directly. */
|
||||||
|
void setIsPublicServer() { m_is_public_server = true; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
/** Returns if connections directly to the server are to be accepted. */
|
||||||
|
bool isPublicServer() const { return m_is_public_server; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
/** Return if a network setting is happening. A network setting is active
|
/** Return if a network setting is happening. A network setting is active
|
||||||
* if a host (server or client) exists. */
|
* if a host (server or client) exists. */
|
||||||
bool isNetworking() const { return m_network_type!=NETWORK_NONE; }
|
bool isNetworking() const { return m_network_type!=NETWORK_NONE; }
|
||||||
|
@ -529,7 +529,7 @@ void* STKHost::mainLoop(void* self)
|
|||||||
ENetHost* host = myself->m_network->getENetHost();
|
ENetHost* host = myself->m_network->getENetHost();
|
||||||
|
|
||||||
if(NetworkConfig::get()->isServer() &&
|
if(NetworkConfig::get()->isServer() &&
|
||||||
NetworkConfig::get()->isLAN() )
|
(NetworkConfig::get()->isLAN() || NetworkConfig::get()->isPublicServer()) )
|
||||||
{
|
{
|
||||||
TransportAddress address(0, NetworkConfig::get()->getServerDiscoveryPort());
|
TransportAddress address(0, NetworkConfig::get()->getServerDiscoveryPort());
|
||||||
ENetAddress eaddr = address.toEnetAddress();
|
ENetAddress eaddr = address.toEnetAddress();
|
||||||
@ -604,6 +604,7 @@ void STKHost::handleDirectSocketRequest()
|
|||||||
BareNetworkString message(buffer, len);
|
BareNetworkString message(buffer, len);
|
||||||
std::string command;
|
std::string command;
|
||||||
message.decodeString(&command);
|
message.decodeString(&command);
|
||||||
|
|
||||||
if (command == "stk-server")
|
if (command == "stk-server")
|
||||||
{
|
{
|
||||||
Log::verbose("STKHost", "Received LAN server query");
|
Log::verbose("STKHost", "Received LAN server query");
|
||||||
@ -629,6 +630,15 @@ void STKHost::handleDirectSocketRequest()
|
|||||||
} // if message is server-requested
|
} // if message is server-requested
|
||||||
else if (command == "connection-request")
|
else if (command == "connection-request")
|
||||||
{
|
{
|
||||||
|
// In case of a LAN connection, we only allow connections from
|
||||||
|
// a LAN address (192.168*, ..., and 127.*).
|
||||||
|
if (NetworkConfig::get()->isLAN() && !sender.isLAN())
|
||||||
|
{
|
||||||
|
Log::error("STKHost", "Client trying to connect from '%s'",
|
||||||
|
sender.toString().c_str());
|
||||||
|
Log::error("STKHost", "which is outside of LAN - rejected.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
Protocol *c = new ConnectToPeer(sender);
|
Protocol *c = new ConnectToPeer(sender);
|
||||||
c->requestStart();
|
c->requestStart();
|
||||||
}
|
}
|
||||||
|
112
src/network/transport_address.cpp
Normal file
112
src/network/transport_address.cpp
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
//
|
||||||
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
|
// Copyright (C) 2013-2015 Joerg Henrichs
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 3
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
#include "network/transport_address.hpp"
|
||||||
|
|
||||||
|
/** Returns if this IP address belongs to a LAN, i.e. is in 192.168* or
|
||||||
|
* 10*, 172.16-31.*, or is on the same host, i.e. 127*.
|
||||||
|
*/
|
||||||
|
bool TransportAddress::isLAN() const
|
||||||
|
{
|
||||||
|
uint32_t ip = getIP();
|
||||||
|
if (ip >> 16 == 0xc0a8) // Check for 192.168.*
|
||||||
|
return true;
|
||||||
|
else if (ip >> 20 == 0xac1 ) // 172.16-31.*
|
||||||
|
return true;
|
||||||
|
else if (ip >> 24 == 0x0a ) // 10.*
|
||||||
|
return true;
|
||||||
|
else if (ip >> 24 == 0x7f ) // 127.* localhost
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
} // isLAN
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Unit testing. Test various LAN patterns to verify that isLAN() works as
|
||||||
|
* expected.
|
||||||
|
*/
|
||||||
|
void TransportAddress::unitTesting()
|
||||||
|
{
|
||||||
|
TransportAddress t1("192.168.0.0");
|
||||||
|
assert(t1.getIP() == (192 << 24) + (168 << 16));
|
||||||
|
assert(t1.isLAN());
|
||||||
|
|
||||||
|
TransportAddress t2("192.168.255.255");
|
||||||
|
assert(t2.getIP() == (192 << 24) + (168 << 16) + (255 << 8) + 255);
|
||||||
|
assert(t2.isLAN());
|
||||||
|
|
||||||
|
TransportAddress t3("193.168.0.1");
|
||||||
|
assert(t3.getIP() == (193 << 24) + (168 << 16) + 1);
|
||||||
|
assert(!t3.isLAN());
|
||||||
|
|
||||||
|
TransportAddress t4("192.167.255.255");
|
||||||
|
assert(t4.getIP() == (192 << 24) + (167 << 16) + (255 << 8) + 255);
|
||||||
|
assert(!t4.isLAN());
|
||||||
|
|
||||||
|
TransportAddress t5("192.169.0.0");
|
||||||
|
assert(t5.getIP() == (192 << 24) + (169 << 16));
|
||||||
|
assert(!t5.isLAN());
|
||||||
|
|
||||||
|
TransportAddress t6("172.16.0.0");
|
||||||
|
assert(t6.getIP() == (172 << 24) + (16 << 16));
|
||||||
|
assert(t6.isLAN());
|
||||||
|
|
||||||
|
TransportAddress t7("172.31.255.255");
|
||||||
|
assert(t7.getIP() == (172 << 24) + (31 << 16) + (255 << 8) + 255);
|
||||||
|
assert(t7.isLAN());
|
||||||
|
|
||||||
|
TransportAddress t8("172.15.255.255");
|
||||||
|
assert(t8.getIP() == (172 << 24) + (15 << 16) + (255 << 8) + 255);
|
||||||
|
assert(!t8.isLAN());
|
||||||
|
|
||||||
|
TransportAddress t9("172.32.0.0");
|
||||||
|
assert(t9.getIP() == (172 << 24) + (32 << 16));
|
||||||
|
assert(!t9.isLAN());
|
||||||
|
|
||||||
|
TransportAddress t10("10.0.0.0");
|
||||||
|
assert(t10.getIP() == (10 << 24));
|
||||||
|
assert(t10.isLAN());
|
||||||
|
|
||||||
|
TransportAddress t11("10.255.255.255");
|
||||||
|
assert(t11.getIP() == (10 << 24) + (255 << 16) + (255 << 8) + 255);
|
||||||
|
assert(t11.isLAN());
|
||||||
|
|
||||||
|
TransportAddress t12("9.255.255.255");
|
||||||
|
assert(t12.getIP() == (9 << 24) + (255 << 16) + (255 << 8) + 255);
|
||||||
|
assert(!t12.isLAN());
|
||||||
|
|
||||||
|
TransportAddress t13("11.0.0.0");
|
||||||
|
assert(t13.getIP() == (11 << 24) );
|
||||||
|
assert(!t13.isLAN());
|
||||||
|
|
||||||
|
TransportAddress t14("127.0.0.0");
|
||||||
|
assert(t14.getIP() == (127 << 24));
|
||||||
|
assert(t14.isLAN());
|
||||||
|
|
||||||
|
TransportAddress t15("127.255.255.255");
|
||||||
|
assert(t15.getIP() == (127 << 24) + (255 << 16) + (255 << 8) + 255);
|
||||||
|
assert(t15.isLAN());
|
||||||
|
|
||||||
|
TransportAddress t16("126.255.255.255");
|
||||||
|
assert(t16.getIP() == (126 << 24) + (255 << 16) + (255 << 8) + 255);
|
||||||
|
assert(!t16.isLAN());
|
||||||
|
|
||||||
|
TransportAddress t17("128.0.0.0");
|
||||||
|
assert(t17.getIP() == (128 << 24));
|
||||||
|
assert(t17.isLAN());
|
||||||
|
|
||||||
|
} // unitTesting
|
@ -63,23 +63,21 @@ public:
|
|||||||
{
|
{
|
||||||
std::string combined = StringUtils::replace(str, ":", ".");
|
std::string combined = StringUtils::replace(str, ":", ".");
|
||||||
std::vector<uint32_t> ip = StringUtils::splitToUInt(combined, '.');
|
std::vector<uint32_t> ip = StringUtils::splitToUInt(combined, '.');
|
||||||
m_ip = 0;
|
m_ip = 0;
|
||||||
m_port = 0;
|
m_port = 0;
|
||||||
if (ip.size() == 5)
|
if (ip.size() >= 4)
|
||||||
{
|
|
||||||
m_ip = (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
|
m_ip = (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
|
||||||
|
|
||||||
|
if(ip.size()==5)
|
||||||
m_port = (uint16_t)(ip[4] < 65536 ? ip[4] : 0);
|
m_port = (uint16_t)(ip[4] < 65536 ? ip[4] : 0);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
m_ip = 0;
|
|
||||||
m_port = 0;
|
m_port = 0;
|
||||||
}
|
|
||||||
} // TransportAddress(string of ip)
|
} // TransportAddress(string of ip)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
~TransportAddress() {}
|
~TransportAddress() {}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
static void unitTesting();
|
||||||
private:
|
private:
|
||||||
friend class NetworkConfig;
|
friend class NetworkConfig;
|
||||||
/** The copy constructor is private, so that the friend class
|
/** The copy constructor is private, so that the friend class
|
||||||
@ -90,6 +88,7 @@ private:
|
|||||||
copy(other);
|
copy(other);
|
||||||
} // TransportAddress(const TransportAddress&)
|
} // TransportAddress(const TransportAddress&)
|
||||||
public:
|
public:
|
||||||
|
bool isLAN() const;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** A copy function (to replace the copy constructor which is disabled
|
/** A copy function (to replace the copy constructor which is disabled
|
||||||
* using NoCopy): it copies the data from the argument into this object.*/
|
* using NoCopy): it copies the data from the argument into this object.*/
|
||||||
|
Loading…
Reference in New Issue
Block a user