diff options
Diffstat (limited to 'src/network/core')
-rw-r--r-- | src/network/core/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/network/core/config.h | 3 | ||||
-rw-r--r-- | src/network/core/tcp_coordinator.cpp | 2 | ||||
-rw-r--r-- | src/network/core/tcp_coordinator.h | 16 | ||||
-rw-r--r-- | src/network/core/tcp_turn.cpp | 71 | ||||
-rw-r--r-- | src/network/core/tcp_turn.h | 79 |
6 files changed, 172 insertions, 1 deletions
diff --git a/src/network/core/CMakeLists.txt b/src/network/core/CMakeLists.txt index bcecad38c..756fa9e8f 100644 --- a/src/network/core/CMakeLists.txt +++ b/src/network/core/CMakeLists.txt @@ -30,6 +30,8 @@ add_files( tcp_listen.h tcp_stun.cpp tcp_stun.h + tcp_turn.cpp + tcp_turn.h udp.cpp udp.h ) diff --git a/src/network/core/config.h b/src/network/core/config.h index 1b66c26cf..10ec070f0 100644 --- a/src/network/core/config.h +++ b/src/network/core/config.h @@ -22,6 +22,7 @@ static const char * const NETWORK_CONTENT_MIRROR_URL = "/bananas"; static const uint16 NETWORK_COORDINATOR_SERVER_PORT = 3976; ///< The default port of the Game Coordinator server (TCP) static const uint16 NETWORK_STUN_SERVER_PORT = 3975; ///< The default port of the STUN server (TCP) +static const uint16 NETWORK_TURN_SERVER_PORT = 3974; ///< The default port of the TURN server (TCP) static const uint16 NETWORK_CONTENT_SERVER_PORT = 3978; ///< The default port of the content server (TCP) static const uint16 NETWORK_CONTENT_MIRROR_PORT = 80; ///< The default port of the content mirror (TCP) static const uint16 NETWORK_DEFAULT_PORT = 3979; ///< The default port of the game server (TCP & UDP) @@ -49,7 +50,7 @@ static const uint16 COMPAT_MTU = 1460; ///< Numbe static const byte NETWORK_GAME_ADMIN_VERSION = 1; ///< What version of the admin network do we use? static const byte NETWORK_GAME_INFO_VERSION = 6; ///< What version of game-info do we use? static const byte NETWORK_COMPANY_INFO_VERSION = 6; ///< What version of company info is this? -static const byte NETWORK_COORDINATOR_VERSION = 4; ///< What version of game-coordinator-protocol do we use? +static const byte NETWORK_COORDINATOR_VERSION = 5; ///< What version of game-coordinator-protocol do we use? static const uint NETWORK_NAME_LENGTH = 80; ///< The maximum length of the server name and map name, in bytes including '\0' static const uint NETWORK_COMPANY_NAME_LENGTH = 128; ///< The maximum length of the company name, in bytes including '\0' diff --git a/src/network/core/tcp_coordinator.cpp b/src/network/core/tcp_coordinator.cpp index 75f3f246f..44395a905 100644 --- a/src/network/core/tcp_coordinator.cpp +++ b/src/network/core/tcp_coordinator.cpp @@ -43,6 +43,7 @@ bool NetworkCoordinatorSocketHandler::HandlePacket(Packet *p) case PACKET_COORDINATOR_SERCLI_STUN_RESULT: return this->Receive_SERCLI_STUN_RESULT(p); case PACKET_COORDINATOR_GC_STUN_CONNECT: return this->Receive_GC_STUN_CONNECT(p); case PACKET_COORDINATOR_GC_NEWGRF_LOOKUP: return this->Receive_GC_NEWGRF_LOOKUP(p); + case PACKET_COORDINATOR_GC_TURN_CONNECT: return this->Receive_GC_TURN_CONNECT(p); default: Debug(net, 0, "[tcp/coordinator] Received invalid packet type {}", type); @@ -102,3 +103,4 @@ bool NetworkCoordinatorSocketHandler::Receive_GC_STUN_REQUEST(Packet *p) { retur bool NetworkCoordinatorSocketHandler::Receive_SERCLI_STUN_RESULT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_SERCLI_STUN_RESULT); } bool NetworkCoordinatorSocketHandler::Receive_GC_STUN_CONNECT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_STUN_CONNECT); } bool NetworkCoordinatorSocketHandler::Receive_GC_NEWGRF_LOOKUP(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_NEWGRF_LOOKUP); } +bool NetworkCoordinatorSocketHandler::Receive_GC_TURN_CONNECT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_TURN_CONNECT); } diff --git a/src/network/core/tcp_coordinator.h b/src/network/core/tcp_coordinator.h index b5395ad73..dea61cdec 100644 --- a/src/network/core/tcp_coordinator.h +++ b/src/network/core/tcp_coordinator.h @@ -42,6 +42,7 @@ enum PacketCoordinatorType { PACKET_COORDINATOR_SERCLI_STUN_RESULT, ///< Client/server informs the Game Coordinator of the result of the STUN request. PACKET_COORDINATOR_GC_STUN_CONNECT, ///< Game Coordinator tells client/server to connect() reusing the STUN local address. PACKET_COORDINATOR_GC_NEWGRF_LOOKUP, ///< Game Coordinator informs client about NewGRF lookup table updates needed for GC_LISTING. + PACKET_COORDINATOR_GC_TURN_CONNECT, ///< Game Coordinator tells client/server to connect to a specific TURN server. PACKET_COORDINATOR_END, ///< Must ALWAYS be on the end of this list!! (period) }; @@ -53,6 +54,7 @@ enum ConnectionType { CONNECTION_TYPE_ISOLATED, ///< The Game Coordinator failed to find a way to connect to your server. Nobody will be able to join. CONNECTION_TYPE_DIRECT, ///< The Game Coordinator can directly connect to your server. CONNECTION_TYPE_STUN, ///< The Game Coordinator can connect to your server via a STUN request. + CONNECTION_TYPE_TURN, ///< The Game Coordinator needs you to connect to a relay. }; /** @@ -288,6 +290,20 @@ protected: */ virtual bool Receive_GC_NEWGRF_LOOKUP(Packet *p); + /** + * Game Coordinator requests that we make a connection to the indicated + * peer, which is a TURN server. + * + * string Token to track the current connect request. + * uint8 Tracking number to track current connect request. + * string Ticket to hand over to the TURN server. + * string Connection string of the TURN server. + * + * @param p The packet that was just received. + * @return True upon success, otherwise false. + */ + virtual bool Receive_GC_TURN_CONNECT(Packet *p); + bool HandlePacket(Packet *p); public: /** diff --git a/src/network/core/tcp_turn.cpp b/src/network/core/tcp_turn.cpp new file mode 100644 index 000000000..026b64194 --- /dev/null +++ b/src/network/core/tcp_turn.cpp @@ -0,0 +1,71 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * @file tcp_turn.cpp Basic functions to receive and send TURN packets. + */ + +#include "../../stdafx.h" +#include "../../date_func.h" +#include "../../debug.h" +#include "tcp_turn.h" + +#include "../../safeguards.h" + +/** + * Handle the given packet, i.e. pass it to the right + * parser receive command. + * @param p the packet to handle + * @return true if we should immediately handle further packets, false otherwise + */ +bool NetworkTurnSocketHandler::HandlePacket(Packet *p) +{ + PacketTurnType type = (PacketTurnType)p->Recv_uint8(); + + switch (type) { + case PACKET_TURN_TURN_ERROR: return this->Receive_TURN_ERROR(p); + case PACKET_TURN_SERCLI_CONNECT: return this->Receive_SERCLI_CONNECT(p); + case PACKET_TURN_TURN_CONNECTED: return this->Receive_TURN_CONNECTED(p); + + default: + Debug(net, 0, "[tcp/turn] Received invalid packet type {}", type); + return false; + } +} + +/** + * Receive a packet at TCP level + * @return Whether at least one packet was received. + */ +bool NetworkTurnSocketHandler::ReceivePackets() +{ + Packet *p; + static const int MAX_PACKETS_TO_RECEIVE = 4; + int i = MAX_PACKETS_TO_RECEIVE; + while (--i != 0 && (p = this->ReceivePacket()) != nullptr) { + bool cont = this->HandlePacket(p); + delete p; + if (!cont) return true; + } + + return i != MAX_PACKETS_TO_RECEIVE - 1; +} + +/** + * Helper for logging receiving invalid packets. + * @param type The received packet type. + * @return Always false, as it's an error. + */ +bool NetworkTurnSocketHandler::ReceiveInvalidPacket(PacketTurnType type) +{ + Debug(net, 0, "[tcp/turn] Received illegal packet type {}", type); + return false; +} + +bool NetworkTurnSocketHandler::Receive_TURN_ERROR(Packet *p) { return this->ReceiveInvalidPacket(PACKET_TURN_TURN_ERROR); } +bool NetworkTurnSocketHandler::Receive_SERCLI_CONNECT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_TURN_SERCLI_CONNECT); } +bool NetworkTurnSocketHandler::Receive_TURN_CONNECTED(Packet *p) { return this->ReceiveInvalidPacket(PACKET_TURN_TURN_CONNECTED); } diff --git a/src/network/core/tcp_turn.h b/src/network/core/tcp_turn.h new file mode 100644 index 000000000..082373199 --- /dev/null +++ b/src/network/core/tcp_turn.h @@ -0,0 +1,79 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * @file tcp_turn.h Basic functions to receive and send TCP packets to/from the TURN server. + */ + +#ifndef NETWORK_CORE_TCP_TURN_H +#define NETWORK_CORE_TCP_TURN_H + +#include "os_abstraction.h" +#include "tcp.h" +#include "packet.h" +#include "game_info.h" + +/** Enum with all types of TCP TURN packets. The order MUST not be changed. **/ +enum PacketTurnType { + PACKET_TURN_TURN_ERROR, ///< TURN server is unable to relay. + PACKET_TURN_SERCLI_CONNECT, ///< Client or server is connecting to the TURN server. + PACKET_TURN_TURN_CONNECTED, ///< TURN server indicates the socket is now being relayed. + PACKET_TURN_END, ///< Must ALWAYS be on the end of this list!! (period) +}; + +/** Base socket handler for all TURN TCP sockets. */ +class NetworkTurnSocketHandler : public NetworkTCPSocketHandler { +protected: + bool ReceiveInvalidPacket(PacketTurnType type); + + /** + * TURN server was unable to connect the client or server based on the + * token. Most likely cause is an invalid token or the other side that + * hasn't connected in a reasonable amount of time. + * + * @param p The packet that was just received. + * @return True upon success, otherwise false. + */ + virtual bool Receive_TURN_ERROR(Packet *p); + + /** + * Client or servers wants to connect to the TURN server (on request by + * the Game Coordinator). + * + * uint8 Game Coordinator protocol version. + * string Token to track the current TURN request. + * + * @param p The packet that was just received. + * @return True upon success, otherwise false. + */ + virtual bool Receive_SERCLI_CONNECT(Packet *p); + + /** + * TURN server has connected client and server together and will now relay + * all packets to each other. No further TURN packets should be send over + * this socket, and the socket should be handed over to the game protocol. + * + * string Hostname of the peer. This can be used to check if a client is not banned etc. + * + * @param p The packet that was just received. + * @return True upon success, otherwise false. + */ + virtual bool Receive_TURN_CONNECTED(Packet *p); + + bool HandlePacket(Packet *p); +public: + /** + * Create a new cs socket handler for a given cs. + * @param s the socket we are connected with. + * @param address IP etc. of the client. + */ + NetworkTurnSocketHandler(SOCKET s = INVALID_SOCKET) : NetworkTCPSocketHandler(s) {} + + bool ReceivePackets(); +}; + +#endif /* NETWORK_CORE_TCP_TURN_H */ |