diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 3539c19b..627b81ae 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,7 +1,7 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) Name: i2pd-git -Version: 2.20.0 +Version: 2.21.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 71bc2b31..2deeecab 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.20.0 +Version: 2.21.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git diff --git a/debian/control b/debian/control index 8ef0b08c..843a153c 100644 --- a/debian/control +++ b/debian/control @@ -1,7 +1,7 @@ Source: i2pd Section: net Priority: optional -Maintainer: R4SAS +Maintainer: r4sas Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.17.2~), gcc (>= 4.7) | clang (>= 3.3), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev Standards-Version: 3.9.6 Homepage: http://i2pd.website/ diff --git a/debian/patches/01-tune-build-opts.patch b/debian/patches/01-tune-build-opts.patch index 2dff9e09..dd2b4638 100644 --- a/debian/patches/01-tune-build-opts.patch +++ b/debian/patches/01-tune-build-opts.patch @@ -13,5 +13,5 @@ index bdadfe0..2f71eec 100644 USE_STATIC := no USE_MESHNET := no USE_UPNP := no - - ifeq ($(WEBSOCKETS),1) + DEBUG := yes + diff --git a/debian/patches/fix-#1210 b/debian/patches/fix-#1210 new file mode 100644 index 00000000..7e68135c --- /dev/null +++ b/debian/patches/fix-#1210 @@ -0,0 +1,25 @@ +Description: fix #1210 + Disables two options, which not presented in old systemd versions +Author: r4sas + +Bug: https://github.com/PurpleI2P/i2pd/issues/1210 +Reviewed-By: r4sas +Last-Update: 2018-08-25 + +--- i2pd-2.20.0.orig/contrib/i2pd.service ++++ i2pd-2.20.0/contrib/i2pd.service +@@ -6,10 +6,10 @@ After=network.target + [Service] + User=i2pd + Group=i2pd +-RuntimeDirectory=i2pd +-RuntimeDirectoryMode=0700 +-LogsDirectory=i2pd +-LogsDirectoryMode=0700 ++#RuntimeDirectory=i2pd ++#RuntimeDirectoryMode=0700 ++#LogsDirectory=i2pd ++#LogsDirectoryMode=0700 + Type=forking + ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --pidfile=/var/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service + ExecReload=/bin/kill -HUP $MAINPID diff --git a/debian/patches/series b/debian/patches/series index 972d2a10..5a9712bd 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1 +1,2 @@ 01-tune-build-opts.patch +fix-#1210 diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index c91bfdb3..7f4d1ca3 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -36,7 +36,7 @@ namespace i2p std::shared_ptr NewI2NPMessage (size_t len) { - return (len < I2NP_MAX_SHORT_MESSAGE_SIZE/2) ? NewI2NPShortMessage () : NewI2NPMessage (); + return (len < I2NP_MAX_SHORT_MESSAGE_SIZE - I2NP_HEADER_SIZE - 2) ? NewI2NPShortMessage () : NewI2NPMessage (); } void I2NPMessage::FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID) diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index deaa2292..15e3a32c 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -106,7 +106,7 @@ namespace tunnel class TunnelPool; } - const size_t I2NP_MAX_MESSAGE_SIZE = 32768; + const size_t I2NP_MAX_MESSAGE_SIZE = 62708; const size_t I2NP_MAX_SHORT_MESSAGE_SIZE = 4096; const unsigned int I2NP_MESSAGE_EXPIRATION_TIMEOUT = 8000; // in milliseconds (as initial RTT) const unsigned int I2NP_MESSAGE_CLOCK_SKEW = 60*1000; // 1 minute in milliseconds diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index ca6dc858..1d60fef5 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -900,6 +900,11 @@ namespace transport case eNTCP2BlkI2NPMessage: { LogPrint (eLogDebug, "NTCP2: I2NP"); + if (size > I2NP_MAX_MESSAGE_SIZE) + { + LogPrint (eLogError, "NTCP2: I2NP block is too long ", size); + break; + } auto nextMsg = NewI2NPMessage (size); nextMsg->len = nextMsg->offset + size + 7; // 7 more bytes for full I2NP header memcpy (nextMsg->GetNTCP2Header (), frame + offset, size); @@ -993,6 +998,11 @@ namespace transport s += len; m_SendQueue.pop_front (); } + else if (len + 3 > NTCP2_UNENCRYPTED_FRAME_MAX_SIZE) + { + LogPrint (eLogError, "NTCP2: I2NP message of size ", len, " can't be sent. Dropped"); + m_SendQueue.pop_front (); + } else break; } @@ -1122,7 +1132,7 @@ namespace transport auto conn = std::make_shared (*this); m_NTCP2V6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAcceptV6, this, conn, std::placeholders::_1)); } catch ( std::exception & ex ) { - LogPrint(eLogError, "NTCP: failed to bind to ip6 port ", address->port); + LogPrint(eLogError, "NTCP2: failed to bind to ip6 port ", address->port); continue; } } diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 0d3c707b..9c1acfcc 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -173,6 +173,7 @@ namespace i2p if (address->IsNTCP2 () && (address->port != port || address->ntcp2->isPublished != publish)) { address->port = port; + address->cost = publish ? 3 : 14; address->ntcp2->isPublished = publish; address->ntcp2->iv = m_NTCP2Keys->iv; updated = true; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index d2bfc7ce..de7cd0be 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -700,7 +700,7 @@ namespace data addr->host = host; addr->port = port; addr->transportStyle = eTransportNTCP; - addr->cost = 3; + addr->cost = port ? 3 : 14; // override from RouterContext::PublishNTCP2Address addr->date = 0; addr->ntcp2.reset (new NTCP2Ext ()); addr->ntcp2->isNTCP2Only = true; // NTCP2 only address diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index d789e70e..3ad5e769 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -320,7 +320,7 @@ namespace transport uint8_t * msgBuf = msg->GetSSUHeader (); uint32_t fragmentNum = 0; - while (len > 0) + while (len > 0 && fragmentNum <= 127) { Fragment * fragment = new Fragment; fragment->fragmentNum = fragmentNum; @@ -332,7 +332,7 @@ namespace transport payload++; htobe32buf (payload, msgID); payload += 4; - bool isLast = (len <= payloadSize); + bool isLast = (len <= payloadSize) || fragmentNum == 127; // 127 fragments max size_t size = isLast ? len : payloadSize; uint32_t fragmentInfo = (fragmentNum << 17); if (isLast) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 2a8cd2d5..255adf42 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -929,7 +929,13 @@ namespace transport if (m_State == eSessionStateEstablished) { for (const auto& it: msgs) - if (it) m_Data.Send (it); + if (it) + { + if (it->GetLength () <= SSU_MAX_I2NP_MESSAGE_SIZE) + m_Data.Send (it); + else + LogPrint (eLogError, "SSU: I2NP message of size ", it->GetLength (), " can't be sent. Dropped"); + } } } diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index 8247c420..7f053d37 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -28,6 +28,7 @@ namespace transport const int SSU_CONNECT_TIMEOUT = 5; // 5 seconds const int SSU_TERMINATION_TIMEOUT = 330; // 5.5 minutes const int SSU_CLOCK_SKEW = 60; // in seconds + const size_t SSU_MAX_I2NP_MESSAGE_SIZE = 32768; // payload types (4 bits) const uint8_t PAYLOAD_TYPE_SESSION_REQUEST = 0; diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index ac2dd853..b7bf6002 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1027,11 +1027,29 @@ namespace client { auto it = params->find (SAM_PARAM_SIGNATURE_TYPE); if (it != params->end ()) + { // TODO: extract string values - signatureType = std::stoi(it->second); + try + { + signatureType = std::stoi(it->second); + } + catch (const std::exception& ex) + { + LogPrint (eLogWarning, "SAM: ", SAM_PARAM_SIGNATURE_TYPE, "error: ", ex.what ()); + } + } it = params->find (SAM_PARAM_CRYPTO_TYPE); if (it != params->end ()) - cryptoType = std::stoi(it->second); + { + try + { + cryptoType = std::stoi(it->second); + } + catch (const std::exception& ex) + { + LogPrint (eLogWarning, "SAM: ", SAM_PARAM_CRYPTO_TYPE, "error: ", ex.what ()); + } + } } localDestination = i2p::client::context.CreateNewLocalDestination (true, signatureType, cryptoType, params); }