mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 13:27:17 +01:00
tunnels reload changes: fix tcp tunnels reload
Signed-off-by: R4SAS <r4sas@i2pmail.org>
This commit is contained in:
parent
349022ae42
commit
6b1ef6e1b9
|
@ -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
|
|||
for (auto& it: m_Destinations)
|
||||
it.second->Stop ();
|
||||
m_Destinations.clear ();
|
||||
|
||||
m_SharedLocalDestination->Release ();
|
||||
m_SharedLocalDestination = nullptr;
|
||||
}
|
||||
|
||||
|
@ -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
|
|||
if (m_HttpProxy)
|
||||
{
|
||||
m_HttpProxy->Stop ();
|
||||
delete m_HttpProxy;
|
||||
m_HttpProxy = nullptr;
|
||||
}
|
||||
ReadHttpProxy ();
|
||||
|
@ -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
|
|||
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
|
|||
if (it != destinations.end ())
|
||||
localDestination = it->second;
|
||||
else
|
||||
{
|
||||
{
|
||||
i2p::data::PrivateKeys k;
|
||||
if(LoadPrivateKeys (k, keys, sigType, cryptoType))
|
||||
{
|
||||
|
@ -597,7 +596,7 @@ namespace client
|
|||
destinations[keys] = localDestination;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) {
|
||||
|
@ -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
|
|||
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
|
|||
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
|
|||
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
|
|||
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
|
|||
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
|
|||
{
|
||||
localDestination = m_HttpProxy->GetLocalDestination ();
|
||||
localDestination->Acquire ();
|
||||
}
|
||||
}
|
||||
else if (socksProxyKeys.length () > 0)
|
||||
{
|
||||
i2p::data::PrivateKeys keys;
|
||||
|
@ -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);
|
||||
}
|
||||
else
|
||||
it = m_ClientTunnels.erase(it);
|
||||
} else {
|
||||
it->second->isUpdated = false;
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
void ClientContext::VisitTunnels (Visitor v)
|
||||
{
|
||||
VisitTunnelsContainer (m_ClientTunnels, v);
|
||||
VisitTunnelsContainer (m_ServerTunnels, v);
|
||||
// TODO: implement UDP forwards
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
|||
LogPrint(eLogInfo, "UDPServer: done");
|
||||
}
|
||||
|
||||
void I2PUDPServerTunnel::Start() {
|
||||
void I2PUDPServerTunnel::Start()
|
||||
{
|
||||
m_LocalDest->Start();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
|||
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
|
|||
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…
Reference in a new issue