Browse Source

add and remove tunnels without stopping others

pull/916/head
orignal 7 years ago
parent
commit
4c8c3b6947
  1. 55
      libi2pd_client/ClientContext.cpp
  2. 3
      libi2pd_client/ClientContext.h
  3. 5
      libi2pd_client/I2PService.cpp
  4. 3
      libi2pd_client/I2PService.h

55
libi2pd_client/ClientContext.cpp

@ -247,10 +247,17 @@ namespace client
void ClientContext::ReloadConfig () void ClientContext::ReloadConfig ()
{ {
std::string config; i2p::config::GetOption("conf", config); // TODO: handle config changes
i2p::config::ParseConfig(config); /*std::string config; i2p::config::GetOption("conf", config);
Stop(); i2p::config::ParseConfig(config);*/
Start();
// 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; });
// delete unused destinations // delete unused destinations
std::unique_lock<std::mutex> l(m_DestinationsMutex); std::unique_lock<std::mutex> l(m_DestinationsMutex);
@ -538,13 +545,18 @@ namespace client
clientTunnel = new I2PClientTunnel (name, dest, address, port, localDestination, destinationPort); clientTunnel = new I2PClientTunnel (name, dest, address, port, localDestination, destinationPort);
clientEndpoint = ((I2PClientTunnel*)clientTunnel)->GetAcceptor().local_endpoint(); clientEndpoint = ((I2PClientTunnel*)clientTunnel)->GetAcceptor().local_endpoint();
} }
if (m_ClientTunnels.insert (std::make_pair (clientEndpoint, std::unique_ptr<I2PService>(clientTunnel))).second) auto ins = m_ClientTunnels.insert (std::make_pair (clientEndpoint, std::unique_ptr<I2PService>(clientTunnel)));
if (ins.second)
{ {
clientTunnel->Start (); clientTunnel->Start ();
numClientTunnels++; numClientTunnels++;
} }
else else
LogPrint (eLogError, "Clients: I2P client tunnel for endpoint ", clientEndpoint, "already exists"); {
// TODO: update
ins.first->second->isUpdated = true;
LogPrint (eLogInfo, "Clients: I2P client tunnel for endpoint ", clientEndpoint, "already exists");
}
} }
} }
else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER
@ -637,15 +649,20 @@ namespace client
while (comma != std::string::npos); while (comma != std::string::npos);
serverTunnel->SetAccessList (idents); serverTunnel->SetAccessList (idents);
} }
if (m_ServerTunnels.insert (std::make_pair ( auto ins = m_ServerTunnels.insert (std::make_pair (
std::make_pair (localDestination->GetIdentHash (), inPort), std::make_pair (localDestination->GetIdentHash (), inPort),
std::unique_ptr<I2PServerTunnel>(serverTunnel))).second) std::unique_ptr<I2PServerTunnel>(serverTunnel)));
if (ins.second)
{ {
serverTunnel->Start (); serverTunnel->Start ();
numServerTunnels++; numServerTunnels++;
} }
else else
LogPrint (eLogError, "Clients: I2P server tunnel for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), "/", inPort, " already exists"); {
// TODO: update
ins.first->second->isUpdated = true;
LogPrint (eLogInfo, "Clients: I2P server tunnel for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), "/", inPort, " already exists");
}
} }
else else
@ -680,5 +697,25 @@ namespace client
ScheduleCleanupUDP(); ScheduleCleanupUDP();
} }
} }
template<typename Container, typename Visitor>
void VisitTunnelsContainer (Container& c, Visitor v)
{
for (auto it = c.begin (); it != c.end ();)
{
if (!v (it->second.get ()))
it = c.erase (it);
else
it++;
}
}
template<typename Visitor>
void ClientContext::VisitTunnels (Visitor v)
{
VisitTunnelsContainer (m_ClientTunnels, v);
VisitTunnelsContainer (m_ServerTunnels, v);
// TODO: implement UDP forwards
}
} }
} }

3
libi2pd_client/ClientContext.h

@ -89,6 +89,9 @@ namespace client
void CleanupUDP(const boost::system::error_code & ecode); void CleanupUDP(const boost::system::error_code & ecode);
void ScheduleCleanupUDP(); void ScheduleCleanupUDP();
template<typename Visitor>
void VisitTunnels (Visitor v); // Visitor: (I2PService *) -> bool, true means retain
private: private:
std::mutex m_DestinationsMutex; std::mutex m_DestinationsMutex;

5
libi2pd_client/I2PService.cpp

@ -11,13 +11,14 @@ namespace client
I2PService::I2PService (std::shared_ptr<ClientDestination> localDestination): I2PService::I2PService (std::shared_ptr<ClientDestination> localDestination):
m_LocalDestination (localDestination ? localDestination : m_LocalDestination (localDestination ? localDestination :
i2p::client::context.CreateNewLocalDestination (false, I2P_SERVICE_DEFAULT_KEY_TYPE)) i2p::client::context.CreateNewLocalDestination (false, I2P_SERVICE_DEFAULT_KEY_TYPE)), isUpdated (true)
{ {
m_LocalDestination->Acquire (); m_LocalDestination->Acquire ();
} }
I2PService::I2PService (i2p::data::SigningKeyType kt): I2PService::I2PService (i2p::data::SigningKeyType kt):
m_LocalDestination (i2p::client::context.CreateNewLocalDestination (false, kt)) m_LocalDestination (i2p::client::context.CreateNewLocalDestination (false, kt)),
isUpdated (true)
{ {
m_LocalDestination->Acquire (); m_LocalDestination->Acquire ();
} }

3
libi2pd_client/I2PService.h

@ -53,6 +53,9 @@ namespace client
std::shared_ptr<ClientDestination> m_LocalDestination; std::shared_ptr<ClientDestination> m_LocalDestination;
std::unordered_set<std::shared_ptr<I2PServiceHandler> > m_Handlers; std::unordered_set<std::shared_ptr<I2PServiceHandler> > m_Handlers;
std::mutex m_HandlersMutex; std::mutex m_HandlersMutex;
public:
bool isUpdated; // transient, used during reload only
}; };
/*Simple interface for I2PHandlers, allows detection of finalization amongst other things */ /*Simple interface for I2PHandlers, allows detection of finalization amongst other things */

Loading…
Cancel
Save