summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2009-01-20 01:32:06 +0000
committerrubidium <rubidium@openttd.org>2009-01-20 01:32:06 +0000
commit5f3772a42c322a99d2ea57b6c97b76fceccbb781 (patch)
treef14ce239c04d4b6e3d7f4dbe6723e777a42cc03f
parent6e1af6a051b5129c0703dd654794427094d672c8 (diff)
downloadopenttd-5f3772a42c322a99d2ea57b6c97b76fceccbb781.tar.xz
(svn r15157) -Codechange: wrap the hostname/ip and port into a single structure so we can pass either one of them and not convert an ip to a string and then back again.
-rw-r--r--src/console_cmds.cpp2
-rw-r--r--src/network/network.cpp52
-rw-r--r--src/network/network_func.h4
-rw-r--r--src/network/network_gamelist.cpp9
-rw-r--r--src/network/network_gui.cpp16
-rw-r--r--src/network/network_internal.h2
-rw-r--r--src/network/network_type.h91
-rw-r--r--src/network/network_udp.cpp27
-rw-r--r--src/network/network_udp.h2
-rw-r--r--src/openttd.cpp6
10 files changed, 155 insertions, 56 deletions
diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp
index ad3375873..c0ef53e30 100644
--- a/src/console_cmds.cpp
+++ b/src/console_cmds.cpp
@@ -692,7 +692,7 @@ DEF_CONSOLE_CMD(ConNetworkConnect)
IConsolePrintF(CC_DEFAULT, " port: %s", port);
}
- NetworkClientConnectGame(ip, rport);
+ NetworkClientConnectGame(NetworkAddress(ip, rport));
return true;
}
diff --git a/src/network/network.cpp b/src/network/network.cpp
index a9175385a..edf6a51b6 100644
--- a/src/network/network.cpp
+++ b/src/network/network.cpp
@@ -451,12 +451,12 @@ void NetworkCloseClient(NetworkClientSocket *cs)
}
// A client wants to connect to a server
-static bool NetworkConnect(const char *hostname, int port)
+static bool NetworkConnect(NetworkAddress address)
{
SOCKET s;
struct sockaddr_in sin;
- DEBUG(net, 1, "Connecting to %s %d", hostname, port);
+ DEBUG(net, 1, "Connecting to %s %d", address.GetHostname(), address.GetPort());
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == INVALID_SOCKET) {
@@ -467,8 +467,8 @@ static bool NetworkConnect(const char *hostname, int port)
if (!SetNoDelay(s)) DEBUG(net, 1, "Setting TCP_NODELAY failed");
sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = NetworkResolveHost(hostname);
- sin.sin_port = htons(port);
+ sin.sin_addr.s_addr = address.GetIP();
+ sin.sin_port = htons(address.GetIP());
_network_last_host_ip = sin.sin_addr.s_addr;
/* We failed to connect for which reason what so ever */
@@ -664,7 +664,7 @@ static void NetworkInitialize()
// Query a server to fetch his game-info
// If game_info is true, only the gameinfo is fetched,
// else only the client_info is fetched
-void NetworkTCPQueryServer(const char *host, unsigned short port)
+void NetworkTCPQueryServer(NetworkAddress address)
{
if (!_network_available) return;
@@ -672,7 +672,7 @@ void NetworkTCPQueryServer(const char *host, unsigned short port)
NetworkInitialize();
// Try to connect
- _networking = NetworkConnect(host, port);
+ _networking = NetworkConnect(address);
// We are connected
if (_networking) {
@@ -701,7 +701,7 @@ void NetworkAddServer(const char *b)
ParseConnectionString(&company, &port, host);
if (port != NULL) rport = atoi(port);
- NetworkUDPQueryServer(host, rport, true);
+ NetworkUDPQueryServer(NetworkAddress(host, rport), true);
}
}
@@ -727,20 +727,20 @@ void NetworkRebuildHostList()
}
// Used by clients, to connect to a server
-void NetworkClientConnectGame(const char *host, uint16 port)
+void NetworkClientConnectGame(NetworkAddress address)
{
if (!_network_available) return;
- if (port == 0) return;
+ if (address.GetPort() == 0) return;
- strecpy(_settings_client.network.last_host, host, lastof(_settings_client.network.last_host));
- _settings_client.network.last_port = port;
+ strecpy(_settings_client.network.last_host, address.GetHostname(), lastof(_settings_client.network.last_host));
+ _settings_client.network.last_port = address.GetPort();
NetworkDisconnect();
NetworkInitialize();
// Try to connect
- _networking = NetworkConnect(host, port);
+ _networking = NetworkConnect(address);
// We are connected
if (_networking) {
@@ -1073,13 +1073,13 @@ static void NetworkGenerateUniqueId()
snprintf(_settings_client.network.network_id, sizeof(_settings_client.network.network_id), "%s", hex_output);
}
-void NetworkStartDebugLog(const char *hostname, uint16 port)
+void NetworkStartDebugLog(NetworkAddress address)
{
extern SOCKET _debug_socket; // Comes from debug.c
SOCKET s;
struct sockaddr_in sin;
- DEBUG(net, 0, "Redirecting DEBUG() to %s:%d", hostname, port);
+ DEBUG(net, 0, "Redirecting DEBUG() to %s:%d", address.GetHostname(), address.GetPort());
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == INVALID_SOCKET) {
@@ -1090,11 +1090,11 @@ void NetworkStartDebugLog(const char *hostname, uint16 port)
if (!SetNoDelay(s)) DEBUG(net, 1, "Setting TCP_NODELAY failed");
sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = NetworkResolveHost(hostname);
- sin.sin_port = htons(port);
+ sin.sin_addr.s_addr = address.GetIP();
+ sin.sin_port = htons(address.GetPort());
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) != 0) {
- DEBUG(net, 0, "Failed to redirection DEBUG() to %s:%d", hostname, port);
+ DEBUG(net, 0, "Failed to redirection DEBUG() to %s:%d", address.GetHostname(), address.GetIP());
return;
}
@@ -1154,6 +1154,24 @@ bool IsNetworkCompatibleVersion(const char *other)
return strncmp(_openttd_revision, other, NETWORK_REVISION_LENGTH - 1) == 0;
}
+const char *NetworkAddress::GetHostname() const
+{
+ if (this->hostname != NULL) return this->hostname;
+
+ in_addr addr;
+ addr.s_addr = this->ip;
+ return inet_ntoa(addr);
+}
+
+uint32 NetworkAddress::GetIP()
+{
+ if (!this->resolved) {
+ this->ip = NetworkResolveHost(this->hostname);
+ this->resolved = true;
+ }
+ return this->ip;
+}
+
#endif /* ENABLE_NETWORK */
/* NOTE: this variable needs to be always available */
diff --git a/src/network/network_func.h b/src/network/network_func.h
index db3de7f8f..c2de52ca7 100644
--- a/src/network/network_func.h
+++ b/src/network/network_func.h
@@ -32,11 +32,11 @@ void NetworkGameLoop();
void NetworkUDPGameLoop();
void NetworkUDPCloseAll();
void ParseConnectionString(const char **company, const char **port, char *connection_string);
-void NetworkStartDebugLog(const char *hostname, uint16 port);
+void NetworkStartDebugLog(NetworkAddress address);
void NetworkPopulateCompanyStats(NetworkCompanyStats *stats);
void NetworkUpdateClientInfo(ClientID client_id);
-void NetworkClientConnectGame(const char *host, uint16 port);
+void NetworkClientConnectGame(NetworkAddress address);
void NetworkClientSendRcon(const char *password, const char *command);
void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const char *msg, int64 data = 0);
void NetworkClientSetPassword(const char *password);
diff --git a/src/network/network_gamelist.cpp b/src/network/network_gamelist.cpp
index efec52220..235e9afe3 100644
--- a/src/network/network_gamelist.cpp
+++ b/src/network/network_gamelist.cpp
@@ -96,18 +96,13 @@ void NetworkGameListRequery()
if (++requery_cnt < REQUERY_EVERY_X_GAMELOOPS) return;
requery_cnt = 0;
- struct in_addr ip;
- NetworkGameList *item;
-
- for (item = _network_game_list; item != NULL; item = item->next) {
+ for (NetworkGameList *item = _network_game_list; item != NULL; item = item->next) {
item->retries++;
if (item->retries < REFRESH_GAMEINFO_X_REQUERIES && (item->online || item->retries >= MAX_GAME_LIST_REQUERY_COUNT)) continue;
- ip.s_addr = item->ip;
-
/* item gets mostly zeroed by NetworkUDPQueryServer */
uint8 retries = item->retries;
- NetworkUDPQueryServer(inet_ntoa(ip), item->port);
+ NetworkUDPQueryServer(NetworkAddress(item->ip, item->port));
item->retries = (retries >= REFRESH_GAMEINFO_X_REQUERIES) ? 0 : retries;
}
}
diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp
index f9b0b7cc9..7209e8145 100644
--- a/src/network/network_gui.cpp
+++ b/src/network/network_gui.cpp
@@ -558,7 +558,7 @@ public:
break;
case NGWW_REFRESH: // Refresh
- if (this->server != NULL) NetworkUDPQueryServer(this->server->info.hostname, this->server->port);
+ if (this->server != NULL) NetworkUDPQueryServer(NetworkAddress(this->server->info.hostname, this->server->port));
break;
case NGWW_NEWGRF: // NewGRF Settings
@@ -1313,22 +1313,22 @@ struct NetworkLobbyWindow : public Window {
case NLWW_JOIN: // Join company
/* Button can be clicked only when it is enabled */
_network_playas = this->company;
- NetworkClientConnectGame(_settings_client.network.last_host, _settings_client.network.last_port);
+ NetworkClientConnectGame(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port));
break;
case NLWW_NEW: // New company
_network_playas = COMPANY_NEW_COMPANY;
- NetworkClientConnectGame(_settings_client.network.last_host, _settings_client.network.last_port);
+ NetworkClientConnectGame(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port));
break;
case NLWW_SPECTATE: // Spectate game
_network_playas = COMPANY_SPECTATOR;
- NetworkClientConnectGame(_settings_client.network.last_host, _settings_client.network.last_port);
+ NetworkClientConnectGame(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port));
break;
case NLWW_REFRESH: // Refresh
- NetworkTCPQueryServer(_settings_client.network.last_host, _settings_client.network.last_port); // company info
- NetworkUDPQueryServer(_settings_client.network.last_host, _settings_client.network.last_port); // general data
+ NetworkTCPQueryServer(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port)); // company info
+ NetworkUDPQueryServer(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port)); // general data
/* Clear the information so removed companies don't remain */
memset(this->company_info, 0, sizeof(company_info));
break;
@@ -1381,8 +1381,8 @@ static void ShowNetworkLobbyWindow(NetworkGameList *ngl)
{
DeleteWindowById(WC_NETWORK_WINDOW, 0);
- NetworkTCPQueryServer(_settings_client.network.last_host, _settings_client.network.last_port); // company info
- NetworkUDPQueryServer(_settings_client.network.last_host, _settings_client.network.last_port); // general data
+ NetworkTCPQueryServer(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port)); // company info
+ NetworkUDPQueryServer(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port)); // general data
new NetworkLobbyWindow(&_network_lobby_window_desc, ngl);
}
diff --git a/src/network/network_internal.h b/src/network/network_internal.h
index be78ae772..8065d660b 100644
--- a/src/network/network_internal.h
+++ b/src/network/network_internal.h
@@ -122,7 +122,7 @@ extern uint16 _network_udp_broadcast;
extern uint8 _network_advertise_retries;
-void NetworkTCPQueryServer(const char *host, unsigned short port);
+void NetworkTCPQueryServer(NetworkAddress address);
void NetworkAddServer(const char *b);
void NetworkRebuildHostList();
diff --git a/src/network/network_type.h b/src/network/network_type.h
index 9104e2f0f..4c6c3e829 100644
--- a/src/network/network_type.h
+++ b/src/network/network_type.h
@@ -11,6 +11,7 @@
#include "../economy_type.h"
#include "core/config.h"
#include "core/game.h"
+#include "core/os_abstraction.h"
enum {
/** How many clients can we have */
@@ -114,5 +115,95 @@ enum NetworkErrorCode {
NETWORK_ERROR_FULL,
};
+/**
+ * Wrapper for (un)resolved network addresses; there's no reason to transform
+ * a numeric IP to a string and then back again to pass it to functions. It
+ * furthermore allows easier delaying of the hostname lookup.
+ */
+class NetworkAddress {
+private:
+ bool resolved; ///< Has the IP address been resolved
+ char *hostname; ///< The hostname, NULL if there isn't one
+ uint32 ip; ///< The resolved IP address
+ uint16 port; ///< The port associated with the address
+
+public:
+ /**
+ * Create a network address based on a resolved IP and port
+ * @param ip the resolved ip
+ * @param port the port
+ */
+ NetworkAddress(in_addr_t ip, uint16 port) :
+ resolved(true),
+ hostname(NULL),
+ ip(ip),
+ port(port)
+ {
+ }
+
+ /**
+ * Create a network address based on a unresolved host and port
+ * @param ip the unresolved hostname
+ * @param port the port
+ */
+ NetworkAddress(const char *hostname, uint16 port) :
+ resolved(false),
+ hostname(strdup(hostname)),
+ ip(0),
+ port(port)
+ {
+ }
+
+ /**
+ * Make a clone of another address
+ * @param address the address to clone
+ */
+ NetworkAddress(const NetworkAddress &address) :
+ resolved(address.resolved),
+ hostname(address.hostname == NULL ? NULL : strdup(address.hostname)),
+ ip(address.ip),
+ port(address.port)
+ {
+ }
+
+ /** Clean up our mess */
+ ~NetworkAddress()
+ {
+ free(hostname);
+ }
+
+ /**
+ * Get the hostname; in case it wasn't given the
+ * IPv4 dotted representation is given.
+ * @return the hostname
+ */
+ const char *GetHostname() const;
+
+ /**
+ * Get the IP address. If the IP has not been resolved yet this will resolve
+ * it possibly blocking this function for a while
+ * @return the IP address
+ */
+ uint32 GetIP();
+
+ /**
+ * Get the port
+ * @return the port
+ */
+ uint16 GetPort() const
+ {
+ return this->port;
+ }
+
+ /**
+ * Check whether the IP address has been resolved already
+ * @return true iff the port has been resolved
+ */
+ bool IsResolved() const
+ {
+ return this->resolved;
+ }
+};
+
#endif /* ENABLE_NETWORK */
#endif /* NETWORK_TYPE_H */
diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp
index 822347b41..9c42d8d31 100644
--- a/src/network/network_udp.cpp
+++ b/src/network/network_udp.cpp
@@ -276,27 +276,22 @@ DEF_UDP_RECEIVE_COMMAND(Client, PACKET_UDP_SERVER_RESPONSE)
DEF_UDP_RECEIVE_COMMAND(Client, PACKET_UDP_MASTER_RESPONSE_LIST)
{
- int i;
- struct in_addr ip;
- uint16 port;
- uint8 ver;
-
/* packet begins with the protocol version (uint8)
* then an uint16 which indicates how many
* ip:port pairs are in this packet, after that
* an uint32 (ip) and an uint16 (port) for each pair
*/
- ver = p->Recv_uint8();
+ uint8 ver = p->Recv_uint8();
if (ver == 1) {
- for (i = p->Recv_uint16(); i != 0 ; i--) {
- ip.s_addr = TO_LE32(p->Recv_uint32());
- port = p->Recv_uint16();
+ for (int i = p->Recv_uint16(); i != 0 ; i--) {
+ uint32 ip = TO_LE32(p->Recv_uint32());
+ uint16 port = p->Recv_uint16();
/* Somehow we reached the end of the packet */
if (this->HasClientQuit()) return;
- NetworkUDPQueryServer(inet_ntoa(ip), port);
+ NetworkUDPQueryServer(NetworkAddress(ip, port));
}
}
}
@@ -425,7 +420,7 @@ void NetworkUDPSearchGame()
_network_udp_broadcast = 300; // Stay searching for 300 ticks
}
-void NetworkUDPQueryServer(const char *host, unsigned short port, bool manually)
+void NetworkUDPQueryServer(NetworkAddress address, bool manually)
{
struct sockaddr_in out_addr;
NetworkGameList *item;
@@ -436,17 +431,17 @@ void NetworkUDPQueryServer(const char *host, unsigned short port, bool manually)
}
out_addr.sin_family = AF_INET;
- out_addr.sin_port = htons(port);
- out_addr.sin_addr.s_addr = NetworkResolveHost(host);
+ out_addr.sin_port = htons(address.GetPort());
+ out_addr.sin_addr.s_addr = address.GetIP();
// Clear item in gamelist
- item = NetworkGameListAddItem(inet_addr(inet_ntoa(out_addr.sin_addr)), ntohs(out_addr.sin_port));
+ item = NetworkGameListAddItem(address.GetIP(), address.GetPort());
if (item == NULL) return;
if (StrEmpty(item->info.server_name)) {
memset(&item->info, 0, sizeof(item->info));
- strecpy(item->info.server_name, host, lastof(item->info.server_name));
- strecpy(item->info.hostname, host, lastof(item->info.hostname));
+ strecpy(item->info.server_name, address.GetHostname(), lastof(item->info.server_name));
+ strecpy(item->info.hostname, address.GetHostname(), lastof(item->info.hostname));
item->online = false;
}
item->manually = manually;
diff --git a/src/network/network_udp.h b/src/network/network_udp.h
index 48fa4e1e6..736524c00 100644
--- a/src/network/network_udp.h
+++ b/src/network/network_udp.h
@@ -10,7 +10,7 @@
void NetworkUDPInitialize();
void NetworkUDPSearchGame();
void NetworkUDPQueryMasterServer();
-void NetworkUDPQueryServer(const char *host, unsigned short port, bool manually = false);
+void NetworkUDPQueryServer(NetworkAddress address, bool manually = false);
void NetworkUDPAdvertise();
void NetworkUDPRemoveAdvertise();
void NetworkUDPShutdown();
diff --git a/src/openttd.cpp b/src/openttd.cpp
index 703bfdb7c..1150cabfa 100644
--- a/src/openttd.cpp
+++ b/src/openttd.cpp
@@ -681,7 +681,7 @@ int ttd_main(int argc, char *argv[])
ParseConnectionString(&not_used, &port, debuglog_conn);
if (port != NULL) rport = atoi(port);
- NetworkStartDebugLog(debuglog_conn, rport);
+ NetworkStartDebugLog(NetworkAddress(debuglog_conn, rport));
}
#endif /* ENABLE_NETWORK */
@@ -728,7 +728,7 @@ int ttd_main(int argc, char *argv[])
LoadIntroGame();
_switch_mode = SM_NONE;
- NetworkClientConnectGame(network_conn, rport);
+ NetworkClientConnectGame(NetworkAddress(network_conn, rport));
}
}
#endif /* ENABLE_NETWORK */
@@ -1219,7 +1219,7 @@ void GameLoop()
if (_network_reconnect > 0 && --_network_reconnect == 0) {
/* This means that we want to reconnect to the last host
* We do this here, because it means that the network is really closed */
- NetworkClientConnectGame(_settings_client.network.last_host, _settings_client.network.last_port);
+ NetworkClientConnectGame(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port));
}
/* Singleplayer */
StateGameLoop();