~swag/armagetronad/0.2.9-sty+ct+ap-fork

« back to all changes in this revision

Viewing changes to src/network/nServerInfo.cpp

  • Committer: Voodoo
  • Date: 2011-07-28 18:46:18 UTC
  • mfrom: (563.24.161 merge)
  • Revision ID: voodoo-20110728184618-0djbrm75ftd07c4v
merge -r 1285..1297 lp:armagetronad/0.2.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
693
693
static nDescriptor BigServerMasterDescriptor(54,nServerInfo::GetBigServerInfoMaster,"big_server_master", true);
694
694
 
695
695
// request small server information from master server/broadcast
696
 
static nDescriptor RequestSmallServerInfoDescriptor(52,nServerInfo::GiveSmallServerInfo,"small_request", true);
 
696
nDescriptor RequestSmallServerInfoDescriptor(52,nServerInfo::GiveSmallServerInfo,"small_request", true);
697
697
 
698
698
// request big server information from master server/broadcast
699
 
static nDescriptor RequestBigServerInfoDescriptor(53,nServerInfo::GiveBigServerInfo,"big_request", true);
 
699
nDescriptor RequestBigServerInfoDescriptor(53,nServerInfo::GiveBigServerInfo,"big_request", true);
700
700
static nDescriptor RequestBigServerInfoMasterDescriptor(55,nServerInfo::GiveBigServerInfoMaster,"big_request_master", true);
701
701
 
702
702
// used to transfer the rest of the server info (name, number of players, etc)
883
883
    double lastTime_[MAX];   // log of the last times the server was pinged by this client
884
884
    int lastTimeIndex_;      // the current index in the array
885
885
    bool warned_;            // flag to avoid warning spam in the log file
 
886
    REAL timeFactor_;        // locked time factor
886
887
 
887
888
    tString GetIP()
