summaryrefslogtreecommitdiff
path: root/src/network/network_turn.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/network_turn.cpp')
-rw-r--r--src/network/network_turn.cpp135
1 files changed, 135 insertions, 0 deletions
diff --git a/src/network/network_turn.cpp b/src/network/network_turn.cpp
new file mode 100644
index 000000000..e04bec47c
--- /dev/null
+++ b/src/network/network_turn.cpp
@@ -0,0 +1,135 @@
+/*
+ * 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 network_turn.cpp TURN sending/receiving part of the network protocol. */
+
+#include "../stdafx.h"
+#include "../debug.h"
+#include "../error.h"
+#include "../strings_func.h"
+#include "network_coordinator.h"
+#include "network_turn.h"
+
+#include "table/strings.h"
+
+#include "../safeguards.h"
+
+/** Connect to the TURN server. */
+class NetworkTurnConnecter : public TCPConnecter {
+private:
+ ClientNetworkTurnSocketHandler *handler;
+
+public:
+ /**
+ * Initiate the connecting.
+ * @param connection_string The address of the TURN server.
+ */
+ NetworkTurnConnecter(ClientNetworkTurnSocketHandler *handler, const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_TURN_SERVER_PORT), handler(handler) {}
+
+ void OnFailure() override
+ {
+ this->handler->connecter = nullptr;
+
+ this->handler->ConnectFailure();
+ }
+
+ void OnConnect(SOCKET s) override
+ {
+ this->handler->connecter = nullptr;
+
+ handler->sock = s;
+ }
+};
+
+bool ClientNetworkTurnSocketHandler::Receive_TURN_ERROR(Packet *p)
+{
+ this->ConnectFailure();
+
+ return false;
+}
+
+bool ClientNetworkTurnSocketHandler::Receive_TURN_CONNECTED(Packet *p)
+{
+ std::string hostname = p->Recv_string(NETWORK_HOSTNAME_LENGTH);
+
+ /* Act like we no longer have a socket, as we are handing it over to the
+ * game handler. */
+ SOCKET game_sock = this->sock;
+ this->sock = INVALID_SOCKET;
+
+ NetworkAddress address = NetworkAddress(hostname, NETWORK_DEFAULT_PORT);
+ _network_coordinator_client.ConnectSuccess(this->token, game_sock, address);
+
+ return false;
+}
+
+/**
+ * Connect to the TURN server.
+ */
+void ClientNetworkTurnSocketHandler::Connect()
+{
+ this->connect_started = true;
+ this->connecter = new NetworkTurnConnecter(this, this->connection_string);
+}
+
+/**
+ * Prepare a TURN connection.
+ * Not until you run Connect() on the resulting instance will it start setting
+ * up the TURN connection.
+ * @param token The token as received from the Game Coordinator.
+ * @param tracking_number The tracking number as recieved from the Game Coordinator.
+ * @param ticket The ticket as received from the Game Coordinator.
+ * @param connection_string Connection string of the TURN server.
+ * @return The handler for this TURN connection.
+ */
+/* static */ std::unique_ptr<ClientNetworkTurnSocketHandler> ClientNetworkTurnSocketHandler::Turn(const std::string &token, uint8 tracking_number, const std::string &ticket, const std::string &connection_string)
+{
+ auto turn_handler = std::make_unique<ClientNetworkTurnSocketHandler>(token, tracking_number, connection_string);
+
+ Packet *p = new Packet(PACKET_TURN_SERCLI_CONNECT);
+ p->Send_uint8(NETWORK_COORDINATOR_VERSION);
+ p->Send_string(ticket);
+
+ turn_handler->SendPacket(p);
+
+ return turn_handler;
+}
+
+void ClientNetworkTurnSocketHandler::ConnectFailure()
+{
+ _network_coordinator_client.ConnectFailure(this->token, this->tracking_number);
+}
+
+NetworkRecvStatus ClientNetworkTurnSocketHandler::CloseConnection(bool error)
+{
+ NetworkTurnSocketHandler::CloseConnection(error);
+
+ /* If our connecter is still pending, shut it down too. Otherwise the
+ * callback of the connecter can call into us, and our object is most
+ * likely about to be destroyed. */
+ if (this->connecter != nullptr) {
+ this->connecter->Kill();
+ this->connecter = nullptr;
+ }
+
+ return NETWORK_RECV_STATUS_OKAY;
+}
+
+/**
+ * Check whether we received/can send some data from/to the TURN server and
+ * when that's the case handle it appropriately
+ */
+void ClientNetworkTurnSocketHandler::SendReceive()
+{
+ if (this->sock == INVALID_SOCKET) return;
+
+ if (this->CanSendReceive()) {
+ this->ReceivePackets();
+ }
+
+ this->SendPackets();
+}