Hello community,

here is the log from the commit of package i2pd for openSUSE:Factory checked in 
at 2019-10-23 15:51:17
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/i2pd (Old)
 and      /work/SRC/openSUSE:Factory/.i2pd.new.2352 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "i2pd"

Wed Oct 23 15:51:17 2019 rev:9 rq:741909 version:2.29.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/i2pd/i2pd.changes        2019-08-29 
17:18:32.919357141 +0200
+++ /work/SRC/openSUSE:Factory/.i2pd.new.2352/i2pd.changes      2019-10-23 
15:51:22.858729021 +0200
@@ -1,0 +2,10 @@
+Tue Oct 22 16:05:12 UTC 2019 - Alexei Podvalsky <avvi...@yandex.by>
+
+- Update to 2.29.0:
+  * Client auth flag for b33 address
+  * Remove incoming NTCP2 session from pending list when established
+  * Handle errors for NTCP2 SessionConfrimed send
+  * SAM crash if invalid lookup address
+  * Possible crash when UPnP enabled on shutdown
+
+-------------------------------------------------------------------

Old:
----
  i2pd-2.28.0.tar.gz

New:
----
  i2pd-2.29.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ i2pd.spec ++++++
--- /var/tmp/diff_new_pack.TFY4yp/_old  2019-10-23 15:51:23.910730158 +0200
+++ /var/tmp/diff_new_pack.TFY4yp/_new  2019-10-23 15:51:23.910730158 +0200
@@ -19,7 +19,7 @@
 %define sysuser i2pd
 %define sysgroup i2pd
 Name:           i2pd
-Version:        2.28.0
+Version:        2.29.0
 Release:        0
 Summary:        C++ implementation of an I2P client
 License:        BSD-3-Clause

++++++ i2pd-2.28.0.tar.gz -> i2pd-2.29.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/ChangeLog new/i2pd-2.29.0/ChangeLog
--- old/i2pd-2.28.0/ChangeLog   2019-08-27 16:17:32.000000000 +0200
+++ new/i2pd-2.29.0/ChangeLog   2019-10-21 18:02:43.000000000 +0200
@@ -1,6 +1,17 @@
 # for this file format description,
 # see https://github.com/olivierlacan/keep-a-changelog
 
+## [2.29.0] - 2019-10-21
+### Added
+- Client auth flag for b33 address
+### Changed
+- Remove incoming  NTCP2 session from pending list when established 
+- Handle errors for NTCP2 SessionConfrimed send
+### Fixed
+- Failure to start on Windows XP
+- SAM crash if invalid lookup address
+- Possible crash when UPnP enabled on shutdown
+
 ## [2.28.0] - 2019-08-27
 ### Added
 - RAW datagrams in SAM
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/Win32/installer.iss 
new/i2pd-2.29.0/Win32/installer.iss
--- old/i2pd-2.28.0/Win32/installer.iss 2019-08-27 16:17:32.000000000 +0200
+++ new/i2pd-2.29.0/Win32/installer.iss 2019-10-21 18:02:43.000000000 +0200
@@ -1,5 +1,5 @@
 #define I2Pd_AppName "i2pd"
-#define I2Pd_ver "2.28.0"
+#define I2Pd_ver "2.29.0"
 #define I2Pd_Publisher "PurpleI2P"
 
 [Setup]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/android/build.gradle 
new/i2pd-2.29.0/android/build.gradle
--- old/i2pd-2.28.0/android/build.gradle        2019-08-27 16:17:32.000000000 
+0200
+++ new/i2pd-2.29.0/android/build.gradle        2019-10-21 18:02:43.000000000 
+0200
@@ -30,8 +30,8 @@
         applicationId "org.purplei2p.i2pd"
         targetSdkVersion 29
         minSdkVersion 14
-        versionCode 2280
-        versionName "2.28.0"
+        versionCode 2290
+        versionName "2.29.0"
         ndk {
             abiFilters 'armeabi-v7a'
             abiFilters 'x86'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/appveyor.yml new/i2pd-2.29.0/appveyor.yml
--- old/i2pd-2.28.0/appveyor.yml        2019-08-27 16:17:32.000000000 +0200
+++ new/i2pd-2.29.0/appveyor.yml        2019-10-21 18:02:43.000000000 +0200
@@ -1,4 +1,4 @@
-version: 2.28.0.{build}
+version: 2.29.0.{build}
 pull_requests:
   do_not_increment_build_number: true
 branches:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/contrib/rpm/i2pd-git.spec 
new/i2pd-2.29.0/contrib/rpm/i2pd-git.spec
--- old/i2pd-2.28.0/contrib/rpm/i2pd-git.spec   2019-08-27 16:17:32.000000000 
+0200
+++ new/i2pd-2.29.0/contrib/rpm/i2pd-git.spec   2019-10-21 18:02:43.000000000 
+0200
@@ -1,7 +1,7 @@
 %define git_hash %(git rev-parse HEAD | cut -c -7)
 
 Name:           i2pd-git
-Version:        2.28.0
+Version:        2.29.0
 Release:        git%{git_hash}%{?dist}
 Summary:        I2P router written in C++
 Conflicts:      i2pd
@@ -110,6 +110,9 @@
 
 
 %changelog
+* Mon Oct 21 2019 orignal <i2porig...@yandex.ru> - 2.29.0
+- update to 2.29.0
+
 * Tue Aug 27 2019 orignal <i2porig...@yandex.ru> - 2.28.0
 - update to 2.28.0
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/contrib/rpm/i2pd.spec 
new/i2pd-2.29.0/contrib/rpm/i2pd.spec
--- old/i2pd-2.28.0/contrib/rpm/i2pd.spec       2019-08-27 16:17:32.000000000 
+0200
+++ new/i2pd-2.29.0/contrib/rpm/i2pd.spec       2019-10-21 18:02:43.000000000 
+0200
@@ -1,5 +1,5 @@
 Name:           i2pd
-Version:        2.28.0
+Version:        2.29.0
 Release:        1%{?dist}
 Summary:        I2P router written in C++
 Conflicts:      i2pd-git
@@ -108,6 +108,9 @@
 
 
 %changelog
+* Mon Oct 21 2019 orignal <i2porig...@yandex.ru> - 2.29.0
+- update to 2.29.0
+
 * Tue Aug 27 2019 orignal <i2porig...@yandex.ru> - 2.28.0
 - update to 2.28.0
 
@@ -130,7 +133,7 @@
 - update to 2.22.0
 - add support of tunnelsdir option
 
-* Thu Oct 22 2018 orignal <i2porig...@yandex.ru> - 2.21.1
+* Mon Oct 22 2018 orignal <i2porig...@yandex.ru> - 2.21.1
 - update to 2.21.1
 
 * Thu Oct 4 2018 orignal <i2porig...@yandex.ru> - 2.21.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/daemon/HTTPServer.cpp 
new/i2pd-2.29.0/daemon/HTTPServer.cpp
--- old/i2pd-2.28.0/daemon/HTTPServer.cpp       2019-08-27 16:17:32.000000000 
+0200
+++ new/i2pd-2.29.0/daemon/HTTPServer.cpp       2019-10-21 18:02:43.000000000 
+0200
@@ -356,7 +356,7 @@
                s << dest->GetIdentity ()->ToBase64 () << 
"</textarea><br>\r\n<br>\r\n";
                if (dest->IsEncryptedLeaseSet ())
                {
-                       i2p::data::BlindedPublicKey blinded (dest->GetIdentity 
());
+                       i2p::data::BlindedPublicKey blinded (dest->GetIdentity 
(), dest->IsPerClientAuth ());
                        s << "<div class='slide'><label 
for='slide-b33'><b>Encrypted B33 address:</b></label>\r\n<input type='checkbox' 
id='slide-b33'/>\r\n<p class='content'>\r\n";
                        s << blinded.ToB33 () << ".b32.i2p<br>\r\n";
                        s << "</p>\r\n</div>\r\n";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/daemon/UPnP.cpp 
new/i2pd-2.29.0/daemon/UPnP.cpp
--- old/i2pd-2.28.0/daemon/UPnP.cpp     2019-08-27 16:17:32.000000000 +0200
+++ new/i2pd-2.29.0/daemon/UPnP.cpp     2019-10-21 18:02:43.000000000 +0200
@@ -79,43 +79,59 @@
 
        void UPnP::Discover ()
        {
-#if MINIUPNPC_API_VERSION >= 14
-               int nerror = 0;
-               m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 
0, 0, 2, &nerror);
-#elif ( MINIUPNPC_API_VERSION >= 8 || defined(UPNPDISCOVER_SUCCESS) )
-               int nerror = 0;
-               m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 
0, 0, &nerror);
+               bool isError;
+        int err;
+
+#if ((MINIUPNPC_API_VERSION >= 8) || defined (UPNPDISCOVER_SUCCESS))
+        err = UPNPDISCOVER_SUCCESS;
+
+#if (MINIUPNPC_API_VERSION >= 14)
+               m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0, 
0, 2, &err);
 #else
