summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2010-08-19 08:59:36 +0000
committerrubidium <rubidium@openttd.org>2010-08-19 08:59:36 +0000
commita4c6d07edc4937087e3f2d0b2bff52cc3980b9e2 (patch)
tree9a939be9e5c3b7bc5a0101cb3077a3d619d2dad8 /src/network
parentcfc0df152b40c7109ce6c2e60f80304fc97adb89 (diff)
downloadopenttd-a4c6d07edc4937087e3f2d0b2bff52cc3980b9e2.tar.xz
(svn r20553) -Feature: allow rate limiting of incoming commands
Diffstat (limited to 'src/network')
-rw-r--r--src/network/core/tcp_game.h3
-rw-r--r--src/network/network.cpp8
-rw-r--r--src/network/network_client.cpp3
-rw-r--r--src/network/network_command.cpp12
-rw-r--r--src/network/network_server.cpp4
-rw-r--r--src/network/network_type.h1
6 files changed, 25 insertions, 6 deletions
diff --git a/src/network/core/tcp_game.h b/src/network/core/tcp_game.h
index a7d3bb462..acbd47ed8 100644
--- a/src/network/core/tcp_game.h
+++ b/src/network/core/tcp_game.h
@@ -78,6 +78,7 @@ struct CommandPacket;
class CommandQueue {
CommandPacket *first; ///< The first packet in the queue.
CommandPacket *last; ///< The last packet in the queue; only valid when first != NULL.
+ uint count; ///< The number of items in the queue.
public:
/** Initialise the command queue. */
@@ -88,6 +89,8 @@ public:
CommandPacket *Pop();
CommandPacket *Peek();
void Free();
+ /** Get the number of items in the queue. */
+ uint Count() const { return this->count; }
};
/** Status of a client */
diff --git a/src/network/network.cpp b/src/network/network.cpp
index cf74c621b..00863f8ad 100644
--- a/src/network/network.cpp
+++ b/src/network/network.cpp
@@ -344,7 +344,8 @@ StringID GetNetworkErrorMsg(NetworkErrorCode err)
STR_NETWORK_ERROR_CLIENT_COMPANY_MISMATCH,
STR_NETWORK_ERROR_CLIENT_KICKED,
STR_NETWORK_ERROR_CLIENT_CHEATER,
- STR_NETWORK_ERROR_CLIENT_SERVER_FULL
+ STR_NETWORK_ERROR_CLIENT_SERVER_FULL,
+ STR_NETWORK_ERROR_CLIENT_TOO_MANY_COMMANDS
};
if (err >= (ptrdiff_t)lengthof(network_error_strings)) err = NETWORK_ERROR_GENERAL;
@@ -1181,14 +1182,13 @@ void NetworkGameLoop()
f = NULL;
}
#endif /* DEBUG_DUMP_COMMANDS */
- NetworkDistributeCommands();
-
if (_frame_counter >= _frame_counter_max) {
/* Only check for active clients just before we're going to send out
* the commands so we don't send multiple pause/unpause commands when
- * the frame_freq is more than 1 tick. */
+ * the frame_freq is more than 1 tick. Same with distributing commands. */
CheckPauseOnJoin();
CheckMinActiveClients();
+ NetworkDistributeCommands();
}
bool send_frame = false;
diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp
index ea478276b..b6ffcbb22 100644
--- a/src/network/network_client.cpp
+++ b/src/network/network_client.cpp
@@ -515,6 +515,9 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_ERROR)
case NETWORK_ERROR_CHEATER:
_switch_mode_errorstr = STR_NETWORK_ERROR_CHEATER;
break;
+ case NETWORK_ERROR_TOO_MANY_COMMANDS:
+ _switch_mode_errorstr = STR_NETWORK_ERROR_TOO_MANY_COMMANDS;
+ break;
default:
_switch_mode_errorstr = STR_NETWORK_ERROR_LOSTCONNECTION;
}
diff --git a/src/network/network_command.cpp b/src/network/network_command.cpp
index 1bec93c7a..1b1712203 100644
--- a/src/network/network_command.cpp
+++ b/src/network/network_command.cpp
@@ -17,6 +17,7 @@
#include "network.h"
#include "../command_func.h"
#include "../company_func.h"
+#include "../settings_type.h"
/** Table with all the callbacks we'll use for conversion*/
static CommandCallback * const _callback_table[] = {
@@ -68,6 +69,7 @@ void CommandQueue::Append(CommandPacket *p)
this->last->next = add;
}
this->last = add;
+ this->count++;
}
/**
@@ -77,7 +79,10 @@ void CommandQueue::Append(CommandPacket *p)
CommandPacket *CommandQueue::Pop()
{
CommandPacket *ret = this->first;
- if (ret != NULL) this->first = this->first->next;
+ if (ret != NULL) {
+ this->first = this->first->next;
+ this->count--;
+ }
return ret;
}
@@ -97,6 +102,7 @@ void CommandQueue::Free()
while ((cp = this->Pop()) != NULL) {
free(cp);
}
+ assert(this->count == 0);
}
/** Local queue of packets waiting for handling. */
@@ -241,8 +247,10 @@ static void DistributeCommandPacket(CommandPacket cp, const NetworkClientSocket
*/
static void DistributeQueue(CommandQueue *queue, const NetworkClientSocket *owner)
{
+ int to_go = _settings_client.network.commands_per_frame;
+
CommandPacket *cp;
- while ((cp = queue->Pop()) != NULL) {
+ while (--to_go >= 0 && (cp = queue->Pop()) != NULL) {
DistributeCommandPacket(*cp, owner);
free(cp);
}
diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp
index dc7d9d0f6..b8ea9fa62 100644
--- a/src/network/network_server.cpp
+++ b/src/network/network_server.cpp
@@ -897,6 +897,10 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)
return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
}
+ if (cs->incoming_queue.Count() >= _settings_client.network.max_commands_in_queue) {
+ return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_TOO_MANY_COMMANDS);
+ }
+
CommandPacket cp;
const char *err = cs->Recv_Command(p, &cp);
diff --git a/src/network/network_type.h b/src/network/network_type.h
index a86ad9948..5b83620e6 100644
--- a/src/network/network_type.h
+++ b/src/network/network_type.h
@@ -110,6 +110,7 @@ enum NetworkErrorCode {
NETWORK_ERROR_KICKED,
NETWORK_ERROR_CHEATER,
NETWORK_ERROR_FULL,
+ NETWORK_ERROR_TOO_MANY_COMMANDS,
};
#endif /* ENABLE_NETWORK */