From fdeb884fe5bf95777ab3022261a84e3bcbbcf2ef Mon Sep 17 00:00:00 2001
From: R4SAS <r4sas@i2pmail.org>
Date: Wed, 27 Jul 2022 13:24:07 +0300
Subject: [PATCH] fixed getting MTU on windows, add address to log messages
 with MTU

Signed-off-by: R4SAS <r4sas@i2pmail.org>
---
 libi2pd/RouterContext.cpp | 54 ++++++++++++++++++-------------------
 libi2pd/util.cpp          | 56 ++++++++++++++++++++++-----------------
 2 files changed, 58 insertions(+), 52 deletions(-)

diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp
index 9e53f23b..636d47ce 100644
--- a/libi2pd/RouterContext.cpp
+++ b/libi2pd/RouterContext.cpp
@@ -230,8 +230,8 @@ namespace i2p
 		auto transports = m_RouterInfo.GetCompatibleTransports (false);
 		return (transports & (i2p::data::RouterInfo::eSSU2V4 | i2p::data::RouterInfo::eSSU2V6)) &&
 			!(transports & (i2p::data::RouterInfo::eSSUV4 | i2p::data::RouterInfo::eSSUV6));
-	}	
-		
+	}
+
 	void RouterContext::SetStatus (RouterStatus status)
 	{
 		if (status != m_Status)
@@ -256,8 +256,8 @@ namespace i2p
 	{
 		if (IsSSU2Only ())
 			SetStatus (status);
-	}	
-		
+	}
+
 	void RouterContext::SetStatusV6 (RouterStatus status)
 	{
 		if (status != m_StatusV6)
@@ -281,8 +281,8 @@ namespace i2p
 	{
 		if (IsSSU2Only ())
 			SetStatusV6 (status);
-	}	
-		
+	}
+
 	void RouterContext::UpdatePort (int port)
 	{
 		bool updated = false;
@@ -472,14 +472,14 @@ namespace i2p
 			UpdateRouterInfo ();
 		return ret;
 	}
-		
+
 	void RouterContext::RemoveSSU2Introducer (const i2p::data::IdentHash& h, bool v4)
 	{
 		if (!IsSSU2Only ()) return;
 		if (m_RouterInfo.RemoveSSU2Introducer (h, v4))
 			UpdateRouterInfo ();
-	}	
-		
+	}
+
 	void RouterContext::SetFloodfill (bool floodfill)
 	{
 		m_IsFloodfill = floodfill;
@@ -598,8 +598,8 @@ namespace i2p
 	{
 		if (IsSSU2Only ())
 			SetUnreachable (v4, v6);
-	}	
-		
+	}
+
 	void RouterContext::SetUnreachable (bool v4, bool v6)
 	{
 		if (v4 || (v6 && !SupportsV4 ()))
@@ -649,7 +649,7 @@ namespace i2p
 		// delete previous introducers
 		bool isSSU2Published = IsSSU2Only (); // TODO
 		if (isSSU2Published)
-			i2p::config::GetOption ("ssu2.published", isSSU2Published);	
+			i2p::config::GetOption ("ssu2.published", isSSU2Published);
 		auto& addresses = m_RouterInfo.GetAddresses ();
 		for (auto& addr : addresses)
 			if (addr->ssu && (!addr->IsSSU2 () || isSSU2Published) && 
@@ -880,34 +880,34 @@ namespace i2p
 			if (addr->ssu && ((v4 && addr->IsV4 ()) || (!v4 && addr->IsV6 ())))
 			{
 				if (!addr->IsSSU2 ()) // SSU1
-				{	
+				{
 					// round to multiple of 16
 					if (v4)
-					{	
+					{
 						if (mtu > 1484) mtu = 1484;
 						else
-						{	
+						{
 							mtu -= 12;
 							mtu = (mtu >> 4) << 4;
 							mtu += 12;
-						}	
-					}		
-					else	
+						}
+					}
+					else
 					{
 						if (mtu > 1488) mtu = 1488;
 						else
 							mtu = (mtu >> 4) << 4;
-					}	
-				}	
+					}
+				}
 				if (mtu)
-				{	
+				{
 					addr->ssu->mtu = mtu;
-					LogPrint (eLogDebug, "Router: MTU for ", v4 ? "ipv4" : "ipv6", " address is set to ", mtu);
-				}	
-			}	
-		}	
-	}	
-		
+					LogPrint (eLogDebug, "Router: MTU for ", v4 ? "ipv4" : "ipv6", " address ", addr->host.to_string(), " is set to ", mtu);
+				}
+			}
+		}
+	}
+
 	void RouterContext::UpdateNTCP2V6Address (const boost::asio::ip::address& host)
 	{
 		bool isYgg = i2p::util::net::IsYggdrasilAddress (host);
diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp
index 5bd0fb00..e8d51dc9 100644
--- a/libi2pd/util.cpp
+++ b/libi2pd/util.cpp
@@ -173,7 +173,7 @@ namespace net
 
 		if(dwRetVal != NO_ERROR)
 		{
-			LogPrint(eLogError, "NetIface: GetMTU(): Enclosed GetAdaptersAddresses() call has failed");
+			LogPrint(eLogError, "NetIface: GetMTU: Enclosed GetAdaptersAddresses() call has failed");
 			FREE(pAddresses);
 			return fallback;
 		}
@@ -185,7 +185,7 @@ namespace net
 
 			pUnicast = pCurrAddresses->FirstUnicastAddress;
 			if(pUnicast == nullptr)
-				LogPrint(eLogError, "NetIface: GetMTU(): Not a unicast IPv4 address, this is not supported");
+				LogPrint(eLogError, "NetIface: GetMTU: Not a unicast IPv4 address, this is not supported");
 
 			for(int i = 0; pUnicast != nullptr; ++i)
 			{
@@ -193,10 +193,13 @@ namespace net
 				sockaddr_in* localInterfaceAddress = (sockaddr_in*) lpAddr;
 				if(localInterfaceAddress->sin_addr.S_un.S_addr == inputAddress.sin_addr.S_un.S_addr)
 				{
-					auto result = pAddresses->Mtu;
+					char addr[INET_ADDRSTRLEN];
+					inet_ntop(AF_INET, &(((struct sockaddr_in *)localInterfaceAddress)->sin_addr), addr, INET_ADDRSTRLEN);
+
+					auto result = pCurrAddresses->Mtu;
 					FREE(pAddresses);
 					pAddresses = nullptr;
-					LogPrint(eLogInfo, "NetIface: GetMTU(): Using ", result, " bytes for IPv4");
+					LogPrint(eLogInfo, "NetIface: GetMTU: Using ", result, " bytes for IPv4 address ", addr);
 					return result;
 				}
 				pUnicast = pUnicast->Next;
@@ -204,7 +207,7 @@ namespace net
 			pCurrAddresses = pCurrAddresses->Next;
 		}
 
-		LogPrint(eLogError, "NetIface: GetMTU(): No usable unicast IPv4 addresses found");
+		LogPrint(eLogError, "NetIface: GetMTU: No usable unicast IPv4 addresses found");
 		FREE(pAddresses);
 		return fallback;
 	}
