Browse Source

Merge remote-tracking branch 'purple/openssl' into meshnet

pull/557/head
Jeff Becker 9 years ago
parent
commit
43be363542
No known key found for this signature in database
GPG Key ID: AB950234D6EA286B
  1. 4
      AddressBook.cpp
  2. 95
      Base.cpp
  3. 117
      Base.h
  4. 2
      Crypto.h
  5. 2
      DaemonWin32.cpp
  6. 29
      Garlic.cpp
  7. 108
      Gzip.cpp
  8. 44
      Gzip.h
  9. 26
      HTTPProxy.cpp
  10. 8
      HTTPServer.cpp
  11. 1
      Makefile
  12. 2
      Makefile.homebrew
  13. 2
      Makefile.linux
  14. 4
      Makefile.mingw
  15. 2
      Makefile.osx
  16. 6
      NTCPSession.cpp
  17. 4
      NetDb.cpp
  18. 2
      NetDb.h
  19. 8
      SSU.cpp
  20. 2
      SSUData.cpp
  21. 4
      SSUSession.cpp
  22. 82
      Tag.h
  23. 4
      TransitTunnel.cpp
  24. 1
      build/CMakeLists.txt
  25. 1
      debian/control
  26. 7
      debian/patches/01-tune-build-opts.patch
  27. 2
      debian/patches/series
  28. 2
      filelist.mk
  29. 4
      qt/i2pd_qt/i2pd_qt.pro
  30. 7
      tests/Makefile
  31. 45
      tests/test-base-64.cpp
  32. 5
      tests/test-http-req.cpp

4
AddressBook.cpp

@ -203,7 +203,7 @@ namespace client
} }
//--------------------------------------------------------------------- //---------------------------------------------------------------------
AddressBook::AddressBook (): m_Storage(new AddressBookFilesystemStorage), m_IsLoaded (false), m_IsDownloading (false), AddressBook::AddressBook (): m_Storage(nullptr), m_IsLoaded (false), m_IsDownloading (false),
m_DefaultSubscription (nullptr), m_SubscriptionsUpdateTimer (nullptr) m_DefaultSubscription (nullptr), m_SubscriptionsUpdateTimer (nullptr)
{ {
} }
@ -215,6 +215,8 @@ namespace client
void AddressBook::Start () void AddressBook::Start ()
{ {
if (!m_Storage)
m_Storage = new AddressBookFilesystemStorage;
m_Storage->Init(); m_Storage->Init();
LoadHosts (); /* try storage, then hosts.txt, then download */ LoadHosts (); /* try storage, then hosts.txt, then download */
StartSubscriptions (); StartSubscriptions ();

95
Base.cpp

@ -1,4 +1,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include "Base.h" #include "Base.h"
namespace i2p namespace i2p
@ -283,99 +285,6 @@ namespace data
} }
return ret; return ret;
} }
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;
}
bool GzipInflator::Inflate (const uint8_t * in, size_t inLen, std::ostream& s)
{
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);
s.setstate(std::ios_base::failbit);
break;
}
s.write ((char *)out, GZIP_CHUNK_SIZE - m_Inflator.avail_out);
}
while (!m_Inflator.avail_out); // more data to read
delete[] out;
return ret == Z_STREAM_END || ret < 0;
}
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;
}
} }
} }

117
Base.h

