mirror of
				https://github.com/PurpleI2P/i2pd.git
				synced 2025-11-04 08:30:46 +00:00 
			
		
		
		
	fix udp tunnels reload
Signed-off-by: R4SAS <r4sas@i2pmail.org>
This commit is contained in:
		
							parent
							
								
									2cd3ebbdb3
								
							
						
					
					
						commit
						923eb9fdb3
					
				
					 4 changed files with 183 additions and 150 deletions
				
			
		| 
						 | 
					@ -608,21 +608,29 @@ namespace client
 | 
				
			||||||
					if (type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) {
 | 
										if (type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) {
 | 
				
			||||||
						// udp client
 | 
											// udp client
 | 
				
			||||||
						// TODO: hostnames
 | 
											// TODO: hostnames
 | 
				
			||||||
						boost::asio::ip::udp::endpoint end(boost::asio::ip::address::from_string(address), port);
 | 
											boost::asio::ip::udp::endpoint end (boost::asio::ip::address::from_string(address), port);
 | 
				
			||||||
						if (!localDestination)
 | 
											if (!localDestination)
 | 
				
			||||||
							localDestination = m_SharedLocalDestination;
 | 
												localDestination = m_SharedLocalDestination;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						bool gzip = section.second.get (I2P_CLIENT_TUNNEL_GZIP, true);
 | 
											bool gzip = section.second.get (I2P_CLIENT_TUNNEL_GZIP, true);
 | 
				
			||||||
						auto clientTunnel = std::make_shared<I2PUDPClientTunnel>(name, dest, end, localDestination, destinationPort, gzip);
 | 
											auto clientTunnel = std::make_shared<I2PUDPClientTunnel> (name, dest, end, localDestination, destinationPort, gzip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						auto ins = m_ClientForwards.insert(std::make_pair(end, clientTunnel));
 | 
											auto ins = m_ClientForwards.insert (std::make_pair (end, clientTunnel));
 | 
				
			||||||
						if (ins.second)
 | 
											if (ins.second)
 | 
				
			||||||
						{
 | 
											{
 | 
				
			||||||
							clientTunnel->Start();
 | 
												clientTunnel->Start ();
 | 
				
			||||||
							numClientTunnels++;
 | 
												numClientTunnels++;
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						else
 | 
											else
 | 
				
			||||||
						{
 | 
											{
 | 
				
			||||||
 | 
												// TODO: update
 | 
				
			||||||
 | 
												if (ins.first->second->GetLocalDestination () != clientTunnel->GetLocalDestination ())
 | 
				
			||||||
 | 
												{
 | 
				
			||||||
 | 
													LogPrint (eLogInfo, "Clients: I2P UDP client tunnel destination updated");
 | 
				
			||||||
 | 
													ins.first->second->Stop ();
 | 
				
			||||||
 | 
													ins.first->second->SetLocalDestination (clientTunnel->GetLocalDestination ());
 | 
				
			||||||
 | 
													ins.first->second->Start ();
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
							ins.first->second->isUpdated = true;
 | 
												ins.first->second->isUpdated = true;
 | 
				
			||||||
							LogPrint(eLogError, "Clients: I2P Client forward for endpoint ", end, " already exists");
 | 
												LogPrint(eLogError, "Clients: I2P Client forward for endpoint ", end, " already exists");
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
| 
						 | 
					@ -976,11 +984,11 @@ namespace client
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* // TODO: Write correct UDP tunnels stop
 | 
							// TODO: Write correct UDP tunnels stop
 | 
				
			||||||
		for (auto it = m_ClientForwards.begin (); it != m_ClientForwards.end ();)
 | 
							for (auto it = m_ClientForwards.begin (); it != m_ClientForwards.end ();)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if(clean && !it->second->isUpdated) {
 | 
								if(clean && !it->second->isUpdated) {
 | 
				
			||||||
				it->second = nullptr;
 | 
									it->second->Stop ();
 | 
				
			||||||
				it = m_ClientForwards.erase(it);
 | 
									it = m_ClientForwards.erase(it);
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				it->second->isUpdated = false;
 | 
									it->second->isUpdated = false;
 | 
				
			||||||
| 
						 | 
					@ -991,13 +999,13 @@ namespace client
 | 
				
			||||||
		for (auto it = m_ServerForwards.begin (); it != m_ServerForwards.end ();)
 | 
							for (auto it = m_ServerForwards.begin (); it != m_ServerForwards.end ();)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if(clean && !it->second->isUpdated) {
 | 
								if(clean && !it->second->isUpdated) {
 | 
				
			||||||
				it->second = nullptr;
 | 
									it->second->Stop ();
 | 
				
			||||||
				it = m_ServerForwards.erase(it);
 | 
									it = m_ServerForwards.erase(it);
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				it->second->isUpdated = false;
 | 
									it->second->isUpdated = false;
 | 
				
			||||||
				it++;
 | 
									it++;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} */
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -142,8 +142,8 @@ namespace client
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			i2p::proxy::HTTPProxy * m_HttpProxy;
 | 
								i2p::proxy::HTTPProxy * m_HttpProxy;
 | 
				
			||||||
			i2p::proxy::SOCKSProxy * m_SocksProxy;
 | 
								i2p::proxy::SOCKSProxy * m_SocksProxy;
 | 
				
			||||||
			std::map<boost::asio::ip::tcp::endpoint, std::shared_ptr<I2PService> > m_ClientTunnels; // local endpoint->tunnel
 | 
								std::map<boost::asio::ip::tcp::endpoint, std::shared_ptr<I2PService> > m_ClientTunnels; // local endpoint -> tunnel
 | 
				
			||||||
			std::map<std::pair<i2p::data::IdentHash, int>, std::shared_ptr<I2PServerTunnel> > m_ServerTunnels; // <destination,port>->tunnel
 | 
								std::map<std::pair<i2p::data::IdentHash, int>, std::shared_ptr<I2PServerTunnel> > m_ServerTunnels; // <destination,port> -> tunnel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			std::mutex m_ForwardsMutex;
 | 
								std::mutex m_ForwardsMutex;
 | 
				
			||||||
			std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<I2PUDPClientTunnel> > m_ClientForwards; // local endpoint -> udp tunnel
 | 
								std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<I2PUDPClientTunnel> > m_ClientForwards; // local endpoint -> udp tunnel
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -583,7 +583,7 @@ namespace client
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (m_KeepAliveTimer)
 | 
							if (m_KeepAliveTimer)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			m_KeepAliveTimer->expires_from_now (boost::posix_time::seconds(m_KeepAliveInterval));
 | 
								m_KeepAliveTimer->expires_from_now (boost::posix_time::seconds (m_KeepAliveInterval));
 | 
				
			||||||
			m_KeepAliveTimer->async_wait (std::bind (&I2PClientTunnel::HandleKeepAliveTimer,
 | 
								m_KeepAliveTimer->async_wait (std::bind (&I2PClientTunnel::HandleKeepAliveTimer,
 | 
				
			||||||
				this, std::placeholders::_1));
 | 
									this, std::placeholders::_1));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -796,7 +796,8 @@ namespace client
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void I2PUDPServerTunnel::ExpireStale(const uint64_t delta) {
 | 
						void I2PUDPServerTunnel::ExpireStale(const uint64_t delta)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
		std::lock_guard<std::mutex> lock(m_SessionsMutex);
 | 
							std::lock_guard<std::mutex> lock(m_SessionsMutex);
 | 
				
			||||||
		uint64_t now = i2p::util::GetMillisecondsSinceEpoch();
 | 
							uint64_t now = i2p::util::GetMillisecondsSinceEpoch();
 | 
				
			||||||
		auto itr = m_Sessions.begin();
 | 
							auto itr = m_Sessions.begin();
 | 
				
			||||||
| 
						 | 
					@ -808,7 +809,8 @@ namespace client
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void I2PUDPClientTunnel::ExpireStale(const uint64_t delta) {
 | 
						void I2PUDPClientTunnel::ExpireStale(const uint64_t delta)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
		std::lock_guard<std::mutex> lock(m_SessionsMutex);
 | 
							std::lock_guard<std::mutex> lock(m_SessionsMutex);
 | 
				
			||||||
		uint64_t now = i2p::util::GetMillisecondsSinceEpoch();
 | 
							uint64_t now = i2p::util::GetMillisecondsSinceEpoch();
 | 
				
			||||||
		std::vector<uint16_t> removePorts;
 | 
							std::vector<uint16_t> removePorts;
 | 
				
			||||||
| 
						 | 
					@ -864,7 +866,8 @@ namespace client
 | 
				
			||||||
		Receive();
 | 
							Receive();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void UDPSession::Receive() {
 | 
						void UDPSession::Receive()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
		LogPrint(eLogDebug, "UDPSession: Receive");
 | 
							LogPrint(eLogDebug, "UDPSession: Receive");
 | 
				
			||||||
		IPSocket.async_receive_from(boost::asio::buffer(m_Buffer, I2P_UDP_MAX_MTU),
 | 
							IPSocket.async_receive_from(boost::asio::buffer(m_Buffer, I2P_UDP_MAX_MTU),
 | 
				
			||||||
			FromEndpoint, std::bind(&UDPSession::HandleReceived, this, std::placeholders::_1, std::placeholders::_2));
 | 
								FromEndpoint, std::bind(&UDPSession::HandleReceived, this, std::placeholders::_1, std::placeholders::_2));
 | 
				
			||||||
| 
						 | 
					@ -901,230 +904,239 @@ namespace client
 | 
				
			||||||
			LogPrint(eLogError, "UDPSession: ", ecode.message());
 | 
								LogPrint(eLogError, "UDPSession: ", ecode.message());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	I2PUDPServerTunnel::I2PUDPServerTunnel(const std::string & name, std::shared_ptr<i2p::client::ClientDestination> localDestination,
 | 
						I2PUDPServerTunnel::I2PUDPServerTunnel (const std::string & name, std::shared_ptr<i2p::client::ClientDestination> localDestination,
 | 
				
			||||||
		boost::asio::ip::address localAddress, boost::asio::ip::udp::endpoint forwardTo, uint16_t port, bool gzip) :
 | 
							boost::asio::ip::address localAddress, boost::asio::ip::udp::endpoint forwardTo, uint16_t port, bool gzip) :
 | 
				
			||||||
		m_IsUniqueLocal(true),
 | 
							m_IsUniqueLocal (true), m_Name (name), m_LocalAddress (localAddress), m_LocalDest (localDestination), m_RemoteEndpoint (forwardTo), m_Gzip (gzip)
 | 
				
			||||||
		m_Name(name),
 | 
					 | 
				
			||||||
		m_LocalAddress(localAddress),
 | 
					 | 
				
			||||||
		m_RemoteEndpoint(forwardTo)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		m_LocalDest = localDestination;
 | 
					 | 
				
			||||||
		m_LocalDest->Start();
 | 
					 | 
				
			||||||
		auto dgram = m_LocalDest->CreateDatagramDestination(gzip);
 | 
					 | 
				
			||||||
		dgram->SetReceiver(std::bind(&I2PUDPServerTunnel::HandleRecvFromI2P, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
 | 
					 | 
				
			||||||
		dgram->SetRawReceiver(std::bind(&I2PUDPServerTunnel::HandleRecvFromI2PRaw, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	I2PUDPServerTunnel::~I2PUDPServerTunnel()
 | 
						I2PUDPServerTunnel::~I2PUDPServerTunnel ()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		auto dgram = m_LocalDest->GetDatagramDestination();
 | 
							Stop ();
 | 
				
			||||||
		if (dgram) dgram->ResetReceiver();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		LogPrint(eLogInfo, "UDPServer: Done");
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void I2PUDPServerTunnel::Start()
 | 
						void I2PUDPServerTunnel::Start ()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		m_LocalDest->Start();
 | 
							m_LocalDest->Start ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							auto dgram = m_LocalDest->CreateDatagramDestination (m_Gzip);
 | 
				
			||||||
 | 
							dgram->SetReceiver (std::bind (&I2PUDPServerTunnel::HandleRecvFromI2P, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
 | 
				
			||||||
 | 
							dgram->SetRawReceiver (std::bind (&I2PUDPServerTunnel::HandleRecvFromI2PRaw, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::vector<std::shared_ptr<DatagramSessionInfo> > I2PUDPServerTunnel::GetSessions()
 | 
						void I2PUDPServerTunnel::Stop ()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							auto dgram = m_LocalDest->GetDatagramDestination ();
 | 
				
			||||||
 | 
							if (dgram) dgram->ResetReceiver ();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::vector<std::shared_ptr<DatagramSessionInfo> > I2PUDPServerTunnel::GetSessions ()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		std::vector<std::shared_ptr<DatagramSessionInfo> > sessions;
 | 
							std::vector<std::shared_ptr<DatagramSessionInfo> > sessions;
 | 
				
			||||||
		std::lock_guard<std::mutex> lock(m_SessionsMutex);
 | 
							std::lock_guard<std::mutex> lock (m_SessionsMutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for ( UDPSessionPtr s : m_Sessions )
 | 
							for (UDPSessionPtr s: m_Sessions)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (!s->m_Destination) continue;
 | 
								if (!s->m_Destination) continue;
 | 
				
			||||||
			auto info = s->m_Destination->GetInfoForRemote(s->Identity);
 | 
								auto info = s->m_Destination->GetInfoForRemote (s->Identity);
 | 
				
			||||||
			if(!info) continue;
 | 
								if (!info) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			auto sinfo = std::make_shared<DatagramSessionInfo>();
 | 
								auto sinfo = std::make_shared<DatagramSessionInfo> ();
 | 
				
			||||||
			sinfo->Name = m_Name;
 | 
								sinfo->Name = m_Name;
 | 
				
			||||||
			sinfo->LocalIdent = std::make_shared<i2p::data::IdentHash>(m_LocalDest->GetIdentHash().data());
 | 
								sinfo->LocalIdent = std::make_shared<i2p::data::IdentHash> (m_LocalDest->GetIdentHash ().data ());
 | 
				
			||||||
			sinfo->RemoteIdent = std::make_shared<i2p::data::IdentHash>(s->Identity.data());
 | 
								sinfo->RemoteIdent = std::make_shared<i2p::data::IdentHash> (s->Identity.data ());
 | 
				
			||||||
			sinfo->CurrentIBGW = info->IBGW;
 | 
								sinfo->CurrentIBGW = info->IBGW;
 | 
				
			||||||
			sinfo->CurrentOBEP = info->OBEP;
 | 
								sinfo->CurrentOBEP = info->OBEP;
 | 
				
			||||||
			sessions.push_back(sinfo);
 | 
								sessions.push_back (sinfo);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return sessions;
 | 
							return sessions;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	I2PUDPClientTunnel::I2PUDPClientTunnel(const std::string & name, const std::string &remoteDest,
 | 
						I2PUDPClientTunnel::I2PUDPClientTunnel (const std::string & name, const std::string &remoteDest,
 | 
				
			||||||
		boost::asio::ip::udp::endpoint localEndpoint,
 | 
							boost::asio::ip::udp::endpoint localEndpoint,
 | 
				
			||||||
		std::shared_ptr<i2p::client::ClientDestination> localDestination,
 | 
							std::shared_ptr<i2p::client::ClientDestination> localDestination,
 | 
				
			||||||
		uint16_t remotePort, bool gzip) :
 | 
							uint16_t remotePort, bool gzip) :
 | 
				
			||||||
		m_Name(name),
 | 
							m_Name (name), m_RemoteDest (remoteDest), m_LocalDest (localDestination), m_LocalEndpoint (localEndpoint),
 | 
				
			||||||
		m_RemoteDest(remoteDest),
 | 
							m_RemoteIdent (nullptr), m_ResolveThread (nullptr), m_LocalSocket (nullptr), RemotePort (remotePort),
 | 
				
			||||||
		m_LocalDest(localDestination),
 | 
							m_LastPort (0), m_cancel_resolve (false), m_Gzip (gzip)
 | 
				
			||||||
		m_LocalEndpoint(localEndpoint),
 | 
					 | 
				
			||||||
		m_RemoteIdent(nullptr),
 | 
					 | 
				
			||||||
		m_ResolveThread(nullptr),
 | 
					 | 
				
			||||||
		m_LocalSocket(localDestination->GetService(), localEndpoint),
 | 
					 | 
				
			||||||
		RemotePort(remotePort), m_LastPort (0),
 | 
					 | 
				
			||||||
		m_cancel_resolve(false)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		m_LocalSocket.set_option (boost::asio::socket_base::receive_buffer_size (I2P_UDP_MAX_MTU));
 | 
						}
 | 
				
			||||||
		m_LocalSocket.set_option (boost::asio::socket_base::reuse_address (true));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		auto dgram = m_LocalDest->CreateDatagramDestination(gzip);
 | 
						I2PUDPClientTunnel::~I2PUDPClientTunnel ()
 | 
				
			||||||
		dgram->SetReceiver(std::bind(&I2PUDPClientTunnel::HandleRecvFromI2P, this,
 | 
						{
 | 
				
			||||||
 | 
							Stop ();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void I2PUDPClientTunnel::Start ()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// Reset flag in case of tunnel reload
 | 
				
			||||||
 | 
							if (m_cancel_resolve) m_cancel_resolve = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							m_LocalSocket.reset (new boost::asio::ip::udp::socket (m_LocalDest->GetService (), m_LocalEndpoint));
 | 
				
			||||||
 | 
							m_LocalSocket->set_option (boost::asio::socket_base::receive_buffer_size (I2P_UDP_MAX_MTU));
 | 
				
			||||||
 | 
							m_LocalSocket->set_option (boost::asio::socket_base::reuse_address (true));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							auto dgram = m_LocalDest->CreateDatagramDestination (m_Gzip);
 | 
				
			||||||
 | 
							dgram->SetReceiver (std::bind (&I2PUDPClientTunnel::HandleRecvFromI2P, this,
 | 
				
			||||||
			std::placeholders::_1, std::placeholders::_2,
 | 
								std::placeholders::_1, std::placeholders::_2,
 | 
				
			||||||
			std::placeholders::_3, std::placeholders::_4,
 | 
								std::placeholders::_3, std::placeholders::_4,
 | 
				
			||||||
			std::placeholders::_5));
 | 
								std::placeholders::_5));
 | 
				
			||||||
		dgram->SetRawReceiver(std::bind(&I2PUDPClientTunnel::HandleRecvFromI2PRaw, this,
 | 
							dgram->SetRawReceiver (std::bind (&I2PUDPClientTunnel::HandleRecvFromI2PRaw, this,
 | 
				
			||||||
			std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
 | 
								std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void I2PUDPClientTunnel::Start() {
 | 
							m_LocalDest->Start ();
 | 
				
			||||||
		m_LocalDest->Start();
 | 
					 | 
				
			||||||
		if (m_ResolveThread == nullptr)
 | 
							if (m_ResolveThread == nullptr)
 | 
				
			||||||
			m_ResolveThread = new std::thread(std::bind(&I2PUDPClientTunnel::TryResolving, this));
 | 
								m_ResolveThread = new std::thread (std::bind (&I2PUDPClientTunnel::TryResolving, this));
 | 
				
			||||||
		RecvFromLocal();
 | 
							RecvFromLocal ();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void I2PUDPClientTunnel::RecvFromLocal()
 | 
						void I2PUDPClientTunnel::Stop ()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		m_LocalSocket.async_receive_from(boost::asio::buffer(m_RecvBuff, I2P_UDP_MAX_MTU),
 | 
							auto dgram = m_LocalDest->GetDatagramDestination ();
 | 
				
			||||||
			m_RecvEndpoint, std::bind(&I2PUDPClientTunnel::HandleRecvFromLocal, this, std::placeholders::_1, std::placeholders::_2));
 | 
							if (dgram) dgram->ResetReceiver ();
 | 
				
			||||||
 | 
							m_cancel_resolve = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							m_Sessions.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(m_LocalSocket && m_LocalSocket->is_open ())
 | 
				
			||||||
 | 
								m_LocalSocket->close ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(m_ResolveThread)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								m_ResolveThread->join ();
 | 
				
			||||||
 | 
								delete m_ResolveThread;
 | 
				
			||||||
 | 
								m_ResolveThread = nullptr;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (m_RemoteIdent)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								delete m_RemoteIdent;
 | 
				
			||||||
 | 
								m_RemoteIdent = nullptr;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void I2PUDPClientTunnel::HandleRecvFromLocal(const boost::system::error_code & ec, std::size_t transferred)
 | 
						void I2PUDPClientTunnel::RecvFromLocal ()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if(m_cancel_resolve) {
 | 
							m_LocalSocket->async_receive_from (boost::asio::buffer (m_RecvBuff, I2P_UDP_MAX_MTU),
 | 
				
			||||||
			LogPrint(eLogDebug, "UDP Client: Ignoring incomming data: stopping");
 | 
								m_RecvEndpoint, std::bind (&I2PUDPClientTunnel::HandleRecvFromLocal, this, std::placeholders::_1, std::placeholders::_2));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void I2PUDPClientTunnel::HandleRecvFromLocal (const boost::system::error_code & ec, std::size_t transferred)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (m_cancel_resolve) {
 | 
				
			||||||
 | 
								LogPrint (eLogDebug, "UDP Client: Ignoring incomming data: stopping");
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if(ec) {
 | 
							if (ec) {
 | 
				
			||||||
			LogPrint(eLogError, "UDP Client: Reading from socket error: ", ec.message(), ". Restarting listener...");
 | 
								LogPrint (eLogError, "UDP Client: Reading from socket error: ", ec.message (), ". Restarting listener...");
 | 
				
			||||||
			RecvFromLocal(); // Restart listener and continue work
 | 
								RecvFromLocal (); // Restart listener and continue work
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if(!m_RemoteIdent) {
 | 
							if (!m_RemoteIdent) {
 | 
				
			||||||
			LogPrint(eLogWarning, "UDP Client: Remote endpoint not resolved yet");
 | 
								LogPrint (eLogWarning, "UDP Client: Remote endpoint not resolved yet");
 | 
				
			||||||
			RecvFromLocal();
 | 
								RecvFromLocal ();
 | 
				
			||||||
			return; // drop, remote not resolved
 | 
								return; // drop, remote not resolved
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		auto remotePort = m_RecvEndpoint.port();
 | 
							auto remotePort = m_RecvEndpoint.port ();
 | 
				
			||||||
		if (!m_LastPort || m_LastPort != remotePort)
 | 
							if (!m_LastPort || m_LastPort != remotePort)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			auto itr = m_Sessions.find(remotePort);
 | 
								auto itr = m_Sessions.find (remotePort);
 | 
				
			||||||
			if (itr != m_Sessions.end())
 | 
								if (itr != m_Sessions.end ())
 | 
				
			||||||
				m_LastSession = itr->second;
 | 
									m_LastSession = itr->second;
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				m_LastSession = std::make_shared<UDPConvo>(boost::asio::ip::udp::endpoint(m_RecvEndpoint), 0);
 | 
									m_LastSession = std::make_shared<UDPConvo> (boost::asio::ip::udp::endpoint (m_RecvEndpoint), 0);
 | 
				
			||||||
				m_Sessions.emplace (remotePort, m_LastSession);
 | 
									m_Sessions.emplace (remotePort, m_LastSession);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			m_LastPort = remotePort;
 | 
								m_LastPort = remotePort;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// send off to remote i2p destination
 | 
							// send off to remote i2p destination
 | 
				
			||||||
		auto ts = i2p::util::GetMillisecondsSinceEpoch();
 | 
							auto ts = i2p::util::GetMillisecondsSinceEpoch ();
 | 
				
			||||||
		LogPrint(eLogDebug, "UDP Client: Send ", transferred, " to ", m_RemoteIdent->ToBase32(), ":", RemotePort);
 | 
							LogPrint (eLogDebug, "UDP Client: Send ", transferred, " to ", m_RemoteIdent->ToBase32 (), ":", RemotePort);
 | 
				
			||||||
		auto session = m_LocalDest->GetDatagramDestination()->GetSession (*m_RemoteIdent);
 | 
							auto session = m_LocalDest->GetDatagramDestination ()->GetSession (*m_RemoteIdent);
 | 
				
			||||||
		if (ts > m_LastSession->second + I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL)
 | 
							if (ts > m_LastSession->second + I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL)
 | 
				
			||||||
			m_LocalDest->GetDatagramDestination()->SendDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort);
 | 
								m_LocalDest->GetDatagramDestination ()->SendDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			m_LocalDest->GetDatagramDestination()->SendRawDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort);
 | 
								m_LocalDest->GetDatagramDestination ()->SendRawDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort);
 | 
				
			||||||
		size_t numPackets = 0;
 | 
							size_t numPackets = 0;
 | 
				
			||||||
		while (numPackets < i2p::datagram::DATAGRAM_SEND_QUEUE_MAX_SIZE)
 | 
							while (numPackets < i2p::datagram::DATAGRAM_SEND_QUEUE_MAX_SIZE)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			boost::system::error_code ec;
 | 
								boost::system::error_code ec;
 | 
				
			||||||
			size_t moreBytes = m_LocalSocket.available(ec);
 | 
								size_t moreBytes = m_LocalSocket->available (ec);
 | 
				
			||||||
			if (ec || !moreBytes) break;
 | 
								if (ec || !moreBytes) break;
 | 
				
			||||||
			transferred = m_LocalSocket.receive_from (boost::asio::buffer (m_RecvBuff, I2P_UDP_MAX_MTU), m_RecvEndpoint, 0, ec);
 | 
								transferred = m_LocalSocket->receive_from (boost::asio::buffer (m_RecvBuff, I2P_UDP_MAX_MTU), m_RecvEndpoint, 0, ec);
 | 
				
			||||||
			remotePort = m_RecvEndpoint.port();
 | 
								remotePort = m_RecvEndpoint.port ();
 | 
				
			||||||
			// TODO: check remotePort
 | 
								// TODO: check remotePort
 | 
				
			||||||
			m_LocalDest->GetDatagramDestination()->SendRawDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort);
 | 
								m_LocalDest->GetDatagramDestination ()->SendRawDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort);
 | 
				
			||||||
			numPackets++;
 | 
								numPackets++;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (numPackets)
 | 
							if (numPackets)
 | 
				
			||||||
			LogPrint(eLogDebug, "UDP Client: Sent ", numPackets, " more packets to ", m_RemoteIdent->ToBase32());
 | 
								LogPrint (eLogDebug, "UDP Client: Sent ", numPackets, " more packets to ", m_RemoteIdent->ToBase32 ());
 | 
				
			||||||
		m_LocalDest->GetDatagramDestination()->FlushSendQueue (session);
 | 
							m_LocalDest->GetDatagramDestination ()->FlushSendQueue (session);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// mark convo as active
 | 
							// mark convo as active
 | 
				
			||||||
		if (m_LastSession)
 | 
							if (m_LastSession)
 | 
				
			||||||
			m_LastSession->second = ts;
 | 
								m_LastSession->second = ts;
 | 
				
			||||||
		RecvFromLocal();
 | 
							RecvFromLocal ();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::vector<std::shared_ptr<DatagramSessionInfo> > I2PUDPClientTunnel::GetSessions()
 | 
						std::vector<std::shared_ptr<DatagramSessionInfo> > I2PUDPClientTunnel::GetSessions ()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		// TODO: implement
 | 
							// TODO: implement
 | 
				
			||||||
		std::vector<std::shared_ptr<DatagramSessionInfo> > infos;
 | 
							std::vector<std::shared_ptr<DatagramSessionInfo> > infos;
 | 
				
			||||||
		return infos;
 | 
							return infos;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void I2PUDPClientTunnel::TryResolving() {
 | 
						void I2PUDPClientTunnel::TryResolving ()
 | 
				
			||||||
		i2p::util::SetThreadName("UDP Resolver");
 | 
						{
 | 
				
			||||||
		LogPrint(eLogInfo, "UDP Tunnel: Trying to resolve ", m_RemoteDest);
 | 
							i2p::util::SetThreadName ("UDP Resolver");
 | 
				
			||||||
 | 
							LogPrint (eLogInfo, "UDP Tunnel: Trying to resolve ", m_RemoteDest);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		std::shared_ptr<const Address> addr;
 | 
							std::shared_ptr<const Address> addr;
 | 
				
			||||||
		while(!(addr = context.GetAddressBook().GetAddress(m_RemoteDest)) && !m_cancel_resolve)
 | 
							while (!(addr = context.GetAddressBook().GetAddress(m_RemoteDest)) && !m_cancel_resolve)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			LogPrint(eLogWarning, "UDP Tunnel: Failed to lookup ", m_RemoteDest);
 | 
								LogPrint (eLogWarning, "UDP Tunnel: Failed to lookup ", m_RemoteDest);
 | 
				
			||||||
			std::this_thread::sleep_for(std::chrono::seconds(1));
 | 
								std::this_thread::sleep_for (std::chrono::seconds (1));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if(m_cancel_resolve)
 | 
							if (m_cancel_resolve)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			LogPrint(eLogError, "UDP Tunnel: Lookup of ", m_RemoteDest, " was cancelled");
 | 
								LogPrint(eLogError, "UDP Tunnel: Lookup of ", m_RemoteDest, " was cancelled");
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (!addr || !addr->IsIdentHash ())
 | 
							if (!addr || !addr->IsIdentHash ())
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			LogPrint(eLogError, "UDP Tunnel: ", m_RemoteDest, " not found");
 | 
								LogPrint (eLogError, "UDP Tunnel: ", m_RemoteDest, " not found");
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		m_RemoteIdent = new i2p::data::IdentHash;
 | 
							m_RemoteIdent = new i2p::data::IdentHash;
 | 
				
			||||||
		*m_RemoteIdent = addr->identHash;
 | 
							*m_RemoteIdent = addr->identHash;
 | 
				
			||||||
		LogPrint(eLogInfo, "UDP Tunnel: Resolved ", m_RemoteDest, " to ", m_RemoteIdent->ToBase32());
 | 
							LogPrint(eLogInfo, "UDP Tunnel: Resolved ", m_RemoteDest, " to ", m_RemoteIdent->ToBase32 ());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void I2PUDPClientTunnel::HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
 | 
						void I2PUDPClientTunnel::HandleRecvFromI2P (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if(m_RemoteIdent && from.GetIdentHash() == *m_RemoteIdent)
 | 
							if (m_RemoteIdent && from.GetIdentHash() == *m_RemoteIdent)
 | 
				
			||||||
			HandleRecvFromI2PRaw (fromPort, toPort, buf, len);
 | 
								HandleRecvFromI2PRaw (fromPort, toPort, buf, len);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			LogPrint(eLogWarning, "UDP Client: Unwarranted traffic from ", from.GetIdentHash().ToBase32());
 | 
								LogPrint(eLogWarning, "UDP Client: Unwarranted traffic from ", from.GetIdentHash().ToBase32 ());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void I2PUDPClientTunnel::HandleRecvFromI2PRaw(uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
 | 
						void I2PUDPClientTunnel::HandleRecvFromI2PRaw (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		auto itr = m_Sessions.find(toPort);
 | 
							auto itr = m_Sessions.find (toPort);
 | 
				
			||||||
		// found convo ?
 | 
							// found convo ?
 | 
				
			||||||
		if(itr != m_Sessions.end())
 | 
							if (itr != m_Sessions.end ())
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			// found convo
 | 
								// found convo
 | 
				
			||||||
			if (len > 0)
 | 
								if (len > 0)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				LogPrint(eLogDebug, "UDP Client: Got ", len, "B from ", m_RemoteIdent ? m_RemoteIdent->ToBase32() : "");
 | 
									LogPrint (eLogDebug, "UDP Client: Got ", len, "B from ", m_RemoteIdent ? m_RemoteIdent->ToBase32 () : "");
 | 
				
			||||||
				m_LocalSocket.send_to(boost::asio::buffer(buf, len), itr->second->first);
 | 
									m_LocalSocket->send_to (boost::asio::buffer (buf, len), itr->second->first);
 | 
				
			||||||
				// mark convo as active
 | 
									// mark convo as active
 | 
				
			||||||
				itr->second->second = i2p::util::GetMillisecondsSinceEpoch();
 | 
									itr->second->second = i2p::util::GetMillisecondsSinceEpoch ();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			LogPrint(eLogWarning, "UDP Client: Not tracking udp session using port ", (int) toPort);
 | 
								LogPrint (eLogWarning, "UDP Client: Not tracking udp session using port ", (int) toPort);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	I2PUDPClientTunnel::~I2PUDPClientTunnel()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		auto dgram = m_LocalDest->GetDatagramDestination();
 | 
					 | 
				
			||||||
		if (dgram) dgram->ResetReceiver();
 | 
					 | 
				
			||||||
		m_cancel_resolve = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		m_Sessions.clear();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if(m_LocalSocket.is_open())
 | 
					 | 
				
			||||||
			m_LocalSocket.close();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if(m_ResolveThread)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			m_ResolveThread->join();
 | 
					 | 
				
			||||||
			delete m_ResolveThread;
 | 
					 | 
				
			||||||
			m_ResolveThread = nullptr;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (m_RemoteIdent) delete m_RemoteIdent;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -230,25 +230,27 @@ namespace client
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		public:
 | 
							public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			I2PUDPServerTunnel(const std::string & name,
 | 
								I2PUDPServerTunnel (const std::string & name,
 | 
				
			||||||
				std::shared_ptr<i2p::client::ClientDestination> localDestination,
 | 
									std::shared_ptr<i2p::client::ClientDestination> localDestination,
 | 
				
			||||||
				boost::asio::ip::address localAddress,
 | 
									boost::asio::ip::address localAddress,
 | 
				
			||||||
				boost::asio::ip::udp::endpoint forwardTo, uint16_t port, bool gzip);
 | 
									boost::asio::ip::udp::endpoint forwardTo, uint16_t port, bool gzip);
 | 
				
			||||||
			~I2PUDPServerTunnel();
 | 
								~I2PUDPServerTunnel ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/** expire stale udp conversations */
 | 
								/** expire stale udp conversations */
 | 
				
			||||||
			void ExpireStale(const uint64_t delta=I2P_UDP_SESSION_TIMEOUT);
 | 
								void ExpireStale (const uint64_t delta=I2P_UDP_SESSION_TIMEOUT);
 | 
				
			||||||
			void Start();
 | 
								void Start ();
 | 
				
			||||||
			const char * GetName() const { return m_Name.c_str(); }
 | 
								void Stop ();
 | 
				
			||||||
			std::vector<std::shared_ptr<DatagramSessionInfo> > GetSessions();
 | 
								const char * GetName () const { return m_Name.c_str(); }
 | 
				
			||||||
 | 
								std::vector<std::shared_ptr<DatagramSessionInfo> > GetSessions ();
 | 
				
			||||||
			std::shared_ptr<ClientDestination> GetLocalDestination () const { return m_LocalDest; }
 | 
								std::shared_ptr<ClientDestination> GetLocalDestination () const { return m_LocalDest; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			void SetUniqueLocal(bool isUniqueLocal = true) { m_IsUniqueLocal = isUniqueLocal; }
 | 
								void SetUniqueLocal (bool isUniqueLocal = true) { m_IsUniqueLocal = isUniqueLocal; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private:
 | 
							private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			void HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
 | 
								void HandleRecvFromI2P (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
 | 
				
			||||||
			void HandleRecvFromI2PRaw (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
 | 
								void HandleRecvFromI2PRaw (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
 | 
				
			||||||
			UDPSessionPtr ObtainUDPSession(const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort);
 | 
								UDPSessionPtr ObtainUDPSession (const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private:
 | 
							private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -260,6 +262,7 @@ namespace client
 | 
				
			||||||
			std::vector<UDPSessionPtr> m_Sessions;
 | 
								std::vector<UDPSessionPtr> m_Sessions;
 | 
				
			||||||
			std::shared_ptr<i2p::client::ClientDestination> m_LocalDest;
 | 
								std::shared_ptr<i2p::client::ClientDestination> m_LocalDest;
 | 
				
			||||||
			UDPSessionPtr m_LastSession;
 | 
								UDPSessionPtr m_LastSession;
 | 
				
			||||||
 | 
								bool m_Gzip;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public:
 | 
							public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -270,27 +273,36 @@ namespace client
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		public:
 | 
							public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			I2PUDPClientTunnel(const std::string & name, const std::string &remoteDest,
 | 
								I2PUDPClientTunnel (const std::string & name, const std::string &remoteDest,
 | 
				
			||||||
				boost::asio::ip::udp::endpoint localEndpoint, std::shared_ptr<i2p::client::ClientDestination> localDestination,
 | 
									boost::asio::ip::udp::endpoint localEndpoint, std::shared_ptr<i2p::client::ClientDestination> localDestination,
 | 
				
			||||||
				uint16_t remotePort, bool gzip);
 | 
									uint16_t remotePort, bool gzip);
 | 
				
			||||||
			~I2PUDPClientTunnel();
 | 
								~I2PUDPClientTunnel ();
 | 
				
			||||||
			void Start();
 | 
					 | 
				
			||||||
			const char * GetName() const { return m_Name.c_str(); }
 | 
					 | 
				
			||||||
			std::vector<std::shared_ptr<DatagramSessionInfo> > GetSessions();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			bool IsLocalDestination(const i2p::data::IdentHash & destination) const { return destination == m_LocalDest->GetIdentHash(); }
 | 
								void Start ();
 | 
				
			||||||
 | 
								void Stop ();
 | 
				
			||||||
 | 
								const char * GetName () const { return m_Name.c_str(); }
 | 
				
			||||||
 | 
								std::vector<std::shared_ptr<DatagramSessionInfo> > GetSessions ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								bool IsLocalDestination (const i2p::data::IdentHash & destination) const { return destination == m_LocalDest->GetIdentHash(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			std::shared_ptr<ClientDestination> GetLocalDestination () const { return m_LocalDest; }
 | 
								std::shared_ptr<ClientDestination> GetLocalDestination () const { return m_LocalDest; }
 | 
				
			||||||
			void ExpireStale(const uint64_t delta=I2P_UDP_SESSION_TIMEOUT);
 | 
								inline void SetLocalDestination (std::shared_ptr<ClientDestination> dest)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (m_LocalDest) m_LocalDest->Release ();
 | 
				
			||||||
 | 
									if (dest) dest->Acquire ();
 | 
				
			||||||
 | 
									m_LocalDest = dest;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								void ExpireStale (const uint64_t delta=I2P_UDP_SESSION_TIMEOUT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private:
 | 
							private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			typedef std::pair<boost::asio::ip::udp::endpoint, uint64_t> UDPConvo;
 | 
								typedef std::pair<boost::asio::ip::udp::endpoint, uint64_t> UDPConvo;
 | 
				
			||||||
			void RecvFromLocal();
 | 
								void RecvFromLocal ();
 | 
				
			||||||
			void HandleRecvFromLocal(const boost::system::error_code & e, std::size_t transferred);
 | 
								void HandleRecvFromLocal (const boost::system::error_code & e, std::size_t transferred);
 | 
				
			||||||
			void HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
 | 
								void HandleRecvFromI2P (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
 | 
				
			||||||
			void HandleRecvFromI2PRaw(uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
 | 
								void HandleRecvFromI2PRaw (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
 | 
				
			||||||
			void TryResolving();
 | 
								void TryResolving ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private:
 | 
							private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -302,11 +314,12 @@ namespace client
 | 
				
			||||||
			const boost::asio::ip::udp::endpoint m_LocalEndpoint;
 | 
								const boost::asio::ip::udp::endpoint m_LocalEndpoint;
 | 
				
			||||||
			i2p::data::IdentHash * m_RemoteIdent;
 | 
								i2p::data::IdentHash * m_RemoteIdent;
 | 
				
			||||||
			std::thread * m_ResolveThread;
 | 
								std::thread * m_ResolveThread;
 | 
				
			||||||
			boost::asio::ip::udp::socket m_LocalSocket;
 | 
								std::unique_ptr<boost::asio::ip::udp::socket> m_LocalSocket;
 | 
				
			||||||
			boost::asio::ip::udp::endpoint m_RecvEndpoint;
 | 
								boost::asio::ip::udp::endpoint m_RecvEndpoint;
 | 
				
			||||||
			uint8_t m_RecvBuff[I2P_UDP_MAX_MTU];
 | 
								uint8_t m_RecvBuff[I2P_UDP_MAX_MTU];
 | 
				
			||||||
			uint16_t RemotePort, m_LastPort;
 | 
								uint16_t RemotePort, m_LastPort;
 | 
				
			||||||
			bool m_cancel_resolve;
 | 
								bool m_cancel_resolve;
 | 
				
			||||||
 | 
								bool m_Gzip;
 | 
				
			||||||
			std::shared_ptr<UDPConvo> m_LastSession;
 | 
								std::shared_ptr<UDPConvo> m_LastSession;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public:
 | 
							public:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue