Guest User

Dirty anti-DoS patch

a guest
Aug 21st, 2018
286
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 4.64 KB | None | 0 0
  1. diff --git src/engine/server/server.cpp src/engine/server/server.cpp
  2. index 6c459257..3dc03cb0 100644
  3. --- src/engine/server/server.cpp
  4. +++ src/engine/server/server.cpp
  5. @@ -1086,7 +1086,7 @@ void CServer::SendServerInfo(const NETADDR *pAddr, int Token)
  6.     {
  7.         if(m_aClients[i].m_State != CClient::STATE_EMPTY)
  8.         {
  9. -           if(GameServer()->IsClientPlayer(i))
  10. +           if(GameServer()->IsClientPlayer(i) && m_NetServer.IsClientOnline(i))
  11.                 PlayerCount++;
  12.  
  13.             ClientCount++;
  14. @@ -1126,7 +1126,7 @@ void CServer::SendServerInfo(const NETADDR *pAddr, int Token)
  15.             p.AddString(ClientClan(i), MAX_CLAN_LENGTH); // client clan
  16.             str_format(aBuf, sizeof(aBuf), "%d", m_aClients[i].m_Country); p.AddString(aBuf, 6); // client country
  17.             str_format(aBuf, sizeof(aBuf), "%d", m_aClients[i].m_Score); p.AddString(aBuf, 6); // client score
  18. -           str_format(aBuf, sizeof(aBuf), "%d", GameServer()->IsClientPlayer(i)?1:0); p.AddString(aBuf, 2); // is player?
  19. +           str_format(aBuf, sizeof(aBuf), "%d", (GameServer()->IsClientPlayer(i) && m_NetServer.IsClientOnline(i)) ? 1 : 0); p.AddString(aBuf, 2); // is player?
  20.         }
  21.     }
  22.  
  23. diff --git src/engine/shared/network.h src/engine/shared/network.h
  24. index b934563c..66a9219e 100644
  25. --- src/engine/shared/network.h
  26. +++ src/engine/shared/network.h
  27. @@ -264,6 +264,8 @@ class CNetServer
  28.     void *m_UserPtr;
  29.  
  30.     CNetRecvUnpacker m_RecvUnpacker;
  31. +  
  32. +   int FindReusableSlot();
  33.  
  34.  public:
  35.     int SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser);
  36. @@ -272,6 +274,9 @@ public:
  37.     bool Open(NETADDR BindAddr, class CNetBan *pNetBan, int MaxClients, int MaxClientsPerIP, int Flags);
  38.     int Close();
  39.  
  40. +   bool IsClientOnline(int ClientID)
  41. +       { return m_aSlots[ClientID].m_Connection.State() == NET_CONNSTATE_ONLINE; }
  42. +
  43.     //
  44.     int Recv(CNetChunk *pChunk);
  45.     int Send(CNetChunk *pChunk);
  46. diff --git src/engine/shared/network_server.cpp src/engine/shared/network_server.cpp
  47. index 537048cb..d9ec177d 100644
  48. --- src/engine/shared/network_server.cpp
  49. +++ src/engine/shared/network_server.cpp
  50. @@ -1,7 +1,11 @@
  51.  /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
  52.  /* If you are missing that file, acquire a complete release at teeworlds.com.                */
  53. +#include <vector>
  54. +#include <cstdlib>
  55. +
  56.  #include <base/system.h>
  57.  
  58. +
  59.  #include <engine/console.h>
  60.  
  61.  #include "netban.h"
  62. @@ -88,9 +92,45 @@ int CNetServer::Update()
  63.     return 0;
  64.  }
  65.  
  66. +#include <iostream>
  67. +
  68. +int CNetServer::FindReusableSlot()
  69. +{
  70. +  
  71. +   // Slots that are completely empty
  72. +   std::vector<int> Empty;
  73. +   // Slots that can be reused if necessary
  74. +   std::vector<int> Reusable;
  75. +  
  76. +   for (int i = 0; i < MaxClients(); ++i)
  77. +   {
  78. +       CNetConnection& Con = m_aSlots[i].m_Connection;
  79. +       std::cerr << Con.State();
  80. +       if (Con.State() == NET_CONNSTATE_OFFLINE)
  81. +       {
  82. +           Empty.push_back(i);
  83. +       }
  84. +       else if (
  85. +           Con.State() == NET_CONNSTATE_ERROR
  86. +           || Con.State() == NET_CONNSTATE_CONNECT
  87. +           || Con.State() == NET_CONNSTATE_PENDING
  88. +       ) {
  89. +           Reusable.push_back(i);
  90. +       }
  91. +   }
  92. +   std::cerr << std::endl;
  93. +  
  94. +   if (!Empty.empty())
  95. +       return Empty[0];
  96. +   if (!Reusable.empty())
  97. +       return Reusable[std::rand() % Reusable.size()];
  98. +   return -1;
  99. +}
  100. +
  101.  /*
  102.     TODO: chopp up this function into smaller working parts
  103.  */
  104. +
  105.  int CNetServer::Recv(CNetChunk *pChunk)
  106.  {
  107.     while(1)
  108. @@ -171,24 +211,29 @@ int CNetServer::Recv(CNetChunk *pChunk)
  109.                                 }
  110.                             }
  111.                         }
  112. -
  113. -                       for(int i = 0; i < MaxClients(); i++)
  114. -                       {
  115. -                           if(m_aSlots[i].m_Connection.State() == NET_CONNSTATE_OFFLINE)
  116. -                           {
  117. -                               Found = true;
  118. -                               m_aSlots[i].m_Connection.Feed(&m_RecvUnpacker.m_Data, &Addr);
  119. -                               if(m_pfnNewClient)
  120. -                                   m_pfnNewClient(i, m_UserPtr);
  121. -                               break;
  122. -                           }
  123. +                      
  124. +                       int Slot = FindReusableSlot();
  125. +                       const char FullMsg[] = "This server is full";
  126. +                      
  127. +                       if(Slot < 0)
  128. +                       {  
  129. +                           std::cerr << "No slot found!" << std::endl;
  130. +                           CNetBase::SendControlMsg(
  131. +                               m_Socket, &Addr, 0, NET_CTRLMSG_CLOSE,
  132. +                               FullMsg, sizeof(FullMsg)
  133. +                           );
  134.                         }
  135. -
  136. -                       if(!Found)
  137. +                       else
  138.                         {
  139. -                           const char FullMsg[] = "This server is full";
  140. -                           CNetBase::SendControlMsg(m_Socket, &Addr, 0, NET_CTRLMSG_CLOSE, FullMsg, sizeof(FullMsg));
  141. +                           std::cerr << "Overwriting slot!" << std::endl;
  142. +                           if (m_aSlots[Slot].m_Connection.State() != NET_CONNSTATE_OFFLINE)
  143. +                               Drop(Slot, FullMsg);
  144. +                                                      
  145. +                           m_aSlots[Slot].m_Connection.Feed(&m_RecvUnpacker.m_Data, &Addr);
  146. +                           if (m_pfnNewClient)
  147. +                               m_pfnNewClient(Slot, m_UserPtr);
  148.                         }
  149. +                      
  150.                     }
  151.                 }
  152.                 else
Add Comment
Please, Sign In to add comment