Browse Source

Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl

pull/323/head
orignal 9 years ago
parent
commit
a85d3f2573
  1. 62
      ClientContext.cpp
  2. 8
      ClientContext.h
  3. 16
      Transports.cpp
  4. 1
      Transports.h
  5. 138
      docs/build_notes_unix.md

62
ClientContext.cpp

@ -40,7 +40,11 @@ namespace client
// proxies // proxies
std::string proxyKeys = i2p::util::config::GetArg("-proxykeys", ""); std::string proxyKeys = i2p::util::config::GetArg("-proxykeys", "");
if (proxyKeys.length () > 0) if (proxyKeys.length () > 0)
localDestination = LoadLocalDestination (proxyKeys, false); {
i2p::data::PrivateKeys keys;
LoadPrivateKeys (keys, proxyKeys);
localDestination = CreateNewLocalDestination (keys, false);
}
LogPrint(eLogInfo, "Clients: starting HTTP Proxy"); LogPrint(eLogInfo, "Clients: starting HTTP Proxy");
m_HttpProxy = new i2p::proxy::HTTPProxy(i2p::util::config::GetArg("-httpproxyaddress", "127.0.0.1"), i2p::util::config::GetArg("-httpproxyport", 4446), localDestination); m_HttpProxy = new i2p::proxy::HTTPProxy(i2p::util::config::GetArg("-httpproxyaddress", "127.0.0.1"), i2p::util::config::GetArg("-httpproxyport", 4446), localDestination);
m_HttpProxy->Start(); m_HttpProxy->Start();
@ -122,10 +126,8 @@ namespace client
m_SharedLocalDestination = nullptr; m_SharedLocalDestination = nullptr;
} }
std::shared_ptr<ClientDestination> ClientContext::LoadLocalDestination (const std::string& filename, void ClientContext::LoadPrivateKeys (i2p::data::PrivateKeys& keys, const std::string& filename, i2p::data::SigningKeyType sigType)
bool isPublic, i2p::data::SigningKeyType sigType, const std::map<std::string, std::string> * params)
{ {
i2p::data::PrivateKeys keys;
std::string fullPath = i2p::util::filesystem::GetFullPath (filename); std::string fullPath = i2p::util::filesystem::GetFullPath (filename);
std::ifstream s(fullPath.c_str (), std::ifstream::binary); std::ifstream s(fullPath.c_str (), std::ifstream::binary);
if (s.is_open ()) if (s.is_open ())
@ -152,22 +154,6 @@ namespace client
LogPrint (eLogInfo, "Clients: New private keys file ", fullPath, " for ", m_AddressBook.ToAddress(keys.GetPublic ()->GetIdentHash ()), " created"); LogPrint (eLogInfo, "Clients: New private keys file ", fullPath, " for ", m_AddressBook.ToAddress(keys.GetPublic ()->GetIdentHash ()), " created");
} }
std::shared_ptr<ClientDestination> localDestination = nullptr;
std::unique_lock<std::mutex> l(m_DestinationsMutex);
auto it = m_Destinations.find (keys.GetPublic ()->GetIdentHash ());
if (it != m_Destinations.end ())
{
LogPrint (eLogWarning, "Clients: Local destination ", m_AddressBook.ToAddress(keys.GetPublic ()->GetIdentHash ()), " already exists");
localDestination = it->second;
}
else
{
localDestination = std::make_shared<ClientDestination> (keys, isPublic, params);
m_Destinations[localDestination->GetIdentHash ()] = localDestination;
localDestination->Start ();
}
return localDestination;
} }
std::shared_ptr<ClientDestination> ClientContext::CreateNewLocalDestination (bool isPublic, i2p::data::SigningKeyType sigType, std::shared_ptr<ClientDestination> ClientContext::CreateNewLocalDestination (bool isPublic, i2p::data::SigningKeyType sigType,
@ -225,7 +211,21 @@ namespace client
return nullptr; return nullptr;
} }
// should be moved in i2p::utils::fs template<typename Section, typename Type>
std::string ClientContext::GetI2CPOption (const Section& section, const std::string& name, const Type& value) const
{
return section.second.get (boost::property_tree::ptree::path_type (name, '/'), std::to_string (value));
}
template<typename Section>
void ClientContext::ReadI2CPOptions (const Section& section, std::map<std::string, std::string>& options) const
{
options[I2CP_PARAM_INBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNEL_LENGTH, DEFAULT_INBOUND_TUNNEL_LENGTH);
options[I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH, DEFAULT_OUTBOUND_TUNNEL_LENGTH);
options[I2CP_PARAM_INBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNELS_QUANTITY, DEFAULT_INBOUND_TUNNELS_QUANTITY);
options[I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY, DEFAULT_OUTBOUND_TUNNELS_QUANTITY);
}
void ClientContext::ReadTunnels () void ClientContext::ReadTunnels ()
{ {
boost::property_tree::ptree pt; boost::property_tree::ptree pt;
@ -259,14 +259,15 @@ namespace client
i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
// I2CP // I2CP
std::map<std::string, std::string> options; std::map<std::string, std::string> options;
options[I2CP_PARAM_INBOUND_TUNNEL_LENGTH] = section.second.get (decltype (pt)::path_type (I2CP_PARAM_INBOUND_TUNNEL_LENGTH, '/'), std::to_string (DEFAULT_INBOUND_TUNNEL_LENGTH)); ReadI2CPOptions (section, options);
options[I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH] = section.second.get (decltype (pt)::path_type (I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH, '/'), std::to_string (DEFAULT_OUTBOUND_TUNNEL_LENGTH));
options[I2CP_PARAM_INBOUND_TUNNELS_QUANTITY] = section.second.get (decltype (pt)::path_type (I2CP_PARAM_INBOUND_TUNNELS_QUANTITY, '/'), std::to_string (DEFAULT_INBOUND_TUNNELS_QUANTITY));
options[I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY] = section.second.get (decltype (pt)::path_type (I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY, '/'), std::to_string (DEFAULT_OUTBOUND_TUNNELS_QUANTITY));
std::shared_ptr<ClientDestination> localDestination = nullptr; std::shared_ptr<ClientDestination> localDestination = nullptr;
if (keys.length () > 0) if (keys.length () > 0)
localDestination = LoadLocalDestination (keys, false, sigType, &options); {
i2p::data::PrivateKeys k;
LoadPrivateKeys (k, keys, sigType);
localDestination = CreateNewLocalDestination (k, false, &options);
}
auto clientTunnel = new I2PClientTunnel (name, dest, address, port, localDestination, destinationPort); auto clientTunnel = new I2PClientTunnel (name, dest, address, port, localDestination, destinationPort);
if (m_ClientTunnels.insert (std::make_pair (port, std::unique_ptr<I2PClientTunnel>(clientTunnel))).second) if (m_ClientTunnels.insert (std::make_pair (port, std::unique_ptr<I2PClientTunnel>(clientTunnel))).second)
clientTunnel->Start (); clientTunnel->Start ();
@ -286,12 +287,11 @@ namespace client
i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
// I2CP // I2CP
std::map<std::string, std::string> options; std::map<std::string, std::string> options;
options[I2CP_PARAM_INBOUND_TUNNEL_LENGTH] = section.second.get (decltype (pt)::path_type (I2CP_PARAM_INBOUND_TUNNEL_LENGTH, '/'), std::to_string (DEFAULT_INBOUND_TUNNEL_LENGTH)); ReadI2CPOptions (section, options);
options[I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH] = section.second.get (decltype (pt)::path_type (I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH, '/'), std::to_string (DEFAULT_OUTBOUND_TUNNEL_LENGTH));
options[I2CP_PARAM_INBOUND_TUNNELS_QUANTITY] = section.second.get (decltype (pt)::path_type (I2CP_PARAM_INBOUND_TUNNELS_QUANTITY, '/'), std::to_string (DEFAULT_INBOUND_TUNNELS_QUANTITY));
options[I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY] = section.second.get (decltype (pt)::path_type (I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY, '/'), std::to_string (DEFAULT_OUTBOUND_TUNNELS_QUANTITY));
auto localDestination = LoadLocalDestination (keys, true, sigType, &options); i2p::data::PrivateKeys k;
LoadPrivateKeys (k, keys, sigType);
auto localDestination = CreateNewLocalDestination (k, true, &options);
I2PServerTunnel * serverTunnel = (type == I2P_TUNNELS_SECTION_TYPE_HTTP) ? I2PServerTunnel * serverTunnel = (type == I2P_TUNNELS_SECTION_TYPE_HTTP) ?
new I2PServerTunnelHTTP (name, host, port, localDestination, inPort) : new I2PServerTunnelHTTP (name, host, port, localDestination, inPort) :
new I2PServerTunnel (name, host, port, localDestination, inPort); new I2PServerTunnel (name, host, port, localDestination, inPort);

8
ClientContext.h

@ -50,9 +50,7 @@ namespace client
const std::map<std::string, std::string> * params = nullptr); const std::map<std::string, std::string> * params = nullptr);
void DeleteLocalDestination (std::shared_ptr<ClientDestination> destination); void DeleteLocalDestination (std::shared_ptr<ClientDestination> destination);
std::shared_ptr<ClientDestination> FindLocalDestination (const i2p::data::IdentHash& destination) const; std::shared_ptr<ClientDestination> FindLocalDestination (const i2p::data::IdentHash& destination) const;
std::shared_ptr<ClientDestination> LoadLocalDestination (const std::string& filename, bool isPublic, void LoadPrivateKeys (i2p::data::PrivateKeys& keys, const std::string& filename, i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256,
const std::map<std::string, std::string> * params = nullptr);
AddressBook& GetAddressBook () { return m_AddressBook; }; AddressBook& GetAddressBook () { return m_AddressBook; };
const SAMBridge * GetSAMBridge () const { return m_SamBridge; }; const SAMBridge * GetSAMBridge () const { return m_SamBridge; };
@ -60,6 +58,10 @@ namespace client
private: private:
void ReadTunnels (); void ReadTunnels ();
template<typename Section, typename Type>
std::string GetI2CPOption (const Section& section, const std::string& name, const Type& value) const;
template<typename Section>
void ReadI2CPOptions (const Section& section, std::map<std::string, std::string>& options) const;
private: private:

16
Transports.cpp

@ -231,8 +231,11 @@ namespace transport
try try
{ {
auto r = netdb.FindRouter (ident); auto r = netdb.FindRouter (ident);
{
std::unique_lock<std::mutex> l(m_PeersMutex);
it = m_Peers.insert (std::pair<i2p::data::IdentHash, Peer>(ident, { 0, r, {}, it = m_Peers.insert (std::pair<i2p::data::IdentHash, Peer>(ident, { 0, r, {},
i2p::util::GetSecondsSinceEpoch (), {} })).first; i2p::util::GetSecondsSinceEpoch (), {} })).first;
}
connected = ConnectToPeer (ident, it->second); connected = ConnectToPeer (ident, it->second);
} }
catch (std::exception& ex) catch (std::exception& ex)
@ -318,6 +321,7 @@ namespace transport
} }
LogPrint (eLogError, "Transports: No NTCP or SSU addresses available"); LogPrint (eLogError, "Transports: No NTCP or SSU addresses available");
peer.Done (); peer.Done ();
std::unique_lock<std::mutex> l(m_PeersMutex);
m_Peers.erase (ident); m_Peers.erase (ident);
return false; return false;
} }
@ -349,6 +353,7 @@ namespace transport
else else
{ {
LogPrint (eLogError, "Transports: RouterInfo not found, Failed to send messages"); LogPrint (eLogError, "Transports: RouterInfo not found, Failed to send messages");
std::unique_lock<std::mutex> l(m_PeersMutex);
m_Peers.erase (it); m_Peers.erase (it);
} }
} }
@ -382,6 +387,7 @@ namespace transport
} }
} }
LogPrint (eLogError, "Transports: Unable to resolve NTCP address: ", ecode.message ()); LogPrint (eLogError, "Transports: Unable to resolve NTCP address: ", ecode.message ());
std::unique_lock<std::mutex> l(m_PeersMutex);
m_Peers.erase (it1); m_Peers.erase (it1);
} }
} }
@ -413,6 +419,7 @@ namespace transport
} }
} }
LogPrint (eLogError, "Transports: Unable to resolve SSU address: ", ecode.message ()); LogPrint (eLogError, "Transports: Unable to resolve SSU address: ", ecode.message ());
std::unique_lock<std::mutex> l(m_PeersMutex);
m_Peers.erase (it1); m_Peers.erase (it1);
} }
} }
@ -502,7 +509,10 @@ namespace transport
it->second.delayedMessages.clear (); it->second.delayedMessages.clear ();
} }
else // incoming connection else // incoming connection
{
std::unique_lock<std::mutex> l(m_PeersMutex);
m_Peers.insert (std::make_pair (ident, Peer{ 0, nullptr, { session }, i2p::util::GetSecondsSinceEpoch (), {} })); m_Peers.insert (std::make_pair (ident, Peer{ 0, nullptr, { session }, i2p::util::GetSecondsSinceEpoch (), {} }));
}
}); });
} }
@ -521,14 +531,18 @@ namespace transport
if (it->second.delayedMessages.size () > 0) if (it->second.delayedMessages.size () > 0)
ConnectToPeer (ident, it->second); ConnectToPeer (ident, it->second);
else else
{
std::unique_lock<std::mutex> l(m_PeersMutex);
m_Peers.erase (it); m_Peers.erase (it);
} }
} }
}
}); });
} }
bool Transports::IsConnected (const i2p::data::IdentHash& ident) const bool Transports::IsConnected (const i2p::data::IdentHash& ident) const
{ {
std::unique_lock<std::mutex> l(m_PeersMutex);
auto it = m_Peers.find (ident); auto it = m_Peers.find (ident);
return it != m_Peers.end (); return it != m_Peers.end ();
} }
@ -543,6 +557,7 @@ namespace transport
if (it->second.sessions.empty () && ts > it->second.creationTime + SESSION_CREATION_TIMEOUT) if (it->second.sessions.empty () && ts > it->second.creationTime + SESSION_CREATION_TIMEOUT)
{ {
LogPrint (eLogWarning, "Transports: Session to peer ", it->first.ToBase64 (), " has not been created in ", SESSION_CREATION_TIMEOUT, " seconds"); LogPrint (eLogWarning, "Transports: Session to peer ", it->first.ToBase64 (), " has not been created in ", SESSION_CREATION_TIMEOUT, " seconds");
std::unique_lock<std::mutex> l(m_PeersMutex);
it = m_Peers.erase (it); it = m_Peers.erase (it);
} }
else else
@ -559,6 +574,7 @@ namespace transport
std::shared_ptr<const i2p::data::RouterInfo> Transports::GetRandomPeer () const std::shared_ptr<const i2p::data::RouterInfo> Transports::GetRandomPeer () const
{ {
if (!m_Peers.size ()) return nullptr; if (!m_Peers.size ()) return nullptr;
std::unique_lock<std::mutex> l(m_PeersMutex);
auto it = m_Peers.begin (); auto it = m_Peers.begin ();
std::advance (it, rand () % m_Peers.size ()); std::advance (it, rand () % m_Peers.size ());
return it != m_Peers.end () ? it->second.router : nullptr; return it != m_Peers.end () ? it->second.router : nullptr;

1
Transports.h

@ -132,6 +132,7 @@ namespace transport
NTCPServer * m_NTCPServer; NTCPServer * m_NTCPServer;
SSUServer * m_SSUServer; SSUServer * m_SSUServer;
mutable std::mutex m_PeersMutex;
std::map<i2p::data::IdentHash, Peer> m_Peers; std::map<i2p::data::IdentHash, Peer> m_Peers;
DHKeysPairSupplier m_DHKeysPairSupplier; DHKeysPairSupplier m_DHKeysPairSupplier;

138
docs/build_notes_unix.md

@ -1,46 +1,90 @@
Building on Unix systems Building on Unix systems
============================= =============================
Common build/install process from sources: First of all we need to make sure that all dependencies are satisfied.
* git clone https://github.com/PurpleI2P/i2pd.git This doc is trying to cover:
* mkdir -p 'i2pd/build/tmp' && cd 'i2pd/build/tmp' * [Debian/Ubuntu](#debianubuntu) (contains packaging instructions)
* cmake -DCMAKE_BUILD_TYPE=Release <more options> .. * [Fedora/Centos](#fedoracentos)
* make * [FreeBSD](#freebsd)
* make install
Available cmake options: Make sure you have all required dependencies for your system successfully installed.
* CMAKE_BUILD_TYPE -- build profile (Debug/Release) If so then we are ready to go!
* WITH_AESNI -- AES-NI support (ON/OFF) Let's clone the repository and start building the i2pd:
* WITH_HARDENING -- enable hardening features (ON/OFF) (gcc only) ```bash
* WITH_BINARY -- build i2pd itself git clone https://github.com/PurpleI2P/i2pd.git
* WITH_LIBRARY -- build libi2pd cd i2pd/build
* WITH_STATIC -- build static versions of library and i2pd binary cmake -DCMAKE_BUILD_TYPE=Release # more options could be passed, see "CMake Options"
* WITH_UPNP -- build with UPnP support (requires libupnp) make
* WITH_PCH -- use pre-compiled header (experimental, speeds up build) ```
After successfull build i2pd could be installed with:
```bash
make install
```
Debian/Ubuntu Debian/Ubuntu
------------- -------------
For building from source on debian system you will need the following "-dev" packages: You will need a compiler and other tools that could be installed with `build-essential` package:
```bash
* libboost-chrono-dev sudo apt-get install build-essential
* libboost-date-time-dev ```
* libboost-filesystem-dev
* libboost-program-options-dev Also you will need a bunch of development libraries:
* libboost-regex-dev ```bash
* libboost-system-dev sudo apt-get install \
* libboost-thread-dev libboost-chrono-dev \
* libssl-dev (e.g. openssl) libboost-date-time-dev \
* zlib1g-dev (libssl-dev already depends on it) libboost-filesystem-dev \
* libminiupnpc-dev (optional, if WITH_UPNP=ON) libboost-program-options-dev \
libboost-regex-dev \
libboost-system-dev \
libboost-thread-dev \
libssl-dev
```
If you need UPnP support (don't forget to run CMake with `WITH_UPNP=ON`) miniupnpc development library should be installed:
```bash
sudo apt-get install libminiupnpc-dev
```
You may also build deb-package with the following: You may also build deb-package with the following:
```bash
apt-get install build-essential fakeroot devscripts sudo apt-get install fakeroot devscripts
cd i2pd cd i2pd
debuild --no-tgz-check # building from git repo debuild --no-tgz-check
```
Fedora/Centos
-------------
You will need a compiler and other tools to perform a build:
```bash
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
```
If you need UPnP support (don't forget to run CMake with `WITH_UPNP=ON`) miniupnpc development library should be installed:
```bash
miniupnpc-devel
```
FreeBSD FreeBSD
------- -------
@ -49,17 +93,35 @@ Branch 9.X has gcc v4.2, that knows nothing about required c++11 standart.
Required ports: Required ports:
* devel/cmake * `devel/cmake`
* devel/boost-libs * `devel/boost-libs`
* lang/gcc47 # or later version * `lang/gcc47`(or later version)
To use newer compiler you should set these variables:
To use newer compiler you should set these variables(replace "47" with your actual gcc version):
```bash
export CC=/usr/local/bin/gcc47 export CC=/usr/local/bin/gcc47
export CXX=/usr/local/bin/g++47 export CXX=/usr/local/bin/g++47
```
Replace "47" with your actual gcc version
Branch 10.X has more reliable clang version, that can finally build i2pd, Branch 10.X has more reliable clang version, that can finally build i2pd,
but i still recommend to use gcc, otherwise you will fight it's bugs by but I still recommend to use gcc, otherwise you will fight it's bugs by
your own. your own.
CMake Options
-------------
Available CMake options(each option has a for of `<key>=<value>`, for more information see `man 1 cmake`):
* `CMAKE_BUILD_TYPE` build profile (Debug/Release)
* `WITH_BINARY` build i2pd itself
* `WITH_LIBRARY` build libi2pd
* `WITH_STATIC` build static versions of library and i2pd binary
* `WITH_UPNP` build with UPnP support (requires libupnp)
* `WITH_AESNI` build with AES-NI support (ON/OFF)
* `WITH_HARDENING` enable hardening features (ON/OFF) (gcc only)
* `WITH_PCH` use pre-compiled header (experimental, speeds up build)
Also there is `-L` flag for CMake that could be used to list current cached options:
```bash
cmake -L
```

Loading…
Cancel
Save