Browse Source

reseed from SU3

pull/117/head
orignal 10 years ago
parent
commit
3643d2f1da
  1. 7
      NetDb.cpp
  2. 1
      NetDb.h
  3. 216
      Reseed.cpp
  4. 12
      Reseed.h

7
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) void NetDb::AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len)
{ {
DeleteRequestedDestination (ident); DeleteRequestedDestination (ident);

1
NetDb.h

@ -62,6 +62,7 @@ namespace data
void Start (); void Start ();
void Stop (); void Stop ();
void AddRouterInfo (const uint8_t * buf, int len);
void AddRouterInfo (const IdentHash& ident, 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); void AddLeaseSet (const IdentHash& ident, const uint8_t * buf, int len, i2p::tunnel::InboundTunnel * from);
std::shared_ptr<RouterInfo> FindRouter (const IdentHash& ident) const; std::shared_ptr<RouterInfo> FindRouter (const IdentHash& ident) const;

216
Reseed.cpp

@ -1,5 +1,5 @@
#include <iostream>
#include <fstream> #include <fstream>
#include <sstream>
#include <boost/regex.hpp> #include <boost/regex.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <cryptopp/zinflate.h> #include <cryptopp/zinflate.h>
@ -7,6 +7,7 @@
#include "Reseed.h" #include "Reseed.h"
#include "Log.h" #include "Log.h"
#include "Identity.h" #include "Identity.h"
#include "NetDb.h"
#include "util.h" #include "util.h"
@ -122,111 +123,142 @@ namespace data
return false; 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"; const char SU3_MAGIC_NUMBER[]="I2Psu3";
void ProcessSU3File (const char * filename) int ProcessSU3Stream (std::istream& s)
{ {
static uint32_t headerSignature = htole32 (0x04034B50); static uint32_t headerSignature = htole32 (0x04034B50);
std::ifstream s(filename, std::ifstream::binary); char magicNumber[7];
if (s.is_open ()) 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]; uint32_t signature;
s.read (magicNumber, 7); // magic number and zero byte 6 s.read ((char *)&signature, 4);
if (strcmp (magicNumber, SU3_MAGIC_NUMBER)) if (signature == headerSignature)
{ {
LogPrint (eLogError, "Unexpected SU3 magic number"); // next local file
return; s.seekg (14, std::ios::cur); // skip field we don't care about
} uint32_t compressedSize, uncompressedSize;
s.seekg (1, std::ios::cur); // su3 file format version s.read ((char *)&compressedSize, 4);
SigningKeyType signatureType; compressedSize = le32toh (compressedSize);
s.read ((char *)&signatureType, 2); // signature type s.read ((char *)&uncompressedSize, 4);
signatureType = be16toh (signatureType); uncompressedSize = le32toh (uncompressedSize);
uint16_t signatureLength; uint16_t fileNameLength, extraFieldLength;
s.read ((char *)&signatureLength, 2); // signature length s.read ((char *)&fileNameLength, 2);
signatureLength = be16toh (signatureLength); fileNameLength = le32toh (fileNameLength);
s.seekg (1, std::ios::cur); // unused s.read ((char *)&extraFieldLength, 2);
uint8_t versionLength; extraFieldLength = le32toh (extraFieldLength);
s.read ((char *)&versionLength, 1); // version length char localFileName[255];
s.seekg (1, std::ios::cur); // unused s.read (localFileName, fileNameLength);
uint8_t signerIDLength; localFileName[fileNameLength] = 0;
s.read ((char *)&signerIDLength, 1); // signer ID length s.seekg (extraFieldLength, std::ios::cur);
uint64_t contentLength; LogPrint (eLogDebug, "Proccessing file ", localFileName, " ", compressedSize, " bytes");
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
// handle content uint8_t * compressed = new uint8_t[compressedSize];
size_t contentPos = s.tellg (); s.read ((char *)compressed, compressedSize);
while (!s.eof ()) CryptoPP::Inflator decompressor;
{ decompressor.Put (compressed, compressedSize);
uint32_t signature; delete[] compressed;
s.read ((char *)&signature, 4); size_t len = decompressor.MaxRetrievable ();
if (signature == headerSignature) if (len <= uncompressedSize)
{ {
// next local file uint8_t * uncompressed = new uint8_t[uncompressedSize];
s.seekg (14, std::ios::cur); // skip field we don't care about decompressor.Get (uncompressed, len);
uint32_t compressedSize, uncompressedSize; i2p::data::netdb.AddRouterInfo (uncompressed, len);
s.read ((char *)&compressedSize, 4); numFiles++;
compressedSize = le32toh (compressedSize); delete[] uncompressed;
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");
} }
else else
break; // no more files LogPrint (eLogError, "Actual uncompressed size ", decompressor.MaxRetrievable (), " exceed ", uncompressedSize, " from header");
size_t end = s.tellg ();
if (end - contentPos >= contentLength)
break; // we are beyond contentLength
} }
else
break; // no more files
size_t end = s.tellg ();
if (end - contentPos >= contentLength)
break; // we are beyond contentLength
} }
else return numFiles;
LogPrint (eLogError, "Can't open file ", filename);
} }
} }
} }

12
Reseed.h

@ -1,6 +1,7 @@
#ifndef RESEED_H #ifndef RESEED_H
#define RESEED_H #define RESEED_H
#include <iostream>
#include <string> #include <string>
#include <vector> #include <vector>
@ -12,12 +13,19 @@ namespace data
class Reseeder class Reseeder
{ {
public: public:
Reseeder(); Reseeder();
~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);
} }
} }

Loading…
Cancel
Save