Remove expired mapped address using last activity

This commit is contained in:
Benau 2019-08-20 13:10:18 +08:00
parent 5cacd486da
commit a92b9abf54
4 changed files with 68 additions and 46 deletions

View File

@ -9,10 +9,6 @@
#include "enet/time.h" #include "enet/time.h"
#include "enet/enet.h" #include "enet/enet.h"
#ifdef ENABLE_IPV6
extern void removeMappedAddress(const ENetAddress* ea);
#endif
static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] = static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] =
{ {
0, 0,
@ -88,10 +84,6 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
event -> peer = peer; event -> peer = peer;
event -> data = peer -> eventData; event -> data = peer -> eventData;
#ifdef ENABLE_IPV6
removeMappedAddress(&peer->address);
#endif
enet_peer_reset (peer); enet_peer_reset (peer);
return 1; return 1;
@ -156,10 +148,6 @@ enet_protocol_notify_disconnect (ENetHost * host, ENetPeer * peer, ENetEvent * e
event -> peer = peer; event -> peer = peer;
event -> data = 0; event -> data = 0;
#ifdef ENABLE_IPV6
removeMappedAddress(&peer->address);
#endif
enet_peer_reset (peer); enet_peer_reset (peer);
} }
else else

View File

@ -881,6 +881,7 @@ void STKHost::mainLoop()
uint64_t last_ping_time = StkTime::getMonoTimeMs(); uint64_t last_ping_time = StkTime::getMonoTimeMs();
uint64_t last_update_speed_time = StkTime::getMonoTimeMs(); uint64_t last_update_speed_time = StkTime::getMonoTimeMs();
uint64_t last_ping_time_update_for_client = StkTime::getMonoTimeMs(); uint64_t last_ping_time_update_for_client = StkTime::getMonoTimeMs();
uint64_t last_disconnect_time_update = StkTime::getMonoTimeMs();
std::map<std::string, uint64_t> ctp; std::map<std::string, uint64_t> ctp;
while (m_exit_timeout.load() > StkTime::getMonoTimeMs()) while (m_exit_timeout.load() > StkTime::getMonoTimeMs())
{ {
@ -920,6 +921,15 @@ void STKHost::mainLoop()
if (is_server) if (is_server)
{ {
if (isIPV6() &&
last_disconnect_time_update < StkTime::getMonoTimeMs())
{
// Check per 20 second, don't need to check client because it
// only has 1 peer
last_disconnect_time_update = StkTime::getMonoTimeMs() + 20000;
removeDisconnectedMappedAddress();
}
std::unique_lock<std::mutex> peer_lock(m_peers_mutex); std::unique_lock<std::mutex> peer_lock(m_peers_mutex);
const float timeout = ServerConfig::m_validation_timeout; const float timeout = ServerConfig::m_validation_timeout;
bool need_ping = false; bool need_ping = false;

View File

@ -152,22 +152,39 @@ std::string getIPV6ReadableFromMappedAddress(const ENetAddress* ea)
return ""; return "";
} // getIPV6ReadableFromMappedAddress } // getIPV6ReadableFromMappedAddress
// ----------------------------------------------------------------------------
void removeDisconnectedMappedAddress()
{
} // removeDisconnectedMappedAddress
#else #else
#include "network/unix_ipv6.hpp" #include "network/unix_ipv6.hpp"
#include "network/transport_address.hpp" #include "network/transport_address.hpp"
#include "utils/string_utils.hpp" #include "utils/string_utils.hpp"
#include "utils/log.hpp" #include "utils/log.hpp"
#include "utils/time.hpp"
#include "utils/types.hpp" #include "utils/types.hpp"
#include <algorithm> #include <algorithm>
#include <utility>
#include <vector> #include <vector>
// ============================================================================ // ============================================================================
uint32_t g_mapped_ipv6_used; uint32_t g_mapped_ipv6_used;
int g_ipv6; int g_ipv6;
std::vector<std::pair<ENetAddress, struct sockaddr_in6> > g_mapped_ips; struct MappedAddress
{
ENetAddress m_addr;
struct sockaddr_in6 m_in6;
uint64_t m_last_activity;
MappedAddress(const ENetAddress& addr, const struct sockaddr_in6& in6)
{
m_addr = addr;
m_in6 = in6;
m_last_activity = StkTime::getMonoTimeMs();
}
};
std::vector<MappedAddress> g_mapped_ips;
// ============================================================================ // ============================================================================
int isIPV6() int isIPV6()
{ {
@ -189,39 +206,18 @@ void unixInitialize()
g_mapped_ips.clear(); g_mapped_ips.clear();
} // unixInitialize } // unixInitialize
// ----------------------------------------------------------------------------
/* Called when a peer is disconnected and we remove its reference to the ipv6.
*/
void removeMappedAddress(const ENetAddress* ea)
{
auto it = std::find_if(g_mapped_ips.begin(), g_mapped_ips.end(),
[ea](const std::pair<ENetAddress, struct sockaddr_in6>& addr)
{
return ea->host == addr.first.host && ea->port == addr.first.port;
});
if (it != g_mapped_ips.end())
{
TransportAddress addr(it->first);
Log::debug("IPV6", "Removing %s, ipv4 address %s.",
getIPV6ReadableFromIn6(&it->second).c_str(),
addr.toString().c_str());
g_mapped_ips.erase(it);
Log::debug("IPV6", "Mapped address size now: %d.",
g_mapped_ips.size());
}
} // removeMappedAddress
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
std::string getIPV6ReadableFromMappedAddress(const ENetAddress* ea) std::string getIPV6ReadableFromMappedAddress(const ENetAddress* ea)
{ {
std::string result; std::string result;
auto it = std::find_if(g_mapped_ips.begin(), g_mapped_ips.end(), auto it = std::find_if(g_mapped_ips.begin(), g_mapped_ips.end(),
[ea](const std::pair<ENetAddress, struct sockaddr_in6>& addr) [ea](const MappedAddress& addr)
{ {
return ea->host == addr.first.host && ea->port == addr.first.port; return ea->host == addr.m_addr.host &&
ea->port == addr.m_addr.port;
}); });
if (it != g_mapped_ips.end()) if (it != g_mapped_ips.end())
result = getIPV6ReadableFromIn6(&it->second); result = getIPV6ReadableFromIn6(&it->m_in6);
return result; return result;
} // getIPV6ReadableFromMappedAddress } // getIPV6ReadableFromMappedAddress
@ -243,12 +239,16 @@ void addMappedAddress(const ENetAddress* ea, const struct sockaddr_in6* in6)
void getIPV6FromMappedAddress(const ENetAddress* ea, struct sockaddr_in6* in6) void getIPV6FromMappedAddress(const ENetAddress* ea, struct sockaddr_in6* in6)
{ {
auto it = std::find_if(g_mapped_ips.begin(), g_mapped_ips.end(), auto it = std::find_if(g_mapped_ips.begin(), g_mapped_ips.end(),
[ea](const std::pair<ENetAddress, struct sockaddr_in6>& addr) [ea](const MappedAddress& addr)
{ {
return ea->host == addr.first.host && ea->port == addr.first.port; return ea->host == addr.m_addr.host &&
ea->port == addr.m_addr.port;
}); });
if (it != g_mapped_ips.end()) if (it != g_mapped_ips.end())
memcpy(in6, &it->second, sizeof(struct sockaddr_in6)); {
it->m_last_activity = StkTime::getMonoTimeMs();
memcpy(in6, &it->m_in6, sizeof(struct sockaddr_in6));
}
else else
memset(in6, 0, sizeof(struct sockaddr_in6)); memset(in6, 0, sizeof(struct sockaddr_in6));
} // getIPV6FromMappedAddress } // getIPV6FromMappedAddress
@ -260,13 +260,14 @@ void getIPV6FromMappedAddress(const ENetAddress* ea, struct sockaddr_in6* in6)
void getMappedFromIPV6(const struct sockaddr_in6* in6, ENetAddress* ea) void getMappedFromIPV6(const struct sockaddr_in6* in6, ENetAddress* ea)
{ {
auto it = std::find_if(g_mapped_ips.begin(), g_mapped_ips.end(), auto it = std::find_if(g_mapped_ips.begin(), g_mapped_ips.end(),
[in6](const std::pair<ENetAddress, struct sockaddr_in6>& addr) [in6](const MappedAddress& addr)
{ {
return sameIPV6(in6, &addr.second); return sameIPV6(in6, &addr.m_in6);
}); });
if (it != g_mapped_ips.end()) if (it != g_mapped_ips.end())
{ {
*ea = it->first; it->m_last_activity = StkTime::getMonoTimeMs();
*ea = it->m_addr;
return; return;
} }
@ -296,4 +297,27 @@ void getMappedFromIPV6(const struct sockaddr_in6* in6, ENetAddress* ea)
} }
} // getMappedFromIPV6 } // getMappedFromIPV6
// ----------------------------------------------------------------------------
/* Called when a peer is expired (no activity for 20 seconds) and we remove its
* reference to the ipv6.
*/
void removeDisconnectedMappedAddress()
{
for (auto it = g_mapped_ips.begin(); it != g_mapped_ips.end();)
{
if (it->m_last_activity + 20000 < StkTime::getMonoTimeMs())
{
TransportAddress addr(it->m_addr);
Log::debug("IPV6", "Removing expired %s, ipv4 address %s.",
getIPV6ReadableFromIn6(&it->m_in6).c_str(),
addr.toString().c_str());
it = g_mapped_ips.erase(it);
Log::debug("IPV6", "Mapped address size now: %d.",
g_mapped_ips.size());
}
else
it++;
}
} // removeDisconnectedMappedAddress
#endif #endif

View File

@ -24,7 +24,6 @@ extern "C" {
int isIPV6(); int isIPV6();
void setIPV6(int val); void setIPV6(int val);
void unixInitialize(); void unixInitialize();
void removeMappedAddress(const ENetAddress* ea);
void getIPV6FromMappedAddress(const ENetAddress* ea, struct sockaddr_in6* in6); void getIPV6FromMappedAddress(const ENetAddress* ea, struct sockaddr_in6* in6);
void getMappedFromIPV6(const struct sockaddr_in6* in6, ENetAddress* ea); void getMappedFromIPV6(const struct sockaddr_in6* in6, ENetAddress* ea);
void addMappedAddress(const ENetAddress* ea, const struct sockaddr_in6* in6); void addMappedAddress(const ENetAddress* ea, const struct sockaddr_in6* in6);
@ -37,3 +36,4 @@ std::string getIPV6ReadableFromMappedAddress(const ENetAddress* ea);
std::string getIPV6ReadableFromIn6(const struct sockaddr_in6* in); std::string getIPV6ReadableFromIn6(const struct sockaddr_in6* in);
bool sameIPV6(const struct sockaddr_in6* in_1, bool sameIPV6(const struct sockaddr_in6* in_1,
const struct sockaddr_in6* in_2); const struct sockaddr_in6* in_2);
void removeDisconnectedMappedAddress();