@ -2,15 +2,11 @@
#define BASE_H__ #define BASE_H__
#include <inttypes.h> #include <inttypes.h>
#include <string.h>
#include <string> #include <string>
#include <zlib.h>
#include <iostream> #include <iostream>
namespace i2p namespace i2p {
{ namespace data {
namespace data
{
size_t ByteStreamToBase64 (const uint8_t * InBuffer, size_t InCount, char * OutBuffer, size_t len); size_t ByteStreamToBase64 (const uint8_t * InBuffer, size_t InCount, char * OutBuffer, size_t len);
size_t Base64ToByteStream (const char * InBuffer, size_t InCount, uint8_t * OutBuffer, size_t len ); size_t Base64ToByteStream (const char * InBuffer, size_t InCount, uint8_t * OutBuffer, size_t len );
const char * GetBase32SubstitutionTable (); const char * GetBase32SubstitutionTable ();
@ -23,112 +19,7 @@ namespace data
Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes
*/ */
size_t Base64EncodingBufferSize(const size_t input_size); size_t Base64EncodingBufferSize(const size_t input_size);
} // data
template<int sz> } // i2p
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];
};
};
const size_t GZIP_CHUNK_SIZE = 16384;
class GzipInflator
{
public:
GzipInflator ();
~GzipInflator ();
size_t Inflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen);
bool Inflate (const uint8_t * in, size_t inLen, std::ostream& s);
// return true when finshed or error, s failbit will be set in case of error
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;
};
}
}
#endif #endif

2
Crypto.h

@ -9,7 +9,9 @@
#include <openssl/dsa.h> #include <openssl/dsa.h>
#include <openssl/sha.h> #include <openssl/sha.h>
#include <openssl/rand.h> #include <openssl/rand.h>
#include "Base.h" #include "Base.h"
#include "Tag.h"
namespace i2p namespace i2p
{ {

2
DaemonWin32.cpp

@ -1,4 +1,5 @@
#include <thread> #include <thread>
#include <clocale>
#include "Config.h" #include "Config.h"
#include "Daemon.h" #include "Daemon.h"
#include "util.h" #include "util.h"
@ -20,6 +21,7 @@ namespace i2p
setlocale(LC_CTYPE, ""); setlocale(LC_CTYPE, "");
SetConsoleCP(1251); SetConsoleCP(1251);
SetConsoleOutputCP(1251); SetConsoleOutputCP(1251);
setlocale(LC_ALL, "Russian");
if (!Daemon_Singleton::init(argc, argv)) if (!Daemon_Singleton::init(argc, argv))
return false; return false;

29
Garlic.cpp

@ -7,6 +7,7 @@
#include "I2NPProtocol.h" #include "I2NPProtocol.h"
#include "Tunnel.h" #include "Tunnel.h"
#include "TunnelPool.h" #include "TunnelPool.h"
#include "Transports.h"
#include "Timestamp.h" #include "Timestamp.h"
#include "Log.h" #include "Log.h"
#include "Garlic.h" #include "Garlic.h"
@ -514,26 +515,34 @@ namespace garlic
buf += 32; buf += 32;
uint32_t gwTunnel = bufbe32toh (buf); uint32_t gwTunnel = bufbe32toh (buf);
buf += 4; buf += 4;
auto msg = CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from);
if (from) // received through an inbound tunnel
{
std::shared_ptr<i2p::tunnel::OutboundTunnel> tunnel; std::shared_ptr<i2p::tunnel::OutboundTunnel> tunnel;
if (from && from->GetTunnelPool ()) if (from->GetTunnelPool ())
tunnel = from->GetTunnelPool ()->GetNextOutboundTunnel (); tunnel = from->GetTunnelPool ()->GetNextOutboundTunnel ();
if (!tunnel) else
{ LogPrint (eLogError, "Garlic: Tunnel pool is not set for inbound tunnel");
tunnel = GetTunnelPool()->GetNextOutboundTunnel();
}
if (tunnel) // we have send it through an outbound tunnel if (tunnel) // we have send it through an outbound tunnel
{
auto msg = CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from);
tunnel->SendTunnelDataMsg (gwHash, gwTunnel, msg); tunnel->SendTunnelDataMsg (gwHash, gwTunnel, msg);
}
else else
LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove given tunnelID=", gwTunnel); LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove");
}
else // received directly
i2p::transport::transports.SendMessage (gwHash, i2p::CreateTunnelGatewayMsg (gwTunnel, msg)); // send directly
break; break;
} }
case eGarlicDeliveryTypeRouter: case eGarlicDeliveryTypeRouter:
LogPrint (eLogWarning, "Garlic: type router not supported"); {
uint8_t * ident = buf;
buf += 32; buf += 32;
if (!from) // received directly
i2p::transport::transports.SendMessage (ident,
CreateI2NPMessage (buf, GetI2NPMessageLength (buf)));
else
LogPrint (eLogWarning, "Garlic: type router for inbound tunnels not supported");
break; break;
}
default: default:
LogPrint (eLogWarning, "Garlic: unknown delivery type ", (int)deliveryType); LogPrint (eLogWarning, "Garlic: unknown delivery type ", (int)deliveryType);
} }

