summaryrefslogtreecommitdiff
path: root/network_udp.c
diff options
context:
space:
mode:
authortruelight <truelight@openttd.org>2005-01-05 14:39:48 +0000
committertruelight <truelight@openttd.org>2005-01-05 14:39:48 +0000
commit523a6a1cffd1a7567453835500f387f3499b10a2 (patch)
tree0321af6b507ef39cda02042c21cc3ae5e417a162 /network_udp.c
parentf1e9fdf76d951dec71c330f12783917cae464160 (diff)
downloadopenttd-523a6a1cffd1a7567453835500f387f3499b10a2.tar.xz
(svn r1389) -Add: [Network] Added packet protection. No longer a client or server
reads beyond the size of the packet -Fix: [Network] A server no longer crashes when a client sends an invalid DoCommand, but drops the client instead.
Diffstat (limited to 'network_udp.c')
-rw-r--r--network_udp.c53
1 files changed, 32 insertions, 21 deletions
diff --git a/network_udp.c b/network_udp.c
index 8abf9171b..bd319322a 100644
--- a/network_udp.c
+++ b/network_udp.c
@@ -38,6 +38,8 @@ enum {
#define DEF_UDP_RECEIVE_COMMAND(type) void NetworkPacketReceive_ ## type ## _command(Packet *p, struct sockaddr_in *client_addr)
void NetworkSendUDP_Packet(SOCKET udp, Packet *p, struct sockaddr_in *recv);
+NetworkClientState _udp_cs;
+
DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER)
{
Packet *packet;
@@ -86,8 +88,10 @@ DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE)
if (_network_udp_server)
return;
- game_info_version = NetworkRecv_uint8(p);
+ game_info_version = NetworkRecv_uint8(&_udp_cs, p);
+ if (_udp_cs.quited)
+ return;
DEBUG(net, 6)("[NET][UDP] Server response from %s:%d", inet_ntoa(client_addr->sin_addr),ntohs(client_addr->sin_port));
@@ -95,20 +99,20 @@ DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE)
item = NetworkGameListAddItem(inet_addr(inet_ntoa(client_addr->sin_addr)), ntohs(client_addr->sin_port));
if (game_info_version == 1) {
- NetworkRecv_string(p, item->info.server_name, sizeof(item->info.server_name));
- NetworkRecv_string(p, item->info.server_revision, sizeof(item->info.server_revision));
- item->info.server_lang = NetworkRecv_uint8(p);
- item->info.use_password = NetworkRecv_uint8(p);
- item->info.clients_max = NetworkRecv_uint8(p);
- item->info.clients_on = NetworkRecv_uint8(p);
- item->info.spectators_on = NetworkRecv_uint8(p);
- item->info.game_date = NetworkRecv_uint16(p);
- item->info.start_date = NetworkRecv_uint16(p);
- NetworkRecv_string(p, item->info.map_name, sizeof(item->info.map_name));
- item->info.map_width = NetworkRecv_uint16(p);
- item->info.map_height = NetworkRecv_uint16(p);
- item->info.map_set = NetworkRecv_uint8(p);
- item->info.dedicated = NetworkRecv_uint8(p);
+ NetworkRecv_string(&_udp_cs, p, item->info.server_name, sizeof(item->info.server_name));
+ NetworkRecv_string(&_udp_cs, p, item->info.server_revision, sizeof(item->info.server_revision));
+ item->info.server_lang = NetworkRecv_uint8(&_udp_cs, p);
+ item->info.use_password = NetworkRecv_uint8(&_udp_cs, p);
+ item->info.clients_max = NetworkRecv_uint8(&_udp_cs, p);
+ item->info.clients_on = NetworkRecv_uint8(&_udp_cs, p);
+ item->info.spectators_on = NetworkRecv_uint8(&_udp_cs, p);
+ item->info.game_date = NetworkRecv_uint16(&_udp_cs, p);
+ item->info.start_date = NetworkRecv_uint16(&_udp_cs, p);
+ NetworkRecv_string(&_udp_cs, p, item->info.map_name, sizeof(item->info.map_name));
+ item->info.map_width = NetworkRecv_uint16(&_udp_cs, p);
+ item->info.map_height = NetworkRecv_uint16(&_udp_cs, p);
+ item->info.map_set = NetworkRecv_uint8(&_udp_cs, p);
+ item->info.dedicated = NetworkRecv_uint8(&_udp_cs, p);
if (item->info.hostname[0] == '\0')
snprintf(item->info.hostname, sizeof(item->info.hostname), "%s", inet_ntoa(client_addr->sin_addr));
@@ -237,12 +241,15 @@ DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_MASTER_RESPONSE_LIST) {
* an uint32 (ip) and an uint16 (port) for each pair
*/
- ver = NetworkRecv_uint8(p);
+ ver = NetworkRecv_uint8(&_udp_cs, p);
+
+ if (_udp_cs.quited)
+ return;
if (ver == 1) {
- for (i = NetworkRecv_uint16(p); i != 0 ; i--) {
- ip.s_addr = TO_LE32(NetworkRecv_uint32(p));
- port = NetworkRecv_uint16(p);
+ for (i = NetworkRecv_uint16(&_udp_cs, p); i != 0 ; i--) {
+ ip.s_addr = TO_LE32(NetworkRecv_uint32(&_udp_cs, p));
+ port = NetworkRecv_uint16(&_udp_cs, p);
NetworkUDPQueryServer(inet_ntoa(ip), port);
}
}
@@ -282,9 +289,13 @@ void NetworkHandleUDPPacket(Packet *p, struct sockaddr_in *client_addr)
{
byte type;
- type = NetworkRecv_uint8(p);
+ /* Fake a client, so we can see when there is an illegal packet */
+ _udp_cs.socket = INVALID_SOCKET;
+ _udp_cs.quited = false;
+
+ type = NetworkRecv_uint8(&_udp_cs, p);
- if (type < PACKET_UDP_END && _network_udp_packet[type] != NULL) {
+ if (type < PACKET_UDP_END && _network_udp_packet[type] != NULL && !_udp_cs.quited) {
_network_udp_packet[type](p, client_addr);
} else {
DEBUG(net, 0)("[NET][UDP] Received invalid packet type %d", type);