888
889
    {
939
940
    // determines whether this client should be considered flooding
940
941
    bool FloodProtection( REAL timeFactor )
941
942
    {
 
943
        if( warned_ && timeFactor < timeFactor_ )
 
944
        {
 
945
            // restore time factor
 
946
            timeFactor = timeFactor_;
 
947
        }
 
948
        else
 
949
        {
 
950
            // store passed time factor for next time
 
951
            timeFactor_ = timeFactor;
 
952
        }
 
953
 
 
954
 
 
955
 
942
956
        int i;
943
957
        double now = tSysTimeFloat();
944
958
 
945
959
        bool protect = false;
946
960
        REAL diff = 0;
947
961
        int count = 0;
 
962
        REAL tolerance = 0;
 
963
        REAL minRelDiff = 10;
948
964
 
949
965
        // go through the different levels
950
 
        for ( i = sn_minPingCount-1; i >= 0; --i )
 
966
        int lowest = 0;
 
967
 
 
968
        // only check 10 and 20 ping limit for the default timefactor
 
969
        if( timeFactor < 1 && sn_minPingTimes[sn_minPingCount-1] > 0 )
 
970
        {
 
971
            // lowest = 2;
 
972
        }
 
973
 
 
974
        for ( i = sn_minPingCount-1; i >= lowest; --i )
951
975
        {
952
976
            // this many pings should be tracked
953
977
            count = sn_minPingCounts[i];
954
978
            diff = now - lastTime_[(lastTimeIndex_ + MAX - count) % MAX];
955
 
            REAL tolerance = sn_minPingTimes[i]*timeFactor;
956
 
            if ( tolerance > 0 && diff < tolerance )
 
979
            tolerance = sn_minPingTimes[i]*timeFactor;
 
980
            if ( tolerance > 0 )
957
981
            {
958
 
                protect = true;
959
 
                break;
 
982
                if( tolerance*minRelDiff > diff )
 
983
                {
 
984
                    minRelDiff = diff/tolerance;
 
985
                }
 
986
 
 
987
                if( diff < tolerance )
 
988
                {
 
989
                    protect = true;
 
990
                    break;
 
991
                }
960
992
            }
961
993
        }
962
994
 
972
1004
        }
973
1005
 
974
1006
        // reset warning flag
975
 
        if ( warned_ && now - lastTime_[(lastTimeIndex_ + MAX-2 ) % MAX] > sn_minPingTimes[ sn_minPingCount-1 ] )
 
1007
        if ( warned_ && minRelDiff > 4 )
976
1008
        {
977
1009
            con << "Flood protection ban of " << GetIP() << " removed.\n";
978
1010
            warned_ = false;
1017
1049
static REAL sn_minPingTimeGlobalFactor = 0.1;
1018
1050
static tSettingItem< REAL > sn_minPingTimeGlobal( "PING_FLOOD_GLOBAL", sn_minPingTimeGlobalFactor );
1019
1051
 
 
1052
// checks for global ping flood events
 
1053
static bool GlobalPingFloodProtection()
 
1054
{
 
1055
    static nMachine server;
 
1056
 
 
1057
    return sn_minPingTimeGlobalFactor > 0 && FloodProtection( server, sn_minPingTimeGlobalFactor );
 
1058
}
 
1059
 
1020
1060
// determines wheter the message comes from a flood attack; if so, reject it (return true)
1021
1061
bool FloodProtection( nMessage const & m )
1022
1062
{
1023
 
    // get the machine infos
1024
 
    nMachine & server = nMachine::GetMachine( 0 );
1025
 
    nMachine & peer   = nMachine::GetMachine( m.SenderID() );
1026
 
 
1027
1063
    // only accept one ping per packet
1028
1064
    if ( !sn_firstInPacket )
1029
1065
    {
 
1066
        // get the machine infos
 
1067
        nMachine & peer   = nMachine::GetMachine( m.SenderID() );
 
1068
 
1030
1069
        GetQueryMessageStats( peer ).Block();
1031
1070
 
1032
1071
        return true;
1038
1077
    if ( sn_minPingTimes[sn_minPingCount - 1] <= 0 )
1039
1078
        return false;
1040
1079
 
1041
 
    // and delegate
1042
 
    return FloodProtection( peer ) || ( sn_minPingTimeGlobalFactor > 0 && FloodProtection( server, sn_minPingTimeGlobalFactor ) );
 
1080
    // and delegate. Only do global check, the per-peer check has already been
 
1081
    // done earlier as the packet was received.
 
1082
    return GlobalPingFloodProtection();
1043
1083
}
1044
1084
 
1045
1085
void nServerInfo::GetSmallServerInfo(nMessage &m){
 
1086
    if ( !sn_IsMaster && sn_GetNetState() == nSERVER )
 
1087
        return;
 
1088
 
1046
1089
    nServerInfoBase baseInfo;
1047
1090
    baseInfo.NetRead( m );
1048
1091
 
1298
1341
 
1299
1342
void nServerInfo::GetBigServerInfo(nMessage &m)
1300
1343
{
 
1344
    if ( !sn_IsMaster && sn_GetNetState() == nSERVER )
 
1345
        return;
 
1346
 
1301
1347
    nServerInfo * server = GetBigServerInfoCommon( m );
1302
1348
 
1303
1349
    if (!server)
1360
1406
 
1361
1407
void nServerInfo::GetBigServerInfoMaster(nMessage &m)
1362
1408
{
1363
 
    if ( sn_GetNetState() == nSERVER && FloodProtection( m ) )
 
1409
    if ( sn_GetNetState() == nSERVER )
1364
1410
        return;
1365
1411
 
1366
1412
    nServerInfo *server = GetBigServerInfoCommon( m );
1373
1419
 
1374
1420
void nServerInfo::GiveBigServerInfoMaster(nMessage &m)
1375
1421
{
 
1422
    if ( !sn_IsMaster )
 
1423
        return;
 
1424
 
1376
1425
    if ( FloodProtection( m ) )
1377
1426
        return;
1378
1427
 
1379
 
    if ( !sn_IsMaster )
1380
 
        return;
1381
 
 
1382
1428
    // read info of desired server from message
1383
1429
    nServerInfoBase baseInfo;
1384
1430
    baseInfo.NetRead( m );
2264
2310
                    sn_Timeout[i] = tSysTimeFloat() + .2f;
2265
2311
            }
2266
2312
 
2267
 
            // defend against DOS attacks: Kill idle clients
 
2313
            // defend against DoS attacks: Kill idle clients
2268
2314
            if(sn_Timeout[i] < tSysTimeFloat())
2269
 
                sn_DisconnectUser(i, "$network_kill_timeout");
2270
 
 
2271
 
            if (!sn_Requested[i] && sn_Timeout[i] < tSysTimeFloat() + 60.0f)
2272
 
                sn_DisconnectUser(i, "$network_kill_timeout");
2273
 
 
 
2315
            {
 
2316
                sn_DisconnectUser(i, "$network_kill_servercomplete");
 
2317
                continue;
 
2318
            }
 
2319
            else if (!sn_Requested[i] && sn_Timeout[i] < tSysTimeFloat() + 60.0f)
 
2320
            {
 
2321
                sn_DisconnectUser(i, "$network_kill_timeout");
 
2322
                continue;
 
2323
            }
2274
2324
        }
2275
2325
 
2276
2326
        if (sn_Transmitting[i] && sn_MessagesPending(i) < 3)