diff --git a/AddressBook.cpp b/AddressBook.cpp index 3b3f85b4..22008294 100644 --- a/AddressBook.cpp +++ b/AddressBook.cpp @@ -24,7 +24,7 @@ namespace client { private: i2p::fs::HashedStorage storage; - std::string indexPath; + std::string etagsPath, indexPath, localPath; public: AddressBookFilesystemStorage (): storage("addressbook", "b", "", "b32") {}; @@ -34,14 +34,34 @@ namespace client bool Init (); int Load (std::map& addresses); + int LoadLocal (std::map& addresses); int Save (const std::map& addresses); + + void SaveEtag (const i2p::data::IdentHash& subsciption, const std::string& etag, const std::string& lastModified); + bool GetEtag (const i2p::data::IdentHash& subscription, std::string& etag, std::string& lastModified); + + private: + + int LoadFromFile (const std::string& filename, std::map& addresses); // returns -1 if can't open file, otherwise number of records + }; bool AddressBookFilesystemStorage::Init() - { + { storage.SetPlace(i2p::fs::GetDataDir()); - indexPath = storage.GetRoot() + i2p::fs::dirSep + "addresses.csv"; - return storage.Init(i2p::data::GetBase32SubstitutionTable(), 32); + // init storage + if (storage.Init(i2p::data::GetBase32SubstitutionTable(), 32)) + { + // init ETags + etagsPath = i2p::fs::StorageRootPath (storage, "etags"); + if (!i2p::fs::Exists (etagsPath)) + i2p::fs::CreateDirectory (etagsPath); + // init address files + indexPath = i2p::fs::StorageRootPath (storage, "addresses.csv"); + localPath = i2p::fs::StorageRootPath (storage, "local.csv"); + return true; + } + return false; } std::shared_ptr AddressBookFilesystemStorage::GetAddress (const i2p::data::IdentHash& ident) const @@ -87,24 +107,18 @@ namespace client storage.Remove( ident.ToBase32() ); } - int AddressBookFilesystemStorage::Load (std::map& addresses) + int AddressBookFilesystemStorage::LoadFromFile (const std::string& filename, std::map& addresses) { int num = 0; - std::string s; - std::ifstream f (indexPath, std::ifstream::in); // in text mode - - if (f.is_open ()) { - LogPrint(eLogInfo, "Addressbook: using index file ", indexPath); - } else { - LogPrint(eLogWarning, "Addressbook: Can't open ", indexPath); - return 0; - } + std::ifstream f (filename, std::ifstream::in); // in text mode + if (!f) return -1; addresses.clear (); - while (!f.eof ()) { + while (!f.eof ()) + { + std::string s; getline(f, s); - if (!s.length()) - continue; // skip empty line + if (!s.length()) continue; // skip empty line std::size_t pos = s.find(','); if (pos != std::string::npos) @@ -118,8 +132,28 @@ namespace client num++; } } + return num; + } + int AddressBookFilesystemStorage::Load (std::map& addresses) + { + int num = LoadFromFile (indexPath, addresses); + if (num < 0) + { + LogPrint(eLogWarning, "Addressbook: Can't open ", indexPath); + return 0; + } + LogPrint(eLogInfo, "Addressbook: using index file ", indexPath); LogPrint (eLogInfo, "Addressbook: ", num, " addresses loaded from storage"); + + return num; + } + + int AddressBookFilesystemStorage::LoadLocal (std::map& addresses) + { + int num = LoadFromFile (localPath, addresses); + if (num < 0) return 0; + LogPrint (eLogInfo, "Addressbook: ", num, " local addresses loaded"); return num; } @@ -146,6 +180,28 @@ namespace client return num; } + void AddressBookFilesystemStorage::SaveEtag (const i2p::data::IdentHash& subscription, const std::string& etag, const std::string& lastModified) + { + std::string fname = etagsPath + i2p::fs::dirSep + subscription.ToBase32 () + ".txt"; + std::ofstream f (fname, std::ofstream::out | std::ofstream::trunc); + if (f) + { + f << etag << std::endl; + f<< lastModified << std::endl; + } + } + + bool AddressBookFilesystemStorage::GetEtag (const i2p::data::IdentHash& subscription, std::string& etag, std::string& lastModified) + { + std::string fname = etagsPath + i2p::fs::dirSep + subscription.ToBase32 () + ".txt"; + std::ifstream f (fname, std::ofstream::in); + if (!f || f.eof ()) return false; + std::getline (f, etag); + if (f.eof ()) return false; + std::getline (f, lastModified); + return true; + } + //--------------------------------------------------------------------- AddressBook::AddressBook (): m_Storage(new AddressBookFilesystemStorage), m_IsLoaded (false), m_IsDownloading (false), m_DefaultSubscription (nullptr), m_SubscriptionsUpdateTimer (nullptr) @@ -274,6 +330,8 @@ namespace client LoadHostsFromStream (f); m_IsLoaded = true; } + // load local + m_Storage->LoadLocal (m_Addresses); } void AddressBook::LoadHostsFromStream (std::istream& f) @@ -337,7 +395,15 @@ namespace client LogPrint (eLogError, "Addressbook: subscriptions already loaded"); } - void AddressBook::DownloadComplete (bool success) + bool AddressBook::GetEtag (const i2p::data::IdentHash& subscription, std::string& etag, std::string& lastModified) + { + if (m_Storage) + return m_Storage->GetEtag (subscription, etag, lastModified); + else + return false; + } + + void AddressBook::DownloadComplete (bool success, const i2p::data::IdentHash& subscription, const std::string& etag, const std::string& lastModified) { m_IsDownloading = false; int nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT; @@ -348,6 +414,7 @@ namespace client nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT; else m_IsLoaded = true; + if (m_Storage) m_Storage->SaveEtag (subscription, etag, lastModified); } if (m_SubscriptionsUpdateTimer) { @@ -438,6 +505,12 @@ namespace client i2p::data::IdentHash ident; if (m_Book.GetIdentHash (u.host_, ident)) { + if (!m_Etag.length ()) + { + // load ETag + m_Book.GetEtag (ident, m_Etag, m_LastModified); + LogPrint (eLogInfo, "Addressbook: set ", m_Link, " ETag: ", m_Etag, " Last-Modified: ", m_LastModified); + } std::condition_variable newDataReceived; std::mutex newDataReceivedMutex; auto leaseSet = i2p::client::context.GetSharedLocalDestination ()->FindLeaseSet (ident); @@ -468,7 +541,7 @@ namespace client << "X-Accept-Encoding: x-i2p-gzip;q=1.0, identity;q=0.5, deflate;q=0, gzip;q=0, *;q=0\r\n" << "Connection: close\r\n"; if (m_Etag.length () > 0) // etag - request << i2p::util::http::IF_NONE_MATCH << ": \"" << m_Etag << "\"\r\n"; + request << i2p::util::http::IF_NONE_MATCH << ": " << m_Etag << "\r\n"; if (m_LastModified.length () > 0) // if-modfief-since request << i2p::util::http::IF_MODIFIED_SINCE << ": " << m_LastModified << "\r\n"; request << "\r\n"; // end of header @@ -529,7 +602,7 @@ namespace client !header.compare (colon + 1, std::string::npos, "x-i2p-gzip"); } } - LogPrint (eLogInfo, "Addressbook: ", m_Link, " ETag: ", m_Etag, " Last-Modified: ", m_LastModified); + LogPrint (eLogInfo, "Addressbook: received ", m_Link, " ETag: ", m_Etag, " Last-Modified: ", m_LastModified); if (!response.eof ()) { success = true; @@ -561,7 +634,7 @@ namespace client if (!success) LogPrint (eLogError, "Addressbook: download hosts.txt from ", m_Link, " failed"); - m_Book.DownloadComplete (success); + m_Book.DownloadComplete (success, ident, m_Etag, m_LastModified); } bool AddressBookSubscription::ProcessResponse (std::stringstream& s, bool isGzip) diff --git a/AddressBook.h b/AddressBook.h index 46df12d0..98422fe1 100644 --- a/AddressBook.h +++ b/AddressBook.h @@ -37,7 +37,11 @@ namespace client virtual bool Init () = 0; virtual int Load (std::map& addresses) = 0; + virtual int LoadLocal (std::map& addresses) = 0; virtual int Save (const std::map& addresses) = 0; + + virtual void SaveEtag (const i2p::data::IdentHash& subscription, const std::string& etag, const std::string& lastModified) = 0; + virtual bool GetEtag (const i2p::data::IdentHash& subscription, std::string& etag, std::string& lastModified) = 0; }; class AddressBookSubscription; @@ -56,10 +60,13 @@ namespace client void InsertAddress (std::shared_ptr address); void LoadHostsFromStream (std::istream& f); - void DownloadComplete (bool success); + void DownloadComplete (bool success, const i2p::data::IdentHash& subscription, const std::string& etag, const std::string& lastModified); //This method returns the ".b32.i2p" address std::string ToAddress(const i2p::data::IdentHash& ident) { return GetB32Address(ident); } std::string ToAddress(std::shared_ptr ident) { return ToAddress(ident->GetIdentHash ()); } + + bool GetEtag (const i2p::data::IdentHash& subscription, std::string& etag, std::string& lastModified); + private: void StartSubscriptions (); @@ -73,7 +80,7 @@ namespace client private: std::mutex m_AddressBookMutex; - std::map m_Addresses; + std::map m_Addresses, m_LocalAddresses; AddressBookStorage * m_Storage; volatile bool m_IsLoaded, m_IsDownloading; std::vector m_Subscriptions; @@ -97,6 +104,7 @@ namespace client AddressBook& m_Book; std::string m_Link, m_Etag, m_LastModified; + // m_Etag must be surrounded by "" }; } } diff --git a/Base.cpp b/Base.cpp index e894b694..e0b6af07 100644 --- a/Base.cpp +++ b/Base.cpp @@ -8,8 +8,8 @@ namespace data { static const char T32[32] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', - 'i', 'k', 'k', 'l', 'm', 'n', 'o', 'p', - 'q', 'r', 't', 't', 'u', 'v', 'w', 'x', + 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '2', '3', '4', '5', '6', '7', }; diff --git a/Config.cpp b/Config.cpp index 15c8ad67..caec7e20 100644 --- a/Config.cpp +++ b/Config.cpp @@ -126,6 +126,7 @@ namespace config { #ifdef _WIN32 ("svcctl", value()->default_value(""), "Windows service management ('install' or 'remove')") ("insomnia", value()->zero_tokens()->default_value(false), "Prevent system from sleeping") + ("close", value()->default_value("ask"), "On close action") // minimize, exit, ask TODO: add custom validator or something #endif ; diff --git a/FS.cpp b/FS.cpp index 19963195..380ab2e5 100644 --- a/FS.cpp +++ b/FS.cpp @@ -102,6 +102,13 @@ namespace fs { return boost::filesystem::remove(path); } + bool CreateDirectory (const std::string& path) + { + if (boost::filesystem::exists(path) && + boost::filesystem::is_directory (boost::filesystem::status (path))) return true; + return boost::filesystem::create_directory(path); + } + void HashedStorage::SetPlace(const std::string &path) { root = path + i2p::fs::dirSep + name; } diff --git a/FS.h b/FS.h index 833258b9..0437ccf9 100644 --- a/FS.h +++ b/FS.h @@ -48,8 +48,8 @@ namespace fs { /** create subdirs in storage */ bool Init(const char* chars, size_t cnt); - const std::string & GetRoot() const { return this->root; } - const std::string & GetName() const { return this->name; } + const std::string & GetRoot() const { return root; } + const std::string & GetName() const { return name; } /** set directory where to place storage directory */ void SetPlace(const std::string & path); /** path to file with given ident */ @@ -108,6 +108,8 @@ namespace fs { * @return true if file exists, false otherwise */ bool Exists(const std::string & path); + + bool CreateDirectory (const std::string& path); template void _ExpandPath(std::stringstream & path, T c) { @@ -136,6 +138,17 @@ namespace fs { return s.str(); } + + template + std::string StorageRootPath (const Storage& storage, Filename... filenames) + { + std::stringstream s(""); + s << storage.GetRoot (); + _ExpandPath(s, filenames...); + + return s.str(); + } + } // fs } // i2p diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp index 160c27f6..6e835d21 100644 --- a/HTTPProxy.cpp +++ b/HTTPProxy.cpp @@ -204,7 +204,7 @@ namespace proxy if (eol) { *eol = 0; eol++; - if (strncmp ((const char *)http_buff, "Referer", 7)) // strip out referer + if (strncmp ((const char *)http_buff, "Referer", 7) && strncmp ((const char *)http_buff, "Connection", 10)) // strip out referer and connection { if (!strncmp ((const char *)http_buff, "User-Agent", 10)) // replace UserAgent m_request.append("User-Agent: MYOB/6.66 (AN/ON)"); diff --git a/NTCPSession.cpp b/NTCPSession.cpp index 2584f584..b0ea2e74 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -93,9 +93,7 @@ namespace transport m_DHKeysPair = nullptr; - SendTimeSyncMessage (); - m_SendQueue.push_back (CreateDatabaseStoreMsg ()); // we tell immediately who we are - + SendTimeSyncMessage (); transports.PeerConnected (shared_from_this ()); } diff --git a/Reseed.cpp b/Reseed.cpp index 380babb5..caac8071 100644 --- a/Reseed.cpp +++ b/Reseed.cpp @@ -26,13 +26,12 @@ namespace data static std::vector httpsReseedHostList = { "https://reseed.i2p-projekt.de/", // Only HTTPS - //"https://i2pseed.zarrenspry.info/", // Only HTTPS and SU3 (v3) support "https://i2p.mooo.com/netDb/", "https://netdb.i2p2.no/", // Only SU3 (v3) support, SNI required "https://us.reseed.i2p2.no:444/", "https://uk.reseed.i2p2.no:444/", - "https://www.torontocrypto.org:8443/", - "https://i2p-0.manas.ca:8443/" + "https://i2p.manas.ca:8443/", + "https://i2p-0.manas.ca:8443/", "https://reseed.i2p.vzaws.com:8443/", // Only SU3 (v3) support "https://user.mx24.eu/", // Only HTTPS and SU3 (v3) support "https://download.xxlspeed.com/" // Only HTTPS and SU3 (v3) support diff --git a/SSUSession.cpp b/SSUSession.cpp index 1fa29475..aa534c56 100644 --- a/SSUSession.cpp +++ b/SSUSession.cpp @@ -855,7 +855,6 @@ namespace transport m_DHKeysPair = nullptr; m_SignedData = nullptr; m_Data.Start (); - m_Data.Send (CreateDatabaseStoreMsg ()); transports.PeerConnected (shared_from_this ()); if (m_IsPeerTest) SendPeerTest (); diff --git a/Transports.cpp b/Transports.cpp index 5fcce0fc..9b327133 100644 --- a/Transports.cpp +++ b/Transports.cpp @@ -505,12 +505,24 @@ namespace transport auto it = m_Peers.find (ident); if (it != m_Peers.end ()) { + bool sendDatabaseStore = true; + if (it->second.delayedMessages.size () > 0) + { + // check if first message is our DatabaseStore (publishing) + auto firstMsg = it->second.delayedMessages[0]; + if (firstMsg && firstMsg->GetTypeID () == eI2NPDatabaseStore && + i2p::data::IdentHash(firstMsg->GetPayload () + DATABASE_STORE_KEY_OFFSET) == i2p::context.GetIdentHash ()) + sendDatabaseStore = false; // we have it in the list already + } + if (sendDatabaseStore) + session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); it->second.sessions.push_back (session); session->SendI2NPMessages (it->second.delayedMessages); it->second.delayedMessages.clear (); } else // incoming connection { + session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); // send DatabaseStore std::unique_lock l(m_PeersMutex); m_Peers.insert (std::make_pair (ident, Peer{ 0, nullptr, { session }, i2p::util::GetSecondsSinceEpoch (), {} })); } diff --git a/Win32/Anke_2200px.jpg b/Win32/Anke_2200px.jpg new file mode 100644 index 00000000..1c5b0f31 Binary files /dev/null and b/Win32/Anke_2200px.jpg differ diff --git a/Win32/Anke_700px.bmp b/Win32/Anke_700px.bmp new file mode 100644 index 00000000..f63cccbb Binary files /dev/null and b/Win32/Anke_700px.bmp differ diff --git a/Win32/Resource.rc b/Win32/Resource.rc index e10ec496..bdc532e9 100644 --- a/Win32/Resource.rc +++ b/Win32/Resource.rc @@ -52,7 +52,11 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -MAINICON ICON "ictoopie.ico" +//MAINICON ICON "ictoopie.ico" +MAINICON ICON "anke.ico" + +MASCOT BITMAP "Anke_700px.bmp" + #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index cd9a8f34..f2915498 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -4,6 +4,11 @@ #include "../Config.h" #include "resource.h" #include "Win32App.h" +#include + +#if defined(_MSC_VER) && _MSC_VER < 1900 +#define snprintf _snprintf +#endif #define ID_ABOUT 2000 #define ID_EXIT 2001 @@ -98,7 +103,7 @@ namespace win32 char buf[30]; std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); - std::snprintf(buf, 30, "http://%s:%d", httpAddr.c_str(), httpPort); + snprintf(buf, 30, "http://%s:%d", httpAddr.c_str(), httpPort); ShellExecute(NULL, "open", buf, NULL, NULL, SW_SHOWNORMAL); return 0; } @@ -119,6 +124,29 @@ namespace win32 ShowWindow(hWnd, SW_HIDE); return 0; } + case SC_CLOSE: + { + std::string close; i2p::config::GetOption("close", close); + if (0 == close.compare("ask")) + switch(::MessageBox(hWnd, "Would you like to minimize instead of exiting?" + " You can add 'close' configuration option. Valid values are: ask, minimize, exit.", + "Minimize instead of exiting?", MB_ICONQUESTION | MB_YESNOCANCEL | MB_DEFBUTTON1)) + { + case IDYES: close = "minimize"; break; + case IDNO: close = "exit"; break; + default: return 0; + } + if (0 == close.compare("minimize")) + { + ShowWindow(hWnd, SW_HIDE); + return 0; + } + if (0 != close.compare("exit")) + { + ::MessageBox(hWnd, close.c_str(), "Unknown close action in config", MB_OK | MB_ICONWARNING); + return 0; + } + } } } case WM_TRAYICON: @@ -136,6 +164,19 @@ namespace win32 } break; } + case WM_PAINT: + { + PAINTSTRUCT ps; + auto hDC = BeginPaint (hWnd, &ps); + auto mascot = LoadBitmap (GetModuleHandle(NULL), MAKEINTRESOURCE (MASCOT)); + auto mascotDC = CreateCompatibleDC (hDC); + SelectObject (mascotDC, mascot); + BitBlt (hDC, 0,0, 533, 700, mascotDC, 0, 0, SRCCOPY); + DeleteDC (mascotDC); + DeleteObject (mascot); + EndPaint (hWnd, &ps); + break; + } } return DefWindowProc( hWnd, uMsg, wParam, lParam); } @@ -164,7 +205,7 @@ namespace win32 wclx.lpszClassName = I2PD_WIN32_CLASSNAME; RegisterClassEx (&wclx); // create new window - if (!CreateWindow(I2PD_WIN32_CLASSNAME, TEXT("i2pd"), WS_OVERLAPPEDWINDOW, 100, 100, 250, 150, NULL, NULL, hInst, NULL)) + if (!CreateWindow(I2PD_WIN32_CLASSNAME, TEXT("i2pd"), WS_OVERLAPPEDWINDOW, 100, 100, 533, 700, NULL, NULL, hInst, NULL)) { MessageBox(NULL, "Failed to create main window", TEXT("Warning!"), MB_ICONERROR | MB_OK | MB_TOPMOST); return false; diff --git a/Win32/anke.ico b/Win32/anke.ico new file mode 100644 index 00000000..509177bb Binary files /dev/null and b/Win32/anke.ico differ diff --git a/Win32/resource.h b/Win32/resource.h index a8309c8b..f37fce46 100644 --- a/Win32/resource.h +++ b/Win32/resource.h @@ -3,6 +3,7 @@ // Used by Resource.rc // #define MAINICON 101 +#define MASCOT 201 // Next default values for new objects // diff --git a/docs/build_notes_cross.md b/docs/build_notes_cross.md new file mode 100644 index 00000000..d819ba34 --- /dev/null +++ b/docs/build_notes_cross.md @@ -0,0 +1,75 @@ +Cross compilation notes +======================= + +Static 64 bit windows binary on Ubuntu 15.10 (Wily Werewolf) +--------------------------------------------------------------------- + +Install cross compiler and friends +```sh +sudo apt-get install g++-mingw-w64-x86-64 +``` +Default is to use Win32 threading model which lacks std::mutex and such. So we change defaults +```sh +sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix +``` +From now on we assume we have everything in `~/dev/`. Get Boost sources unpacked into `~/dev/boost_1_60_0/` +and change directory to it. +Now add out cross compiler configuration. Warning: the following will wipe out whatever you had in there. +```sh +echo "using gcc : mingw : x86_64-w64-mingw32-g++ ;" > ~/user-config.jam +``` +Proceed with building Boost normal way, but let's define dedicated staging directory +```sh +./bootstrap.sh +./b2 toolset=gcc-mingw target-os=windows variant=release link=static runtime-link=static address-model=64 \ + --build-type=minimal --with-filesystem --with-program_options --with-regex --with-date_time \ + --stagedir=stage-mingw-64 +cd .. +``` +Now we get & build OpenSSL +```sh +git clone https://github.com/openssl/openssl +cd openssl +git checkout OpenSSL_1_0_2g +./Configure mingw64 no-rc2 no-rc4 no-rc5 no-idea no-bf no-cast no-whirlpool no-md2 no-md4 no-ripemd no-mdc2 \ + no-camellia no-seed no-comp no-krb5 no-gmp no-rfc3779 no-ec2m no-ssl2 no-jpake no-srp no-sctp no-srtp \ + --prefix=~/dev/stage --cross-compile-prefix=x86_64-w64-mingw32- +make depend +make +make install +cd .. +``` +and Zlib +```sh +git clone https://github.com/madler/zlib +cd zlib +git checkout v1.2.8 +CC=x86_64-w64-mingw32-gcc CFLAGS=-O3 ./configure --static --64 --prefix=~/dev/stage +make +make install +cd .. +``` +Now we prepare cross toolchain hint file for CMake, let's name it `~/dev/toolchain-mingw.cmake` +```cmake +SET(CMAKE_SYSTEM_NAME Windows) +SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) +SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) +SET(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) +SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +``` +Download miniupnpc, unpack, and symlink it into `~/dev/miniupnpc/`. +Finally, we can build i2pd with all that goodness +```sh +git clone https://github.com/PurpleI2P/i2pd +mkdir i2pd-mingw-64-build +cd i2pd-mingw-64-build +BOOST_ROOT=~/dev/boost_1_60_0 cmake -G 'Unix Makefiles' ~/dev/i2pd/build -DBUILD_TYPE=Release \ + -DCMAKE_TOOLCHAIN_FILE=~/dev/toolchain-mingw.cmake -DWITH_AESNI=ON -DWITH_UPNP=ON -DWITH_STATIC=ON \ + -DWITH_HARDENING=ON -DCMAKE_INSTALL_PREFIX:PATH=~/dev/i2pd-mingw-64-static \ + -DZLIB_ROOT=~/dev/stage -DBOOST_LIBRARYDIR:PATH=~/dev/boost_1_60_0/stage-mingw-64/lib \ + -DOPENSSL_ROOT_DIR:PATH=~/dev/stage +make +x86_64-w64-mingw32-strip i2pd.exe +``` +By now, you should have a release build with stripped symbols. diff --git a/docs/configuration.md b/docs/configuration.md index 79f95f10..46e5092c 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -17,9 +17,9 @@ Command line options * --port= - The port to listen on * --daemon - Router will go to background after start * --service - Router will use system folders like '/var/lib/i2pd' -* --ipv6 - Enable communication through ipv6 -* --notransit - Router will not accept transit tunnels at startup -* --floodfill - Router will be floodfill +* --ipv6 - Enable communication through ipv6. false by default +* --notransit - Router will not accept transit tunnels at startup. false by default +* --floodfill - Router will be floodfill. false by default * --bandwidth= - L if bandwidth is limited to 32Kbs/sec, O - to 256Kbs/sec, P - unlimited * --family= - Name of a family, router belongs to * --svcctl= - Windows service management (--svcctl="install" or --svcctl="remove") @@ -30,21 +30,26 @@ Command line options * --httpproxy.address= - The address to listen on (HTTP Proxy) * --httpproxy.port= - The port to listen on (HTTP Proxy) 4446 by default * --httpproxy.keys= - optional keys file for proxy local destination (both HTTP and SOCKS) +* --httpproxy.enabled= - If HTTP proxy is enabled. true by default * --socksproxy.address= - The address to listen on (SOCKS Proxy) * --socksproxy.port= - The port to listen on (SOCKS Proxy). 4447 by default * --socksproxy.keys= - optional keys file for proxy local destination (both HTTP and SOCKS) -* --socksproxy.outproxy= - Address of outproxy. requests outside i2p will go there +* --socksproxy.enabled= - If SOCKS proxy is enabled. true by default +* --socksproxy.outproxy= - Address of outproxy. requests outside i2p will go there * --socksproxy.outproxyport= - Outproxy remote port * --sam.address= - The address to listen on (SAM bridge) * --sam.port= - Port of SAM bridge. Usually 7656. SAM is off if not specified +* --sam.enabled= - If SAM is enabled. false by default * --bob.address= - The address to listen on (BOB command channel) * --bob.port= - Port of BOB command channel. Usually 2827. BOB is off if not specified +* --sam.enabled= - If BOB is enabled. false by default * --i2pcontrol.address= - The address to listen on (I2P control service) * --i2pcontrol.port= - Port of I2P control service. Usually 7650. I2PControl is off if not specified +* --i2pcontrol.enabled= - If I2P control is enabled. false by default Config files ------------ @@ -58,15 +63,15 @@ For example: i2p.conf: # comment - log = yes - ipv6 = yes + log = true + ipv6 = true # settings for specific module [httpproxy] port = 4444 # ^^ this will be --httproxy.port= in cmdline # another one [sam] - enabled = yes + enabled = true tunnels.cfg (filename of this config is subject of change): diff --git a/docs/i2pd.conf b/docs/i2pd.conf new file mode 100644 index 00000000..32c524ca --- /dev/null +++ b/docs/i2pd.conf @@ -0,0 +1,111 @@ +## Configuration file for a typical i2pd user +## See https://i2pd.readthedocs.org/en/latest/configuration.html +## for more options you can use in this file. + +## Lines that begin with "## " try to explain what's going on. Lines +## that begin with just "#" are disabled commands: you can enable them +## by removing the "#" symbol. + +## Tunnels config file +## Default: ~/.i2pd/tunnels.cfg or /var/lib/i2pd/tunnels.cfg +#tunconf = /var/lib/i2pd/tunnels.cfg + +## Where to write pidfile (don't write by default) +#pidfile = /var/run/i2pd.pid + +## Logging configuration section +## By default logs go to stdout with level info +## +## Logs destination (stdout, file) +#log = file +## Path to logfile (default - autodetect) +#logfile = /var/log/i2pd.log +## Log messages above this level (debug, *info, warn, error) +#loglevel = info + +## Path to storage of i2pd data (RI, keys, peer profiles, ...) +## Default: ~/.i2pd or /var/lib/i2pd +#datadir = /var/lib/i2pd + +## Daemon mode. Router will go to background after start +#daemon +## Run as a service. Router will use system folders like ‘/var/lib/i2pd’ +#service + +## External IP address to listen for connections +## By default i2pd sets IP automatically +#host = 1.2.3.4 +## Port to listen for connections +## By default i2pd picks random port. You MUST pick a random number too, +## don't just uncomment this +#port = 4321 +##Enable communication through ipv6 +ipv6 +## Bandwidth configuration +## L limit bandwidth to 32Kbs/sec, O - to 256Kbs/sec, P - unlimited +## Default is P for floodfill, L for regular node +#bandwidth = L + +## Router will not accept transit tunnels at startup +#notransit + +## Router will be floodfill +#floodfill + +## Section for Web Console +## By default it's available at 127.0.0.1:7070 even if it's not configured +[http] +## The address to listen on +address = 127.0.0.1 +## The port to listen on +port = 7070 + +## Section for HTTP proxy +## By default it's available at 127.0.0.1:4444 even if it's not configured +[httpproxy] +## The address to listen on +address = 127.0.0.1 +## The port to listen on +port = 4444 +## Optional keys file for proxy local destination +#keys = http-proxy-keys.dat +## Uncomment if you want to disable HTTP proxy +#enabled=false + +## Section for Socks proxy +## By default it's available at 127.0.0.1:4447 even if it's not configured +#[socksproxy] +## The address to listen on +#address = 127.0.0.1 +## The port to listen on +#port = 4447 +## Optional keys file for proxy local destination +#keys = socks-proxy-keys.dat +## Uncomment if you want to disable Socks proxy +#enabled=false +## Socks outproxy. Example below is set to use Tor for all connections except i2p +## Address of outproxy +#outproxy = 127.0.0.1 +## Outproxy remote port +#outproxyport = 9050 + +## Section for SAM bridge +#[sam] +## The address to listen on +#address = 127.0.0.1 +## Port of SAM bridge +#port = 7656 + +## Section for BOB command channel +#[bob] +## The address to listen on +#address = 127.0.0.1 +## Port of BOB command channel. Usually 2827. BOB is off if not specified +#port = 2827 + +## Section for I2PControl protocol +#[i2pcontrol] +## The address to listen on +#address = 127.0.0.1 +## Port of I2P control service +#port = 7650