ref: 2d45e6c02cfe002ff4c5a3aa6a360f918ee54e61
parent: 89332f29ae9d780129c2bcc2a831f959eda255ec
author: Simon Howard <[email protected]>
date: Thu Apr 6 13:53:43 EDT 2006
Sanity check data received by the server. Send version string earlier in SYN packets to allow the fields that follow to be changed later on if necessary. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 461
--- a/src/net_client.c
+++ b/src/net_client.c
@@ -1,7 +1,7 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
-// $Id: net_client.c 455 2006-03-30 19:08:37Z fraggle $
+// $Id: net_client.c 461 2006-04-06 17:53:43Z fraggle $
//
// Copyright(C) 2005 Simon Howard
//
@@ -1012,11 +1012,11 @@
packet = NET_NewPacket(10);
NET_WriteInt16(packet, NET_PACKET_TYPE_SYN);
NET_WriteInt32(packet, NET_MAGIC_NUMBER);
+ NET_WriteString(packet, PACKAGE_STRING);
NET_WriteInt16(packet, gamemode);
NET_WriteInt16(packet, gamemission);
NET_WriteInt8(packet, lowres_turn);
NET_WriteString(packet, net_player_name);
- NET_WriteString(packet, PACKAGE_STRING);
NET_Conn_SendPacket(&client_connection, packet);
NET_FreePacket(packet);
}
--- a/src/net_common.c
+++ b/src/net_common.c
@@ -1,7 +1,7 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
-// $Id: net_common.c 456 2006-03-30 19:13:20Z fraggle $
+// $Id: net_common.c 461 2006-04-06 17:53:43Z fraggle $
//
// Copyright(C) 2005 Simon Howard
//
@@ -557,4 +557,71 @@
putchar('\n');
}
+// Check that a gamemode+gamemission received over the network is valid.
+
+boolean NET_ValidGameMode(GameMode_t mode, GameMission_t mission)
+{
+ if (mode == shareware || mode == registered || mode == retail)
+ {
+ return true;
+ }
+ else if (mode == commercial)
+ {
+ return mission == doom2 || mission == pack_tnt || mission == pack_plut;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+// Check that game settings are valid
+
+boolean NET_ValidGameSettings(GameMode_t mode, GameMission_t mission,
+ net_gamesettings_t *settings)
+{
+ if (settings->ticdup <= 0)
+ return false;
+
+ if (settings->extratics < 0)
+ return false;
+
+ if (settings->deathmatch < 0 || settings->deathmatch > 2)
+ return false;
+
+ if (settings->skill < sk_noitems || settings->skill > sk_nightmare)
+ return false;
+
+ if (settings->gameversion < exe_doom_1_9 || settings->gameversion > exe_final)
+ return false;
+
+ if (mode == shareware || mode == retail || mode == registered)
+ {
+ if (settings->map < 1 || settings->map > 9)
+ return false;
+ }
+ else
+ {
+ if (settings->map < 1 || settings->map > 32)
+ return false;
+ }
+
+ if (mode == shareware)
+ {
+ if (settings->episode != 1)
+ return false;
+ }
+ else if (mode == registered)
+ {
+ if (settings->episode < 1 || settings->episode > 3)
+ return false;
+ }
+ else if (mode == retail)
+ {
+ if (settings->episode < 1 || settings->episode > 4)
+ return false;
+ }
+
+ return true;
+}
--- a/src/net_common.h
+++ b/src/net_common.h
@@ -1,7 +1,7 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
-// $Id: net_common.h 412 2006-03-07 18:24:12Z fraggle $
+// $Id: net_common.h 461 2006-04-06 17:53:43Z fraggle $
//
// Copyright(C) 2005 Simon Howard
//
@@ -134,6 +134,10 @@
void NET_SafePuts(char *msg);
unsigned int NET_ExpandTicNum(unsigned int relative, unsigned int b);
+
+boolean NET_ValidGameMode(GameMode_t mode, GameMission_t mission);
+boolean NET_ValidGameSettings(GameMode_t mode, GameMission_t mission,
+ net_gamesettings_t *settings);
#endif /* #ifndef NET_COMMON_H */
--- a/src/net_server.c
+++ b/src/net_server.c
@@ -1,7 +1,7 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
-// $Id: net_server.c 460 2006-04-01 20:16:43Z fraggle $
+// $Id: net_server.c 461 2006-04-06 17:53:43Z fraggle $
//
// Copyright(C) 2005 Simon Howard
//
@@ -544,6 +544,21 @@
return;
}
+ // Check the client version is the same as the server
+ //
+ client_version = NET_ReadString(packet);
+
+ if (client_version == NULL)
+ {
+ return;
+ }
+
+ if (strcmp(client_version, PACKAGE_STRING) != 0)
+ {
+ NET_SV_SendReject(addr, "Different versions cannot play a network game!");
+ return;
+ }
+
// read the game mode and mission
if (!NET_ReadInt16(packet, &cl_gamemode)
@@ -553,6 +568,11 @@
return;
}
+ if (!NET_ValidGameMode(cl_gamemode, cl_gamemission))
+ {
+ return;
+ }
+
// read the player's name
player_name = NET_ReadString(packet);
@@ -561,13 +581,6 @@
{
return;
}
-
- client_version = NET_ReadString(packet);
-
- if (client_version == NULL)
- {
- return;
- }
// received a valid SYN
@@ -576,6 +589,7 @@
if (server_state != SERVER_WAITING_START)
{
NET_SV_SendReject(addr, "Server is not currently accepting connections");
+ return;
}
// allocate a client slot if there isn't one already
@@ -626,12 +640,6 @@
return;
}
- if (strcmp(client_version, PACKAGE_STRING) != 0)
- {
- NET_SV_SendReject(addr, "Different versions cannot play a network game!");
- return;
- }
-
// TODO: Add server option to allow rejecting clients which
// set lowres_turn. This is potentially desirable as the
// presence of such clients affects turning resolution.
@@ -689,6 +697,13 @@
return;
}
+ // Check the game settings are valid
+
+ if (!NET_ValidGameSettings(sv_gamemode, sv_gamemission, &settings))
+ {
+ return;
+ }
+
if (server_state != SERVER_WAITING_START)
{
// Can only start a game if we are in the waiting start state.
@@ -1003,8 +1018,9 @@
static void NET_SV_ParseResendRequest(net_packet_t *packet, net_client_t *client)
{
- static unsigned int start;
- static unsigned int num_tics;
+ unsigned int start, last;
+ unsigned int num_tics;
+ int i;
// Read the starting tic and number of tics
@@ -1016,9 +1032,30 @@
//printf("SV: %p: resend %i-%i\n", client, start, start+num_tics-1);
+ // Check we have all the requested tics
+
+ last = start + num_tics - 1;
+
+ for (i=start; i<=last; ++i)
+ {
+ net_full_ticcmd_t *cmd;
+
+ cmd = &client->sendqueue[i % BACKUPTICS];
+
+ if (i != cmd->seq)
+ {
+ // We do not have the requested tic (any more)
+ // This is pretty fatal. We could disconnect the client,
+ // but then again this could be a spoofed packet. Just
+ // ignore it.
+
+ return;
+ }
+ }
+
// Resend those tics
- NET_SV_SendTics(client, start, start + num_tics - 1);
+ NET_SV_SendTics(client, start, last);
}