2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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/>.
8 /** @file network_turn.cpp TURN sending/receiving part of the network protocol. */
10 #include "../stdafx.h"
13 #include "../strings_func.h"
14 #include "network_coordinator.h"
15 #include "network_turn.h"
17 #include "table/strings.h"
19 #include "../safeguards.h"
21 /** Connect to the TURN server. */
22 class NetworkTurnConnecter
: public TCPConnecter
{
24 ClientNetworkTurnSocketHandler
*handler
;
28 * Initiate the connecting.
29 * @param connection_string The address of the TURN server.
31 NetworkTurnConnecter(ClientNetworkTurnSocketHandler
*handler
, const std::string
&connection_string
) : TCPConnecter(connection_string
, NETWORK_TURN_SERVER_PORT
), handler(handler
) {}
33 void OnFailure() override
35 Debug(net
, 9, "Turn::OnFailure()");
37 this->handler
->connecter
= nullptr;
39 this->handler
->ConnectFailure();
42 void OnConnect(SOCKET s
) override
44 Debug(net
, 9, "Turn::OnConnect()");
46 this->handler
->connecter
= nullptr;
48 this->handler
->sock
= s
;
52 bool ClientNetworkTurnSocketHandler::Receive_TURN_ERROR(Packet
&)
54 Debug(net
, 9, "Receive_TURN_ERROR()");
56 this->ConnectFailure();
61 bool ClientNetworkTurnSocketHandler::Receive_TURN_CONNECTED(Packet
&p
)
63 Debug(net
, 9, "Receive_TURN_CONNECTED()");
65 std::string hostname
= p
.Recv_string(NETWORK_HOSTNAME_LENGTH
);
67 /* Act like we no longer have a socket, as we are handing it over to the
69 SOCKET game_sock
= this->sock
;
70 this->sock
= INVALID_SOCKET
;
72 NetworkAddress address
= NetworkAddress(hostname
, NETWORK_DEFAULT_PORT
);
73 _network_coordinator_client
.ConnectSuccess(this->token
, game_sock
, address
);
79 * Connect to the TURN server.
81 void ClientNetworkTurnSocketHandler::Connect()
83 Debug(net
, 9, "Turn::Connect()");
85 this->connect_started
= true;
86 this->connecter
= TCPConnecter::Create
<NetworkTurnConnecter
>(this, this->connection_string
);
90 * Prepare a TURN connection.
91 * Not until you run Connect() on the resulting instance will it start setting
92 * up the TURN connection.
93 * @param token The token as received from the Game Coordinator.
94 * @param tracking_number The tracking number as recieved from the Game Coordinator.
95 * @param ticket The ticket as received from the Game Coordinator.
96 * @param connection_string Connection string of the TURN server.
97 * @return The handler for this TURN connection.
99 /* static */ std::unique_ptr
<ClientNetworkTurnSocketHandler
> ClientNetworkTurnSocketHandler::Turn(const std::string
&token
, uint8_t tracking_number
, const std::string
&ticket
, const std::string
&connection_string
)
101 auto turn_handler
= std::make_unique
<ClientNetworkTurnSocketHandler
>(token
, tracking_number
, connection_string
);
103 auto p
= std::make_unique
<Packet
>(turn_handler
.get(), PACKET_TURN_SERCLI_CONNECT
);
104 p
->Send_uint8(NETWORK_COORDINATOR_VERSION
);
105 p
->Send_string(ticket
);
107 turn_handler
->SendPacket(std::move(p
));
112 void ClientNetworkTurnSocketHandler::ConnectFailure()
114 _network_coordinator_client
.ConnectFailure(this->token
, this->tracking_number
);
117 NetworkRecvStatus
ClientNetworkTurnSocketHandler::CloseConnection(bool error
)
119 NetworkTurnSocketHandler::CloseConnection(error
);
121 /* Also make sure any pending connecter is killed ASAP. */
122 if (this->connecter
!= nullptr) {
123 this->connecter
->Kill();
124 this->connecter
= nullptr;
127 return NETWORK_RECV_STATUS_OKAY
;
130 ClientNetworkTurnSocketHandler::~ClientNetworkTurnSocketHandler()
132 if (this->connecter
!= nullptr) {
133 this->connecter
->Kill();
134 this->connecter
= nullptr;
139 * Check whether we received/can send some data from/to the TURN server and
140 * when that's the case handle it appropriately
142 void ClientNetworkTurnSocketHandler::SendReceive()
144 if (this->sock
== INVALID_SOCKET
) return;
146 if (this->CanSendReceive()) {
147 this->ReceivePackets();