mirror of https://github.com/PurpleI2P/i2pd.git
chertov
11 years ago
24 changed files with 1167 additions and 221 deletions
@ -1,26 +1,31 @@
@@ -1,26 +1,31 @@
|
||||
|
||||
CC = g++ |
||||
CFLAGS = -g -Wall -std=c++0x |
||||
OBJECTS = i2p.o base64.o NTCPSession.o RouterInfo.o Transports.o RouterContext.o \
|
||||
NetDb.o LeaseSet.o Tunnel.o TunnelEndpoint.o TunnelGateway.o TransitTunnel.o \
|
||||
I2NPProtocol.o Log.o Garlic.o HTTPServer.o Streaming.o Identity.o SSU.o |
||||
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/Reseed.o |
||||
INCFLAGS = |
||||
LDFLAGS = -Wl,-rpath,/usr/local/lib -lcryptopp -lboost_system -lboost_filesystem |
||||
LDFLAGS = -Wl,-rpath,/usr/local/lib -lcryptopp -lboost_system -lboost_filesystem -lboost_regex -lboost_program_options -lpthread |
||||
LIBS = |
||||
|
||||
all: i2p |
||||
all: obj i2p |
||||
|
||||
i2p: $(OBJECTS) |
||||
$(CC) -o i2p $(OBJECTS) $(LDFLAGS) $(LIBS) |
||||
i2p: $(OBJECTS:obj/%=obj/%) |
||||
$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) |
||||
|
||||
.SUFFIXES: |
||||
.SUFFIXES: .c .cc .C .cpp .o |
||||
|
||||
.cpp.o : |
||||
$(CC) -o $@ -c $(CFLAGS) $< $(INCFLAGS) |
||||
obj/%.o : %.cpp |
||||
$(CC) -o $@ $< -c $(CFLAGS) $(INCFLAGS) |
||||
|
||||
obj: |
||||
mkdir -p obj |
||||
|
||||
clean: |
||||
rm -f *.o |
||||
rm -fr obj i2p |
||||
|
||||
.PHONY: all |
||||
.PHONY: clean |
||||
|
||||
|
@ -0,0 +1,101 @@
@@ -0,0 +1,101 @@
|
||||
#include <iostream> |
||||
#include <fstream> |
||||
#include <boost/regex.hpp> |
||||
#include <boost/filesystem.hpp> |
||||
#include "Reseed.h" |
||||
#include "Log.h" |
||||
#include "util.h" |
||||
|
||||
|
||||
namespace i2p |
||||
{ |
||||
namespace data |
||||
{ |
||||
|
||||
static std::vector<std::string> httpReseedHostList = { |
||||
"http://193.150.121.66/netDb/", |
||||
"http://netdb.i2p2.no/", |
||||
"http://reseed.i2p-projekt.de/", |
||||
"http://cowpuncher.drollette.com/netdb/", |
||||
"http://i2p.mooo.com/netDb/", |
||||
"http://reseed.info/", |
||||
"http://reseed.pkol.de/", |
||||
"http://uk.reseed.i2p2.no/", |
||||
"http://i2p-netdb.innovatio.no/", |
||||
"http://ieb9oopo.mooo.com" |
||||
}; |
||||
|
||||
//TODO: Implement v2 reseeding. Lightweight zip library is needed.
|
||||
//TODO: Implement SU3, utils.
|
||||
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; |
||||
//TODO: Ugly code, try to clean up.
|
||||
//TODO: Try to reduce N number of variables
|
||||
std::string name; |
||||
std::string routerInfo; |
||||
std::string tmpUrl; |
||||
std::string filename; |
||||
std::string ignoreFileSuffix = ".zip"; |
||||
boost::filesystem::path root = i2p::util::filesystem::GetDataDir(); |
||||
while (i != j) |
||||
{ |
||||
name = *i++; |
||||
if (name.find(ignoreFileSuffix)!=std::string::npos) |
||||
continue; |
||||
LogPrint("Downloading ", name); |
||||
tmpUrl = reseedHost; |
||||
tmpUrl.append(name); |
||||
routerInfo = i2p::util::http::httpRequest(tmpUrl); |
||||
if (routerInfo.size()==0) |
||||
continue; |
||||
filename = root.string(); |
||||
#ifndef _WIN32 |
||||
filename += "/netDb/r"; |
||||
#else |
||||
filename += "\\netDb\\r"; |
||||
#endif |
||||
filename += name.at(11); // first char in id
|
||||
#ifndef _WIN32 |
||||
filename.append("/"); |
||||
#else |
||||
filename.append("\\"); |
||||
#endif |
||||
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; |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
#ifndef RESEED_H |
||||
#define RESEED_H |
||||
|
||||
#include <string> |
||||
#include <vector> |
||||
|
||||
namespace i2p |
||||
{ |
||||
namespace data |
||||
{ |
||||
|
||||
class Reseeder |
||||
{ |
||||
public: |
||||
Reseeder(); |
||||
~Reseeder(); |
||||
bool reseedNow(); |
||||
}; |
||||
|
||||
} |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,261 @@
@@ -0,0 +1,261 @@
|
||||
#include <string> |
||||
#include <algorithm> |
||||
#include <cctype> |
||||
#include <functional> |
||||
#include <fstream> |
||||
#include <set> |
||||
#include <boost/asio.hpp> |
||||
#include <boost/filesystem.hpp> |
||||
#include <boost/filesystem/fstream.hpp> |
||||
#include <boost/foreach.hpp> |
||||
#include <boost/program_options/detail/config_file.hpp> |
||||
#include <boost/program_options/parsers.hpp> |
||||
#include "util.h" |
||||
#include "Log.h" |
||||
|
||||
namespace i2p |
||||
{ |
||||
namespace util |
||||
{ |
||||
|
||||
namespace config |
||||
{ |
||||
std::map<std::string, std::string> mapArgs; |
||||
std::map<std::string, std::vector<std::string> > mapMultiArgs; |
||||
|
||||
void OptionParser(int argc, const char* const argv[]) |
||||
{ |
||||
mapArgs.clear(); |
||||
mapMultiArgs.clear(); |
||||
for (int i = 1; i < argc; i++) |
||||
{ |
||||
std::string strKey (argv[i]); |
||||
std::string strValue; |
||||
size_t has_data = strKey.find('='); |
||||
if (has_data != std::string::npos) |
||||
{ |
||||
strValue = strKey.substr(has_data+1); |
||||
strKey = strKey.substr(0, has_data); |
||||
} |
||||
|
||||
#ifdef WIN32 |
||||
boost::to_lower(strKey); |
||||
if (boost::algorithm::starts_with(strKey, "/")) |
||||
strKey = "-" + strKey.substr(1); |
||||
#endif |
||||
if (strKey[0] != '-') |
||||
break; |
||||
|
||||
mapArgs[strKey] = strValue; |
||||
mapMultiArgs[strKey].push_back(strValue); |
||||
} |
||||
|
||||
BOOST_FOREACH(PAIRTYPE(const std::string,std::string)& entry, mapArgs) |
||||
{ |
||||
std::string name = entry.first; |
||||
|
||||
// interpret --foo as -foo (as long as both are not set)
|
||||
if (name.find("--") == 0) |
||||
{ |
||||
std::string singleDash(name.begin()+1, name.end()); |
||||
if (mapArgs.count(singleDash) == 0) |
||||
mapArgs[singleDash] = entry.second; |
||||
name = singleDash; |
||||
} |
||||
} |
||||
} |
||||
|
||||
const char* GetCharArg(const std::string& strArg, const std::string& nDefault) |
||||
{ |
||||
if (mapArgs.count(strArg)) |
||||
return mapArgs[strArg].c_str(); |
||||
return nDefault.c_str(); |
||||
} |
||||
|
||||
std::string GetArg(const std::string& strArg, const std::string& strDefault) |
||||
{ |
||||
if (mapArgs.count(strArg)) |
||||
return mapArgs[strArg]; |
||||
return strDefault; |
||||
} |
||||
|
||||
int GetArg(const std::string& strArg, int nDefault) |
||||
{ |
||||
if (mapArgs.count(strArg)) |
||||
return atoi(mapArgs[strArg].c_str()); |
||||
return nDefault; |
||||
} |
||||
} |
||||
|
||||
namespace filesystem |
||||
{ |
||||
const boost::filesystem::path &GetDataDir() |
||||
{ |
||||
static boost::filesystem::path path; |
||||
|
||||
if (i2p::util::config::mapArgs.count("-datadir")) { |
||||
path = boost::filesystem::system_complete(i2p::util::config::mapArgs["-datadir"]); |
||||
} else { |
||||
path = GetDefaultDataDir(); |
||||
} |
||||
|
||||
if (!boost::filesystem::exists( path )) |
||||
{ |
||||
// Create data directory
|
||||
if (!boost::filesystem::create_directory( path )) |
||||
{ |
||||
LogPrint("Failed to create data directory!"); |
||||
path = ""; |
||||
return path; |
||||
} |
||||
} |
||||
if (!boost::filesystem::is_directory(path)) { |
||||
path = GetDefaultDataDir(); |
||||
} |
||||
return path; |
||||
} |
||||
|
||||
boost::filesystem::path GetConfigFile() |
||||
{ |
||||
boost::filesystem::path pathConfigFile(i2p::util::config::GetArg("-conf", "i2p.conf")); |
||||
if (!pathConfigFile.is_complete()) pathConfigFile = GetDataDir() / pathConfigFile; |
||||
return pathConfigFile; |
||||
} |
||||
|
||||
void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, |
||||
std::map<std::string, std::vector<std::string> >& mapMultiSettingsRet) |
||||
{ |
||||
boost::filesystem::ifstream streamConfig(GetConfigFile()); |
||||
if (!streamConfig.good()) |
||||
return; // No i2pd.conf file is OK
|
||||
|
||||
std::set<std::string> setOptions; |
||||
setOptions.insert("*"); |
||||
|
||||
for (boost::program_options::detail::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it) |
||||
{ |
||||
// Don't overwrite existing settings so command line settings override i2pd.conf
|
||||
std::string strKey = std::string("-") + it->string_key; |
||||
if (mapSettingsRet.count(strKey) == 0) |
||||
{ |
||||
mapSettingsRet[strKey] = it->value[0]; |
||||
} |
||||
mapMultiSettingsRet[strKey].push_back(it->value[0]); |
||||
} |
||||
} |
||||
|
||||
boost::filesystem::path GetDefaultDataDir() |
||||
{ |
||||
// Windows < Vista: C:\Documents and Settings\Username\Application Data\i2pd
|
||||
// Windows >= Vista: C:\Users\Username\AppData\Roaming\i2pd
|
||||
// Mac: ~/Library/Application Support/i2pd
|
||||
// Unix: ~/.i2pd
|
||||
#ifdef WIN32 |
||||
// Windows
|
||||
return GetSpecialFolderPath(CSIDL_APPDATA) / "i2pd"; |
||||
#else |
||||
boost::filesystem::path pathRet; |
||||
char* pszHome = getenv("HOME"); |
||||
if (pszHome == NULL || strlen(pszHome) == 0) |
||||
pathRet = boost::filesystem::path("/"); |
||||
else |
||||
pathRet = boost::filesystem::path(pszHome); |
||||
#ifdef MAC_OSX |
||||
// Mac
|
||||
pathRet /= "Library/Application Support"; |
||||
boost::filesystem::create_directory(pathRet); |
||||
return pathRet / "i2pd"; |
||||
#else |
||||
// Unix
|
||||
return pathRet / ".i2pd"; |
||||
#endif |
||||
#endif |
||||
} |
||||
} |
||||
|
||||
namespace http |
||||
{ |
||||
std::string httpRequest(const std::string& address) |
||||
{ |
||||
try |
||||
{ |
||||
i2p::util::http::url u(address); |
||||
boost::asio::ip::tcp::iostream site; |
||||
// please don't uncomment following line because it's not compatible with boost 1.46
|
||||
// 1.46 is default boost for Ubuntu 12.04 LTS
|
||||
//site.expires_from_now (boost::posix_time::seconds(30));
|
||||
site.connect(u.host_, "http"); |
||||
if (site) |
||||
{ |
||||
// 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
|
||||
} |
@ -0,0 +1,49 @@
@@ -0,0 +1,49 @@
|
||||
#ifndef UTIL_H |
||||
#define UTIL_H |
||||
|
||||
#include <map> |
||||
#include <string> |
||||
#include <boost/filesystem.hpp> |
||||
#include <boost/filesystem/fstream.hpp> |
||||
|
||||
#define PAIRTYPE(t1, t2) std::pair<t1, t2> |
||||
|
||||
namespace i2p |
||||
{ |
||||
namespace util |
||||
{ |
||||
namespace config |
||||
{ |
||||
extern std::map<std::string, std::string> mapArgs; |
||||
extern std::map<std::string, std::vector<std::string> > mapMultiArgs; |
||||
void OptionParser(int argc, const char* const argv[]); |
||||
int GetArg(const std::string& strArg, int nDefault); |
||||
std::string GetArg(const std::string& strArg, const std::string& strDefault); |
||||
const char* GetCharArg(const std::string& strArg, const std::string& nDefault); |
||||
} |
||||
|
||||
namespace filesystem |
||||
{ |
||||
const boost::filesystem::path &GetDataDir(); |
||||
boost::filesystem::path GetDefaultDataDir(); |
||||
boost::filesystem::path GetConfigFile(); |
||||
void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, |
||||
std::map<std::string, std::vector<std::string> >& mapMultiSettingsRet); |
||||
} |
||||
|
||||
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_; |
||||
}; |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
#endif |
Loading…
Reference in new issue