Browse Source

tunnels reload changes: fix tcp tunnels reload

Signed-off-by: R4SAS <r4sas@i2pmail.org>
pull/1688/head
R4SAS 3 years ago
parent
commit
6b1ef6e1b9
Signed by: r4sas
GPG Key ID: 66F6C87B98EBCFE2
  1. 128
      libi2pd_client/ClientContext.cpp
  2. 3
      libi2pd_client/ClientContext.h
  3. 10
      libi2pd_client/I2PTunnel.cpp
  4. 10
      libi2pd_client/I2PTunnel.h

128
libi2pd_client/ClientContext.cpp

@ -185,7 +185,7 @@ namespace client @@ -185,7 +185,7 @@ namespace client
LogPrint(eLogInfo, "Clients: stopping AddressBook");
m_AddressBook.Stop ();
{
{
std::lock_guard<std::mutex> lock(m_ForwardsMutex);
m_ServerForwards.clear();
m_ClientForwards.clear();
@ -200,6 +200,8 @@ namespace client @@ -200,6 +200,8 @@ namespace client
for (auto& it: m_Destinations)
it.second->Stop ();
m_Destinations.clear ();
m_SharedLocalDestination->Release ();
m_SharedLocalDestination = nullptr;
}
@ -209,14 +211,6 @@ namespace client @@ -209,14 +211,6 @@ namespace client
/*std::string config; i2p::config::GetOption("conf", config);
i2p::config::ParseConfig(config);*/
// handle tunnels
// reset isUpdated for each tunnel
VisitTunnels ([](I2PService * s)->bool { s->isUpdated = false; return true; });
// reload tunnels
ReadTunnels();
// delete not updated tunnels (not in config anymore)
VisitTunnels ([](I2PService * s)->bool { return s->isUpdated; });
// change shared local destination
m_SharedLocalDestination->Release ();
CreateNewSharedLocalDestination ();
@ -225,6 +219,7 @@ namespace client @@ -225,6 +219,7 @@ namespace client
if (m_HttpProxy)
{
m_HttpProxy->Stop ();
delete m_HttpProxy;
m_HttpProxy = nullptr;
}
ReadHttpProxy ();
@ -233,10 +228,19 @@ namespace client @@ -233,10 +228,19 @@ namespace client
if (m_SocksProxy)
{
m_SocksProxy->Stop ();
delete m_SocksProxy;
m_SocksProxy = nullptr;
}
ReadSocksProxy ();
// handle tunnels
// reset isUpdated for each tunnel
VisitTunnels (false);
// reload tunnels
ReadTunnels();
// delete not updated tunnels (not in config anymore)
VisitTunnels (true);
// delete unused destinations
std::unique_lock<std::mutex> l(m_DestinationsMutex);
for (auto it = m_Destinations.begin (); it != m_Destinations.end ();)
@ -504,20 +508,15 @@ namespace client @@ -504,20 +508,15 @@ namespace client
int numClientTunnels = 0, numServerTunnels = 0;
std::string tunConf; i2p::config::GetOption("tunconf", tunConf);
if (tunConf.empty ())
{
// TODO: cleanup this in 2.8.0
tunConf = i2p::fs::DataDirPath ("tunnels.cfg");
if (i2p::fs::Exists(tunConf))
LogPrint(eLogWarning, "Clients: please rename tunnels.cfg -> tunnels.conf here: ", tunConf);
else
tunConf = i2p::fs::DataDirPath ("tunnels.conf");
}
tunConf = i2p::fs::DataDirPath ("tunnels.conf");
LogPrint(eLogDebug, "Clients: tunnels config file: ", tunConf);
ReadTunnels (tunConf, numClientTunnels, numServerTunnels);
std::string tunDir; i2p::config::GetOption("tunnelsdir", tunDir);
if (tunDir.empty ())
tunDir = i2p::fs::DataDirPath ("tunnels.d");
if (i2p::fs::Exists (tunDir))
{
std::vector<std::string> files;
@ -582,7 +581,7 @@ namespace client @@ -582,7 +581,7 @@ namespace client
if (it != destinations.end ())
localDestination = it->second;
else
{
{
i2p::data::PrivateKeys k;
if(LoadPrivateKeys (k, keys, sigType, cryptoType))
{
@ -597,7 +596,7 @@ namespace client @@ -597,7 +596,7 @@ namespace client
destinations[keys] = localDestination;
}
}
}
}
}
if (type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) {
@ -609,10 +608,18 @@ namespace client @@ -609,10 +608,18 @@ namespace client
bool gzip = section.second.get (I2P_CLIENT_TUNNEL_GZIP, true);
auto clientTunnel = std::make_shared<I2PUDPClientTunnel>(name, dest, end, localDestination, destinationPort, gzip);
if(m_ClientForwards.insert(std::make_pair(end, clientTunnel)).second)
auto ins = m_ClientForwards.insert(std::make_pair(end, clientTunnel));
if (ins.second)
{
clientTunnel->Start();
numClientTunnels++;
}
else
{
ins.first->second->isUpdated = true;
LogPrint(eLogError, "Clients: I2P Client forward for endpoint ", end, " already exists");
}
} else {
boost::asio::ip::tcp::endpoint clientEndpoint;
@ -666,13 +673,16 @@ namespace client @@ -666,13 +673,16 @@ namespace client
if (ins.first->second->GetLocalDestination () != clientTunnel->GetLocalDestination ())
{
LogPrint (eLogInfo, "Clients: I2P client tunnel destination updated");
ins.first->second->Stop ();
ins.first->second->SetLocalDestination (clientTunnel->GetLocalDestination ());
ins.first->second->Start ();
}
ins.first->second->isUpdated = true;
LogPrint (eLogInfo, "Clients: I2P client tunnel for endpoint ", clientEndpoint, " already exists");
}
}
}
else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER
|| type == I2P_TUNNELS_SECTION_TYPE_HTTP
|| type == I2P_TUNNELS_SECTION_TYPE_IRC
@ -705,17 +715,17 @@ namespace client @@ -705,17 +715,17 @@ namespace client
if (it != destinations.end ())
localDestination = it->second;
else
{
{
i2p::data::PrivateKeys k;
if(!LoadPrivateKeys (k, keys, sigType, cryptoType))
continue;
localDestination = FindLocalDestination (k.GetPublic ()->GetIdentHash ());
if (!localDestination)
{
{
localDestination = CreateNewLocalDestination (k, true, &options);
destinations[keys] = localDestination;
}
}
}
}
if (type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER)
{
// udp server tunnel
@ -727,8 +737,8 @@ namespace client @@ -727,8 +737,8 @@ namespace client
address = "::1";
else
address = "127.0.0.1";
}
auto localAddress = boost::asio::ip::address::from_string(address);
}
auto localAddress = boost::asio::ip::address::from_string(address);
auto serverTunnel = std::make_shared<I2PUDPServerTunnel>(name, localDestination, localAddress, endpoint, port, gzip);
if(!isUniqueLocal)
{
@ -736,16 +746,16 @@ namespace client @@ -736,16 +746,16 @@ namespace client
serverTunnel->SetUniqueLocal(isUniqueLocal);
}
std::lock_guard<std::mutex> lock(m_ForwardsMutex);
if(m_ServerForwards.insert(
std::make_pair(
std::make_pair(
localDestination->GetIdentHash(), port),
serverTunnel)).second)
auto ins = m_ServerForwards.insert(std::make_pair(
std::make_pair(localDestination->GetIdentHash(), port),
serverTunnel));
if (ins.second)
{
serverTunnel->Start();
LogPrint(eLogInfo, "Clients: I2P Server Forward created for UDP Endpoint ", host, ":", port, " bound on ", address, " for ",localDestination->GetIdentHash().ToBase32());
}
else
ins.first->second->isUpdated = true;
LogPrint(eLogError, "Clients: I2P Server Forward for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash()), "/", port, "already exists");
continue;
@ -795,7 +805,9 @@ namespace client @@ -795,7 +805,9 @@ namespace client
if (ins.first->second->GetLocalDestination () != serverTunnel->GetLocalDestination ())
{
LogPrint (eLogInfo, "Clients: I2P server tunnel destination updated");
ins.first->second->Stop ();
ins.first->second->SetLocalDestination (serverTunnel->GetLocalDestination ());
ins.first->second->Start ();
}
ins.first->second->isUpdated = true;
LogPrint (eLogInfo, "Clients: I2P server tunnel for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), "/", inPort, " already exists");
@ -872,7 +884,7 @@ namespace client @@ -872,7 +884,7 @@ namespace client
{
localDestination = m_HttpProxy->GetLocalDestination ();
localDestination->Acquire ();
}
}
else if (socksProxyKeys.length () > 0)
{
i2p::data::PrivateKeys keys;
@ -920,27 +932,51 @@ namespace client @@ -920,27 +932,51 @@ namespace client
}
}
template<typename Container, typename Visitor>
void VisitTunnelsContainer (Container& c, Visitor v)
void ClientContext::VisitTunnels (bool clean)
{
for (auto it = c.begin (); it != c.end ();)
for (auto it = m_ClientTunnels.begin (); it != m_ClientTunnels.end ();)
{
if (!v (it->second.get ()))
{
if(clean && !it->second->isUpdated) {
it->second->Stop ();
it = c.erase (it);
it = m_ClientTunnels.erase(it);
} else {
it->second->isUpdated = false;
it++;
}
else
}
for (auto it = m_ServerTunnels.begin (); it != m_ServerTunnels.end ();)
{
if(clean && !it->second->isUpdated) {
it->second->Stop ();
it = m_ServerTunnels.erase(it);
} else {
it->second->isUpdated = false;
it++;
}
}
}
template<typename Visitor>
void ClientContext::VisitTunnels (Visitor v)
{
VisitTunnelsContainer (m_ClientTunnels, v);
VisitTunnelsContainer (m_ServerTunnels, v);
// TODO: implement UDP forwards
for (auto it = m_ClientForwards.begin (); it != m_ClientForwards.end ();)
{
if(clean && !it->second->isUpdated) {
it->second = nullptr;
it = m_ClientForwards.erase(it);
} else {
it->second->isUpdated = false;
it++;
}
}
for (auto it = m_ServerForwards.begin (); it != m_ServerForwards.end ();)
{
if(clean && !it->second->isUpdated) {
it->second = nullptr;
it = m_ServerForwards.erase(it);
} else {
it->second->isUpdated = false;
it++;
}
}
}
}
}

