mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-02-07 07:44:13 +00:00
Merge remote-tracking branch 'purple/openssl' into fix-ntcp-threading-race
This commit is contained in:
commit
ff5c26adf2
6
Makefile
6
Makefile
@ -30,12 +30,12 @@ ifneq (, $(findstring darwin, $(SYS)))
|
|||||||
else
|
else
|
||||||
include Makefile.osx
|
include Makefile.osx
|
||||||
endif
|
endif
|
||||||
|
else ifneq (, $(findstring linux, $(SYS))$(findstring gnu, $(SYS)))
|
||||||
|
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
||||||
|
include Makefile.linux
|
||||||
else ifneq (, $(findstring freebsd, $(SYS))$(findstring openbsd, $(SYS)))
|
else ifneq (, $(findstring freebsd, $(SYS))$(findstring openbsd, $(SYS)))
|
||||||
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
||||||
include Makefile.bsd
|
include Makefile.bsd
|
||||||
else ifneq (, $(findstring linux, $(SYS)))
|
|
||||||
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
|
||||||
include Makefile.linux
|
|
||||||
else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS)))
|
else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS)))
|
||||||
DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32Service.cpp Win32/Win32App.cpp
|
DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32Service.cpp Win32/Win32App.cpp
|
||||||
include Makefile.mingw
|
include Makefile.mingw
|
||||||
|
@ -94,13 +94,17 @@ endif()
|
|||||||
|
|
||||||
add_library(libi2pd ${LIBI2PD_SRC})
|
add_library(libi2pd ${LIBI2PD_SRC})
|
||||||
set_target_properties(libi2pd PROPERTIES PREFIX "")
|
set_target_properties(libi2pd PROPERTIES PREFIX "")
|
||||||
install(TARGETS libi2pd
|
|
||||||
EXPORT libi2pd
|
if (WITH_LIBRARY)
|
||||||
ARCHIVE DESTINATION lib
|
install(TARGETS libi2pd
|
||||||
COMPONENT Libraries)
|
EXPORT libi2pd
|
||||||
|
ARCHIVE DESTINATION lib
|
||||||
|
LIBRARY DESTINATION lib
|
||||||
|
COMPONENT Libraries)
|
||||||
# TODO Make libi2pd available to 3rd party projects via CMake as imported target
|
# TODO Make libi2pd available to 3rd party projects via CMake as imported target
|
||||||
# FIXME This pulls stdafx
|
# FIXME This pulls stdafx
|
||||||
# install(EXPORT libi2pd DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
# install(EXPORT libi2pd DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
set (CLIENT_SRC
|
set (CLIENT_SRC
|
||||||
"${LIBI2PD_CLIENT_SRC_DIR}/AddressBook.cpp"
|
"${LIBI2PD_CLIENT_SRC_DIR}/AddressBook.cpp"
|
||||||
@ -119,7 +123,17 @@ set (CLIENT_SRC
|
|||||||
if(WITH_WEBSOCKETS)
|
if(WITH_WEBSOCKETS)
|
||||||
list (APPEND CLIENT_SRC "${LIBI2PD_CLIENT_SRC_DIR}/Websocket.cpp")
|
list (APPEND CLIENT_SRC "${LIBI2PD_CLIENT_SRC_DIR}/Websocket.cpp")
|
||||||
endif ()
|
endif ()
|
||||||
add_library(i2pdclient ${CLIENT_SRC})
|
|
||||||
|
add_library(libi2pdclient ${CLIENT_SRC})
|
||||||
|
set_target_properties(libi2pdclient PROPERTIES PREFIX "")
|
||||||
|
|
||||||
|
if (WITH_LIBRARY)
|
||||||
|
install(TARGETS libi2pdclient
|
||||||
|
EXPORT libi2pdclient
|
||||||
|
ARCHIVE DESTINATION lib
|
||||||
|
LIBRARY DESTINATION lib
|
||||||
|
COMPONENT Libraries)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(DAEMON_SRC_DIR ../daemon)
|
set(DAEMON_SRC_DIR ../daemon)
|
||||||
|
|
||||||
@ -303,7 +317,7 @@ if (WITH_PCH)
|
|||||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||||
)
|
)
|
||||||
target_compile_options(libi2pd PRIVATE /FIstdafx.h /Yustdafx.h /Zm155 "/Fp${CMAKE_BINARY_DIR}/stdafx.dir/$<CONFIG>/stdafx.pch")
|
target_compile_options(libi2pd PRIVATE /FIstdafx.h /Yustdafx.h /Zm155 "/Fp${CMAKE_BINARY_DIR}/stdafx.dir/$<CONFIG>/stdafx.pch")
|
||||||
target_compile_options(i2pdclient PRIVATE /FIstdafx.h /Yustdafx.h /Zm155 "/Fp${CMAKE_BINARY_DIR}/stdafx.dir/$<CONFIG>/stdafx.pch")
|
target_compile_options(libi2pdclient PRIVATE /FIstdafx.h /Yustdafx.h /Zm155 "/Fp${CMAKE_BINARY_DIR}/stdafx.dir/$<CONFIG>/stdafx.pch")
|
||||||
else()
|
else()
|
||||||
string(TOUPPER ${CMAKE_BUILD_TYPE} BTU)
|
string(TOUPPER ${CMAKE_BUILD_TYPE} BTU)
|
||||||
get_directory_property(DEFS DEFINITIONS)
|
get_directory_property(DEFS DEFINITIONS)
|
||||||
@ -312,12 +326,12 @@ if (WITH_PCH)
|
|||||||
COMMAND ${CMAKE_CXX_COMPILER} ${FLAGS} -c ${CMAKE_CURRENT_SOURCE_DIR}/../libi2pd/stdafx.h -o ${CMAKE_BINARY_DIR}/stdafx.h.gch
|
COMMAND ${CMAKE_CXX_COMPILER} ${FLAGS} -c ${CMAKE_CURRENT_SOURCE_DIR}/../libi2pd/stdafx.h -o ${CMAKE_BINARY_DIR}/stdafx.h.gch
|
||||||
)
|
)
|
||||||
target_compile_options(libi2pd PRIVATE -include libi2pd/stdafx.h)
|
target_compile_options(libi2pd PRIVATE -include libi2pd/stdafx.h)
|
||||||
target_compile_options(i2pdclient PRIVATE -include libi2pd/stdafx.h)
|
target_compile_options(libi2pdclient PRIVATE -include libi2pd/stdafx.h)
|
||||||
endif()
|
endif()
|
||||||
target_link_libraries(libi2pd stdafx)
|
target_link_libraries(libi2pd stdafx)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(i2pdclient libi2pd)
|
target_link_libraries(libi2pdclient libi2pd)
|
||||||
|
|
||||||
find_package ( Boost COMPONENTS system filesystem program_options date_time REQUIRED )
|
find_package ( Boost COMPONENTS system filesystem program_options date_time REQUIRED )
|
||||||
if(NOT DEFINED Boost_INCLUDE_DIRS)
|
if(NOT DEFINED Boost_INCLUDE_DIRS)
|
||||||
@ -450,7 +464,7 @@ if (WITH_BINARY)
|
|||||||
if (WITH_STATIC)
|
if (WITH_STATIC)
|
||||||
set(DL_LIB ${CMAKE_DL_LIBS})
|
set(DL_LIB ${CMAKE_DL_LIBS})
|
||||||
endif()
|
endif()
|
||||||
target_link_libraries( "${PROJECT_NAME}" libi2pd i2pdclient ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES})
|
target_link_libraries( "${PROJECT_NAME}" libi2pd libi2pdclient ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES})
|
||||||
|
|
||||||
install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime)
|
install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime)
|
||||||
set (APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
|
set (APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
|
||||||
|
@ -8,6 +8,8 @@ User=i2pd
|
|||||||
Group=i2pd
|
Group=i2pd
|
||||||
RuntimeDirectory=i2pd
|
RuntimeDirectory=i2pd
|
||||||
RuntimeDirectoryMode=0700
|
RuntimeDirectoryMode=0700
|
||||||
|
LogsDirectory=i2pd
|
||||||
|
LogsDirectoryMode=0700
|
||||||
Type=simple
|
Type=simple
|
||||||
ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --pidfile=/var/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service
|
ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --pidfile=/var/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service
|
||||||
ExecReload=/bin/kill -HUP $MAINPID
|
ExecReload=/bin/kill -HUP $MAINPID
|
||||||
|
@ -65,6 +65,7 @@ namespace client
|
|||||||
m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler;
|
m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler;
|
||||||
m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler;
|
m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler;
|
||||||
m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler;
|
m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler;
|
||||||
|
m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler;
|
||||||
|
|
||||||
// I2PControl
|
// I2PControl
|
||||||
m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler;
|
m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler;
|
||||||
@ -92,6 +93,14 @@ namespace client
|
|||||||
// NetworkSetting
|
// NetworkSetting
|
||||||
m_NetworkSettingHandlers["i2p.router.net.bw.in"] = &I2PControlService::InboundBandwidthLimit;
|
m_NetworkSettingHandlers["i2p.router.net.bw.in"] = &I2PControlService::InboundBandwidthLimit;
|
||||||
m_NetworkSettingHandlers["i2p.router.net.bw.out"] = &I2PControlService::OutboundBandwidthLimit;
|
m_NetworkSettingHandlers["i2p.router.net.bw.out"] = &I2PControlService::OutboundBandwidthLimit;
|
||||||
|
|
||||||
|
// ClientServicesInfo
|
||||||
|
m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlService::I2PTunnelInfoHandler;
|
||||||
|
m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlService::HTTPProxyInfoHandler;
|
||||||
|
m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler;
|
||||||
|
m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler;
|
||||||
|
m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler;
|
||||||
|
m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
I2PControlService::~I2PControlService ()
|
I2PControlService::~I2PControlService ()
|
||||||
@ -289,6 +298,13 @@ namespace client
|
|||||||
ss << "\"" << name << "\":" << std::fixed << std::setprecision(2) << value;
|
ss << "\"" << name << "\":" << std::fixed << std::setprecision(2) << value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void I2PControlService::InsertParam (std::ostringstream& ss, const std::string& name, const boost::property_tree::ptree& value) const
|
||||||
|
{
|
||||||
|
std::ostringstream buf;
|
||||||
|
boost::property_tree::write_json (buf, value, false);
|
||||||
|
ss << "\"" << name << "\":" << buf.str();
|
||||||
|
}
|
||||||
|
|
||||||
void I2PControlService::SendResponse (std::shared_ptr<ssl_socket> socket,
|
void I2PControlService::SendResponse (std::shared_ptr<ssl_socket> socket,
|
||||||
std::shared_ptr<I2PControlBuffer> buf, std::ostringstream& response, bool isHtml)
|
std::shared_ptr<I2PControlBuffer> buf, std::ostringstream& response, bool isHtml)
|
||||||
{
|
{
|
||||||
@ -457,6 +473,7 @@ namespace client
|
|||||||
InsertParam (results, "i2p.router.net.total.sent.bytes", (double)i2p::transport::transports.GetTotalSentBytes ());
|
InsertParam (results, "i2p.router.net.total.sent.bytes", (double)i2p::transport::transports.GetTotalSentBytes ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// RouterManager
|
// RouterManager
|
||||||
|
|
||||||
void I2PControlService::RouterManagerHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
void I2PControlService::RouterManagerHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
||||||
@ -586,5 +603,178 @@ namespace client
|
|||||||
}
|
}
|
||||||
EVP_PKEY_free (pkey);
|
EVP_PKEY_free (pkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClientServicesInfo
|
||||||
|
|
||||||
|
void I2PControlService::ClientServicesInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
||||||
|
{
|
||||||
|
for (auto it = params.begin (); it != params.end (); it++)
|
||||||
|
{
|
||||||
|
LogPrint (eLogDebug, "I2PControl: ClientServicesInfo request: ", it->first);
|
||||||
|
auto it1 = m_ClientServicesInfoHandlers.find (it->first);
|
||||||
|
if (it1 != m_ClientServicesInfoHandlers.end ())
|
||||||
|
{
|
||||||
|
if (it != params.begin ()) results << ",";
|
||||||
|
(this->*(it1->second))(results);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogError, "I2PControl: ClientServicesInfo unknown request ", it->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2PControlService::I2PTunnelInfoHandler (std::ostringstream& results)
|
||||||
|
{
|
||||||
|
boost::property_tree::ptree pt;
|
||||||
|
boost::property_tree::ptree client_tunnels, server_tunnels;
|
||||||
|
|
||||||
|
for (auto& it: i2p::client::context.GetClientTunnels ())
|
||||||
|
{
|
||||||
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||||
|
boost::property_tree::ptree ct;
|
||||||
|
ct.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
|
||||||
|
client_tunnels.add_child(it.second->GetName (), ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& serverTunnels = i2p::client::context.GetServerTunnels ();
|
||||||
|
if (!serverTunnels.empty ()) {
|
||||||
|
for (auto& it: serverTunnels)
|
||||||
|
{
|
||||||
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||||
|
boost::property_tree::ptree st;
|
||||||
|
st.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
|
||||||
|
st.put("port", it.second->GetLocalPort ());
|
||||||
|
server_tunnels.add_child(it.second->GetName (), st);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& clientForwards = i2p::client::context.GetClientForwards ();
|
||||||
|
if (!clientForwards.empty ())
|
||||||
|
{
|
||||||
|
for (auto& it: clientForwards)
|
||||||
|
{
|
||||||
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||||
|
boost::property_tree::ptree ct;
|
||||||
|
ct.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
|
||||||
|
client_tunnels.add_child(it.second->GetName (), ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& serverForwards = i2p::client::context.GetServerForwards ();
|
||||||
|
if (!serverForwards.empty ())
|
||||||
|
{
|
||||||
|
for (auto& it: serverForwards)
|
||||||
|
{
|
||||||
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||||
|
boost::property_tree::ptree st;
|
||||||
|
st.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
|
||||||
|
server_tunnels.add_child(it.second->GetName (), st);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pt.add_child("client", client_tunnels);
|
||||||
|
pt.add_child("server", server_tunnels);
|
||||||
|
|
||||||
|
InsertParam (results, "I2PTunnel", pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2PControlService::HTTPProxyInfoHandler (std::ostringstream& results)
|
||||||
|
{
|
||||||
|
boost::property_tree::ptree pt;
|
||||||
|
|
||||||
|
auto httpProxy = i2p::client::context.GetHttpProxy ();
|
||||||
|
if (httpProxy)
|
||||||
|
{
|
||||||
|
auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash();
|
||||||
|
pt.put("enabled", true);
|
||||||
|
pt.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pt.put("enabled", false);
|
||||||
|
|
||||||
|
InsertParam (results, "HTTPProxy", pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2PControlService::SOCKSInfoHandler (std::ostringstream& results)
|
||||||
|
{
|
||||||
|
boost::property_tree::ptree pt;
|
||||||
|
|
||||||
|
auto socksProxy = i2p::client::context.GetSocksProxy ();
|
||||||
|
if (socksProxy)
|
||||||
|
{
|
||||||
|
auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash();
|
||||||
|
pt.put("enabled", true);
|
||||||
|
pt.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pt.put("enabled", false);
|
||||||
|
|
||||||
|
InsertParam (results, "SOCKS", pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2PControlService::SAMInfoHandler (std::ostringstream& results)
|
||||||
|
{
|
||||||
|
boost::property_tree::ptree pt;
|
||||||
|
auto sam = i2p::client::context.GetSAMBridge ();
|
||||||
|
if (sam)
|
||||||
|
{
|
||||||
|
pt.put("enabled", true);
|
||||||
|
boost::property_tree::ptree sam_sessions;
|
||||||
|
for (auto& it: sam->GetSessions ())
|
||||||
|
{
|
||||||
|
boost::property_tree::ptree sam_session, sam_session_sockets;
|
||||||
|
auto& name = it.second->localDestination->GetNickname ();
|
||||||
|
auto& ident = it.second->localDestination->GetIdentHash();
|
||||||
|
sam_session.put("name", name);
|
||||||
|
sam_session.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
|
||||||
|
|
||||||
|
for (const auto& socket: it.second->ListSockets())
|
||||||
|
{
|
||||||
|
boost::property_tree::ptree stream;
|
||||||
|
stream.put("type", socket->GetSocketType ());
|
||||||
|
stream.put("peer", socket->GetSocket ().remote_endpoint());
|
||||||
|
|
||||||
|
sam_session_sockets.push_back(std::make_pair("", stream));
|
||||||
|
}
|
||||||
|
sam_session.add_child("sockets", sam_session_sockets);
|
||||||
|
sam_sessions.add_child(it.first, sam_session);
|
||||||
|
}
|
||||||
|
|
||||||
|
pt.add_child("sessions", sam_sessions);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pt.put("enabled", false);
|
||||||
|
|
||||||
|
InsertParam (results, "SAM", pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2PControlService::BOBInfoHandler (std::ostringstream& results)
|
||||||
|
{
|
||||||
|
boost::property_tree::ptree pt;
|
||||||
|
auto bob = i2p::client::context.GetBOBCommandChannel ();
|
||||||
|
if (bob)
|
||||||
|
{
|
||||||
|
/* TODO more info */
|
||||||
|
pt.put("enabled", true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pt.put("enabled", false);
|
||||||
|
|
||||||
|
InsertParam (results, "BOB", pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2PControlService::I2CPInfoHandler (std::ostringstream& results)
|
||||||
|
{
|
||||||
|
boost::property_tree::ptree pt;
|
||||||
|
auto i2cp = i2p::client::context.GetI2CPServer ();
|
||||||
|
if (i2cp)
|
||||||
|
{
|
||||||
|
/* TODO more info */
|
||||||
|
pt.put("enabled", true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pt.put("enabled", false);
|
||||||
|
|
||||||
|
InsertParam (results, "I2CP", pt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,7 @@ namespace client
|
|||||||
void InsertParam (std::ostringstream& ss, const std::string& name, int value) const;
|
void InsertParam (std::ostringstream& ss, const std::string& name, int value) const;
|
||||||
void InsertParam (std::ostringstream& ss, const std::string& name, double value) const;
|
void InsertParam (std::ostringstream& ss, const std::string& name, double value) const;
|
||||||
void InsertParam (std::ostringstream& ss, const std::string& name, const std::string& value) const;
|
void InsertParam (std::ostringstream& ss, const std::string& name, const std::string& value) const;
|
||||||
|
void InsertParam (std::ostringstream& ss, const std::string& name, const boost::property_tree::ptree& value) const;
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
typedef void (I2PControlService::*MethodHandler)(const boost::property_tree::ptree& params, std::ostringstream& results);
|
typedef void (I2PControlService::*MethodHandler)(const boost::property_tree::ptree& params, std::ostringstream& results);
|
||||||
@ -67,6 +68,7 @@ namespace client
|
|||||||
void RouterInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
|
void RouterInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
|
||||||
void RouterManagerHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
|
void RouterManagerHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
|
||||||
void NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
|
void NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
|
||||||
|
void ClientServicesInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
|
||||||
|
|
||||||
// I2PControl
|
// I2PControl
|
||||||
typedef void (I2PControlService::*I2PControlRequestHandler)(const std::string& value);
|
typedef void (I2PControlService::*I2PControlRequestHandler)(const std::string& value);
|
||||||
@ -98,6 +100,15 @@ namespace client
|
|||||||
void InboundBandwidthLimit (const std::string& value, std::ostringstream& results);
|
void InboundBandwidthLimit (const std::string& value, std::ostringstream& results);
|
||||||
void OutboundBandwidthLimit (const std::string& value, std::ostringstream& results);
|
void OutboundBandwidthLimit (const std::string& value, std::ostringstream& results);
|
||||||
|
|
||||||
|
// ClientServicesInfo
|
||||||
|
typedef void (I2PControlService::*ClientServicesInfoRequestHandler)(std::ostringstream& results);
|
||||||
|
void I2PTunnelInfoHandler (std::ostringstream& results);
|
||||||
|
void HTTPProxyInfoHandler (std::ostringstream& results);
|
||||||
|
void SOCKSInfoHandler (std::ostringstream& results);
|
||||||
|
void SAMInfoHandler (std::ostringstream& results);
|
||||||
|
void BOBInfoHandler (std::ostringstream& results);
|
||||||
|
void I2CPInfoHandler (std::ostringstream& results);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::string m_Password;
|
std::string m_Password;
|
||||||
@ -115,6 +126,7 @@ namespace client
|
|||||||
std::map<std::string, RouterInfoRequestHandler> m_RouterInfoHandlers;
|
std::map<std::string, RouterInfoRequestHandler> m_RouterInfoHandlers;
|
||||||
std::map<std::string, RouterManagerRequestHandler> m_RouterManagerHandlers;
|
std::map<std::string, RouterManagerRequestHandler> m_RouterManagerHandlers;
|
||||||
std::map<std::string, NetworkSettingRequestHandler> m_NetworkSettingHandlers;
|
std::map<std::string, NetworkSettingRequestHandler> m_NetworkSettingHandlers;
|
||||||
|
std::map<std::string, ClientServicesInfoRequestHandler> m_ClientServicesInfoHandlers;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -373,7 +373,7 @@ namespace crypto
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ECIES
|
// ECIES
|
||||||
void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx)
|
void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding)
|
||||||
{
|
{
|
||||||
BN_CTX_start (ctx);
|
BN_CTX_start (ctx);
|
||||||
BIGNUM * q = BN_CTX_get (ctx);
|
BIGNUM * q = BN_CTX_get (ctx);
|
||||||
@ -386,10 +386,19 @@ namespace crypto
|
|||||||
EC_POINT_mul (curve, p, k, nullptr, nullptr, ctx);
|
EC_POINT_mul (curve, p, k, nullptr, nullptr, ctx);
|
||||||
BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx);
|
BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx);
|
||||||
EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr);
|
EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr);
|
||||||
encrypted[0] = 0;
|
if (zeroPadding)
|
||||||
bn2buf (x, encrypted + 1, len);
|
{
|
||||||
bn2buf (y, encrypted + 1 + len, len);
|
encrypted[0] = 0;
|
||||||
RAND_bytes (encrypted + 1 + 2*len, 256 - 2*len);
|
bn2buf (x, encrypted + 1, len);
|
||||||
|
bn2buf (y, encrypted + 1 + len, len);
|
||||||
|
RAND_bytes (encrypted + 1 + 2*len, 256 - 2*len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bn2buf (x, encrypted, len);
|
||||||
|
bn2buf (y, encrypted + len, len);
|
||||||
|
RAND_bytes (encrypted + 2*len, 256 - 2*len);
|
||||||
|
}
|
||||||
// ecryption key and iv
|
// ecryption key and iv
|
||||||
EC_POINT_mul (curve, p, nullptr, key, k, ctx);
|
EC_POINT_mul (curve, p, nullptr, key, k, ctx);
|
||||||
EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr);
|
EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr);
|
||||||
@ -403,16 +412,21 @@ namespace crypto
|
|||||||
memcpy (m+33, data, 222);
|
memcpy (m+33, data, 222);
|
||||||
SHA256 (m+33, 222, m+1);
|
SHA256 (m+33, 222, m+1);
|
||||||
// encrypt
|
// encrypt
|
||||||
encrypted[257] = 0;
|
|
||||||
CBCEncryption encryption;
|
CBCEncryption encryption;
|
||||||
encryption.SetKey (shared);
|
encryption.SetKey (shared);
|
||||||
encryption.SetIV (iv);
|
encryption.SetIV (iv);
|
||||||
encryption.Encrypt (m, 256, encrypted + 258);
|
if (zeroPadding)
|
||||||
|
{
|
||||||
|
encrypted[257] = 0;
|
||||||
|
encryption.Encrypt (m, 256, encrypted + 258);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
encryption.Encrypt (m, 256, encrypted + 256);
|
||||||
EC_POINT_free (p);
|
EC_POINT_free (p);
|
||||||
BN_CTX_end (ctx);
|
BN_CTX_end (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx)
|
bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding)
|
||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
BN_CTX_start (ctx);
|
BN_CTX_start (ctx);
|
||||||
@ -421,8 +435,16 @@ namespace crypto
|
|||||||
int len = BN_num_bytes (q);
|
int len = BN_num_bytes (q);
|
||||||
// point for shared secret
|
// point for shared secret
|
||||||
BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx);
|
BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx);
|
||||||
BN_bin2bn (encrypted + 1, len, x);
|
if (zeroPadding)
|
||||||
BN_bin2bn (encrypted + 1 + len, len, y);
|
{
|
||||||
|
BN_bin2bn (encrypted + 1, len, x);
|
||||||
|
BN_bin2bn (encrypted + 1 + len, len, y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BN_bin2bn (encrypted, len, x);
|
||||||
|
BN_bin2bn (encrypted + len, len, y);
|
||||||
|
}
|
||||||
auto p = EC_POINT_new (curve);
|
auto p = EC_POINT_new (curve);
|
||||||
if (EC_POINT_set_affine_coordinates_GFp (curve, p, x, y, nullptr))
|
if (EC_POINT_set_affine_coordinates_GFp (curve, p, x, y, nullptr))
|
||||||
{
|
{
|
||||||
@ -439,7 +461,10 @@ namespace crypto
|
|||||||
CBCDecryption decryption;
|
CBCDecryption decryption;
|
||||||
decryption.SetKey (shared);
|
decryption.SetKey (shared);
|
||||||
decryption.SetIV (iv);
|
decryption.SetIV (iv);
|
||||||
decryption.Decrypt (encrypted + 258, 256, m);
|
if (zeroPadding)
|
||||||
|
decryption.Decrypt (encrypted + 258, 256, m);
|
||||||
|
else
|
||||||
|
decryption.Decrypt (encrypted + 256, 256, m);
|
||||||
// verify and copy
|
// verify and copy
|
||||||
uint8_t hash[32];
|
uint8_t hash[32];
|
||||||
SHA256 (m + 33, 222, hash);
|
SHA256 (m + 33, 222, hash);
|
||||||
|
@ -54,8 +54,8 @@ namespace crypto
|
|||||||
void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub);
|
void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub);
|
||||||
|
|
||||||
// ECIES
|
// ECIES
|
||||||
void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx); // 222 bytes data, 514 bytes encrypted
|
void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false); // 222 bytes data, 514 bytes encrypted with zeropadding, 512 without
|
||||||
bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx);
|
bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding = false);
|
||||||
void GenerateECIESKeyPair (const EC_GROUP * curve, BIGNUM *& priv, EC_POINT *& pub);
|
void GenerateECIESKeyPair (const EC_GROUP * curve, BIGNUM *& priv, EC_POINT *& pub);
|
||||||
|
|
||||||
// HMAC
|
// HMAC
|
||||||
|
@ -12,9 +12,9 @@ namespace crypto
|
|||||||
memcpy (m_PublicKey, pub, 256);
|
memcpy (m_PublicKey, pub, 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElGamalEncryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx)
|
void ElGamalEncryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding)
|
||||||
{
|
{
|
||||||
ElGamalEncrypt (m_PublicKey, data, encrypted, ctx, true);
|
ElGamalEncrypt (m_PublicKey, data, encrypted, ctx, zeroPadding);
|
||||||
}
|
}
|
||||||
|
|
||||||
ElGamalDecryptor::ElGamalDecryptor (const uint8_t * priv)
|
ElGamalDecryptor::ElGamalDecryptor (const uint8_t * priv)
|
||||||
@ -22,9 +22,9 @@ namespace crypto
|
|||||||
memcpy (m_PrivateKey, priv, 256);
|
memcpy (m_PrivateKey, priv, 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ElGamalDecryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx)
|
bool ElGamalDecryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding)
|
||||||
{
|
{
|
||||||
return ElGamalDecrypt (m_PrivateKey, encrypted, data, ctx, true);
|
return ElGamalDecrypt (m_PrivateKey, encrypted, data, ctx, zeroPadding);
|
||||||
}
|
}
|
||||||
|
|
||||||
ECIESP256Encryptor::ECIESP256Encryptor (const uint8_t * pub)
|
ECIESP256Encryptor::ECIESP256Encryptor (const uint8_t * pub)
|
||||||
@ -44,10 +44,10 @@ namespace crypto
|
|||||||
if (m_PublicKey) EC_POINT_free (m_PublicKey);
|
if (m_PublicKey) EC_POINT_free (m_PublicKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ECIESP256Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx)
|
void ECIESP256Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding)
|
||||||
{
|
{
|
||||||
if (m_Curve && m_PublicKey)
|
if (m_Curve && m_PublicKey)
|
||||||
ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted, ctx);
|
ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted, ctx, zeroPadding);
|
||||||
}
|
}
|
||||||
|
|
||||||
ECIESP256Decryptor::ECIESP256Decryptor (const uint8_t * priv)
|
ECIESP256Decryptor::ECIESP256Decryptor (const uint8_t * priv)
|
||||||
@ -62,10 +62,10 @@ namespace crypto
|
|||||||
if (m_PrivateKey) BN_free (m_PrivateKey);
|
if (m_PrivateKey) BN_free (m_PrivateKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ECIESP256Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx)
|
bool ECIESP256Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding)
|
||||||
{
|
{
|
||||||
if (m_Curve && m_PrivateKey)
|
if (m_Curve && m_PrivateKey)
|
||||||
return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data, ctx);
|
return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data, ctx, zeroPadding);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,10 +104,10 @@ namespace crypto
|
|||||||
if (m_PublicKey) EC_POINT_free (m_PublicKey);
|
if (m_PublicKey) EC_POINT_free (m_PublicKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ECIESGOSTR3410Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx)
|
void ECIESGOSTR3410Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding)
|
||||||
{
|
{
|
||||||
if (m_PublicKey)
|
if (m_PublicKey)
|
||||||
ECIESEncrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PublicKey, data, encrypted, ctx);
|
ECIESEncrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PublicKey, data, encrypted, ctx, zeroPadding);
|
||||||
}
|
}
|
||||||
|
|
||||||
ECIESGOSTR3410Decryptor::ECIESGOSTR3410Decryptor (const uint8_t * priv)
|
ECIESGOSTR3410Decryptor::ECIESGOSTR3410Decryptor (const uint8_t * priv)
|
||||||
@ -120,10 +120,10 @@ namespace crypto
|
|||||||
if (m_PrivateKey) BN_free (m_PrivateKey);
|
if (m_PrivateKey) BN_free (m_PrivateKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ECIESGOSTR3410Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx)
|
bool ECIESGOSTR3410Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding)
|
||||||
{
|
{
|
||||||
if (m_PrivateKey)
|
if (m_PrivateKey)
|
||||||
return ECIESDecrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PrivateKey, encrypted, data, ctx);
|
return ECIESDecrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PrivateKey, encrypted, data, ctx, zeroPadding);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ namespace crypto
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
virtual ~CryptoKeyEncryptor () {};
|
virtual ~CryptoKeyEncryptor () {};
|
||||||
virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) = 0; // 222 bytes data, 512 bytes encrypted
|
virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) = 0; // 222 bytes data, 512/514 bytes encrypted
|
||||||
};
|
};
|
||||||
|
|
||||||
class CryptoKeyDecryptor
|
class CryptoKeyDecryptor
|
||||||
@ -21,7 +21,7 @@ namespace crypto
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
virtual ~CryptoKeyDecryptor () {};
|
virtual ~CryptoKeyDecryptor () {};
|
||||||
virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) = 0; // 512 bytes encrypted, 222 bytes data
|
virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) = 0; // 512/514 bytes encrypted, 222 bytes data
|
||||||
};
|
};
|
||||||
|
|
||||||
// ElGamal
|
// ElGamal
|
||||||
@ -30,7 +30,7 @@ namespace crypto
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
ElGamalEncryptor (const uint8_t * pub);
|
ElGamalEncryptor (const uint8_t * pub);
|
||||||
void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx);
|
void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ namespace crypto
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
ElGamalDecryptor (const uint8_t * priv);
|
ElGamalDecryptor (const uint8_t * priv);
|
||||||
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx);
|
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ namespace crypto
|
|||||||
|
|
||||||
ECIESP256Encryptor (const uint8_t * pub);
|
ECIESP256Encryptor (const uint8_t * pub);
|
||||||
~ECIESP256Encryptor ();
|
~ECIESP256Encryptor ();
|
||||||
void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx);
|
void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ namespace crypto
|
|||||||
|
|
||||||
ECIESP256Decryptor (const uint8_t * priv);
|
ECIESP256Decryptor (const uint8_t * priv);
|
||||||
~ECIESP256Decryptor ();
|
~ECIESP256Decryptor ();
|
||||||
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx);
|
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ namespace crypto
|
|||||||
|
|
||||||
ECIESGOSTR3410Encryptor (const uint8_t * pub);
|
ECIESGOSTR3410Encryptor (const uint8_t * pub);
|
||||||
~ECIESGOSTR3410Encryptor ();
|
~ECIESGOSTR3410Encryptor ();
|
||||||
void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx);
|
void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ namespace crypto
|
|||||||
|
|
||||||
ECIESGOSTR3410Decryptor (const uint8_t * priv);
|
ECIESGOSTR3410Decryptor (const uint8_t * priv);
|
||||||
~ECIESGOSTR3410Decryptor ();
|
~ECIESGOSTR3410Decryptor ();
|
||||||
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx);
|
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -169,6 +169,46 @@ namespace client
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LeaseSetDestination::Reconfigure(std::map<std::string, std::string> params)
|
||||||
|
{
|
||||||
|
|
||||||
|
auto itr = params.find("i2cp.dontPublishLeaseSet");
|
||||||
|
if (itr != params.end())
|
||||||
|
{
|
||||||
|
m_IsPublic = itr->second != "true";
|
||||||
|
}
|
||||||
|
|
||||||
|
int inLen, outLen, inQuant, outQuant, numTags, minLatency, maxLatency;
|
||||||
|
std::map<std::string, int&> intOpts = {
|
||||||
|
{I2CP_PARAM_INBOUND_TUNNEL_LENGTH, inLen},
|
||||||
|
{I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH, outLen},
|
||||||
|
{I2CP_PARAM_INBOUND_TUNNELS_QUANTITY, inQuant},
|
||||||
|
{I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY, outQuant},
|
||||||
|
{I2CP_PARAM_TAGS_TO_SEND, numTags},
|
||||||
|
{I2CP_PARAM_MIN_TUNNEL_LATENCY, minLatency},
|
||||||
|
{I2CP_PARAM_MAX_TUNNEL_LATENCY, maxLatency}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto pool = GetTunnelPool();
|
||||||
|
inLen = pool->GetNumInboundHops();
|
||||||
|
outLen = pool->GetNumOutboundHops();
|
||||||
|
inQuant = pool->GetNumInboundTunnels();
|
||||||
|
outQuant = pool->GetNumOutboundTunnels();
|
||||||
|
minLatency = 0;
|
||||||
|
maxLatency = 0;
|
||||||
|
|
||||||
|
for (auto & opt : intOpts)
|
||||||
|
{
|
||||||
|
itr = params.find(opt.first);
|
||||||
|
if(itr != params.end())
|
||||||
|
{
|
||||||
|
opt.second = std::stoi(itr->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pool->RequireLatency(minLatency, maxLatency);
|
||||||
|
return pool->Reconfigure(inLen, outLen, inQuant, outQuant);
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<const i2p::data::LeaseSet> LeaseSetDestination::FindLeaseSet (const i2p::data::IdentHash& ident)
|
std::shared_ptr<const i2p::data::LeaseSet> LeaseSetDestination::FindLeaseSet (const i2p::data::IdentHash& ident)
|
||||||
{
|
{
|
||||||
std::shared_ptr<i2p::data::LeaseSet> remoteLS;
|
std::shared_ptr<i2p::data::LeaseSet> remoteLS;
|
||||||
@ -241,8 +281,12 @@ namespace client
|
|||||||
i2p::garlic::GarlicDestination::SetLeaseSetUpdated ();
|
i2p::garlic::GarlicDestination::SetLeaseSetUpdated ();
|
||||||
if (m_IsPublic)
|
if (m_IsPublic)
|
||||||
{
|
{
|
||||||
m_PublishVerificationTimer.cancel ();
|
auto s = shared_from_this ();
|
||||||
Publish ();
|
m_Service.post ([s](void)
|
||||||
|
{
|
||||||
|
s->m_PublishVerificationTimer.cancel ();
|
||||||
|
s->Publish ();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -984,7 +1028,7 @@ namespace client
|
|||||||
bool ClientDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const
|
bool ClientDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const
|
||||||
{
|
{
|
||||||
if (m_Decryptor)
|
if (m_Decryptor)
|
||||||
return m_Decryptor->Decrypt (encrypted, data, ctx);
|
return m_Decryptor->Decrypt (encrypted, data, ctx, true);
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Destinations: decryptor is not set");
|
LogPrint (eLogError, "Destinations: decryptor is not set");
|
||||||
return false;
|
return false;
|
||||||
|
@ -96,6 +96,10 @@ namespace client
|
|||||||
|
|
||||||
virtual bool Start ();
|
virtual bool Start ();
|
||||||
virtual bool Stop ();
|
virtual bool Stop ();
|
||||||
|
|
||||||
|
/** i2cp reconfigure */
|
||||||
|
virtual bool Reconfigure(std::map<std::string, std::string> i2cpOpts);
|
||||||
|
|
||||||
bool IsRunning () const { return m_IsRunning; };
|
bool IsRunning () const { return m_IsRunning; };
|
||||||
boost::asio::io_service& GetService () { return m_Service; };
|
boost::asio::io_service& GetService () { return m_Service; };
|
||||||
std::shared_ptr<i2p::tunnel::TunnelPool> GetTunnelPool () { return m_Pool; };
|
std::shared_ptr<i2p::tunnel::TunnelPool> GetTunnelPool () { return m_Pool; };
|
||||||
|
@ -327,7 +327,7 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "I2NP: Build request record ", i, " is ours");
|
LogPrint (eLogDebug, "I2NP: Build request record ", i, " is ours");
|
||||||
BN_CTX * ctx = BN_CTX_new ();
|
BN_CTX * ctx = BN_CTX_new ();
|
||||||
i2p::crypto::ElGamalDecrypt (i2p::context.GetPrivateKeys ().GetPrivateKey () , record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText, ctx);
|
i2p::context.DecryptTunnelBuildRecord (record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText, ctx);
|
||||||
BN_CTX_free (ctx);
|
BN_CTX_free (ctx);
|
||||||
// replace record to reply
|
// replace record to reply
|
||||||
if (i2p::context.AcceptsTunnels () &&
|
if (i2p::context.AcceptsTunnels () &&
|
||||||
|
@ -212,7 +212,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
auto encryptor = m_Identity->CreateEncryptor (m_EncryptionKey);
|
auto encryptor = m_Identity->CreateEncryptor (m_EncryptionKey);
|
||||||
if (encryptor)
|
if (encryptor)
|
||||||
encryptor->Encrypt (data, encrypted, ctx);
|
encryptor->Encrypt (data, encrypted, ctx, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalLeaseSet::LocalLeaseSet (std::shared_ptr<const IdentityEx> identity, const uint8_t * encryptionPublicKey, std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels):
|
LocalLeaseSet::LocalLeaseSet (std::shared_ptr<const IdentityEx> identity, const uint8_t * encryptionPublicKey, std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels):
|
||||||
|
@ -184,7 +184,7 @@ namespace transport
|
|||||||
}
|
}
|
||||||
// TODO: check for number of pending keys
|
// TODO: check for number of pending keys
|
||||||
auto work = new NTCPWork{shared_from_this()};
|
auto work = new NTCPWork{shared_from_this()};
|
||||||
m_Server.Work(work->session, [work]() -> std::function<void(void)> {
|
m_Server.Work(work->session, [work, this]() -> std::function<void(void)> {
|
||||||
if (!work->session->m_DHKeysPair)
|
if (!work->session->m_DHKeysPair)
|
||||||
work->session->m_DHKeysPair = transports.GetNextDHKeysPair ();
|
work->session->m_DHKeysPair = transports.GetNextDHKeysPair ();
|
||||||
work->session->CreateAESKey (work->session->m_Establisher->phase1.pubKey);
|
work->session->CreateAESKey (work->session->m_Establisher->phase1.pubKey);
|
||||||
@ -250,7 +250,7 @@ namespace transport
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto work = new NTCPWork{shared_from_this()};
|
auto work = new NTCPWork{shared_from_this()};
|
||||||
m_Server.Work(work->session, [work]() -> std::function<void(void)> {
|
m_Server.Work(work->session, [work, this]() -> std::function<void(void)> {
|
||||||
work->session->CreateAESKey (work->session->m_Establisher->phase2.pubKey);
|
work->session->CreateAESKey (work->session->m_Establisher->phase2.pubKey);
|
||||||
return std::bind(&NTCPSession::HandlePhase2, work->session, work);
|
return std::bind(&NTCPSession::HandlePhase2, work->session, work);
|
||||||
});
|
});
|
||||||
|
@ -34,11 +34,7 @@ namespace i2p
|
|||||||
|
|
||||||
void RouterContext::CreateNewRouter ()
|
void RouterContext::CreateNewRouter ()
|
||||||
{
|
{
|
||||||
#if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER)
|
|
||||||
m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519);
|
m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519);
|
||||||
#else
|
|
||||||
m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_DSA_SHA1);
|
|
||||||
#endif
|
|
||||||
SaveKeys ();
|
SaveKeys ();
|
||||||
NewRouterInfo ();
|
NewRouterInfo ();
|
||||||
}
|
}
|
||||||
@ -482,6 +478,11 @@ namespace i2p
|
|||||||
|
|
||||||
bool RouterContext::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const
|
bool RouterContext::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const
|
||||||
{
|
{
|
||||||
return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx) : false;
|
return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx, true) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RouterContext::DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const
|
||||||
|
{
|
||||||
|
return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx, false) : false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,7 @@ namespace i2p
|
|||||||
void SetError (RouterError error) { m_Status = eRouterStatusError; m_Error = error; };
|
void SetError (RouterError error) { m_Status = eRouterStatusError; m_Error = error; };
|
||||||
int GetNetID () const { return m_NetID; };
|
int GetNetID () const { return m_NetID; };
|
||||||
void SetNetID (int netID) { m_NetID = netID; };
|
void SetNetID (int netID) { m_NetID = netID; };
|
||||||
|
bool DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const;
|
||||||
|
|
||||||
void UpdatePort (int port); // called from Daemon
|
void UpdatePort (int port); // called from Daemon
|
||||||
void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon
|
void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon
|
||||||
|
@ -840,7 +840,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
auto encryptor = m_RouterIdentity->CreateEncryptor (nullptr);
|
auto encryptor = m_RouterIdentity->CreateEncryptor (nullptr);
|
||||||
if (encryptor)
|
if (encryptor)
|
||||||
encryptor->Encrypt (data, encrypted, ctx);
|
encryptor->Encrypt (data, encrypted, ctx, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -670,10 +670,13 @@ namespace tunnel
|
|||||||
{
|
{
|
||||||
if (!tunnel->IsRecreated () && ts + TUNNEL_RECREATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
|
if (!tunnel->IsRecreated () && ts + TUNNEL_RECREATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
|
||||||
{
|
{
|
||||||
tunnel->SetIsRecreated ();
|
|
||||||
auto pool = tunnel->GetTunnelPool ();
|
auto pool = tunnel->GetTunnelPool ();
|
||||||
if (pool)
|
// let it die if the tunnel pool has been reconfigured and this is old
|
||||||
|
if (pool && tunnel->GetNumHops() == pool->GetNumOutboundHops())
|
||||||
|
{
|
||||||
|
tunnel->SetIsRecreated ();
|
||||||
pool->RecreateOutboundTunnel (tunnel);
|
pool->RecreateOutboundTunnel (tunnel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
|
if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
|
||||||
tunnel->SetState (eTunnelStateExpiring);
|
tunnel->SetState (eTunnelStateExpiring);
|
||||||
@ -721,10 +724,13 @@ namespace tunnel
|
|||||||
{
|
{
|
||||||
if (!tunnel->IsRecreated () && ts + TUNNEL_RECREATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
|
if (!tunnel->IsRecreated () && ts + TUNNEL_RECREATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
|
||||||
{
|
{
|
||||||
tunnel->SetIsRecreated ();
|
|
||||||
auto pool = tunnel->GetTunnelPool ();
|
auto pool = tunnel->GetTunnelPool ();
|
||||||
if (pool)
|
// let it die if the tunnel pool was reconfigured and has different number of hops
|
||||||
|
if (pool && tunnel->GetNumHops() == pool->GetNumInboundHops())
|
||||||
|
{
|
||||||
|
tunnel->SetIsRecreated ();
|
||||||
pool->RecreateInboundTunnel (tunnel);
|
pool->RecreateInboundTunnel (tunnel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
|
if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
|
||||||
|
@ -105,6 +105,7 @@ namespace tunnel
|
|||||||
bool IsFailed () const { return m_State == eTunnelStateFailed; };
|
bool IsFailed () const { return m_State == eTunnelStateFailed; };
|
||||||
bool IsRecreated () const { return m_IsRecreated; };
|
bool IsRecreated () const { return m_IsRecreated; };
|
||||||
void SetIsRecreated () { m_IsRecreated = true; };
|
void SetIsRecreated () { m_IsRecreated = true; };
|
||||||
|
int GetNumHops () const { return m_Hops.size (); };
|
||||||
virtual bool IsInbound() const = 0;
|
virtual bool IsInbound() const = 0;
|
||||||
|
|
||||||
std::shared_ptr<TunnelPool> GetTunnelPool () const { return m_Pool; };
|
std::shared_ptr<TunnelPool> GetTunnelPool () const { return m_Pool; };
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "Crypto.h"
|
|
||||||
#include "Identity.h"
|
#include "Identity.h"
|
||||||
#include "RouterContext.h"
|
#include "RouterContext.h"
|
||||||
#include "Timestamp.h"
|
#include "Timestamp.h"
|
||||||
@ -35,6 +34,7 @@ namespace tunnel
|
|||||||
RAND_bytes (replyKey, 32);
|
RAND_bytes (replyKey, 32);
|
||||||
RAND_bytes (replyIV, 16);
|
RAND_bytes (replyIV, 16);
|
||||||
RAND_bytes ((uint8_t *)&tunnelID, 4);
|
RAND_bytes ((uint8_t *)&tunnelID, 4);
|
||||||
|
if (!tunnelID) tunnelID = 1; // tunnelID can't be zero
|
||||||
isGateway = true;
|
isGateway = true;
|
||||||
isEndpoint = true;
|
isEndpoint = true;
|
||||||
ident = r;
|
ident = r;
|
||||||
@ -50,6 +50,7 @@ namespace tunnel
|
|||||||
nextIdent = ident;
|
nextIdent = ident;
|
||||||
isEndpoint = false;
|
isEndpoint = false;
|
||||||
RAND_bytes ((uint8_t *)&nextTunnelID, 4);
|
RAND_bytes ((uint8_t *)&nextTunnelID, 4);
|
||||||
|
if (!nextTunnelID) nextTunnelID = 1; // tunnelID can't be zero
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetReplyHop (uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent)
|
void SetReplyHop (uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent)
|
||||||
@ -101,7 +102,9 @@ namespace tunnel
|
|||||||
htobe32buf (clearText + BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetHoursSinceEpoch ());
|
htobe32buf (clearText + BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetHoursSinceEpoch ());
|
||||||
htobe32buf (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID);
|
htobe32buf (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID);
|
||||||
RAND_bytes (clearText + BUILD_REQUEST_RECORD_PADDING_OFFSET, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - BUILD_REQUEST_RECORD_PADDING_OFFSET);
|
RAND_bytes (clearText + BUILD_REQUEST_RECORD_PADDING_OFFSET, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - BUILD_REQUEST_RECORD_PADDING_OFFSET);
|
||||||
i2p::crypto::ElGamalEncrypt (ident->GetEncryptionPublicKey (), clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx);
|
auto encryptor = ident->CreateEncryptor (nullptr);
|
||||||
|
if (encryptor)
|
||||||
|
encryptor->Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx, false);
|
||||||
memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16);
|
memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -69,6 +69,18 @@ namespace tunnel
|
|||||||
m_Tests.clear ();
|
m_Tests.clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TunnelPool::Reconfigure(int inHops, int outHops, int inQuant, int outQuant) {
|
||||||
|
if( inHops >= 0 && outHops >= 0 && inQuant > 0 && outQuant > 0)
|
||||||
|
{
|
||||||
|
m_NumInboundHops = inHops;
|
||||||
|
m_NumOutboundHops = outHops;
|
||||||
|
m_NumInboundTunnels = inQuant;
|
||||||
|
m_NumOutboundTunnels = outQuant;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void TunnelPool::TunnelCreated (std::shared_ptr<InboundTunnel> createdTunnel)
|
void TunnelPool::TunnelCreated (std::shared_ptr<InboundTunnel> createdTunnel)
|
||||||
{
|
{
|
||||||
if (!m_IsActive) return;
|
if (!m_IsActive) return;
|
||||||
@ -479,11 +491,17 @@ namespace tunnel
|
|||||||
outboundTunnel = tunnels.GetNextOutboundTunnel ();
|
outboundTunnel = tunnels.GetNextOutboundTunnel ();
|
||||||
LogPrint (eLogDebug, "Tunnels: Re-creating destination inbound tunnel...");
|
LogPrint (eLogDebug, "Tunnels: Re-creating destination inbound tunnel...");
|
||||||
std::shared_ptr<TunnelConfig> config;
|
std::shared_ptr<TunnelConfig> config;
|
||||||
if (m_NumInboundHops > 0) config = std::make_shared<TunnelConfig>(tunnel->GetPeers ());
|
if (m_NumInboundHops > 0 && tunnel->GetPeers().size())
|
||||||
auto newTunnel = tunnels.CreateInboundTunnel (config, outboundTunnel);
|
{
|
||||||
newTunnel->SetTunnelPool (shared_from_this());
|
config = std::make_shared<TunnelConfig>(tunnel->GetPeers ());
|
||||||
if (newTunnel->IsEstablished ()) // zero hops
|
}
|
||||||
TunnelCreated (newTunnel);
|
if (m_NumInboundHops == 0 || config)
|
||||||
|
{
|
||||||
|
auto newTunnel = tunnels.CreateInboundTunnel (config, outboundTunnel);
|
||||||
|
newTunnel->SetTunnelPool (shared_from_this());
|
||||||
|
if (newTunnel->IsEstablished ()) // zero hops
|
||||||
|
TunnelCreated (newTunnel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TunnelPool::CreateOutboundTunnel ()
|
void TunnelPool::CreateOutboundTunnel ()
|
||||||
@ -521,12 +539,17 @@ namespace tunnel
|
|||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "Tunnels: Re-creating destination outbound tunnel...");
|
LogPrint (eLogDebug, "Tunnels: Re-creating destination outbound tunnel...");
|
||||||
std::shared_ptr<TunnelConfig> config;
|
std::shared_ptr<TunnelConfig> config;
|
||||||
if (m_NumOutboundHops > 0)
|
if (m_NumOutboundHops > 0 && tunnel->GetPeers().size())
|
||||||
|
{
|
||||||
config = std::make_shared<TunnelConfig>(tunnel->GetPeers (), inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ());
|
config = std::make_shared<TunnelConfig>(tunnel->GetPeers (), inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ());
|
||||||
auto newTunnel = tunnels.CreateOutboundTunnel (config);
|
}
|
||||||
newTunnel->SetTunnelPool (shared_from_this ());
|
if(m_NumOutboundHops == 0 || config)
|
||||||
if (newTunnel->IsEstablished ()) // zero hops
|
{
|
||||||
TunnelCreated (newTunnel);
|
auto newTunnel = tunnels.CreateOutboundTunnel (config);
|
||||||
|
newTunnel->SetTunnelPool (shared_from_this ());
|
||||||
|
if (newTunnel->IsEstablished ()) // zero hops
|
||||||
|
TunnelCreated (newTunnel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogDebug, "Tunnels: Can't re-create outbound tunnel, no inbound tunnels found");
|
LogPrint (eLogDebug, "Tunnels: Can't re-create outbound tunnel, no inbound tunnels found");
|
||||||
|
@ -78,7 +78,12 @@ namespace tunnel
|
|||||||
|
|
||||||
int GetNumInboundTunnels () const { return m_NumInboundTunnels; };
|
int GetNumInboundTunnels () const { return m_NumInboundTunnels; };
|
||||||
int GetNumOutboundTunnels () const { return m_NumOutboundTunnels; };
|
int GetNumOutboundTunnels () const { return m_NumOutboundTunnels; };
|
||||||
|
int GetNumInboundHops() const { return m_NumInboundHops; };
|
||||||
|
int GetNumOutboundHops() const { return m_NumOutboundHops; };
|
||||||
|
|
||||||
|
/** i2cp reconfigure */
|
||||||
|
bool Reconfigure(int inboundHops, int outboundHops, int inboundQuant, int outboundQuant);
|
||||||
|
|
||||||
void SetCustomPeerSelector(ITunnelPeerSelector * selector);
|
void SetCustomPeerSelector(ITunnelPeerSelector * selector);
|
||||||
void UnsetCustomPeerSelector();
|
void UnsetCustomPeerSelector();
|
||||||
bool HasCustomPeerSelector();
|
bool HasCustomPeerSelector();
|
||||||
|
@ -37,7 +37,7 @@ namespace client
|
|||||||
bool I2CPDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const
|
bool I2CPDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const
|
||||||
{
|
{
|
||||||
if (m_Decryptor)
|
if (m_Decryptor)
|
||||||
return m_Decryptor->Decrypt (encrypted, data, ctx);
|
return m_Decryptor->Decrypt (encrypted, data, ctx, true);
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "I2CP: decryptor is not set");
|
LogPrint (eLogError, "I2CP: decryptor is not set");
|
||||||
return false;
|
return false;
|
||||||
@ -416,9 +416,60 @@ namespace client
|
|||||||
|
|
||||||
void I2CPSession::ReconfigureSessionMessageHandler (const uint8_t * buf, size_t len)
|
void I2CPSession::ReconfigureSessionMessageHandler (const uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
// TODO: implement actual reconfiguration
|
uint8_t status = 3; // rejected
|
||||||
SendSessionStatusMessage (2); // updated
|
if(len > sizeof(uint16_t))
|
||||||
}
|
{
|
||||||
|
uint16_t sessionID = bufbe16toh(buf);
|
||||||
|
if(sessionID == m_SessionID)
|
||||||
|
{
|
||||||
|
buf += sizeof(uint16_t);
|
||||||
|
const uint8_t * body = buf;
|
||||||
|
i2p::data::IdentityEx ident;
|
||||||
|
if(ident.FromBuffer(buf, len - sizeof(uint16_t)))
|
||||||
|
{
|
||||||
|
if (ident == *m_Destination->GetIdentity())
|
||||||
|
{
|
||||||
|
size_t identsz = ident.GetFullLen();
|
||||||
|
buf += identsz;
|
||||||
|
uint16_t optssize = bufbe16toh(buf);
|
||||||
|
if (optssize <= len - sizeof(uint16_t) - sizeof(uint64_t) - identsz - ident.GetSignatureLen() - sizeof(uint16_t))
|
||||||
|
{
|
||||||
|
buf += sizeof(uint16_t);
|
||||||
|
std::map<std::string, std::string> opts;
|
||||||
|
ExtractMapping(buf, optssize, opts);
|
||||||
|
buf += optssize;
|
||||||
|
//uint64_t date = bufbe64toh(buf);
|
||||||
|
buf += sizeof(uint64_t);
|
||||||
|
const uint8_t * sig = buf;
|
||||||
|
if(ident.Verify(body, len - sizeof(uint16_t) - ident.GetSignatureLen(), sig))
|
||||||
|
{
|
||||||
|
if(m_Destination->Reconfigure(opts))
|
||||||
|
{
|
||||||
|
LogPrint(eLogInfo, "I2CP: reconfigured destination");
|
||||||
|
status = 2; // updated
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint(eLogWarning, "I2CP: failed to reconfigure destination");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint(eLogError, "I2CP: invalid reconfigure message signature");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint(eLogError, "I2CP: mapping size missmatch");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint(eLogError, "I2CP: destination missmatch");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint(eLogError, "I2CP: malfromed destination");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint(eLogError, "I2CP: session missmatch");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint(eLogError, "I2CP: short message");
|
||||||
|
SendSessionStatusMessage (status);
|
||||||
|
}
|
||||||
|
|
||||||
void I2CPSession::SendSessionStatusMessage (uint8_t status)
|
void I2CPSession::SendSessionStatusMessage (uint8_t status)
|
||||||
{
|
{
|
||||||
|
@ -107,6 +107,21 @@ namespace client
|
|||||||
std::placeholders::_1, std::placeholders::_2));
|
std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool SAMVersionAcceptable(const std::string & ver)
|
||||||
|
{
|
||||||
|
return ver == "3.0" || ver == "3.1";
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool SAMVersionTooLow(const std::string & ver)
|
||||||
|
{
|
||||||
|
return ver.size() && ver[0] < '3';
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool SAMVersionTooHigh(const std::string & ver)
|
||||||
|
{
|
||||||
|
return ver.size() && ver > "3.1";
|
||||||
|
}
|
||||||
|
|
||||||
void SAMSocket::HandleHandshakeReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred)
|
void SAMSocket::HandleHandshakeReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred)
|
||||||
{
|
{
|
||||||
if (ecode)
|
if (ecode)
|
||||||
@ -132,19 +147,37 @@ namespace client
|
|||||||
|
|
||||||
if (!strcmp (m_Buffer, SAM_HANDSHAKE))
|
if (!strcmp (m_Buffer, SAM_HANDSHAKE))
|
||||||
{
|
{
|
||||||
std::string version("3.0");
|
std::string maxver("3.1");
|
||||||
|
std::string minver("3.0");
|
||||||
// try to find MIN and MAX, 3.0 if not found
|
// try to find MIN and MAX, 3.0 if not found
|
||||||
if (separator)
|
if (separator)
|
||||||
{
|
{
|
||||||
separator++;
|
separator++;
|
||||||
std::map<std::string, std::string> params;
|
std::map<std::string, std::string> params;
|
||||||
ExtractParams (separator, params);
|
ExtractParams (separator, params);
|
||||||
//auto it = params.find (SAM_PARAM_MAX);
|
auto it = params.find (SAM_PARAM_MAX);
|
||||||
// TODO: check MIN as well
|
if (it != params.end ())
|
||||||
//if (it != params.end ())
|
maxver = it->second;
|
||||||
// version = it->second;
|
it = params.find(SAM_PARAM_MIN);
|
||||||
|
if (it != params.end ())
|
||||||
|
minver = it->second;
|
||||||
}
|
}
|
||||||
if (version[0] == '3') // we support v3 (3.0 and 3.1) only
|
// version negotiation
|
||||||
|
std::string version;
|
||||||
|
if (SAMVersionAcceptable(maxver))
|
||||||
|
{
|
||||||
|
version = maxver;
|
||||||
|
}
|
||||||
|
else if (SAMVersionAcceptable(minver))
|
||||||
|
{
|
||||||
|
version = minver;
|
||||||
|
}
|
||||||
|
else if (SAMVersionTooLow(minver) && SAMVersionTooHigh(maxver))
|
||||||
|
{
|
||||||
|
version = "3.0";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SAMVersionAcceptable(version))
|
||||||
{
|
{
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
size_t l = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_HANDSHAKE_REPLY, version.c_str ());
|
size_t l = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_HANDSHAKE_REPLY, version.c_str ());
|
||||||
@ -156,7 +189,7 @@ namespace client
|
|||||||
std::placeholders::_1, std::placeholders::_2));
|
std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SendMessageReply (SAM_HANDSHAKE_I2P_ERROR, strlen (SAM_HANDSHAKE_I2P_ERROR), true);
|
SendMessageReply (SAM_HANDSHAKE_NOVERSION, strlen (SAM_HANDSHAKE_NOVERSION), true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -23,6 +23,7 @@ namespace client
|
|||||||
const int SAM_SESSION_READINESS_CHECK_INTERVAL = 20; // in seconds
|
const int SAM_SESSION_READINESS_CHECK_INTERVAL = 20; // in seconds
|
||||||
const char SAM_HANDSHAKE[] = "HELLO VERSION";
|
const char SAM_HANDSHAKE[] = "HELLO VERSION";
|
||||||
const char SAM_HANDSHAKE_REPLY[] = "HELLO REPLY RESULT=OK VERSION=%s\n";
|
const char SAM_HANDSHAKE_REPLY[] = "HELLO REPLY RESULT=OK VERSION=%s\n";
|
||||||
|
const char SAM_HANDSHAKE_NOVERSION[] = "HELLO REPLY RESULT=NOVERSION\n";
|
||||||
const char SAM_HANDSHAKE_I2P_ERROR[] = "HELLO REPLY RESULT=I2P_ERROR\n";
|
const char SAM_HANDSHAKE_I2P_ERROR[] = "HELLO REPLY RESULT=I2P_ERROR\n";
|
||||||
const char SAM_SESSION_CREATE[] = "SESSION CREATE";
|
const char SAM_SESSION_CREATE[] = "SESSION CREATE";
|
||||||
const char SAM_SESSION_CREATE_REPLY_OK[] = "SESSION STATUS RESULT=OK DESTINATION=%s\n";
|
const char SAM_SESSION_CREATE_REPLY_OK[] = "SESSION STATUS RESULT=OK DESTINATION=%s\n";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user