mirror of https://github.com/PurpleI2P/i2pd.git
Jeff Becker
9 years ago
32 changed files with 486 additions and 382 deletions
@ -1,113 +1,115 @@
@@ -1,113 +1,115 @@
|
||||
#include <thread> |
||||
#include "Config.h" |
||||
#include "Daemon.h" |
||||
#include "util.h" |
||||
#include "Log.h" |
||||
|
||||
#ifdef _WIN32 |
||||
|
||||
#include "Win32/Win32Service.h" |
||||
#ifdef WIN32_APP |
||||
#include "Win32/Win32App.h" |
||||
#endif |
||||
|
||||
namespace i2p |
||||
{ |
||||
namespace util |
||||
{ |
||||
bool DaemonWin32::init(int argc, char* argv[]) |
||||
{ |
||||
setlocale(LC_CTYPE, ""); |
||||
SetConsoleCP(1251); |
||||
SetConsoleOutputCP(1251); |
||||
|
||||
if (!Daemon_Singleton::init(argc, argv)) |
||||
return false; |
||||
|
||||
std::string serviceControl; i2p::config::GetOption("svcctl", serviceControl); |
||||
if (serviceControl == "install") |
||||
{ |
||||
LogPrint(eLogInfo, "WinSVC: installing ", SERVICE_NAME, " as service"); |
||||
InstallService( |
||||
SERVICE_NAME, // Name of service
|
||||
SERVICE_DISPLAY_NAME, // Name to display
|
||||
SERVICE_START_TYPE, // Service start type
|
||||
SERVICE_DEPENDENCIES, // Dependencies
|
||||
SERVICE_ACCOUNT, // Service running account
|
||||
SERVICE_PASSWORD // Password of the account
|
||||
); |
||||
return false; |
||||
} |
||||
else if (serviceControl == "remove") |
||||
{ |
||||
LogPrint(eLogInfo, "WinSVC: uninstalling ", SERVICE_NAME, " service"); |
||||
UninstallService(SERVICE_NAME); |
||||
return false; |
||||
} |
||||
|
||||
#include <thread> |
||||
#include <clocale> |
||||
#include "Config.h" |
||||
#include "Daemon.h" |
||||
#include "util.h" |
||||
#include "Log.h" |
||||
|
||||
#ifdef _WIN32 |
||||
|
||||
#include "Win32/Win32Service.h" |
||||
#ifdef WIN32_APP |
||||
#include "Win32/Win32App.h" |
||||
#endif |
||||
|
||||
namespace i2p |
||||
{ |
||||
namespace util |
||||
{ |
||||
bool DaemonWin32::init(int argc, char* argv[]) |
||||
{ |
||||
setlocale(LC_CTYPE, ""); |
||||
SetConsoleCP(1251); |
||||
SetConsoleOutputCP(1251); |
||||
setlocale(LC_ALL, "Russian"); |
||||
|
||||
if (!Daemon_Singleton::init(argc, argv)) |
||||
return false; |
||||
|
||||
std::string serviceControl; i2p::config::GetOption("svcctl", serviceControl); |
||||
if (serviceControl == "install") |
||||
{ |
||||
LogPrint(eLogInfo, "WinSVC: installing ", SERVICE_NAME, " as service"); |
||||
InstallService( |
||||
SERVICE_NAME, // Name of service
|
||||
SERVICE_DISPLAY_NAME, // Name to display
|
||||
SERVICE_START_TYPE, // Service start type
|
||||
SERVICE_DEPENDENCIES, // Dependencies
|
||||
SERVICE_ACCOUNT, // Service running account
|
||||
SERVICE_PASSWORD // Password of the account
|
||||
); |
||||
return false; |
||||
} |
||||
else if (serviceControl == "remove") |
||||
{ |
||||
LogPrint(eLogInfo, "WinSVC: uninstalling ", SERVICE_NAME, " service"); |
||||
UninstallService(SERVICE_NAME); |
||||
return false; |
||||
} |
||||
|
||||
if (isDaemon) |
||||
{ |
||||
LogPrint(eLogDebug, "Daemon: running as service"); |
||||
I2PService service(SERVICE_NAME); |
||||
if (!I2PService::Run(service)) |
||||
{ |
||||
LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError()); |
||||
return false; |
||||
} |
||||
return false; |
||||
} |
||||
else |
||||
LogPrint(eLogDebug, "Daemon: running as user"); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
bool DaemonWin32::start() |
||||
{ |
||||
setlocale(LC_CTYPE, ""); |
||||
SetConsoleCP(1251); |
||||
SetConsoleOutputCP(1251); |
||||
setlocale(LC_ALL, "Russian"); |
||||
#ifdef WIN32_APP |
||||
if (!i2p::win32::StartWin32App ()) return false; |
||||
|
||||
// override log
|
||||
i2p::config::SetOption("log", std::string ("file")); |
||||
#endif |
||||
bool ret = Daemon_Singleton::start(); |
||||
if (ret && i2p::log::Logger().GetLogType() == eLogFile) |
||||
{ |
||||
// TODO: find out where this garbage to console comes from
|
||||
SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE); |
||||
SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE); |
||||
} |
||||
bool insomnia; i2p::config::GetOption("insomnia", insomnia); |
||||
if (insomnia) |
||||
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED); |
||||
return ret; |
||||
} |
||||
|
||||
bool DaemonWin32::stop() |
||||
{ |
||||
#ifdef WIN32_APP |
||||
i2p::win32::StopWin32App (); |
||||
#endif |
||||
return Daemon_Singleton::stop(); |
||||
} |
||||
|
||||
void DaemonWin32::run () |
||||
{ |
||||
#ifdef WIN32_APP |
||||
i2p::win32::RunWin32App (); |
||||
#else |
||||
while (running) |
||||
{ |
||||
std::this_thread::sleep_for (std::chrono::seconds(1)); |
||||
} |
||||
|
||||
#endif |
||||
} |
||||
} |
||||
} |
||||
|
||||
#endif |
||||
{ |
||||
LogPrint(eLogDebug, "Daemon: running as service"); |
||||
I2PService service(SERVICE_NAME); |
||||
if (!I2PService::Run(service)) |
||||
{ |
||||
LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError()); |
||||
return false; |
||||
} |
||||
return false; |
||||
} |
||||
else |
||||
LogPrint(eLogDebug, "Daemon: running as user"); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
bool DaemonWin32::start() |
||||
{ |
||||
setlocale(LC_CTYPE, ""); |
||||
SetConsoleCP(1251); |
||||
SetConsoleOutputCP(1251); |
||||
setlocale(LC_ALL, "Russian"); |
||||
#ifdef WIN32_APP |
||||
if (!i2p::win32::StartWin32App ()) return false; |
||||
|
||||
// override log
|
||||
i2p::config::SetOption("log", std::string ("file")); |
||||
#endif |
||||
bool ret = Daemon_Singleton::start(); |
||||
if (ret && i2p::log::Logger().GetLogType() == eLogFile) |
||||
{ |
||||
// TODO: find out where this garbage to console comes from
|
||||
SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE); |
||||
SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE); |
||||
} |
||||
bool insomnia; i2p::config::GetOption("insomnia", insomnia); |
||||
if (insomnia) |
||||
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED); |
||||
return ret; |
||||
} |
||||
|
||||
bool DaemonWin32::stop() |
||||
{ |
||||
#ifdef WIN32_APP |
||||
i2p::win32::StopWin32App (); |
||||
#endif |
||||
return Daemon_Singleton::stop(); |
||||
} |
||||
|
||||
void DaemonWin32::run () |
||||
{ |
||||
#ifdef WIN32_APP |
||||
i2p::win32::RunWin32App (); |
||||
#else |
||||
while (running) |
||||
{ |
||||
std::this_thread::sleep_for (std::chrono::seconds(1)); |
||||
} |
||||
|
||||
#endif |
||||
} |
||||
} |
||||
} |
||||
|
||||
#endif |
||||
|
@ -0,0 +1,108 @@
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, The PurpleI2P Project |
||||
* |
||||
* This file is part of Purple i2pd project and licensed under BSD3 |
||||
* |
||||
* See full license text in LICENSE file at top of project tree |
||||
*/ |
||||
|
||||
#include <inttypes.h> |
||||
#include <string.h> /* memset */ |
||||
#include <iostream> |
||||
|
||||
#include "Gzip.h" |
||||
|
||||
namespace i2p { |
||||
namespace data { |
||||
const size_t GZIP_CHUNK_SIZE = 16384; |
||||
|
||||
GzipInflator::GzipInflator (): m_IsDirty (false) |
||||
{ |
||||
memset (&m_Inflator, 0, sizeof (m_Inflator)); |
||||
inflateInit2 (&m_Inflator, MAX_WBITS + 16); // gzip
|
||||
} |
||||
|
||||
GzipInflator::~GzipInflator () |
||||
{ |
||||
inflateEnd (&m_Inflator); |
||||
} |
||||
|
||||
size_t GzipInflator::Inflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen) |
||||
{ |
||||
if (m_IsDirty) inflateReset (&m_Inflator); |
||||
m_IsDirty = true; |
||||
m_Inflator.next_in = const_cast<uint8_t *>(in); |
||||
m_Inflator.avail_in = inLen; |
||||
m_Inflator.next_out = out; |
||||
m_Inflator.avail_out = outLen; |
||||
int err; |
||||
if ((err = inflate (&m_Inflator, Z_NO_FLUSH)) == Z_STREAM_END) { |
||||
return outLen - m_Inflator.avail_out; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
void GzipInflator::Inflate (const uint8_t * in, size_t inLen, std::ostream& os) |
||||
{ |
||||
m_IsDirty = true; |
||||
uint8_t * out = new uint8_t[GZIP_CHUNK_SIZE]; |
||||
m_Inflator.next_in = const_cast<uint8_t *>(in); |
||||
m_Inflator.avail_in = inLen; |
||||
int ret; |
||||
do { |
||||
m_Inflator.next_out = out; |
||||
m_Inflator.avail_out = GZIP_CHUNK_SIZE; |
||||
ret = inflate (&m_Inflator, Z_NO_FLUSH); |
||||
if (ret < 0) { |
||||
inflateEnd (&m_Inflator); |
||||
os.setstate(std::ios_base::failbit); |
||||
break; |
||||
} |
||||
os.write ((char *)out, GZIP_CHUNK_SIZE - m_Inflator.avail_out); |
||||
} while (!m_Inflator.avail_out); // more data to read
|
||||
delete[] out; |
||||
} |
||||
|
||||
void GzipInflator::Inflate (std::istream& in, std::ostream& out) |
||||
{ |
||||
uint8_t * buf = new uint8_t[GZIP_CHUNK_SIZE]; |
||||
while (!in.eof ()) |
||||
{ |
||||
in.read ((char *) buf, GZIP_CHUNK_SIZE); |
||||
Inflate (buf, in.gcount (), out); |
||||
} |
||||
delete[] buf; |
||||
} |
||||
|
||||
GzipDeflator::GzipDeflator (): m_IsDirty (false) |
||||
{ |
||||
memset (&m_Deflator, 0, sizeof (m_Deflator)); |
||||
deflateInit2 (&m_Deflator, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY); // 15 + 16 sets gzip
|
||||
} |
||||
|
||||
GzipDeflator::~GzipDeflator () |
||||
{ |
||||
deflateEnd (&m_Deflator); |
||||
} |
||||
|
||||
void GzipDeflator::SetCompressionLevel (int level) |
||||
{ |
||||
deflateParams (&m_Deflator, level, Z_DEFAULT_STRATEGY); |
||||
} |
||||
|
||||
size_t GzipDeflator::Deflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen) |
||||
{ |
||||
if (m_IsDirty) deflateReset (&m_Deflator); |
||||
m_IsDirty = true; |
||||
m_Deflator.next_in = const_cast<uint8_t *>(in); |
||||
m_Deflator.avail_in = inLen; |
||||
m_Deflator.next_out = out; |
||||
m_Deflator.avail_out = outLen; |
||||
int err; |
||||
if ((err = deflate (&m_Deflator, Z_FINISH)) == Z_STREAM_END) { |
||||
return outLen - m_Deflator.avail_out; |
||||
} /* else */ |
||||
return 0; |
||||
} |
||||
} // data
|
||||
} // i2p
|
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
#ifndef GZIP_H__ |
||||
#define GZIP_H__ |
||||
|
||||
#include <zlib.h> |
||||
|
||||
namespace i2p { |
||||
namespace data { |
||||
class GzipInflator |
||||
{ |
||||
public: |
||||
|
||||
GzipInflator (); |
||||
~GzipInflator (); |
||||
|
||||
size_t Inflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen); |
||||
/** @note @a os failbit will be set in case of error */ |
||||
void Inflate (const uint8_t * in, size_t inLen, std::ostream& os); |
||||
void Inflate (std::istream& in, std::ostream& out); |
||||
|
||||
private: |
||||
|
||||
z_stream m_Inflator; |
||||
bool m_IsDirty; |
||||
}; |
||||
|
||||
class GzipDeflator |
||||
{ |
||||
public: |
||||
|
||||
GzipDeflator (); |
||||
~GzipDeflator (); |
||||
|
||||
void SetCompressionLevel (int level); |
||||
size_t Deflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen); |
||||
|
||||
private: |
||||
|
||||
z_stream m_Deflator; |
||||
bool m_IsDirty; |
||||
}; |
||||
} // data
|
||||
} // i2p
|
||||
|
||||
#endif /* GZIP_H__ */ |
@ -0,0 +1,82 @@
@@ -0,0 +1,82 @@
|
||||
#ifndef TAG_H__ |
||||
#define TAG_H__ |
||||
|
||||
#include <string.h> /* memcpy */ |
||||
|
||||
#include "Base.h" |
||||
|
||||
namespace i2p { |
||||
namespace data { |
||||
template<int sz> |
||||
class Tag |
||||
{ |
||||
public: |
||||
|
||||
Tag (const uint8_t * buf) { memcpy (m_Buf, buf, sz); }; |
||||
Tag (const Tag<sz>& ) = default; |
||||
#ifndef _WIN32 // FIXME!!! msvs 2013 can't compile it
|
||||
Tag (Tag<sz>&& ) = default; |
||||
#endif |
||||
Tag () = default; |
||||
|
||||
Tag<sz>& operator= (const Tag<sz>& ) = default; |
||||
#ifndef _WIN32 |
||||
Tag<sz>& operator= (Tag<sz>&& ) = default; |
||||
#endif |
||||
|
||||
uint8_t * operator()() { return m_Buf; }; |
||||
const uint8_t * operator()() const { return m_Buf; }; |
||||
|
||||
operator uint8_t * () { return m_Buf; }; |
||||
operator const uint8_t * () const { return m_Buf; }; |
||||
|
||||
const uint64_t * GetLL () const { return ll; }; |
||||
|
||||
bool operator== (const Tag<sz>& other) const { return !memcmp (m_Buf, other.m_Buf, sz); }; |
||||
bool operator< (const Tag<sz>& other) const { return memcmp (m_Buf, other.m_Buf, sz) < 0; }; |
||||
|
||||
bool IsZero () const |
||||
{ |
||||
for (int i = 0; i < sz/8; i++) |
||||
if (ll[i]) return false; |
||||
return true; |
||||
} |
||||
|
||||
std::string ToBase64 () const |
||||
{ |
||||
char str[sz*2]; |
||||
int l = i2p::data::ByteStreamToBase64 (m_Buf, sz, str, sz*2); |
||||
str[l] = 0; |
||||
return std::string (str); |
||||
} |
||||
|
||||
std::string ToBase32 () const |
||||
{ |
||||
char str[sz*2]; |
||||
int l = i2p::data::ByteStreamToBase32 (m_Buf, sz, str, sz*2); |
||||
str[l] = 0; |
||||
return std::string (str); |
||||
} |
||||
|
||||
void FromBase32 (const std::string& s) |
||||
{ |
||||
i2p::data::Base32ToByteStream (s.c_str (), s.length (), m_Buf, sz); |
||||
} |
||||
|
||||
void FromBase64 (const std::string& s) |
||||
{ |
||||
i2p::data::Base64ToByteStream (s.c_str (), s.length (), m_Buf, sz); |
||||
} |
||||
|
||||
private: |
||||
|
||||
union // 8 bytes alignment
|
||||
{ |
||||
uint8_t m_Buf[sz]; |
||||
uint64_t ll[sz/8]; |
||||
}; |
||||
}; |
||||
} // data
|
||||
} // i2p
|
||||
|
||||
#endif /* TAG_H__ */ |
@ -1,13 +1,16 @@
@@ -1,13 +1,16 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 2e86fd8..c1037af 100644
|
||||
index fe8ae7e..fc8abda 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -9,7 +9,7 @@ DEPS := obj/make.dep
|
||||
@@ -9,9 +9,9 @@ DEPS := obj/make.dep
|
||||
|
||||
include filelist.mk |
||||
|
||||
-USE_AESNI := yes
|
||||
+USE_AESNI := no
|
||||
USE_STATIC := no |
||||
-USE_UPNP := no
|
||||
+USE_UPNP := yes
|
||||
|
||||
ifeq ($(UNAME),Darwin) |
||||
DAEMON_SRC += DaemonLinux.cpp |
@ -1 +1 @@
@@ -1 +1 @@
|
||||
0001-disable-aesni-by-default.patch |
||||
01-tune-build-opts.patch |
||||
|
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
#include <cassert> |
||||
#include <string.h> |
||||
|
||||
#include "../Base.h" |
||||
|
||||
using namespace i2p::data; |
||||
|
||||
int main() { |
||||
const char *in = "test"; |
||||
size_t in_len = strlen(in); |
||||
char out[16]; |
||||
|
||||
/* bytes -> b64 */ |
||||
assert(ByteStreamToBase64(NULL, 0, NULL, 0) == 0); |
||||
assert(ByteStreamToBase64(NULL, 0, out, sizeof(out)) == 0); |
||||
|
||||
assert(Base64EncodingBufferSize(2) == 4); |
||||
assert(Base64EncodingBufferSize(4) == 8); |
||||
assert(Base64EncodingBufferSize(6) == 8); |
||||
assert(Base64EncodingBufferSize(7) == 12); |
||||
assert(Base64EncodingBufferSize(9) == 12); |
||||
assert(Base64EncodingBufferSize(10) == 16); |
||||
assert(Base64EncodingBufferSize(12) == 16); |
||||
assert(Base64EncodingBufferSize(13) == 20); |
||||
|
||||
assert(ByteStreamToBase64((uint8_t *) in, in_len, out, sizeof(out)) == 8); |
||||
assert(memcmp(out, "dGVzdA==", 8) == 0); |
||||
|
||||
/* b64 -> bytes */ |
||||
assert(Base64ToByteStream(NULL, 0, NULL, 0) == 0); |
||||
assert(Base64ToByteStream(NULL, 0, (uint8_t *) out, sizeof(out)) == 0); |
||||
|
||||
in = "dGVzdA=="; /* valid b64 */ |
||||
assert(Base64ToByteStream(in, strlen(in), (uint8_t *) out, sizeof(out)) == 4); |
||||
assert(memcmp(out, "test", 4) == 0); |
||||
|
||||
in = "dGVzdA="; /* invalid b64 : not padded */ |
||||
assert(Base64ToByteStream(in, strlen(in), (uint8_t *) out, sizeof(out)) == 0); |
||||
|
||||
in = "dG/z.A=="; /* invalid b64 : char not from alphabet */ |
||||
// assert(Base64ToByteStream(in, strlen(in), (uint8_t *) out, sizeof(out)) == 0);
|
||||
// ^^^ fails, current implementation not checks acceptable symbols
|
||||
|
||||
return 0; |
||||
} |
Loading…
Reference in new issue