108
Gzip.cpp

@ -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

44
Gzip.h

@ -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__ */

26
HTTPProxy.cpp

@ -82,13 +82,13 @@ namespace proxy {
void HTTPReqHandler::AsyncSockRead() void HTTPReqHandler::AsyncSockRead()
{ {
LogPrint(eLogDebug, "HTTPProxy: async sock read"); LogPrint(eLogDebug, "HTTPProxy: async sock read");
if(m_sock) { if (!m_sock) {
LogPrint(eLogError, "HTTPProxy: no socket for read");
return;
}
m_sock->async_receive(boost::asio::buffer(m_http_buff, http_buffer_size), m_sock->async_receive(boost::asio::buffer(m_http_buff, http_buffer_size),
std::bind(&HTTPReqHandler::HandleSockRecv, shared_from_this(), std::bind(&HTTPReqHandler::HandleSockRecv, shared_from_this(),
std::placeholders::_1, std::placeholders::_2)); std::placeholders::_1, std::placeholders::_2));
} else {
LogPrint(eLogError, "HTTPProxy: no socket for read");
}
} }
void HTTPReqHandler::Terminate() { void HTTPReqHandler::Terminate() {
@ -335,21 +335,19 @@ namespace proxy {
void HTTPReqHandler::HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream) void HTTPReqHandler::HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream)
{ {
if (stream) if (!stream) {
{ LogPrint (eLogError, "HTTPProxy: error when creating the stream, check the previous warnings for more info");
if (Kill()) return; HTTPRequestFailed("error when creating the stream, check logs");
LogPrint (eLogInfo, "HTTPProxy: New I2PTunnel connection"); return;
}
if (Kill())
return;
LogPrint (eLogDebug, "HTTPProxy: New I2PTunnel connection");
auto connection = std::make_shared<i2p::client::I2PTunnelConnection>(GetOwner(), m_sock, stream); auto connection = std::make_shared<i2p::client::I2PTunnelConnection>(GetOwner(), m_sock, stream);
GetOwner()->AddHandler (connection); GetOwner()->AddHandler (connection);
connection->I2PConnect (reinterpret_cast<const uint8_t*>(m_request.data()), m_request.size()); connection->I2PConnect (reinterpret_cast<const uint8_t*>(m_request.data()), m_request.size());
Done (shared_from_this()); Done (shared_from_this());
} }
else
{
LogPrint (eLogError, "HTTPProxy: error when creating the stream, check the previous warnings for more info");
HTTPRequestFailed("error when creating the stream, check logs");
}
}
HTTPProxy::HTTPProxy(const std::string& address, int port, std::shared_ptr<i2p::client::ClientDestination> localDestination): HTTPProxy::HTTPProxy(const std::string& address, int port, std::shared_ptr<i2p::client::ClientDestination> localDestination):
TCPIPAcceptor(address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()) TCPIPAcceptor(address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ())

8
HTTPServer.cpp

@ -126,8 +126,12 @@ namespace http {
s << s <<
"<!DOCTYPE html>\r\n" "<!DOCTYPE html>\r\n"
"<html lang=\"en\">\r\n" /* TODO: Add support for locale */ "<html lang=\"en\">\r\n" /* TODO: Add support for locale */
" <head>\r\n" " <head>\r\n" /* TODO: Find something to parse html/template system. This is horrible. */
" <meta charset=\"UTF-8\">\r\n" /* TODO: Find something to parse html/template system. This is horrible. */ #if (!defined(WIN32))
" <meta charset=\"UTF-8\">\r\n"
#else
" <meta charset=\"windows-1251\">\r\n"
#endif
" <link rel=\"shortcut icon\" href=\"" << itoopieFavicon << "\">\r\n" " <link rel=\"shortcut icon\" href=\"" << itoopieFavicon << "\">\r\n"
" <title>Purple I2P " VERSION " Webconsole</title>\r\n" " <title>Purple I2P " VERSION " Webconsole</title>\r\n"
<< cssStyles << << cssStyles <<

1
Makefile

@ -12,6 +12,7 @@ include filelist.mk
USE_AESNI := yes USE_AESNI := yes
USE_STATIC := no USE_STATIC := no
USE_MESHNET := yes USE_MESHNET := yes
USE_UPNP := no
ifeq ($(UNAME),Darwin) ifeq ($(UNAME),Darwin)
DAEMON_SRC += DaemonLinux.cpp DAEMON_SRC += DaemonLinux.cpp

2
Makefile.homebrew

@ -8,7 +8,7 @@ INCFLAGS = -I${SSLROOT}/include -I${BOOSTROOT}/include
LDFLAGS = -L${SSLROOT}/lib -L${BOOSTROOT}/lib LDFLAGS = -L${SSLROOT}/lib -L${BOOSTROOT}/lib
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
ifeq ($(USE_UPNP),1) ifeq ($(USE_UPNP),yes)
LDFLAGS += -ldl LDFLAGS += -ldl
CXXFLAGS += -DUSE_UPNP CXXFLAGS += -DUSE_UPNP
endif endif

2
Makefile.linux

@ -43,7 +43,7 @@ else
endif endif
# UPNP Support (miniupnpc 1.5 or 1.6) # UPNP Support (miniupnpc 1.5 or 1.6)
ifeq ($(USE_UPNP),1) ifeq ($(USE_UPNP),yes)
LDFLAGS += -lminiupnpc LDFLAGS += -lminiupnpc
CXXFLAGS += -DUSE_UPNP CXXFLAGS += -DUSE_UPNP
endif endif

4
Makefile.mingw

@ -9,7 +9,7 @@ LDFLAGS = -Wl,-rpath,/usr/local/lib \
-L/usr/local/lib -L/usr/local/lib
# UPNP Support # UPNP Support
ifeq ($(USE_UPNP),1) ifeq ($(USE_UPNP),yes)
CXXFLAGS += -DUSE_UPNP -DMINIUPNP_STATICLIB CXXFLAGS += -DUSE_UPNP -DMINIUPNP_STATICLIB
LDLIBS = -Wl,-Bstatic -lminiupnpc LDLIBS = -Wl,-Bstatic -lminiupnpc
endif endif
@ -37,7 +37,7 @@ ifeq ($(USE_WIN32_APP), yes)
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC)) DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
endif endif
ifeq ($(USE_AESNI),1) ifeq ($(USE_AESNI),yes)
CPU_FLAGS = -maes -DAESNI CPU_FLAGS = -maes -DAESNI
else else
CPU_FLAGS = -msse CPU_FLAGS = -msse

2
Makefile.osx vendored

@ -5,7 +5,7 @@ INCFLAGS = -I/usr/local/include -I/usr/local/ssl/include
LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib -L/usr/local/ssl/lib LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib -L/usr/local/ssl/lib
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
ifeq ($(USE_UPNP),1) ifeq ($(USE_UPNP),yes)
LDFLAGS += -ldl LDFLAGS += -ldl
CXXFLAGS += -DUSE_UPNP CXXFLAGS += -DUSE_UPNP
endif endif

6
NTCPSession.cpp

@ -1,6 +1,6 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <zlib.h>
#include "I2PEndian.h" #include "I2PEndian.h"
#include "Base.h" #include "Base.h"
#include "Crypto.h" #include "Crypto.h"
@ -430,7 +430,7 @@ namespace transport
} }
else else
{ {
LogPrint (eLogInfo, "NTCP: Server session from ", m_Socket.remote_endpoint (), " connected"); LogPrint (eLogDebug, "NTCP: Server session from ", m_Socket.remote_endpoint (), " connected");
m_Server.AddNTCPSession (shared_from_this ()); m_Server.AddNTCPSession (shared_from_this ());
Connected (); Connected ();
@ -942,7 +942,7 @@ namespace transport
{ {
if (ecode) if (ecode)
{ {
LogPrint (eLogError, "NTCP: Connect error: ", ecode.message ()); LogPrint (eLogError, "NTCP: Can't connect to ", conn->GetSocket ().remote_endpoint (), ": ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted) if (ecode != boost::asio::error::operation_aborted)
i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true);
conn->Terminate (); conn->Terminate ();

4
NetDb.cpp

@ -2,7 +2,7 @@
#include <fstream> #include <fstream>
#include <vector> #include <vector>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <zlib.h>
#include "I2PEndian.h" #include "I2PEndian.h"
#include "Base.h" #include "Base.h"
#include "Crypto.h" #include "Crypto.h"
@ -671,7 +671,7 @@ namespace data
if (!replyMsg) if (!replyMsg)
{ {
LogPrint (eLogWarning, "NetDb: Requested ", key, " not found. ", numExcluded, " excluded"); LogPrint (eLogWarning, "NetDb: Requested ", key, " not found, ", numExcluded, " peers excluded");
// find or cleate response // find or cleate response
std::vector<IdentHash> closestFloodfills; std::vector<IdentHash> closestFloodfills;
bool found = false; bool found = false;

2
NetDb.h

@ -8,7 +8,9 @@
#include <string> #include <string>
#include <thread> #include <thread>
#include <mutex> #include <mutex>
#include "Base.h" #include "Base.h"
#include "Gzip.h"
#include "FS.h" #include "FS.h"
#include "Queue.h" #include "Queue.h"
#include "I2NPProtocol.h" #include "I2NPProtocol.h"

8
SSU.cpp

@ -253,7 +253,7 @@ namespace transport
session = std::make_shared<SSUSession> (*this, packet->from); session = std::make_shared<SSUSession> (*this, packet->from);
session->WaitForConnect (); session->WaitForConnect ();
(*sessions)[packet->from] = session; (*sessions)[packet->from] = session;
LogPrint (eLogInfo, "SSU: new session from ", packet->from.address ().to_string (), ":", packet->from.port (), " created"); LogPrint (eLogDebug, "SSU: new session from ", packet->from.address ().to_string (), ":", packet->from.port (), " created");
} }
} }
session->ProcessNextMessage (packet->buf, packet->len, packet->from); session->ProcessNextMessage (packet->buf, packet->len, packet->from);
@ -334,7 +334,7 @@ namespace transport
auto session = std::make_shared<SSUSession> (*this, remoteEndpoint, router, peerTest); auto session = std::make_shared<SSUSession> (*this, remoteEndpoint, router, peerTest);
sessions[remoteEndpoint] = session; sessions[remoteEndpoint] = session;
// connect // connect
LogPrint (eLogInfo, "SSU: Creating new session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), "] ", LogPrint (eLogDebug, "SSU: Creating new session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), "] ",
remoteEndpoint.address ().to_string (), ":", remoteEndpoint.port ()); remoteEndpoint.address ().to_string (), ":", remoteEndpoint.port ());
session->Connect (); session->Connect ();
} }
@ -386,10 +386,10 @@ namespace transport
} }
if (introducerSession) // session found if (introducerSession) // session found
LogPrint (eLogInfo, "SSU: Session to introducer already exists"); LogPrint (eLogWarning, "SSU: Session to introducer already exists");
else // create new else // create new
{ {
LogPrint (eLogInfo, "SSU: Creating new session to introducer"); LogPrint (eLogDebug, "SSU: Creating new session to introducer ", introducer->iHost);
boost::asio::ip::udp::endpoint introducerEndpoint (introducer->iHost, introducer->iPort); boost::asio::ip::udp::endpoint introducerEndpoint (introducer->iHost, introducer->iPort);
introducerSession = std::make_shared<SSUSession> (*this, introducerEndpoint, router); introducerSession = std::make_shared<SSUSession> (*this, introducerEndpoint, router);
m_Sessions[introducerEndpoint] = introducerSession; m_Sessions[introducerEndpoint] = introducerSession;

2
SSUData.cpp

@ -241,7 +241,7 @@ namespace transport
if (!msg->IsExpired ()) if (!msg->IsExpired ())
m_Handler.PutNextMessage (msg); m_Handler.PutNextMessage (msg);
else else
LogPrint (eLogInfo, "SSU: message expired"); LogPrint (eLogDebug, "SSU: message expired");
} }
else else
LogPrint (eLogWarning, "SSU: Message ", msgID, " already received"); LogPrint (eLogWarning, "SSU: Message ", msgID, " already received");

