629
630
// *************************************************************
633
static int sn_GetRandomOffset()
635
static tReproducibleRandomizer rand;
636
return rand.Get(0x7fffffff);
640
static int sn_SynTimestamp()
642
static int offset = sn_GetRandomOffset();
644
return offset + tSysTimeFloat()/16;
647
// a cookie consists of two shorts, each transmitted as MessageID
648
// of two consecutive fake login accept packets. They'll be sent back
649
// to the server inside ONE ack message by a real, non-spoofed client.
652
unsigned short first;
653
unsigned short second;
655
nCookie(): first(0), second(0){}
658
static void sn_SynGenerateCookie(int stamp, nAddress const & sender, nCookie & ret)
660
// just some random modulus.
661
static const unsigned int modulo = 0x7f71fa35;
664
// calculate just some random checksum. Doesn't need to be any good,
665
// we can change it any time should someone be able to predict it.
666
int checksum = stamp;
667
int mul = ( stamp & 0x7fff ) + 3;
668
sockaddr const * sock = sender;
669
for(int i = sender.GetAddressLength()-1; i >= 0; --i )
672
checksum += (checksum >> 16) * mul;
673
checksum += reinterpret_cast< char const * >( sock )[i];
677
// message IDs must not be 0, so we need to add a 1 offset and can't
678
// do the usual &0xffff / >>16 split.
679
ret.first = ( checksum % 0xfffe ) + 1;
680
ret.second = (checksum + 1 - ret.first)/0xfffe + 1;
683
static void sn_SynGenerateCookie(int stamp, nMessage const &m, nCookie & ret)
685
sn_SynGenerateCookie( stamp, peers[m.SenderID()], ret );
689
// *************************************************************
632
692
void ack_handler(nMessage &m){
693
if( m.SenderID() == MAXCLIENTS+1 )
695
// check for syn cookie response
701
m.Read(cookie.first);
706
m.Read(cookie.second);
712
int stamp = sn_SynTimestamp();
713
for(int offset=0; offset >= -1; --offset)
716
sn_SynGenerateCookie( stamp+offset , m, correct );
717
if( correct.first == cookie.first && correct.second == cookie.second )
719
nMachine::GetMachine( m.SenderID() ).Validate();
634
728
sn_Connections[m.SenderID()].AckReceived();
636
730
unsigned short ack;
1677
1775
// the network stuff planned to send:
1678
1776
tHeap<planned_send> send_queue[MAXCLIENTS+2];
1778
// defined in nServerInfo.cpp
1779
extern bool FloodProtection( nMachine & machine, REAL timeFactor=1.0 );
1781
// time factor for incoming connections, lower makes turtle mode kick in later
1782
static REAL sn_minConnectionTimeGlobalFactor = 0.1;
1783
static tSettingItem< REAL > sn_minPingTimeGlobal( "CONNECTION_FLOOD_SENSITIVITY", sn_minConnectionTimeGlobalFactor );
1785
// enforce turtle mode
1786
static bool sn_forceTurtleMode = false;
1787
static tSettingItem< bool > sn_forceTurtleModeConf( "FORCE_TURTLE_MODE", sn_forceTurtleMode );
1789
// keep recording even in turtle mode
1790
static bool sn_recordTurtleMode = false;
1791
static tSettingItem< bool > sn_recordTurtleModeConf( "RECORD_TURTLE_MODE", sn_recordTurtleMode );
1793
// enforce the anti-spoof login part of turtle mode at all times
1794
static bool sn_synCookie = false;
1795
static tSettingItem< bool > sn_synCookieConf( "ANTI_SPOOF", sn_synCookie );
1798
// number of packets from unknown sources to process each call to rec_peer
1799
static int sn_connectionLimit = 100;
1800
static tSettingItem< int > sn_connectionLimitConf( "CONNECTION_LIMIT", sn_connectionLimit );
1802
// turtle mode control
1803
class nTurtleControl
1805
REAL lastTurtleModeTime; // last time turtle mode was activated
1808
// true while we're turtling from a flood
1812
: lastTurtleModeTime(-700)
1813
, setThisFrame(false)
1818
operator bool() const
1823
// activates turtle mode. It will persist for at least 60 seconds.
1824
void SetTurtleMode()
1831
sn_ConsoleOut( tOutput("$turtle_mode_activated") );
1834
if( !sn_recordTurtleMode && tRecorder::IsRecording() )
1836
tRecorder::StopRecording();
1841
setThisFrame = true;
1842
lastTurtleModeTime = tSysTimeFloat();
1849
setThisFrame = false;
1850
if( lastTurtleModeTime + 60 < tSysTimeFloat() )
1852
if( turtleMode && !sn_forceTurtleMode )
1855
sn_ConsoleOut( tOutput("$turtle_mode_deactivated") );
1858
turtleMode = sn_forceTurtleMode;
1862
static nTurtleControl sn_turtleMode;
1864
// checks for global flood events
1865
static inline bool GlobalConnectionFloodProtection( REAL extraFactor = 1.0f )
1867
static nMachine server;
1869
if( sn_minConnectionTimeGlobalFactor > 0 && FloodProtection( server, sn_minConnectionTimeGlobalFactor*extraFactor ) )
1871
sn_turtleMode.SetTurtleMode();
1874
return sn_turtleMode;
1877
// checks for individual flood events
1878
bool IndividualConnectionFloodProtection( nMachine * machine, int peer, REAL extraFactor = 1.0f )
1880
// IP is not spoofed or there is no
1881
// current spoof heavy attack. Really look up the machine.
1884
machine = &nMachine::GetMachine( peer );
1887
// check individual flood protection (be lenient in turtle mode, login responses may have trouble getting through an attack)
1888
return FloodProtection( *machine, ( sn_turtleMode ? .2 : 1 ) * extraFactor );
1891
// report login failure. Or don't if we're flooded.
1892
int sn_ReportFailure(nMessage &m, char const * reason)
1894
if( !sn_turtleMode )
1896
sn_DisconnectUser(m.SenderID(), reason);
1680
1902
int login_handler( nMessage &m, unsigned short rate ){
1681
1903
nCurrentSenderID senderID;
1725
1947
con << tOutput( "$network_ban", machine.GetIP() , int(banned/60), reason.Len() > 1 ? reason : tOutput( "$network_ban_noreason" ) );
1727
1949
sn_DisconnectUser(m.SenderID(), tOutput( "$network_kill_banned", int(banned/60), reason ) );
1730
1954
// ignore multiple logins
1731
1955
if( CountSameConnection( m.SenderID() ) > 0 )
1734
// ignore login floods
1735
if ( FloodProtection( m ) )
1738
1958
bool success=false;
1740
1960
int new_id = -1;
1746
1966
nVersion mergedVersion;
1747
1967
if ( !mergedVersion.Merge( version, sn_CurrentVersion() ) )
1749
sn_DisconnectUser(m.SenderID(), "$network_kill_incompatible");
1969
return sn_ReportFailure(m, "$network_kill_incompatible");
1752
1972
// expire 0.2.8 test versions, they have a security flaw
1753
1973
if ( sn_lockOut028tTest && version.Max() >= 5 && version.Max() <= 10 )
1755
sn_DisconnectUser(m.SenderID(), "0.2.8_beta and 0.2.8.0_rc versions have a dangerous security flaw and are obsoleted, please upgrade to 0.2.8.2.1.");
1975
return sn_ReportFailure(m, "0.2.8_beta and 0.2.8.0_rc versions have a dangerous security flaw and are obsoleted, please upgrade to 0.2.8.2.1.");
1758
1978
if (m.SenderID()!=MAXCLIENTS+1)
2288
2517
tERR_WARN( "Oversized network packet received. Read buffer has been enlargened to catch it the next time.");
2290
// no use in processing the truncated packet. Some messages may get lost,
2291
// but that's better than the inevitable network error and connection
2292
// termination that expects us if we go on.
2297
// terminate the connection
2298
sn_DisconnectUser( peer, "$network_kill_error" );
2523
// packet WAAAAY too large.
2524
static float totalFatsoes = 10; // number of oversized packages checked
2525
static float clientFatsoes = 10; // number of oversized pacakges that could be attributed to clients
2526
static float bother = 5; // counter that determines whether we bother to check.
2527
bother+=clientFatsoes;
2529
// what follows is work, so we only do it if it payed off in the past
2530
// if this block is entered not at all by error, no biggie. The clients
2531
// will time out eventually.
2532
bool success = false;
2533
if(bother>totalFatsoes)
2535
bother-=totalFatsoes;
2537
// increase total stat
2540
// If it's from a connected client,
2541
// terminate the connection. If not, it's an attack and
2542
// we should rather ignore it.
2543
for( int id=MAXCLIENTS; id > 0; --id )
2545
if (sn_Connections[id].socket && peers[id] == addrFrom)
2547
sn_DisconnectUser( id, "$network_kill_error" );
2552
// count the successfully removed client
2558
// scale down the stats
2559
const float factor=.99;
2560
totalFatsoes*=factor;
2561
clientFatsoes*=factor;
2567
// check for global and local spam (just for reporting, the packet
2568
// is going to get blocked either way)
2569
REAL severity = len*.5/MAX_MESS_LEN;
2570
if( !GlobalConnectionFloodProtection( severity ) )
2572
peers[ MAXCLIENTS+1] = addrFrom;
2573
IndividualConnectionFloodProtection( NULL, MAXCLIENTS+1, severity );
2578
// no use in processing the truncated packet. Some messages may get lost,
2579
// but that's better than the inevitable network error and connection
2580
// termination that expects us if we go on.
2302
2584
unsigned short *b=buff;
2615
// check for communication from last partner
2616
if( claim_id > 0 && 0 == nAddress::Compare( addrFrom, lastPeers[claim_id] ) )
2618
// ignore. The peer think it's still a client, but it's wrong.
2619
// new login packets, pings etc. all come with claim_id == 0.
2330
2623
// assume it's a new connection
2331
2624
id = MAXCLIENTS+1;
2332
2625
peers[ MAXCLIENTS+1 ] = addrFrom;
2333
2626
sn_Connections[ MAXCLIENTS+1 ].socket = sn_Connections[peer].socket;
2628
// #define NO_GLOBAL_FLOODPROTECTION
2629
#ifndef NO_GLOBAL_FLOODPROTECTION
2630
// flood check for pings, logins and other potential nasties; as early as possible
2631
if( sn_turtleMode && count > sn_connectionLimit*10 )
2636
nMachine * machine = nMachine::PeekMachine( peer );
2638
if( sn_GetNetState() == nSERVER )
2640
// check whether we're currently getting flooded
2641
GlobalConnectionFloodProtection();
2643
if( sn_turtleMode || sn_synCookie )
2645
// peek at descriptor
2646
unsigned short descriptor = ntohs(*b);
2648
// do some extra checks
2649
if( descriptor == s_Acknowledge.ID() )
2651
// this must be the cookie response triggered by the code below.
2652
// allow it, but be careful to only read the first message.
2653
onlyReadFirstMessage = true;
2655
else if( descriptor == login_accept.ID() )
2657
// Hah. Nice trick. Won't work, though.
2659
else if( !sn_turtleMode &&
2660
( descriptor == RequestSmallServerInfoDescriptor.ID() ||
2661
descriptor == RequestBigServerInfoDescriptor.ID() ) )
2663
// Pings. Let them in unless we're under real attack.
2664
onlyReadFirstMessage = true;
2666
else if( !machine || !machine->IsValidated() )
2668
if( count > sn_connectionLimit )
2673
// send fake login accept messages; the ack response whitelists the IP
2675
sn_SynGenerateCookie( sn_SynTimestamp(), peers[peer], cookie );
2676
tJUST_CONTROLLED_PTR<nMessage> r = tNEW(nMessage)(login_accept);
2677
r->BendMessageID( cookie.first );
2678
r->SendImmediately(peer,false);
2679
r = tNEW(nMessage)(login_accept);
2680
r->BendMessageID( cookie.second );
2681
r->SendImmediately(peer,false);
2682
int idback = ::sn_myNetID;
2683
sn_myNetID = 1; // set a fake ID so the client doesn't consider the packet as a response from the server and messes up its ack data
2684
nMessage::SendCollected(peer);
2685
::sn_myNetID = idback;
2687
// and ignore for now
2692
// IP is not spoofed or there is no
2693
// current spoof heavy attack. Check closer.
2694
if( IndividualConnectionFloodProtection( machine, peer ) )
2336
2703
// if (peer!=id)
2337
2704
// con << "Changed incoming address.\n";
2338
2705
int lenleft = bend - b;
4138
4533
void nPingAverager::Timestep( REAL decay )
4140
snail_.Timestep( decay * .02 );
4141
slow_.Timestep ( decay * .2 );
4142
fast_.Timestep ( decay * 2 );
4535
if( snail_.GetWeight() > 100 )
4536
snail_.Timestep( decay * .02 );
4537
if( slow_.GetWeight() > 30 )
4538
slow_.Timestep ( decay * .2 );
4539
if( fast_.GetWeight() > 10 )
4540
fast_.Timestep ( decay * 2 );
4145
4543
// *******************************************************************************************
4289
4688
nMachinePTR & operator=(nMachinePTR const & other){ machine = other.machine; other.machine=0;return *this;}
4292
typedef std::map< tString, nMachinePTR > nMachineMap;
4691
typedef sockaddr nMachineKey;
4693
bool operator < ( nMachineKey const & a, nMachineKey const & b )
4695
return reinterpret_cast< sockaddr_in const & >( a ).sin_addr.s_addr < reinterpret_cast< sockaddr_in const & >( b ).sin_addr.s_addr;
4698
typedef std::map< nMachineKey, nMachinePTR > nMachineMap;
4293
4699
static nMachineMap & sn_GetMachineMap()
4295
4701
static nMachineMap map;
4705
static nMachine & sn_LookupMachine( nMachineKey const * address )
4707
// get map of all machines and look address up
4708
nMachineMap & map = sn_GetMachineMap();
4709
nMachine & ret = *map[ *address ].machine;
4710
if( ret.GetIP().Len() <= 2 )
4713
sockaddr * target = addr;
4715
ret.SetIP( addr.GetAddress() );
4720
static nMachine * sn_PeekMachine( nMachineKey const * address )
4722
// get map of all machines and look address up
4723
nMachineMap & map = sn_GetMachineMap();
4724
nMachineMap::const_iterator i = map.find( *address );
4725
if( i != map.end() )
4727
return (*i).second.machine;
4299
4735
static nMachine & sn_LookupMachine( tString const & address )
4301
// get map of all machines and look address up
4302
nMachineMap & map = sn_GetMachineMap();
4303
return map[ address ].machine->SetIP( address );
4738
addr.SetAddress( address );
4739
return sn_LookupMachine( addr );
4306
4742
// *******************************************************************************
4343
4779
static nMachine invalid;
4344
4780
return invalid;
4347
peers[ userID ].GetAddress( address );
4350
// add client ID so multiple connects from one machine are distinguished
4352
newIP << address << " " << userID;
4357
return sn_LookupMachine( address );
4784
return sn_LookupMachine( peers[userID] );
4787
// *******************************************************************************
4791
// *******************************************************************************
4793
//! @param userID the user ID to fetch the machine for
4794
//! @return the machine the user ID belongs to
4796
// *******************************************************************************
4798
nMachine * nMachine::PeekMachine( unsigned short userID )
4800
// hardcoding: the server itself
4801
if ( userID == 0 && sn_GetNetState() != nCLIENT )
4803
return &GetMachine( userID );
4806
tASSERT( userID <= MAXCLIENTS+1 );
4808
if( sn_GetNetState() != nSERVER )
4810
// invalid ID, return invalid machine (clients don't track machines)
4811
return &GetMachine( userID );
4815
tVERIFY( userID <= MAXCLIENTS+1 );
4816
if( !sn_Connections[userID].socket )
4818
// invalid ID, return invalid machine
4819
return &GetMachine( userID );
4823
return sn_PeekMachine( peers[userID] );
4360
4826
// safely delete iterator from map