summaryrefslogtreecommitdiff
path: root/src/network/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/core')
-rw-r--r--src/network/core/CMakeLists.txt2
-rw-r--r--src/network/core/config.h3
-rw-r--r--src/network/core/tcp_coordinator.cpp2
-rw-r--r--src/network/core/tcp_coordinator.h16
-rw-r--r--src/network/core/tcp_turn.cpp71
-rw-r--r--src/network/core/tcp_turn.h79
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 */