From 3ef8b3dcbb55a3b1714eb46f3cd86bec2d53000a Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 24 Jul 2020 20:44:01 -0400 Subject: [PATCH 01/71] don't send repliable datagram after less then 100 milliseconds --- libi2pd_client/I2PTunnel.cpp | 16 ++++++++++++---- libi2pd_client/I2PTunnel.h | 3 ++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 95f56873..3575e062 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -708,9 +708,12 @@ namespace client if(!ecode) { LogPrint(eLogDebug, "UDPSession: forward ", len, "B from ", FromEndpoint); - LastActivity = i2p::util::GetMillisecondsSinceEpoch(); + auto ts = i2p::util::GetMillisecondsSinceEpoch(); auto session = m_Destination->GetSession (Identity); - m_Destination->SendDatagram(session, m_Buffer, len, LocalPort, RemotePort); + if (ts > LastActivity + I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL) + m_Destination->SendDatagram(session, m_Buffer, len, LocalPort, RemotePort); + else + m_Destination->SendRawDatagram(session, m_Buffer, len, LocalPort, RemotePort); size_t numPackets = 0; while (numPackets < i2p::datagram::DATAGRAM_SEND_QUEUE_MAX_SIZE) { @@ -724,6 +727,7 @@ namespace client if (numPackets > 0) LogPrint(eLogDebug, "UDPSession: forward more ", numPackets, "packets B from ", FromEndpoint); m_Destination->FlushSendQueue (session); + LastActivity = ts; Receive(); } else @@ -841,9 +845,13 @@ namespace client m_LastPort = remotePort; } // send off to remote i2p destination + auto ts = i2p::util::GetMillisecondsSinceEpoch(); LogPrint(eLogDebug, "UDP Client: send ", transferred, " to ", m_RemoteIdent->ToBase32(), ":", RemotePort); auto session = m_LocalDest->GetDatagramDestination()->GetSession (*m_RemoteIdent); - m_LocalDest->GetDatagramDestination()->SendDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort); + if (ts > m_LastSession->second + I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL) + m_LocalDest->GetDatagramDestination()->SendDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort); + else + m_LocalDest->GetDatagramDestination()->SendRawDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort); size_t numPackets = 0; while (numPackets < i2p::datagram::DATAGRAM_SEND_QUEUE_MAX_SIZE) { @@ -862,7 +870,7 @@ namespace client // mark convo as active if (m_LastSession) - m_LastSession->second = i2p::util::GetMillisecondsSinceEpoch(); + m_LastSession->second = ts; RecvFromLocal(); } diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index eb1d8ed9..b76a1027 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -165,7 +165,8 @@ namespace client /** 2 minute timeout for udp sessions */ const uint64_t I2P_UDP_SESSION_TIMEOUT = 1000 * 60 * 2; - + const uint64_t I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL = 100; // in milliseconds + /** max size for i2p udp */ const size_t I2P_UDP_MAX_MTU = 64*1024; From c3aa6b9cda922a4c76221c3383287ae60a20a038 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 Jul 2020 17:47:46 -0400 Subject: [PATCH 02/71] use delivery type local if destination is not secified --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 15 +++++++++------ libi2pd/ECIESX25519AEADRatchetSession.h | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index dac5dbe0..51ca9242 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -739,8 +739,11 @@ namespace garlic uint64_t ts = i2p::util::GetMillisecondsSinceEpoch (); size_t payloadLen = 0; if (first) payloadLen += 7;// datatime - if (msg && m_Destination) - payloadLen += msg->GetPayloadLength () + 13 + 32; + if (msg) + { + payloadLen += msg->GetPayloadLength () + 13; + if (m_Destination) payloadLen += 32; + } auto leaseSet = (GetLeaseSetUpdateStatus () == eLeaseSetUpdated || (GetLeaseSetUpdateStatus () == eLeaseSetSubmitted && ts > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT)) ? @@ -816,7 +819,7 @@ namespace garlic } // msg if (msg && m_Destination) - offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset, true); + offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset); // ack if (m_AckRequests.size () > 0) { @@ -875,16 +878,16 @@ namespace garlic return v; } - size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination) + size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len) { if (!msg) return 0; uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; - if (isDestination) cloveSize += 32; + if (m_Destination) cloveSize += 32; if ((int)len < cloveSize + 3) return 0; buf[0] = eECIESx25519BlkGalicClove; // clove type htobe16buf (buf + 1, cloveSize); // size buf += 3; - if (isDestination) + if (m_Destination) { *buf = (eGarlicDeliveryTypeDestination << 5); memcpy (buf + 1, *m_Destination, 32); buf += 32; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index cccb4092..73e129d7 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -171,7 +171,7 @@ namespace garlic bool NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); std::vector CreatePayload (std::shared_ptr msg, bool first); - size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination = false); + size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len); size_t CreateLeaseSetClove (std::shared_ptr ls, uint64_t ts, uint8_t * buf, size_t len); void GenerateMoreReceiveTags (std::shared_ptr receiveTagset, int numTags); From 9636d82b37ff021cd7ee7a7a0d55e89624e4a183 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 3 Aug 2020 18:31:03 -0400 Subject: [PATCH 03/71] MixHash for SessionConfirmed processing --- libi2pd/NTCP2.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index f1f7e59f..4e3b219c 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -338,11 +338,8 @@ namespace transport KDF3Bob (); if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer + 48, m3p2Len - 16, GetH (), 32, GetK (), nonce, m3p2Buf, m3p2Len - 16, false)) // decrypt - { // caclulate new h again for KDF data - memcpy (m_SessionConfirmedBuffer + 16, m_H, 32); // h || ciphertext - SHA256 (m_SessionConfirmedBuffer + 16, m3p2Len + 32, m_H); //h = SHA256(h || ciphertext); - } + MixHash (m_SessionConfirmedBuffer + 48, m3p2Len); // h = SHA256(h || ciphertext) else { LogPrint (eLogWarning, "NTCP2: SessionConfirmed Part2 AEAD verification failed "); From 8e252265744cc8fdb942b90c2b27b8968d45698c Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 8 Aug 2020 13:34:27 -0400 Subject: [PATCH 04/71] use unordered_map for incomplete and sent messages --- libi2pd/SSUData.cpp | 2 +- libi2pd/SSUData.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 5068f006..fde684d0 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -301,7 +301,7 @@ namespace transport void SSUData::Send (std::shared_ptr msg) { uint32_t msgID = msg->ToSSU (); - if (m_SentMessages.count (msgID) > 0) + if (m_SentMessages.find (msgID) != m_SentMessages.end()) { LogPrint (eLogWarning, "SSU: message ", msgID, " already sent"); return; diff --git a/libi2pd/SSUData.h b/libi2pd/SSUData.h index f4a5ba4f..2e606053 100644 --- a/libi2pd/SSUData.h +++ b/libi2pd/SSUData.h @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include #include @@ -124,8 +124,8 @@ namespace transport private: SSUSession& m_Session; - std::map > m_IncompleteMessages; - std::map > m_SentMessages; + std::unordered_map > m_IncompleteMessages; + std::unordered_map > m_SentMessages; std::unordered_set m_ReceivedMessages; boost::asio::deadline_timer m_ResendTimer, m_IncompleteMessagesCleanupTimer; int m_MaxPacketSize, m_PacketSize; From e50abbb250da622191cebcb2c9d9f989087bfd8b Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 8 Aug 2020 19:01:55 -0400 Subject: [PATCH 05/71] avoid replay upon SSU packet resend --- libi2pd/SSUData.cpp | 23 +++++++++++++++-------- libi2pd/SSUSession.cpp | 26 ++++++++++++++++---------- libi2pd/SSUSession.h | 1 + 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index fde684d0..bd188ab7 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -326,8 +326,7 @@ namespace transport { Fragment * fragment = new Fragment; fragment->fragmentNum = fragmentNum; - uint8_t * buf = fragment->buf; - uint8_t * payload = buf + sizeof (SSUHeader); + uint8_t * payload = fragment->buf + sizeof (SSUHeader); *payload = DATA_FLAG_WANT_REPLY; // for compatibility payload++; *payload = 1; // always 1 message fragment per message @@ -346,14 +345,20 @@ namespace transport payload += 3; memcpy (payload, msgBuf, size); - size += payload - buf; - if (size & 0x0F) // make sure 16 bytes boundary - size = ((size >> 4) + 1) << 4; // (/16 + 1)*16 + size += payload - fragment->buf; + uint8_t rem = size & 0x0F; + if (rem) // make sure 16 bytes boundary + { + auto padding = 16 - rem; + memset (fragment->buf + size, 0, padding); + size += padding; + } fragment->len = size; fragments.push_back (std::unique_ptr (fragment)); // encrypt message with session key - m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, buf, size); + uint8_t buf[SSU_V4_MAX_PACKET_SIZE + 18]; + m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, fragment->buf, size, buf); try { m_Session.Send (buf, size); @@ -432,6 +437,7 @@ namespace transport { if (ecode != boost::asio::error::operation_aborted) { + uint8_t buf[SSU_V4_MAX_PACKET_SIZE + 18]; uint32_t ts = i2p::util::GetSecondsSinceEpoch (); int numResent = 0; for (auto it = m_SentMessages.begin (); it != m_SentMessages.end ();) @@ -444,8 +450,9 @@ namespace transport if (f) { try - { - m_Session.Send (f->buf, f->len); // resend + { + m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, f->buf, f->len, buf); + m_Session.Send (buf, f->len); // resend numResent++; } catch (boost::system::system_error& ec) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 73699d6a..fca074b3 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -744,27 +744,33 @@ namespace transport } void SSUSession::FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len) + { + FillHeaderAndEncrypt (payloadType, buf, len, buf); + } + + void SSUSession::FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * in, size_t len, uint8_t * out) { if (len < sizeof (SSUHeader)) { LogPrint (eLogError, "SSU: Unexpected packet length ", len); return; } - SSUHeader * header = (SSUHeader *)buf; + SSUHeader * header = (SSUHeader *)out; RAND_bytes (header->iv, 16); // random iv m_SessionKeyEncryption.SetIV (header->iv); - header->flag = payloadType << 4; // MSB is 0 - htobe32buf (header->time, i2p::util::GetSecondsSinceEpoch ()); - uint8_t * encrypted = &header->flag; - uint16_t encryptedLen = len - (encrypted - buf); - m_SessionKeyEncryption.Encrypt (encrypted, encryptedLen, encrypted); - // assume actual buffer size is 18 (16 + 2) bytes more - memcpy (buf + len, header->iv, 16); + SSUHeader * inHeader = (SSUHeader *)in; + inHeader->flag = payloadType << 4; // MSB is 0 + htobe32buf (inHeader->time, i2p::util::GetSecondsSinceEpoch ()); + uint8_t * encrypted = &header->flag, * clear = &inHeader->flag; + uint16_t encryptedLen = len - (encrypted - out); + m_SessionKeyEncryption.Encrypt (clear, encryptedLen, encrypted); + // assume actual out buffer size is 18 (16 + 2) bytes more + memcpy (out + len, header->iv, 16); uint16_t netid = i2p::context.GetNetID (); - htobe16buf (buf + len + 16, (netid == I2PD_NET_ID) ? encryptedLen : encryptedLen ^ ((netid - 2) << 8)); + htobe16buf (out + len + 16, (netid == I2PD_NET_ID) ? encryptedLen : encryptedLen ^ ((netid - 2) << 8)); i2p::crypto::HMACMD5Digest (encrypted, encryptedLen + 18, m_MacKey, header->mac); } - + void SSUSession::Decrypt (uint8_t * buf, size_t len, const i2p::crypto::AESKey& aesKey) { if (len < sizeof (SSUHeader)) diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index 066e01eb..ea820517 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -138,6 +138,7 @@ namespace transport void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len, const i2p::crypto::AESKey& aesKey, const uint8_t * iv, const i2p::crypto::MACKey& macKey, uint8_t flag = 0); void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len); // with session key + void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * in, size_t len, uint8_t * out); // with session key void Decrypt (uint8_t * buf, size_t len, const i2p::crypto::AESKey& aesKey); void DecryptSessionKey (uint8_t * buf, size_t len); bool Validate (uint8_t * buf, size_t len, const i2p::crypto::MACKey& macKey); From 6fec92c012b8fa067284f26355c427610f8624fb Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 10 Aug 2020 17:49:46 -0400 Subject: [PATCH 06/71] shared transient addresses --- libi2pd_client/ClientContext.cpp | 52 +++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index e8e8eb2d..fc48ddbb 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -253,7 +253,8 @@ namespace client bool ClientContext::LoadPrivateKeys (i2p::data::PrivateKeys& keys, const std::string& filename, i2p::data::SigningKeyType sigType, i2p::data::CryptoKeyType cryptoType) { - if (filename == "transient") + static const std::string transient("transient"); + if (!filename.compare (0, transient.length (), transient)) // starts with transient { keys = i2p::data::PrivateKeys::CreateRandomKeys (sigType, cryptoType); LogPrint (eLogInfo, "Clients: New transient keys address ", m_AddressBook.ToAddress(keys.GetPublic ()->GetIdentHash ()), " created"); @@ -533,6 +534,7 @@ namespace client return; } + std::map > destinations; // keys -> destination for (auto& section: pt) { std::string name = section.first; @@ -564,18 +566,25 @@ namespace client std::shared_ptr localDestination = nullptr; if (keys.length () > 0) { - i2p::data::PrivateKeys k; - if(LoadPrivateKeys (k, keys, sigType, cryptoType)) - { - localDestination = FindLocalDestination (k.GetPublic ()->GetIdentHash ()); - if (!localDestination) + auto it = destinations.find (keys); + if (it != destinations.end ()) + localDestination = it->second; + else + { + i2p::data::PrivateKeys k; + if(LoadPrivateKeys (k, keys, sigType, cryptoType)) { - if(matchTunnels) - localDestination = CreateNewMatchedTunnelDestination(k, dest, &options); - else - localDestination = CreateNewLocalDestination (k, type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT, &options); + localDestination = FindLocalDestination (k.GetPublic ()->GetIdentHash ()); + if (!localDestination) + { + if(matchTunnels) + localDestination = CreateNewMatchedTunnelDestination(k, dest, &options); + else + localDestination = CreateNewLocalDestination (k, type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT, &options); + destinations[keys] = localDestination; + } } - } + } } if (type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) { @@ -679,12 +688,21 @@ namespace client ReadI2CPOptions (section, options); std::shared_ptr localDestination = nullptr; - i2p::data::PrivateKeys k; - if(!LoadPrivateKeys (k, keys, sigType, cryptoType)) - continue; - localDestination = FindLocalDestination (k.GetPublic ()->GetIdentHash ()); - if (!localDestination) - localDestination = CreateNewLocalDestination (k, true, &options); + auto it = destinations.find (keys); + if (it != destinations.end ()) + localDestination = it->second; + else + { + i2p::data::PrivateKeys k; + if(!LoadPrivateKeys (k, keys, sigType, cryptoType)) + continue; + localDestination = FindLocalDestination (k.GetPublic ()->GetIdentHash ()); + if (!localDestination) + { + localDestination = CreateNewLocalDestination (k, true, &options); + destinations[keys] = localDestination; + } + } if (type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER) { // udp server tunnel From e7ff6fbffc437adef64e198eed8ae34085741cc9 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 14 Aug 2020 09:54:31 -0400 Subject: [PATCH 07/71] don't save invalid addreses --- libi2pd_client/AddressBook.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index 8b8e781d..7af1272d 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -198,13 +198,18 @@ namespace client for (const auto& it: addresses) { - f << it.first << ","; - if (it.second->IsIdentHash ()) - f << it.second->identHash.ToBase32 (); + if (it.second->IsValid ()) + { + f << it.first << ","; + if (it.second->IsIdentHash ()) + f << it.second->identHash.ToBase32 (); + else + f << it.second->blindedPublicKey->ToB33 (); + f << std::endl; + num++; + } else - f << it.second->blindedPublicKey->ToB33 (); - f << std::endl; - num++; + LogPrint (eLogWarning, "Addressbook: invalid address ", it.first); } LogPrint (eLogInfo, "Addressbook: ", num, " addresses saved"); return num; From 3159b06988a215a745eba48c1e1c8c41fcf231c3 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 15 Aug 2020 13:53:49 -0400 Subject: [PATCH 08/71] reseeds update --- .../certificates/reseed/bugme_at_mail.i2p.crt | 32 ----------------- .../reseed/reseed_at_diva.exchange.crt | 34 +++++++++++++++++++ libi2pd/Config.cpp | 2 +- 3 files changed, 35 insertions(+), 33 deletions(-) delete mode 100644 contrib/certificates/reseed/bugme_at_mail.i2p.crt create mode 100644 contrib/certificates/reseed/reseed_at_diva.exchange.crt diff --git a/contrib/certificates/reseed/bugme_at_mail.i2p.crt b/contrib/certificates/reseed/bugme_at_mail.i2p.crt deleted file mode 100644 index 2b6acac0..00000000 --- a/contrib/certificates/reseed/bugme_at_mail.i2p.crt +++ /dev/null @@ -1,32 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFezCCA2OgAwIBAgIEUQYyQjANBgkqhkiG9w0BAQ0FADBuMQswCQYDVQQGEwJY -WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt -b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEXMBUGA1UEAwwOYnVnbWVAbWFpbC5p -MnAwHhcNMTQxMTA2MDkxMTE0WhcNMjQxMTA1MDkxMTE0WjBuMQswCQYDVQQGEwJY -WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt -b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEXMBUGA1UEAwwOYnVnbWVAbWFpbC5p -MnAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCrThOH0eSDT0VnCSBC -sqYmAydWH+O8eNttDXr2mSvZLhvAW+6/xHTkKhaWvkIvvS0Vh8hujMnD90Cgp4Fk -TKCxMj9K527o5xIZwWW05OevbjlBwIpVLO1PjmsfsoD1nIX14eEzJSEoAulKsv7V -jGUC/6hC11mmVvH9buQLSRv6sCjuAcMszmw3TAD+XYBIs+z57KuwYXtX3+OA543c -l1/ZKLYkkwY8cwzZqWDVWqTKP5TfVae58t40HhJk3bOsr21FZsaOjlmao3GO+d/3 -exKuUGJRcolSqskL3sZ1ovFqko81obvvx0upI0YA0iMr/NRGl3VPuf/LJvRppYGc -LsJHgy9TIgtHvaXRi5Nt4CbKl9sZh/7WkkTTI5YGvevu00btlabAN+DSAZZqdsB3 -wY8HhM1MHiA9SWsqwU65TwErcRrjNna2FiDHEu0xk5+/iAGl6CSKHZBmNcYKXSv8 -cwShB0jjmciK0a05nC638RPgj0fng7KRrSglyzfjXRrljmZ40LSBL/GGMZMWpOM7 -mEsBH5UZJ/2BEmjc9X9257zBdx8BK8y1TXpAligpNBsERcTw1WP1PJ35einZvlXW -qI3GwMf0sl26sn+evcK0gDl27jVDZ45MtNQEq64M4NV3Tn9zq0eg/39YvjVeqrI5 -l7sxmYqYGR6BuSncwdc4x+t6swIDAQABoyEwHzAdBgNVHQ4EFgQU/REZ7NMbVZHr -Xkao6Q8Ccqv2kAMwDQYJKoZIhvcNAQENBQADggIBACc2YjLVNbl1kJUdg2klCLJt -5LjNTiIZa2Cha5GStlC/lyoRRge6+q/y9TN3tTptlzLPS9pI9EE1GfIQaE+HAk+e -/bC3KUOAHgVuETvsNAbfpaVsPCdWpFuXmp/4b9iDN7qZy4afTKUPA/Ir/cLfNp14 -JULfP4z2yFOsCQZ5viNFAs1u99FrwobV2LBzUSIJQewsksuOwj96zIyau0Y629oJ -k+og88Tifd9EH3MVZNGhdpojQDDdwHQSITnCDgfRP5yER1WIA4jg6l+mM90QkvLY -5NjWTna5kJ3X6UizvgCk365yzT2sbN3R9UGXfCJa9GBcnnviJtJF3+/gC0abwY2f -NtVYp32Xky45NY/NdRhDg0bjHP3psxmX+Sc0M9NuQcDQ+fUR+CzM0IGeiszkzXOs -RG+bOou2cZ81G4oxWdAALHIRrn7VvLGlkFMxiIZyhYcTGQZzsTPT6n18dY99+DAV -yQWZfIRdm8DOnt0G+cwfeohc/9ZwDmj4jJAAi0aeTXdY6NEGIVydk6MAycEhg2Hx -9EV96kRwZNIW0AGY8CozECFL3Eyo2ClQVV4Q35SsBibsitDjM03usc2DJ/qjynXA -C8HoOSWgbddiBvqZueqK8GdhykOy3J3ysr+MNN/lbG48LqkQr1OWxev9rGGQ6RJT -wpBgPyAFAwouPy1whmnx ------END CERTIFICATE----- diff --git a/contrib/certificates/reseed/reseed_at_diva.exchange.crt b/contrib/certificates/reseed/reseed_at_diva.exchange.crt new file mode 100644 index 00000000..04b1524b --- /dev/null +++ b/contrib/certificates/reseed/reseed_at_diva.exchange.crt @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF0zCCA7ugAwIBAgIQWjHyC+NRh3emuuAwcEnKSjANBgkqhkiG9w0BAQsFADB0 +MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK +ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEdMBsGA1UEAwwU +cmVzZWVkQGRpdmEuZXhjaGFuZ2UwHhcNMjAwNjA5MDUzNjQ1WhcNMzAwNjA5MDUz +NjQ1WjB0MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4w +HAYDVQQKExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEdMBsG +A1UEAwwUcmVzZWVkQGRpdmEuZXhjaGFuZ2UwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQC6BJGeMEgoXk9dlzKVfmwHrT2VpwTT+wRJvh3eAM746u4uDT2y +NPHXhdGcQ9dRRZ63T98IshWCwOmWSlm1kdWkmKkVVb93GUoMQ3gziCi0apLJMAau +gEu/sPCbORS2dPsQeAPW2eIsJO7dSjTRiQAuquW//NcIXG4gnxDA52lgke1BvpKr +83SJlCrqECAy6OKtZ49yn75CqmPPWFn0b/E8bxruN5ffeipTTospvdEtT41gXUqk +hOz3k8ang+QTWiP//jOjk31KXZ2dbh0LOlNJOvRxCqQmBZafNxxCR4DH8RewfPlL +qOiOJVzbLSP9RjqPLwnny5BOjbLWXcaybN5Qv2Pyd4mKtN3EpqBwRu7VnzXpsuuG +gRbxNmfKJ/vBEGrZAHAxi0NkHHEEne3B7pPDc2dVZHOfTfCu31m9uDHZ4eHEsNOJ +SJRiGjq74l0chCSlBGLrD1Y9LPyqadjdwuB9bzM0tMFC1wPflanQCflhhnEzAfbN +BaU2GRXo/I1UCDW/dH1FIkqEe61eMW1Lwqr5tdlrUpdr5VIddTyNJRBJogbZ+HZE +8mcoJW2lXRAkYi7KEm4b4EQNe7sbRNTF0j+fAJ+3ZOZ3O3SMHss6ignlSa+giVim +VvL+Joc6wpSzxpeNPf6m82cEO/UvifFYeOC9TpiRriSt+vvgQVzQtfQ+fQIDAQAB +o2EwXzAOBgNVHQ8BAf8EBAMCAoQwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUF +BwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHJlc2VlZEBkaXZhLmV4Y2hh +bmdlMA0GCSqGSIb3DQEBCwUAA4ICAQCFGOb1dHlwjmgFHEER6oMiGWl1mI3Hb7GX +NNI6QUhZQ+iEWGYtsOTk3Q8xejL8t6AG/ZLXfZviLIJXZc5XZfPXk0ezDSC2cYxQ +ZAyYPw2dRP14brI86sCSqNAFIax/U5SM3zXhCbBiTfaEoBPfDpvKjx+VliaITUnc +sHTRn+C5ID5M8cZIqUSGECPEMU/bDtuRNJLTKYaJ98yXtYuS2CWsMEM4o0GGcnYQ +5HOZT/lbbwfq1Ks7IyJpeIpRaS5qckGcfgkxFY4eGujDuaFeWC+HCIh9RzBJrqZR +73Aly4Pyu7Jjg8xCCf9MswDjtqAjEHgWCmRLWL7p3H6cPipFKNMY6yomYZl5urE7 +q6DUAZFKwPqlZpyeaY4/SVvaHTxuPp7484s3db4kPhdmuQS/DOB/7d+cn/S580Vy +ALqlFQjtjLEaT16upceAV0gYktDInE6Rtym/OsqilrtYks/Sc0GROSz8lJhDDWbr +W3t92muSXDh0rYrEUYWl+xl1gSTpbIP75zzU+cUr1E/qlRY9qZn66FsJpOuN0I0q +UXsQS/bPDcA+IW48Hd9LfO9gtTWZslwFTimjEvQ2nJAnUlUQP6OfuPUKHoYX/CwY +2LCN8+pv2bKPDVHvp0lf6xrbbZNvFtzfR0G3AprZjYpuu2XgjVB5nJnwmbH74b9w +LD8d2z2Lgg== +-----END CERTIFICATE----- diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index d11152dd..6ce3a714 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -195,7 +195,7 @@ namespace config { ("reseed.proxy", value()->default_value(""), "url for reseed proxy, supports http/socks") ("reseed.urls", value()->default_value( "https://reseed.i2p-projekt.de/," - "https://i2p.mooo.com/netDb/," + "https://reseed.diva.exchange/," "https://reseed.i2p2.no/," "https://reseed-fr.i2pd.xyz/," "https://reseed.memcpy.io/," From 0777bad2c3b92607825c25898383346ae877a236 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 23 Aug 2020 22:25:54 +0300 Subject: [PATCH 09/71] [webconsole] fix warning, mobile page width Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 416cf1e4..d6b7a2ef 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -83,17 +83,18 @@ namespace http { " .disabled:after { color: #D33F3F; content: \"Disabled\" }\r\n" " .enabled:after { color: #56B734; content: \"Enabled\" }\r\n" " @media screen and (max-width: 980px) {\r\n" /* adaptive style */ + " body { padding: 1.5em 0 0 0; }\r\n" " .menu { width: 100%; display: block; float: none; position: unset; font-size: 16px;\r\n" " text-align: center; }\r\n" " .menu a, .commands a { padding: 2px; }\r\n" - " .content { float: none; margin: 0; margin-top: 16px; max-width: 100%; width: 100%;\r\n" + " .content { float: none; margin-left: unset; margin-top: 16px; max-width: 100%; width: 100%;\r\n" " text-align: center; }\r\n" " a, .slide label { /* margin-right: 10px; */ display: block; /* font-size: 18px; */ }\r\n" " .header { margin: unset; font-size: 1.5em; } small {display: block}\r\n" " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n" " color: initial; margin-top: 10px; padding: 6px; border: 1px solid #894c84; width: -webkit-fill-available; }\r\n" " input { width: 35%; text-align: center; padding: 5px;\r\n" - " border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 24px; }\r\n" + " border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 18px; }\r\n" " textarea { width: -webkit-fill-available; height: auto; padding:5px; border:2px solid #ccc;\r\n" " -webkit-border-radius: 5px; border-radius: 5px; font-size: 12px; }\r\n" " button[type=submit] { padding: 5px 15px; background: #ccc; border: 0 none; cursor: pointer;\r\n" @@ -933,7 +934,7 @@ namespace http { time_t t = divTime.quot; struct tm *tm = localtime(&t); char date[128]; - snprintf(date, sizeof(date), "%02d/%02d/%d %02d:%02d:%02d.%03ld", tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec, divTime.rem); + snprintf(date, sizeof(date), "%02d/%02d/%d %02d:%02d:%02d.%03lld", tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec, divTime.rem); return date; } From 954781262c1be24673c9c7d57527eefe921aa065 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 24 Aug 2020 12:27:39 -0400 Subject: [PATCH 10/71] 2.33.0 --- ChangeLog | 23 +++++++++++++++++++ Win32/installer.iss | 2 +- android/build.gradle | 4 ++-- contrib/rpm/i2pd-git.spec | 5 +++- contrib/rpm/i2pd.spec | 5 +++- debian/changelog | 6 +++++ libi2pd/version.h | 6 ++--- qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 1 + 8 files changed, 44 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 33792a97..362b28bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,29 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.33.0] - 2020-08-24 +### Added +- Shared transient addresses +- crypto.ratchet.inboundTags paramater +- Multiple encryption keys through I2CP +- Pre-calculated x25519 ephemeral keys +- Change datagram routing path if nothing comes back in 10 seconds +- Shared routing path for datagram session +### Changed +- UDP tunnels send mix of repliable and raw datagrams in bulk +- Encrypt SSU packet again upon resend +- Start new tunnel message if remaining buffer is too small +- Use LeaseSet2 for ECIES-X25519-AEAD-Ratchet automatically +- Save new ECIES-X25519-AEAD-Ratchet session with NSR tagset +- Generate random padding lengths for ECIES-X25519-AEAD-Ratchet in bulk +- Webconsole layout +- Reseed servers list +### Fixed +- Don't connect through terminated SAM destination +- Differentiate UDP server sessions by port +- ECIES-X25519-AEAD-Ratchet through I2CP +- Don't save invalid address to AddressBook + ## [2.32.1] - 2020-06-02 ### Added - Read explicit peers in tunnels config diff --git a/Win32/installer.iss b/Win32/installer.iss index 40724d7a..fbbeba53 100644 --- a/Win32/installer.iss +++ b/Win32/installer.iss @@ -1,5 +1,5 @@ #define I2Pd_AppName "i2pd" -#define I2Pd_ver "2.32.1" +#define I2Pd_ver "2.33.0" #define I2Pd_Publisher "PurpleI2P" [Setup] diff --git a/android/build.gradle b/android/build.gradle index c9e8429c..ace2047a 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -30,8 +30,8 @@ android { applicationId "org.purplei2p.i2pd" targetSdkVersion 29 minSdkVersion 14 - versionCode 2321 - versionName "2.32.1" + versionCode 2330 + versionName "2.33.0" setProperty("archivesBaseName", archivesBaseName + "-" + versionName) ndk { abiFilters 'armeabi-v7a' diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 7079ec23..00bea0b0 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.32.1 +Version: 2.33.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -124,6 +124,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Aug 24 2020 orignal - 2.33.0 +- update to 2.33.0 + * Tue Jun 02 2020 r4sas - 2.32.1 - update to 2.32.1 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 5c0b8fbd..22287f24 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.32.1 +Version: 2.33.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -122,6 +122,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Aug 24 2020 orignal - 2.33.0 +- update to 2.33.0 + * Tue Jun 02 2020 r4sas - 2.32.1 - update to 2.32.1 diff --git a/debian/changelog b/debian/changelog index b01f9519..bac3f3b3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.33.0-1) unstable; urgency=medium + + * updated to version 2.33.0/0.9.47 + + -- orignal Mon, 24 Aug 2020 16:00:00 +0000 + i2pd (2.32.1-1) unstable; urgency=high * updated to version 2.32.1 diff --git a/libi2pd/version.h b/libi2pd/version.h index c234516f..db30eee8 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -16,8 +16,8 @@ #define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 32 -#define I2PD_VERSION_MICRO 1 +#define I2PD_VERSION_MINOR 33 +#define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) #define VERSION I2PD_VERSION @@ -30,7 +30,7 @@ #define I2P_VERSION_MAJOR 0 #define I2P_VERSION_MINOR 9 -#define I2P_VERSION_MICRO 46 +#define I2P_VERSION_MICRO 47 #define I2P_VERSION_PATCH 0 #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) #define I2P_VERSION_NUMBER MAKE_VERSION_NUMBER(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index 75c57fb7..d3fa2e9e 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -35,6 +35,7 @@ + From a0685d804d158796adbdc96deb30fdadc65aa4e5 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 24 Aug 2020 12:48:09 -0400 Subject: [PATCH 11/71] 2.33.0 --- ChangeLog | 2 ++ appveyor.yml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 362b28bf..beef7a5a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,8 @@ - Differentiate UDP server sessions by port - ECIES-X25519-AEAD-Ratchet through I2CP - Don't save invalid address to AddressBook +- ECDSA signatures names in SAM +- AppArmor profile ## [2.32.1] - 2020-06-02 ### Added diff --git a/appveyor.yml b/appveyor.yml index 0567127c..a6278d2d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.32.1.{build} +version: 2.33.0.{build} pull_requests: do_not_increment_build_number: true branches: From a05a54b38edba546dc77f9d60037ab4dcec1129e Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 7 Sep 2020 18:45:05 -0400 Subject: [PATCH 12/71] trim behind ECIESx25519 tags --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 3 +++ libi2pd/ECIESX25519AEADRatchetSession.h | 6 ++++-- libi2pd/Garlic.cpp | 21 ++++++++++++--------- libi2pd/Garlic.h | 1 - 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 51ca9242..229578a1 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -657,7 +657,10 @@ namespace garlic moreTags -= (receiveTagset->GetNextIndex () - index); } if (moreTags > 0) + { GenerateMoreReceiveTags (receiveTagset, moreTags); + receiveTagset->MoveTrimBehind (moreTags >> 1); // /2 + } } return true; } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 73e129d7..c9f21463 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -56,10 +56,12 @@ namespace garlic std::shared_ptr GetSession () { return m_Session.lock (); }; int GetTagSetID () const { return m_TagSetID; }; void SetTagSetID (int tagsetID) { m_TagSetID = tagsetID; }; + void MoveTrimBehind (int offset) { m_TrimBehindIndex += offset; }; void Expire (); bool IsExpired (uint64_t ts) const { return m_ExpirationTimestamp && ts > m_ExpirationTimestamp; }; - + bool IsIndexExpired (int index) const { return m_Session.expired () || index < m_TrimBehindIndex; }; + private: union @@ -73,7 +75,7 @@ namespace garlic } m_KeyData; uint8_t m_SessTagConstant[32], m_SymmKeyCK[32], m_CurrentSymmKeyCK[64], m_NextRootKey[32]; - int m_NextIndex, m_NextSymmKeyIndex; + int m_NextIndex, m_NextSymmKeyIndex, m_TrimBehindIndex = 0; std::unordered_map > m_ItermediateSymmKeys; std::weak_ptr m_Session; int m_TagSetID = 0; diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 84a0519e..6d50aa1e 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -802,14 +802,6 @@ namespace garlic } } // ECIESx25519 - for (auto it = m_ECIESx25519Tags.begin (); it != m_ECIESx25519Tags.end ();) - { - if (it->second.tagset->IsExpired (ts) || ts > it->second.creationTime + ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT) - it = m_ECIESx25519Tags.erase (it); - else - ++it; - } - for (auto it = m_ECIESx25519Sessions.begin (); it != m_ECIESx25519Sessions.end ();) { if (it->second->CheckExpired (ts)) @@ -820,6 +812,17 @@ namespace garlic else ++it; } + + numExpiredTags = 0; + for (auto it = m_ECIESx25519Tags.begin (); it != m_ECIESx25519Tags.end ();) + { + if (it->second.tagset->IsExpired (ts) || it->second.tagset->IsIndexExpired (it->second.index)) + it = m_ECIESx25519Tags.erase (it); + else + ++it; + } + if (numExpiredTags > 0) + LogPrint (eLogDebug, "Garlic: ", numExpiredTags, " ECIESx25519 tags expired for ", GetIdentHash().ToBase64 ()); } void GarlicDestination::RemoveDeliveryStatusSession (uint32_t msgID) @@ -1009,7 +1012,7 @@ namespace garlic { auto index = tagset->GetNextIndex (); uint64_t tag = tagset->GetNextSessionTag (); - m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexTagset{index, tagset, i2p::util::GetSecondsSinceEpoch ()}); + m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexTagset{index, tagset}); } void GarlicDestination::AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session) diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 2168ee81..b97eaab2 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -220,7 +220,6 @@ namespace garlic { int index; RatchetTagSetPtr tagset; - uint64_t creationTime; // seconds since epoch }; class GarlicDestination: public i2p::data::LocalDestination From da1e52357f9b11dd45e240afbc8d1e6248eeb9b5 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 8 Sep 2020 07:46:55 -0400 Subject: [PATCH 13/71] delete symmkey on cleanup --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 9 ++++++++- libi2pd/ECIESX25519AEADRatchetSession.h | 3 ++- libi2pd/Garlic.cpp | 3 +++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 229578a1..885dc1fc 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -88,6 +88,11 @@ namespace garlic } } + void RatchetTagSet::DeleteSymmKey (int index) + { + m_ItermediateSymmKeys.erase (index); + } + void RatchetTagSet::Expire () { if (!m_ExpirationTimestamp) @@ -659,7 +664,9 @@ namespace garlic if (moreTags > 0) { GenerateMoreReceiveTags (receiveTagset, moreTags); - receiveTagset->MoveTrimBehind (moreTags >> 1); // /2 + index -= (moreTags >> 1); // /2 + if (index > 0) + receiveTagset->SetTrimBehind (index); } } return true; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index c9f21463..c7451b98 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -52,11 +52,12 @@ namespace garlic const uint8_t * GetNextRootKey () const { return m_NextRootKey; }; int GetNextIndex () const { return m_NextIndex; }; void GetSymmKey (int index, uint8_t * key); + void DeleteSymmKey (int index); std::shared_ptr GetSession () { return m_Session.lock (); }; int GetTagSetID () const { return m_TagSetID; }; void SetTagSetID (int tagsetID) { m_TagSetID = tagsetID; }; - void MoveTrimBehind (int offset) { m_TrimBehindIndex += offset; }; + void SetTrimBehind (int index) { if (index > m_TrimBehindIndex) m_TrimBehindIndex = index; }; void Expire (); bool IsExpired (uint64_t ts) const { return m_ExpirationTimestamp && ts > m_ExpirationTimestamp; }; diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 6d50aa1e..6bdbb630 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -817,7 +817,10 @@ namespace garlic for (auto it = m_ECIESx25519Tags.begin (); it != m_ECIESx25519Tags.end ();) { if (it->second.tagset->IsExpired (ts) || it->second.tagset->IsIndexExpired (it->second.index)) + { + it->second.tagset->DeleteSymmKey (it->second.index); it = m_ECIESx25519Tags.erase (it); + } else ++it; } From d0d71c93af3859fd24491678b37d500f1e4769ef Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 10 Sep 2020 19:27:29 -0400 Subject: [PATCH 14/71] set LeaseSet type to 3 for ratchets if not specified --- libi2pd/Destination.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index a764224c..c8940383 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -855,8 +855,7 @@ namespace client // extract encryption type params for LS2 std::set encryptionKeyTypes; - if ((GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2 || - GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) && params) + if (params) { auto it = params->find (I2CP_PARAM_LEASESET_ENCRYPTION_TYPE); if (it != params->end ()) From 2b0d1a2190743135f3a412c0d106b2e520e304d0 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 15 Sep 2020 19:39:18 -0400 Subject: [PATCH 15/71] implement DatabaseLookupTagSet --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 50 +++++++++++++++++++++++ libi2pd/ECIESX25519AEADRatchetSession.h | 21 +++++++++- libi2pd/Garlic.cpp | 3 +- 3 files changed, 70 insertions(+), 4 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 885dc1fc..aef273ed 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -99,6 +99,56 @@ namespace garlic m_ExpirationTimestamp = i2p::util::GetSecondsSinceEpoch () + ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT; } + bool RatchetTagSet::HandleNextMessage (uint8_t * buf, size_t len, int index) + { + auto session = GetSession (); + if (!session) return false; + return session->HandleNextMessage (buf, len, shared_from_this (), index); + } + + DatabaseLookupTagSet::DatabaseLookupTagSet (GarlicDestination * destination, const uint8_t * key): + RatchetTagSet (nullptr), m_Destination (destination) + { + memcpy (m_Key, key, 32); + Expire (); + } + + bool DatabaseLookupTagSet::HandleNextMessage (uint8_t * buf, size_t len, int index) + { + if (len < 24) return false; + uint8_t nonce[12]; + memset (nonce, 0, 12); // n = 0 + size_t offset = 8; // first 8 bytes is reply tag used as AD + len -= 16; // poly1305 + if (!i2p::crypto::AEADChaCha20Poly1305 (buf + offset, len - offset, buf, 8, m_Key, nonce, buf + offset, len - offset, false)) // decrypt + { + LogPrint (eLogWarning, "Garlic: Lookup reply AEAD decryption failed"); + return false; + } + // we assume 1 I2NP block with delivery type local + if (offset + 3 > len) + { + LogPrint (eLogWarning, "Garlic: Lookup reply is too short ", len); + return false; + } + if (buf[offset] != eECIESx25519BlkGalicClove) + { + LogPrint (eLogWarning, "Garlic: Lookup reply unexpected block ", (int)buf[offset]); + return false; + } + offset++; + auto size = bufbe16toh (buf + offset); + offset += 2; + if (offset + size > len) + { + LogPrint (eLogWarning, "Garlic: Lookup reply block is too long ", size); + return false; + } + if (m_Destination) + m_Destination->HandleECIESx25519GarlicClove (buf + offset, size); + return true; + } + ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet): GarlicRoutingSession (owner, attachLeaseSet) { diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index c7451b98..af0b5de5 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -40,7 +40,7 @@ namespace garlic // - 16 /* I2NP header */ - 16 /* poly hash */ - 8 /* tag */ - 4 /* garlic length */ class ECIESX25519AEADRatchetSession; - class RatchetTagSet + class RatchetTagSet: public std::enable_shared_from_this { public: @@ -61,7 +61,9 @@ namespace garlic void Expire (); bool IsExpired (uint64_t ts) const { return m_ExpirationTimestamp && ts > m_ExpirationTimestamp; }; - bool IsIndexExpired (int index) const { return m_Session.expired () || index < m_TrimBehindIndex; }; + virtual bool IsIndexExpired (int index) const { return m_Session.expired () || index < m_TrimBehindIndex; }; + + virtual bool HandleNextMessage (uint8_t * buf, size_t len, int index); private: @@ -94,6 +96,21 @@ namespace garlic std::shared_ptr m_DummySession; // we need a strong pointer for NS }; + + class DatabaseLookupTagSet: public RatchetTagSet + { + public: + + DatabaseLookupTagSet (GarlicDestination * destination, const uint8_t * key); + + bool IsIndexExpired (int index) const { return false; }; + bool HandleNextMessage (uint8_t * buf, size_t len, int index); + + private: + + GarlicDestination * m_Destination; + uint8_t m_Key[32]; + }; enum ECIESx25519BlockType { diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 6bdbb630..05d7fd3e 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -507,8 +507,7 @@ namespace garlic if (it1 != m_ECIESx25519Tags.end ()) { found = true; - auto session = it1->second.tagset->GetSession (); - if (!session || !session->HandleNextMessage (buf, length, it1->second.tagset, it1->second.index)) + if (!it1->second.tagset->HandleNextMessage (buf, length, it1->second.index)) LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); m_ECIESx25519Tags.erase (it1); } From 024c29b180d2ad6bfcf6179d64119a14ef94f9c4 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 17 Sep 2020 21:11:46 -0400 Subject: [PATCH 16/71] eliminate boost/bind --- daemon/HTTPServer.cpp | 5 ++-- daemon/UPnP.cpp | 53 ++++++++++++++++++------------------------ libi2pd/SSU.cpp | 1 - libi2pd/SSUData.cpp | 1 - libi2pd/SSUSession.cpp | 1 - 5 files changed, 24 insertions(+), 37 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index d6b7a2ef..52b655b9 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include "Base.h" @@ -1321,8 +1320,8 @@ namespace http { void HTTPServer::Accept () { auto newSocket = std::make_shared (m_Service); - m_Acceptor.async_accept (*newSocket, boost::bind (&HTTPServer::HandleAccept, this, - boost::asio::placeholders::error, newSocket)); + m_Acceptor.async_accept (*newSocket, std::bind (&HTTPServer::HandleAccept, this, + std::placeholders::_1, newSocket)); } void HTTPServer::HandleAccept(const boost::system::error_code& ecode, diff --git a/daemon/UPnP.cpp b/daemon/UPnP.cpp index 852122f2..92a41011 100644 --- a/daemon/UPnP.cpp +++ b/daemon/UPnP.cpp @@ -1,18 +1,9 @@ -/* -* Copyright (c) 2013-2020, The PurpleI2P Project -* -* This file is part of Purple i2pd project and licensed under BSD3 -* -* See full license text in LICENSE file at top of project tree -*/ - #ifdef USE_UPNP #include #include #include #include -#include #include "Log.h" @@ -88,10 +79,10 @@ namespace transport void UPnP::Discover () { bool isError; - int err; + int err; #if ((MINIUPNPC_API_VERSION >= 8) || defined (UPNPDISCOVER_SUCCESS)) - err = UPNPDISCOVER_SUCCESS; + err = UPNPDISCOVER_SUCCESS; #if (MINIUPNPC_API_VERSION >= 14) m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0, 0, 2, &err); @@ -100,9 +91,9 @@ namespace transport #endif isError = err != UPNPDISCOVER_SUCCESS; -#else // MINIUPNPC_API_VERSION >= 8 - err = 0; - m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0); +#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 { @@ -113,15 +104,15 @@ namespace transport if (isError) { - LogPrint (eLogError, "UPnP: unable to discover Internet Gateway Devices: error ", err); + 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; + m_upnpUrlsInitialized=err!=0; if (err == UPNP_IGD_VALID_CONNECTED) { - err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress); + err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress); if(err != UPNPCOMMAND_SUCCESS) { LogPrint (eLogError, "UPnP: unable to get external address: error ", err); @@ -132,14 +123,14 @@ namespace transport LogPrint (eLogError, "UPnP: found Internet Gateway Device ", m_upnpUrls.controlURL); if (!m_externalIPAddress[0]) { - LogPrint (eLogError, "UPnP: found Internet Gateway Device doesn't know our external address"); + LogPrint (eLogError, "UPnP: found Internet Gateway Device doesn't know our external address"); return; } } } else { - LogPrint (eLogError, "UPnP: unable to find valid Internet Gateway Device: error ", err); + LogPrint (eLogError, "UPnP: unable to find valid Internet Gateway Device: error ", err); return; } @@ -190,7 +181,7 @@ namespace transport 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); + 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); @@ -210,7 +201,7 @@ namespace transport } else { - LogPrint (eLogDebug, "UPnP: external forward from ", m_NetworkAddr, ":", strPort, " exists on current Internet Gateway Device"); + LogPrint (eLogDebug, "UPnP: external forward from ", m_NetworkAddr, ":", strPort, " exists on current Internet Gateway Device"); return; } } @@ -227,14 +218,14 @@ namespace transport void UPnP::CloseMapping (std::shared_ptr address) { - if(!m_upnpUrlsInitialized) { - return; - } + if(!m_upnpUrlsInitialized) { + return; + } std::string strType (GetProto (address)), strPort (std::to_string (address->port)); int err = UPNPCOMMAND_SUCCESS; - + err = CheckMapping (strPort.c_str (), strType.c_str ()); - if (err == UPNPCOMMAND_SUCCESS) + 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); @@ -245,11 +236,11 @@ namespace transport { freeUPNPDevlist (m_Devlist); m_Devlist = 0; - if(m_upnpUrlsInitialized){ - FreeUPNPUrls (&m_upnpUrls); - m_upnpUrlsInitialized=false; - } - } + if(m_upnpUrlsInitialized){ + FreeUPNPUrls (&m_upnpUrls); + m_upnpUrlsInitialized=false; + } + } std::string UPnP::GetProto (std::shared_ptr address) { diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index c435715f..0f4526bd 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -7,7 +7,6 @@ */ #include -#include #include "Log.h" #include "Timestamp.h" #include "RouterContext.h" diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index bd188ab7..4e0e712f 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -7,7 +7,6 @@ */ #include -#include #include "Log.h" #include "Timestamp.h" #include "NetDb.hpp" diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index fca074b3..399b2fc7 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -6,7 +6,6 @@ * See full license text in LICENSE file at top of project tree */ -#include #include "version.h" #include "Crypto.h" #include "Log.h" From 09fdb068d2cbf70c4c4162748bb047331de69b47 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 19 Sep 2020 21:15:42 -0400 Subject: [PATCH 17/71] Database lookups from ECIES destinations --- libi2pd/Destination.cpp | 11 ++++++++--- libi2pd/Garlic.cpp | 8 ++++++++ libi2pd/Garlic.h | 1 + libi2pd/I2NPProtocol.cpp | 18 ++++++++++++++---- libi2pd/I2NPProtocol.h | 5 +++-- 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index c8940383..6b51fe1a 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -744,14 +744,19 @@ namespace client request->excluded.insert (nextFloodfill->GetIdentHash ()); request->requestTimeoutTimer.cancel (); + bool isECIES = SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) && + nextFloodfill->GetVersion () >= MAKE_VERSION_NUMBER(0, 9, 46); // >= 0.9.46; uint8_t replyKey[32], replyTag[32]; RAND_bytes (replyKey, 32); // random session key - RAND_bytes (replyTag, 32); // random session tag - AddSessionKey (replyKey, replyTag); + RAND_bytes (replyTag, isECIES ? 8 : 32); // random session tag + if (isECIES) + AddECIESx25519Key (replyKey, replyTag); + else + AddSessionKey (replyKey, replyTag); auto msg = WrapMessage (nextFloodfill, CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, - request->replyTunnel, replyKey, replyTag)); + request->replyTunnel, replyKey, replyTag, isECIES)); request->outboundTunnel->SendTunnelDataMsg ( { i2p::tunnel::TunnelMessageBlock diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 05d7fd3e..429a2092 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -460,6 +460,14 @@ namespace garlic } } + void GarlicDestination::AddECIESx25519Key (const uint8_t * key, const uint8_t * tag) + { + uint64_t t; + memcpy (&t, tag, 8); + auto tagset = std::make_shared(this, key); + m_ECIESx25519Tags.emplace (t, ECIESX25519AEADRatchetIndexTagset{0, tagset}); + } + bool GarlicDestination::SubmitSessionKey (const uint8_t * key, const uint8_t * tag) { AddSessionKey (key, tag); diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index b97eaab2..f1e363df 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -241,6 +241,7 @@ namespace garlic std::shared_ptr msg, bool attachLeaseSet = false); void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag + void AddECIESx25519Key (const uint8_t * key, const uint8_t * tag); // one tag virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread void DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID); void AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset); diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 53afbca4..36e7a763 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -171,7 +171,8 @@ namespace i2p std::shared_ptr CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest, const std::set& excludedFloodfills, - std::shared_ptr replyTunnel, const uint8_t * replyKey, const uint8_t * replyTag) + std::shared_ptr replyTunnel, const uint8_t * replyKey, + const uint8_t * replyTag, bool replyECIES) { int cnt = excludedFloodfills.size (); auto m = cnt > 7 ? NewI2NPMessage () : NewI2NPShortMessage (); @@ -180,7 +181,8 @@ namespace i2p buf += 32; memcpy (buf, replyTunnel->GetNextIdentHash (), 32); // reply tunnel GW buf += 32; - *buf = DATABASE_LOOKUP_DELIVERY_FLAG | DATABASE_LOOKUP_ENCRYPTION_FLAG | DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP; // flags + *buf = DATABASE_LOOKUP_DELIVERY_FLAG | DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP; // flags + *buf |= (replyECIES ? DATABASE_LOOKUP_ECIES_FLAG : DATABASE_LOOKUP_ENCRYPTION_FLAG); buf ++; htobe32buf (buf, replyTunnel->GetNextTunnelID ()); // reply tunnel ID buf += 4; @@ -204,8 +206,16 @@ namespace i2p // encryption memcpy (buf, replyKey, 32); buf[32] = 1; // 1 tag - memcpy (buf + 33, replyTag, 32); - buf += 65; + if (replyECIES) + { + memcpy (buf + 33, replyTag, 8); // 8 bytes tag + buf += 41; + } + else + { + memcpy (buf + 33, replyTag, 32); // 32 bytes tag + buf += 65; + } m->len += (buf - m->GetPayload ()); m->FillI2NPMessageHeader (eI2NPDatabaseLookup); diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 695de798..fe5ca968 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -251,8 +251,9 @@ namespace tunnel std::shared_ptr CreateRouterInfoDatabaseLookupMsg (const uint8_t * key, const uint8_t * from, uint32_t replyTunnelID, bool exploratory = false, std::set * excludedPeers = nullptr); std::shared_ptr CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest, - const std::set& excludedFloodfills, - std::shared_ptr replyTunnel, const uint8_t * replyKey, const uint8_t * replyTag); + const std::set& excludedFloodfills, + std::shared_ptr replyTunnel, + const uint8_t * replyKey, const uint8_t * replyTag, bool replyECIES = false); std::shared_ptr CreateDatabaseSearchReply (const i2p::data::IdentHash& ident, std::vector routers); std::shared_ptr CreateDatabaseStoreMsg (std::shared_ptr router = nullptr, uint32_t replyToken = 0); From f939a7b349a930f2f2da5aee654095c50fa53500 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 21 Sep 2020 19:22:53 -0400 Subject: [PATCH 18/71] reduce variable tunnel build length to 4 --- libi2pd/Tunnel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 1fb12af9..a50bc31a 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -36,7 +36,7 @@ namespace tunnel const int TUNNEL_EXPIRATION_THRESHOLD = 60; // 1 minute const int TUNNEL_RECREATION_THRESHOLD = 90; // 1.5 minutes const int TUNNEL_CREATION_TIMEOUT = 30; // 30 seconds - const int STANDARD_NUM_RECORDS = 5; // in VariableTunnelBuild message + const int STANDARD_NUM_RECORDS = 4; // in VariableTunnelBuild message enum TunnelState { From 335f9394a5727596fc9a196b4c622464721e69b9 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 26 Sep 2020 19:32:19 -0400 Subject: [PATCH 19/71] drop gcc 4.7 support --- Makefile.linux | 2 +- daemon/I2PControl.cpp | 69 +++++++++++++++-------------------------- libi2pd/Destination.cpp | 3 +- 3 files changed, 27 insertions(+), 47 deletions(-) diff --git a/Makefile.linux b/Makefile.linux index 1cdf0a48..3ef4793c 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -15,7 +15,7 @@ ifeq ($(shell expr match $(CXX) 'clang'),5) NEEDED_CXXFLAGS += -std=c++11 else ifeq ($(shell expr match ${CXXVER} "4\.[0-9][0-9]"),4) # gcc >= 4.10 NEEDED_CXXFLAGS += -std=c++11 -else ifeq ($(shell expr match ${CXXVER} "4\.[7-9]"),3) # gcc 4.7 - 4.9 +else ifeq ($(shell expr match ${CXXVER} "4\.[8-9]"),3) # gcc 4.8 - 4.9 NEEDED_CXXFLAGS += -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 else ifeq ($(shell expr match ${CXXVER} "[5-6]"),1) # gcc 5 - 6 NEEDED_CXXFLAGS += -std=c++11 diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index 77614f2f..e8c6e031 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -1,11 +1,3 @@ -/* -* Copyright (c) 2013-2020, The PurpleI2P Project -* -* This file is part of Purple i2pd project and licensed under BSD3 -* -* See full license text in LICENSE file at top of project tree -*/ - #include #include #include @@ -14,12 +6,7 @@ #include #include #include - -// There is bug in boost 1.49 with gcc 4.7 coming with Debian Wheezy -#define GCC47_BOOST149 ((BOOST_VERSION == 104900) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) -#if !GCC47_BOOST149 #include -#endif #include "Crypto.h" #include "FS.h" @@ -67,28 +54,29 @@ namespace client m_SSLContext.use_private_key_file (i2pcp_key, boost::asio::ssl::context::pem); // handlers - m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler; - m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler; - m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler; - m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler; - m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler; - m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler; - m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler; + m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler; + m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler; + m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler; + m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler; + m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler; + m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler; + m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler; // I2PControl m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler; // RouterInfo - m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler; - m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler; - m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler; - m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler; - m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler; - m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlService::InboundBandwidth1S; - m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S; - m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler; + m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler; + m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler; + m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler; + m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler; + m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler; + m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlService::InboundBandwidth1S; + m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S; + m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler; m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlService::TunnelsParticipatingHandler; - m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = &I2PControlService::TunnelsSuccessRateHandler; + m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = +&I2PControlService::TunnelsSuccessRateHandler; m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes; m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes; @@ -104,10 +92,10 @@ namespace client // ClientServicesInfo m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlService::I2PTunnelInfoHandler; m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlService::HTTPProxyInfoHandler; - m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler; - m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler; - m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler; - m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler; + m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler; + m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler; + m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler; + m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler; } I2PControlService::~I2PControlService () @@ -242,12 +230,6 @@ namespace client } } std::ostringstream response; -#if GCC47_BOOST149 - LogPrint (eLogError, "I2PControl: json_read is not supported due bug in boost 1.49 with gcc 4.7"); - response << "{\"id\":null,\"error\":"; - response << "{\"code\":-32603,\"message\":\"JSON requests is not supported with this version of boost\"},"; - response << "\"jsonrpc\":\"2.0\"}"; -#else boost::property_tree::ptree pt; boost::property_tree::read_json (ss, pt); @@ -267,7 +249,6 @@ namespace client response << "{\"code\":-32601,\"message\":\"Method not found\"},"; response << "\"jsonrpc\":\"2.0\"}"; } -#endif SendResponse (socket, buf, response, isHtml); } catch (std::exception& ex) @@ -408,8 +389,8 @@ namespace client auto it1 = m_RouterInfoHandlers.find (it->first); if (it1 != m_RouterInfoHandlers.end ()) { - if (!first) results << ","; - else first = false; + if (!first) results << ","; + else first = false; (this->*(it1->second))(results); } else @@ -507,7 +488,7 @@ namespace client m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(1)); // 1 second to make sure response has been sent m_ShutdownTimer.async_wait ( [](const boost::system::error_code& ecode) - { + { Daemon.running = 0; }); } @@ -521,7 +502,7 @@ namespace client m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(timeout + 1)); // + 1 second m_ShutdownTimer.async_wait ( [](const boost::system::error_code& ecode) - { + { Daemon.running = 0; }); } diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 6b51fe1a..cd0ad9ab 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -603,9 +603,8 @@ namespace client return; } auto s = shared_from_this (); - // we must capture this for gcc 4.7 due the bug RequestLeaseSet (ls->GetStoreHash (), - [s, ls, this](std::shared_ptr leaseSet) + [s, ls](std::shared_ptr leaseSet) { if (leaseSet) { From 4d850793727f067a64c12499123325a911da1a89 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 27 Sep 2020 17:46:15 -0400 Subject: [PATCH 20/71] correct addressbook request --- libi2pd_client/AddressBook.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index 7af1272d..c044a047 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -806,6 +806,7 @@ namespace client i2p::http::HTTPReq req; req.AddHeader("Host", dest_host); req.AddHeader("User-Agent", "Wget/1.11.4"); + req.AddHeader("Accept-Encoding", "gzip"); req.AddHeader("X-Accept-Encoding", "x-i2p-gzip;q=1.0, identity;q=0.5, deflate;q=0, gzip;q=0, *;q=0"); req.AddHeader("Connection", "close"); if (!m_Etag.empty()) @@ -816,6 +817,7 @@ namespace client url.schema = ""; url.host = ""; req.uri = url.to_string(); + req.version = "HTTP/1.1"; auto stream = i2p::client::context.GetSharedLocalDestination ()->CreateStream (leaseSet, dest_port); std::string request = req.to_string(); stream->Send ((const uint8_t *) request.data(), request.length()); @@ -895,7 +897,7 @@ namespace client i2p::http::MergeChunkedResponse (in, out); response = out.str(); } - else if (res.is_gzipped()) + if (res.is_gzipped()) { std::stringstream out; i2p::data::GzipInflator inflator; From 949fc47f311bb7c33ef073fc5e05cb369214718a Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 27 Sep 2020 19:07:58 -0400 Subject: [PATCH 21/71] two tunnels for shared local destination --- libi2pd_client/ClientContext.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index fc48ddbb..b24ce3ce 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -401,7 +401,14 @@ namespace client void ClientContext::CreateNewSharedLocalDestination () { - m_SharedLocalDestination = CreateNewLocalDestination (); // non-public, EDDSA + std::map params + { + { I2CP_PARAM_INBOUND_TUNNELS_QUANTITY, "2" }, + { I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY, "2" }, + { I2CP_PARAM_LEASESET_TYPE, "3" } + }; + m_SharedLocalDestination = CreateNewLocalDestination (false, i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519, + i2p::data::CRYPTO_KEY_TYPE_ELGAMAL, ¶ms); // non-public, EDDSA m_SharedLocalDestination->Acquire (); } From 489c38ec5b13c1be33b22ff887f96f925cd49866 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 27 Sep 2020 19:19:48 -0400 Subject: [PATCH 22/71] read Last-Modified --- libi2pd_client/AddressBook.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index c044a047..5c1cffbb 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -889,7 +889,7 @@ namespace client /* assert: res.code == 200 */ auto it = res.headers.find("ETag"); if (it != res.headers.end()) m_Etag = it->second; - it = res.headers.find("If-Modified-Since"); + it = res.headers.find("Last-Modified"); if (it != res.headers.end()) m_LastModified = it->second; if (res.is_chunked()) { From 5f42888b6118277b1569551296fef3759593ff25 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Sep 2020 03:43:47 +0300 Subject: [PATCH 23/71] [appveyor] disable fix introdued in 7864053 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index a6278d2d..378fadc8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -23,7 +23,7 @@ environment: install: - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc" # TODO: revert that change when appveyor's images will be updated -- c:\msys64\usr\bin\bash -l "build/appveyor-msys2-upgrade.bash" +#- c:\msys64\usr\bin\bash -l "build/appveyor-msys2-upgrade.bash" # update runtime - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" # update packages and install required From dec7a9a01c30238399d5b5bb86c36d4376708d58 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 27 Sep 2020 20:50:57 -0400 Subject: [PATCH 24/71] shared transient destination between proxies --- libi2pd/Config.cpp | 4 ++-- libi2pd_client/ClientContext.cpp | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 6ce3a714..7668d6a7 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -96,7 +96,7 @@ namespace config { ("httpproxy.enabled", value()->default_value(true), "Enable or disable HTTP Proxy") ("httpproxy.address", value()->default_value("127.0.0.1"), "HTTP Proxy listen address") ("httpproxy.port", value()->default_value(4444), "HTTP Proxy listen port") - ("httpproxy.keys", value()->default_value(""), "File to persist HTTP Proxy keys") + ("httpproxy.keys", value()->default_value("transient-proxy"), "File to persist HTTP Proxy keys. Transient by default") ("httpproxy.signaturetype", value()-> default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default") ("httpproxy.inbound.length", value()->default_value("3"), "HTTP proxy inbound tunnel length") @@ -116,7 +116,7 @@ namespace config { ("socksproxy.enabled", value()->default_value(true), "Enable or disable SOCKS Proxy") ("socksproxy.address", value()->default_value("127.0.0.1"), "SOCKS Proxy listen address") ("socksproxy.port", value()->default_value(4447), "SOCKS Proxy listen port") - ("socksproxy.keys", value()->default_value(""), "File to persist SOCKS Proxy keys") + ("socksproxy.keys", value()->default_value("transient-proxy"), "File to persist SOCKS Proxy keys. Transient by default") ("socksproxy.signaturetype", value()-> default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default") ("socksproxy.inbound.length", value()->default_value("3"), "SOCKS proxy inbound tunnel length") diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index b24ce3ce..e1316a7f 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -844,6 +844,8 @@ namespace client bool socksproxy; i2p::config::GetOption("socksproxy.enabled", socksproxy); if (socksproxy) { + std::string httpProxyKeys; i2p::config::GetOption("httpproxy.keys", httpProxyKeys); + // we still need httpProxyKeys to compare with sockProxyKeys std::string socksProxyKeys; i2p::config::GetOption("socksproxy.keys", socksProxyKeys); std::string socksProxyAddr; i2p::config::GetOption("socksproxy.address", socksProxyAddr); uint16_t socksProxyPort; i2p::config::GetOption("socksproxy.port", socksProxyPort); @@ -852,7 +854,12 @@ namespace client uint16_t socksOutProxyPort; i2p::config::GetOption("socksproxy.outproxyport", socksOutProxyPort); i2p::data::SigningKeyType sigType; i2p::config::GetOption("socksproxy.signaturetype", sigType); LogPrint(eLogInfo, "Clients: starting SOCKS Proxy at ", socksProxyAddr, ":", socksProxyPort); - if (socksProxyKeys.length () > 0) + if (httpProxyKeys == socksProxyKeys && m_HttpProxy) + { + localDestination = m_HttpProxy->GetLocalDestination (); + localDestination->Acquire (); + } + else if (socksProxyKeys.length () > 0) { i2p::data::PrivateKeys keys; if (LoadPrivateKeys (keys, socksProxyKeys, sigType)) From 730c6aff11e7617cde385e4e0e63a1644db642e0 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Sep 2020 04:08:39 +0300 Subject: [PATCH 25/71] Update appveyor.yml --- appveyor.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 378fadc8..0e7dc3a9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -21,9 +21,13 @@ environment: MSYS_BITNESS: 32 install: +# install new signing keyring +- c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" +- c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" +- c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" +- c:\msys64\usr\bin\bash -lc "pacman -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" +# remove packages which can break build - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc" -# TODO: revert that change when appveyor's images will be updated -#- c:\msys64\usr\bin\bash -l "build/appveyor-msys2-upgrade.bash" # update runtime - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" # update packages and install required From cb41c0455185beff299f10c46c0b8033609ae543 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Sep 2020 04:10:11 +0300 Subject: [PATCH 26/71] [appveyor] install keyring package without question --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 0e7dc3a9..11f6c9fd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -25,7 +25,7 @@ install: - c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" - c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" - c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" -- c:\msys64\usr\bin\bash -lc "pacman -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" +- c:\msys64\usr\bin\bash -lc "pacman -y -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" # remove packages which can break build - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc" # update runtime From 208707c00b86d130ae7ddd565b03c27b0e5c1438 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Sep 2020 04:11:40 +0300 Subject: [PATCH 27/71] [appveyor] install keyring package without question --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 11f6c9fd..5b365634 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -25,7 +25,7 @@ install: - c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" - c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" - c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" -- c:\msys64\usr\bin\bash -lc "pacman -y -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" +- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" # remove packages which can break build - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc" # update runtime From 7d34f1e8831d9b3d5702281ae64e19ecf68b7664 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Sep 2020 04:20:18 +0300 Subject: [PATCH 28/71] [appveyor] add delay before second try --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 5b365634..c233f535 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -30,6 +30,8 @@ install: - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc" # update runtime - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" +# Sleep for 5 seconds before next try? +- ping -n 5 127.0.0.1 > nul # update packages and install required - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu ${MSYS_PACKAGES}" From 221b7cbf76bf6a3244f354a0181ace6300e5d96a Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Sep 2020 04:29:43 +0300 Subject: [PATCH 29/71] [appveyor] kill bash before second try Ok, just waiting for bash termination doesn't works, so lets kill it. --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index c233f535..4b6c8b9a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -30,8 +30,8 @@ install: - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc" # update runtime - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" -# Sleep for 5 seconds before next try? -- ping -n 5 127.0.0.1 > nul +# Kill bash before next try +- taskkill /T /F /IM bash.exe # update packages and install required - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu ${MSYS_PACKAGES}" From beb5d26e6d1aff804438285f9918216f56e3a298 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Sep 2020 04:44:18 +0300 Subject: [PATCH 30/71] [appveyor] kill gpg --- appveyor.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 4b6c8b9a..07308d10 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -31,7 +31,9 @@ install: # update runtime - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" # Kill bash before next try -- taskkill /T /F /IM bash.exe +- taskkill /T /F /IM bash.exe /IM gpg.exe /IM gpg-agent.exe +# For debug purposes +- tasklist # update packages and install required - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu ${MSYS_PACKAGES}" From 873b4f3178d2d6fc570d206fa11512f38394a2a6 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Sep 2020 04:48:57 +0300 Subject: [PATCH 31/71] [appveyor] suppress error code --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 07308d10..83dee927 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -31,7 +31,7 @@ install: # update runtime - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" # Kill bash before next try -- taskkill /T /F /IM bash.exe /IM gpg.exe /IM gpg-agent.exe +- taskkill /T /F /IM bash.exe /IM gpg.exe /IM gpg-agent.exe | exit /B 0 # For debug purposes - tasklist # update packages and install required From ac5a4fe70ff4d6226da8c9bac150f1f4f7e8044d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Sep 2020 04:51:13 +0300 Subject: [PATCH 32/71] [appveyor] remove tasklist print --- appveyor.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 83dee927..9d035653 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -32,8 +32,6 @@ install: - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" # Kill bash before next try - taskkill /T /F /IM bash.exe /IM gpg.exe /IM gpg-agent.exe | exit /B 0 -# For debug purposes -- tasklist # update packages and install required - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu ${MSYS_PACKAGES}" From fd9229c4676b158137532bb61aee0ffb84408263 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 30 Sep 2020 17:12:28 -0400 Subject: [PATCH 33/71] ping/pong for streaming --- libi2pd/Destination.cpp | 10 +++++++--- libi2pd/Destination.h | 6 +++++- libi2pd/Streaming.cpp | 31 +++++++++++++++++++++++++++++++ libi2pd/Streaming.h | 2 ++ libi2pd_client/ClientContext.cpp | 1 + 5 files changed, 46 insertions(+), 4 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index cd0ad9ab..af3b4cbc 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -849,8 +849,9 @@ namespace client ClientDestination::ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): - LeaseSetDestination (service, isPublic, params), - m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), + LeaseSetDestination (service, isPublic, params), + m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), + m_IsStreamingAnswerPings (DEFAULT_ANSWER_PINGS), m_DatagramDestination (nullptr), m_RefCounter (0), m_ReadyChecker(service) { @@ -918,7 +919,10 @@ namespace client auto it = params->find (I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY); if (it != params->end ()) m_StreamingAckDelay = std::stoi(it->second); - + it = params->find (I2CP_PARAM_STREAMING_ANSWER_PINGS); + if (it != params->end ()) + m_IsStreamingAnswerPings = (it->second == "true"); + if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) { // authentication for encrypted LeaseSet diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 1d5c0a55..a7567534 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -78,6 +78,8 @@ namespace client // streaming const char I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY[] = "i2p.streaming.initialAckDelay"; const int DEFAULT_INITIAL_ACK_DELAY = 200; // milliseconds + const char I2CP_PARAM_STREAMING_ANSWER_PINGS[] = "i2p.streaming.answerPings"; + const int DEFAULT_ANSWER_PINGS = true; typedef std::function stream)> StreamRequestComplete; @@ -242,7 +244,8 @@ namespace client bool IsAcceptingStreams () const; void AcceptOnce (const i2p::stream::StreamingDestination::Acceptor& acceptor); int GetStreamingAckDelay () const { return m_StreamingAckDelay; } - + bool IsStreamingAnswerPings () const { return m_IsStreamingAnswerPings; } + // datagram i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; }; i2p::datagram::DatagramDestination * CreateDatagramDestination (bool gzip = true); @@ -275,6 +278,7 @@ namespace client std::unique_ptr m_ECIESx25519EncryptionKey; int m_StreamingAckDelay; + bool m_IsStreamingAnswerPings; std::shared_ptr m_StreamingDestination; // default std::map > m_StreamingDestinationsByPorts; i2p::datagram::DatagramDestination * m_DatagramDestination; diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index ff8915c0..ab08f41f 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -351,6 +351,28 @@ namespace stream return true; } + void Stream::HandlePing (Packet * packet) + { + uint16_t flags = packet->GetFlags (); + if (ProcessOptions (flags, packet) && m_RemoteIdentity) + { + // send pong + Packet p; + memset (p.buf, 0, 22); // minimal header all zeroes + memcpy (p.buf + 4, packet->buf, 4); // but receiveStreamID is the sendStreamID from the ping + htobe16buf (p.buf + 18, PACKET_FLAG_ECHO); // and echo flag + ssize_t payloadLen = packet->len - (packet->GetPayload () - packet->buf); + if (payloadLen > 0) + memcpy (p.buf + 22, packet->GetPayload (), payloadLen); + else + payloadLen = 0; + p.len = payloadLen + 22; + SendPackets (std::vector { &p }); + LogPrint (eLogDebug, "Streaming: Pong of ", p.len, " bytes sent"); + } + m_LocalDestination.DeletePacket (packet); + } + void Stream::ProcessAck (Packet * packet) { bool acknowledged = false; @@ -609,6 +631,7 @@ namespace stream packet[size] = 0; size++; // NACK count } + packet[size] = 0; size++; // resend delay htobuf16 (packet + size, 0); // no flags set size += 2; // flags @@ -666,6 +689,7 @@ namespace stream size += 4; // ack Through packet[size] = 0; size++; // NACK count + packet[size] = 0; size++; // resend delay htobe16buf (packet + size, PACKET_FLAG_CLOSE | PACKET_FLAG_SIGNATURE_INCLUDED); size += 2; // flags @@ -1016,6 +1040,13 @@ namespace stream auto it = m_Streams.find (sendStreamID); if (it != m_Streams.end ()) it->second->HandleNextPacket (packet); + else if (packet->IsEcho () && m_Owner->IsStreamingAnswerPings ()) + { + // ping + LogPrint (eLogInfo, "Streaming: Ping received sSID=", sendStreamID); + auto s = std::make_shared (m_Owner->GetService (), *this); + s->HandlePing (packet); + } else { LogPrint (eLogInfo, "Streaming: Unknown stream sSID=", sendStreamID); diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index a56b0565..e8b8db91 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -87,6 +87,7 @@ namespace stream bool IsSYN () const { return GetFlags () & PACKET_FLAG_SYNCHRONIZE; }; bool IsNoAck () const { return GetFlags () & PACKET_FLAG_NO_ACK; }; + bool IsEcho () const { return GetFlags () & PACKET_FLAG_ECHO; }; }; struct PacketCmp @@ -168,6 +169,7 @@ namespace stream StreamingDestination& GetLocalDestination () { return m_LocalDestination; }; void HandleNextPacket (Packet * packet); + void HandlePing (Packet * packet); size_t Send (const uint8_t * buf, size_t len); void AsyncSend (const uint8_t * buf, size_t len, SendHandler handler); diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index e1316a7f..a70add7d 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -453,6 +453,7 @@ namespace client options[I2CP_PARAM_MIN_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MIN_TUNNEL_LATENCY, DEFAULT_MIN_TUNNEL_LATENCY); options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MAX_TUNNEL_LATENCY, DEFAULT_MAX_TUNNEL_LATENCY); options[I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY] = GetI2CPOption(section, I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY, DEFAULT_INITIAL_ACK_DELAY); + options[I2CP_PARAM_STREAMING_ANSWER_PINGS] = GetI2CPOption(section, I2CP_PARAM_STREAMING_ANSWER_PINGS, DEFAULT_ANSWER_PINGS); options[I2CP_PARAM_LEASESET_TYPE] = GetI2CPOption(section, I2CP_PARAM_LEASESET_TYPE, DEFAULT_LEASESET_TYPE); std::string encType = GetI2CPStringOption(section, I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, ""); if (encType.length () > 0) options[I2CP_PARAM_LEASESET_ENCRYPTION_TYPE] = encType; From ee8429199740b69a4e75cc5eb65b62857f1a306e Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 30 Sep 2020 19:06:13 -0400 Subject: [PATCH 34/71] handle i2p.streaming.answerPings properly --- libi2pd/Destination.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index af3b4cbc..e88ac411 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -13,6 +13,7 @@ #include #include #include "Crypto.h" +#include "Config.h" #include "Log.h" #include "FS.h" #include "Timestamp.h" @@ -921,7 +922,7 @@ namespace client m_StreamingAckDelay = std::stoi(it->second); it = params->find (I2CP_PARAM_STREAMING_ANSWER_PINGS); if (it != params->end ()) - m_IsStreamingAnswerPings = (it->second == "true"); + i2p::config::GetOption (it->second, m_IsStreamingAnswerPings); if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) { From 3a2724ec586e9fb7ac6c61b4b4290a0a93aa28e4 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 2 Oct 2020 13:13:27 -0400 Subject: [PATCH 35/71] single thread for I2CP --- libi2pd/Config.cpp | 1 + libi2pd_client/ClientContext.cpp | 3 +- libi2pd_client/I2CP.cpp | 101 ++++++++++++++----------------- libi2pd_client/I2CP.h | 37 ++++++----- 4 files changed, 70 insertions(+), 72 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 7668d6a7..b8016a7c 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -152,6 +152,7 @@ namespace config { ("i2cp.enabled", value()->default_value(false), "Enable or disable I2CP") ("i2cp.address", value()->default_value("127.0.0.1"), "I2CP listen address") ("i2cp.port", value()->default_value(7654), "I2CP listen port") + ("i2cp.singlethread", value()->default_value(true), "Destinations run in the I2CP server's thread") ; options_description i2pcontrol("I2PControl options"); diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index a70add7d..e83e293a 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -102,10 +102,11 @@ namespace client { std::string i2cpAddr; i2p::config::GetOption("i2cp.address", i2cpAddr); uint16_t i2cpPort; i2p::config::GetOption("i2cp.port", i2cpPort); + bool singleThread; i2p::config::GetOption("i2cp.singlethread", singleThread); LogPrint(eLogInfo, "Clients: starting I2CP at ", i2cpAddr, ":", i2cpPort); try { - m_I2CPServer = new I2CPServer (i2cpAddr, i2cpPort); + m_I2CPServer = new I2CPServer (i2cpAddr, i2cpPort, singleThread); m_I2CPServer->Start (); } catch (std::exception& e) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index b0f334f5..24c2496b 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -23,36 +23,13 @@ namespace i2p namespace client { - I2CPDestination::I2CPDestination (std::shared_ptr owner, std::shared_ptr identity, bool isPublic, const std::map& params): - RunnableService ("I2CP"), LeaseSetDestination (GetIOService (), isPublic, ¶ms), + I2CPDestination::I2CPDestination (boost::asio::io_service& service, std::shared_ptr owner, + std::shared_ptr identity, bool isPublic, const std::map& params): + LeaseSetDestination (service, isPublic, ¶ms), m_Owner (owner), m_Identity (identity), m_EncryptionKeyType (m_Identity->GetCryptoKeyType ()) { } - I2CPDestination::~I2CPDestination () - { - if (IsRunning ()) - Stop (); - } - - void I2CPDestination::Start () - { - if (!IsRunning ()) - { - LeaseSetDestination::Start (); - StartIOService (); - } - } - - void I2CPDestination::Stop () - { - if (IsRunning ()) - { - LeaseSetDestination::Stop (); - StopIOService (); - } - } - void I2CPDestination::SetEncryptionPrivateKey (const uint8_t * key) { m_Decryptor = i2p::data::PrivateKeys::CreateDecryptor (m_Identity->GetCryptoKeyType (), key); @@ -217,6 +194,37 @@ namespace client } } + RunnableI2CPDestination::RunnableI2CPDestination (std::shared_ptr owner, + std::shared_ptr identity, bool isPublic, const std::map& params): + RunnableService ("I2CP"), + I2CPDestination (GetIOService (), owner, identity, isPublic, params) + { + } + + RunnableI2CPDestination::~RunnableI2CPDestination () + { + if (IsRunning ()) + Stop (); + } + + void RunnableI2CPDestination::Start () + { + if (!IsRunning ()) + { + I2CPDestination::Start (); + StartIOService (); + } + } + + void RunnableI2CPDestination::Stop () + { + if (IsRunning ()) + { + I2CPDestination::Stop (); + StopIOService (); + } + } + I2CPSession::I2CPSession (I2CPServer& owner, std::shared_ptr socket): m_Owner (owner), m_Socket (socket), m_Payload (nullptr), m_SessionID (0xFFFF), m_MessageID (0), m_IsSendAccepted (true) @@ -451,7 +459,9 @@ namespace client if (params[I2CP_PARAM_DONT_PUBLISH_LEASESET] == "true") isPublic = false; if (!m_Destination) { - m_Destination = std::make_shared(shared_from_this (), identity, isPublic, params); + m_Destination = m_Owner.IsSingleThread () ? + std::make_shared(m_Owner.GetService (), shared_from_this (), identity, isPublic, params): + std::make_shared(shared_from_this (), identity, isPublic, params); SendSessionStatusMessage (1); // created LogPrint (eLogDebug, "I2CP: session ", m_SessionID, " created"); m_Destination->Start (); @@ -800,9 +810,9 @@ namespace client std::placeholders::_1, std::placeholders::_2, buf)); } - I2CPServer::I2CPServer (const std::string& interface, int port): - m_IsRunning (false), m_Thread (nullptr), - m_Acceptor (m_Service, + I2CPServer::I2CPServer (const std::string& interface, int port, bool isSingleThread): + RunnableService ("I2CP"), m_IsSingleThread (isSingleThread), + m_Acceptor (GetIOService (), #ifdef ANDROID I2CPSession::proto::endpoint(std::string (1, '\0') + interface)) // leading 0 for abstract address #else @@ -825,20 +835,18 @@ namespace client I2CPServer::~I2CPServer () { - if (m_IsRunning) + if (IsRunning ()) Stop (); } void I2CPServer::Start () { Accept (); - m_IsRunning = true; - m_Thread = new std::thread (std::bind (&I2CPServer::Run, this)); + StartIOService (); } void I2CPServer::Stop () { - m_IsRunning = false; m_Acceptor.cancel (); { auto sessions = m_Sessions; @@ -846,33 +854,12 @@ namespace client it.second->Stop (); } m_Sessions.clear (); - m_Service.stop (); - if (m_Thread) - { - m_Thread->join (); - delete m_Thread; - m_Thread = nullptr; - } - } - - void I2CPServer::Run () - { - while (m_IsRunning) - { - try - { - m_Service.run (); - } - catch (std::exception& ex) - { - LogPrint (eLogError, "I2CP: runtime exception: ", ex.what ()); - } - } + StopIOService (); } void I2CPServer::Accept () { - auto newSocket = std::make_shared (m_Service); + auto newSocket = std::make_shared (GetIOService ()); m_Acceptor.async_accept (*newSocket, std::bind (&I2CPServer::HandleAccept, this, std::placeholders::_1, newSocket)); } diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index adb648f4..4c6b7531 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -63,16 +63,14 @@ namespace client const char I2CP_PARAM_MESSAGE_RELIABILITY[] = "i2cp.messageReliability"; class I2CPSession; - class I2CPDestination: private i2p::util::RunnableService, public LeaseSetDestination + class I2CPDestination: public LeaseSetDestination { public: - I2CPDestination (std::shared_ptr owner, std::shared_ptr identity, bool isPublic, const std::map& params); - ~I2CPDestination (); - - void Start (); - void Stop (); - + I2CPDestination (boost::asio::io_service& service, std::shared_ptr owner, + std::shared_ptr identity, bool isPublic, const std::map& params); + ~I2CPDestination () {}; + void SetEncryptionPrivateKey (const uint8_t * key); void SetEncryptionType (i2p::data::CryptoKeyType keyType) { m_EncryptionKeyType = keyType; }; void SetECIESx25519EncryptionPrivateKey (const uint8_t * key); @@ -109,6 +107,18 @@ namespace client uint64_t m_LeaseSetExpirationTime; }; + class RunnableI2CPDestination: private i2p::util::RunnableService, public I2CPDestination + { + public: + + RunnableI2CPDestination (std::shared_ptr owner, std::shared_ptr identity, + bool isPublic, const std::map& params); + ~RunnableI2CPDestination (); + + void Start (); + void Stop (); + }; + class I2CPServer; class I2CPSession: public std::enable_shared_from_this { @@ -179,17 +189,18 @@ namespace client }; typedef void (I2CPSession::*I2CPMessageHandler)(const uint8_t * buf, size_t len); - class I2CPServer + class I2CPServer: private i2p::util::RunnableService { public: - I2CPServer (const std::string& interface, int port); + I2CPServer (const std::string& interface, int port, bool isSingleThread); ~I2CPServer (); void Start (); void Stop (); - boost::asio::io_service& GetService () { return m_Service; }; - + boost::asio::io_service& GetService () { return GetIOService (); }; + bool IsSingleThread () const { return m_IsSingleThread; }; + bool InsertSession (std::shared_ptr session); void RemoveSession (uint16_t sessionID); @@ -203,12 +214,10 @@ namespace client private: + bool m_IsSingleThread; I2CPMessageHandler m_MessagesHandlers[256]; std::map > m_Sessions; - bool m_IsRunning; - std::thread * m_Thread; - boost::asio::io_service m_Service; I2CPSession::proto::acceptor m_Acceptor; public: From 9450dc84dacfd6950bab8534160337c9c281c950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=AD=D1=80=D0=B8=D0=BA=20=D0=97=D0=B0=D0=BC=D0=B0=D0=B1?= =?UTF-8?q?=D1=83=D0=B2=D0=B0=D1=80=D0=B0=D0=B5=D0=B2=E2=80=90=D0=81=D0=BC?= =?UTF-8?q?=D0=BE=D0=BB=D0=BA=D1=83=D1=83?= Date: Sun, 4 Oct 2020 03:32:02 +0700 Subject: [PATCH 36/71] Update Win32NetState.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QueryInterface должна увеличивать счётчик ссылок. --- Win32/Win32NetState.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Win32/Win32NetState.h b/Win32/Win32NetState.h index bcb6c8d7..c2ddaee4 100644 --- a/Win32/Win32NetState.h +++ b/Win32/Win32NetState.h @@ -31,7 +31,8 @@ public: } else { Result = E_NOINTERFACE; } - + AddRef(); + return Result; } @@ -90,4 +91,4 @@ void SubscribeToEvents() { } void UnSubscribeFromEvents() { } #endif // WINVER -#endif \ No newline at end of file +#endif From 8483464aab8763ccf141b365a878359f37bc3d80 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 3 Oct 2020 17:20:04 -0400 Subject: [PATCH 37/71] don't attach our RouterInfo to router's request --- libi2pd/Destination.cpp | 12 ++++++------ libi2pd/NetDb.cpp | 40 ++++++++++++++++++++-------------------- libi2pd/NetDb.hpp | 2 +- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index e88ac411..669fd791 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -465,14 +465,14 @@ namespace client if (request->excluded.size () < MAX_NUM_FLOODFILLS_PER_REQUEST) { for (int i = 0; i < num; i++) - { - i2p::data::IdentHash peerHash (buf + 33 + i*32); - if (!request->excluded.count (peerHash) && !i2p::data::netdb.FindRouter (peerHash)) { - LogPrint (eLogInfo, "Destination: Found new floodfill, request it"); // TODO: recheck this message - i2p::data::netdb.RequestDestination (peerHash); + i2p::data::IdentHash peerHash (buf + 33 + i*32); + if (!request->excluded.count (peerHash) && !i2p::data::netdb.FindRouter (peerHash)) + { + LogPrint (eLogInfo, "Destination: Found new floodfill, request it"); + i2p::data::netdb.RequestDestination (peerHash, nullptr, false); // through exploratory + } } - } auto floodfill = i2p::data::netdb.GetClosestFloodfill (key, request->excluded); if (floodfill) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 466016c5..5930baf7 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -610,7 +610,7 @@ namespace data } } - void NetDb::RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete) + void NetDb::RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete, bool direct) { auto dest = m_Requests.CreateRequest (destination, false, requestComplete); // non-exploratory if (!dest) @@ -621,7 +621,23 @@ namespace data auto floodfill = GetClosestFloodfill (destination, dest->GetExcludedPeers ()); if (floodfill) - transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ())); + { + if (direct) + transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ())); + else + { + auto pool = i2p::tunnel::tunnels.GetExploratoryPool (); + auto outbound = pool ? pool->GetNextOutboundTunnel () : nullptr; + auto inbound = pool ? pool->GetNextInboundTunnel () : nullptr; + if (outbound && inbound) + outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0, dest->CreateRequestMessage (floodfill, inbound)); + else + { + LogPrint (eLogError, "NetDb: ", destination.ToBase64(), " destination requested, but no tunnels found"); + m_Requests.RequestComplete (destination, nullptr); + } + } + } else { LogPrint (eLogError, "NetDb: ", destination.ToBase64(), " destination requested, but no floodfills found"); @@ -775,37 +791,21 @@ namespace data // reply to our destination. Try other floodfills if (outbound && inbound) { - std::vector msgs; auto count = dest->GetExcludedPeers ().size (); if (count < 7) { auto nextFloodfill = GetClosestFloodfill (dest->GetDestination (), dest->GetExcludedPeers ()); if (nextFloodfill) { - // tell floodfill about us - msgs.push_back (i2p::tunnel::TunnelMessageBlock - { - i2p::tunnel::eDeliveryTypeRouter, - nextFloodfill->GetIdentHash (), 0, - CreateDatabaseStoreMsg () - }); - // request destination LogPrint (eLogDebug, "NetDb: Try ", key, " at ", count, " floodfill ", nextFloodfill->GetIdentHash ().ToBase64 ()); - auto msg = dest->CreateRequestMessage (nextFloodfill, inbound); - msgs.push_back (i2p::tunnel::TunnelMessageBlock - { - i2p::tunnel::eDeliveryTypeRouter, - nextFloodfill->GetIdentHash (), 0, msg - }); + outbound->SendTunnelDataMsg (nextFloodfill->GetIdentHash (), 0, + dest->CreateRequestMessage (nextFloodfill, inbound)); deleteDest = false; } } else LogPrint (eLogWarning, "NetDb: ", key, " was not found on ", count, " floodfills"); - - if (msgs.size () > 0) - outbound->SendTunnelDataMsg (msgs); } } diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index d4501ab9..f9a57ccd 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -70,7 +70,7 @@ namespace data std::shared_ptr FindLeaseSet (const IdentHash& destination) const; std::shared_ptr FindRouterProfile (const IdentHash& ident) const; - void RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete = nullptr); + void RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete = nullptr, bool direct = true); void RequestDestinationFrom (const IdentHash& destination, const IdentHash & from, bool exploritory, RequestedDestination::RequestComplete requestComplete = nullptr); void HandleDatabaseStoreMsg (std::shared_ptr msg); From c601a2986f3febae1430baf162c09640db30038c Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 4 Oct 2020 00:35:12 +0300 Subject: [PATCH 38/71] [appveyor] test without manual keyring installation --- appveyor.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 9d035653..00dd8c1b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -22,10 +22,10 @@ environment: install: # install new signing keyring -- c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" -- c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" -- c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" +#- c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" +#- c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" +#- c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" +#- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" # remove packages which can break build - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc" # update runtime From cfda807057f361f32f3563cb40b06f14f261dfaf Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 4 Oct 2020 00:45:30 +0300 Subject: [PATCH 39/71] [appveyor] use different mirror for keyring Default repo mirror is not available, changed to other one. --- appveyor.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 00dd8c1b..d5f67b14 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -22,10 +22,10 @@ environment: install: # install new signing keyring -#- c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" -#- c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" -#- c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" -#- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" +- c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" +- c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" +- c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" +- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" # remove packages which can break build - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc" # update runtime From a8d23b5439d363ae3eae3dd7989b1a9a51732a53 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 3 Oct 2020 18:46:12 -0400 Subject: [PATCH 40/71] disable NTCP for good --- libi2pd/Config.cpp | 2 +- libi2pd/RouterContext.cpp | 83 +++++++++++---------------------------- libi2pd/RouterInfo.cpp | 26 ++++-------- libi2pd/RouterInfo.h | 2 - libi2pd/Transports.cpp | 36 +---------------- 5 files changed, 33 insertions(+), 116 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index b8016a7c..e0dc66d8 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -58,7 +58,7 @@ namespace config { ("floodfill", bool_switch()->default_value(false), "Router will be floodfill (default: disabled)") ("bandwidth", value()->default_value(""), "Bandwidth limit: integer in KBps or letters: L (32), O (256), P (2048), X (>9000)") ("share", value()->default_value(100), "Limit of transit traffic from max bandwidth in percents. (default: 100)") - ("ntcp", value()->default_value(false), "Enable NTCP transport (default: disabled)") + ("ntcp", value()->default_value(false), "Ignored. Always false") ("ssu", value()->default_value(true), "Enable SSU transport (default: enabled)") ("ntcpproxy", value()->default_value(""), "Proxy URL for NTCP transport") #ifdef _WIN32 diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index cbbd961e..7333e613 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -63,7 +63,6 @@ namespace i2p bool ipv4; i2p::config::GetOption("ipv4", ipv4); bool ipv6; i2p::config::GetOption("ipv6", ipv6); bool ssu; i2p::config::GetOption("ssu", ssu); - bool ntcp; i2p::config::GetOption("ntcp", ntcp); bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); bool nat; i2p::config::GetOption("nat", nat); std::string ifname; i2p::config::GetOption("ifname", ifname); @@ -83,8 +82,6 @@ namespace i2p if (ssu) routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash ()); - if (ntcp) - routerInfo.AddNTCPAddress (host.c_str(), port); } if (ipv6) { @@ -99,8 +96,6 @@ namespace i2p if (ssu) routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash ()); - if (ntcp) - routerInfo.AddNTCPAddress (host.c_str(), port); } routerInfo.SetCaps (i2p::data::RouterInfo::eReachable | @@ -115,20 +110,17 @@ namespace i2p { if (!m_NTCP2Keys) NewNTCP2Keys (); UpdateNTCP2Address (true); - if (!ntcp) // NTCP2 should replace NTCP + bool published; i2p::config::GetOption("ntcp2.published", published); + if (published) { - bool published; i2p::config::GetOption("ntcp2.published", published); - if (published) + PublishNTCP2Address (port, true); + if (ipv6) { - PublishNTCP2Address (port, true); - if (ipv6) - { - // add NTCP2 ipv6 address - std::string host = "::1"; - if (!i2p::config::IsDefault ("ntcp2.addressv6")) - i2p::config::GetOption ("ntcp2.addressv6", host); - m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v6::from_string (host), port); - } + // add NTCP2 ipv6 address + std::string host = "::1"; + if (!i2p::config::IsDefault ("ntcp2.addressv6")) + i2p::config::GetOption ("ntcp2.addressv6", host); + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v6::from_string (host), port); } } } @@ -444,16 +436,10 @@ namespace i2p addr->ssu->introducers.clear (); port = addr->port; } - // remove NTCP or NTCP2 v4 address - bool ntcp; i2p::config::GetOption("ntcp", ntcp); - if (ntcp) - PublishNTCPAddress (false); - else - { - bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); - if (ntcp2) - PublishNTCP2Address (port, false, true); - } + // remove NTCP2 v4 address + bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); + if (ntcp2) + PublishNTCP2Address (port, false, true); // update UpdateRouterInfo (); } @@ -477,23 +463,16 @@ namespace i2p addr->ssu->introducers.clear (); port = addr->port; } - // insert NTCP or NTCP2 back - bool ntcp; i2p::config::GetOption("ntcp", ntcp); - if (ntcp) - PublishNTCPAddress (true); - else + // insert NTCP2 back + bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); + if (ntcp2) { - // ntcp2 - bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); - if (ntcp2) + bool published; i2p::config::GetOption ("ntcp2.published", published); + if (published) { - bool published; i2p::config::GetOption ("ntcp2.published", published); - if (published) - { - uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); - if (!ntcp2Port) ntcp2Port = port; - PublishNTCP2Address (ntcp2Port, true, true); - } + uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); + if (!ntcp2Port) ntcp2Port = port; + PublishNTCP2Address (ntcp2Port, true, true); } } // update @@ -506,7 +485,7 @@ namespace i2p { m_RouterInfo.EnableV6 (); // insert v6 addresses if necessary - bool foundSSU = false, foundNTCP = false, foundNTCP2 = false; + bool foundSSU = false, foundNTCP2 = false; uint16_t port = 0; auto& addresses = m_RouterInfo.GetAddresses (); for (auto& addr: addresses) @@ -515,12 +494,8 @@ namespace i2p { if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU) foundSSU = true; - else if (addr->IsNTCP2 ()) - { - if (addr->IsPublishedNTCP2 ()) foundNTCP2 = true; - } - else - foundNTCP = true; + else if (addr->IsPublishedNTCP2 ()) + foundNTCP2 = true; } port = addr->port; } @@ -552,16 +527,6 @@ namespace i2p m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address::from_string (ntcp2Host), ntcp2Port); } } - // NTCP - if (!foundNTCP) - { - bool ntcp; i2p::config::GetOption("ntcp", ntcp); - if (ntcp) - { - std::string host = "::1"; - m_RouterInfo.AddNTCPAddress (host.c_str (), port); - } - } } else m_RouterInfo.DisableV6 (); diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 91c12b60..703c853f 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -316,7 +316,7 @@ namespace data } if (introducers) supportedTransports |= eSSUV4; // in case if host is not presented if (isNTCP2Only && address->ntcp2) address->ntcp2->isNTCP2Only = true; - if (supportedTransports) + if (supportedTransports & ~(eNTCPV4 | eNTCPV6)) // exclude NTCP only { addresses->push_back(address); m_SupportedTransports |= supportedTransports; @@ -477,7 +477,12 @@ namespace data s.write ((const char *)&address.date, sizeof (address.date)); std::stringstream properties; if (address.transportStyle == eTransportNTCP) - WriteString (address.IsNTCP2 () ? "NTCP2" : "NTCP", s); + { + if (address.IsNTCP2 ()) + WriteString ("NTCP2", s); + else + continue; // don't write NTCP address + } else if (address.transportStyle == eTransportSSU) { WriteString ("SSU", s); @@ -817,14 +822,6 @@ namespace data return ""; } - bool RouterInfo::IsNTCP (bool v4only) const - { - if (v4only) - return m_SupportedTransports & eNTCPV4; - else - return m_SupportedTransports & (eNTCPV4 | eNTCPV6); - } - bool RouterInfo::IsSSU (bool v4only) const { if (v4only) @@ -907,15 +904,6 @@ namespace data return m_Caps & Caps::eUnreachable; // non-reachable } - std::shared_ptr RouterInfo::GetNTCPAddress (bool v4only) const - { - return GetAddress ( - [v4only](std::shared_ptr address)->bool - { - return (address->transportStyle == eTransportNTCP) && !address->IsNTCP2Only () && (!v4only || address->host.is_v4 ()); - }); - } - std::shared_ptr RouterInfo::GetSSUAddress (bool v4only) const { return GetAddress ( diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index ef902c0e..1c0063b0 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -153,7 +153,6 @@ namespace data uint64_t GetTimestamp () const { return m_Timestamp; }; int GetVersion () const { return m_Version; }; Addresses& GetAddresses () { return *m_Addresses; }; // should be called for local RI only, otherwise must return shared_ptr - std::shared_ptr GetNTCPAddress (bool v4only = true) const; std::shared_ptr GetNTCP2Address (bool publishedOnly, bool v4only = true) const; std::shared_ptr GetSSUAddress (bool v4only = true) const; std::shared_ptr GetSSUV6Address () const; @@ -169,7 +168,6 @@ namespace data void ClearProperties () { m_Properties.clear (); }; bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; }; bool IsReachable () const { return m_Caps & Caps::eReachable; }; - bool IsNTCP (bool v4only = true) const; bool IsSSU (bool v4only = true) const; bool IsSSUV6 () const; bool IsNTCP2 (bool v4only = true) const; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index edfe33fa..54bf3fd9 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -472,41 +472,7 @@ namespace transport } } } - if (peer.numAttempts == 1) // NTCP1 - { - peer.numAttempts++; - auto address = peer.router->GetNTCPAddress (!context.SupportsV6 ()); - if (address && m_NTCPServer) - { - if (!peer.router->UsesIntroducer () && !peer.router->IsUnreachable ()) - { - if(!m_NTCPServer->ShouldLimit()) - { - auto s = std::make_shared (*m_NTCPServer, peer.router); - if(m_NTCPServer->UsingProxy()) - { - NTCPServer::RemoteAddressType remote = NTCPServer::eIP4Address; - std::string addr = address->host.to_string(); - - if(address->host.is_v6()) - remote = NTCPServer::eIP6Address; - - m_NTCPServer->ConnectWithProxy(addr, address->port, remote, s); - } - else - m_NTCPServer->Connect (address->host, address->port, s); - return true; - } - else - { - LogPrint(eLogWarning, "Transports: NTCP Limit hit falling back to SSU"); - } - } - } - else - LogPrint (eLogDebug, "Transports: NTCP address is not present for ", i2p::data::GetIdentHashAbbreviation (ident), ", trying SSU"); - } - if (peer.numAttempts == 2)// SSU + if (peer.numAttempts == 1)// SSU { peer.numAttempts++; if (m_SSUServer && peer.router->IsSSU (!context.SupportsV6 ())) From faae2709d9e8ba7fede3ae73228dec493250cd17 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 3 Oct 2020 21:58:20 -0400 Subject: [PATCH 41/71] removed NTCP --- build/CMakeLists.txt | 1 - daemon/Daemon.cpp | 60 +- daemon/HTTPServer.cpp | 7 - libi2pd/NTCP2.cpp | 2 +- libi2pd/NTCPSession.cpp | 1317 --------------------------------------- libi2pd/NTCPSession.h | 242 ------- libi2pd/Transports.cpp | 70 +-- libi2pd/Transports.h | 6 +- qt/i2pd_qt/i2pd_qt.pro | 2 - 9 files changed, 30 insertions(+), 1677 deletions(-) delete mode 100644 libi2pd/NTCPSession.cpp delete mode 100644 libi2pd/NTCPSession.h diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 8271ce3a..4825855b 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -68,7 +68,6 @@ set(LIBI2PD_SRC "${LIBI2PD_SRC_DIR}/NetDb.cpp" "${LIBI2PD_SRC_DIR}/NetDbRequests.cpp" "${LIBI2PD_SRC_DIR}/NTCP2.cpp" - "${LIBI2PD_SRC_DIR}/NTCPSession.cpp" "${LIBI2PD_SRC_DIR}/Poly1305.cpp" "${LIBI2PD_SRC_DIR}/Profiling.cpp" "${LIBI2PD_SRC_DIR}/Reseed.cpp" diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 264013cf..5f98d47a 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -1,11 +1,3 @@ -/* -* Copyright (c) 2013-2020, The PurpleI2P Project -* -* This file is part of Purple i2pd project and licensed under BSD3 -* -* See full license text in LICENSE file at top of project tree -*/ - #include #include @@ -17,7 +9,6 @@ #include "Base.h" #include "version.h" #include "Transports.h" -#include "NTCPSession.h" #include "RouterInfo.h" #include "RouterContext.h" #include "Tunnel.h" @@ -135,8 +126,8 @@ namespace i2p i2p::context.SetNetID (netID); i2p::context.Init (); - bool ipv6; i2p::config::GetOption("ipv6", ipv6); - bool ipv4; i2p::config::GetOption("ipv4", ipv4); + bool ipv6; i2p::config::GetOption("ipv6", ipv6); + bool ipv4; i2p::config::GetOption("ipv4", ipv4); #ifdef MESHNET // manual override for meshnet ipv4 = false; @@ -151,8 +142,8 @@ namespace i2p i2p::context.SetSupportsV6 (ipv6); i2p::context.SetSupportsV4 (ipv4); - bool ntcp; i2p::config::GetOption("ntcp", ntcp); - i2p::context.PublishNTCPAddress (ntcp, !ipv6); + bool ntcp; i2p::config::GetOption("ntcp", ntcp); + i2p::context.PublishNTCPAddress (ntcp, !ipv6); bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) { @@ -180,13 +171,10 @@ namespace i2p SetMaxNumTransitTunnels (transitTunnels); bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill); - if (isFloodfill) - { + if (isFloodfill) { LogPrint(eLogInfo, "Daemon: router will be floodfill"); i2p::context.SetFloodfill (true); - } - else - { + } else { i2p::context.SetFloodfill (false); } @@ -254,8 +242,7 @@ namespace i2p i2p::transport::transports.RestrictRoutesToFamilies(fams); restricted = fams.size() > 0; } - if (routers.length() > 0) - { + if (routers.length() > 0) { std::set idents; size_t pos = 0, comma; do @@ -291,8 +278,7 @@ namespace i2p i2p::data::netdb.Start(); bool upnp; i2p::config::GetOption("upnp.enabled", upnp); - if (upnp) - { + if (upnp) { d.UPnP = std::unique_ptr(new i2p::transport::UPnP); d.UPnP->Start (); } @@ -304,16 +290,16 @@ namespace i2p d.m_NTPSync->Start (); } - bool ntcp; i2p::config::GetOption("ntcp", ntcp); - bool ssu; i2p::config::GetOption("ssu", ssu); + bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); + bool ssu; i2p::config::GetOption("ssu", ssu); LogPrint(eLogInfo, "Daemon: starting Transports"); if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled"); - if(!ntcp) LogPrint(eLogInfo, "Daemon: ntcp disabled"); + if(!ntcp2) LogPrint(eLogInfo, "Daemon: ntcp2 disabled"); - i2p::transport::transports.Start(ntcp, ssu); - if (i2p::transport::transports.IsBoundNTCP() || i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2()) + i2p::transport::transports.Start(ntcp2, ssu); + if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2()) LogPrint(eLogInfo, "Daemon: Transports started"); - else + else { LogPrint(eLogError, "Daemon: failed to start Transports"); /** shut down netdb right away */ @@ -323,23 +309,23 @@ namespace i2p } bool http; i2p::config::GetOption("http.enabled", http); - if (http) - { + if (http) { std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); LogPrint(eLogInfo, "Daemon: starting webconsole at ", httpAddr, ":", httpPort); - try + try { d.httpServer = std::unique_ptr(new i2p::http::HTTPServer(httpAddr, httpPort)); d.httpServer->Start(); - } - catch (std::exception& ex) + } + catch (std::exception& ex) { LogPrint (eLogError, "Daemon: failed to start webconsole: ", ex.what ()); ThrowFatal ("Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ()); } } + LogPrint(eLogInfo, "Daemon: starting Tunnels"); i2p::tunnel::tunnels.Start(); @@ -352,12 +338,12 @@ namespace i2p std::string i2pcpAddr; i2p::config::GetOption("i2pcontrol.address", i2pcpAddr); uint16_t i2pcpPort; i2p::config::GetOption("i2pcontrol.port", i2pcpPort); LogPrint(eLogInfo, "Daemon: starting I2PControl at ", i2pcpAddr, ":", i2pcpPort); - try + try { d.m_I2PControlService = std::unique_ptr(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort)); d.m_I2PControlService->Start (); - } - catch (std::exception& ex) + } + catch (std::exception& ex) { LogPrint (eLogError, "Daemon: failed to start I2PControl: ", ex.what ()); ThrowFatal ("Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ()); @@ -374,7 +360,7 @@ namespace i2p LogPrint(eLogInfo, "Daemon: stopping Tunnels"); i2p::tunnel::tunnels.Stop(); - if (d.UPnP) + if (d.UPnP) { d.UPnP->Stop (); d.UPnP = nullptr; diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 52b655b9..19734038 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -732,13 +732,6 @@ namespace http { void ShowTransports (std::stringstream& s) { s << "Transports:
\r\n"; - auto ntcpServer = i2p::transport::transports.GetNTCPServer (); - if (ntcpServer) - { - auto sessions = ntcpServer->GetNTCPSessions (); - if (!sessions.empty ()) - ShowNTCPTransports (s, sessions, "NTCP"); - } auto ntcp2Server = i2p::transport::transports.GetNTCP2Server (); if (ntcp2Server) { diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 4e3b219c..cdf660b7 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1435,7 +1435,7 @@ namespace transport { auto timer = std::make_shared(GetService()); - auto timeout = NTCP_CONNECT_TIMEOUT * 5; + auto timeout = NTCP2_CONNECT_TIMEOUT * 5; conn->SetTerminationTimeout(timeout * 2); timer->expires_from_now (boost::posix_time::seconds(timeout)); timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp deleted file mode 100644 index 4d3f1da6..00000000 --- a/libi2pd/NTCPSession.cpp +++ /dev/null @@ -1,1317 +0,0 @@ -/* -* Copyright (c) 2013-2020, The PurpleI2P Project -* -* This file is part of Purple i2pd project and licensed under BSD3 -* -* See full license text in LICENSE file at top of project tree -*/ - -#include -#include -#include - -#include "I2PEndian.h" -#include "Base.h" -#include "Crypto.h" -#include "Log.h" -#include "Timestamp.h" -#include "I2NPProtocol.h" -#include "RouterContext.h" -#include "Transports.h" -#include "NetDb.hpp" -#include "NTCPSession.h" -#include "HTTP.h" -#include "util.h" - -using namespace i2p::crypto; - -namespace i2p -{ -namespace transport -{ - - struct NTCPWork - { - std::shared_ptr session; - }; - - NTCPSession::NTCPSession (NTCPServer& server, std::shared_ptr in_RemoteRouter): - TransportSession (in_RemoteRouter, NTCP_ESTABLISH_TIMEOUT), - m_Server (server), m_Socket (m_Server.GetService ()), - m_IsEstablished (false), m_IsTerminated (false), - m_ReceiveBufferOffset (0), m_NextMessage (nullptr), m_IsSending (false) - { - m_Establisher = new Establisher; - } - - NTCPSession::~NTCPSession () - { - delete m_Establisher; - } - - void NTCPSession::CreateAESKey (uint8_t * pubKey) - { - uint8_t sharedKey[256]; - m_DHKeysPair->Agree (pubKey, sharedKey); // time consuming operation - - i2p::crypto::AESKey aesKey; - if (sharedKey[0] & 0x80) - { - aesKey[0] = 0; - memcpy (aesKey + 1, sharedKey, 31); - } - else if (sharedKey[0]) - memcpy (aesKey, sharedKey, 32); - else - { - // find first non-zero byte - uint8_t * nonZero = sharedKey + 1; - while (!*nonZero) - { - nonZero++; - if (nonZero - sharedKey > 32) - { - LogPrint (eLogWarning, "NTCP: First 32 bytes of shared key is all zeros, ignored"); - return; - } - } - memcpy (aesKey, nonZero, 32); - } - - m_Decryption.SetKey (aesKey); - m_Encryption.SetKey (aesKey); - } - - void NTCPSession::Done () - { - m_Server.GetService ().post (std::bind (&NTCPSession::Terminate, shared_from_this ())); - } - - void NTCPSession::Terminate () - { - if (!m_IsTerminated) - { - m_IsTerminated = true; - m_IsEstablished = false; - m_Socket.close (); - transports.PeerDisconnected (shared_from_this ()); - m_Server.RemoveNTCPSession (shared_from_this ()); - m_SendQueue.clear (); - m_NextMessage = nullptr; - LogPrint (eLogDebug, "NTCP: session terminated"); - } - } - - void NTCPSession::Connected () - { - m_IsEstablished = true; - - delete m_Establisher; - m_Establisher = nullptr; - - m_DHKeysPair = nullptr; - - SetTerminationTimeout (NTCP_TERMINATION_TIMEOUT); - SendTimeSyncMessage (); - transports.PeerConnected (shared_from_this ()); - } - - boost::asio::io_service & NTCPSession::GetService() - { - return m_Server.GetService(); - } - - void NTCPSession::ClientLogin () - { - if (!m_DHKeysPair) - m_DHKeysPair = transports.GetNextDHKeysPair (); - // send Phase1 - const uint8_t * x = m_DHKeysPair->GetPublicKey (); - memcpy (m_Establisher->phase1.pubKey, x, 256); - SHA256(x, 256, m_Establisher->phase1.HXxorHI); - const uint8_t * ident = m_RemoteIdentity->GetIdentHash (); - for (int i = 0; i < 32; i++) - m_Establisher->phase1.HXxorHI[i] ^= ident[i]; - - boost::asio::async_write (m_Socket, boost::asio::buffer (&m_Establisher->phase1, sizeof (NTCPPhase1)), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase1Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); - } - - void NTCPSession::ServerLogin () - { - m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); - // receive Phase1 - boost::asio::async_read (m_Socket, boost::asio::buffer(&m_Establisher->phase1, sizeof (NTCPPhase1)), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase1Received, shared_from_this (), - std::placeholders::_1, std::placeholders::_2)); - } - - void NTCPSession::HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred) - { - (void) bytes_transferred; - if (ecode) - { - LogPrint (eLogInfo, "NTCP: couldn't send Phase 1 message: ", ecode.message ()); - if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - else - { - boost::asio::async_read (m_Socket, boost::asio::buffer(&m_Establisher->phase2, sizeof (NTCPPhase2)), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase2Received, shared_from_this (), - std::placeholders::_1, std::placeholders::_2)); - } - } - - void NTCPSession::HandlePhase1Received (const boost::system::error_code& ecode, std::size_t bytes_transferred) - { - (void) bytes_transferred; - if (ecode) - { - LogPrint (eLogInfo, "NTCP: phase 1 read error: ", ecode.message ()); - if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - else - { - // verify ident - uint8_t digest[32]; - SHA256(m_Establisher->phase1.pubKey, 256, digest); - const uint8_t * ident = i2p::context.GetIdentHash (); - for (int i = 0; i < 32; i++) - { - if ((m_Establisher->phase1.HXxorHI[i] ^ ident[i]) != digest[i]) - { - LogPrint (eLogError, "NTCP: phase 1 error: ident mismatch"); - Terminate (); - return; - } - } - // TODO: check for number of pending keys - auto work = new NTCPWork{shared_from_this()}; - m_Server.Work(work->session, [work, this]() -> std::function { - if (!work->session->m_DHKeysPair) - work->session->m_DHKeysPair = transports.GetNextDHKeysPair (); - work->session->CreateAESKey (work->session->m_Establisher->phase1.pubKey); - return std::bind(&NTCPSession::SendPhase2, work->session, work); - }); - } - } - - void NTCPSession::SendPhase2 (NTCPWork * work) - { - if(work) - delete work; - const uint8_t * y = m_DHKeysPair->GetPublicKey (); - memcpy (m_Establisher->phase2.pubKey, y, 256); - uint8_t xy[512]; - memcpy (xy, m_Establisher->phase1.pubKey, 256); - memcpy (xy + 256, y, 256); - SHA256(xy, 512, m_Establisher->phase2.encrypted.hxy); - uint32_t tsB = htobe32 (i2p::util::GetSecondsSinceEpoch ()); - memcpy (m_Establisher->phase2.encrypted.timestamp, &tsB, 4); - RAND_bytes (m_Establisher->phase2.encrypted.filler, 12); - - m_Encryption.SetIV (y + 240); - m_Decryption.SetIV (m_Establisher->phase1.HXxorHI + 16); - - m_Encryption.Encrypt ((uint8_t *)&m_Establisher->phase2.encrypted, sizeof(m_Establisher->phase2.encrypted), (uint8_t *)&m_Establisher->phase2.encrypted); - boost::asio::async_write(m_Socket, boost::asio::buffer (&m_Establisher->phase2, sizeof (NTCPPhase2)), boost::asio::transfer_all(), - std::bind(&NTCPSession::HandlePhase2Sent, shared_from_this(), std::placeholders::_1, std::placeholders::_2, tsB)); - } - - void NTCPSession::HandlePhase2Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB) - { - (void) bytes_transferred; - if (ecode) - { - LogPrint (eLogInfo, "NTCP: Couldn't send Phase 2 message: ", ecode.message ()); - if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - else - { - boost::asio::async_read (m_Socket, boost::asio::buffer(m_ReceiveBuffer, NTCP_DEFAULT_PHASE3_SIZE), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase3Received, shared_from_this (), - std::placeholders::_1, std::placeholders::_2, tsB)); - } - } - - void NTCPSession::HandlePhase2Received (const boost::system::error_code& ecode, std::size_t bytes_transferred) - { - (void) bytes_transferred; - if (ecode) - { - LogPrint (eLogInfo, "NTCP: Phase 2 read error: ", ecode.message (), ". Wrong ident assumed"); - if (ecode != boost::asio::error::operation_aborted) - { - // this RI is not valid - i2p::data::netdb.SetUnreachable (GetRemoteIdentity ()->GetIdentHash (), true); - transports.ReuseDHKeysPair (m_DHKeysPair); - m_DHKeysPair = nullptr; - Terminate (); - } - } - else - { - auto work = new NTCPWork{shared_from_this()}; - m_Server.Work(work->session, [work, this]() -> std::function { - work->session->CreateAESKey (work->session->m_Establisher->phase2.pubKey); - return std::bind(&NTCPSession::HandlePhase2, work->session, work); - }); - } - } - - void NTCPSession::HandlePhase2 (NTCPWork * work) - { - if(work) delete work; - m_Decryption.SetIV (m_Establisher->phase2.pubKey + 240); - m_Encryption.SetIV (m_Establisher->phase1.HXxorHI + 16); - - m_Decryption.Decrypt((uint8_t *)&m_Establisher->phase2.encrypted, sizeof(m_Establisher->phase2.encrypted), (uint8_t *)&m_Establisher->phase2.encrypted); - // verify - uint8_t xy[512]; - memcpy (xy, m_DHKeysPair->GetPublicKey (), 256); - memcpy (xy + 256, m_Establisher->phase2.pubKey, 256); - uint8_t digest[32]; - SHA256 (xy, 512, digest); - if (memcmp(m_Establisher->phase2.encrypted.hxy, digest, 32)) - { - LogPrint (eLogError, "NTCP: Phase 2 process error: incorrect hash"); - transports.ReuseDHKeysPair (m_DHKeysPair); - m_DHKeysPair = nullptr; - Terminate (); - return ; - } - SendPhase3 (); - } - - void NTCPSession::SendPhase3 () - { - auto& keys = i2p::context.GetPrivateKeys (); - uint8_t * buf = m_ReceiveBuffer; - htobe16buf (buf, keys.GetPublic ()->GetFullLen ()); - buf += 2; - buf += i2p::context.GetIdentity ()->ToBuffer (buf, NTCP_BUFFER_SIZE); - uint32_t tsA = htobe32 (i2p::util::GetSecondsSinceEpoch ()); - htobuf32(buf,tsA); - buf += 4; - size_t signatureLen = keys.GetPublic ()->GetSignatureLen (); - size_t len = (buf - m_ReceiveBuffer) + signatureLen; - size_t paddingSize = len & 0x0F; // %16 - if (paddingSize > 0) - { - paddingSize = 16 - paddingSize; - // fill padding with random data - RAND_bytes(buf, paddingSize); - buf += paddingSize; - len += paddingSize; - } - - SignedData s; - s.Insert (m_Establisher->phase1.pubKey, 256); // x - s.Insert (m_Establisher->phase2.pubKey, 256); // y - s.Insert (m_RemoteIdentity->GetIdentHash (), 32); // ident - s.Insert (tsA); // tsA - s.Insert (m_Establisher->phase2.encrypted.timestamp, 4); // tsB - s.Sign (keys, buf); - - m_Encryption.Encrypt(m_ReceiveBuffer, len, m_ReceiveBuffer); - boost::asio::async_write (m_Socket, boost::asio::buffer (m_ReceiveBuffer, len), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase3Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, tsA)); - } - - void NTCPSession::HandlePhase3Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA) - { - (void) bytes_transferred; - if (ecode) - { - LogPrint (eLogInfo, "NTCP: Couldn't send Phase 3 message: ", ecode.message ()); - if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - else - { - // wait for phase4 - auto signatureLen = m_RemoteIdentity->GetSignatureLen (); - size_t paddingSize = signatureLen & 0x0F; // %16 - if (paddingSize > 0) signatureLen += (16 - paddingSize); - boost::asio::async_read (m_Socket, boost::asio::buffer(m_ReceiveBuffer, signatureLen), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase4Received, shared_from_this (), - std::placeholders::_1, std::placeholders::_2, tsA)); - } - } - - void NTCPSession::HandlePhase3Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB) - { - if (ecode) - { - LogPrint (eLogInfo, "NTCP: Phase 3 read error: ", ecode.message ()); - if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - else - { - m_Decryption.Decrypt (m_ReceiveBuffer, bytes_transferred, m_ReceiveBuffer); - uint8_t * buf = m_ReceiveBuffer; - uint16_t size = bufbe16toh (buf); - auto identity = std::make_shared (buf + 2, size); - if (m_Server.FindNTCPSession (identity->GetIdentHash ())) - { - LogPrint (eLogInfo, "NTCP: session already exists"); - Terminate (); - } - auto existing = i2p::data::netdb.FindRouter (identity->GetIdentHash ()); // check if exists already - SetRemoteIdentity (existing ? existing->GetRouterIdentity () : identity); - - size_t expectedSize = size + 2/*size*/ + 4/*timestamp*/ + m_RemoteIdentity->GetSignatureLen (); - size_t paddingLen = expectedSize & 0x0F; - if (paddingLen) paddingLen = (16 - paddingLen); - if (expectedSize > NTCP_DEFAULT_PHASE3_SIZE) - { - // we need more bytes for Phase3 - expectedSize += paddingLen; - boost::asio::async_read (m_Socket, boost::asio::buffer(m_ReceiveBuffer + NTCP_DEFAULT_PHASE3_SIZE, expectedSize - NTCP_DEFAULT_PHASE3_SIZE), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase3ExtraReceived, shared_from_this (), - std::placeholders::_1, std::placeholders::_2, tsB, paddingLen)); - } - else - HandlePhase3 (tsB, paddingLen); - } - } - - void NTCPSession::HandlePhase3ExtraReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB, size_t paddingLen) - { - if (ecode) - { - LogPrint (eLogInfo, "NTCP: Phase 3 extra read error: ", ecode.message ()); - if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - else - { - m_Decryption.Decrypt (m_ReceiveBuffer + NTCP_DEFAULT_PHASE3_SIZE, bytes_transferred, m_ReceiveBuffer+ NTCP_DEFAULT_PHASE3_SIZE); - HandlePhase3 (tsB, paddingLen); - } - } - - void NTCPSession::HandlePhase3 (uint32_t tsB, size_t paddingLen) - { - uint8_t * buf = m_ReceiveBuffer + m_RemoteIdentity->GetFullLen () + 2 /*size*/; - uint32_t tsA = buf32toh(buf); - buf += 4; - buf += paddingLen; - - // check timestamp - auto ts = i2p::util::GetSecondsSinceEpoch (); - uint32_t tsA1 = be32toh (tsA); - if (tsA1 < ts - NTCP_CLOCK_SKEW || tsA1 > ts + NTCP_CLOCK_SKEW) - { - LogPrint (eLogError, "NTCP: Phase3 time difference ", (int)(ts - tsA1), " exceeds clock skew"); - Terminate (); - return; - } - - // check signature - SignedData s; - s.Insert (m_Establisher->phase1.pubKey, 256); // x - s.Insert (m_Establisher->phase2.pubKey, 256); // y - s.Insert (i2p::context.GetRouterInfo ().GetIdentHash (), 32); // ident - s.Insert (tsA); // tsA - s.Insert (tsB); // tsB - if (!s.Verify (m_RemoteIdentity, buf)) - { - LogPrint (eLogError, "NTCP: signature verification failed"); - Terminate (); - return; - } - - SendPhase4 (tsA, tsB); - } - - void NTCPSession::SendPhase4 (uint32_t tsA, uint32_t tsB) - { - SignedData s; - s.Insert (m_Establisher->phase1.pubKey, 256); // x - s.Insert (m_Establisher->phase2.pubKey, 256); // y - s.Insert (m_RemoteIdentity->GetIdentHash (), 32); // ident - s.Insert (tsA); // tsA - s.Insert (tsB); // tsB - auto& keys = i2p::context.GetPrivateKeys (); - auto signatureLen = keys.GetPublic ()->GetSignatureLen (); - s.Sign (keys, m_ReceiveBuffer); - size_t paddingSize = signatureLen & 0x0F; // %16 - if (paddingSize > 0) signatureLen += (16 - paddingSize); - m_Encryption.Encrypt (m_ReceiveBuffer, signatureLen, m_ReceiveBuffer); - - boost::asio::async_write (m_Socket, boost::asio::buffer (m_ReceiveBuffer, signatureLen), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase4Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); - } - - void NTCPSession::HandlePhase4Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred) - { - (void) bytes_transferred; - if (ecode) - { - LogPrint (eLogWarning, "NTCP: Couldn't send Phase 4 message: ", ecode.message ()); - if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - else - { - LogPrint (eLogDebug, "NTCP: Server session from ", m_Socket.remote_endpoint (), " connected"); - m_Server.AddNTCPSession (shared_from_this ()); - - Connected (); - m_ReceiveBufferOffset = 0; - m_NextMessage = nullptr; - Receive (); - } - } - - void NTCPSession::HandlePhase4Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA) - { - if (ecode) - { - LogPrint (eLogError, "NTCP: Phase 4 read error: ", ecode.message (), ". Check your clock"); - if (ecode != boost::asio::error::operation_aborted) - { - // this router doesn't like us - i2p::data::netdb.SetUnreachable (GetRemoteIdentity ()->GetIdentHash (), true); - Terminate (); - } - } - else - { - m_Decryption.Decrypt(m_ReceiveBuffer, bytes_transferred, m_ReceiveBuffer); - - // check timestamp - uint32_t tsB = bufbe32toh (m_Establisher->phase2.encrypted.timestamp); - auto ts = i2p::util::GetSecondsSinceEpoch (); - if (tsB < ts - NTCP_CLOCK_SKEW || tsB > ts + NTCP_CLOCK_SKEW) - { - LogPrint (eLogError, "NTCP: Phase4 time difference ", (int)(ts - tsB), " exceeds clock skew"); - Terminate (); - return; - } - - // verify signature - SignedData s; - s.Insert (m_Establisher->phase1.pubKey, 256); // x - s.Insert (m_Establisher->phase2.pubKey, 256); // y - s.Insert (i2p::context.GetIdentHash (), 32); // ident - s.Insert (tsA); // tsA - s.Insert (m_Establisher->phase2.encrypted.timestamp, 4); // tsB - - if (!s.Verify (m_RemoteIdentity, m_ReceiveBuffer)) - { - LogPrint (eLogError, "NTCP: Phase 4 process error: signature verification failed"); - Terminate (); - return; - } - LogPrint (eLogDebug, "NTCP: session to ", m_Socket.remote_endpoint (), " connected"); - Connected (); - - m_ReceiveBufferOffset = 0; - m_NextMessage = nullptr; - Receive (); - } - } - - void NTCPSession::Receive () - { - m_Socket.async_read_some (boost::asio::buffer(m_ReceiveBuffer + m_ReceiveBufferOffset, NTCP_BUFFER_SIZE - m_ReceiveBufferOffset), - std::bind(&NTCPSession::HandleReceived, shared_from_this (), - std::placeholders::_1, std::placeholders::_2)); - } - - void NTCPSession::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) - { - if (ecode) - { - if (ecode != boost::asio::error::operation_aborted) - LogPrint (eLogDebug, "NTCP: Read error: ", ecode.message ()); - //if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - else - { - m_NumReceivedBytes += bytes_transferred; - i2p::transport::transports.UpdateReceivedBytes (bytes_transferred); - m_ReceiveBufferOffset += bytes_transferred; - - if (m_ReceiveBufferOffset >= 16) - { - // process received data - uint8_t * nextBlock = m_ReceiveBuffer; - while (m_ReceiveBufferOffset >= 16) - { - if (!DecryptNextBlock (nextBlock)) // 16 bytes - { - Terminate (); - return; - } - nextBlock += 16; - m_ReceiveBufferOffset -= 16; - } - if (m_ReceiveBufferOffset > 0) - memcpy (m_ReceiveBuffer, nextBlock, m_ReceiveBufferOffset); - } - - // read and process more is available - boost::system::error_code ec; - size_t moreBytes = m_Socket.available(ec); - if (moreBytes && !ec) - { - uint8_t * buf = nullptr, * moreBuf = m_ReceiveBuffer; - if (moreBytes + m_ReceiveBufferOffset > NTCP_BUFFER_SIZE) - { - buf = new uint8_t[moreBytes + m_ReceiveBufferOffset + 16]; - moreBuf = buf; - uint8_t rem = ((size_t)buf) & 0x0f; - if (rem) moreBuf += (16 - rem); // align 16 - if (m_ReceiveBufferOffset) - memcpy (moreBuf, m_ReceiveBuffer, m_ReceiveBufferOffset); - } - moreBytes = m_Socket.read_some (boost::asio::buffer (moreBuf + m_ReceiveBufferOffset, moreBytes), ec); - if (ec) - { - LogPrint (eLogInfo, "NTCP: Read more bytes error: ", ec.message ()); - delete[] buf; - Terminate (); - return; - } - m_ReceiveBufferOffset += moreBytes; - m_NumReceivedBytes += moreBytes; - i2p::transport::transports.UpdateReceivedBytes (moreBytes); - // process more data - uint8_t * nextBlock = moreBuf; - while (m_ReceiveBufferOffset >= 16) - { - if (!DecryptNextBlock (nextBlock)) // 16 bytes - { - delete[] buf; - Terminate (); - return; - } - nextBlock += 16; - m_ReceiveBufferOffset -= 16; - } - if (m_ReceiveBufferOffset > 0) - memcpy (m_ReceiveBuffer, nextBlock, m_ReceiveBufferOffset); // nextBlock points to memory inside buf - delete[] buf; - } - m_Handler.Flush (); - - m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); - Receive (); - } - } - - bool NTCPSession::DecryptNextBlock (const uint8_t * encrypted) // 16 bytes - { - if (!m_NextMessage) // new message, header expected - { - // decrypt header and extract length - uint8_t buf[16]; - m_Decryption.Decrypt (encrypted, buf); - uint16_t dataSize = bufbe16toh (buf); - if (dataSize) - { - // new message - if (dataSize + 16U + 15U > NTCP_MAX_MESSAGE_SIZE - 2) // + 6 + padding - { - LogPrint (eLogError, "NTCP: data size ", dataSize, " exceeds max size"); - return false; - } - m_NextMessage = (dataSize + 16U + 15U) <= I2NP_MAX_SHORT_MESSAGE_SIZE - 2 ? NewI2NPShortMessage () : NewI2NPMessage (); - m_NextMessage->Align (16); - m_NextMessage->offset += 2; // size field - m_NextMessage->len = m_NextMessage->offset + dataSize; - memcpy (m_NextMessage->GetBuffer () - 2, buf, 16); - m_NextMessageOffset = 16; - } - else - { - // timestamp - int diff = (int)bufbe32toh (buf + 2) - (int)i2p::util::GetSecondsSinceEpoch (); - LogPrint (eLogInfo, "NTCP: Timestamp. Time difference ", diff, " seconds"); - return true; - } - } - else // message continues - { - m_Decryption.Decrypt (encrypted, m_NextMessage->GetBuffer () - 2 + m_NextMessageOffset); - m_NextMessageOffset += 16; - } - - if (m_NextMessageOffset >= m_NextMessage->GetLength () + 2 + 4) // +checksum - { - // we have a complete I2NP message - uint8_t checksum[4]; - htobe32buf (checksum, adler32 (adler32 (0, Z_NULL, 0), m_NextMessage->GetBuffer () - 2, m_NextMessageOffset - 4)); - if (!memcmp (m_NextMessage->GetBuffer () - 2 + m_NextMessageOffset - 4, checksum, 4)) - { - if (!m_NextMessage->IsExpired ()) - { - m_Handler.PutNextMessage (m_NextMessage); - } - else - LogPrint (eLogInfo, "NTCP: message expired"); - } - else - LogPrint (eLogWarning, "NTCP: Incorrect adler checksum of message, dropped"); - m_NextMessage = nullptr; - } - return true; - } - - void NTCPSession::Send (std::shared_ptr msg) - { - m_IsSending = true; - boost::asio::async_write (m_Socket, CreateMsgBuffer (msg), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandleSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, std::vector >{ msg })); - } - - boost::asio::const_buffers_1 NTCPSession::CreateMsgBuffer (std::shared_ptr msg) - { - uint8_t * sendBuffer; - int len; - - if (msg) - { - // regular I2NP - if (msg->offset < 2) - LogPrint (eLogError, "NTCP: Malformed I2NP message"); // TODO: - sendBuffer = msg->GetBuffer () - 2; - len = msg->GetLength (); - htobe16buf (sendBuffer, len); - } - else - { - // prepare timestamp - sendBuffer = m_TimeSyncBuffer; - len = 4; - htobuf16(sendBuffer, 0); - htobe32buf (sendBuffer + 2, i2p::util::GetSecondsSinceEpoch ()); - } - int rem = (len + 6) & 0x0F; // %16 - int padding = 0; - if (rem > 0) { - padding = 16 - rem; - // fill with random padding - RAND_bytes(sendBuffer + len + 2, padding); - } - htobe32buf (sendBuffer + len + 2 + padding, adler32 (adler32 (0, Z_NULL, 0), sendBuffer, len + 2+ padding)); - - int l = len + padding + 6; - m_Encryption.Encrypt(sendBuffer, l, sendBuffer); - return boost::asio::buffer ((const uint8_t *)sendBuffer, l); - } - - - void NTCPSession::Send (const std::vector >& msgs) - { - m_IsSending = true; - std::vector bufs; - for (const auto& it: msgs) - bufs.push_back (CreateMsgBuffer (it)); - boost::asio::async_write (m_Socket, bufs, boost::asio::transfer_all (), - std::bind(&NTCPSession::HandleSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, msgs)); - } - - void NTCPSession::HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, std::vector > msgs) - { - (void) msgs; - m_IsSending = false; - if (ecode) - { - LogPrint (eLogWarning, "NTCP: Couldn't send msgs: ", ecode.message ()); - // we shouldn't call Terminate () here, because HandleReceive takes care - // TODO: 'delete this' statement in Terminate () must be eliminated later - // Terminate (); - } - else - { - m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); - m_NumSentBytes += bytes_transferred; - i2p::transport::transports.UpdateSentBytes (bytes_transferred); - if (!m_SendQueue.empty()) - { - Send (m_SendQueue); - m_SendQueue.clear (); - } - } - } - - void NTCPSession::SendTimeSyncMessage () - { - Send (nullptr); - } - - void NTCPSession::SendI2NPMessages (const std::vector >& msgs) - { - m_Server.GetService ().post (std::bind (&NTCPSession::PostI2NPMessages, shared_from_this (), msgs)); - } - - void NTCPSession::PostI2NPMessages (std::vector > msgs) - { - if (m_IsTerminated) return; - if (m_IsSending) - { - if (m_SendQueue.size () < NTCP_MAX_OUTGOING_QUEUE_SIZE) - { - for (const auto& it: msgs) - m_SendQueue.push_back (it); - } - else - { - LogPrint (eLogWarning, "NTCP: outgoing messages queue size exceeds ", NTCP_MAX_OUTGOING_QUEUE_SIZE); - Terminate (); - } - } - else - Send (msgs); - } - -//----------------------------------------- - NTCPServer::NTCPServer (int workers): - m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service), - m_TerminationTimer (m_Service), m_NTCPAcceptor (nullptr), m_NTCPV6Acceptor (nullptr), - m_ProxyType(eNoProxy), m_Resolver(m_Service), m_ProxyEndpoint(nullptr), - m_SoftLimit(0), m_HardLimit(0) - { - if(workers <= 0) workers = 1; - m_CryptoPool = std::make_shared(workers); - } - - NTCPServer::~NTCPServer () - { - Stop (); - } - - void NTCPServer::Start () - { - if (!m_IsRunning) - { - m_IsRunning = true; - m_Thread = new std::thread (std::bind (&NTCPServer::Run, this)); - // we are using a proxy, don't create any acceptors - if(UsingProxy()) - { - // TODO: resolve proxy until it is resolved - boost::asio::ip::tcp::resolver::query q(m_ProxyAddress, std::to_string(m_ProxyPort)); - boost::system::error_code e; - auto itr = m_Resolver.resolve(q, e); - if(e) - { - LogPrint(eLogError, "NTCP: Failed to resolve proxy ", e.message()); - } - else - { - m_ProxyEndpoint = new boost::asio::ip::tcp::endpoint(*itr); - } - } - else - { - // create acceptors - auto& addresses = context.GetRouterInfo ().GetAddresses (); - for (const auto& address: addresses) - { - if (!address) continue; - if (address->transportStyle == i2p::data::RouterInfo::eTransportNTCP && !address->IsNTCP2 ()) - { - if (address->host.is_v4()) - { - try - { - m_NTCPAcceptor = new boost::asio::ip::tcp::acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), address->port)); - LogPrint (eLogInfo, "NTCP: Start listening v6 TCP port ", address->port); - } - catch ( std::exception & ex ) - { - /** fail to bind ip4 */ - LogPrint(eLogError, "NTCP: Failed to bind to v4 port ", address->port, ": ", ex.what()); - ThrowFatal ("Unable to start IPv4 NTCP transport at port ", address->port, ": ", ex.what ()); - continue; - } - - LogPrint (eLogInfo, "NTCP: Start listening TCP port ", address->port); - auto conn = std::make_shared(*this); - m_NTCPAcceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAccept, this, conn, std::placeholders::_1)); - } - else if (address->host.is_v6() && context.SupportsV6 ()) - { - m_NTCPV6Acceptor = new boost::asio::ip::tcp::acceptor (m_Service); - try - { - m_NTCPV6Acceptor->open (boost::asio::ip::tcp::v6()); - m_NTCPV6Acceptor->set_option (boost::asio::ip::v6_only (true)); - m_NTCPV6Acceptor->set_option (boost::asio::socket_base::reuse_address (true)); - m_NTCPV6Acceptor->bind (boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v6(), address->port)); - m_NTCPV6Acceptor->listen (); - - LogPrint (eLogInfo, "NTCP: Start listening v6 TCP port ", address->port); - auto conn = std::make_shared (*this); - m_NTCPV6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAcceptV6, this, conn, std::placeholders::_1)); - } - catch ( std::exception & ex ) - { - LogPrint(eLogError, "NTCP: failed to bind to v6 port ", address->port, ": ", ex.what()); - ThrowFatal (eLogError, "Unable to start IPv6 NTCP transport at port ", address->port, ": ", ex.what ()); - continue; - } - } - } - } - } - ScheduleTermination (); - } - } - - void NTCPServer::Stop () - { - { - // we have to copy it because Terminate changes m_NTCPSessions - auto ntcpSessions = m_NTCPSessions; - for (auto& it: ntcpSessions) - it.second->Terminate (); - for (auto& it: m_PendingIncomingSessions) - it->Terminate (); - } - m_NTCPSessions.clear (); - - if (m_IsRunning) - { - m_IsRunning = false; - m_TerminationTimer.cancel (); - if (m_NTCPAcceptor) - { - delete m_NTCPAcceptor; - m_NTCPAcceptor = nullptr; - } - if (m_NTCPV6Acceptor) - { - delete m_NTCPV6Acceptor; - m_NTCPV6Acceptor = nullptr; - } - m_Service.stop (); - if (m_Thread) - { - m_Thread->join (); - delete m_Thread; - m_Thread = nullptr; - } - if(m_ProxyEndpoint) - { - delete m_ProxyEndpoint; - m_ProxyEndpoint = nullptr; - } - } - } - - void NTCPServer::Run () - { - while (m_IsRunning) - { - try - { - m_Service.run (); - } - catch (std::exception& ex) - { - LogPrint (eLogError, "NTCP: runtime exception: ", ex.what ()); - } - } - } - - bool NTCPServer::AddNTCPSession (std::shared_ptr session) - { - if (!session || !session->GetRemoteIdentity ()) return false; - auto& ident = session->GetRemoteIdentity ()->GetIdentHash (); - auto it = m_NTCPSessions.find (ident); - if (it != m_NTCPSessions.end ()) - { - LogPrint (eLogWarning, "NTCP: session to ", ident.ToBase64 (), " already exists"); - session->Terminate(); - return false; - } - m_NTCPSessions.insert (std::pair >(ident, session)); - return true; - } - - void NTCPServer::RemoveNTCPSession (std::shared_ptr session) - { - if (session && session->GetRemoteIdentity ()) - m_NTCPSessions.erase (session->GetRemoteIdentity ()->GetIdentHash ()); - } - - std::shared_ptr NTCPServer::FindNTCPSession (const i2p::data::IdentHash& ident) - { - auto it = m_NTCPSessions.find (ident); - if (it != m_NTCPSessions.end ()) - return it->second; - return nullptr; - } - - void NTCPServer::HandleAccept (std::shared_ptr conn, const boost::system::error_code& error) - { - if (!error) - { - boost::system::error_code ec; - auto ep = conn->GetSocket ().remote_endpoint(ec); - if (!ec) - { - if(ShouldLimit()) - { - // hit limit, close premature - LogPrint(eLogWarning, "NTCP: limiting with backoff session from ", ep); - conn->Terminate(); - return; - } - LogPrint (eLogDebug, "NTCP: Connected from ", ep); - if (conn) - { - conn->ServerLogin (); - m_PendingIncomingSessions.push_back (conn); - } - } - else - LogPrint (eLogError, "NTCP: Connected from error ", ec.message ()); - } - - - if (error != boost::asio::error::operation_aborted) - { - conn = std::make_shared (*this); - m_NTCPAcceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAccept, this, - conn, std::placeholders::_1)); - } - } - - void NTCPServer::HandleAcceptV6 (std::shared_ptr conn, const boost::system::error_code& error) - { - if (!error) - { - boost::system::error_code ec; - auto ep = conn->GetSocket ().remote_endpoint(ec); - if (!ec) - { - if(ShouldLimit()) - { - // hit limit, close premature - LogPrint(eLogWarning, "NTCP: limiting with backoff on session from ", ep); - conn->Terminate(); - return; - } - - LogPrint (eLogDebug, "NTCP: Connected from ", ep); - if (conn) - { - conn->ServerLogin (); - m_PendingIncomingSessions.push_back (conn); - } - } - else - LogPrint (eLogError, "NTCP: Connected from error ", ec.message ()); - } - - if (error != boost::asio::error::operation_aborted) - { - conn = std::make_shared (*this); - m_NTCPV6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAcceptV6, this, - conn, std::placeholders::_1)); - } - } - - void NTCPServer::Connect(const boost::asio::ip::address & address, uint16_t port, std::shared_ptr conn) - { - LogPrint (eLogDebug, "NTCP: Connecting to ", address ,":", port); - m_Service.post([=]() { - if (this->AddNTCPSession (conn)) - { - - auto timer = std::make_shared(m_Service); - timer->expires_from_now (boost::posix_time::seconds(NTCP_CONNECT_TIMEOUT)); - timer->async_wait ([conn](const boost::system::error_code& ecode) { - if (ecode != boost::asio::error::operation_aborted) - { - LogPrint (eLogInfo, "NTCP: Not connected in ", NTCP_CONNECT_TIMEOUT, " seconds"); - conn->Terminate (); - } - }); - conn->GetSocket ().async_connect (boost::asio::ip::tcp::endpoint (address, port), std::bind (&NTCPServer::HandleConnect, this, std::placeholders::_1, conn, timer)); - } - }); - } - - void NTCPServer::ConnectWithProxy (const std::string& host, uint16_t port, RemoteAddressType addrtype, std::shared_ptr conn) - { - if(m_ProxyEndpoint == nullptr) - { - return; - } - m_Service.post([=]() { - if (this->AddNTCPSession (conn)) - { - - auto timer = std::make_shared(m_Service); - auto timeout = NTCP_CONNECT_TIMEOUT * 5; - conn->SetTerminationTimeout(timeout * 2); - timer->expires_from_now (boost::posix_time::seconds(timeout)); - timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) { - if (ecode != boost::asio::error::operation_aborted) - { - LogPrint (eLogInfo, "NTCP: Not connected in ", timeout, " seconds"); - i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); - conn->Terminate (); - } - }); - conn->GetSocket ().async_connect (*m_ProxyEndpoint, std::bind (&NTCPServer::HandleProxyConnect, this, std::placeholders::_1, conn, timer, host, port, addrtype)); - } - }); - } - - void NTCPServer::HandleConnect (const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer) - { - timer->cancel (); - if (ecode) - { - LogPrint (eLogInfo, "NTCP: Connect error ", ecode.message ()); - if (ecode != boost::asio::error::operation_aborted) - i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); - conn->Terminate (); - } - else - { - LogPrint (eLogDebug, "NTCP: Connected to ", conn->GetSocket ().remote_endpoint ()); - conn->ClientLogin (); - } - } - - void NTCPServer::UseProxy(ProxyType proxytype, const std::string & addr, uint16_t port) - { - m_ProxyType = proxytype; - m_ProxyAddress = addr; - m_ProxyPort = port; - } - - void NTCPServer::HandleProxyConnect(const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) - { - if(ecode) - { - LogPrint(eLogWarning, "NTCP: failed to connect to proxy ", ecode.message()); - timer->cancel(); - conn->Terminate(); - return; - } - if(m_ProxyType == eSocksProxy) - { - // TODO: support username/password auth etc - uint8_t buff[3] = {0x05, 0x01, 0x00}; - boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, 3), boost::asio::transfer_all(), [=] (const boost::system::error_code & ec, std::size_t transferred) { - (void) transferred; - if(ec) - { - LogPrint(eLogWarning, "NTCP: socks5 write error ", ec.message()); - } - }); - uint8_t readbuff[2]; - boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff, 2), [=](const boost::system::error_code & ec, std::size_t transferred) { - if(ec) - { - LogPrint(eLogError, "NTCP: socks5 read error ", ec.message()); - timer->cancel(); - conn->Terminate(); - return; - } - else if(transferred == 2) - { - if(readbuff[1] == 0x00) - { - AfterSocksHandshake(conn, timer, host, port, addrtype); - return; - } - else if (readbuff[1] == 0xff) - { - LogPrint(eLogError, "NTCP: socks5 proxy rejected authentication"); - timer->cancel(); - conn->Terminate(); - return; - } - } - LogPrint(eLogError, "NTCP: socks5 server gave invalid response"); - timer->cancel(); - conn->Terminate(); - }); - } - else if(m_ProxyType == eHTTPProxy) - { - i2p::http::HTTPReq req; - req.method = "CONNECT"; - req.version ="HTTP/1.1"; - if(addrtype == eIP6Address) - req.uri = "[" + host + "]:" + std::to_string(port); - else - req.uri = host + ":" + std::to_string(port); - - boost::asio::streambuf writebuff; - std::ostream out(&writebuff); - out << req.to_string(); - - boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), [=](const boost::system::error_code & ec, std::size_t transferred) { - (void) transferred; - if(ec) - LogPrint(eLogError, "NTCP: http proxy write error ", ec.message()); - }); - - boost::asio::streambuf * readbuff = new boost::asio::streambuf; - boost::asio::async_read_until(conn->GetSocket(), *readbuff, "\r\n\r\n", [=] (const boost::system::error_code & ec, std::size_t transferred) { - if(ec) - { - LogPrint(eLogError, "NTCP: http proxy read error ", ec.message()); - timer->cancel(); - conn->Terminate(); - } - else - { - readbuff->commit(transferred); - i2p::http::HTTPRes res; - if(res.parse(boost::asio::buffer_cast(readbuff->data()), readbuff->size()) > 0) - { - if(res.code == 200) - { - timer->cancel(); - conn->ClientLogin(); - delete readbuff; - return; - } - else - { - LogPrint(eLogError, "NTCP: http proxy rejected request ", res.code); - } - } - else - LogPrint(eLogError, "NTCP: http proxy gave malformed response"); - timer->cancel(); - conn->Terminate(); - delete readbuff; - } - }); - } - else - LogPrint(eLogError, "NTCP: unknown proxy type, invalid state"); - } - - void NTCPServer::AfterSocksHandshake(std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) - { - // build request - size_t sz = 0; - uint8_t buff[256]; - uint8_t readbuff[256]; - buff[0] = 0x05; - buff[1] = 0x01; - buff[2] = 0x00; - - if(addrtype == eIP4Address) - { - buff[3] = 0x01; - auto addr = boost::asio::ip::address::from_string(host).to_v4(); - auto addrbytes = addr.to_bytes(); - auto addrsize = addrbytes.size(); - memcpy(buff+4, addrbytes.data(), addrsize); - } - else if (addrtype == eIP6Address) - { - buff[3] = 0x04; - auto addr = boost::asio::ip::address::from_string(host).to_v6(); - auto addrbytes = addr.to_bytes(); - auto addrsize = addrbytes.size(); - memcpy(buff+4, addrbytes.data(), addrsize); - } - else if (addrtype == eHostname) - { - buff[3] = 0x03; - size_t addrsize = host.size(); - sz = addrsize + 1 + 4; - if (2 + sz > sizeof(buff)) - { - // too big - return; - } - buff[4] = (uint8_t) addrsize; - memcpy(buff+5, host.c_str(), addrsize); - } - htobe16buf(buff+sz, port); - sz += 2; - boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, sz), boost::asio::transfer_all(), [=](const boost::system::error_code & ec, std::size_t written) { - if(ec) - { - LogPrint(eLogError, "NTCP: failed to write handshake to socks proxy ", ec.message()); - return; - } - }); - - boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff, 10), [=](const boost::system::error_code & e, std::size_t transferred) { - if(e) - { - LogPrint(eLogError, "NTCP: socks proxy read error ", e.message()); - } - else if(transferred == sz) - { - if( readbuff[1] == 0x00) - { - timer->cancel(); - conn->ClientLogin(); - return; - } - } - if(!e) - i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); - timer->cancel(); - conn->Terminate(); - }); - } - - void NTCPServer::ScheduleTermination () - { - m_TerminationTimer.expires_from_now (boost::posix_time::seconds(NTCP_TERMINATION_CHECK_TIMEOUT)); - m_TerminationTimer.async_wait (std::bind (&NTCPServer::HandleTerminationTimer, - this, std::placeholders::_1)); - } - - void NTCPServer::HandleTerminationTimer (const boost::system::error_code& ecode) - { - if (ecode != boost::asio::error::operation_aborted) - { - auto ts = i2p::util::GetSecondsSinceEpoch (); - // established - for (auto& it: m_NTCPSessions) - if (it.second->IsTerminationTimeoutExpired (ts)) - { - auto session = it.second; - // Terminate modifies m_NTCPSession, so we postpone it - m_Service.post ([session] { - LogPrint (eLogDebug, "NTCP: No activity for ", session->GetTerminationTimeout (), " seconds"); - session->Terminate (); - }); - } - // pending - for (auto it = m_PendingIncomingSessions.begin (); it != m_PendingIncomingSessions.end ();) - { - if ((*it)->IsEstablished () || (*it)->IsTerminated ()) - it = m_PendingIncomingSessions.erase (it); // established or terminated - else if ((*it)->IsTerminationTimeoutExpired (ts)) - { - (*it)->Terminate (); - it = m_PendingIncomingSessions.erase (it); // expired - } - else - it++; - } - - ScheduleTermination (); - } - } -} -} diff --git a/libi2pd/NTCPSession.h b/libi2pd/NTCPSession.h deleted file mode 100644 index d3aa6f7c..00000000 --- a/libi2pd/NTCPSession.h +++ /dev/null @@ -1,242 +0,0 @@ -/* -* Copyright (c) 2013-2020, The PurpleI2P Project -* -* This file is part of Purple i2pd project and licensed under BSD3 -* -* See full license text in LICENSE file at top of project tree -*/ - -#ifndef NTCP_SESSION_H__ -#define NTCP_SESSION_H__ - -#include -#include -#include -#include -#include -#include -#include "Crypto.h" -#include "Identity.h" -#include "RouterInfo.h" -#include "I2NPProtocol.h" -#include "TransportSession.h" -#include "CryptoWorker.h" - -namespace i2p -{ -namespace transport -{ - struct NTCPPhase1 - { - uint8_t pubKey[256]; - uint8_t HXxorHI[32]; - }; - - struct NTCPPhase2 - { - uint8_t pubKey[256]; - struct - { - uint8_t hxy[32]; - uint8_t timestamp[4]; - uint8_t filler[12]; - } encrypted; - }; - - struct NTCPWork; - - const size_t NTCP_MAX_MESSAGE_SIZE = 16384; - const size_t NTCP_BUFFER_SIZE = 1028; // fits 1 tunnel data message - const int NTCP_CONNECT_TIMEOUT = 5; // 5 seconds - const int NTCP_ESTABLISH_TIMEOUT = 10; // 10 seconds - const int NTCP_TERMINATION_TIMEOUT = 120; // 2 minutes - const int NTCP_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds - const size_t NTCP_DEFAULT_PHASE3_SIZE = 2/*size*/ + i2p::data::DEFAULT_IDENTITY_SIZE/*387*/ + 4/*ts*/ + 15/*padding*/ + 40/*signature*/; // 448 - const int NTCP_CLOCK_SKEW = 60; // in seconds - const int NTCP_MAX_OUTGOING_QUEUE_SIZE = 200; // how many messages we can queue up - - class NTCPServer; - class NTCPSession: public TransportSession, public std::enable_shared_from_this - { - public: - - NTCPSession (NTCPServer& server, std::shared_ptr in_RemoteRouter = nullptr); - ~NTCPSession (); - void Terminate (); - void Done (); - - boost::asio::ip::tcp::socket& GetSocket () { return m_Socket; }; - boost::asio::io_service & GetService(); - bool IsEstablished () const { return m_IsEstablished; }; - bool IsTerminated () const { return m_IsTerminated; }; - - void ClientLogin (); - void ServerLogin (); - void SendI2NPMessages (const std::vector >& msgs); - - private: - - void PostI2NPMessages (std::vector > msgs); - void Connected (); - void SendTimeSyncMessage (); - void SetIsEstablished (bool isEstablished) { m_IsEstablished = isEstablished; } - - void CreateAESKey (uint8_t * pubKey); - - // client - void SendPhase3 (); - void HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred); - void HandlePhase2Received (const boost::system::error_code& ecode, std::size_t bytes_transferred); - void HandlePhase2 (NTCPWork * work=nullptr); - void HandlePhase3Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA); - void HandlePhase4Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA); - - //server - void SendPhase2 (NTCPWork * work=nullptr); - void SendPhase4 (uint32_t tsA, uint32_t tsB); - void HandlePhase1Received (const boost::system::error_code& ecode, std::size_t bytes_transferred); - void HandlePhase2Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB); - void HandlePhase3Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB); - void HandlePhase3ExtraReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB, size_t paddingLen); - void HandlePhase3 (uint32_t tsB, size_t paddingLen); - void HandlePhase4Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred); - - // common - void Receive (); - void HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); - bool DecryptNextBlock (const uint8_t * encrypted); - - void Send (std::shared_ptr msg); - boost::asio::const_buffers_1 CreateMsgBuffer (std::shared_ptr msg); - void Send (const std::vector >& msgs); - void HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, std::vector > msgs); - - private: - - NTCPServer& m_Server; - boost::asio::ip::tcp::socket m_Socket; - bool m_IsEstablished, m_IsTerminated; - - i2p::crypto::CBCDecryption m_Decryption; - i2p::crypto::CBCEncryption m_Encryption; - - struct Establisher - { - NTCPPhase1 phase1; - NTCPPhase2 phase2; - } * m_Establisher; - - i2p::crypto::AESAlignedBuffer m_ReceiveBuffer; - i2p::crypto::AESAlignedBuffer<16> m_TimeSyncBuffer; - int m_ReceiveBufferOffset; - - std::shared_ptr m_NextMessage; - size_t m_NextMessageOffset; - i2p::I2NPMessagesHandler m_Handler; - - bool m_IsSending; - std::vector > m_SendQueue; - }; - - // TODO: move to NTCP.h/.cpp - class NTCPServer - { - public: - - typedef i2p::worker::ThreadPool Pool; - - enum RemoteAddressType - { - eIP4Address, - eIP6Address, - eHostname - }; - - enum ProxyType - { - eNoProxy, - eSocksProxy, - eHTTPProxy - }; - - - NTCPServer (int workers=4); - ~NTCPServer (); - - void Start (); - void Stop (); - - bool AddNTCPSession (std::shared_ptr session); - void RemoveNTCPSession (std::shared_ptr session); - std::shared_ptr FindNTCPSession (const i2p::data::IdentHash& ident); - void ConnectWithProxy (const std::string& addr, uint16_t port, RemoteAddressType addrtype, std::shared_ptr conn); - void Connect(const boost::asio::ip::address & address, uint16_t port, std::shared_ptr conn); - - bool IsBoundV4() const { return m_NTCPAcceptor != nullptr; }; - bool IsBoundV6() const { return m_NTCPV6Acceptor != nullptr; }; - bool NetworkIsReady() const { return IsBoundV4() || IsBoundV6() || UsingProxy(); }; - bool UsingProxy() const { return m_ProxyType != eNoProxy; }; - - void UseProxy(ProxyType proxy, const std::string & address, uint16_t port); - - boost::asio::io_service& GetService () { return m_Service; }; - - void SetSessionLimits(uint16_t softLimit, uint16_t hardLimit) { m_SoftLimit = softLimit; m_HardLimit = hardLimit; } - bool ShouldLimit() const { return ShouldHardLimit() || ShouldSoftLimit(); } - void Work(std::shared_ptr conn, Pool::WorkFunc work) - { - m_CryptoPool->Offer({conn, work}); - } - private: - - /** @brief return true for hard limit */ - bool ShouldHardLimit() const { return m_HardLimit && m_NTCPSessions.size() >= m_HardLimit; } - - /** @brief return true for probabalistic soft backoff */ - bool ShouldSoftLimit() const - { - auto sessions = m_NTCPSessions.size(); - return sessions && m_SoftLimit && m_SoftLimit < sessions && ( rand() % sessions ) <= m_SoftLimit; - } - void Run (); - void HandleAccept (std::shared_ptr conn, const boost::system::error_code& error); - void HandleAcceptV6 (std::shared_ptr conn, const boost::system::error_code& error); - - void HandleConnect (const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer); - - void HandleProxyConnect(const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType adddrtype); - void AfterSocksHandshake(std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType adddrtype); - - // timer - void ScheduleTermination (); - void HandleTerminationTimer (const boost::system::error_code& ecode); - - private: - - bool m_IsRunning; - std::thread * m_Thread; - boost::asio::io_service m_Service; - boost::asio::io_service::work m_Work; - boost::asio::deadline_timer m_TerminationTimer; - boost::asio::ip::tcp::acceptor * m_NTCPAcceptor, * m_NTCPV6Acceptor; - std::map > m_NTCPSessions; // access from m_Thread only - std::list > m_PendingIncomingSessions; - - ProxyType m_ProxyType; - std::string m_ProxyAddress; - uint16_t m_ProxyPort; - boost::asio::ip::tcp::resolver m_Resolver; - boost::asio::ip::tcp::endpoint * m_ProxyEndpoint; - - std::shared_ptr m_CryptoPool; - - uint16_t m_SoftLimit, m_HardLimit; - public: - - // for HTTP/I2PControl - const decltype(m_NTCPSessions)& GetNTCPSessions () const { return m_NTCPSessions; }; - }; -} -} - -#endif diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 54bf3fd9..19e17f52 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -133,7 +133,7 @@ namespace transport Transports::Transports (): m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_Thread (nullptr), m_Service (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr), - m_NTCPServer (nullptr), m_SSUServer (nullptr), m_NTCP2Server (nullptr), + m_SSUServer (nullptr), m_NTCP2Server (nullptr), m_DHKeysPairSupplier (5), m_X25519KeysPairSupplier (5), // 5 pre-generated keys m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0), m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth(0), @@ -154,7 +154,7 @@ namespace transport } } - void Transports::Start (bool enableNTCP, bool enableSSU) + void Transports::Start (bool enableNTCP2, bool enableSSU) { if (!m_Service) { @@ -169,50 +169,10 @@ namespace transport m_X25519KeysPairSupplier.Start (); m_IsRunning = true; m_Thread = new std::thread (std::bind (&Transports::Run, this)); - std::string ntcpproxy; i2p::config::GetOption("ntcpproxy", ntcpproxy); std::string ntcp2proxy; i2p::config::GetOption("ntcp2.proxy", ntcp2proxy); - i2p::http::URL proxyurl; - uint16_t softLimit, hardLimit, threads; - i2p::config::GetOption("limits.ntcpsoft", softLimit); - i2p::config::GetOption("limits.ntcphard", hardLimit); - i2p::config::GetOption("limits.ntcpthreads", threads); - if(softLimit > 0 && hardLimit > 0 && softLimit >= hardLimit) - { - LogPrint(eLogError, "ntcp soft limit must be less than ntcp hard limit"); - return; - } - if(ntcpproxy.size() && enableNTCP) - { - if(proxyurl.parse(ntcpproxy)) - { - if(proxyurl.schema == "socks" || proxyurl.schema == "http") - { - m_NTCPServer = new NTCPServer(threads); - m_NTCPServer->SetSessionLimits(softLimit, hardLimit); - NTCPServer::ProxyType proxytype = NTCPServer::eSocksProxy; - - if (proxyurl.schema == "http") - proxytype = NTCPServer::eHTTPProxy; - m_NTCPServer->UseProxy(proxytype, proxyurl.host, proxyurl.port); - m_NTCPServer->Start(); - if(!m_NTCPServer->NetworkIsReady()) - { - LogPrint(eLogError, "Transports: NTCP failed to start with proxy"); - m_NTCPServer->Stop(); - delete m_NTCPServer; - m_NTCPServer = nullptr; - } - } - else - LogPrint(eLogError, "Transports: unsupported NTCP proxy URL ", ntcpproxy); - } - else - LogPrint(eLogError, "Transports: invalid NTCP proxy url ", ntcpproxy); - return; - } + i2p::http::URL proxyurl; // create NTCP2. TODO: move to acceptor - bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); - if (ntcp2) + if (enableNTCP2) { if(!ntcp2proxy.empty()) { @@ -248,20 +208,6 @@ namespace transport for (const auto& address : addresses) { if (!address) continue; - if (m_NTCPServer == nullptr && enableNTCP) - { - m_NTCPServer = new NTCPServer (threads); - m_NTCPServer->SetSessionLimits(softLimit, hardLimit); - m_NTCPServer->Start (); - if (!(m_NTCPServer->IsBoundV6() || m_NTCPServer->IsBoundV4())) { - /** failed to bind to NTCP */ - LogPrint(eLogError, "Transports: failed to bind to TCP"); - m_NTCPServer->Stop(); - delete m_NTCPServer; - m_NTCPServer = nullptr; - } - } - if (address->transportStyle == RouterInfo::eTransportSSU) { if (m_SSUServer == nullptr && enableSSU) @@ -306,13 +252,7 @@ namespace transport delete m_SSUServer; m_SSUServer = nullptr; } - if (m_NTCPServer) - { - m_NTCPServer->Stop (); - delete m_NTCPServer; - m_NTCPServer = nullptr; - } - + if (m_NTCP2Server) { m_NTCP2Server->Stop (); diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 48eee4b4..c3008b09 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -21,7 +21,6 @@ #include #include #include "TransportSession.h" -#include "NTCPSession.h" #include "SSU.h" #include "NTCP2.h" #include "RouterInfo.h" @@ -88,10 +87,9 @@ namespace transport Transports (); ~Transports (); - void Start (bool enableNTCP=true, bool enableSSU=true); + void Start (bool enableNTCP2=true, bool enableSSU=true); void Stop (); - bool IsBoundNTCP() const { return m_NTCPServer != nullptr; } bool IsBoundSSU() const { return m_SSUServer != nullptr; } bool IsBoundNTCP2() const { return m_NTCP2Server != nullptr; } @@ -159,7 +157,6 @@ namespace transport boost::asio::io_service::work * m_Work; boost::asio::deadline_timer * m_PeerCleanupTimer, * m_PeerTestTimer; - NTCPServer * m_NTCPServer; SSUServer * m_SSUServer; NTCP2Server * m_NTCP2Server; mutable std::mutex m_PeersMutex; @@ -186,7 +183,6 @@ namespace transport public: // for HTTP only - const NTCPServer * GetNTCPServer () const { return m_NTCPServer; }; const SSUServer * GetSSUServer () const { return m_SSUServer; }; const NTCP2Server * GetNTCP2Server () const { return m_NTCP2Server; }; const decltype(m_Peers)& GetPeers () const { return m_Peers; }; diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 6eec3a16..468d2d00 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -42,7 +42,6 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd/NetDb.cpp \ ../../libi2pd/NetDbRequests.cpp \ ../../libi2pd/NTCP2.cpp \ - ../../libi2pd/NTCPSession.cpp \ ../../libi2pd/Poly1305.cpp \ ../../libi2pd/Profiling.cpp \ ../../libi2pd/Reseed.cpp \ @@ -123,7 +122,6 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../libi2pd/NetDb.hpp \ ../../libi2pd/NetDbRequests.h \ ../../libi2pd/NTCP2.h \ - ../../libi2pd/NTCPSession.h \ ../../libi2pd/Poly1305.h \ ../../libi2pd/Profiling.h \ ../../libi2pd/Queue.h \ From c2f13a1496272237d348ed1f76d0836d4daaca8e Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 3 Oct 2020 22:29:52 -0400 Subject: [PATCH 42/71] some cleanup --- daemon/Daemon.cpp | 5 ++--- libi2pd/RouterContext.cpp | 45 +++++++-------------------------------- libi2pd/RouterContext.h | 2 +- libi2pd/RouterInfo.cpp | 14 ------------ libi2pd/RouterInfo.h | 1 - 5 files changed, 11 insertions(+), 56 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 5f98d47a..f5d4d24f 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -142,8 +142,7 @@ namespace i2p i2p::context.SetSupportsV6 (ipv6); i2p::context.SetSupportsV4 (ipv4); - bool ntcp; i2p::config::GetOption("ntcp", ntcp); - i2p::context.PublishNTCPAddress (ntcp, !ipv6); + i2p::context.RemoveNTCPAddress (!ipv6); // TODO: remove later bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) { @@ -151,7 +150,7 @@ namespace i2p if (published) { uint16_t ntcp2port; i2p::config::GetOption("ntcp2.port", ntcp2port); - if (!ntcp && !ntcp2port) ntcp2port = port; // use standard port + if (!ntcp2port) ntcp2port = port; // use standard port i2p::context.PublishNTCP2Address (ntcp2port, true); // publish if (ipv6) { diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 7333e613..69e69d7c 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -373,48 +373,19 @@ namespace i2p return m_RouterInfo.GetCaps () & i2p::data::RouterInfo::eUnreachable; } - void RouterContext::PublishNTCPAddress (bool publish, bool v4only) + void RouterContext::RemoveNTCPAddress (bool v4only) { auto& addresses = m_RouterInfo.GetAddresses (); - if (publish) + for (auto it = addresses.begin (); it != addresses.end ();) { - for (const auto& addr : addresses) // v4 + if ((*it)->transportStyle == i2p::data::RouterInfo::eTransportNTCP && !(*it)->IsNTCP2 () && + (!v4only || (*it)->host.is_v4 ())) { - if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU && - addr->host.is_v4 ()) - { - // insert NTCP address with host/port from SSU - m_RouterInfo.AddNTCPAddress (addr->host.to_string ().c_str (), addr->port); - break; - } - } - if (!v4only) - { - for (const auto& addr : addresses) // v6 - { - if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU && - addr->host.is_v6 ()) - { - // insert NTCP address with host/port from SSU - m_RouterInfo.AddNTCPAddress (addr->host.to_string ().c_str (), addr->port); - break; - } - } - } - } - else - { - for (auto it = addresses.begin (); it != addresses.end ();) - { - if ((*it)->transportStyle == i2p::data::RouterInfo::eTransportNTCP && !(*it)->IsNTCP2 () && - (!v4only || (*it)->host.is_v4 ())) - { - it = addresses.erase (it); - if (v4only) break; // otherwise might be more than one address - } - else - ++it; + it = addresses.erase (it); + if (v4only) break; // otherwise might be more than one address } + else + ++it; } } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 6f08a87a..a576d6b6 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -89,7 +89,7 @@ namespace i2p void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon void PublishNTCP2Address (int port, bool publish = true, bool v4only = false); void UpdateNTCP2Address (bool enable); - void PublishNTCPAddress (bool publish, bool v4only = true); + void RemoveNTCPAddress (bool v4only = true); // delete NTCP address for older routers. TODO: remove later bool AddIntroducer (const i2p::data::RouterInfo::Introducer& introducer); void RemoveIntroducer (const boost::asio::ip::udp::endpoint& e); bool IsUnreachable () const; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 703c853f..12f81a42 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -709,20 +709,6 @@ namespace data s.write (str.c_str (), len); } - void RouterInfo::AddNTCPAddress (const char * host, int port) - { - auto addr = std::make_shared
(); - addr->host = boost::asio::ip::address::from_string (host); - addr->port = port; - addr->transportStyle = eTransportNTCP; - addr->cost = 6; - addr->date = 0; - for (const auto& it: *m_Addresses) // don't insert same address twice - if (*it == *addr) return; - m_SupportedTransports |= addr->host.is_v6 () ? eNTCPV6 : eNTCPV4; - m_Addresses->push_front(std::move(addr)); // always make NTCP first - } - void RouterInfo::AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu) { auto addr = std::make_shared
(); diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 1c0063b0..282c34f9 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -157,7 +157,6 @@ namespace data std::shared_ptr GetSSUAddress (bool v4only = true) const; std::shared_ptr GetSSUV6Address () const; - void AddNTCPAddress (const char * host, int port); void AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu = 0); void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, const boost::asio::ip::address& host = boost::asio::ip::address(), int port = 0); bool AddIntroducer (const Introducer& introducer); From d3f7eea0a3e505a9adee2780036a646e6ef008fe Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 4 Oct 2020 09:05:57 +0300 Subject: [PATCH 43/71] [appveyor] Disable unavailable repository Ref: https://github.com/msys2/MINGW-packages/issues/7084 --- appveyor.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index d5f67b14..0b105031 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -26,6 +26,9 @@ install: - c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" - c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" +# disable inaccessible miror (doing same for sourceforge because it's laggy) - https://github.com/msys2/MINGW-packages/issues/7084 +- c:\msys64\usr\bin\bash -lc "sed -i 's/^Server\ =\ http:\/\/repo\.msys2\.org/#Server\ =\ http:\/\/repo\.msys2\.org/g' /etc/pacman.d/mirrorlist.*" +- c:\msys64\usr\bin\bash -lc "sed -i 's/^Server\ =\ https:\/\/sourceforge\.net/#Server\ =\ https:\/\/sourceforge\.net/g' /etc/pacman.d/mirrorlist.*" # remove packages which can break build - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc" # update runtime From 7ceb81cc8302d3e504b9a3106c39e0579ad7706d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 4 Oct 2020 09:16:43 +0300 Subject: [PATCH 44/71] [appveyor] clean packages cache after disabling mirrors --- appveyor.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 0b105031..350a2c05 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -26,9 +26,10 @@ install: - c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" - c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" -# disable inaccessible miror (doing same for sourceforge because it's laggy) - https://github.com/msys2/MINGW-packages/issues/7084 +# disable inaccessible miror (doing same for sourceforge because it's laggy) and clean cache - https://github.com/msys2/MINGW-packages/issues/7084 - c:\msys64\usr\bin\bash -lc "sed -i 's/^Server\ =\ http:\/\/repo\.msys2\.org/#Server\ =\ http:\/\/repo\.msys2\.org/g' /etc/pacman.d/mirrorlist.*" - c:\msys64\usr\bin\bash -lc "sed -i 's/^Server\ =\ https:\/\/sourceforge\.net/#Server\ =\ https:\/\/sourceforge\.net/g' /etc/pacman.d/mirrorlist.*" +- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syy" # remove packages which can break build - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc" # update runtime From 65e15d74fc255cc920a0ae30164454e480b377cd Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 4 Oct 2020 09:32:21 +0300 Subject: [PATCH 45/71] [appveyor] print mirrorlist (testing) --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 350a2c05..c993a6ba 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -26,10 +26,10 @@ install: - c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" - c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" -# disable inaccessible miror (doing same for sourceforge because it's laggy) and clean cache - https://github.com/msys2/MINGW-packages/issues/7084 +# disable inaccessible miror (doing same for sourceforge because it's laggy) - https://github.com/msys2/MINGW-packages/issues/7084 - c:\msys64\usr\bin\bash -lc "sed -i 's/^Server\ =\ http:\/\/repo\.msys2\.org/#Server\ =\ http:\/\/repo\.msys2\.org/g' /etc/pacman.d/mirrorlist.*" - c:\msys64\usr\bin\bash -lc "sed -i 's/^Server\ =\ https:\/\/sourceforge\.net/#Server\ =\ https:\/\/sourceforge\.net/g' /etc/pacman.d/mirrorlist.*" -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syy" +- c:\msys64\usr\bin\bash -lc "cat /etc/pacman.d/mirrorlist.*" # remove packages which can break build - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc" # update runtime From e614226926ce51f217364d0630130c245fb36437 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 4 Oct 2020 09:39:40 +0300 Subject: [PATCH 46/71] [appveyor] change repository disabling way (testing) --- appveyor.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index c993a6ba..346cda4c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -26,9 +26,8 @@ install: - c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" - c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" -# disable inaccessible miror (doing same for sourceforge because it's laggy) - https://github.com/msys2/MINGW-packages/issues/7084 -- c:\msys64\usr\bin\bash -lc "sed -i 's/^Server\ =\ http:\/\/repo\.msys2\.org/#Server\ =\ http:\/\/repo\.msys2\.org/g' /etc/pacman.d/mirrorlist.*" -- c:\msys64\usr\bin\bash -lc "sed -i 's/^Server\ =\ https:\/\/sourceforge\.net/#Server\ =\ https:\/\/sourceforge\.net/g' /etc/pacman.d/mirrorlist.*" +# disable inaccessible miror - https://github.com/msys2/MINGW-packages/issues/7084 +- c:\msys64\usr\bin\bash -lc "sed -e '/repo\.msys2\.org/ s/^#*/#/' -i /etc/pacman.d/mirrorlist.*" - c:\msys64\usr\bin\bash -lc "cat /etc/pacman.d/mirrorlist.*" # remove packages which can break build - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc" From 77231bfc6c03c8176065699b0c535c7a6b8e0cc9 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 4 Oct 2020 09:53:31 +0300 Subject: [PATCH 47/71] [appeveyor] rewrite mirrorlist (testing) https://github.com/msys2/MINGW-packages/issues/7084#issuecomment-703211308 --- appveyor.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 346cda4c..c6b562c4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -26,8 +26,10 @@ install: - c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" - c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" -# disable inaccessible miror - https://github.com/msys2/MINGW-packages/issues/7084 -- c:\msys64\usr\bin\bash -lc "sed -e '/repo\.msys2\.org/ s/^#*/#/' -i /etc/pacman.d/mirrorlist.*" +# disable inaccessible miror (something block sed from changing files, so rewrite them) - https://github.com/msys2/MINGW-packages/issues/7084 +- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/x86_64/' > /etc/pacman.d/mirrorlist.mingw64" +- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/i686/' > /etc/pacman.d/mirrorlist.mingw32" +- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/msys/$arch/' > /etc/pacman.d/mirrorlist.msys" - c:\msys64\usr\bin\bash -lc "cat /etc/pacman.d/mirrorlist.*" # remove packages which can break build - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc" From 67b76809eab7b57c66295b0224e334ef68a4b2dc Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 4 Oct 2020 09:57:45 +0300 Subject: [PATCH 48/71] [appveyor] rewrite mirrorlist after updating runtime If pacman was updated on runtime update, changes which we domne earlier will be rewrited by config from package --- appveyor.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index c6b562c4..10165e5f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -30,13 +30,16 @@ install: - c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/x86_64/' > /etc/pacman.d/mirrorlist.mingw64" - c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/i686/' > /etc/pacman.d/mirrorlist.mingw32" - c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/msys/$arch/' > /etc/pacman.d/mirrorlist.msys" -- c:\msys64\usr\bin\bash -lc "cat /etc/pacman.d/mirrorlist.*" # remove packages which can break build - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc" # update runtime - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" # Kill bash before next try - taskkill /T /F /IM bash.exe /IM gpg.exe /IM gpg-agent.exe | exit /B 0 +# rewrite mirrorlist again because pacman update can rewrite it +- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/x86_64/' > /etc/pacman.d/mirrorlist.mingw64" +- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/i686/' > /etc/pacman.d/mirrorlist.mingw32" +- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/msys/$arch/' > /etc/pacman.d/mirrorlist.msys" # update packages and install required - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu ${MSYS_PACKAGES}" From 243f6e755b27b58b5e33b41b8022c7afc0bd5881 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 4 Oct 2020 09:34:15 -0400 Subject: [PATCH 49/71] restore copyright header --- daemon/Daemon.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index f5d4d24f..1b9c0a2c 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include From d218c9a9832f7419e11c94573a5a866bdef4a6e6 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 4 Oct 2020 10:12:33 -0400 Subject: [PATCH 50/71] disable ntcpproxy --- libi2pd/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index e0dc66d8..1c565083 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -60,7 +60,7 @@ namespace config { ("share", value()->default_value(100), "Limit of transit traffic from max bandwidth in percents. (default: 100)") ("ntcp", value()->default_value(false), "Ignored. Always false") ("ssu", value()->default_value(true), "Enable SSU transport (default: enabled)") - ("ntcpproxy", value()->default_value(""), "Proxy URL for NTCP transport") + ("ntcpproxy", value()->default_value(""), "Ignored") #ifdef _WIN32 ("svcctl", value()->default_value(""), "Windows service management ('install' or 'remove')") ("insomnia", bool_switch()->default_value(false), "Prevent system from sleeping (default: disabled)") From 59032d515b0b9cb41dec1b0abc7adf8394dbfd0e Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 4 Oct 2020 19:52:12 -0400 Subject: [PATCH 51/71] i2p.streaming.answerPings=false by default for client tunnels --- libi2pd_client/ClientContext.cpp | 8 ++++---- libi2pd_client/ClientContext.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index e83e293a..04f50e6f 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -444,7 +444,7 @@ namespace client } template - void ClientContext::ReadI2CPOptions (const Section& section, std::map& options) const + void ClientContext::ReadI2CPOptions (const Section& section, bool isServer, std::map& options) const { options[I2CP_PARAM_INBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNEL_LENGTH, DEFAULT_INBOUND_TUNNEL_LENGTH); options[I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH, DEFAULT_OUTBOUND_TUNNEL_LENGTH); @@ -454,7 +454,7 @@ namespace client options[I2CP_PARAM_MIN_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MIN_TUNNEL_LATENCY, DEFAULT_MIN_TUNNEL_LATENCY); options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MAX_TUNNEL_LATENCY, DEFAULT_MAX_TUNNEL_LATENCY); options[I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY] = GetI2CPOption(section, I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY, DEFAULT_INITIAL_ACK_DELAY); - options[I2CP_PARAM_STREAMING_ANSWER_PINGS] = GetI2CPOption(section, I2CP_PARAM_STREAMING_ANSWER_PINGS, DEFAULT_ANSWER_PINGS); + options[I2CP_PARAM_STREAMING_ANSWER_PINGS] = GetI2CPOption(section, I2CP_PARAM_STREAMING_ANSWER_PINGS, isServer ? DEFAULT_ANSWER_PINGS : false); options[I2CP_PARAM_LEASESET_TYPE] = GetI2CPOption(section, I2CP_PARAM_LEASESET_TYPE, DEFAULT_LEASESET_TYPE); std::string encType = GetI2CPStringOption(section, I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, ""); if (encType.length () > 0) options[I2CP_PARAM_LEASESET_ENCRYPTION_TYPE] = encType; @@ -570,7 +570,7 @@ namespace client i2p::data::CryptoKeyType cryptoType = section.second.get (I2P_CLIENT_TUNNEL_CRYPTO_TYPE, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL); // I2CP std::map options; - ReadI2CPOptions (section, options); + ReadI2CPOptions (section, false, options); std::shared_ptr localDestination = nullptr; if (keys.length () > 0) @@ -694,7 +694,7 @@ namespace client // I2CP std::map options; - ReadI2CPOptions (section, options); + ReadI2CPOptions (section, true, options); std::shared_ptr localDestination = nullptr; auto it = destinations.find (keys); diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 05b754fe..076aaa5f 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -115,7 +115,7 @@ namespace client template void ReadI2CPOptionsGroup (const Section& section, const std::string& group, std::map& options) const; template - void ReadI2CPOptions (const Section& section, std::map& options) const; // for tunnels + void ReadI2CPOptions (const Section& section, bool isServer, std::map& options) const; // for tunnels void ReadI2CPOptionsFromConfig (const std::string& prefix, std::map& options) const; // for HTTP and SOCKS proxy void CleanupUDP(const boost::system::error_code & ecode); From 471c46ad8e2f9f6869e005105730bfb87fa69e0b Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 6 Oct 2020 16:22:40 -0400 Subject: [PATCH 52/71] remove some HTTP headers from response --- libi2pd_client/I2PTunnel.cpp | 104 ++++++++++++++++++++++++++--------- libi2pd_client/I2PTunnel.h | 6 +- 2 files changed, 83 insertions(+), 27 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 3575e062..946d55d5 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -139,22 +139,25 @@ namespace client } } else - { - if (m_Stream) - { - auto s = shared_from_this (); - m_Stream->AsyncSend (m_Buffer, bytes_transferred, - [s](const boost::system::error_code& ecode) - { - if (!ecode) - s->Receive (); - else - s->Terminate (); - }); - } - } + WriteToStream (m_Buffer, bytes_transferred); } + void I2PTunnelConnection::WriteToStream (const uint8_t * buf, size_t len) + { + if (m_Stream) + { + auto s = shared_from_this (); + m_Stream->AsyncSend (buf, len, + [s](const boost::system::error_code& ecode) + { + if (!ecode) + s->Receive (); + else + s->Terminate (); + }); + } + } + void I2PTunnelConnection::HandleWrite (const boost::system::error_code& ecode) { if (ecode) @@ -302,7 +305,8 @@ namespace client I2PServerTunnelConnectionHTTP::I2PServerTunnelConnectionHTTP (I2PService * owner, std::shared_ptr stream, std::shared_ptr socket, const boost::asio::ip::tcp::endpoint& target, const std::string& host): - I2PTunnelConnection (owner, stream, socket, target), m_Host (host), m_HeaderSent (false), m_From (stream->GetRemoteIdentity ()) + I2PTunnelConnection (owner, stream, socket, target), m_Host (host), + m_HeaderSent (false), m_ResponseHeaderSent (false), m_From (stream->GetRemoteIdentity ()) { } @@ -333,12 +337,59 @@ namespace client else break; } - // add X-I2P fields - if (m_From) + + if (endOfHeader) { - m_OutHeader << X_I2P_DEST_B32 << ": " << context.GetAddressBook ().ToAddress(m_From->GetIdentHash ()) << "\r\n"; - m_OutHeader << X_I2P_DEST_HASH << ": " << m_From->GetIdentHash ().ToBase64 () << "\r\n"; - m_OutHeader << X_I2P_DEST_B64 << ": " << m_From->ToBase64 () << "\r\n"; + // add X-I2P fields + if (m_From) + { + m_OutHeader << X_I2P_DEST_B32 << ": " << context.GetAddressBook ().ToAddress(m_From->GetIdentHash ()) << "\r\n"; + m_OutHeader << X_I2P_DEST_HASH << ": " << m_From->GetIdentHash ().ToBase64 () << "\r\n"; + m_OutHeader << X_I2P_DEST_B64 << ": " << m_From->ToBase64 () << "\r\n"; + } + + m_OutHeader << "\r\n"; // end of header + m_OutHeader << m_InHeader.str ().substr (m_InHeader.tellg ()); // data right after header + m_InHeader.str (""); + m_From = nullptr; + m_HeaderSent = true; + I2PTunnelConnection::Write ((uint8_t *)m_OutHeader.str ().c_str (), m_OutHeader.str ().length ()); + } + } + } + + void I2PServerTunnelConnectionHTTP::WriteToStream (const uint8_t * buf, size_t len) + { + if (m_ResponseHeaderSent) + I2PTunnelConnection::WriteToStream (buf, len); + else + { + m_InHeader.clear (); + if (m_InHeader.str ().empty ()) m_OutHeader.str (""); // start of response + m_InHeader.write ((const char *)buf, len); + std::string line; + bool endOfHeader = false; + while (!endOfHeader) + { + std::getline(m_InHeader, line); + if (!m_InHeader.fail ()) + { + if (line == "\r") endOfHeader = true; + else + { + if (line.find ("Server:") != std::string::npos) continue; // exclude "Server:" + if (line.find ("Date:") != std::string::npos) continue; // exclude "Date"" + if (line[0] == 'X') + { + if (line.find ("X-Runtime:") != std::string::npos) continue; // exclude "X-Runtime:" + if (line.find ("X-Powered-By:") != std::string::npos) continue; // exclude "X-Powered-By:" + } + + m_OutHeader << line << "\n"; + } + } + else + break; } if (endOfHeader) @@ -346,12 +397,15 @@ namespace client m_OutHeader << "\r\n"; // end of header m_OutHeader << m_InHeader.str ().substr (m_InHeader.tellg ()); // data right after header m_InHeader.str (""); - m_HeaderSent = true; - I2PTunnelConnection::Write ((uint8_t *)m_OutHeader.str ().c_str (), m_OutHeader.str ().length ()); - } - } + m_ResponseHeaderSent = true; + I2PTunnelConnection::WriteToStream ((uint8_t *)m_OutHeader.str ().c_str (), m_OutHeader.str ().length ()); + m_OutHeader.str (""); + } + else + Receive (); + } } - + I2PTunnelConnectionIRC::I2PTunnelConnectionIRC (I2PService * owner, std::shared_ptr stream, std::shared_ptr socket, const boost::asio::ip::tcp::endpoint& target, const std::string& webircpass): diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index b76a1027..f7185dfd 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -57,7 +57,8 @@ namespace client void HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); virtual void Write (const uint8_t * buf, size_t len); // can be overloaded void HandleWrite (const boost::system::error_code& ecode); - + virtual void WriteToStream (const uint8_t * buf, size_t len); // can be overloaded + void StreamReceive (); void HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleConnect (const boost::system::error_code& ecode); @@ -103,12 +104,13 @@ namespace client protected: void Write (const uint8_t * buf, size_t len); + void WriteToStream (const uint8_t * buf, size_t len); private: std::string m_Host; std::stringstream m_InHeader, m_OutHeader; - bool m_HeaderSent; + bool m_HeaderSent, m_ResponseHeaderSent; std::shared_ptr m_From; }; From 724662498330644693bd74df24aef144778c5bdd Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 6 Oct 2020 19:24:03 -0400 Subject: [PATCH 53/71] list of headers to remove --- libi2pd_client/I2PTunnel.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 946d55d5..081294c6 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -328,7 +328,7 @@ namespace client if (line == "\r") endOfHeader = true; else { - if (m_Host.length () > 0 && line.find ("Host:") != std::string::npos) + if (m_Host.length () > 0 && !line.compare(0, 5, "Host:")) m_OutHeader << "Host: " << m_Host << "\r\n"; // override host else m_OutHeader << line << "\n"; @@ -377,15 +377,19 @@ namespace client if (line == "\r") endOfHeader = true; else { - if (line.find ("Server:") != std::string::npos) continue; // exclude "Server:" - if (line.find ("Date:") != std::string::npos) continue; // exclude "Date"" - if (line[0] == 'X') - { - if (line.find ("X-Runtime:") != std::string::npos) continue; // exclude "X-Runtime:" - if (line.find ("X-Powered-By:") != std::string::npos) continue; // exclude "X-Powered-By:" - } - - m_OutHeader << line << "\n"; + static const std::vector excluded // list of excluded headers + { + "Server:", "Date:", "X-Runtime:", "X-Powered-By:", "Proxy" + }; + bool matched = false; + for (const auto& it: excluded) + if (!line.compare(0, it.length (), it)) + { + matched = true; + break; + } + if (!matched) + m_OutHeader << line << "\n"; } } else From e2a1cd12c36d1d00120b260158fe487ef269e17f Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 7 Oct 2020 21:13:26 -0400 Subject: [PATCH 54/71] don't delete unreachable routers if too few --- libi2pd/NetDb.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 5930baf7..4ce839ee 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -560,6 +560,9 @@ namespace data updatedCount++; continue; } + // make router reachable back if too few routers + if (it.second->IsUnreachable () && total - deletedCount < NETDB_MIN_ROUTERS) + it.second->SetUnreachable (false); // find & mark expired routers if (it.second->UsesIntroducer ()) { @@ -575,7 +578,7 @@ namespace data // delete RI file m_Storage.Remove(ident); deletedCount++; - if (total - deletedCount < NETDB_MIN_ROUTERS) checkForExpiration = false; + if (total - deletedCount < NETDB_MIN_ROUTERS) checkForExpiration = false; } } // m_RouterInfos iteration From e21dac21c8b813e023fbbf44296eb4a90df3792c Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 11 Oct 2020 14:02:12 -0400 Subject: [PATCH 55/71] fixed #1557. don't try to send empty message --- libi2pd/Tunnel.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index fe7e36af..704706ba 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -303,6 +303,7 @@ namespace tunnel { for (auto& msg : msgs) { + if (!msg.data) continue; switch (msg.deliveryType) { case eDeliveryTypeLocal: From ffa0f0afd91b786e13a479087d4092de5bed121a Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 11 Oct 2020 17:51:40 -0400 Subject: [PATCH 56/71] check network status --- daemon/HTTPServer.cpp | 3 +++ libi2pd/NetDb.cpp | 3 ++- libi2pd/RouterContext.h | 3 ++- libi2pd/Transports.cpp | 15 ++++++++++++++- libi2pd/Transports.h | 5 +++-- 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 19734038..d00387aa 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -259,6 +259,9 @@ namespace http { case eRouterErrorClockSkew: s << "
Clock skew"; break; + case eRouterErrorOffline: + s << "
Offline"; + break; default: ; } break; diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 4ce839ee..318db953 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -125,7 +125,8 @@ namespace data } } if (!m_IsRunning) break; - + if (!i2p::transport::transports.IsOnline ()) continue; // don't manage netdb when offline + uint64_t ts = i2p::util::GetSecondsSinceEpoch (); if (ts - lastManageRequest >= 15) // manage requests every 15 seconds { diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index a576d6b6..37e1791d 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -37,7 +37,8 @@ namespace i2p enum RouterError { eRouterErrorNone = 0, - eRouterErrorClockSkew = 1 + eRouterErrorClockSkew = 1, + eRouterErrorOffline = 2 }; class RouterContext: public i2p::garlic::GarlicDestination diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 19e17f52..8a44bc3e 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -321,7 +321,8 @@ namespace transport void Transports::SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg) { - SendMessages (ident, std::vector > {msg }); + if (m_IsOnline) + SendMessages (ident, std::vector > {msg }); } void Transports::SendMessages (const i2p::data::IdentHash& ident, const std::vector >& msgs) @@ -756,5 +757,17 @@ namespace transport } return false; } + + void Transports::SetOnline (bool online) + { + if (m_IsOnline != online) + { + m_IsOnline = online; + if (online) + PeerTest (); + else + i2p::context.SetError (eRouterErrorOffline); + } + } } } diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index c3008b09..661337a2 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -94,7 +94,7 @@ namespace transport bool IsBoundNTCP2() const { return m_NTCP2Server != nullptr; } bool IsOnline() const { return m_IsOnline; }; - void SetOnline (bool online) { m_IsOnline = online; }; + void SetOnline (bool online); boost::asio::io_service& GetService () { return *m_Service; }; std::shared_ptr GetNextDHKeysPair (); @@ -151,7 +151,8 @@ namespace transport private: - bool m_IsOnline, m_IsRunning, m_IsNAT; + volatile bool m_IsOnline; + bool m_IsRunning, m_IsNAT; std::thread * m_Thread; boost::asio::io_service * m_Service; boost::asio::io_service::work * m_Work; From 0b372a344c0738f62420a5db3048adab428a44a2 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 12 Oct 2020 07:29:46 +0300 Subject: [PATCH 57/71] [webconsole] change error status print format Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index d00387aa..3b9f6eaa 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -257,11 +257,11 @@ namespace http { switch (i2p::context.GetError ()) { case eRouterErrorClockSkew: - s << "
Clock skew"; + s << " - Clock skew"; break; case eRouterErrorOffline: - s << "
Offline"; - break; + s << " - Offline"; + break; default: ; } break; From 99d046ca11430bd59ee0bf67456f90dd648daf67 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 12 Oct 2020 07:31:57 +0300 Subject: [PATCH 58/71] [http] handle WebDAV methods Signed-off-by: R4SAS --- libi2pd/HTTP.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp index 4f7b03a1..484f4c0c 100644 --- a/libi2pd/HTTP.cpp +++ b/libi2pd/HTTP.cpp @@ -16,8 +16,8 @@ namespace i2p { namespace http { const std::vector HTTP_METHODS = { - "GET", "HEAD", "POST", "PUT", "PATCH", - "DELETE", "OPTIONS", "CONNECT", "PROPFIND" + "GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "CONNECT", // HTTP basic methods + "COPY", "LOCK", "MKCOL", "MOVE", "PROPFIND", "PROPPATCH", "UNLOCK", "SEARCH" // WebDAV methods, for SEARCH see rfc5323 }; const std::vector HTTP_VERSIONS = { "HTTP/1.0", "HTTP/1.1" From 85e9da82b023323da1541be4d2e5eed01d9d03cf Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 12 Oct 2020 17:36:44 +0300 Subject: [PATCH 59/71] [transports] validate IP when trying connect to remote peer for being in reserved IP range Signed-off-by: R4SAS --- daemon/Daemon.cpp | 6 ++++-- libi2pd/Config.cpp | 1 + libi2pd/SSU.cpp | 1 + libi2pd/Transports.cpp | 47 +++++++++++++++++++++------------------- libi2pd/Transports.h | 5 ++++- libi2pd/util.cpp | 49 +++++++++++++++++++++++++++++++++++++++++- libi2pd/util.h | 1 + 7 files changed, 84 insertions(+), 26 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 1b9c0a2c..0317704a 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -299,14 +299,16 @@ namespace i2p bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); bool ssu; i2p::config::GetOption("ssu", ssu); + bool checkInReserved; i2p::config::GetOption("reservedrange", checkInReserved); LogPrint(eLogInfo, "Daemon: starting Transports"); if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled"); if(!ntcp2) LogPrint(eLogInfo, "Daemon: ntcp2 disabled"); + i2p::transport::transports.SetCheckReserved(checkInReserved); i2p::transport::transports.Start(ntcp2, ssu); - if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2()) + if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2()) LogPrint(eLogInfo, "Daemon: Transports started"); - else + else { LogPrint(eLogError, "Daemon: failed to start Transports"); /** shut down netdb right away */ diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 1c565083..b924a108 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -51,6 +51,7 @@ namespace config { ("port", value()->default_value(0), "Port to listen for incoming connections (default: auto)") ("ipv4", value()->default_value(true), "Enable communication through ipv4 (default: enabled)") ("ipv6", bool_switch()->default_value(false), "Enable communication through ipv6 (default: disabled)") + ("reservedrange", value()->default_value(true), "Check remote RI for being in blacklist of reserved IP ranges (default: enabled)") ("netid", value()->default_value(I2PD_NET_ID), "Specify NetID. Main I2P is 2") ("daemon", bool_switch()->default_value(false), "Router will go to background after start (default: disabled)") ("service", bool_switch()->default_value(false), "Router will use system folders like '/var/lib/i2pd' (default: disabled)") diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 0f4526bd..f9c06f37 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -459,6 +459,7 @@ namespace transport // otherwise create new session auto session = std::make_shared (*this, remoteEndpoint, router, peerTest); sessions[remoteEndpoint] = session; + // connect LogPrint (eLogDebug, "SSU: Creating new session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), "] ", remoteEndpoint.address ().to_string (), ":", remoteEndpoint.port ()); diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 8a44bc3e..ca86cf42 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -27,20 +27,20 @@ namespace transport { } - template + template EphemeralKeysSupplier::~EphemeralKeysSupplier () { Stop (); } - template + template void EphemeralKeysSupplier::Start () { m_IsRunning = true; m_Thread = new std::thread (std::bind (&EphemeralKeysSupplier::Run, this)); } - template + template void EphemeralKeysSupplier::Stop () { { @@ -56,7 +56,7 @@ namespace transport } } - template + template void EphemeralKeysSupplier::Run () { while (m_IsRunning) @@ -81,7 +81,7 @@ namespace transport } } - template + template void EphemeralKeysSupplier::CreateEphemeralKeys (int num) { if (num > 0) @@ -96,7 +96,7 @@ namespace transport } } - template + template std::shared_ptr EphemeralKeysSupplier::Acquire () { { @@ -115,7 +115,7 @@ namespace transport return pair; } - template + template void EphemeralKeysSupplier::Return (std::shared_ptr pair) { if (pair) @@ -131,8 +131,8 @@ namespace transport Transports transports; Transports::Transports (): - m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_Thread (nullptr), m_Service (nullptr), - m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr), + m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_СheckReserved(true), m_Thread (nullptr), + m_Service (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr), m_SSUServer (nullptr), m_NTCP2Server (nullptr), m_DHKeysPairSupplier (5), m_X25519KeysPairSupplier (5), // 5 pre-generated keys m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0), @@ -170,7 +170,7 @@ namespace transport m_IsRunning = true; m_Thread = new std::thread (std::bind (&Transports::Run, this)); std::string ntcp2proxy; i2p::config::GetOption("ntcp2.proxy", ntcp2proxy); - i2p::http::URL proxyurl; + i2p::http::URL proxyurl; // create NTCP2. TODO: move to acceptor if (enableNTCP2) { @@ -252,7 +252,7 @@ namespace transport delete m_SSUServer; m_SSUServer = nullptr; } - + if (m_NTCP2Server) { m_NTCP2Server->Stop (); @@ -372,7 +372,7 @@ namespace transport } else { - LogPrint (eLogWarning, "Transports: delayed messages queue size to ", + LogPrint (eLogWarning, "Transports: delayed messages queue size to ", ident.ToBase64 (), " exceeds ", MAX_NUM_DELAYED_MESSAGES); std::unique_lock l(m_PeersMutex); m_Peers.erase (it); @@ -393,7 +393,7 @@ namespace transport { // NTCP2 have priority over NTCP auto address = peer.router->GetNTCP2Address (true, !context.SupportsV6 ()); // published only - if (address && !peer.router->IsUnreachable ()) + if (address && !peer.router->IsUnreachable () && (!m_СheckReserved || !i2p::util::net::IsInReservedRange(address->host))) { auto s = std::make_shared (*m_NTCP2Server, peer.router); @@ -419,8 +419,11 @@ namespace transport if (m_SSUServer && peer.router->IsSSU (!context.SupportsV6 ())) { auto address = peer.router->GetSSUAddress (!context.SupportsV6 ()); - m_SSUServer->CreateSession (peer.router, address->host, address->port); - return true; + if (!m_СheckReserved || !i2p::util::net::IsInReservedRange(address->host)) + { + m_SSUServer->CreateSession (peer.router, address->host, address->port); + return true; + } } } LogPrint (eLogInfo, "Transports: No NTCP or SSU addresses available"); @@ -556,7 +559,7 @@ namespace transport { m_X25519KeysPairSupplier.Return (pair); } - + void Transports::PeerConnected (std::shared_ptr session) { m_Service->post([session, this]() @@ -758,16 +761,16 @@ namespace transport return false; } - void Transports::SetOnline (bool online) - { + void Transports::SetOnline (bool online) + { if (m_IsOnline != online) - { - m_IsOnline = online; + { + m_IsOnline = online; if (online) PeerTest (); else i2p::context.SetError (eRouterErrorOffline); - } - } + } + } } } diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 661337a2..55170ee8 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -136,6 +136,9 @@ namespace transport void PeerTest (); + void SetCheckReserved (bool check) { m_СheckReserved = check; }; + bool IsCheckReserved () { return m_СheckReserved; }; + private: void Run (); @@ -152,7 +155,7 @@ namespace transport private: volatile bool m_IsOnline; - bool m_IsRunning, m_IsNAT; + bool m_IsRunning, m_IsNAT, m_СheckReserved; std::thread * m_Thread; boost::asio::io_service * m_Service; boost::asio::io_service::work * m_Work; diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index f5204a50..2cc101c7 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -61,6 +61,9 @@ int inet_pton_xp(int af, const char *src, void *dst) #include #endif +#define address_pair_v4(a,b) { boost::asio::ip::address_v4::from_string (a).to_ulong (), boost::asio::ip::address_v4::from_string (b).to_ulong () } +#define address_pair_v6(a,b) { boost::asio::ip::address_v6::from_string (a).to_bytes (), boost::asio::ip::address_v6::from_string (b).to_bytes () } + namespace i2p { namespace util @@ -391,6 +394,50 @@ namespace net return boost::asio::ip::address::from_string(fallback); #endif } -} + + bool IsInReservedRange(const boost::asio::ip::address& host) { + // https://en.wikipedia.org/wiki/Reserved_IP_addresses + if(host.is_v4()) + { + static const std::vector< std::pair > reservedIPv4Ranges { + address_pair_v4("0.0.0.0", "0.255.255.255"), + address_pair_v4("10.0.0.0", "10.255.255.255"), + address_pair_v4("100.64.0.0", "100.127.255.255"), + address_pair_v4("127.0.0.0", "127.255.255.255"), + address_pair_v4("169.254.0.0", "169.254.255.255"), + address_pair_v4("172.16.0.0", "172.31.255.255"), + address_pair_v4("192.0.0.0", "192.0.0.255"), + address_pair_v4("192.0.2.0", "192.0.2.255"), + address_pair_v4("192.88.99.0", "192.88.99.255"), + address_pair_v4("192.168.0.0", "192.168.255.255"), + address_pair_v4("198.18.0.0", "192.19.255.255"), + address_pair_v4("198.51.100.0", "198.51.100.255"), + address_pair_v4("203.0.113.0", "203.0.113.255"), + address_pair_v4("224.0.0.0", "255.255.255.255") + }; + + uint32_t ipv4_address = host.to_v4 ().to_ulong (); + for(const auto& it : reservedIPv4Ranges) { + if (ipv4_address >= it.first && ipv4_address <= it.second) + return true; + } + } + if(host.is_v6()) + { + static const std::vector< std::pair > reservedIPv6Ranges { + address_pair_v6("2001:db8::", "2001:db8:ffff:ffff:ffff:ffff:ffff:ffff"), + address_pair_v6("fc00::", "fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + address_pair_v6("fe80::", "febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff") + }; + + boost::asio::ip::address_v6::bytes_type ipv6_address = host.to_v6 ().to_bytes (); + for(const auto& it : reservedIPv6Ranges) { + if (ipv6_address >= it.first && ipv6_address <= it.second) + return true; + } + } + return false; + } +} // net } // util } // i2p diff --git a/libi2pd/util.h b/libi2pd/util.h index cb8fd8f1..56ce1e08 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -172,6 +172,7 @@ namespace util { int GetMTU (const boost::asio::ip::address& localAddress); const boost::asio::ip::address GetInterfaceAddress(const std::string & ifname, bool ipv6=false); + bool IsInReservedRange(const boost::asio::ip::address& host); } } } From 18bb4a71c2fe044f9435671c424e162c8145b3c8 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 12 Oct 2020 18:27:25 +0300 Subject: [PATCH 60/71] fix incorrect chars in variable Signed-off-by: R4SAS --- libi2pd/Transports.cpp | 6 +++--- libi2pd/Transports.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index ca86cf42..8fe4a731 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -131,7 +131,7 @@ namespace transport Transports transports; Transports::Transports (): - m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_СheckReserved(true), m_Thread (nullptr), + m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_CheckReserved(true), m_Thread (nullptr), m_Service (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr), m_SSUServer (nullptr), m_NTCP2Server (nullptr), m_DHKeysPairSupplier (5), m_X25519KeysPairSupplier (5), // 5 pre-generated keys @@ -393,7 +393,7 @@ namespace transport { // NTCP2 have priority over NTCP auto address = peer.router->GetNTCP2Address (true, !context.SupportsV6 ()); // published only - if (address && !peer.router->IsUnreachable () && (!m_СheckReserved || !i2p::util::net::IsInReservedRange(address->host))) + if (address && !peer.router->IsUnreachable () && (!m_CheckReserved || !i2p::util::net::IsInReservedRange(address->host))) { auto s = std::make_shared (*m_NTCP2Server, peer.router); @@ -419,7 +419,7 @@ namespace transport if (m_SSUServer && peer.router->IsSSU (!context.SupportsV6 ())) { auto address = peer.router->GetSSUAddress (!context.SupportsV6 ()); - if (!m_СheckReserved || !i2p::util::net::IsInReservedRange(address->host)) + if (!m_CheckReserved || !i2p::util::net::IsInReservedRange(address->host)) { m_SSUServer->CreateSession (peer.router, address->host, address->port); return true; diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 55170ee8..7108fbac 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -136,8 +136,8 @@ namespace transport void PeerTest (); - void SetCheckReserved (bool check) { m_СheckReserved = check; }; - bool IsCheckReserved () { return m_СheckReserved; }; + void SetCheckReserved (bool check) { m_CheckReserved = check; }; + bool IsCheckReserved () { return m_CheckReserved; }; private: @@ -155,7 +155,7 @@ namespace transport private: volatile bool m_IsOnline; - bool m_IsRunning, m_IsNAT, m_СheckReserved; + bool m_IsRunning, m_IsNAT, m_CheckReserved; std::thread * m_Thread; boost::asio::io_service * m_Service; boost::asio::io_service::work * m_Work; From e3464add50dd04f9adf797a31c9f7bf8326c2a4b Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 12 Oct 2020 17:15:17 -0400 Subject: [PATCH 61/71] don't create new tunnels if offline --- libi2pd/Tunnel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 704706ba..c91d0215 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -522,7 +522,7 @@ namespace tunnel } uint64_t ts = i2p::util::GetSecondsSinceEpoch (); - if (ts - lastTs >= 15) // manage tunnels every 15 seconds + if (ts - lastTs >= 15 && i2p::transport::transports.IsOnline()) // manage tunnels every 15 seconds { ManageTunnels (); lastTs = ts; From 3f45a11f12a0b513ea1a8568e48a74e56feca5e9 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 13 Oct 2020 15:22:39 +0300 Subject: [PATCH 62/71] [SSU] handle ICMP responses Windows network stack can forward ICMP to socket and simple deleting of packet can cause socket death. Same thing can happen on other systems but without socket death. Signed-off-by: R4SAS --- libi2pd/SSU.cpp | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index f9c06f37..af76ab2b 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -242,10 +242,16 @@ namespace transport void SSUServer::Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to) { + boost::system::error_code ec; if (to.protocol () == boost::asio::ip::udp::v4()) - m_Socket.send_to (boost::asio::buffer (buf, len), to); + m_Socket.send_to (boost::asio::buffer (buf, len), to, 0, ec); else - m_SocketV6.send_to (boost::asio::buffer (buf, len), to); + m_SocketV6.send_to (boost::asio::buffer (buf, len), to, 0, ec); + + if (ec) + { + LogPrint (eLogError, "SSU: send exception: ", ec.message (), " while trying to send data to ", to.address (), ":", to.port (), " (length: ", len, ")"); + } } void SSUServer::Receive () @@ -264,7 +270,13 @@ namespace transport void SSUServer::HandleReceivedFrom (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet) { - if (!ecode) + if (!ecode || + ecode == boost::asio::error::connection_refused || + ecode == boost::asio::error::connection_reset || + ecode == boost::asio::error::network_unreachable || + ecode == boost::asio::error::host_unreachable) + // just try continue reading when received ICMP response otherwise socket can crash, + // but better to find out which host were sent it and mark that router as unreachable { packet->len = bytes_transferred; std::vector packets; @@ -286,7 +298,7 @@ namespace transport } else { - LogPrint (eLogError, "SSU: receive_from error: ", ec.message ()); + LogPrint (eLogError, "SSU: receive_from error: code ", ec.value(), ": ", ec.message ()); delete packet; break; } @@ -301,7 +313,7 @@ namespace transport delete packet; if (ecode != boost::asio::error::operation_aborted) { - LogPrint (eLogError, "SSU: receive error: ", ecode.message ()); + LogPrint (eLogError, "SSU: receive error: code ", ecode.value(), ": ", ecode.message ()); m_Socket.close (); OpenSocket (); Receive (); @@ -311,7 +323,13 @@ namespace transport void SSUServer::HandleReceivedFromV6 (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet) { - if (!ecode) + if (!ecode || + ecode == boost::asio::error::connection_refused || + ecode == boost::asio::error::connection_reset || + ecode == boost::asio::error::network_unreachable || + ecode == boost::asio::error::host_unreachable) + // just try continue reading when received ICMP response otherwise socket can crash, + // but better to find out which host were sent it and mark that router as unreachable { packet->len = bytes_transferred; std::vector packets; @@ -333,7 +351,7 @@ namespace transport } else { - LogPrint (eLogError, "SSU: v6 receive_from error: ", ec.message ()); + LogPrint (eLogError, "SSU: v6 receive_from error: code ", ec.value(), ": ", ec.message ()); delete packet; break; } @@ -348,7 +366,7 @@ namespace transport delete packet; if (ecode != boost::asio::error::operation_aborted) { - LogPrint (eLogError, "SSU: v6 receive error: ", ecode.message ()); + LogPrint (eLogError, "SSU: v6 receive error: code ", ecode.value(), ": ", ecode.message ()); m_SocketV6.close (); OpenSocketV6 (); ReceiveV6 (); From 614921276e0f490f2cf7d94504049b0e40f18972 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 13 Oct 2020 12:33:27 +0000 Subject: [PATCH 63/71] [appveyor] update configuration to support cache (#1559) --- appveyor.yml | 45 ++++++++++++++++--------------- build/appveyor-msys2-upgrade.bash | 10 ------- 2 files changed, 24 insertions(+), 31 deletions(-) delete mode 100644 build/appveyor-msys2-upgrade.bash diff --git a/appveyor.yml b/appveyor.yml index 10165e5f..3cf51c2b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,46 +9,49 @@ os: Visual Studio 2015 shallow_clone: true clone_depth: 1 +# avoid building 32-bit if 64-bit failed already +matrix: + fast_finish: true + environment: + APPVEYOR_SAVE_CACHE_ON_ERROR: true MSYS2_PATH_TYPE: inherit CHERE_INVOKING: enabled_from_arguments matrix: - MSYSTEM: MINGW64 - MSYS_PACKAGES: mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc - MSYS_BITNESS: 64 - MSYSTEM: MINGW32 - MSYS_PACKAGES: mingw-w64-i686-boost mingw-w64-i686-miniupnpc - MSYS_BITNESS: 32 + +cache: + - c:\msys64\var\cache\pacman\pkg\ install: -# install new signing keyring -- c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" -- c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" -- c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" +# install new signing keyring +- c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" +- c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" +- c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" -# disable inaccessible miror (something block sed from changing files, so rewrite them) - https://github.com/msys2/MINGW-packages/issues/7084 -- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/x86_64/' > /etc/pacman.d/mirrorlist.mingw64" -- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/i686/' > /etc/pacman.d/mirrorlist.mingw32" -- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/msys/$arch/' > /etc/pacman.d/mirrorlist.msys" # remove packages which can break build - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc" # update runtime - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" # Kill bash before next try - taskkill /T /F /IM bash.exe /IM gpg.exe /IM gpg-agent.exe | exit /B 0 -# rewrite mirrorlist again because pacman update can rewrite it -- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/x86_64/' > /etc/pacman.d/mirrorlist.mingw64" -- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/i686/' > /etc/pacman.d/mirrorlist.mingw32" -- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/msys/$arch/' > /etc/pacman.d/mirrorlist.msys" # update packages and install required -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu ${MSYS_PACKAGES}" +- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu $MINGW_PACKAGE_PREFIX-boost $MINGW_PACKAGE_PREFIX-miniupnpc" build_script: -- echo MSYSTEM = %MSYSTEM%, bitness = %MSYS_BITNESS% -- c:\msys64\usr\bin\bash -lc "make USE_UPNP=yes -j3" -- 7z a -tzip -mx9 -mmt i2pd-mingw-win%MSYS_BITNESS%.zip i2pd.exe +- c:\msys64\usr\bin\bash -lc "make USE_UPNP=yes DEBUG=no -j3" +# prepare archive for uploading +- set "FILELIST=i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates contrib/tunnels.d" +- echo This is development build, use it carefully! For running in portable mode, move all files from contrib directory here. > README.txt +- 7z a -tzip -mx9 -mmt i2pd-%APPVEYOR_BUILD_VERSION%-%APPVEYOR_REPO_COMMIT:~0,7%-mingw-win%MSYSTEM:~-2%.zip %FILELIST% + +after_build: +- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sc" test: off +deploy: off + artifacts: -- path: i2pd-mingw-win*.zip +- path: i2pd-*.zip diff --git a/build/appveyor-msys2-upgrade.bash b/build/appveyor-msys2-upgrade.bash deleted file mode 100644 index 20c6af69..00000000 --- a/build/appveyor-msys2-upgrade.bash +++ /dev/null @@ -1,10 +0,0 @@ -set -e -x - -base_url='http://repo.msys2.org/msys/x86_64/' -packages="libzstd-1.4.4-2-x86_64.pkg.tar.xz pacman-5.2.1-6-x86_64.pkg.tar.xz zstd-1.4.4-2-x86_64.pkg.tar.xz" -for p in $packages -do - curl "${base_url}$p" -o "$p" -done -pacman -U --noconfirm $packages -rm -f $packages From acc5592f590248067e41cdbed383eb337f3ebe6b Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 13 Oct 2020 21:12:52 -0400 Subject: [PATCH 64/71] create DH keys for SSU session directly --- libi2pd/SSUSession.cpp | 12 ++++++++---- libi2pd/SSUSession.h | 1 + libi2pd/TransportSession.h | 3 +-- libi2pd/Transports.cpp | 14 +------------- libi2pd/Transports.h | 4 ---- 5 files changed, 11 insertions(+), 23 deletions(-) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 399b2fc7..9ce6e2e3 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -224,7 +224,11 @@ namespace transport return; } if (!m_DHKeysPair) - m_DHKeysPair = transports.GetNextDHKeysPair (); + { + auto pair = std::make_shared (); + pair->GenerateKeys (); + m_DHKeysPair = pair; + } CreateAESandMacKey (buf + headerSize); SendSessionCreated (buf + headerSize, sendRelayTag); } @@ -826,9 +830,9 @@ namespace transport { if (m_State == eSessionStateUnknown) { - // set connect timer - ScheduleConnectTimer (); - m_DHKeysPair = transports.GetNextDHKeysPair (); + ScheduleConnectTimer (); // set connect timer + m_DHKeysPair = std::make_shared (); + m_DHKeysPair->GenerateKeys (); SendSessionRequest (); } } diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index ea820517..3aa04638 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -166,6 +166,7 @@ namespace transport bool m_IsDataReceived; std::unique_ptr m_SignedData; // we need it for SessionConfirmed only std::map > m_RelayRequests; // nonce->Charlie + std::shared_ptr m_DHKeysPair; // X - for client and Y - for server }; } } diff --git a/libi2pd/TransportSession.h b/libi2pd/TransportSession.h index a97f246f..12d4894b 100644 --- a/libi2pd/TransportSession.h +++ b/libi2pd/TransportSession.h @@ -64,7 +64,7 @@ namespace transport public: TransportSession (std::shared_ptr router, int terminationTimeout): - m_DHKeysPair (nullptr), m_NumSentBytes (0), m_NumReceivedBytes (0), m_IsOutgoing (router), m_TerminationTimeout (terminationTimeout), + m_NumSentBytes (0), m_NumReceivedBytes (0), m_IsOutgoing (router), m_TerminationTimeout (terminationTimeout), m_LastActivityTimestamp (i2p::util::GetSecondsSinceEpoch ()) { if (router) @@ -103,7 +103,6 @@ namespace transport std::shared_ptr m_RemoteIdentity; mutable std::mutex m_RemoteIdentityMutex; - std::shared_ptr m_DHKeysPair; // X - for client and Y - for server size_t m_NumSentBytes, m_NumReceivedBytes; bool m_IsOutgoing; int m_TerminationTimeout; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 8fe4a731..4e0aa6a5 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -134,7 +134,7 @@ namespace transport m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_CheckReserved(true), m_Thread (nullptr), m_Service (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr), m_SSUServer (nullptr), m_NTCP2Server (nullptr), - m_DHKeysPairSupplier (5), m_X25519KeysPairSupplier (5), // 5 pre-generated keys + m_X25519KeysPairSupplier (5), // 5 pre-generated keys m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0), m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth(0), m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0), @@ -165,7 +165,6 @@ namespace transport } i2p::config::GetOption("nat", m_IsNAT); - m_DHKeysPairSupplier.Start (); m_X25519KeysPairSupplier.Start (); m_IsRunning = true; m_Thread = new std::thread (std::bind (&Transports::Run, this)); @@ -260,7 +259,6 @@ namespace transport m_NTCP2Server = nullptr; } - m_DHKeysPairSupplier.Stop (); m_X25519KeysPairSupplier.Stop (); m_IsRunning = false; if (m_Service) m_Service->stop (); @@ -540,16 +538,6 @@ namespace transport } } - std::shared_ptr Transports::GetNextDHKeysPair () - { - return m_DHKeysPairSupplier.Acquire (); - } - - void Transports::ReuseDHKeysPair (std::shared_ptr pair) - { - m_DHKeysPairSupplier.Return (pair); - } - std::shared_ptr Transports::GetNextX25519KeysPair () { return m_X25519KeysPairSupplier.Acquire (); diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 7108fbac..d480840a 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -59,7 +59,6 @@ namespace transport std::condition_variable m_Acquired; std::mutex m_AcquiredMutex; }; - typedef EphemeralKeysSupplier DHKeysPairSupplier; typedef EphemeralKeysSupplier X25519KeysPairSupplier; struct Peer @@ -97,8 +96,6 @@ namespace transport void SetOnline (bool online); boost::asio::io_service& GetService () { return *m_Service; }; - std::shared_ptr GetNextDHKeysPair (); - void ReuseDHKeysPair (std::shared_ptr pair); std::shared_ptr GetNextX25519KeysPair (); void ReuseX25519KeysPair (std::shared_ptr pair); @@ -166,7 +163,6 @@ namespace transport mutable std::mutex m_PeersMutex; std::unordered_map m_Peers; - DHKeysPairSupplier m_DHKeysPairSupplier; X25519KeysPairSupplier m_X25519KeysPairSupplier; std::atomic m_TotalSentBytes, m_TotalReceivedBytes, m_TotalTransitTransmittedBytes; From 11691fb44abea05940f12b3579b8c73e2e28ca56 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 14 Oct 2020 07:20:26 +0300 Subject: [PATCH 65/71] create GH workflow Add workflow to build on ubuntu with make --- .github/workflows/build.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..41b71bdf --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,18 @@ +name: Build on Ubuntu with make + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-16.04 + strategy: + fail-fast: true + matrix: + with_upnp: ['yes', 'no'] + steps: + - uses: actions/checkout@v2 + - name: Building with USE_UPNP=${{ matrix.with_upnp }} flag + - name: install packages + run: apt-get install build-essential libboost-date-time-dev libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libminiupnpc-dev libssl-dev zlib1g-dev + - name: build application + run: make USE_AVX=no USE_AESNI=no USE_UPNP=yes USE_UPNP=${{ matrix.with_upnp }} -j3 From 1dbc35f13d2e120c2e15d00223f31d648de61072 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 14 Oct 2020 07:22:00 +0300 Subject: [PATCH 66/71] fix workflow --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 41b71bdf..0aac49f4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,8 +10,8 @@ jobs: matrix: with_upnp: ['yes', 'no'] steps: - - uses: actions/checkout@v2 - name: Building with USE_UPNP=${{ matrix.with_upnp }} flag + uses: actions/checkout@v2 - name: install packages run: apt-get install build-essential libboost-date-time-dev libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libminiupnpc-dev libssl-dev zlib1g-dev - name: build application From 44d3854a1393e660f0cd6e8d740862666f18c0e4 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 14 Oct 2020 07:24:02 +0300 Subject: [PATCH 67/71] [workflow] use sudo when installing packages --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0aac49f4..518a148c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,6 +13,6 @@ jobs: - name: Building with USE_UPNP=${{ matrix.with_upnp }} flag uses: actions/checkout@v2 - name: install packages - run: apt-get install build-essential libboost-date-time-dev libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libminiupnpc-dev libssl-dev zlib1g-dev + run: sudo apt-get install build-essential libboost-date-time-dev libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libminiupnpc-dev libssl-dev zlib1g-dev - name: build application - run: make USE_AVX=no USE_AESNI=no USE_UPNP=yes USE_UPNP=${{ matrix.with_upnp }} -j3 + run: make USE_AVX=no USE_AESNI=no USE_UPNP=${{ matrix.with_upnp }} -j3 From 36fc0daa126393f62911c99e2f037e90cdb9ffb3 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 14 Oct 2020 07:36:16 +0300 Subject: [PATCH 68/71] [workflow] use latest boost from PPA --- .github/workflows/build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 518a148c..77704af5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,6 +13,9 @@ jobs: - name: Building with USE_UPNP=${{ matrix.with_upnp }} flag uses: actions/checkout@v2 - name: install packages - run: sudo apt-get install build-essential libboost-date-time-dev libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libminiupnpc-dev libssl-dev zlib1g-dev + run: | + sudo add-apt-repository ppa:mhier/libboost-latest + sudo apt-get update + sudo apt-get install build-essential libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev - name: build application run: make USE_AVX=no USE_AESNI=no USE_UPNP=${{ matrix.with_upnp }} -j3 From 8e24d1b909a9e910023231bdbd82ee60f5d3d42b Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 14 Oct 2020 07:44:22 +0300 Subject: [PATCH 69/71] [workflow] change options order Apply name for job, not for step. --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 77704af5..ba6acbf8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,14 +4,14 @@ on: [push, pull_request] jobs: build: + name: Building with USE_UPNP=${{ matrix.with_upnp }} flag runs-on: ubuntu-16.04 strategy: fail-fast: true matrix: with_upnp: ['yes', 'no'] steps: - - name: Building with USE_UPNP=${{ matrix.with_upnp }} flag - uses: actions/checkout@v2 + - uses: actions/checkout@v2 - name: install packages run: | sudo add-apt-repository ppa:mhier/libboost-latest From d9d31521f9d240020846f4aff7a3938208d10541 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 14 Oct 2020 08:06:22 +0300 Subject: [PATCH 70/71] [workflow] add windows build --- .github/workflows/build-windows.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/build-windows.yml diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml new file mode 100644 index 00000000..9fd66bbc --- /dev/null +++ b/.github/workflows/build-windows.yml @@ -0,0 +1,29 @@ +name: Build on Windows + +on: [push, pull_request] + +defaults: + run: + shell: msys2 {0} + +jobs: + build: + name: Building for ${{ matrix.arch }} + runs-on: windows-latest + strategy: + fail-fast: true + matrix: + include: [ + { msystem: MINGW64, arch: x86_64 }, + { msystem: MINGW32, arch: i686 } + ] + steps: + - uses: actions/checkout@v2 + - name: Setup MSYS2 + uses: msys2/setup-msys2@v2 + with: + msystem: ${{ matrix.msystem }} + install: base-devel mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-miniupnpc + update: true + - name: build application + run: make USE_UPNP=yes DEBUG=no -j3 From 2648f1ba89d5032262a72ca8b2d2d8a70e441b9a Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 14 Oct 2020 08:14:33 +0300 Subject: [PATCH 71/71] [workflow] install required packages --- .github/workflows/build-windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 9fd66bbc..9763f75b 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -23,7 +23,7 @@ jobs: uses: msys2/setup-msys2@v2 with: msystem: ${{ matrix.msystem }} - install: base-devel mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-miniupnpc + install: base-devel mingw-w64-${{ matrix.arch }}-gcc mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-openssl mingw-w64-${{ matrix.arch }}-miniupnpc update: true - name: build application run: make USE_UPNP=yes DEBUG=no -j3