You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
4.5 KiB
179 lines
4.5 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
// |
|
//=============================================================================// |
|
|
|
|
|
#if defined(_WIN32) && !defined(_X360) |
|
#include <winsock.h> |
|
#elif POSIX |
|
#include <sys/socket.h> |
|
#include <netinet/in.h> |
|
#elif !defined(_X360) |
|
#error "define socket.h" |
|
#endif |
|
#include "host.h" |
|
#include "blockingudpsocket.h" |
|
#include "cserserverprotocol_engine.h" |
|
#include "KeyValues.h" |
|
#include "bitbuf.h" |
|
#include "mathlib/IceKey.H" |
|
#include "net.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
static int CountFields( KeyValues *fields ) |
|
{ |
|
int c = 0; |
|
KeyValues *kv = fields->GetFirstSubKey(); |
|
while ( kv ) |
|
{ |
|
c++; |
|
kv = kv->GetNextKey(); |
|
} |
|
return c; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: encrypts an 8-byte sequence |
|
//----------------------------------------------------------------------------- |
|
static inline void Encrypt8ByteSequence( IceKey& cipher, const unsigned char *plainText, unsigned char *cipherText) |
|
{ |
|
cipher.encrypt(plainText, cipherText); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
static void EncryptBuffer( IceKey& cipher, unsigned char *bufData, uint bufferSize) |
|
{ |
|
unsigned char *cipherText = bufData; |
|
unsigned char *plainText = bufData; |
|
uint bytesEncrypted = 0; |
|
|
|
while (bytesEncrypted < bufferSize) |
|
{ |
|
// encrypt 8 byte section |
|
Encrypt8ByteSequence( cipher, plainText, cipherText); |
|
bytesEncrypted += 8; |
|
cipherText += 8; |
|
plainText += 8; |
|
} |
|
} |
|
|
|
static void BuildUploadDataMessage( bf_write& buf, char const *tablename, KeyValues *fields ) |
|
{ |
|
bf_write encrypted; |
|
ALIGN4 byte encrypted_data[ 2048 ] ALIGN4_POST; |
|
|
|
buf.WriteByte( C2M_UPLOADDATA ); |
|
buf.WriteByte( '\n' ); |
|
buf.WriteByte( C2M_UPLOADDATA_PROTOCOL_VERSION ); |
|
|
|
// encryption object |
|
IceKey cipher(1); /* medium encryption level */ |
|
unsigned char ucEncryptionKey[8] = { 54, 175, 165, 5, 76, 251, 29, 113 }; |
|
cipher.set( ucEncryptionKey ); |
|
|
|
encrypted.StartWriting( encrypted_data, sizeof( encrypted_data ) ); |
|
|
|
byte corruption_identifier = 0x01; |
|
|
|
encrypted.WriteByte( corruption_identifier ); |
|
|
|
// Data version protocol |
|
encrypted.WriteByte( C2M_UPLOADDATA_DATA_VERSION ); |
|
|
|
encrypted.WriteString( tablename ); |
|
|
|
int fieldCount = CountFields( fields ); |
|
|
|
if ( fieldCount > 255 ) |
|
{ |
|
Host_Error( "Too many fields in uploaddata (%i max = 255)\n", fieldCount ); |
|
} |
|
|
|
encrypted.WriteByte( (byte)fieldCount ); |
|
|
|
KeyValues *kv = fields->GetFirstSubKey(); |
|
while ( kv ) |
|
{ |
|
encrypted.WriteString( kv->GetName() ); |
|
encrypted.WriteString( kv->GetString() ); |
|
|
|
kv = kv->GetNextKey(); |
|
} |
|
|
|
// Round to multiple of 8 for encrypted |
|
while ( encrypted.GetNumBytesWritten() % 8 ) |
|
{ |
|
encrypted.WriteByte( 0 ); |
|
} |
|
|
|
EncryptBuffer( cipher, (unsigned char *)encrypted.GetData(), encrypted.GetNumBytesWritten() ); |
|
|
|
buf.WriteShort( (int)encrypted.GetNumBytesWritten() ); |
|
buf.WriteBytes( (unsigned char *)encrypted.GetData(), encrypted.GetNumBytesWritten() ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *cserIP - |
|
// *tablename - |
|
// *fields - |
|
// Output : Returns true on success, false on failure. |
|
//----------------------------------------------------------------------------- |
|
bool UploadData( char const *cserIP, char const *tablename, KeyValues *fields ) |
|
{ |
|
#ifndef _XBOX |
|
bf_write buf; |
|
ALIGN4 byte data[ 2048 ] ALIGN4_POST; |
|
|
|
buf.StartWriting( data, sizeof( data ) ); |
|
|
|
BuildUploadDataMessage( buf, tablename, fields ); |
|
|
|
netadr_t cseradr; |
|
|
|
if ( NET_StringToAdr( cserIP, &cseradr ) ) |
|
{ |
|
CBlockingUDPSocket *socket = new CBlockingUDPSocket(); |
|
if ( socket ) |
|
{ |
|
struct sockaddr_in sa; |
|
cseradr.ToSockadr( (struct sockaddr *)&sa ); |
|
|
|
// Don't bother waiting for response here |
|
socket->SendSocketMessage( sa, (const byte *)buf.GetData(), buf.GetNumBytesWritten() ); |
|
delete socket; |
|
|
|
return true; |
|
} |
|
} |
|
|
|
return false; |
|
#else |
|
return true; |
|
#endif |
|
} |
|
|
|
/* |
|
CON_COMMAND( datatest, "" ) |
|
{ |
|
KeyValues *kv = new KeyValues( "data" ); |
|
kv->SetString( "IDHash", "abcdefg" ); |
|
kv->SetString( "Time", "DATETIME" ); |
|
kv->SetString( "DXDeviceID", "1001" ); |
|
kv->SetString( "DXVendorID", "1001" ); |
|
kv->SetString( "Framerate", "999" ); |
|
kv->SetString( "BuildNumber", va( "%i", build_number() ) ); |
|
|
|
bool bret = UploadData( "127.0.0.1:27013", "benchmark", kv ); |
|
|
|
kv->deleteThis(); |
|
} |
|
*/
|
|
|