changeset 11279:2f792e7a69dd draft

(svn r15628) -Fix [FS#2705]: kicking/banning a client from the Client list window crashed the server
author smatz <smatz@openttd.org>
date Fri, 06 Mar 2009 12:42:01 +0000
parents d1a6e82f03c5
children 2bfe78996515
files src/console_cmds.cpp src/network/network_func.h src/network/network_gui.cpp src/network/network_server.cpp
diffstat 4 files changed, 40 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/src/console_cmds.cpp
+++ b/src/console_cmds.cpp
@@ -411,18 +411,11 @@
 	if (ci != NULL) {
 		IConsolePrint(CC_DEFAULT, "Client banned");
 		banip = GetClientIP(ci);
-		NetworkServerSendError(client_id, NETWORK_ERROR_KICKED);
 	} else {
 		IConsolePrint(CC_DEFAULT, "Client not online, banned IP");
 	}
 
-	/* Add user to ban-list */
-	for (uint index = 0; index < lengthof(_network_ban_list); index++) {
-		if (_network_ban_list[index] == NULL) {
-			_network_ban_list[index] = strdup(banip);
-			break;
-		}
-	}
+	NetworkServerBanIP(banip);
 
 	return true;
 }
@@ -613,7 +606,7 @@
 	}
 
 	if (ci != NULL) {
-		NetworkServerSendError(client_id, NETWORK_ERROR_KICKED);
+		NetworkServerKickClient(client_id);
 	} else {
 		IConsoleError("Client not found");
 	}
--- a/src/network/network_func.h
+++ b/src/network/network_func.h
@@ -69,6 +69,9 @@
 void NetworkServerSendError(ClientID client_id, NetworkErrorCode error);
 void NetworkServerSendChat(NetworkAction action, DestType type, int dest, const char *msg, ClientID from_id, int64 data = 0);
 
+void NetworkServerKickClient(ClientID client_id);
+void NetworkServerBanIP(const char *banip);
+
 void NetworkInitChatMessage();
 void CDECL NetworkAddChatMessage(TextColour colour, uint8 duration, const char *message, ...);
 void NetworkUndrawChatMessage();
--- a/src/network/network_gui.cpp
+++ b/src/network/network_gui.cpp
@@ -1445,25 +1445,20 @@
 // Here we start to define the options out of the menu
 static void ClientList_Kick(byte client_no)
 {
-	if (client_no < MAX_CLIENTS) {
-		SEND_COMMAND(PACKET_SERVER_ERROR)(GetNetworkClientSocket(client_no), NETWORK_ERROR_KICKED);
-	}
+	const NetworkClientInfo *ci = NetworkFindClientInfo(client_no);
+
+	if (ci == NULL) return;
+
+	NetworkServerKickClient(ci->client_id);
 }
 
 static void ClientList_Ban(byte client_no)
 {
-	uint32 ip = NetworkFindClientInfo(client_no)->client_ip;
+	const NetworkClientInfo *ci = NetworkFindClientInfo(client_no);
 
-	for (uint i = 0; i < lengthof(_network_ban_list); i++) {
-		if (_network_ban_list[i] == NULL) {
-			_network_ban_list[i] = strdup(inet_ntoa(*(struct in_addr *)&ip));
-			break;
-		}
-	}
+	if (ci == NULL) return;
 
-	if (client_no < MAX_CLIENTS) {
-		SEND_COMMAND(PACKET_SERVER_ERROR)(GetNetworkClientSocket(client_no), NETWORK_ERROR_KICKED);
-	}
+	NetworkServerBanIP(GetClientIP(ci));
 }
 
 static void ClientList_GiveMoney(byte client_no)
--- a/src/network/network_server.cpp
+++ b/src/network/network_server.cpp
@@ -1766,6 +1766,33 @@
 	SEND_COMMAND(PACKET_SERVER_ERROR)(NetworkFindClientStateFromClientID(client_id), error);
 }
 
+void NetworkServerKickClient(ClientID client_id)
+{
+	if (client_id == CLIENT_ID_SERVER) return;
+	NetworkServerSendError(client_id, NETWORK_ERROR_KICKED);
+}
+
+void NetworkServerBanIP(const char *banip)
+{
+	const NetworkClientInfo *ci;
+	uint32 ip_number = inet_addr(banip);
+
+	/* There can be multiple clients with the same IP, kick them all */
+	FOR_ALL_CLIENT_INFOS(ci) {
+		if (ci->client_ip == ip_number) {
+			NetworkServerKickClient(ci->client_id);
+		}
+	}
+
+	/* Add user to ban-list */
+	for (uint index = 0; index < lengthof(_network_ban_list); index++) {
+		if (_network_ban_list[index] == NULL) {
+			_network_ban_list[index] = strdup(banip);
+			break;
+		}
+	}
+}
+
 bool NetworkCompanyHasClients(CompanyID company)
 {
 	const NetworkClientInfo *ci;