mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-12 18:38:07 +00:00
Adding reseed support. v1, only http so far.
This commit is contained in:
parent
d107ef4007
commit
86355cfe09
4
Makefile
4
Makefile
@ -4,9 +4,9 @@ CFLAGS = -g -Wall -std=c++0x
|
||||
OBJECTS = obj/i2p.o obj/base64.o obj/NTCPSession.o obj/RouterInfo.o obj/Transports.o \
|
||||
obj/RouterContext.o obj/NetDb.o obj/LeaseSet.o obj/Tunnel.o obj/TunnelEndpoint.o \
|
||||
obj/TunnelGateway.o obj/TransitTunnel.o obj/I2NPProtocol.o obj/Log.o obj/Garlic.o \
|
||||
obj/HTTPServer.o obj/Streaming.o obj/Identity.o obj/SSU.o obj/util.o
|
||||
obj/HTTPServer.o obj/Streaming.o obj/Identity.o obj/SSU.o obj/util.o obj/Reseed.o
|
||||
INCFLAGS =
|
||||
LDFLAGS = -Wl,-rpath,/usr/local/lib -lcryptopp -lboost_system -lboost_filesystem -lpthread
|
||||
LDFLAGS = -Wl,-rpath,/usr/local/lib -lcryptopp -lboost_system -lboost_filesystem -lboost_regex -lpthread
|
||||
LIBS =
|
||||
|
||||
all: i2p
|
||||
|
56
NetDb.cpp
56
NetDb.cpp
@ -13,6 +13,7 @@
|
||||
#include "RouterContext.h"
|
||||
#include "Garlic.h"
|
||||
#include "NetDb.h"
|
||||
#include "Reseed.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
@ -207,12 +208,23 @@ namespace data
|
||||
|
||||
void NetDb::Load (const char * directory)
|
||||
{
|
||||
Load(directory, false);
|
||||
}
|
||||
|
||||
void NetDb::Load (const char * directory, bool reseed)
|
||||
{
|
||||
i2p::data::Reseeder *reseeder = new i2p::data::Reseeder();
|
||||
boost::filesystem::path p (directory);
|
||||
if (!boost::filesystem::exists (p))
|
||||
{
|
||||
if (!CreateNetDb(directory)) return;
|
||||
reseeder->reseedNow();
|
||||
}
|
||||
if (reseed)
|
||||
{
|
||||
reseeder->reseedNow();
|
||||
m_reseedRetries++;
|
||||
}
|
||||
// TODO: Reseed if needed.
|
||||
int numRouters = 0;
|
||||
boost::filesystem::directory_iterator end;
|
||||
for (boost::filesystem::directory_iterator it (p); it != end; ++it)
|
||||
@ -232,6 +244,8 @@ namespace data
|
||||
}
|
||||
}
|
||||
LogPrint (numRouters, " routers loaded");
|
||||
if (numRouters < 100 && m_reseedRetries < 10)
|
||||
Load(directory, true); // Reseed
|
||||
}
|
||||
|
||||
void NetDb::SaveUpdated (const char * directory)
|
||||
@ -601,45 +615,5 @@ namespace data
|
||||
return r;
|
||||
}
|
||||
|
||||
//TODO: Move to reseed.
|
||||
//TODO: Implement v1 & v2 reseeding. Lightweight zip library is needed for v2.
|
||||
// orignal: zip is part of crypto++, see implementation of DatabaseStoreMsg
|
||||
//TODO: Implement SU3, utils.
|
||||
void NetDb::DownloadRouterInfo (const std::string& address, const std::string& filename)
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::asio::ip::tcp::iostream site(address, "http");
|
||||
if (!site)
|
||||
{
|
||||
//site.expires_from_now (boost::posix_time::seconds (10)); // wait for 10 seconds
|
||||
site << "GET " << filename << "HTTP/1.0\nHost: " << address << "\nAccept: */*\nConnection: close\n\n";
|
||||
// read response
|
||||
std::string version, statusMessage;
|
||||
site >> version; // HTTP version
|
||||
int status;
|
||||
site >> status; // status
|
||||
std::getline (site, statusMessage);
|
||||
if (status == 200) // OK
|
||||
{
|
||||
std::string header;
|
||||
while (header != "\n")
|
||||
std::getline (site, header);
|
||||
// read content
|
||||
std::stringstream ss;
|
||||
ss << site.rdbuf();
|
||||
AddRouterInfo ((uint8_t *)ss.str ().c_str (), ss.str ().size ());
|
||||
}
|
||||
else
|
||||
LogPrint ("HTTP response ", status);
|
||||
}
|
||||
else
|
||||
LogPrint ("Can't connect to ", address);
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
LogPrint ("Failed to download ", filename, " : ", ex.what ());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
3
NetDb.h
3
NetDb.h
@ -78,8 +78,8 @@ namespace data
|
||||
|
||||
bool CreateNetDb(const char * directory);
|
||||
void Load (const char * directory);
|
||||
void Load (const char * directory, bool reseed);
|
||||
void SaveUpdated (const char * directory);
|
||||
void DownloadRouterInfo (const std::string& address, const std::string& filename); // for reseed
|
||||
void Run (); // exploratory thread
|
||||
void Explore ();
|
||||
const RouterInfo * GetClosestFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded) const;
|
||||
@ -95,6 +95,7 @@ namespace data
|
||||
std::map<IdentHash, RequestedDestination *> m_RequestedDestinations;
|
||||
|
||||
bool m_IsRunning;
|
||||
int m_reseedRetries = 0;
|
||||
std::thread * m_Thread;
|
||||
i2p::util::Queue<I2NPMessage> m_Queue; // of I2NPDatabaseStoreMsg
|
||||
};
|
||||
|
70
Reseed.cpp
Normal file
70
Reseed.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
#include "Reseed.h"
|
||||
#include "Log.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace data
|
||||
{
|
||||
|
||||
Reseeder::Reseeder()
|
||||
{
|
||||
}
|
||||
|
||||
Reseeder::~Reseeder()
|
||||
{
|
||||
}
|
||||
|
||||
bool Reseeder::reseedNow()
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string reseedHost = httpReseedHostList[(rand() % httpReseedHostList.size())];
|
||||
LogPrint("Reseeding from ", reseedHost);
|
||||
std::string content = i2p::util::http::httpRequest(reseedHost);
|
||||
if (content == "")
|
||||
{
|
||||
LogPrint("Reseed failed");
|
||||
return false;
|
||||
}
|
||||
boost::regex e("<\\s*A\\s+[^>]*href\\s*=\\s*\"([^\"]*)\"",
|
||||
boost::regex::normal | boost::regbase::icase);
|
||||
boost::sregex_token_iterator i(content.begin(), content.end(), e, 1);
|
||||
boost::sregex_token_iterator j;
|
||||
std::string name;
|
||||
std::string routerInfo;
|
||||
std::string tmpUrl;
|
||||
std::string filename;
|
||||
while (i != j)
|
||||
{
|
||||
name = *i++;
|
||||
LogPrint("Downloading ", name);
|
||||
tmpUrl = reseedHost;
|
||||
tmpUrl.append(name);
|
||||
routerInfo = i2p::util::http::httpRequest(tmpUrl);
|
||||
filename = "netDb/r";
|
||||
filename += name.at(11);
|
||||
filename.append("/");
|
||||
filename.append(name.c_str());
|
||||
std::ofstream outfile (filename, std::ios::binary);
|
||||
outfile << routerInfo;
|
||||
outfile.close();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
//TODO: error reporting
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
28
Reseed.h
Normal file
28
Reseed.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef RESEED_H
|
||||
#define RESEED_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace data
|
||||
{
|
||||
|
||||
class Reseeder
|
||||
{
|
||||
public:
|
||||
Reseeder();
|
||||
~Reseeder();
|
||||
bool reseedNow();
|
||||
private:
|
||||
std::vector<std::string> httpReseedHostList = {
|
||||
"http://193.150.121.66/netDb/",
|
||||
"http://netdb.i2p2.no/"
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
95
util.cpp
95
util.cpp
@ -1,4 +1,11 @@
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <functional>
|
||||
#include <fstream>
|
||||
#include <boost/asio.hpp>
|
||||
#include "util.h"
|
||||
#include "Log.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
@ -40,6 +47,94 @@ const char* GetCharArg(const std::string& strArg, const std::string& nDefault)
|
||||
return nDefault.c_str();
|
||||
}
|
||||
|
||||
namespace http
|
||||
{
|
||||
//const std::string& filename
|
||||
//AddRouterInfo ((uint8_t *)ss.str ().c_str (), ss.str ().size ());
|
||||
//TODO: Move to reseed.
|
||||
//TODO: Implement v1 & v2 reseeding. Lightweight zip library is needed for v2.
|
||||
// orignal: zip is part of crypto++, see implementation of DatabaseStoreMsg
|
||||
//TODO: Implement SU3, utils.
|
||||
std::string httpRequest(const std::string& address)
|
||||
{
|
||||
try
|
||||
{
|
||||
i2p::util::http::url u(address);
|
||||
boost::asio::ip::tcp::iostream site;
|
||||
site.expires_from_now (boost::posix_time::seconds(30));
|
||||
site.connect(u.host_, "http");
|
||||
if (site)
|
||||
{
|
||||
//site.expires_from_now (boost::posix_time::seconds (10)); // wait for 10 seconds
|
||||
// User-Agent is needed to get the server list routerInfo files.
|
||||
site << "GET " << u.path_ << " HTTP/1.0\r\nHost: " << u.host_
|
||||
<< "\r\nAccept: */*\r\n" << "User-Agent: Wget/1.11.4\r\n" << "Connection: close\r\n\r\n";
|
||||
// read response
|
||||
std::string version, statusMessage;
|
||||
site >> version; // HTTP version
|
||||
int status;
|
||||
site >> status; // status
|
||||
std::getline (site, statusMessage);
|
||||
if (status == 200) // OK
|
||||
{
|
||||
std::string header;
|
||||
while (std::getline(site, header) && header != "\r"){}
|
||||
std::stringstream ss;
|
||||
ss << site.rdbuf();
|
||||
return ss.str();
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint ("HTTP response ", status);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint ("Can't connect to ", address);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
LogPrint ("Failed to download ", address, " : ", ex.what ());
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
url::url(const std::string& url_s)
|
||||
{
|
||||
parse(url_s);
|
||||
}
|
||||
|
||||
void url::parse(const std::string& url_s)
|
||||
{
|
||||
const std::string prot_end("://");
|
||||
std::string::const_iterator prot_i = search(url_s.begin(), url_s.end(),
|
||||
prot_end.begin(), prot_end.end());
|
||||
protocol_.reserve(distance(url_s.begin(), prot_i));
|
||||
transform(url_s.begin(), prot_i,
|
||||
back_inserter(protocol_),
|
||||
std::ptr_fun<int,int>(tolower)); // protocol is icase
|
||||
if( prot_i == url_s.end() )
|
||||
return;
|
||||
advance(prot_i, prot_end.length());
|
||||
std::string::const_iterator path_i = find(prot_i, url_s.end(), '/');
|
||||
host_.reserve(distance(prot_i, path_i));
|
||||
transform(prot_i, path_i,
|
||||
back_inserter(host_),
|
||||
std::ptr_fun<int,int>(tolower)); // host is icase
|
||||
std::string::const_iterator query_i = find(path_i, url_s.end(), '?');
|
||||
path_.assign(path_i, query_i);
|
||||
if( query_i != url_s.end() )
|
||||
++query_i;
|
||||
query_.assign(query_i, url_s.end());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // Namespace end
|
||||
}
|
||||
|
12
util.h
12
util.h
@ -12,7 +12,17 @@ namespace util
|
||||
void OptionParser(int argc, const char* const argv[]);
|
||||
int GetIntArg(const std::string& strArg, int nDefault);
|
||||
const char* GetCharArg(const std::string& strArg, const std::string& nDefault);
|
||||
|
||||
namespace http
|
||||
{
|
||||
std::string httpRequest(const std::string& address);
|
||||
struct url {
|
||||
url(const std::string& url_s); // omitted copy, ==, accessors, ...
|
||||
private:
|
||||
void parse(const std::string& url_s);
|
||||
public:
|
||||
std::string protocol_, host_, path_, query_;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user