diff --git a/Crypto.cpp b/Crypto.cpp index 885c65f4..94d1c4c6 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -135,11 +135,8 @@ namespace crypto DSA * CreateDSA () { DSA * dsa = DSA_new (); - dsa->p = BN_dup (dsap); - dsa->q = BN_dup (dsaq); - dsa->g = BN_dup (dsag); - dsa->priv_key = NULL; - dsa->pub_key = NULL; + DSA_set0_pqg (dsa, BN_dup (dsap), BN_dup (dsaq), BN_dup (dsag)); + DSA_set0_key (dsa, NULL, NULL); return dsa; } diff --git a/Crypto.h b/Crypto.h index a66f51b7..4408a193 100644 --- a/Crypto.h +++ b/Crypto.h @@ -279,6 +279,16 @@ namespace crypto void InitCrypto (bool precomputation); void TerminateCrypto (); + +// take care about openssl version +#include +#if (OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER) // 1.1.0 or LibreSSL +// define getters and setters introduced in 1.1.0 +inline int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) { d->p = p; d->q = q; d->g = g; return 1; } +inline int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) { d->pub_key = pub_key; d->priv_key = priv_key; return 1; } + +#endif + } } diff --git a/DaemonLinux.cpp b/DaemonLinux.cpp index 22d7dec8..87e50a72 100644 --- a/DaemonLinux.cpp +++ b/DaemonLinux.cpp @@ -75,10 +75,12 @@ namespace i2p return false; } +#if !defined(__OpenBSD__) // point std{in,out,err} descriptors to /dev/null stdin = freopen("/dev/null", "r", stdin); stdout = freopen("/dev/null", "w", stdout); stderr = freopen("/dev/null", "w", stderr); +#endif } // Pidfile diff --git a/Destination.cpp b/Destination.cpp index d400259c..d020d96e 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -373,26 +373,24 @@ namespace client for (int i = 0; i < num; i++) { i2p::data::IdentHash peerHash (buf + 33 + i*32); - auto floodfill = i2p::data::netdb.FindRouter (peerHash); - if (floodfill) + if (!request->excluded.count (peerHash) && !i2p::data::netdb.FindRouter (peerHash)) { - LogPrint (eLogInfo, "Destination: Requesting ", key.ToBase64 (), " at ", peerHash.ToBase64 ()); - if (SendLeaseSetRequest (key, floodfill, request)) - found = true; - } - else - { LogPrint (eLogInfo, "Destination: Found new floodfill, request it"); // TODO: recheck this message i2p::data::netdb.RequestDestination (peerHash); } } - if (!found) - LogPrint (eLogError, "Destination: Suggested floodfills are not presented in netDb"); + + auto floodfill = i2p::data::netdb.GetClosestFloodfill (key, request->excluded); + if (floodfill) + { + LogPrint (eLogInfo, "Destination: Requesting ", key.ToBase64 (), " at ", floodfill->GetIdentHash ().ToBase64 ()); + if (SendLeaseSetRequest (key, floodfill, request)) + found = true; + } } - else - LogPrint (eLogInfo, "Destination: ", key.ToBase64 (), " was not found on ", MAX_NUM_FLOODFILLS_PER_REQUEST, " floodfills"); if (!found) - { + { + LogPrint (eLogInfo, "Destination: ", key.ToBase64 (), " was not found on ", MAX_NUM_FLOODFILLS_PER_REQUEST, " floodfills"); if (request->requestComplete) request->requestComplete (nullptr); m_LeaseSetRequests.erase (key); } @@ -718,6 +716,7 @@ namespace client return false; } +#ifdef I2LUA void ClientDestination::Ready(ReadyPromise & p) { ScheduleCheckForReady(&p); @@ -741,6 +740,7 @@ namespace client else // we are not ready ScheduleCheckForReady(p); } +#endif void ClientDestination::HandleDataMessage (const uint8_t * buf, size_t len) { diff --git a/Destination.h b/Destination.h index 22ffa603..e2d532e8 100644 --- a/Destination.h +++ b/Destination.h @@ -8,7 +8,9 @@ #include #include #include +#ifdef I2LUA #include +#endif #include #include "Identity.h" #include "TunnelPool.h" @@ -145,18 +147,19 @@ namespace client class ClientDestination: public LeaseSetDestination { public: +#ifdef I2LUA // type for informing that a client destination is ready typedef std::promise > ReadyPromise; + // informs promise with shared_from_this() when this destination is ready to use + // if cancelled before ready, informs promise with nullptr + void Ready(ReadyPromise & p); +#endif ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params = nullptr); ~ClientDestination (); bool Start (); bool Stop (); - - // informs promise with shared_from_this() when this destination is ready to use - // if cancelled before ready, informs promise with nullptr - void Ready(ReadyPromise & p); const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; }; void Sign (const uint8_t * buf, int len, uint8_t * signature) const { m_Keys.Sign (buf, len, signature); }; @@ -191,10 +194,10 @@ namespace client std::shared_ptr GetSharedFromThis () { return std::static_pointer_cast(shared_from_this ()); } void PersistTemporaryKeys (); - +#ifdef I2LUA void ScheduleCheckForReady(ReadyPromise * p); void HandleCheckForReady(const boost::system::error_code & ecode, ReadyPromise * p); - +#endif private: i2p::data::PrivateKeys m_Keys; diff --git a/FS.cpp b/FS.cpp index a809e8c4..84b30f21 100644 --- a/FS.cpp +++ b/FS.cpp @@ -45,9 +45,19 @@ namespace fs { return; } #if defined(WIN32) || defined(_WIN32) - char localAppData[MAX_PATH]; - SHGetFolderPath(NULL, CSIDL_APPDATA, 0, NULL, localAppData); - dataDir = std::string(localAppData) + "\\" + appName; + char localAppData[MAX_PATH]; + // check executable directory first + GetModuleFileName (NULL, localAppData, MAX_PATH); + auto execPath = boost::filesystem::path(localAppData).parent_path(); + // if config file exists in .exe's folder use it + if(boost::filesystem::exists(execPath/"i2pd.conf")) // TODO: magic string + dataDir = execPath.string (); + else + { + // otherwise %appdata% + SHGetFolderPath(NULL, CSIDL_APPDATA, 0, NULL, localAppData); + dataDir = std::string(localAppData) + "\\" + appName; + } return; #elif defined(MAC_OSX) char *home = getenv("HOME"); @@ -57,12 +67,12 @@ namespace fs { #else /* other unix */ #if defined(ANDROID) if (boost::filesystem::exists("/sdcard")) - { - dataDir = "/sdcard/" + appName; + { + dataDir = "/sdcard/" + appName; return; - } - // otherwise use /data/files -#endif + } + // otherwise use /data/files +#endif char *home = getenv("HOME"); if (isService) { dataDir = "/var/lib/" + appName; @@ -112,10 +122,10 @@ namespace fs { bool CreateDirectory (const std::string& path) { - if (boost::filesystem::exists(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; @@ -125,7 +135,7 @@ namespace fs { if (!boost::filesystem::exists(root)) { boost::filesystem::create_directories(root); } - + for (size_t i = 0; i < count; i++) { auto p = root + i2p::fs::dirSep + prefix1 + chars[i]; if (boost::filesystem::exists(p)) diff --git a/I2PTunnel.cpp b/I2PTunnel.cpp index be48b83a..0ce9a7e3 100644 --- a/I2PTunnel.cpp +++ b/I2PTunnel.cpp @@ -175,7 +175,9 @@ namespace client Write (m_StreamBuffer, bytes_transferred); // postpone termination else Terminate (); - } + } + else + Terminate (); } else Write (m_StreamBuffer, bytes_transferred); diff --git a/Identity.cpp b/Identity.cpp index 99da059e..30051914 100644 --- a/Identity.cpp +++ b/Identity.cpp @@ -309,6 +309,7 @@ namespace data void IdentityEx::CreateVerifier () const { + if (m_Verifier) return; // don't create again auto keyType = GetSigningKeyType (); switch (keyType) { @@ -476,6 +477,7 @@ namespace data void PrivateKeys::CreateSigner () const { + if (m_Signer) return; switch (m_Public->GetSigningKeyType ()) { case SIGNING_KEY_TYPE_DSA_SHA1: diff --git a/Makefile b/Makefile index 147bedd4..5cb32004 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ ifeq ($(UNAME),Darwin) else include Makefile.osx endif -else ifeq ($(shell echo $(UNAME) | $(GREP) -c FreeBSD),1) +else ifeq ($(shell echo $(UNAME) | $(GREP) -Ec '(Free|Open)BSD'),1) DAEMON_SRC += DaemonLinux.cpp include Makefile.bsd else ifeq ($(UNAME),Linux) diff --git a/NetDb.h b/NetDb.h index d8ee148a..d295ebbe 100644 --- a/NetDb.h +++ b/NetDb.h @@ -8,7 +8,6 @@ #include #include #include -#include #include "Base.h" #include "Gzip.h" diff --git a/README.md b/README.md index 1fbf6c43..77527562 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ i2pd ==== +[Русская версия](https://github.com/PurpleI2P/i2pd_docs_ru/blob/master/README.md) + i2pd (I2P Daemon) is a full-featured C++ implementation of I2P client. I2P (Invisible Internet Protocol) is a universal anonymous network layer. @@ -37,11 +39,12 @@ i2pd from source on your OS. * Mac OS X * FreeBSD * Android +* iOS Using i2pd ---------- -See [documentation](https://i2pd.readthedocs.io/en/latest/) and +See [documentation](https://i2pd.readthedocs.io/en/latest/usage.html) and [example config file](https://github.com/PurpleI2P/i2pd/blob/openssl/docs/i2pd.conf). Donations diff --git a/Win32/installer.iss b/Win32/installer.iss new file mode 100644 index 00000000..7bfe63d9 --- /dev/null +++ b/Win32/installer.iss @@ -0,0 +1,32 @@ +#define I2Pd_AppName "i2pd" +#define I2Pd_ver "2.10.0" + +[Setup] +AppName={#I2Pd_AppName} +AppVersion={#I2Pd_ver} +DefaultDirName={pf}\I2Pd +DefaultGroupName=I2Pd +UninstallDisplayIcon={app}\I2Pd.exe +OutputDir=. +LicenseFile=../LICENSE +OutputBaseFilename=setup_{#I2Pd_AppName}_v{#I2Pd_ver} +InternalCompressLevel=ultra64 +Compression=lzma/ultra64 +SolidCompression=true +ArchitecturesInstallIn64BitMode=x64 + +[Files] +Source: "..\i2pd_x86.exe"; DestDir: "{app}"; DestName: "i2pd.exe"; Flags: ignoreversion; Check: not IsWin64 +Source: "..\i2pd_x64.exe"; DestDir: "{app}"; DestName: "i2pd.exe"; Flags: ignoreversion; Check: IsWin64 +Source: "..\README.md"; DestDir: "{app}"; DestName: "Readme.txt"; Flags: onlyifdoesntexist +Source: "..\docs\i2pd.conf"; DestDir: "{userappdata}\i2pd"; Flags: onlyifdoesntexist +Source: "..\docs\subscriptions.txt"; DestDir: "{userappdata}\i2pd"; Flags: onlyifdoesntexist +Source: "..\docs\tunnels.conf"; DestDir: "{userappdata}\i2pd"; Flags: onlyifdoesntexist +Source: "..\contrib\*"; DestDir: "{userappdata}\i2pd"; Flags: onlyifdoesntexist recursesubdirs createallsubdirs + +[Icons] +Name: "{group}\I2Pd"; Filename: "{app}\i2pd.exe" +Name: "{group}\Readme"; Filename: "{app}\Readme.txt" + +[UninstallDelete] +Type: filesandordirs; Name: {app}\* diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index b6cc6f26..b7e13979 100755 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -2,7 +2,7 @@ + android:versionName="2.10.0"> diff --git a/contrib/rpm/i2pd.service b/contrib/rpm/i2pd.service new file mode 100644 index 00000000..b14af025 --- /dev/null +++ b/contrib/rpm/i2pd.service @@ -0,0 +1,16 @@ +[Unit] +Description=I2P router +After=network.target + +[Service] +User=i2pd +Group=i2pd +Type=simple +ExecStart=/usr/bin/i2pd --service +PIDFile=/var/lib/i2pd/i2pd.pid +Restart=always +PrivateTmp=true + +[Install] +WantedBy=multi-user.target + diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec new file mode 100644 index 00000000..bb58d28d --- /dev/null +++ b/contrib/rpm/i2pd.spec @@ -0,0 +1,129 @@ +Name: i2pd +Version: 2.10.0 +Release: 3%{?dist} +Summary: I2P router written in C++ + +License: BSD +URL: https://github.com/PurpleI2P/i2pd +Source0: https://github.com/PurpleI2P/i2pd/archive/%{version}/%name-%version.tar.gz + +%if 0%{?rhel} == 7 +BuildRequires: cmake3 +%else +BuildRequires: cmake +%endif + +BuildRequires: chrpath +BuildRequires: gcc-c++ +BuildRequires: zlib-devel +BuildRequires: boost-devel +BuildRequires: openssl-devel +BuildRequires: miniupnpc-devel +BuildRequires: systemd-units + +%description +C++ implementation of I2P. + + +%package systemd +Summary: Files to run I2P router under systemd +Requires: i2pd +Requires: systemd +Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd +Obsoletes: %{name}-daemon + + +%description systemd +C++ implementation of I2P. + +This package contains systemd unit file to run i2pd as a system service +using dedicated user's permissions. + + +%prep +%setup -q + + +%build +cd build +%if 0%{?rhel} == 7 +%cmake3 \ + -DWITH_LIBRARY=OFF \ + -DWITH_UPNP=ON \ + -DWITH_HARDENING=ON \ + -DBUILD_SHARED_LIBS:BOOL=OFF +%else +%cmake \ + -DWITH_LIBRARY=OFF \ + -DWITH_UPNP=ON \ + -DWITH_HARDENING=ON \ + -DBUILD_SHARED_LIBS:BOOL=OFF +%endif + +make %{?_smp_mflags} + + +%install +cd build +chrpath -d i2pd +install -D -m 755 i2pd %{buildroot}%{_bindir}/i2pd +install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.service %{buildroot}/%{_unitdir}/i2pd.service +install -d -m 700 %{buildroot}/%{_sharedstatedir}/i2pd + + +%pre systemd +getent group i2pd >/dev/null || %{_sbindir}/groupadd -r i2pd +getent passwd i2pd >/dev/null || \ + %{_sbindir}/useradd -r -g i2pd -s %{_sbindir}/nologin \ + -d %{_sharedstatedir}/i2pd -c 'I2P Service' i2pd + + +%post systemd +%systemd_post i2pd.service + + +%preun systemd +%systemd_preun i2pd.service + + +%postun systemd +%systemd_postun_with_restart i2pd.service + + +%files +%doc LICENSE README.md +%_bindir/i2pd + + +%files systemd +/%_unitdir/i2pd.service +%dir %attr(0700,i2pd,i2pd) %_sharedstatedir/i2pd + + +%changelog +* Tue Oct 20 2016 Anatolii Vorona - 2.10.0-3 +- add support C7 +- move rpm-related files to contrib folder + +* Sun Oct 16 2016 Oleg Girko - 2.10.0-1 +- update to 2.10.0 + +* Sun Aug 14 2016 Oleg Girko - 2.9.0-1 +- update to 2.9.0 + +* Sun Aug 07 2016 Oleg Girko - 2.8.0-2 +- rename daemon subpackage to systemd + +* Sat Aug 06 2016 Oleg Girko - 2.8.0-1 +- update to 2.8.0 +- remove wrong rpath from i2pd binary +- add daemon subpackage with systemd unit file + +* Sat May 21 2016 Oleg Girko - 2.7.0-1 +- update to 2.7.0 + +* Tue Apr 05 2016 Oleg Girko - 2.6.0-1 +- update to 2.6.0 + +* Tue Jan 26 2016 Yaroslav Sidlovsky - 2.3.0-1 +- initial package for version 2.3.0 diff --git a/debian/changelog b/debian/changelog index 6600f8e4..1ecafa34 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +i2pd (2.10.0-1) unstable; urgency=low + + * updated to version 2.10.0/0.9.27 + * reseed.verify set to true by default + + -- orignal Sun, 16 Oct 2016 13:55:40 +0000 + i2pd (2.9.0-1) unstable; urgency=low * updated to version 2.9.0 diff --git a/docs/build_notes_unix.md b/docs/build_notes_unix.md index 18e51e62..b1cc4148 100644 --- a/docs/build_notes_unix.md +++ b/docs/build_notes_unix.md @@ -4,8 +4,9 @@ Building on Unix systems First of all we need to make sure that all dependencies are satisfied. This doc is trying to cover: -* [Debian/Ubuntu](#debianubuntu) (contains packaging instructions) -* [Fedora/Centos](#fedoracentos) +* [Debian/Ubuntu](#debian-ubuntu) (contains packaging instructions) +* [Fedora/Centos](#fedora-centos) +* [Fedora/Centos](#mac-os-x) * [FreeBSD](#freebsd) Make sure you have all required dependencies for your system successfully installed. @@ -73,15 +74,6 @@ sudo yum install make cmake gcc gcc-c++ *Latest Fedora system using [DNF](https://en.wikipedia.org/wiki/DNF_(software)) instead of YUM by default, you may prefer to use DNF, but YUM should be ok* -> *Centos 7 has CMake 2.8.11 in the official repositories that too old to build i2pd, CMake >=2.8.12 is required* -> You could build CMake for Centos manualy(WARNING there are a lot of build dependencies!): -> ```bash -> wget https://kojipkgs.fedoraproject.org/packages/cmake/2.8.12/3.fc21/src/cmake-2.8.12-3.fc21.src.rpm -> yum-builddep cmake-2.8.12-3.fc21.src.rpm -> rpmbuild --rebuild cmake-2.8.12-3.fc21.src.rpm -> yum install ~/rpmbuild/RPMS/x86_64/cmake-2.8.12-3.el7.centos.x86_64.rpm -> ``` - Also you will need a bunch of development libraries ```bash sudo yum install boost-devel openssl-devel @@ -91,11 +83,20 @@ If you need UPnP support (don't forget to run CMake with `WITH_UPNP=ON`) miniupn ```bash miniupnpc-devel ``` +> *Centos 7 has CMake 2.8.11 in the official repositories that too old to build i2pd, CMake >=2.8.12 is required.* +> +> But you can use cmake3 from the epel repository: +> ```bash +> yum install epel-release -y +> yum install make cmake3 gcc gcc-c++ miniupnpc-devel boost-devel openssl-devel -y +> cmake3 -DWITH_LIBRARY=OFF -DWITH_UPNP=ON -DWITH_HARDENING=ON -DBUILD_SHARED_LIBS:BOOL=OFF +> make +> ``` MAC OS X -------- -Requires homebrew +Requires [homebrew](http://brew.sh/) ```bash brew install libressl boost diff --git a/docs/i2pd.conf b/docs/i2pd.conf index 9ade3663..5e2770f6 100644 --- a/docs/i2pd.conf +++ b/docs/i2pd.conf @@ -92,6 +92,8 @@ ipv6 = false # name = I2Pd [reseed] +## Enable or disable reseed data verification. +verify = true ## URLs to request reseed data from, separated by comma ## Default: "mainline" I2P Network reseeds # urls = https://reseed.i2p-projekt.de/,https://i2p.mooo.com/netDb/,https://netdb.i2p2.no/ diff --git a/docs/usage.md b/docs/usage.md index cb678cb4..9480a556 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -35,19 +35,19 @@ If you wish to run your own website in Invisible Internet, follow those steps: 2) Configure i2pd to create HTTP server tunnel. Put in your ~/.i2pd/tunnels.conf file: - [anon-website] - type = http - host = 127.0.0.1 - port = 8080 - keys = anon-website.dat + [anon-website] + type = http + host = 127.0.0.1 + port = 8080 + keys = anon-website.dat 3) Restart i2pd. 4) Find b32 destination of your website. -Go to webconsole -> [I2P tunnels page](http://127.0.0.1:7070/?page=i2p_tunnels). Look for Sever tunnels and you will see address like \.b32.i2p next to anon-website. + Go to webconsole -> [I2P tunnels page](http://127.0.0.1:7070/?page=i2p_tunnels). Look for Sever tunnels and you will see address like \.b32.i2p next to anon-website. -Website is now available in Invisible Internet by visiting this address. + Website is now available in Invisible Internet by visiting this address. 5) (Optional) Register short and rememberable .i2p domain on [inr.i2p](http://inr.i2p). @@ -58,51 +58,51 @@ Website is now available in Invisible Internet by visiting this address. 1) Run your IRC server software and find out which host:port it uses (for example, 127.0.0.1:5555). -For small private IRC servers you can use [miniircd](https://github.com/jrosdahl/miniircd), for large public networks [UnreadIRCd](https://www.unrealircd.org/). + For small private IRC servers you can use [miniircd](https://github.com/jrosdahl/miniircd), for large public networks [UnreadIRCd](https://www.unrealircd.org/). 2) Configure i2pd to create IRC server tunnel. -Simplest case, if your server does not support WebIRC, add this to ~/.i2pd/tunnels.conf: + Simplest case, if your server does not support WebIRC, add this to ~/.i2pd/tunnels.conf: - [anon-chatserver] - type = irc - host = 127.0.0.1 - port = 5555 - keys = chatserver-key.dat + [anon-chatserver] + type = irc + host = 127.0.0.1 + port = 5555 + keys = chatserver-key.dat -And that is it. + And that is it. -Alternatively, if your IRC server supports WebIRC, for example, UnreadIRCd, put this into UnrealIRCd config: + Alternatively, if your IRC server supports WebIRC, for example, UnreadIRCd, put this into UnrealIRCd config: - webirc { - mask 127.0.0.1; - password your_password; - }; + webirc { + mask 127.0.0.1; + password your_password; + }; -Also change line: + Also change line: - modes-on-connect "+ixw"; + modes-on-connect "+ixw"; -to + to - modes-on-connect "+iw"; + modes-on-connect "+iw"; -And this in ~/.i2pd/tunnels.conf: + And this in ~/.i2pd/tunnels.conf: - [anon-chatserver] - type = irc - host = 127.0.0.1 - port = 5555 - keys = chatserver-key.dat - webircpassword = your_password + [anon-chatserver] + type = irc + host = 127.0.0.1 + port = 5555 + keys = chatserver-key.dat + webircpassword = your_password 3) Restart i2pd. 4) Find b32 destination of your anonymous IRC server. -Go to webconsole -> [I2P tunnels page](http://127.0.0.1:7070/?page=i2p_tunnels). Look for Sever tunnels and you will see address like \.b32.i2p next to anon-chatserver. + Go to webconsole -> [I2P tunnels page](http://127.0.0.1:7070/?page=i2p_tunnels). Look for Sever tunnels and you will see address like \.b32.i2p next to anon-chatserver. -Clients will use this address to connect to your server anonymously. + Clients will use this address to connect to your server anonymously. ### Connect to anonymous IRC server diff --git a/version.h b/version.h index 00064c00..3814f5f4 100644 --- a/version.h +++ b/version.h @@ -7,7 +7,7 @@ #define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 9 +#define I2PD_VERSION_MINOR 10 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) @@ -21,7 +21,7 @@ #define I2P_VERSION_MAJOR 0 #define I2P_VERSION_MINOR 9 -#define I2P_VERSION_MICRO 26 +#define I2P_VERSION_MICRO 27 #define I2P_VERSION_PATCH 0 #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO)