Changeset - r25848:1aa50567d7ba
[Not reviewed]
master
0 3 0
Patric Stout - 3 years ago 2021-07-19 17:32:22
truebrain@openttd.org
Fix: [Network] rework when to close connections and inform Game Coordinator if needed
3 files changed with 32 insertions and 33 deletions:
0 comments (0 inline, 0 general)
src/network/network.cpp
Show inline comments
 
@@ -592,13 +592,13 @@ void NetworkClose(bool close_admins)
 
	} else {
 
		if (MyClient::my_client != nullptr) {
 
			MyClient::SendQuit();
 
			MyClient::my_client->CloseConnection(NETWORK_RECV_STATUS_CLIENT_QUIT);
 
		}
 

	
 
		_network_coordinator_client.CloseAllTokens();
 
		_network_coordinator_client.CloseAllConnections();
 
	}
 

	
 
	TCPConnecter::KillAll();
 

	
 
	_networking = false;
 
	_network_server = false;
src/network/network_coordinator.cpp
Show inline comments
 
@@ -141,13 +141,17 @@ bool ClientNetworkCoordinatorSocketHandl
 
			_settings_client.network.server_game_type = SERVER_GAME_TYPE_LOCAL;
 

	
 
			this->CloseConnection();
 
			return false;
 

	
 
		case NETWORK_COORDINATOR_ERROR_INVALID_INVITE_CODE: {
 
			this->CloseToken(detail);
 
			auto connecter_pre_it = this->connecter_pre.find(detail);
 
			if (connecter_pre_it != this->connecter_pre.end()) {
 
				connecter_pre_it->second->SetFailure();
 
				this->connecter_pre.erase(connecter_pre_it);
 
			}
 

	
 
			/* Mark the server as offline. */
 
			NetworkGameList *item = NetworkGameListAddItem(detail);
 
			item->online = false;
 

	
 
			UpdateNetworkGameWindow();
 
@@ -255,36 +259,28 @@ bool ClientNetworkCoordinatorSocketHandl
 
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_CONNECTING(Packet *p)
 
{
 
	std::string token = p->Recv_string(NETWORK_TOKEN_LENGTH);
 
	std::string invite_code = p->Recv_string(NETWORK_INVITE_CODE_LENGTH);
 

	
 
	/* Find the connecter based on the invite code. */
 
	auto connecter_it = this->connecter_pre.find(invite_code);
 
	if (connecter_it == this->connecter_pre.end()) {
 
	auto connecter_pre_it = this->connecter_pre.find(invite_code);
 
	if (connecter_pre_it == this->connecter_pre.end()) {
 
		this->CloseConnection();
 
		return false;
 
	}
 

	
 
	/* Now store it based on the token. */
 
	this->connecter[token] = connecter_it->second;
 
	this->connecter_pre.erase(connecter_it);
 
	this->connecter[token] = connecter_pre_it->second;
 
	this->connecter_pre.erase(connecter_pre_it);
 

	
 
	return true;
 
}
 

	
 
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_CONNECT_FAILED(Packet *p)
 
{
 
	std::string token = p->Recv_string(NETWORK_TOKEN_LENGTH);
 

	
 
	auto connecter_it = this->connecter.find(token);
 
	if (connecter_it != this->connecter.end()) {
 
		connecter_it->second->SetFailure();
 
		this->connecter.erase(connecter_it);
 
	}
 

	
 
	/* Close all remaining connections. */
 
	this->CloseToken(token);
 

	
 
	return true;
 
}
 

	
 
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_DIRECT_CONNECT(Packet *p)
 
@@ -379,13 +375,13 @@ NetworkRecvStatus ClientNetworkCoordinat
 
	this->CloseSocket();
 
	this->connecting = false;
 

	
 
	_network_server_connection_type = CONNECTION_TYPE_UNKNOWN;
 
	this->next_update = {};
 

	
 
	this->CloseAllTokens();
 
	this->CloseAllConnections();
 

	
 
	SetWindowDirty(WC_CLIENT_LIST, 0);
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
@@ -521,17 +517,20 @@ void ClientNetworkCoordinatorSocketHandl
 
		 * doesn't have to, as it is implied by the client telling. */
 
		Packet *p = new Packet(PACKET_COORDINATOR_CLIENT_CONNECTED);
 
		p->Send_uint8(NETWORK_COORDINATOR_VERSION);
 
		p->Send_string(token);
 
		this->SendPacket(p);
 

	
 
		/* Find the connecter; it can happen it no longer exist, in cases where
 
		 * we aborted the connect but the Game Coordinator was already in the
 
		 * processes of connecting us. */
 
		auto connecter_it = this->connecter.find(token);
 
		assert(connecter_it != this->connecter.end());
 

	
 
		connecter_it->second->SetConnected(sock);
 
		this->connecter.erase(connecter_it);
 
		if (connecter_it != this->connecter.end()) {
 
			connecter_it->second->SetConnected(sock);
 
			this->connecter.erase(connecter_it);
 
		}
 
	}
 

	
 
	/* Close all remaining connections. */
 
	this->CloseToken(token);
 
}
 

	
 