@@ -216,7 +219,7 @@ namespace net
 		PIP_ADAPTER_ADDRESSES pCurrAddresses = nullptr;
 		PIP_ADAPTER_UNICAST_ADDRESS pUnicast = nullptr;
 
-		if(GetAdaptersAddresses(AF_INET6, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen)
+		if (GetAdaptersAddresses(AF_INET6, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen)
 			== ERROR_BUFFER_OVERFLOW)
 		{
 			FREE(pAddresses);
@@ -227,23 +230,23 @@ namespace net
 			AF_INET6, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen
 		);
 
-		if(dwRetVal != NO_ERROR)
+		if (dwRetVal != NO_ERROR)
 		{
-			LogPrint(eLogError, "NetIface: GetMTU(): Enclosed GetAdaptersAddresses() call has failed");
+			LogPrint(eLogError, "NetIface: GetMTU: Enclosed GetAdaptersAddresses() call has failed");
 			FREE(pAddresses);
 			return fallback;
 		}
 
 		bool found_address = false;
 		pCurrAddresses = pAddresses;
-		while(pCurrAddresses)
+		while (pCurrAddresses)
 		{
 			PIP_ADAPTER_UNICAST_ADDRESS firstUnicastAddress = pCurrAddresses->FirstUnicastAddress;
 			pUnicast = pCurrAddresses->FirstUnicastAddress;
-			if(pUnicast == nullptr)
-				LogPrint(eLogError, "NetIface: GetMTU(): Not a unicast IPv6 address, this is not supported");
+			if (pUnicast == nullptr)
+				LogPrint(eLogError, "NetIface: GetMTU: Not a unicast IPv6 address, this is not supported");
 
-			for(int i = 0; pUnicast != nullptr; ++i)
+			for (int i = 0; pUnicast != nullptr; ++i)
 			{
 				LPSOCKADDR lpAddr = pUnicast->Address.lpSockaddr;
 				sockaddr_in6 *localInterfaceAddress = (sockaddr_in6*) lpAddr;
@@ -258,10 +261,13 @@ namespace net
 
 				if (found_address)
 				{
-					auto result = pAddresses->Mtu;
+					char addr[INET6_ADDRSTRLEN];
+					inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)localInterfaceAddress)->sin6_addr), addr, INET6_ADDRSTRLEN);
+
+					auto result = pCurrAddresses->Mtu;
 					FREE(pAddresses);
 					pAddresses = nullptr;
-					LogPrint(eLogInfo, "NetIface: GetMTU(): Using ", result, " bytes for IPv6");
+					LogPrint(eLogInfo, "NetIface: GetMTU: Using ", result, " bytes for IPv6 address ", addr);
 					return result;
 				}
 				pUnicast = pUnicast->Next;
@@ -270,7 +276,7 @@ namespace net
 			pCurrAddresses = pCurrAddresses->Next;
 		}
 
-		LogPrint(eLogError, "NetIface: GetMTU(): No usable unicast IPv6 addresses found");
+		LogPrint(eLogError, "NetIface: GetMTU: No usable unicast IPv6 addresses found");
 		FREE(pAddresses);
 		return fallback;
 	}
@@ -302,7 +308,7 @@ namespace net
 		}
 		else
 		{
-			LogPrint(eLogError, "NetIface: GetMTU(): Address family is not supported");
+			LogPrint(eLogError, "NetIface: GetMTU: Address family is not supported");
 			return fallback;
 		}
 	}
@@ -434,20 +440,20 @@ namespace net
 		{
 			case 0x20010470:
 			case 0x260070ff:
-			// Hurricane Electric	
+			// Hurricane Electric
 				return 1480;
 			break;
-			case 0x2a06a003:	
+			case 0x2a06a003:
 			case 0x2a06a004:
-			case 0x2a06a005:	
-			//  route48	
+			case 0x2a06a005:
+			// route48
 				return 1420;
-			break;	
-			default: ;	
-		}	
+			break;
+			default: ;
+		}
 		return 1500;
-	}	
-	
+	}
+
 	static bool IsYggdrasilAddress (const uint8_t addr[16])
 	{
 		return addr[0] == 0x02 || addr[0] == 0x03;