@@ -152,22 +152,39 @@ std::string getIPV6ReadableFromMappedAddress(const ENetAddress* ea)
152152 return " " ;
153153} // getIPV6ReadableFromMappedAddress
154154
155+ // ----------------------------------------------------------------------------
156+ void removeDisconnectedMappedAddress ()
157+ {
158+ } // removeDisconnectedMappedAddress
159+
155160#else
156161
157162#include " network/unix_ipv6.hpp"
158163#include " network/transport_address.hpp"
159164#include " utils/string_utils.hpp"
160165#include " utils/log.hpp"
166+ #include " utils/time.hpp"
161167#include " utils/types.hpp"
162168
163169#include < algorithm>
164- #include < utility>
165170#include < vector>
166171
167172// ============================================================================
168173uint32_t g_mapped_ipv6_used;
169174int g_ipv6;
170- std::vector<std::pair<ENetAddress, struct sockaddr_in6 > > g_mapped_ips;
175+ struct MappedAddress
176+ {
177+ ENetAddress m_addr;
178+ struct sockaddr_in6 m_in6;
179+ uint64_t m_last_activity;
180+ MappedAddress (const ENetAddress& addr, const struct sockaddr_in6 & in6)
181+ {
182+ m_addr = addr;
183+ m_in6 = in6;
184+ m_last_activity = StkTime::getMonoTimeMs ();
185+ }
186+ };
187+ std::vector<MappedAddress> g_mapped_ips;
171188// ============================================================================
172189int isIPV6 ()
173190{
@@ -189,39 +206,18 @@ void unixInitialize()
189206 g_mapped_ips.clear ();
190207} // unixInitialize
191208
192- // ----------------------------------------------------------------------------
193- /* Called when a peer is disconnected and we remove its reference to the ipv6.
194- */
195- void removeMappedAddress (const ENetAddress* ea)
196- {
197- auto it = std::find_if (g_mapped_ips.begin (), g_mapped_ips.end (),
198- [ea](const std::pair<ENetAddress, struct sockaddr_in6 >& addr)
199- {
200- return ea->host == addr.first .host && ea->port == addr.first .port ;
201- });
202- if (it != g_mapped_ips.end ())
203- {
204- TransportAddress addr (it->first );
205- Log::debug (" IPV6" , " Removing %s, ipv4 address %s." ,
206- getIPV6ReadableFromIn6 (&it->second ).c_str (),
207- addr.toString ().c_str ());
208- g_mapped_ips.erase (it);
209- Log::debug (" IPV6" , " Mapped address size now: %d." ,
210- g_mapped_ips.size ());
211- }
212- } // removeMappedAddress
213-
214209// ----------------------------------------------------------------------------
215210std::string getIPV6ReadableFromMappedAddress (const ENetAddress* ea)
216211{
217212 std::string result;
218213 auto it = std::find_if (g_mapped_ips.begin (), g_mapped_ips.end (),
219- [ea](const std::pair<ENetAddress, struct sockaddr_in6 > & addr)
214+ [ea](const MappedAddress & addr)
220215 {
221- return ea->host == addr.first .host && ea->port == addr.first .port ;
216+ return ea->host == addr.m_addr .host &&
217+ ea->port == addr.m_addr .port ;
222218 });
223219 if (it != g_mapped_ips.end ())
224- result = getIPV6ReadableFromIn6 (&it->second );
220+ result = getIPV6ReadableFromIn6 (&it->m_in6 );
225221 return result;
226222} // getIPV6ReadableFromMappedAddress
227223
@@ -243,12 +239,16 @@ void addMappedAddress(const ENetAddress* ea, const struct sockaddr_in6* in6)
243239void getIPV6FromMappedAddress (const ENetAddress* ea, struct sockaddr_in6 * in6)
244240{
245241 auto it = std::find_if (g_mapped_ips.begin (), g_mapped_ips.end (),
246- [ea](const std::pair<ENetAddress, struct sockaddr_in6 > & addr)
242+ [ea](const MappedAddress & addr)
247243 {
248- return ea->host == addr.first .host && ea->port == addr.first .port ;
244+ return ea->host == addr.m_addr .host &&
245+ ea->port == addr.m_addr .port ;
249246 });
250247 if (it != g_mapped_ips.end ())
251- memcpy (in6, &it->second , sizeof (struct sockaddr_in6 ));
248+ {
249+ it->m_last_activity = StkTime::getMonoTimeMs ();
250+ memcpy (in6, &it->m_in6 , sizeof (struct sockaddr_in6 ));
251+ }
252252 else
253253 memset (in6, 0 , sizeof (struct sockaddr_in6 ));
254254} // getIPV6FromMappedAddress
@@ -260,13 +260,14 @@ void getIPV6FromMappedAddress(const ENetAddress* ea, struct sockaddr_in6* in6)
260260void getMappedFromIPV6 (const struct sockaddr_in6 * in6, ENetAddress* ea)
261261{
262262 auto it = std::find_if (g_mapped_ips.begin (), g_mapped_ips.end (),
263- [in6](const std::pair<ENetAddress, struct sockaddr_in6 > & addr)
263+ [in6](const MappedAddress & addr)
264264 {
265- return sameIPV6 (in6, &addr.second );
265+ return sameIPV6 (in6, &addr.m_in6 );
266266 });
267267 if (it != g_mapped_ips.end ())
268268 {
269- *ea = it->first ;
269+ it->m_last_activity = StkTime::getMonoTimeMs ();
270+ *ea = it->m_addr ;
270271 return ;
271272 }
272273
@@ -296,4 +297,27 @@ void getMappedFromIPV6(const struct sockaddr_in6* in6, ENetAddress* ea)
296297 }
297298} // getMappedFromIPV6
298299
300+ // ----------------------------------------------------------------------------
301+ /* Called when a peer is expired (no activity for 20 seconds) and we remove its
302+ * reference to the ipv6.
303+ */
304+ void removeDisconnectedMappedAddress ()
305+ {
306+ for (auto it = g_mapped_ips.begin (); it != g_mapped_ips.end ();)
307+ {
308+ if (it->m_last_activity + 20000 < StkTime::getMonoTimeMs ())
309+ {
310+ TransportAddress addr (it->m_addr );
311+ Log::debug (" IPV6" , " Removing expired %s, ipv4 address %s." ,
312+ getIPV6ReadableFromIn6 (&it->m_in6 ).c_str (),
313+ addr.toString ().c_str ());
314+ it = g_mapped_ips.erase (it);
315+ Log::debug (" IPV6" , " Mapped address size now: %d." ,
316+ g_mapped_ips.size ());
317+ }
318+ else
319+ it++;
320+ }
321+ } // removeDisconnectedMappedAddress
322+
299323#endif
0 commit comments