Add firewall penetration for IPv6 client
This commit is contained in:
parent
6abd3bbf69
commit
9132fba714
@ -23,6 +23,7 @@
|
|||||||
#include "network/event.hpp"
|
#include "network/event.hpp"
|
||||||
#include "network/network_config.hpp"
|
#include "network/network_config.hpp"
|
||||||
#include "network/network_string.hpp"
|
#include "network/network_string.hpp"
|
||||||
|
#include "network/socket_address.hpp"
|
||||||
#include "network/transport_address.hpp"
|
#include "network/transport_address.hpp"
|
||||||
#include "utils/file_utils.hpp"
|
#include "utils/file_utils.hpp"
|
||||||
#include "utils/log.hpp"
|
#include "utils/log.hpp"
|
||||||
@ -179,6 +180,90 @@ int Network::receiveRawPacket(char *buffer, int buf_len,
|
|||||||
return len;
|
return len;
|
||||||
} // receiveRawPacket
|
} // receiveRawPacket
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** \brief Sends a packet whithout ENet adding its headers.
|
||||||
|
* This function is used in particular to achieve the STUN protocol.
|
||||||
|
* \param data : Data to send.
|
||||||
|
* \param dst : Destination of the packet.
|
||||||
|
*/
|
||||||
|
void Network::sendRawPacket(const BareNetworkString &buffer,
|
||||||
|
const SocketAddress& dst)
|
||||||
|
{
|
||||||
|
sendto(m_host->socket, buffer.getData(), buffer.size(), 0,
|
||||||
|
dst.getSockaddr(), dst.getSocklen());
|
||||||
|
if (m_connection_debug)
|
||||||
|
{
|
||||||
|
Log::verbose("Network", "Raw packet sent to %s",
|
||||||
|
dst.toString().c_str());
|
||||||
|
}
|
||||||
|
Network::logPacket(buffer, false);
|
||||||
|
} // sendRawPacket
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** \brief Receives a packet directly from the network interface and
|
||||||
|
* filter its address.
|
||||||
|
* Receive a packet whithout ENet processing it. Checks that the
|
||||||
|
* sender of the packet is the one that corresponds to the sender
|
||||||
|
* parameter. Does not check the port right now.
|
||||||
|
* \param buffer A buffer to receive the data in.
|
||||||
|
* \param buf_len Length of the buffer.
|
||||||
|
* \param[out] sender : Transport address of the original sender of the
|
||||||
|
* wanted packet. If the ip address is 0, do not check
|
||||||
|
* the sender's ip address, otherwise wait till a message
|
||||||
|
* from the specified sender arrives. All other messages
|
||||||
|
* are discarded.
|
||||||
|
* \param max_tries : Number of times we try to read data from the
|
||||||
|
* socket. This is aproximately the time we wait in
|
||||||
|
* milliseconds. -1 means eternal tries.
|
||||||
|
* \return Length of the received data, or -1 if no data was received.
|
||||||
|
*/
|
||||||
|
int Network::receiveRawPacket(char *buffer, int buf_len,
|
||||||
|
SocketAddress *sender, int max_tries)
|
||||||
|
{
|
||||||
|
memset(buffer, 0, buf_len);
|
||||||
|
|
||||||
|
struct sockaddr_storage addr = {};
|
||||||
|
socklen_t from_len = sizeof(addr);
|
||||||
|
|
||||||
|
int len = recvfrom(m_host->socket, buffer, buf_len, 0,
|
||||||
|
(struct sockaddr*)(&addr), &from_len);
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
// wait to receive the message because enet sockets are non-blocking
|
||||||
|
while(len < 0 && (count<max_tries || max_tries==-1) )
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
StkTime::sleep(1); // wait 1 millisecond between two checks
|
||||||
|
len = recvfrom(m_host->socket, buffer, buf_len, 0,
|
||||||
|
(struct sockaddr*)(&addr), &from_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// No message received
|
||||||
|
if(len<0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
Network::logPacket(BareNetworkString(buffer, len), true);
|
||||||
|
switch (addr.ss_family)
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
sender->setSockAddrIn(AF_INET, (sockaddr*)(&addr),
|
||||||
|
sizeof(sockaddr_in));
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
sender->setSockAddrIn(AF_INET6, (sockaddr*)(&addr),
|
||||||
|
sizeof(sockaddr_in6));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (m_connection_debug)
|
||||||
|
{
|
||||||
|
Log::verbose("Network", "Address of the sender was %s",
|
||||||
|
sender->toString().c_str());
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
} // receiveRawPacket
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** \brief Broadcasts a packet to all peers.
|
/** \brief Broadcasts a packet to all peers.
|
||||||
* \param data : Data to send.
|
* \param data : Data to send.
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
class BareNetworkString;
|
class BareNetworkString;
|
||||||
class NetworkString;
|
class NetworkString;
|
||||||
class TransportAddress;
|
class TransportAddress;
|
||||||
|
class SocketAddress;
|
||||||
|
|
||||||
/** \class EnetHost
|
/** \class EnetHost
|
||||||
* A small wrapper around enet to allow sending and receiving
|
* A small wrapper around enet to allow sending and receiving
|
||||||
@ -68,6 +69,10 @@ public:
|
|||||||
const TransportAddress& dst);
|
const TransportAddress& dst);
|
||||||
int receiveRawPacket(char *buffer, int buf_len,
|
int receiveRawPacket(char *buffer, int buf_len,
|
||||||
TransportAddress* sender, int max_tries = -1);
|
TransportAddress* sender, int max_tries = -1);
|
||||||
|
void sendRawPacket(const BareNetworkString &buffer,
|
||||||
|
const SocketAddress& dst);
|
||||||
|
int receiveRawPacket(char *buffer, int buf_len,
|
||||||
|
SocketAddress* sender, int max_tries = -1);
|
||||||
void broadcastPacket(NetworkString *data,
|
void broadcastPacket(NetworkString *data,
|
||||||
bool reliable = true);
|
bool reliable = true);
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include "network/protocols/connect_to_peer.hpp"
|
#include "network/protocols/connect_to_peer.hpp"
|
||||||
|
#include "network/network.hpp"
|
||||||
#include "network/stk_host.hpp"
|
#include "network/stk_host.hpp"
|
||||||
#include "utils/time.hpp"
|
#include "utils/time.hpp"
|
||||||
#include "utils/log.hpp"
|
#include "utils/log.hpp"
|
||||||
@ -26,7 +26,7 @@
|
|||||||
/** Constructor for peer address.
|
/** Constructor for peer address.
|
||||||
* \param address The address to connect to.
|
* \param address The address to connect to.
|
||||||
*/
|
*/
|
||||||
ConnectToPeer::ConnectToPeer(const TransportAddress &address)
|
ConnectToPeer::ConnectToPeer(const SocketAddress &address)
|
||||||
: Protocol(PROTOCOL_CONNECTION)
|
: Protocol(PROTOCOL_CONNECTION)
|
||||||
{
|
{
|
||||||
m_peer_address = address;
|
m_peer_address = address;
|
||||||
@ -62,13 +62,14 @@ void ConnectToPeer::asynchronousUpdate()
|
|||||||
// the client will use enet intercept to discover if server
|
// the client will use enet intercept to discover if server
|
||||||
// address or port is different from stk addons database.
|
// address or port is different from stk addons database.
|
||||||
// (Happens if there is firewall in between)
|
// (Happens if there is firewall in between)
|
||||||
TransportAddress broadcast_address;
|
BareNetworkString aloha("aloha-stk");
|
||||||
broadcast_address = m_peer_address;
|
|
||||||
|
|
||||||
// Enet packet will not have 0xFFFF for first 2 bytes
|
// Enet packet will not have 0xFFFF for first 2 bytes
|
||||||
BareNetworkString aloha("aloha-stk");
|
// We use the feature to distinguish between the enet packets
|
||||||
|
// and this aloha
|
||||||
aloha.getBuffer().insert(aloha.getBuffer().begin(), 2, 0xFF);
|
aloha.getBuffer().insert(aloha.getBuffer().begin(), 2, 0xFF);
|
||||||
STKHost::get()->sendRawPacket(aloha, broadcast_address);
|
|
||||||
|
STKHost::get()->sendRawPacket(aloha, m_peer_address);
|
||||||
Log::debug("ConnectToPeer", "Broadcast aloha sent.");
|
Log::debug("ConnectToPeer", "Broadcast aloha sent.");
|
||||||
// 20 seconds timeout
|
// 20 seconds timeout
|
||||||
if (m_tried_connection++ > 10)
|
if (m_tried_connection++ > 10)
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#define CONNECT_TO_PEER_HPP
|
#define CONNECT_TO_PEER_HPP
|
||||||
|
|
||||||
#include "network/protocol.hpp"
|
#include "network/protocol.hpp"
|
||||||
#include "network/transport_address.hpp"
|
#include "network/socket_address.hpp"
|
||||||
#include "utils/cpp2011.hpp"
|
#include "utils/cpp2011.hpp"
|
||||||
|
|
||||||
/** One instance of this is started for every peer who tries to
|
/** One instance of this is started for every peer who tries to
|
||||||
@ -29,8 +29,7 @@
|
|||||||
class ConnectToPeer : public Protocol
|
class ConnectToPeer : public Protocol
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
SocketAddress m_peer_address;
|
||||||
TransportAddress m_peer_address;
|
|
||||||
|
|
||||||
/** Timer use for tracking broadcast. */
|
/** Timer use for tracking broadcast. */
|
||||||
uint64_t m_timer = 0;
|
uint64_t m_timer = 0;
|
||||||
@ -46,7 +45,7 @@ protected:
|
|||||||
} m_state;
|
} m_state;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ConnectToPeer(const TransportAddress &address);
|
ConnectToPeer(const SocketAddress &address);
|
||||||
virtual ~ConnectToPeer() {}
|
virtual ~ConnectToPeer() {}
|
||||||
virtual void setup() OVERRIDE {}
|
virtual void setup() OVERRIDE {}
|
||||||
virtual void update(int ticks) OVERRIDE {}
|
virtual void update(int ticks) OVERRIDE {}
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "network/crypto.hpp"
|
#include "network/crypto.hpp"
|
||||||
#include "network/event.hpp"
|
#include "network/event.hpp"
|
||||||
#include "network/game_setup.hpp"
|
#include "network/game_setup.hpp"
|
||||||
|
#include "network/network.hpp"
|
||||||
#include "network/network_config.hpp"
|
#include "network/network_config.hpp"
|
||||||
#include "network/network_player_profile.hpp"
|
#include "network/network_player_profile.hpp"
|
||||||
#include "network/peer_vote.hpp"
|
#include "network/peer_vote.hpp"
|
||||||
@ -2604,7 +2605,9 @@ void ServerLobby::checkIncomingConnectionRequests()
|
|||||||
{
|
{
|
||||||
uint32_t addr, id;
|
uint32_t addr, id;
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
|
std::string ipv6;
|
||||||
users_xml->getNode(i)->get("ip", &addr);
|
users_xml->getNode(i)->get("ip", &addr);
|
||||||
|
users_xml->getNode(i)->get("ipv6", &ipv6);
|
||||||
users_xml->getNode(i)->get("port", &port);
|
users_xml->getNode(i)->get("port", &port);
|
||||||
users_xml->getNode(i)->get("id", &id);
|
users_xml->getNode(i)->get("id", &id);
|
||||||
users_xml->getNode(i)->get("aes-key", &keys[id].m_aes_key);
|
users_xml->getNode(i)->get("aes-key", &keys[id].m_aes_key);
|
||||||
@ -2615,7 +2618,10 @@ void ServerLobby::checkIncomingConnectionRequests()
|
|||||||
keys[id].m_tried = false;
|
keys[id].m_tried = false;
|
||||||
if (ServerConfig::m_firewalled_server)
|
if (ServerConfig::m_firewalled_server)
|
||||||
{
|
{
|
||||||
TransportAddress peer_addr(addr, port);
|
SocketAddress peer_addr(addr, port);
|
||||||
|
if (!ipv6.empty())
|
||||||
|
peer_addr.init(ipv6, port);
|
||||||
|
peer_addr.convertForIPv6Socket();
|
||||||
std::string peer_addr_str = peer_addr.toString();
|
std::string peer_addr_str = peer_addr.toString();
|
||||||
if (sl->m_pending_peer_connection.find(peer_addr_str) !=
|
if (sl->m_pending_peer_connection.find(peer_addr_str) !=
|
||||||
sl->m_pending_peer_connection.end())
|
sl->m_pending_peer_connection.end())
|
||||||
|
@ -344,9 +344,7 @@ void loadServerLobbyFromConfig()
|
|||||||
|
|
||||||
if (m_ipv6_server)
|
if (m_ipv6_server)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_IPV6
|
#ifndef ENABLE_IPV6
|
||||||
m_firewalled_server = false;
|
|
||||||
#else
|
|
||||||
Log::warn("ServerConfig", "IPv6 support not compiled.");
|
Log::warn("ServerConfig", "IPv6 support not compiled.");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1302,7 +1302,7 @@ void STKHost::handleDirectSocketRequest(Network* direct_socket,
|
|||||||
const int LEN=2048;
|
const int LEN=2048;
|
||||||
char buffer[LEN];
|
char buffer[LEN];
|
||||||
|
|
||||||
TransportAddress sender;
|
SocketAddress sender;
|
||||||
int len = direct_socket->receiveRawPacket(buffer, LEN, &sender, 1);
|
int len = direct_socket->receiveRawPacket(buffer, LEN, &sender, 1);
|
||||||
if(len<=0) return;
|
if(len<=0) return;
|
||||||
BareNetworkString message(buffer, len);
|
BareNetworkString message(buffer, len);
|
||||||
@ -1383,6 +1383,25 @@ bool STKHost::peerExists(const TransportAddress& peer)
|
|||||||
return false;
|
return false;
|
||||||
} // peerExists
|
} // peerExists
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** \brief Tells if a peer is known.
|
||||||
|
* \return True if the peer is known, false elseway.
|
||||||
|
*/
|
||||||
|
bool STKHost::peerExists(const SocketAddress& peer)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_peers_mutex);
|
||||||
|
for (auto p : m_peers)
|
||||||
|
{
|
||||||
|
auto stk_peer = p.second;
|
||||||
|
if (stk_peer->getSocketAddress() == peer ||
|
||||||
|
((stk_peer->getSocketAddress().isPublicAddressLocalhost() &&
|
||||||
|
peer.isPublicAddressLocalhost()) &&
|
||||||
|
stk_peer->getSocketAddress().getPort() == peer.getPort()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} // peerExists
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** \brief Return the only server peer for client.
|
/** \brief Return the only server peer for client.
|
||||||
* \return STKPeer the STKPeer of server.
|
* \return STKPeer the STKPeer of server.
|
||||||
@ -1691,3 +1710,17 @@ std::string STKHost::getVaildPublicAddress() const
|
|||||||
return m_public_address.toString();
|
return m_public_address.toString();
|
||||||
return "";
|
return "";
|
||||||
} // getVaildPublicAddress
|
} // getVaildPublicAddress
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
int STKHost::receiveRawPacket(char *buffer, int buffer_len,
|
||||||
|
SocketAddress* sender, int max_tries)
|
||||||
|
{
|
||||||
|
return m_network->receiveRawPacket(buffer, buffer_len, sender,
|
||||||
|
max_tries);
|
||||||
|
} // receiveRawPacket
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void STKHost::sendRawPacket(const BareNetworkString &buffer,
|
||||||
|
const SocketAddress& dst)
|
||||||
|
{
|
||||||
|
m_network->sendRawPacket(buffer, dst);
|
||||||
|
} // sendRawPacket
|
||||||
|
@ -54,6 +54,7 @@ class NetworkTimerSynchronizer;
|
|||||||
class Server;
|
class Server;
|
||||||
class ServerLobby;
|
class ServerLobby;
|
||||||
class SeparateProcess;
|
class SeparateProcess;
|
||||||
|
class SocketAddress;
|
||||||
|
|
||||||
enum ENetCommandType : unsigned int
|
enum ENetCommandType : unsigned int
|
||||||
{
|
{
|
||||||
@ -273,6 +274,8 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
bool peerExists(const TransportAddress& peer_address);
|
bool peerExists(const TransportAddress& peer_address);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
bool peerExists(const SocketAddress& peer_address);
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
bool isConnectedTo(const TransportAddress& peer_address);
|
bool isConnectedTo(const TransportAddress& peer_address);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
std::shared_ptr<STKPeer> getServerPeerForClient() const;
|
std::shared_ptr<STKPeer> getServerPeerForClient() const;
|
||||||
@ -307,6 +310,12 @@ public:
|
|||||||
m_network->sendRawPacket(buffer, dst);
|
m_network->sendRawPacket(buffer, dst);
|
||||||
} // sendRawPacket
|
} // sendRawPacket
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
int receiveRawPacket(char *buffer, int buffer_len,
|
||||||
|
SocketAddress* sender, int max_tries = -1);
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void sendRawPacket(const BareNetworkString &buffer,
|
||||||
|
const SocketAddress& dst);
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
Network* getNetwork() const { return m_network; }
|
Network* getNetwork() const { return m_network; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns a copied list of peers. */
|
/** Returns a copied list of peers. */
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "network/event.hpp"
|
#include "network/event.hpp"
|
||||||
#include "network/network_config.hpp"
|
#include "network/network_config.hpp"
|
||||||
#include "network/network_string.hpp"
|
#include "network/network_string.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/transport_address.hpp"
|
#include "network/transport_address.hpp"
|
||||||
@ -38,9 +39,25 @@ STKPeer::STKPeer(ENetPeer *enet_peer, STKHost* host, uint32_t host_id)
|
|||||||
: m_peer_address(enet_peer->address), m_host(host)
|
: m_peer_address(enet_peer->address), m_host(host)
|
||||||
{
|
{
|
||||||
m_addons_scores.fill(-1);
|
m_addons_scores.fill(-1);
|
||||||
// We use 0.x.x.x ip to map to IPv6 address internally
|
uint32_t addr = htonl(enet_peer->address.host);
|
||||||
if (m_peer_address.getIP() < 16777216)
|
#ifdef ENABLE_IPV6
|
||||||
m_ipv6_address = getIPV6ReadableFromMappedAddress(&enet_peer->address);
|
if (isIPv6Socket())
|
||||||
|
{
|
||||||
|
// This will return the mapped IPv4 address too for IPv6 socket
|
||||||
|
// So we can sendto directly with it
|
||||||
|
struct sockaddr_in6 in6 = {};
|
||||||
|
getIPV6FromMappedAddress(&enet_peer->address, &in6);
|
||||||
|
m_socket_address.reset(new SocketAddress());
|
||||||
|
m_socket_address->setSockAddrIn(AF_INET6, (sockaddr*)&in6, sizeof(in6));
|
||||||
|
if (m_socket_address->isIPv6())
|
||||||
|
m_ipv6_address = m_socket_address->toString(false/*show_port*/);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
m_socket_address.reset(
|
||||||
|
new SocketAddress(addr, enet_peer->address.port));
|
||||||
|
}
|
||||||
m_enet_peer = enet_peer;
|
m_enet_peer = enet_peer;
|
||||||
m_host_id = host_id;
|
m_host_id = host_id;
|
||||||
m_connected_time = StkTime::getMonoTimeMs();
|
m_connected_time = StkTime::getMonoTimeMs();
|
||||||
|
@ -43,7 +43,7 @@ class Crypto;
|
|||||||
class NetworkPlayerProfile;
|
class NetworkPlayerProfile;
|
||||||
class NetworkString;
|
class NetworkString;
|
||||||
class STKHost;
|
class STKHost;
|
||||||
class TransportAddress;
|
class SocketAddress;
|
||||||
|
|
||||||
enum PeerDisconnectInfo : unsigned int
|
enum PeerDisconnectInfo : unsigned int
|
||||||
{
|
{
|
||||||
@ -89,6 +89,8 @@ protected:
|
|||||||
|
|
||||||
TransportAddress m_peer_address;
|
TransportAddress m_peer_address;
|
||||||
|
|
||||||
|
std::unique_ptr<SocketAddress> m_socket_address;
|
||||||
|
|
||||||
STKHost* m_host;
|
STKHost* m_host;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<NetworkPlayerProfile> > m_players;
|
std::vector<std::shared_ptr<NetworkPlayerProfile> > m_players;
|
||||||
@ -293,6 +295,9 @@ public:
|
|||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
int getConsecutiveMessages() const { return m_consecutive_messages; }
|
int getConsecutiveMessages() const { return m_consecutive_messages; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
const SocketAddress& getSocketAddress() const
|
||||||
|
{ return *m_socket_address.get(); }
|
||||||
}; // STKPeer
|
}; // STKPeer
|
||||||
|
|
||||||
#endif // STK_PEER_HPP
|
#endif // STK_PEER_HPP
|
||||||
|
Loading…
Reference in New Issue
Block a user