-               m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 
0);
+               m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0, 
0, &err);
 #endif
+
+               isError = err != UPNPDISCOVER_SUCCESS;
+#else  // MINIUPNPC_API_VERSION >= 8
+        err = 0;
+        m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0);
+               isError = m_Devlist == NULL;
+#endif // MINIUPNPC_API_VERSION >= 8
                {
-                       // notify satrting thread
+                       // notify starting thread
                        std::unique_lock<std::mutex> l(m_StartedMutex);
                        m_Started.notify_all ();
                }
 
-               int r;
-               r = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, 
m_NetworkAddr, sizeof (m_NetworkAddr));
-               if (r == 1)
+               if (isError)
+               {
+            LogPrint (eLogError, "UPnP: unable to discover Internet Gateway 
Devices: error ", err);
+                       return;
+               }
+
+               err = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, 
m_NetworkAddr, sizeof (m_NetworkAddr));
+        m_upnpUrlsInitialized=err!=0;
+               if (err == UPNP_IGD_VALID_CONNECTED)
                {
-                       r = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, 
m_upnpData.first.servicetype, m_externalIPAddress);
-                       if(r != UPNPCOMMAND_SUCCESS)
+            err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, 
m_upnpData.first.servicetype, m_externalIPAddress);
+                       if(err != UPNPCOMMAND_SUCCESS)
                        {
-                               LogPrint (eLogError, "UPnP: 
UPNP_GetExternalIPAddress() returned ", r);
+                               LogPrint (eLogError, "UPnP: unable to get 
external address: error ", err);
                                return;
                        }
                        else
                        {
+                               LogPrint (eLogError, "UPnP: found Internet 
Gateway Device ", m_upnpUrls.controlURL);
                                if (!m_externalIPAddress[0])
                                {
-                                       LogPrint (eLogError, "UPnP: 
GetExternalIPAddress() failed.");
+                    LogPrint (eLogError, "UPnP: found Internet Gateway Device 
doesn't know our external address");
                                        return;
                                }
                        }
                }
                else
                {
-                       LogPrint (eLogError, "UPnP: GetValidIGD() failed.");
+            LogPrint (eLogError, "UPnP: unable to find valid Internet Gateway 
Device: error ", err);
                        return;
                }
 
@@ -126,6 +142,20 @@
                PortMapping ();
        }
 
+       int UPnP::CheckMapping (const char* port, const char* type)
+       {
+               int err = UPNPCOMMAND_SUCCESS;
+
+#if (MINIUPNPC_API_VERSION >= 10)
+               err = UPNP_GetSpecificPortMappingEntry(m_upnpUrls.controlURL, 
m_upnpData.first.servicetype, port, type, NULL, NULL, NULL, NULL, NULL, NULL);
+#elif ((MINIUPNPC_API_VERSION >= 8) || defined (UPNPDISCOVER_SUCCESS))
+               err = UPNP_GetSpecificPortMappingEntry(m_upnpUrls.controlURL, 
m_upnpData.first.servicetype, port, type, NULL, NULL, NULL, NULL, NULL);
+#else
+               err = UPNP_GetSpecificPortMappingEntry(m_upnpUrls.controlURL, 
m_upnpData.first.servicetype, port, type, NULL, NULL);
+#endif
+               return err;
+       }
+
        void UPnP::PortMapping ()
        {
                const auto& a = context.GetRouterInfo().GetAddresses();
@@ -134,72 +164,95 @@
                        if (!address->host.is_v6 () && address->port)
                                TryPortMapping (address);
                }
-               m_Timer.expires_from_now (boost::posix_time::minutes(20));      
// every 20 minutes
+               m_Timer.expires_from_now (boost::posix_time::minutes(20)); // 
every 20 minutes
                m_Timer.async_wait ([this](const boost::system::error_code& 
ecode)
                {
                        if (ecode != boost::asio::error::operation_aborted)
                        PortMapping ();
                });
-
-       }
-
-       void UPnP::CloseMapping ()
-       {
-               const auto& a = context.GetRouterInfo().GetAddresses();
-               for (const auto& address : a)
-               {
-                       if (!address->host.is_v6 () && address->port)
-                       CloseMapping (address);
-               }
        }
 
        void UPnP::TryPortMapping 
(std::shared_ptr<i2p::data::RouterInfo::Address> address)
        {
                std::string strType (GetProto (address)), strPort 
(std::to_string (address->port));
-               int r;
                std::string strDesc; i2p::config::GetOption("upnp.name", 
strDesc);
-#ifdef UPNPDISCOVER_SUCCESS
-               r = UPNP_AddPortMapping (m_upnpUrls.controlURL, 
m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), 
m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0, "0");
+               int err = UPNPCOMMAND_SUCCESS;
+
+               // check for existing mapping
+               err = CheckMapping (strPort.c_str (), strType.c_str ());
+               if (err != UPNPCOMMAND_SUCCESS) // if mapping not found
+               {
+            LogPrint (eLogDebug, "UPnP: possibly port ", strPort, " is not 
forwarded: return code ", err);
+
+#if ((MINIUPNPC_API_VERSION >= 8) || defined (UPNPDISCOVER_SUCCESS))
+                       err = UPNP_AddPortMapping (m_upnpUrls.controlURL, 
m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), 
m_NetworkAddr, strDesc.c_str (), strType.c_str (), NULL, NULL);
 #else
-               r = UPNP_AddPortMapping (m_upnpUrls.controlURL, 
m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), 
m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0);
+                       err = UPNP_AddPortMapping (m_upnpUrls.controlURL, 
m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), 
m_NetworkAddr, strDesc.c_str (), strType.c_str (), NULL);
 #endif
-               if (r!=UPNPCOMMAND_SUCCESS)
-               {
-                       LogPrint (eLogError, "UPnP: AddPortMapping (", 
m_NetworkAddr, ":", strPort, ") failed with code ", r);
-                       return;
+                       if (err != UPNPCOMMAND_SUCCESS)
+                       {
+                               LogPrint (eLogError, "UPnP: port forwarding to 
", m_NetworkAddr, ":", strPort, " failed: return code ", err);
+                               return;
+                       }
+                       else
+                       {
+                               LogPrint (eLogInfo, "UPnP: port successfully 
forwarded (", m_externalIPAddress ,":", strPort, " type ", strType, " -> ", 
m_NetworkAddr ,":", strPort ,")");
+                               return;
+                       }
                }
                else
                {
-                       LogPrint (eLogDebug, "UPnP: Port Mapping successful. 
(", m_NetworkAddr ,":", strPort, " type ", strType, " -> ", m_externalIPAddress 
,":", strPort ,")");
+            LogPrint (eLogDebug, "UPnP: external forward from ", 
m_NetworkAddr, ":", strPort, " exists on current Internet Gateway Device");
                        return;
                }
        }
 
+       void UPnP::CloseMapping ()
+       {
+               const auto& a = context.GetRouterInfo().GetAddresses();
+               for (const auto& address : a)
+               {
+                       if (!address->host.is_v6 () && address->port)
+                       CloseMapping (address);
+               }
+       }
+
        void UPnP::CloseMapping 
(std::shared_ptr<i2p::data::RouterInfo::Address> address)
        {
+        if(!m_upnpUrlsInitialized) {
+            return;
+        }
                std::string strType (GetProto (address)), strPort 
(std::to_string (address->port));
-               int r = 0;
-               r = UPNP_DeletePortMapping (m_upnpUrls.controlURL, 
m_upnpData.first.servicetype, strPort.c_str (), strType.c_str (), 0);
-               LogPrint (eLogError, "UPnP: DeletePortMapping() returned : ", 
r);
+               int err = UPNPCOMMAND_SUCCESS;
+               
+               err = CheckMapping (strPort.c_str (), strType.c_str ());
+        if (err == UPNPCOMMAND_SUCCESS)
+               {
+                       err = UPNP_DeletePortMapping (m_upnpUrls.controlURL, 
m_upnpData.first.servicetype, strPort.c_str (), strType.c_str (), NULL);
+                       LogPrint (eLogError, "UPnP: DeletePortMapping() 
returned : ", err);
+               }
        }
 
        void UPnP::Close ()
        {
                freeUPNPDevlist (m_Devlist);
                m_Devlist = 0;
-               FreeUPNPUrls (&m_upnpUrls);
-       }
+        if(m_upnpUrlsInitialized){
+            FreeUPNPUrls (&m_upnpUrls);
+            m_upnpUrlsInitialized=false;
+        }
+    }
 
        std::string UPnP::GetProto 
(std::shared_ptr<i2p::data::RouterInfo::Address> address)
        {
                switch (address->transportStyle)
                {
                        case i2p::data::RouterInfo::eTransportNTCP:
-                       return "TCP";
-                       break;
+                               return "TCP";
+                               break;
                        case i2p::data::RouterInfo::eTransportSSU:
                        default:
-                       return "UDP";
+                               return "UDP";
                }
        }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/daemon/UPnP.h 
new/i2pd-2.29.0/daemon/UPnP.h
--- old/i2pd-2.28.0/daemon/UPnP.h       2019-08-27 16:17:32.000000000 +0200
+++ new/i2pd-2.29.0/daemon/UPnP.h       2019-10-21 18:02:43.000000000 +0200
@@ -19,20 +19,31 @@
 {
 namespace transport
 {
+       const int UPNP_RESPONSE_TIMEOUT = 2000; // in milliseconds
+
+       enum
+       {
+               UPNP_IGD_NONE = 0,
+               UPNP_IGD_VALID_CONNECTED = 1,
+               UPNP_IGD_VALID_NOT_CONNECTED = 2,
+               UPNP_IGD_INVALID = 3
+       };
+
        class UPnP
        {
-       public:
+               public:
 
                UPnP ();
                ~UPnP ();
-        void Close ();
+               void Close ();
 
-        void Start ();
-        void Stop ();
+               void Start ();
+               void Stop ();
 
-       private:
+               private:
 
                void Discover ();
+               int  CheckMapping (const char* port, const char* type);
                void PortMapping ();
                void TryPortMapping 
(std::shared_ptr<i2p::data::RouterInfo::Address> address);
                void CloseMapping ();
@@ -41,23 +52,22 @@
                void Run ();
                std::string GetProto 
(std::shared_ptr<i2p::data::RouterInfo::Address> address);
 
-       private:
+               private:
 
                bool m_IsRunning;
-        std::unique_ptr<std::thread> m_Thread;
+               std::unique_ptr<std::thread> m_Thread;
                std::condition_variable m_Started;
                std::mutex m_StartedMutex;
                boost::asio::io_service m_Service;
                boost::asio::deadline_timer m_Timer;
-        struct UPNPUrls m_upnpUrls;
-        struct IGDdatas m_upnpData;
-
-        // For miniupnpc
-        char * m_MulticastIf = 0;
-        char * m_Minissdpdpath = 0;
-        struct UPNPDev * m_Devlist = 0;
-        char m_NetworkAddr[64];
-        char m_externalIPAddress[40];
+        bool m_upnpUrlsInitialized=false;
+               struct UPNPUrls m_upnpUrls;
+               struct IGDdatas m_upnpData;
+
+               // For miniupnpc
+               struct UPNPDev * m_Devlist = 0;
+               char m_NetworkAddr[64];
+               char m_externalIPAddress[40];
        };
 }
 }
@@ -65,14 +75,15 @@
 #else  // USE_UPNP
 namespace i2p {
 namespace transport {
-  /* class stub */
-  class UPnP {
-  public:
-    UPnP () {};
-    ~UPnP () {};
-    void Start () { LogPrint(eLogWarning, "UPnP: this module was disabled at 
compile-time"); }
-    void Stop () {};
-  };
+       /* class stub */
+       class UPnP {
+               public:
+
+               UPnP () {};
+               ~UPnP () {};
+               void Start () { LogPrint(eLogWarning, "UPnP: this module was 
disabled at compile-time"); }
+               void Stop () {};
+       };
 }
 }
 #endif // USE_UPNP
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/debian/changelog 
new/i2pd-2.29.0/debian/changelog
--- old/i2pd-2.28.0/debian/changelog    2019-08-27 16:17:32.000000000 +0200
+++ new/i2pd-2.29.0/debian/changelog    2019-10-21 18:02:43.000000000 +0200
@@ -1,3 +1,9 @@
+i2pd (2.29.0-1) unstable; urgency=medium
+
+  * updated to version 2.29.0/0.9.43
+
+ -- orignal <orig...@i2pmail.org>  Mon, 21 Oct 2019 16:00:00 +0000
+
 i2pd (2.28.0-1) unstable; urgency=medium
 
   * updated to version 2.28.0/0.9.42
@@ -48,7 +54,7 @@
 
   * updated to version 2.21.1
 
- -- orignal <orig...@i2pmail.org>  Thu, 22 Oct 2018 16:00:00 +0000
+ -- orignal <orig...@i2pmail.org>  Mon, 22 Oct 2018 16:00:00 +0000
 
 i2pd (2.21.0-1) unstable; urgency=medium
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/libi2pd/Blinding.cpp 
new/i2pd-2.29.0/libi2pd/Blinding.cpp
--- old/i2pd-2.28.0/libi2pd/Blinding.cpp        2019-08-27 16:17:32.000000000 
+0200
+++ new/i2pd-2.29.0/libi2pd/Blinding.cpp        2019-10-21 18:02:43.000000000 
+0200
@@ -124,8 +124,14 @@
                return publicKeyLength;
        }
 
+//----------------------------------------------------------
 
-       BlindedPublicKey::BlindedPublicKey (std::shared_ptr<const IdentityEx> 
identity)
+       const uint8_t B33_TWO_BYTES_SIGTYPE_FLAG = 0x01;
+       const uint8_t B33_PER_SECRET_FLAG = 0x02; // not used for now   
+       const uint8_t B33_PER_CLIENT_AUTH_FLAG = 0x04;
+
+       BlindedPublicKey::BlindedPublicKey (std::shared_ptr<const IdentityEx> 
identity, bool clientAuth):
+               m_IsClientAuth (clientAuth)
        {
                if (!identity) return;
                auto len = identity->GetSigningPublicKeyLen ();
@@ -135,7 +141,8 @@
                m_BlindedSigType = m_SigType;   
        }
 
-       BlindedPublicKey::BlindedPublicKey (const std::string& b33)
+       BlindedPublicKey::BlindedPublicKey (const std::string& b33):
+               m_SigType (0) // 0 means invalid, we can't blind DSA, set it 
later
        {
                uint8_t addr[40]; // TODO: define length from b33
                size_t l = i2p::data::Base32ToByteStream (b33.c_str (), 
b33.length (), addr, 40);
@@ -147,9 +154,9 @@
                uint32_t checksum = crc32 (0, addr + 3, l - 3); 
                // checksum is Little Endian
                addr[0] ^= checksum; addr[1] ^= (checksum >> 8); addr[2] ^= 
(checksum >> 16);  
-               uint8_t flag = addr[0];
+               uint8_t flags = addr[0];
                size_t offset = 1;      
-               if (flag & 0x01) // two bytes signatures
+               if (flags & B33_TWO_BYTES_SIGTYPE_FLAG) // two bytes signatures
                {
                        m_SigType = bufbe16toh (addr + offset); offset += 2;
                        m_BlindedSigType = bufbe16toh (addr + offset); offset 
+= 2;
@@ -159,6 +166,8 @@
                        m_SigType = addr[offset]; offset++;
                        m_BlindedSigType = addr[offset]; offset++;
                }
+               m_IsClientAuth = flags & B33_PER_CLIENT_AUTH_FLAG;
+
                std::unique_ptr<i2p::crypto::Verifier> blindedVerifier 
(i2p::data::IdentityEx::CreateVerifier (m_SigType));
                if (blindedVerifier)
                {
@@ -179,7 +188,9 @@
        {
                if (m_PublicKey.size () > 32) return ""; // assume 25519
                uint8_t addr[35]; char str[60]; // TODO: define actual length
-               addr[0] = 0; // flags
+               uint8_t flags = 0;
+               if (m_IsClientAuth) flags |= B33_PER_CLIENT_AUTH_FLAG;          
+               addr[0] = flags; // flags
                addr[1] = m_SigType; // sig type
                addr[2] = m_BlindedSigType; // blinded sig type
                memcpy (addr + 3, m_PublicKey.data (), m_PublicKey.size ());
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/libi2pd/Blinding.h 
new/i2pd-2.29.0/libi2pd/Blinding.h
--- old/i2pd-2.28.0/libi2pd/Blinding.h  2019-08-27 16:17:32.000000000 +0200
+++ new/i2pd-2.29.0/libi2pd/Blinding.h  2019-10-21 18:02:43.000000000 +0200
@@ -14,7 +14,7 @@
        {
                public:
 
-                       BlindedPublicKey (std::shared_ptr<const IdentityEx> 
identity);
+                       BlindedPublicKey (std::shared_ptr<const IdentityEx> 
identity, bool clientAuth = false);
                        BlindedPublicKey (const std::string& b33); // from b33 
without .b32.i2p                 
                        std::string ToB33 () const;
 
@@ -22,6 +22,7 @@
                        size_t GetPublicKeyLen () const { return 
m_PublicKey.size (); };
                        SigningKeyType GetSigType () const  { return m_SigType; 
};
                        SigningKeyType GetBlindedSigType () const  { return 
m_BlindedSigType; };
+                       bool IsValid () const { return GetSigType (); }; // 
signature type 0 means invalid
 
                        void GetSubcredential (const uint8_t * blinded, size_t 
len, uint8_t * subcredential) const; // 32 bytes
                        size_t GetBlindedKey (const char * date, uint8_t * 
blindedKey) const; // date is 8 chars "YYYYMMDD", return public key length  
@@ -38,6 +39,7 @@
 
                        std::vector<uint8_t> m_PublicKey;
                        i2p::data::SigningKeyType m_SigType, m_BlindedSigType;
+                       bool m_IsClientAuth = false;
        };
 }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/libi2pd/Destination.cpp 
new/i2pd-2.29.0/libi2pd/Destination.cpp
--- old/i2pd-2.28.0/libi2pd/Destination.cpp     2019-08-27 16:17:32.000000000 
+0200
+++ new/i2pd-2.29.0/libi2pd/Destination.cpp     2019-10-21 18:02:43.000000000 
+0200
@@ -17,7 +17,7 @@
                m_IsRunning (false), m_Thread (nullptr), m_IsPublic (isPublic),
                m_PublishReplyToken (0), m_LastSubmissionTime (0), 
m_PublishConfirmationTimer (m_Service),
                m_PublishVerificationTimer (m_Service), m_PublishDelayTimer 
(m_Service), m_CleanupTimer (m_Service),
-               m_LeaseSetType (DEFAULT_LEASESET_TYPE)
+               m_LeaseSetType (DEFAULT_LEASESET_TYPE), m_AuthType 
(i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE)
        {
                int inLen   = DEFAULT_INBOUND_TUNNEL_LENGTH;
                int inQty   = DEFAULT_INBOUND_TUNNELS_QUANTITY;
@@ -70,6 +70,19 @@
                                it = params->find (I2CP_PARAM_LEASESET_TYPE);
                                if (it != params->end ())
                                        m_LeaseSetType = std::stoi(it->second);
+                               if (m_LeaseSetType == 
i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2)
+                               {
+                                       // authentication for encrypted LeaseSet
+                                       it = params->find 
(I2CP_PARAM_LEASESET_AUTH_TYPE);
+                                       if (it != params->end ())
+                                       {
+                                               auto authType = std::stoi 
(it->second);
+                                               if (authType >= 
i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE && authType <= 
i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK)
+                                                       m_AuthType = authType;
+                                               else
+                                                       LogPrint (eLogError, 
"Destination: Unknown auth type ", authType);
+                                       }
+                               }
                                it = params->find 
(I2CP_PARAM_LEASESET_PRIV_KEY);
                                if (it != params->end ())
                                {
@@ -846,7 +859,7 @@
        ClientDestination::ClientDestination (const i2p::data::PrivateKeys& 
keys, bool isPublic, const std::map<std::string, std::string> * params):
                LeaseSetDestination (isPublic, params), m_Keys (keys), 
m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY),
                m_DatagramDestination (nullptr), m_RefCounter (0),
-               m_ReadyChecker(GetService()), m_AuthType 
(i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE)
+               m_ReadyChecker(GetService())
        {
                if (keys.IsOfflineSignature () && GetLeaseSetType () == 
i2p::data::NETDB_STORE_TYPE_LEASESET)
                        SetLeaseSetType 
(i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2); // offline keys can be 
published with LS2 only
@@ -880,25 +893,21 @@
                                if (GetLeaseSetType () == 
i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2)
                                {
                                        // authentication for encrypted LeaseSet
-                                       it = params->find 
(I2CP_PARAM_LEASESET_AUTH_TYPE);
-                                       m_AuthType = std::stoi (it->second);
-                                       if (m_AuthType > 0)
+                                       auto authType = GetAuthType ();
+                                       if (authType > 0)
                                        {
                                                m_AuthKeys = 
std::make_shared<std::vector<i2p::data::AuthPublicKey> >();
-                                               if (m_AuthType == 
i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_DH)
+                                               if (authType == 
i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_DH)
                                                        ReadAuthKey 
(I2CP_PARAM_LEASESET_CLIENT_DH, params);    
-                                               else if (m_AuthType == 
i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK)
+                                               else if (authType == 
i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK)
                                                        ReadAuthKey 
(I2CP_PARAM_LEASESET_CLIENT_PSK, params);   
                                                else
-                                               {
-                                                       LogPrint (eLogError, 
"Destination: Unexpected auth type ", m_AuthType);
-                                                       m_AuthType = 0;
-                                               }
+                                                       LogPrint (eLogError, 
"Destination: Unexpected auth type ", authType);
                                                if (m_AuthKeys->size ())
                                                        LogPrint (eLogInfo, 
"Destination: ", m_AuthKeys->size (), " auth keys read");
                                                else
                                                {
-                                                       LogPrint (eLogError, 
"Destination: No auth keys read for auth type ", m_AuthType);
+                                                       LogPrint (eLogError, 
"Destination: No auth keys read for auth type ", authType);
                                                        m_AuthKeys = nullptr;   
                                                }
                                        }
@@ -1184,7 +1193,7 @@
                        auto ls2 = std::make_shared<i2p::data::LocalLeaseSet2> 
(i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2,
                                m_Keys, m_EncryptionKeyType, keyLen, 
m_EncryptionPublicKey, tunnels, IsPublic (), isPublishedEncrypted);
                        if (isPublishedEncrypted) // encrypt if type 5
-                               ls2 = 
std::make_shared<i2p::data::LocalEncryptedLeaseSet2> (ls2, m_Keys, m_AuthType, 
m_AuthKeys);
+                               ls2 = 
std::make_shared<i2p::data::LocalEncryptedLeaseSet2> (ls2, m_Keys, GetAuthType 
(), m_AuthKeys);
                        leaseSet = ls2;
                }
                SetLeaseSet (leaseSet);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/libi2pd/Destination.h 
new/i2pd-2.29.0/libi2pd/Destination.h
--- old/i2pd-2.28.0/libi2pd/Destination.h       2019-08-27 16:17:32.000000000 
+0200
+++ new/i2pd-2.29.0/libi2pd/Destination.h       2019-10-21 18:02:43.000000000 
+0200
@@ -134,6 +134,7 @@
                        void SetLeaseSet (std::shared_ptr<const 
i2p::data::LocalLeaseSet> newLeaseSet);
                        int GetLeaseSetType () const { return m_LeaseSetType; };
                        void SetLeaseSetType (int leaseSetType) { 
m_LeaseSetType = leaseSetType; };
+                       int GetAuthType () const { return m_AuthType; };
                        bool IsPublic () const { return m_IsPublic; };
                        virtual void CleanupDestination () {}; // additional 
clean up in derived classes
                        // I2CP
@@ -179,7 +180,7 @@
                        boost::asio::deadline_timer m_PublishConfirmationTimer, 
m_PublishVerificationTimer,
                                m_PublishDelayTimer, m_CleanupTimer;
                        std::string m_Nickname;
-                       int m_LeaseSetType;
+                       int m_LeaseSetType, m_AuthType;
                        std::unique_ptr<i2p::data::Tag<32> > m_LeaseSetPrivKey; 
// non-null if presented
 
                public:
@@ -188,6 +189,7 @@
                        int GetNumRemoteLeaseSets () const { return 
m_RemoteLeaseSets.size (); };
                        const decltype(m_RemoteLeaseSets)& GetLeaseSets () 
const { return m_RemoteLeaseSets; };
                        bool IsEncryptedLeaseSet () const { return 
m_LeaseSetType == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2; };
+                       bool IsPerClientAuth () const { return m_AuthType > 0; 
};
        };
 
        class ClientDestination: public LeaseSetDestination
@@ -270,8 +272,7 @@
 
                        boost::asio::deadline_timer m_ReadyChecker;
 
-                       int m_AuthType;
-                       std::shared_ptr<std::vector<i2p::data::AuthPublicKey> > 
m_AuthKeys;  
+                       std::shared_ptr<std::vector<i2p::data::AuthPublicKey> > 
m_AuthKeys; // we don't need them for I2CP  
 
                public:
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/libi2pd/NTCP2.cpp 
new/i2pd-2.29.0/libi2pd/NTCP2.cpp
--- old/i2pd-2.28.0/libi2pd/NTCP2.cpp   2019-08-27 16:17:32.000000000 +0200
+++ new/i2pd-2.29.0/libi2pd/NTCP2.cpp   2019-10-21 18:02:43.000000000 +0200
@@ -602,20 +602,29 @@
 
        void NTCP2Session::HandleSessionConfirmedSent (const 
boost::system::error_code& ecode, std::size_t bytes_transferred)
        {
-               LogPrint (eLogDebug, "NTCP2: SessionConfirmed sent");
-               KeyDerivationFunctionDataPhase ();
-               // Alice data phase keys
-               m_SendKey = m_Kab;
-               m_ReceiveKey = m_Kba; 
-               SetSipKeys (m_Sipkeysab, m_Sipkeysba);
-               memcpy (m_ReceiveIV.buf, m_Sipkeysba + 16, 8);
-               memcpy (m_SendIV.buf, m_Sipkeysab + 16, 8);
-               Established ();
-               ReceiveLength ();
-
-               // TODO: remove
-               // m_SendQueue.push_back (CreateDeliveryStatusMsg (1));
-               // SendQueue ();
+               (void) bytes_transferred;
+               if (ecode)
+               {
+                       LogPrint (eLogWarning, "NTCP2: couldn't send 
SessionConfirmed message: ", ecode.message ());
+                       Terminate ();
+               }
+               else
+               {       
+                       LogPrint (eLogDebug, "NTCP2: SessionConfirmed sent");
+                       KeyDerivationFunctionDataPhase ();
+                       // Alice data phase keys
+                       m_SendKey = m_Kab;
+                       m_ReceiveKey = m_Kba; 
+                       SetSipKeys (m_Sipkeysab, m_Sipkeysba);
+                       memcpy (m_ReceiveIV.buf, m_Sipkeysba + 16, 8);
+                       memcpy (m_SendIV.buf, m_Sipkeysab + 16, 8);
+                       Established ();
+                       ReceiveLength ();
+
+                       // TODO: remove
+                       // m_SendQueue.push_back (CreateDeliveryStatusMsg (1));
+                       // SendQueue ();
+               }               
        }
 
        void NTCP2Session::HandleSessionCreatedSent (const 
boost::system::error_code& ecode, std::size_t bytes_transferred)
@@ -710,7 +719,7 @@
                                        // ready to communicate 
                                        auto existing = 
i2p::data::netdb.FindRouter (ri.GetRouterIdentity ()->GetIdentHash ()); // 
check if exists already
                                        SetRemoteIdentity (existing ? 
existing->GetRouterIdentity () : ri.GetRouterIdentity ());
-                                       m_Server.AddNTCP2Session 
(shared_from_this ());
+                                       m_Server.AddNTCP2Session 
(shared_from_this (), true);
                                        Established ();
                                        ReceiveLength ();
                                }
@@ -1249,7 +1258,7 @@
                }
        }
 
-       bool NTCP2Server::AddNTCP2Session (std::shared_ptr<NTCP2Session> 
session)
+       bool NTCP2Server::AddNTCP2Session (std::shared_ptr<NTCP2Session> 
session, bool incoming)
        {
                if (!session || !session->GetRemoteIdentity ()) return false;
                auto& ident = session->GetRemoteIdentity ()->GetIdentHash ();
@@ -1261,6 +1270,8 @@
                        return false;
                }
                m_NTCP2Sessions.insert (std::make_pair (ident, session));
+               if (incoming)   
+                       m_PendingIncomingSessions.remove (session);
                return true;
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/libi2pd/NTCP2.h 
new/i2pd-2.29.0/libi2pd/NTCP2.h
--- old/i2pd-2.28.0/libi2pd/NTCP2.h     2019-08-27 16:17:32.000000000 +0200
+++ new/i2pd-2.29.0/libi2pd/NTCP2.h     2019-10-21 18:02:43.000000000 +0200
@@ -227,7 +227,7 @@
                        void Start ();
                        void Stop ();
 
-                       bool AddNTCP2Session (std::shared_ptr<NTCP2Session> 
session);
+                       bool AddNTCP2Session (std::shared_ptr<NTCP2Session> 
session, bool incoming = false);
                        void RemoveNTCP2Session (std::shared_ptr<NTCP2Session> 
session);
                        std::shared_ptr<NTCP2Session> FindNTCP2Session (const 
i2p::data::IdentHash& ident);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/libi2pd/RouterContext.cpp 
new/i2pd-2.29.0/libi2pd/RouterContext.cpp
--- old/i2pd-2.28.0/libi2pd/RouterContext.cpp   2019-08-27 16:17:32.000000000 
+0200
+++ new/i2pd-2.29.0/libi2pd/RouterContext.cpp   2019-10-21 18:02:43.000000000 
+0200
@@ -27,7 +27,12 @@
        void RouterContext::Init ()
        {
                srand (i2p::util::GetMillisecondsSinceEpoch () % 1000);
+#ifdef WIN32
+               // for compatibility with WinXP
+               m_StartupTime = i2p::util::GetSecondsSinceEpoch ();     
+#else
                m_StartupTime = std::chrono::steady_clock::now();
+#endif
                if (!Load ())
                        CreateNewRouter ();
                m_Decryptor = m_Keys.CreateDecryptor (nullptr);
@@ -716,7 +721,12 @@
 
        uint32_t RouterContext::GetUptime () const
        {
+#ifdef WIN32
+               // for compatibility with WinXP
+               return i2p::util::GetSecondsSinceEpoch () - m_StartupTime;
+#else
                return std::chrono::duration_cast<std::chrono::seconds> 
(std::chrono::steady_clock::now() - m_StartupTime).count ();
+#endif
        }
 
        bool RouterContext::Decrypt (const uint8_t * encrypted, uint8_t * data, 
BN_CTX * ctx) const
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/libi2pd/RouterContext.h 
new/i2pd-2.29.0/libi2pd/RouterContext.h
--- old/i2pd-2.28.0/libi2pd/RouterContext.h     2019-08-27 16:17:32.000000000 
+0200
+++ new/i2pd-2.29.0/libi2pd/RouterContext.h     2019-10-21 18:02:43.000000000 
+0200
@@ -137,7 +137,11 @@
                        std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> 
m_Decryptor;
                        uint64_t m_LastUpdateTime; // in seconds
                        bool m_AcceptsTunnels, m_IsFloodfill;
+#ifdef WIN32
+                       uint64_t m_StartupTime = 0; // in seconds since epoch
+#else                  
                        std::chrono::time_point<std::chrono::steady_clock> 
m_StartupTime;
+#endif
                        uint64_t m_BandwidthLimit; // allowed bandwidth
                        int m_ShareRatio;
                        RouterStatus m_Status;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/libi2pd/Transports.cpp 
new/i2pd-2.29.0/libi2pd/Transports.cpp
--- old/i2pd-2.28.0/libi2pd/Transports.cpp      2019-08-27 16:17:32.000000000 
+0200
+++ new/i2pd-2.29.0/libi2pd/Transports.cpp      2019-10-21 18:02:43.000000000 
+0200
@@ -503,28 +503,6 @@
                        }
                }
        }
-       
-       void Transports::CloseSession (std::shared_ptr<const 
i2p::data::RouterInfo> router)
-       {
-               if (!router) return;
-               m_Service->post (std::bind (&Transports::PostCloseSession, 
this, router));
-       }
-
-       void Transports::PostCloseSession (std::shared_ptr<const 
i2p::data::RouterInfo> router)
-       {
-               auto ssuSession = m_SSUServer ? m_SSUServer->FindSession 
(router) : nullptr;
-               if (ssuSession) // try SSU first
-               {
-                       m_SSUServer->DeleteSession (ssuSession);
-                       LogPrint (eLogDebug, "Transports: SSU session closed");
-               }
-               auto ntcpSession = m_NTCPServer ? 
m_NTCPServer->FindNTCPSession(router->GetIdentHash()) : nullptr;
-               if (ntcpSession) // try deleting ntcp session too
-               {
-                       ntcpSession->Terminate ();
-                       LogPrint(eLogDebug, "Transports: NTCP session closed");
-               }
-       }
 
        void Transports::DetectExternalIP ()
        {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/libi2pd/Transports.h 
new/i2pd-2.29.0/libi2pd/Transports.h
--- old/i2pd-2.28.0/libi2pd/Transports.h        2019-08-27 16:17:32.000000000 
+0200
+++ new/i2pd-2.29.0/libi2pd/Transports.h        2019-10-21 18:02:43.000000000 
+0200
@@ -92,7 +92,6 @@
 
                        void SendMessage (const i2p::data::IdentHash& ident, 
std::shared_ptr<i2p::I2NPMessage> msg);
                        void SendMessages (const i2p::data::IdentHash& ident, 
const std::vector<std::shared_ptr<i2p::I2NPMessage> >& msgs);
-                       void CloseSession (std::shared_ptr<const 
i2p::data::RouterInfo> router);
 
                        void PeerConnected (std::shared_ptr<TransportSession> 
session);
                        void PeerDisconnected 
(std::shared_ptr<TransportSession> session);
@@ -131,7 +130,6 @@
                        void RequestComplete (std::shared_ptr<const 
i2p::data::RouterInfo> r, const i2p::data::IdentHash& ident);
                        void HandleRequestComplete (std::shared_ptr<const 
i2p::data::RouterInfo> r, i2p::data::IdentHash ident);
                        void PostMessages (i2p::data::IdentHash ident, 
std::vector<std::shared_ptr<i2p::I2NPMessage> > msgs);
-                       void PostCloseSession (std::shared_ptr<const 
i2p::data::RouterInfo> router);
                        bool ConnectToPeer (const i2p::data::IdentHash& ident, 
Peer& peer);
                        void HandlePeerCleanupTimer (const 
boost::system::error_code& ecode);
                        void HandlePeerTestTimer (const 
boost::system::error_code& ecode);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/libi2pd/version.h 
new/i2pd-2.29.0/libi2pd/version.h
--- old/i2pd-2.28.0/libi2pd/version.h   2019-08-27 16:17:32.000000000 +0200
+++ new/i2pd-2.29.0/libi2pd/version.h   2019-10-21 18:02:43.000000000 +0200
@@ -7,7 +7,7 @@
 #define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c)
 
 #define I2PD_VERSION_MAJOR 2
-#define I2PD_VERSION_MINOR 28
+#define I2PD_VERSION_MINOR 29
 #define I2PD_VERSION_MICRO 0
 #define I2PD_VERSION_PATCH 0
 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, 
I2PD_VERSION_MICRO)
@@ -21,7 +21,7 @@
 
 #define I2P_VERSION_MAJOR 0
 #define I2P_VERSION_MINOR 9
-#define I2P_VERSION_MICRO 42
+#define I2P_VERSION_MICRO 43
 #define I2P_VERSION_PATCH 0
 #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, 
I2P_VERSION_MICRO)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/libi2pd_client/AddressBook.cpp 
new/i2pd-2.29.0/libi2pd_client/AddressBook.cpp
--- old/i2pd-2.28.0/libi2pd_client/AddressBook.cpp      2019-08-27 
16:17:32.000000000 +0200
+++ new/i2pd-2.29.0/libi2pd_client/AddressBook.cpp      2019-10-21 
18:02:43.000000000 +0200
@@ -237,17 +237,19 @@
 
 //---------------------------------------------------------------------
 
-       Address::Address (const std::string& b32)
+       Address::Address (const std::string& b32):
+               addressType (eAddressInvalid)
        {
                if (b32.length () <= B33_ADDRESS_THRESHOLD)
                {
-                       addressType = eAddressIndentHash;
-                       identHash.FromBase32 (b32);
+                       if (identHash.FromBase32 (b32) > 0)
+                               addressType = eAddressIndentHash;
                }
                else
                {
-                       addressType = eAddressBlindedPublicKey;
                        blindedPublicKey = 
std::make_shared<i2p::data::BlindedPublicKey>(b32);
+                       if (blindedPublicKey->IsValid ())
+                               addressType = eAddressBlindedPublicKey;
                }
        }       
 
@@ -320,7 +322,10 @@
        {
                auto pos = address.find(".b32.i2p");
                if (pos != std::string::npos)
-                       return std::make_shared<const Address>(address.substr 
(0, pos));
+               {                       
+                       auto addr = std::make_shared<const 
Address>(address.substr (0, pos));
+                       return addr->IsValid () ? addr : nullptr;
+               }
                else
                {
                        pos = address.find (".i2p");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/libi2pd_client/AddressBook.h 
new/i2pd-2.29.0/libi2pd_client/AddressBook.h
--- old/i2pd-2.28.0/libi2pd_client/AddressBook.h        2019-08-27 
16:17:32.000000000 +0200
+++ new/i2pd-2.29.0/libi2pd_client/AddressBook.h        2019-10-21 
18:02:43.000000000 +0200
@@ -33,13 +33,14 @@
 
        struct Address
        {
-               enum { eAddressIndentHash, eAddressBlindedPublicKey } 
addressType;
+               enum { eAddressIndentHash, eAddressBlindedPublicKey, 
eAddressInvalid } addressType;
                i2p::data::IdentHash identHash;
                std::shared_ptr<i2p::data::BlindedPublicKey> blindedPublicKey;
 
                Address (const std::string& b32);       
                Address (const i2p::data::IdentHash& hash);     
                bool IsIdentHash () const { return addressType == 
eAddressIndentHash; };
+               bool IsValid () const { return addressType != eAddressInvalid; 
};
        };
 
        inline std::string GetB32Address(const i2p::data::IdentHash& ident) { 
return ident.ToBase32().append(".b32.i2p"); }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/i2pd-2.28.0/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml 
new/i2pd-2.29.0/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml
--- old/i2pd-2.28.0/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml       
2019-08-27 16:17:32.000000000 +0200
+++ new/i2pd-2.29.0/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml       
2019-10-21 18:02:43.000000000 +0200
@@ -8,19 +8,19 @@
   <name>i2pd</name>
   <summary>Invisible Internet</summary>
   <description>
-        <p>i2pd (I2P Daemon) is a full-featured C++ implementation of I2P 
client.</p>
-        <p>I2P (Invisible Internet Protocol) is a universal anonymous network 
layer. 
-        All communications over I2P are anonymous and end-to-end encrypted, 
participants
-        don't reveal their real IP addresses. </p>
-        <p>I2P allows people from all around the world to communicate and 
share information
-        without restrictions.</p>
-        <p>Features:</p>
-        <ul>
-            <li>Distributed anonymous networking framework</li>
-            <li>End-to-end encrypted communications</li>
-            <li>Small footprint, simple dependencies, fast performance</li>
-            <li>Rich set of APIs for developers of secure applications</li>
-        </ul>
+    <p>i2pd (I2P Daemon) is a full-featured C++ implementation of I2P 
client.</p>
+    <p>I2P (Invisible Internet Protocol) is a universal anonymous network 
layer. 
+    All communications over I2P are anonymous and end-to-end encrypted, 
participants
+    don't reveal their real IP addresses. </p>
+    <p>I2P allows people from all around the world to communicate and share 
information
+    without restrictions.</p>
+    <p>Features:</p>
+    <ul>
+        <li>Distributed anonymous networking framework</li>
+        <li>End-to-end encrypted communications</li>
+        <li>Small footprint, simple dependencies, fast performance</li>
+        <li>Rich set of APIs for developers of secure applications</li>
+    </ul>
   </description>
   <screenshots>
     <screenshot type="default">
@@ -35,15 +35,16 @@
   <translation type="qt" />
 
   <releases>
-      <release version="2.28.0" date="2019-08-27" />           
-      <release version="2.27.0" date="2019-07-03" />
-      <release version="2.26.0" date="2019-06-07" />
-      <release version="2.25.0" date="2019-05-09" />
-      <release version="2.24.0" date="2019-03-21" />   
-      <release version="2.23.0" date="2019-01-21" />
-      <release version="2.22.0" date="2018-11-09" />
-      <release version="2.21.1" date="2018-10-22" />
-      <release version="2.21.0" date="2018-10-04" />
+    <release version="2.29.0" date="2019-10-21" />
+    <release version="2.28.0" date="2019-08-27" />
+    <release version="2.27.0" date="2019-07-03" />
+    <release version="2.26.0" date="2019-06-07" />
+    <release version="2.25.0" date="2019-05-09" />
+    <release version="2.24.0" date="2019-03-21" />
+    <release version="2.23.0" date="2019-01-21" />
+    <release version="2.22.0" date="2018-11-09" />
+    <release version="2.21.1" date="2018-10-22" />
+    <release version="2.21.0" date="2018-10-04" />
   </releases>
   <content_rating type="oars-1.1" />
 </component>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i2pd-2.28.0/qt/i2pd_qt/i2pd_qt.pro 
new/i2pd-2.29.0/qt/i2pd_qt/i2pd_qt.pro
--- old/i2pd-2.28.0/qt/i2pd_qt/i2pd_qt.pro      2019-08-27 16:17:32.000000000 
+0200
+++ new/i2pd-2.29.0/qt/i2pd_qt/i2pd_qt.pro      2019-10-21 18:02:43.000000000 
+0200
@@ -6,11 +6,14 @@
 TEMPLATE = app
 QMAKE_CXXFLAGS *= -std=c++11 -Wno-unused-parameter -Wno-maybe-uninitialized
 
-# For now, disable UPnP which currently crashes on Stop() -- 
https://github.com/PurpleI2P/i2pd/issues/1387
-#DEFINES += USE_UPNP
-DEFINES -= USE_UPNP
+DEFINES += USE_UPNP
 
-debug: DEFINES += DEBUG_WITH_DEFAULT_LOGGING
+CONFIG(debug, debug|release) {
+    message(Debug build)
+    DEFINES += DEBUG_WITH_DEFAULT_LOGGING
+} else {
+    message(Release build)
+}
 
 SOURCES += DaemonQT.cpp mainwindow.cpp \
     ../../libi2pd/api.cpp \


Reply via email to