connection-less msg packet without token-support
| 296 | |
| 297 | // connection-less msg packet without token-support |
| 298 | void CNetServer::OnPreConnMsg(NETADDR &Addr, CNetPacketConstruct &Packet) |
| 299 | { |
| 300 | bool IsCtrl = Packet.m_Flags & NET_PACKETFLAG_CONTROL; |
| 301 | int CtrlMsg = Packet.m_aChunkData[0]; |
| 302 | |
| 303 | if(IsCtrl && CtrlMsg == NET_CTRLMSG_CONNECT) |
| 304 | { |
| 305 | if(g_Config.m_SvVanillaAntiSpoof && g_Config.m_Password[0] == '\0') |
| 306 | { |
| 307 | bool Flooding = false; |
| 308 | |
| 309 | if(g_Config.m_SvVanConnPerSecond) |
| 310 | { |
| 311 | // detect flooding |
| 312 | Flooding = m_VConnNum > g_Config.m_SvVanConnPerSecond; |
| 313 | const int64_t Now = time_get(); |
| 314 | |
| 315 | if(Now <= m_VConnFirst + time_freq()) |
| 316 | { |
| 317 | m_VConnNum++; |
| 318 | } |
| 319 | else |
| 320 | { |
| 321 | m_VConnNum = 1; |
| 322 | m_VConnFirst = Now; |
| 323 | } |
| 324 | } |
| 325 | |
| 326 | if(g_Config.m_Debug && Flooding) |
| 327 | { |
| 328 | dbg_msg("security", "vanilla connection flooding detected"); |
| 329 | } |
| 330 | |
| 331 | // simulate accept |
| 332 | SendControl(Addr, NET_CTRLMSG_CONNECTACCEPT, nullptr, 0, NET_SECURITY_TOKEN_UNSUPPORTED); |
| 333 | |
| 334 | // Begin vanilla compatible token handshake |
| 335 | // The idea is to pack a security token in the gametick |
| 336 | // parameter of NETMSG_SNAPEMPTY. The Client then will |
| 337 | // return the token/gametick in NETMSG_INPUT, allowing |
| 338 | // us to validate the token. |
| 339 | // https://github.com/eeeee/ddnet/commit/b8e40a244af4e242dc568aa34854c5754c75a39a |
| 340 | |
| 341 | // Before we can send NETMSG_SNAPEMPTY, the client needs |
| 342 | // to load a map, otherwise it might crash. The map |
| 343 | // should be as small as is possible and directly available |
| 344 | // to the client. Therefore a dummy map is sent in the same |
| 345 | // packet. To reduce the traffic we'll fallback to a default |
| 346 | // map if there are too many connection attempts at once. |
| 347 | |
| 348 | // send mapchange + map data + con_ready + 3 x empty snap (with token) |
| 349 | CPacker MapChangeMsg; |
| 350 | MapChangeMsg.Reset(); |
| 351 | MapChangeMsg.AddInt((NETMSG_MAP_CHANGE << 1) | 1); |
| 352 | if(Flooding) |
| 353 | { |
| 354 | // Fallback to dm1 |
| 355 | MapChangeMsg.AddString("dm1", 0); |