4
SSUSession.cpp

@ -814,7 +814,7 @@ namespace transport
if (!ecode) if (!ecode)
{ {
// timeout expired // timeout expired
LogPrint (eLogWarning, "SSU: session was not established after ", SSU_CONNECT_TIMEOUT, " seconds"); LogPrint (eLogWarning, "SSU: session with ", m_RemoteEndpoint, " was not established after ", SSU_CONNECT_TIMEOUT, " seconds");
Failed (); Failed ();
} }
} }
@ -891,7 +891,7 @@ namespace transport
{ {
if (ecode != boost::asio::error::operation_aborted) if (ecode != boost::asio::error::operation_aborted)
{ {
LogPrint (eLogWarning, "SSU: no activity for ", SSU_TERMINATION_TIMEOUT, " seconds"); LogPrint (eLogWarning, "SSU: no activity with ", m_RemoteEndpoint, " for ", SSU_TERMINATION_TIMEOUT, " seconds");
Failed (); Failed ();
} }
} }

82
Tag.h

@ -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__ */

4
TransitTunnel.cpp

@ -92,7 +92,7 @@ namespace tunnel
{ {
if (isEndpoint) if (isEndpoint)
{ {
LogPrint (eLogInfo, "TransitTunnel: endpoint ", receiveTunnelID, " created"); LogPrint (eLogDebug, "TransitTunnel: endpoint ", receiveTunnelID, " created");
return std::make_shared<TransitTunnelEndpoint> (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey); return std::make_shared<TransitTunnelEndpoint> (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey);
} }
else if (isGateway) else if (isGateway)
@ -102,7 +102,7 @@ namespace tunnel
} }
else else
{ {
LogPrint (eLogInfo, "TransitTunnel: ", receiveTunnelID, "->", nextTunnelID, " created"); LogPrint (eLogDebug, "TransitTunnel: ", receiveTunnelID, "->", nextTunnelID, " created");
return std::make_shared<TransitTunnelParticipant> (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey); return std::make_shared<TransitTunnelParticipant> (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey);
} }
} }

