From 6d42cccadc5391aab9d5bc7ca7adb830bad2e444 Mon Sep 17 00:00:00 2001
From: orignal <romakoshelkin@yandex.ru>
Date: Tue, 8 Apr 2014 21:56:34 -0400
Subject: [PATCH] extract SSU caps

---
 RouterInfo.cpp | 17 ++++++++++++++---
 RouterInfo.h   |  6 +++++-
 Transports.cpp | 12 ++++++------
 3 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/RouterInfo.cpp b/RouterInfo.cpp
index d3cbb865..9a4f8f97 100644
--- a/RouterInfo.cpp
+++ b/RouterInfo.cpp
@@ -129,6 +129,8 @@ namespace data
 					address.port = boost::lexical_cast<int>(value);
 				else if (!strcmp (key, "key"))
 					Base64ToByteStream (value, strlen (value), address.key, 32);
+				else if (!strcmp (key, "caps"))
+					ExtractCaps (value);
 				else if (key[0] == 'i')
 				{	
 					// introducers
@@ -191,7 +193,6 @@ namespace data
 
 	void RouterInfo::ExtractCaps (const char * value)
 	{
-		m_Caps = 0;	
 		const char * cap = value;
 		while (*cap)
 		{
@@ -208,6 +209,12 @@ namespace data
 				case 'R':
 					m_Caps |= Caps::eReachable;
 				break;
+				case 'B':
+					m_Caps |= Caps::eSSUTesting;
+				break;	
+				case 'C':
+					m_Caps |= Caps::eSSUIntroducer;
+				break;		
 				default: ;
 			}	
 			cap++;
@@ -249,7 +256,10 @@ namespace data
 				// caps
 				WriteString ("caps", properties);
 				properties << '=';
-				WriteString ("B", properties); // TODO: should be 'BC' for introducers
+				std::string caps;
+				if (IsPeerTesting ()) caps += 'B';
+				if (IsIntroducer ()) caps += 'C';
+				WriteString (caps, properties);
 				properties << ';';
 			}	
 			else
@@ -344,11 +354,12 @@ namespace data
 		addr.host = boost::asio::ip::address::from_string (host);
 		addr.port = port;
 		addr.transportStyle = eTransportSSU;
-		addr.cost = 10; // NTCP should have prioprity over SSU
+		addr.cost = 10; // NTCP should have priority over SSU
 		addr.date = 0;
 		memcpy (addr.key, key, 32);
 		m_Addresses.push_back(addr);	
 		m_SupportedTransports |= eSSUV4;
+		m_Caps |= eSSUTesting; // TODO
 	}	
 		
 	void RouterInfo::SetProperty (const char * key, const char * value)
diff --git a/RouterInfo.h b/RouterInfo.h
index 19521a6d..d730c5f8 100644
--- a/RouterInfo.h
+++ b/RouterInfo.h
@@ -29,7 +29,9 @@ namespace data
 			{
 				eFloodfill = 0x01,
 				eHighBandwidth = 0x02,
-				eReachable = 0x04
+				eReachable = 0x04,
+				eSSUTesting = 0x08,
+				eSSUIntroducer = 0x10
 			};
 
 			enum TransportStyle
@@ -84,6 +86,8 @@ namespace data
 			bool IsSSU (bool v4only = true) const;
 			bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; };
 			bool UsesIntroducer () const;
+			bool IsIntroducer () const { return m_Caps & eSSUIntroducer; };
+			bool IsPeerTesting () const { return m_Caps & eSSUTesting; };
 			uint8_t GetCaps () const { return m_Caps; };			
 
 			void SetUnreachable (bool unreachable) { m_IsUnreachable = unreachable; }; 
diff --git a/Transports.cpp b/Transports.cpp
index d427635c..d7bdd634 100644
--- a/Transports.cpp
+++ b/Transports.cpp
@@ -123,16 +123,16 @@ namespace i2p
 		
 	void Transports::Stop ()
 	{	
-		for (auto session: m_NTCPSessions)
-			delete session.second;
-		m_NTCPSessions.clear ();
-		delete m_NTCPAcceptor;
-		
 		if (m_SSUServer)
 		{
 			m_SSUServer->Stop ();
 			delete m_SSUServer;
-		}
+		}	
+		
+		for (auto session: m_NTCPSessions)
+			delete session.second;
+		m_NTCPSessions.clear ();
+		delete m_NTCPAcceptor;
 
 		m_DHKeysPairSupplier.Stop ();
 		m_IsRunning = false;