From 3643d2f1da92ff8b6d10808440eb0d4950516e09 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 11 Dec 2014 15:41:04 -0500 Subject: [PATCH] reseed from SU3 --- NetDb.cpp | 7 ++ NetDb.h | 1 + Reseed.cpp | 216 ++++++++++++++++++++++++++++++----------------------- Reseed.h | 12 ++- 4 files changed, 142 insertions(+), 94 deletions(-) diff --git a/NetDb.cpp b/NetDb.cpp index 9c80a532..572eff98 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -165,6 +165,13 @@ namespace data } } + void NetDb::AddRouterInfo (const uint8_t * buf, int len) + { + IdentityEx identity; + identity.FromBuffer (buf, len); + AddRouterInfo (identity.GetIdentHash (), buf, len); + } + void NetDb::AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len) { DeleteRequestedDestination (ident); diff --git a/NetDb.h b/NetDb.h index 042347dc..3bc96b93 100644 --- a/NetDb.h +++ b/NetDb.h @@ -62,6 +62,7 @@ namespace data void Start (); void Stop (); + void AddRouterInfo (const uint8_t * buf, int len); void AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len); void AddLeaseSet (const IdentHash& ident, const uint8_t * buf, int len, i2p::tunnel::InboundTunnel * from); std::shared_ptr FindRouter (const IdentHash& ident) const; diff --git a/Reseed.cpp b/Reseed.cpp index 78b4522f..3d8a01de 100644 --- a/Reseed.cpp +++ b/Reseed.cpp @@ -1,5 +1,5 @@ -#include #include +#include #include #include #include @@ -7,6 +7,7 @@ #include "Reseed.h" #include "Log.h" #include "Identity.h" +#include "NetDb.h" #include "util.h" @@ -122,111 +123,142 @@ namespace data return false; } + int Reseeder::ReseedNowSU3 () + { + std::string reseedHost = httpReseedHostList[(rand() % httpReseedHostList.size())]; + return ReseedFromSU3 (reseedHost); + } + + int Reseeder::ReseedFromSU3 (const std::string& host) + { + std::string url = host + "i2pseeds.su3"; + LogPrint (eLogInfo, "Dowloading SU3 from ", host); + std::string su3 = i2p::util::http::httpRequest (url); + if (su3.length () > 0) + { + std::stringstream s(su3); + return ProcessSU3Stream (s); + } + else + { + LogPrint (eLogWarning, "SU3 download failed"); + return 0; + } + } + int ProcessSU3File (const char * filename) + { + std::ifstream s(filename, std::ifstream::binary); + if (s.is_open ()) + return ProcessSU3Stream (s); + else + { + LogPrint (eLogError, "Can't open file ", filename); + return 0; + } + } + const char SU3_MAGIC_NUMBER[]="I2Psu3"; - void ProcessSU3File (const char * filename) + int ProcessSU3Stream (std::istream& s) { static uint32_t headerSignature = htole32 (0x04034B50); - std::ifstream s(filename, std::ifstream::binary); - if (s.is_open ()) + char magicNumber[7]; + s.read (magicNumber, 7); // magic number and zero byte 6 + if (strcmp (magicNumber, SU3_MAGIC_NUMBER)) + { + LogPrint (eLogError, "Unexpected SU3 magic number"); + return 0; + } + s.seekg (1, std::ios::cur); // su3 file format version + SigningKeyType signatureType; + s.read ((char *)&signatureType, 2); // signature type + signatureType = be16toh (signatureType); + uint16_t signatureLength; + s.read ((char *)&signatureLength, 2); // signature length + signatureLength = be16toh (signatureLength); + s.seekg (1, std::ios::cur); // unused + uint8_t versionLength; + s.read ((char *)&versionLength, 1); // version length + s.seekg (1, std::ios::cur); // unused + uint8_t signerIDLength; + s.read ((char *)&signerIDLength, 1); // signer ID length + uint64_t contentLength; + s.read ((char *)&contentLength, 8); // content length + contentLength = be64toh (contentLength); + s.seekg (1, std::ios::cur); // unused + uint8_t fileType; + s.read ((char *)&fileType, 1); // file type + if (fileType != 0x00) // zip file + { + LogPrint (eLogError, "Can't handle file type ", (int)fileType); + return 0; + } + s.seekg (1, std::ios::cur); // unused + uint8_t contentType; + s.read ((char *)&contentType, 1); // content type + if (contentType != 0x03) // reseed data + { + LogPrint (eLogError, "Unexpected content type ", (int)contentType); + return 0; + } + s.seekg (12, std::ios::cur); // unused + + s.seekg (versionLength, std::ios::cur); // skip version + s.seekg (signerIDLength, std::ios::cur); // skip signer ID + + // handle content + int numFiles = 0; + size_t contentPos = s.tellg (); + while (!s.eof ()) { - char magicNumber[7]; - s.read (magicNumber, 7); // magic number and zero byte 6 - if (strcmp (magicNumber, SU3_MAGIC_NUMBER)) + uint32_t signature; + s.read ((char *)&signature, 4); + if (signature == headerSignature) { - LogPrint (eLogError, "Unexpected SU3 magic number"); - return; - } - s.seekg (1, std::ios::cur); // su3 file format version - SigningKeyType signatureType; - s.read ((char *)&signatureType, 2); // signature type - signatureType = be16toh (signatureType); - uint16_t signatureLength; - s.read ((char *)&signatureLength, 2); // signature length - signatureLength = be16toh (signatureLength); - s.seekg (1, std::ios::cur); // unused - uint8_t versionLength; - s.read ((char *)&versionLength, 1); // version length - s.seekg (1, std::ios::cur); // unused - uint8_t signerIDLength; - s.read ((char *)&signerIDLength, 1); // signer ID length - uint64_t contentLength; - s.read ((char *)&contentLength, 8); // content length - contentLength = be64toh (contentLength); - s.seekg (1, std::ios::cur); // unused - uint8_t fileType; - s.read ((char *)&fileType, 1); // file type - if (fileType != 0x00) // zip file - { - LogPrint (eLogError, "Can't handle file type ", (int)fileType); - return; - } - s.seekg (1, std::ios::cur); // unused - uint8_t contentType; - s.read ((char *)&contentType, 1); // content type - if (contentType != 0x03) // reseed data - { - LogPrint (eLogError, "Unexpected content type ", (int)contentType); - return; - } - s.seekg (12, std::ios::cur); // unused - - s.seekg (versionLength, std::ios::cur); // skip version - s.seekg (signerIDLength, std::ios::cur); // skip signer ID + // next local file + s.seekg (14, std::ios::cur); // skip field we don't care about + uint32_t compressedSize, uncompressedSize; + s.read ((char *)&compressedSize, 4); + compressedSize = le32toh (compressedSize); + s.read ((char *)&uncompressedSize, 4); + uncompressedSize = le32toh (uncompressedSize); + uint16_t fileNameLength, extraFieldLength; + s.read ((char *)&fileNameLength, 2); + fileNameLength = le32toh (fileNameLength); + s.read ((char *)&extraFieldLength, 2); + extraFieldLength = le32toh (extraFieldLength); + char localFileName[255]; + s.read (localFileName, fileNameLength); + localFileName[fileNameLength] = 0; + s.seekg (extraFieldLength, std::ios::cur); + LogPrint (eLogDebug, "Proccessing file ", localFileName, " ", compressedSize, " bytes"); - // handle content - size_t contentPos = s.tellg (); - while (!s.eof ()) - { - uint32_t signature; - s.read ((char *)&signature, 4); - if (signature == headerSignature) + uint8_t * compressed = new uint8_t[compressedSize]; + s.read ((char *)compressed, compressedSize); + CryptoPP::Inflator decompressor; + decompressor.Put (compressed, compressedSize); + delete[] compressed; + size_t len = decompressor.MaxRetrievable (); + if (len <= uncompressedSize) { - // next local file - s.seekg (14, std::ios::cur); // skip field we don't care about - uint32_t compressedSize, uncompressedSize; - s.read ((char *)&compressedSize, 4); - compressedSize = le32toh (compressedSize); - s.read ((char *)&uncompressedSize, 4); - uncompressedSize = le32toh (uncompressedSize); - uint16_t fileNameLength, extraFieldLength; - s.read ((char *)&fileNameLength, 2); - fileNameLength = le32toh (fileNameLength); - s.read ((char *)&extraFieldLength, 2); - extraFieldLength = le32toh (extraFieldLength); - char localFileName[255]; - s.read (localFileName, fileNameLength); - localFileName[fileNameLength] = 0; - s.seekg (extraFieldLength, std::ios::cur); - LogPrint (eLogDebug, "Proccessing file ", localFileName, " ", compressedSize, " bytes"); - - uint8_t * compressed = new uint8_t[compressedSize]; - s.read ((char *)compressed, compressedSize); - CryptoPP::Inflator decompressor; - decompressor.Put (compressed, compressedSize); - delete[] compressed; - if (decompressor.MaxRetrievable () <= uncompressedSize) - { - uint8_t * uncompressed = new uint8_t[uncompressedSize]; - decompressor.Get (uncompressed, decompressor.MaxRetrievable ()); - // TODO: save file - delete[] uncompressed; - } - else - LogPrint (eLogError, "Actual uncompressed size ", decompressor.MaxRetrievable (), " exceed ", uncompressedSize, " from header"); + uint8_t * uncompressed = new uint8_t[uncompressedSize]; + decompressor.Get (uncompressed, len); + i2p::data::netdb.AddRouterInfo (uncompressed, len); + numFiles++; + delete[] uncompressed; } else - break; // no more files - size_t end = s.tellg (); - if (end - contentPos >= contentLength) - break; // we are beyond contentLength + LogPrint (eLogError, "Actual uncompressed size ", decompressor.MaxRetrievable (), " exceed ", uncompressedSize, " from header"); } + else + break; // no more files + size_t end = s.tellg (); + if (end - contentPos >= contentLength) + break; // we are beyond contentLength } - else - LogPrint (eLogError, "Can't open file ", filename); + return numFiles; } - } } diff --git a/Reseed.h b/Reseed.h index 2b5b8272..97257fab 100644 --- a/Reseed.h +++ b/Reseed.h @@ -1,6 +1,7 @@ #ifndef RESEED_H #define RESEED_H +#include #include #include @@ -12,12 +13,19 @@ namespace data class Reseeder { public: + Reseeder(); ~Reseeder(); - bool reseedNow(); + bool reseedNow(); // depreacted + int ReseedNowSU3 (); + + private: + + int ReseedFromSU3 (const std::string& host); }; - void ProcessSU3File (const char * filename); + int ProcessSU3File (const char * filename); + int ProcessSU3Stream (std::istream& s); } }