1
build/CMakeLists.txt

@ -21,6 +21,7 @@ set (LIBI2PD_SRC
"${CMAKE_SOURCE_DIR}/Config.cpp" "${CMAKE_SOURCE_DIR}/Config.cpp"
"${CMAKE_SOURCE_DIR}/Crypto.cpp" "${CMAKE_SOURCE_DIR}/Crypto.cpp"
"${CMAKE_SOURCE_DIR}/Garlic.cpp" "${CMAKE_SOURCE_DIR}/Garlic.cpp"
"${CMAKE_SOURCE_DIR}/Gzip.cpp"
"${CMAKE_SOURCE_DIR}/I2NPProtocol.cpp" "${CMAKE_SOURCE_DIR}/I2NPProtocol.cpp"
"${CMAKE_SOURCE_DIR}/Identity.cpp" "${CMAKE_SOURCE_DIR}/Identity.cpp"
"${CMAKE_SOURCE_DIR}/LeaseSet.cpp" "${CMAKE_SOURCE_DIR}/LeaseSet.cpp"

1
debian/control vendored

@ -8,6 +8,7 @@ Build-Depends: debhelper (>= 9.0.0), dpkg-dev (>= 1.16.1~),
libboost-date-time-dev, libboost-date-time-dev,
libboost-filesystem-dev, libboost-filesystem-dev,
libboost-program-options-dev, libboost-program-options-dev,
libminiupnpc-dev,
libssl-dev libssl-dev
Standards-Version: 3.9.3 Standards-Version: 3.9.3
Homepage: https://github.com/PurpleI2P/i2pd Homepage: https://github.com/PurpleI2P/i2pd

7
debian/patches/0001-disable-aesni-by-default.patch → debian/patches/01-tune-build-opts.patch vendored

@ -1,13 +1,16 @@
diff --git a/Makefile b/Makefile diff --git a/Makefile b/Makefile
index 2e86fd8..c1037af 100644 index fe8ae7e..fc8abda 100644
--- a/Makefile --- a/Makefile
+++ b/Makefile +++ b/Makefile
@@ -9,7 +9,7 @@ DEPS := obj/make.dep @@ -9,9 +9,9 @@ DEPS := obj/make.dep
include filelist.mk include filelist.mk
-USE_AESNI := yes -USE_AESNI := yes
+USE_AESNI := no +USE_AESNI := no
USE_STATIC := no USE_STATIC := no
-USE_UPNP := no
+USE_UPNP := yes
ifeq ($(UNAME),Darwin) ifeq ($(UNAME),Darwin)
DAEMON_SRC += DaemonLinux.cpp

2
debian/patches/series vendored

@ -1 +1 @@
0001-disable-aesni-by-default.patch 01-tune-build-opts.patch

2
filelist.mk

@ -1,5 +1,5 @@
LIB_SRC = \ LIB_SRC = \
Crypto.cpp Datagram.cpp Garlic.cpp I2NPProtocol.cpp LeaseSet.cpp \ Gzip.cpp Crypto.cpp Datagram.cpp Garlic.cpp I2NPProtocol.cpp LeaseSet.cpp \
Log.cpp NTCPSession.cpp NetDb.cpp NetDbRequests.cpp Profiling.cpp \ Log.cpp NTCPSession.cpp NetDb.cpp NetDbRequests.cpp Profiling.cpp \
Reseed.cpp RouterContext.cpp RouterInfo.cpp Signature.cpp SSU.cpp \ Reseed.cpp RouterContext.cpp RouterInfo.cpp Signature.cpp SSU.cpp \
SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \ SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \

4
qt/i2pd_qt/i2pd_qt.pro

@ -36,7 +36,7 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \
../../RouterInfo.cpp ../../SAM.cpp ../../Signature.cpp ../../SOCKS.cpp ../../SSU.cpp \ ../../RouterInfo.cpp ../../SAM.cpp ../../Signature.cpp ../../SOCKS.cpp ../../SSU.cpp \
../../SSUData.cpp ../../SSUSession.cpp ../../Streaming.cpp ../../TransitTunnel.cpp \ ../../SSUData.cpp ../../SSUSession.cpp ../../Streaming.cpp ../../TransitTunnel.cpp \
../../Transports.cpp ../../Tunnel.cpp ../../TunnelEndpoint.cpp ../../TunnelGateway.cpp \ ../../Transports.cpp ../../Tunnel.cpp ../../TunnelEndpoint.cpp ../../TunnelGateway.cpp \
../../TunnelPool.cpp ../../UPnP.cpp ../../util.cpp ../../i2pd.cpp ../../TunnelPool.cpp ../../UPnP.cpp ../../util.cpp ../../Gzip.cpp ../../i2pd.cpp
HEADERS += DaemonQT.h mainwindow.h \ HEADERS += DaemonQT.h mainwindow.h \
../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \ ../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \
@ -50,7 +50,7 @@ HEADERS += DaemonQT.h mainwindow.h \
../../Streaming.h ../../Timestamp.h ../../TransitTunnel.h ../../Transports.h \ ../../Streaming.h ../../Timestamp.h ../../TransitTunnel.h ../../Transports.h \
../../TransportSession.h ../../Tunnel.h ../../TunnelBase.h ../../TunnelConfig.h \ ../../TransportSession.h ../../Tunnel.h ../../TunnelBase.h ../../TunnelConfig.h \
../../TunnelEndpoint.h ../../TunnelGateway.h ../../TunnelPool.h ../../UPnP.h \ ../../TunnelEndpoint.h ../../TunnelGateway.h ../../TunnelPool.h ../../UPnP.h \
../../util.h ../../version.h ../../util.h ../../version.h ..//../Gzip.h ../../Tag.h
FORMS += mainwindow.ui FORMS += mainwindow.ui

7
tests/Makefile

@ -1,11 +1,14 @@
CXXFLAGS += -Wall -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 CXXFLAGS += -Wall -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1
TESTS = test-http-url test-http-req test-http-res test-http-url_decode \ TESTS = test-http-url test-http-req test-http-res test-http-url_decode \
test-http-merge_chunked test-http-merge_chunked test-base-64
all: $(TESTS) run all: $(TESTS) run
test-http-%: test-http-%.cpp ../HTTP.cpp test-http-%: ../HTTP.cpp test-http-%.cpp
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^
test-base-%: ../Base.cpp test-base-%.cpp
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^
run: $(TESTS) run: $(TESTS)

45
tests/test-base-64.cpp

@ -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;
}

