- Harden the client and server protocol against UDP spoofing attacks. This will defend ioquake3 against http://aluigi.altervista.org/papers/q3noclient.txt (#3041)
- Retains full compatibility to the old but unsecure protocol between clients and servers - Harden the connection process against DoS attacks, possibly connected to UDP spoofing
This commit is contained in:
parent
06d12f6085
commit
a5580d8974
11 changed files with 296 additions and 75 deletions
|
@ -83,7 +83,12 @@ Netchan_Setup
|
|||
called to open a channel to a remote system
|
||||
==============
|
||||
*/
|
||||
void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport ) {
|
||||
void Netchan_Setup(netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, int challenge
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
, qboolean compat
|
||||
#endif
|
||||
)
|
||||
{
|
||||
Com_Memset (chan, 0, sizeof(*chan));
|
||||
|
||||
chan->sock = sock;
|
||||
|
@ -91,6 +96,10 @@ void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport ) {
|
|||
chan->qport = qport;
|
||||
chan->incomingSequence = 0;
|
||||
chan->outgoingSequence = 1;
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
chan->compat = compat;
|
||||
chan->challenge = challenge;
|
||||
#endif
|
||||
}
|
||||
|
||||
// TTimo: unused, commenting out to make gcc happy
|
||||
|
@ -190,17 +199,24 @@ void Netchan_TransmitNextFragment( netchan_t *chan ) {
|
|||
msg_t send;
|
||||
byte send_buf[MAX_PACKETLEN];
|
||||
int fragmentLength;
|
||||
int outgoingSequence;
|
||||
|
||||
// write the packet header
|
||||
MSG_InitOOB (&send, send_buf, sizeof(send_buf)); // <-- only do the oob here
|
||||
|
||||
MSG_WriteLong( &send, chan->outgoingSequence | FRAGMENT_BIT );
|
||||
outgoingSequence = chan->outgoingSequence | FRAGMENT_BIT;
|
||||
MSG_WriteLong(&send, outgoingSequence);
|
||||
|
||||
// send the qport if we are a client
|
||||
if ( chan->sock == NS_CLIENT ) {
|
||||
MSG_WriteShort( &send, qport->integer );
|
||||
}
|
||||
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
if(!chan->compat)
|
||||
#endif
|
||||
MSG_WriteLong(&send, NETCHAN_GENCHECKSUM(chan->challenge, chan->outgoingSequence));
|
||||
|
||||
// copy the reliable message to the packet first
|
||||
fragmentLength = FRAGMENT_SIZE;
|
||||
if ( chan->unsentFragmentStart + fragmentLength > chan->unsentLength ) {
|
||||
|
@ -268,12 +284,17 @@ void Netchan_Transmit( netchan_t *chan, int length, const byte *data ) {
|
|||
MSG_InitOOB (&send, send_buf, sizeof(send_buf));
|
||||
|
||||
MSG_WriteLong( &send, chan->outgoingSequence );
|
||||
chan->outgoingSequence++;
|
||||
|
||||
// send the qport if we are a client
|
||||
if ( chan->sock == NS_CLIENT ) {
|
||||
MSG_WriteShort( &send, qport->integer );
|
||||
}
|
||||
if(chan->sock == NS_CLIENT)
|
||||
MSG_WriteShort(&send, qport->integer);
|
||||
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
if(!chan->compat)
|
||||
#endif
|
||||
MSG_WriteLong(&send, NETCHAN_GENCHECKSUM(chan->challenge, chan->outgoingSequence));
|
||||
|
||||
chan->outgoingSequence++;
|
||||
|
||||
MSG_WriteData( &send, data, length );
|
||||
|
||||
|
@ -327,6 +348,17 @@ qboolean Netchan_Process( netchan_t *chan, msg_t *msg ) {
|
|||
qport = MSG_ReadShort( msg );
|
||||
}
|
||||
|
||||
#ifdef PROTOCOL_SUPPORT_OLD
|
||||
if(!chan->compat)
|
||||
#endif
|
||||
{
|
||||
int checksum = MSG_ReadLong(msg);
|
||||
|
||||
// UDP spoofing protection
|
||||
if(NETCHAN_GENCHECKSUM(chan->challenge, sequence) != checksum)
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// read the fragment information
|
||||
if ( fragmented ) {
|
||||
fragmentStart = MSG_ReadShort( msg );
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue