diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp
index 87a987fe..3035bd31 100644
--- a/libi2pd/RouterInfo.cpp
+++ b/libi2pd/RouterInfo.cpp
@@ -36,7 +36,7 @@ namespace data
 
 	RouterInfo::RouterInfo (const std::string& fullPath):
 		m_FullPath (fullPath), m_IsUpdated (false), m_IsUnreachable (false),
-		m_SupportedTransports (0), m_Caps (0), m_Version (0)
+		m_SupportedTransports (0), m_ReachableTransports (0), m_Caps (0), m_Version (0)
 	{
 		m_Addresses = boost::make_shared<Addresses>(); // create empty list
 		m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
@@ -45,7 +45,7 @@ namespace data
 
 	RouterInfo::RouterInfo (const uint8_t * buf, int len):
 		m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0),
-		m_Caps (0), m_Version (0)
+		m_ReachableTransports (0), m_Caps (0), m_Version (0)
 	{
 		m_Addresses = boost::make_shared<Addresses>(); // create empty list
 		if (len <= MAX_RI_BUFFER_SIZE)
@@ -84,6 +84,7 @@ namespace data
 			m_IsUpdated = true;
 			m_IsUnreachable = false;
 			m_SupportedTransports = 0;
+			m_ReachableTransports = 0;
 			m_Caps = 0;
 			// don't clean up m_Addresses, it will be replaced in ReadFromStream
 			m_Properties.clear ();
@@ -305,9 +306,10 @@ namespace data
 					if (isHost)
 					{
 						if (address->host.is_v6 ())
-							supportedTransports |= i2p::util::net::IsYggdrasilAddress (address->host) ? eNTCP2V6Mesh :  eNTCP2V6;
+							supportedTransports |= (i2p::util::net::IsYggdrasilAddress (address->host) ? eNTCP2V6Mesh :  eNTCP2V6);
 						else
 							supportedTransports |= eNTCP2V4; 
+						m_ReachableTransports |= supportedTransports;
 					}	
 					else if (!address->published)
 					{
@@ -347,10 +349,16 @@ namespace data
 							else
 								it.iPort = 0;
 						}	
-						if (!numValid) address->ssu->introducers.resize (0);
+						if (numValid)
+							m_ReachableTransports |= supportedTransports;
+						else	
+							address->ssu->introducers.resize (0);
 					}	
 					else if (isHost && address->port)
+					{	
 						address->published = true;
+						m_ReachableTransports |= supportedTransports;
+					}	
 				}	
 			}	
 			if (supportedTransports)
@@ -860,6 +868,7 @@ namespace data
 				for (auto& intro: addr->ssu->introducers)
 					if (intro.iTag == introducer.iTag) return false; // already presented
 				addr->ssu->introducers.push_back (introducer);
+				m_ReachableTransports |= (addr->IsV4 () ? eSSUV4 : eSSUV6);
 				return true;
 			}
 		}
@@ -877,6 +886,8 @@ namespace data
 					if (boost::asio::ip::udp::endpoint (it->iHost, it->iPort) == e)
 					{
 						addr->ssu->introducers.erase (it);
+						if (addr->ssu->introducers.empty ())
+							m_ReachableTransports &= ~(addr->IsV4 () ? eSSUV4 : eSSUV6);
 						return true;
 					}
 			}
@@ -1184,5 +1195,31 @@ namespace data
 			}
 		}
 	}
+
+	void RouterInfo::UpdateSupportedTransports ()
+	{
+		m_SupportedTransports = 0;
+		m_ReachableTransports = 0;
+		for (const auto& addr: *m_Addresses)
+		{
+			uint8_t transports = 0;
+			if (addr->transportStyle == eTransportNTCP)
+			{
+				if (addr->IsV4 ()) transports |= eNTCP2V4;
+				if (addr->IsV6 ()) 
+					transports |= (i2p::util::net::IsYggdrasilAddress (addr->host) ? eNTCP2V6Mesh : eNTCP2V6);
+				if (addr->IsPublishedNTCP2 ())
+					m_ReachableTransports |= transports;
+			}
+			else if (addr->transportStyle == eTransportSSU)
+			{
+				if (addr->IsV4 ()) transports |= eSSUV4;
+				if (addr->IsV6 ()) transports |= eSSUV6;
+				if (addr->IsReachableSSU ())
+					m_ReachableTransports |= transports;
+			}	
+			m_SupportedTransports |= transports;
+		}
+	}	
 }
 }
diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h
index dd3e7e13..bea83fda 100644
--- a/libi2pd/RouterInfo.h
+++ b/libi2pd/RouterInfo.h
@@ -59,7 +59,7 @@ namespace data
 	{
 		public:
 
-			enum SupportedTranports
+			enum SupportedTransports
 			{
 				eNTCP2V4 = 0x01,
 				eNTCP2V6 = 0x02,
@@ -147,7 +147,7 @@ namespace data
 
 				bool IsNTCP2 () const { return (bool)ntcp2; };
 				bool IsPublishedNTCP2 () const { return IsNTCP2 () && published; };
-				bool IsReachableSSU () const { return (bool)ssu && (!host.is_unspecified () || !ssu->introducers.empty ()); };
+				bool IsReachableSSU () const { return (bool)ssu && (published || !ssu->introducers.empty ()); };
 				bool UsesIntroducer () const { return  (bool)ssu && !ssu->introducers.empty (); };
 				
 				bool IsIntroducer () const { return caps & eSSUIntroducer; };
@@ -187,6 +187,7 @@ namespace data
 			std::string GetProperty (const std::string& key) const; // called from RouterContext only
 			void ClearProperties () { m_Properties.clear (); };
 			void SetUnreachableAddressesTransportCaps (uint8_t transports); // bitmask of AddressCaps
+			void UpdateSupportedTransports ();
 			bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; };
 			bool IsReachable () const { return m_Caps & Caps::eReachable; };
 			bool IsSSU (bool v4only = true) const;
@@ -269,7 +270,7 @@ namespace data
 			boost::shared_ptr<Addresses> m_Addresses; // TODO: use std::shared_ptr and std::atomic_store for gcc >= 4.9
 			std::map<std::string, std::string> m_Properties;
 			bool m_IsUpdated, m_IsUnreachable;
-			uint8_t m_SupportedTransports, m_Caps;
+			uint8_t m_SupportedTransports, m_ReachableTransports, m_Caps;
 			int m_Version;
 			mutable std::shared_ptr<RouterProfile> m_Profile;
 	};