3
libi2pd_client/ClientContext.h

@ -121,8 +121,7 @@ namespace client @@ -121,8 +121,7 @@ namespace client
void CleanupUDP(const boost::system::error_code & ecode);
void ScheduleCleanupUDP();
template<typename Visitor>
void VisitTunnels (Visitor v); // Visitor: (I2PService *) -> bool, true means retain
void VisitTunnels (bool clean);
void CreateNewSharedLocalDestination ();
void AddLocalDestination (std::shared_ptr<ClientDestination> localDestination);

10
libi2pd_client/I2PTunnel.cpp

@ -303,7 +303,7 @@ namespace client @@ -303,7 +303,7 @@ namespace client
m_ProxyConnectionSent = true;
}
else
m_OutHeader << line << "\n";
m_OutHeader << line << "\n";
}
}
else
@ -888,7 +888,8 @@ namespace client @@ -888,7 +888,8 @@ namespace client
LogPrint(eLogInfo, "UDPServer: done");
}
void I2PUDPServerTunnel::Start() {
void I2PUDPServerTunnel::Start()
{
m_LocalDest->Start();
}
@ -1064,8 +1065,9 @@ namespace client @@ -1064,8 +1065,9 @@ namespace client
else
LogPrint(eLogWarning, "UDP Client: not tracking udp session using port ", (int) toPort);
}
I2PUDPClientTunnel::~I2PUDPClientTunnel() {
I2PUDPClientTunnel::~I2PUDPClientTunnel()
{
auto dgram = m_LocalDest->GetDatagramDestination();
if (dgram) dgram->ResetReceiver();

10
libi2pd_client/I2PTunnel.h

@ -254,6 +254,10 @@ namespace client @@ -254,6 +254,10 @@ namespace client
std::vector<UDPSessionPtr> m_Sessions;
std::shared_ptr<i2p::client::ClientDestination> m_LocalDest;
UDPSessionPtr m_LastSession;
public:
bool isUpdated; // transient, used during reload only
};
class I2PUDPClientTunnel
@ -283,7 +287,7 @@ namespace client @@ -283,7 +287,7 @@ namespace client
void TryResolving();
private:
const std::string m_Name;
std::mutex m_SessionsMutex;
std::unordered_map<uint16_t, std::shared_ptr<UDPConvo> > m_Sessions; // maps i2p port -> local udp convo
@ -298,6 +302,10 @@ namespace client @@ -298,6 +302,10 @@ namespace client
uint16_t RemotePort, m_LastPort;
bool m_cancel_resolve;
std::shared_ptr<UDPConvo> m_LastSession;
public:
bool isUpdated; // transient, used during reload only
};
class I2PServerTunnel: public I2PService

Loading…
Cancel
Save