From cee8174d02e38542548fc74de93450cfebefaa91 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Wed, 28 Apr 2021 14:36:14 +0200 Subject: Codechange: track servers with a ServerAddress instead of a NetworkAddress This allows future extensions to have different ways of referencing a server, instead of forcing to use IP:port. --- src/network/core/address.cpp | 18 ++++++++++++++++++ src/network/core/address.h | 34 ++++++++++++++++++++++++++++++++++ src/network/core/tcp.h | 12 ++++++++++++ src/network/core/tcp_connect.cpp | 20 ++++++++++++++++++++ src/network/network.cpp | 31 +++++++------------------------ src/network/network_gamelist.cpp | 4 ++-- 6 files changed, 93 insertions(+), 26 deletions(-) diff --git a/src/network/core/address.cpp b/src/network/core/address.cpp index 0c16a2c3c..113dae686 100644 --- a/src/network/core/address.cpp +++ b/src/network/core/address.cpp @@ -10,6 +10,7 @@ #include "../../stdafx.h" #include "address.h" +#include "../network_internal.h" #include "../../debug.h" #include "../../safeguards.h" @@ -411,3 +412,20 @@ void NetworkAddress::Listen(int socktype, SocketList *sockets) getpeername(sock, (sockaddr *)&addr, &addr_len); return NetworkAddress(addr, addr_len).GetAddressAsString(); } + +/** + * Convert a string containing either "hostname" or "hostname:ip" to a + * ServerAddress, where the string can be postfixed with "#company" to + * indicate the requested company. + * + * @param connection_string The string to parse. + * @param default_port The default port to set port to if not in connection_string. + * @param company Pointer to the company variable to set iff indicted. + * @return A valid ServerAddress of the parsed information. + */ +/* static */ ServerAddress ServerAddress::Parse(const std::string &connection_string, uint16 default_port, CompanyID *company_id) +{ + uint16 port = default_port; + std::string_view ip = ParseFullConnectionString(connection_string, port, company_id); + return ServerAddress(SERVER_ADDRESS_DIRECT, std::string(ip) + ":" + std::to_string(port)); +} diff --git a/src/network/core/address.h b/src/network/core/address.h index af10a2756..b22bcac0e 100644 --- a/src/network/core/address.h +++ b/src/network/core/address.h @@ -12,6 +12,7 @@ #include "os_abstraction.h" #include "config.h" +#include "../../company_type.h" #include "../../string_func.h" #include "../../core/smallmap_type.hpp" @@ -177,4 +178,37 @@ public: static const std::string GetPeerName(SOCKET sock); }; +/** + * Types of server addresses we know. + * + * Sorting will prefer entries at the top of this list above ones at the bottom. + */ +enum ServerAddressType { + SERVER_ADDRESS_DIRECT, ///< Server-address is based on an hostname:port. +}; + +/** + * Address to a game server. + * + * This generalises addresses which are based on different identifiers. + */ +class ServerAddress { +private: + /** + * Create a new ServerAddress object. + * + * Please use ServerAddress::Parse() instead of calling this directly. + * + * @param type The type of the ServerAdress. + * @param connection_string The connection_string that belongs to this ServerAddress type. + */ + ServerAddress(ServerAddressType type, const std::string &connection_string) : type(type), connection_string(connection_string) {} + +public: + ServerAddressType type; ///< The type of this ServerAddress. + std::string connection_string; ///< The connection string for this ServerAddress. + + static ServerAddress Parse(const std::string &connection_string, uint16 default_port, CompanyID *company_id = nullptr); +}; + #endif /* NETWORK_CORE_ADDRESS_H */ diff --git a/src/network/core/tcp.h b/src/network/core/tcp.h index 3b217cb2e..379ef8b92 100644 --- a/src/network/core/tcp.h +++ b/src/network/core/tcp.h @@ -103,9 +103,14 @@ private: void Connect(addrinfo *address); bool CheckActivity(); + /* We do not want any other derived classes from this class being able to + * access these private members, but it is okay for TCPServerConnecter. */ + friend class TCPServerConnecter; + static void ResolveThunk(TCPConnecter *connecter); public: + TCPConnecter() {}; TCPConnecter(const std::string &connection_string, uint16 default_port); virtual ~TCPConnecter(); @@ -124,4 +129,11 @@ public: static void KillAll(); }; +class TCPServerConnecter : public TCPConnecter { +public: + ServerAddress server_address; ///< Address we are connecting to. + + TCPServerConnecter(const std::string &connection_string, uint16 default_port); +}; + #endif /* NETWORK_CORE_TCP_H */ diff --git a/src/network/core/tcp_connect.cpp b/src/network/core/tcp_connect.cpp index dc7a23bb3..bb96e33f9 100644 --- a/src/network/core/tcp_connect.cpp +++ b/src/network/core/tcp_connect.cpp @@ -33,6 +33,26 @@ TCPConnecter::TCPConnecter(const std::string &connection_string, uint16 default_ _tcp_connecters.push_back(this); } +/** + * Create a new connecter for the server. + * @param connection_string The address to connect to. + * @param default_port If not indicated in connection_string, what port to use. + */ +TCPServerConnecter::TCPServerConnecter(const std::string &connection_string, uint16 default_port) : + server_address(ServerAddress::Parse(connection_string, default_port)) +{ + switch (this->server_address.type) { + case SERVER_ADDRESS_DIRECT: + this->connection_string = this->server_address.connection_string; + break; + + default: + NOT_REACHED(); + } + + _tcp_connecters.push_back(this); +} + TCPConnecter::~TCPConnecter() { if (this->resolve_thread.joinable()) { diff --git a/src/network/network.cpp b/src/network/network.cpp index 395c374b8..4e48ce351 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -531,23 +531,6 @@ NetworkAddress ParseConnectionString(const std::string &connection_string, uint1 return NetworkAddress(ip, port); } -/** - * Convert a string containing either "hostname" or "hostname:ip" to a - * NetworkAddress, where the string can be postfixed with "#company" to - * indicate the requested company. - * - * @param connection_string The string to parse. - * @param default_port The default port to set port to if not in connection_string. - * @param company Pointer to the company variable to set iff indicted. - * @return A valid NetworkAddress of the parsed information. - */ -static NetworkAddress ParseGameConnectionString(const std::string &connection_string, uint16 default_port, CompanyID *company) -{ - uint16 port = default_port; - std::string_view ip = ParseFullConnectionString(connection_string, port, company); - return NetworkAddress(ip, port); -} - /** * Handle the accepting of a connection to the server. * @param s The socket of the new connection. @@ -624,12 +607,12 @@ static void NetworkInitialize(bool close_admins = true) } /** Non blocking connection to query servers for their game info. */ -class TCPQueryConnecter : TCPConnecter { +class TCPQueryConnecter : TCPServerConnecter { private: std::string connection_string; public: - TCPQueryConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {} + TCPQueryConnecter(const std::string &connection_string) : TCPServerConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {} void OnFailure() override { @@ -661,12 +644,12 @@ void NetworkQueryServer(const std::string &connection_string) } /** Non blocking connection to query servers for their game and company info. */ -class TCPLobbyQueryConnecter : TCPConnecter { +class TCPLobbyQueryConnecter : TCPServerConnecter { private: std::string connection_string; public: - TCPLobbyQueryConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {} + TCPLobbyQueryConnecter(const std::string &connection_string) : TCPServerConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {} void OnFailure() override { @@ -756,12 +739,12 @@ void NetworkRebuildHostList() } /** Non blocking connection create to actually connect to servers */ -class TCPClientConnecter : TCPConnecter { +class TCPClientConnecter : TCPServerConnecter { private: std::string connection_string; public: - TCPClientConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {} + TCPClientConnecter(const std::string &connection_string) : TCPServerConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {} void OnFailure() override { @@ -797,7 +780,7 @@ public: bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const std::string &join_server_password, const std::string &join_company_password) { CompanyID join_as = default_company; - std::string resolved_connection_string = ParseGameConnectionString(connection_string, NETWORK_DEFAULT_PORT, &join_as).GetAddressAsString(false); + std::string resolved_connection_string = ServerAddress::Parse(connection_string, NETWORK_DEFAULT_PORT, &join_as).connection_string; if (!_network_available) return false; if (!NetworkValidateOurClientName()) return false; diff --git a/src/network/network_gamelist.cpp b/src/network/network_gamelist.cpp index 92964bf25..d4843ff67 100644 --- a/src/network/network_gamelist.cpp +++ b/src/network/network_gamelist.cpp @@ -26,7 +26,7 @@ int _network_game_list_version = 0; ///< Current version of all items in the lis /** * Add a new item to the linked gamelist. If the IP and Port match * return the existing item instead of adding it again - * @param address the address of the to-be added item + * @param connection_string the address of the to-be added item * @return a point to the newly added or already existing item */ NetworkGameList *NetworkGameListAddItem(const std::string &connection_string) @@ -34,7 +34,7 @@ NetworkGameList *NetworkGameListAddItem(const std::string &connection_string) NetworkGameList *item, *prev_item; /* Parse the connection string to ensure the default port is there. */ - const std::string resolved_connection_string = ParseConnectionString(connection_string, NETWORK_DEFAULT_PORT).GetAddressAsString(false); + const std::string resolved_connection_string = ServerAddress::Parse(connection_string, NETWORK_DEFAULT_PORT).connection_string; prev_item = nullptr; for (item = _network_game_list; item != nullptr; item = item->next) { -- cgit v1.2.3-70-g09d2