5
tests/test-http-req.cpp

@ -22,7 +22,6 @@ int main() {
assert(req->version == "HTTP/1.0"); assert(req->version == "HTTP/1.0");
assert(req->method == "GET"); assert(req->method == "GET");
assert(req->uri == "/"); assert(req->uri == "/");
assert(req->host == "inr.i2p");
assert(req->headers.size() == 3); assert(req->headers.size() == 3);
assert(req->headers.count("Host") == 1); assert(req->headers.count("Host") == 1);
assert(req->headers.count("Accept") == 1); assert(req->headers.count("Accept") == 1);
@ -42,7 +41,6 @@ int main() {
assert(req->version == "HTTP/1.0"); assert(req->version == "HTTP/1.0");
assert(req->method == "GET"); assert(req->method == "GET");
assert(req->uri == "/"); assert(req->uri == "/");
assert(req->host == "");
assert(req->headers.size() == 0); assert(req->headers.size() == 0);
delete req; delete req;
@ -52,7 +50,7 @@ int main() {
"\r\n"; "\r\n";
len = strlen(buf); len = strlen(buf);
req = new HTTPReq; req = new HTTPReq;
assert((ret = req->parse(buf, len)) == -1); /* no host header */ assert((ret = req->parse(buf, len)) > 0);
delete req; delete req;
/* test: parsing incomplete request */ /* test: parsing incomplete request */
@ -76,7 +74,6 @@ int main() {
assert((ret = req->parse(buf, len)) == len); /* no host header */ assert((ret = req->parse(buf, len)) == len); /* no host header */
assert(req->method == "GET"); assert(req->method == "GET");
assert(req->uri == "http://inr.i2p"); assert(req->uri == "http://inr.i2p");
assert(req->host == "stats.i2p");
assert(req->headers.size() == 3); assert(req->headers.size() == 3);
assert(req->headers.count("Host") == 1); assert(req->headers.count("Host") == 1);
assert(req->headers.count("Accept") == 1); assert(req->headers.count("Accept") == 1);

Loading…
Cancel
Save