@@ -549,12 +548,17 @@ void ClientNetworkCoordinatorSocketHandl
 
	p->Send_string(token);
 
	p->Send_uint8(family);
 
	p->Send_bool(result);
 
	this->SendPacket(p);
 
}
 

	
 
/**
 
 * Close the STUN handler.
 
 * @param token The token used for the STUN handlers.
 
 * @param family The family of STUN handlers to close. AF_UNSPEC to close all STUN handlers for this token.
 
 */
 
void ClientNetworkCoordinatorSocketHandler::CloseStunHandler(const std::string &token, uint8 family)
 
{
 
	auto stun_it = this->stun_handlers.find(token);
 
	if (stun_it == this->stun_handlers.end()) return;
 

	
 
	if (family == AF_UNSPEC) {
 
@@ -578,54 +582,49 @@ void ClientNetworkCoordinatorSocketHandl
 
/**
 
 * Close everything related to this connection token.
 
 * @param token The connection token to close.
 
 */
 
void ClientNetworkCoordinatorSocketHandler::CloseToken(const std::string &token)
 
{
 
	/* Ensure all other pending connection attempts are also killed. */
 
	if (this->game_connecter != nullptr) {
 
		this->game_connecter->Kill();
 
		this->game_connecter = nullptr;
 
	}
 

	
 
	/* Close all remaining STUN connections. */
 
	this->CloseStunHandler(token);
 

	
 
	/* Close the caller of the connection attempt. */
 
	auto connecter_it = this->connecter.find(token);
 
	if (connecter_it != this->connecter.end()) {
 
		connecter_it->second->SetFailure();
 
		this->connecter.erase(connecter_it);
 
	}
 
	auto connecter_pre_it = this->connecter_pre.find(token);
 
	if (connecter_pre_it != this->connecter_pre.end()) {
 
		connecter_pre_it->second->SetFailure();
 
		this->connecter_pre.erase(connecter_pre_it);
 
	}
 
}
 

	
 
/**
 
 * Close all pending connection tokens.
 
 */
 
void ClientNetworkCoordinatorSocketHandler::CloseAllTokens()
 
void ClientNetworkCoordinatorSocketHandler::CloseAllConnections()
 
{
 
	/* Ensure all other pending connection attempts are also killed. */
 
	if (this->game_connecter != nullptr) {
 
		this->game_connecter->Kill();
 
		this->game_connecter = nullptr;
 
	}
 

	
 
	/* Mark any pending connecters as failed. */
 
	for (auto &[token, it] : this->connecter) {
 
		this->CloseStunHandler(token);
 
		it->SetFailure();
 

	
 
		/* Inform the Game Coordinator he can stop trying to connect us to the server. */
 
		this->ConnectFailure(token, 0);
 
	}
 
	this->stun_handlers.clear();
 
	this->connecter.clear();
 

	
 
	/* Also close any pending invite-code requests. */
 
	for (auto &[invite_code, it] : this->connecter_pre) {
 
		it->SetFailure();
 
	}
 
	this->connecter.clear();
 
	this->connecter_pre.clear();
 
}
 

	
 
/**
 
 * Check whether we received/can send some data from/to the Game Coordinator server and
 
 * when that's the case handle it appropriately.
src/network/network_coordinator.h
Show inline comments
 
@@ -83,13 +83,13 @@ public:
 
	void ConnectFailure(const std::string &token, uint8 tracking_number);
 
	void ConnectSuccess(const std::string &token, SOCKET sock, NetworkAddress &address);
 
	void StunResult(const std::string &token, uint8 family, bool result);
 

	
 
	void Connect();
 
	void CloseToken(const std::string &token);
 
	void CloseAllTokens();
 
	void CloseAllConnections();
 
	void CloseStunHandler(const std::string &token, uint8 family = AF_UNSPEC);
 

	
 
	void Register();
 
	void SendServerUpdate();
 
	void GetListing();
 

	
0 comments (0 inline, 0 general)