|
|
@ -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) |
|
|
|
|
|
|
|
|
|
|
|
I2PUDPServerTunnel::~I2PUDPServerTunnel () |
|
|
|
{ |
|
|
|
{ |
|
|
|
m_LocalDest = localDestination; |
|
|
|
Stop (); |
|
|
|
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() |
|
|
|
void I2PUDPServerTunnel::Start () |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto dgram = m_LocalDest->GetDatagramDestination(); |
|
|
|
m_LocalDest->Start (); |
|
|
|
if (dgram) dgram->ResetReceiver(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LogPrint(eLogInfo, "UDPServer: Done"); |
|
|
|
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)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void I2PUDPServerTunnel::Start() |
|
|
|
void I2PUDPServerTunnel::Stop () |
|
|
|
{ |
|
|
|
{ |
|
|
|
m_LocalDest->Start(); |
|
|
|
auto dgram = m_LocalDest->GetDatagramDestination (); |
|
|
|
|
|
|
|
if (dgram) dgram->ResetReceiver (); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::vector<std::shared_ptr<DatagramSessionInfo> > I2PUDPServerTunnel::GetSessions() |
|
|
|
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), |
|
|
|
I2PUDPClientTunnel::~I2PUDPClientTunnel () |
|
|
|
RemotePort(remotePort), m_LastPort (0), |
|
|
|
{ |
|
|
|
m_cancel_resolve(false) |
|
|
|
Stop (); |
|
|
|
{ |
|
|
|
} |
|
|
|
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)); |
|
|
|
void I2PUDPClientTunnel::Start () |
|
|
|
|
|
|
|
{ |
|
|
|
auto dgram = m_LocalDest->CreateDatagramDestination(gzip); |
|
|
|
// Reset flag in case of tunnel reload
|
|
|
|
dgram->SetReceiver(std::bind(&I2PUDPClientTunnel::HandleRecvFromI2P, this, |
|
|
|
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::Stop () |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto dgram = m_LocalDest->GetDatagramDestination (); |
|
|
|
|
|
|
|
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::RecvFromLocal() |
|
|
|
void I2PUDPClientTunnel::RecvFromLocal () |
|
|
|
{ |
|
|
|
{ |
|
|
|
m_LocalSocket.async_receive_from(boost::asio::buffer(m_RecvBuff, I2P_UDP_MAX_MTU), |
|
|
|
m_LocalSocket->async_receive_from (boost::asio::buffer (m_RecvBuff, I2P_UDP_MAX_MTU), |
|
|
|
m_RecvEndpoint, std::bind(&I2PUDPClientTunnel::HandleRecvFromLocal, this, std::placeholders::_1, std::placeholders::_2)); |
|
|
|
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) |
|
|
|
void I2PUDPClientTunnel::HandleRecvFromLocal (const boost::system::error_code & ec, std::size_t transferred) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if(m_cancel_resolve) { |
|
|
|
if (m_cancel_resolve) { |
|
|
|
LogPrint(eLogDebug, "UDP Client: Ignoring incomming data: stopping"); |
|
|
|
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; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|