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

View File

@ -881,6 +881,7 @@ void STKHost::mainLoop()
uint64_t last_ping_time = StkTime::getMonoTimeMs();
uint64_t last_update_speed_time = 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;
while (m_exit_timeout.load() > StkTime::getMonoTimeMs())
{
@ -920,6 +921,15 @@ void STKHost::mainLoop()
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);
const float timeout = ServerConfig::m_validation_timeout;
bool need_ping = false;

View File

@ -152,22 +152,39 @@ std::string getIPV6ReadableFromMappedAddress(const ENetAddress* ea)
return "";
} // getIPV6ReadableFromMappedAddress
// ----------------------------------------------------------------------------
void removeDisconnectedMappedAddress()
{
} // removeDisconnectedMappedAddress
#else
#include "network/unix_ipv6.hpp"
#include "network/transport_address.hpp"
#include "utils/string_utils.hpp"
#include "utils/log.hpp"
#include "utils/time.hpp"
#include "utils/types.hpp"
#include <algorithm>
#include <utility>
#include <vector>
// ============================================================================
uint32_t g_mapped_ipv6_used;
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()
{
@ -189,39 +206,18 @@ void unixInitialize()
g_mapped_ips.clear();
} // 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 result;
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())
result = getIPV6ReadableFromIn6(&it->second);
result = getIPV6ReadableFromIn6(&it->m_in6);
return result;
} // getIPV6ReadableFromMappedAddress
@ -243,12 +239,16 @@ void addMappedAddress(const ENetAddress* ea, const 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(),
[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())
memcpy(in6, &it->second, sizeof(struct sockaddr_in6));
{
it->m_last_activity = StkTime::getMonoTimeMs();
memcpy(in6, &it->m_in6, sizeof(struct sockaddr_in6));
}
else
memset(in6, 0, sizeof(struct sockaddr_in6));
} // getIPV6FromMappedAddress
@ -260,13 +260,14 @@ void getIPV6FromMappedAddress(const ENetAddress* ea, struct sockaddr_in6* in6)
void getMappedFromIPV6(const struct sockaddr_in6* in6, ENetAddress* ea)
{
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())
{
*ea = it->first;
it->m_last_activity = StkTime::getMonoTimeMs();
*ea = it->m_addr;
return;
}
@ -296,4 +297,27 @@ void getMappedFromIPV6(const struct sockaddr_in6* in6, ENetAddress* ea)
}
} // 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

View File

@ -24,7 +24,6 @@ extern "C" {
int isIPV6();
void setIPV6(int val);
void unixInitialize();
void removeMappedAddress(const ENetAddress* ea);
void getIPV6FromMappedAddress(const ENetAddress* ea, struct sockaddr_in6* in6);
void getMappedFromIPV6(const struct sockaddr_in6* in6, ENetAddress* ea);
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);
bool sameIPV6(const struct sockaddr_in6* in_1,
const struct sockaddr_in6* in_2);
void removeDisconnectedMappedAddress();