Browse Source

fixes

pull/628/head
Jeff Becker 8 years ago
parent
commit
7f7acd8bde
No known key found for this signature in database
GPG Key ID: AB950234D6EA286B
  1. 4
      ClientContext.cpp
  2. 53
      I2PTunnel.cpp
  3. 17
      I2PTunnel.h

4
ClientContext.cpp

@ -412,7 +412,7 @@ namespace client
if (!localDestination) { if (!localDestination) {
localDestination = m_SharedLocalDestination; localDestination = m_SharedLocalDestination;
} }
auto clientTunnel = new I2PUDPClientTunnel(name, dest, end, localDestination, destinationPort, m_Service); auto clientTunnel = new I2PUDPClientTunnel(name, dest, end, localDestination, destinationPort);
if(m_ClientForwards.insert(std::make_pair(end, std::unique_ptr<I2PUDPClientTunnel>(clientTunnel))).second) { if(m_ClientForwards.insert(std::make_pair(end, std::unique_ptr<I2PUDPClientTunnel>(clientTunnel))).second) {
clientTunnel->Start(); clientTunnel->Start();
} else { } else {
@ -462,7 +462,7 @@ namespace client
// udp server tunnel // udp server tunnel
// TODO: ipv6 and hostnames // TODO: ipv6 and hostnames
boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(host), port); boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(host), port);
I2PUDPServerTunnel * serverTunnel = new I2PUDPServerTunnel(name, localDestination, endpoint, port, m_Service); I2PUDPServerTunnel * serverTunnel = new I2PUDPServerTunnel(name, localDestination, endpoint, port);
std::lock_guard<std::mutex> lock(m_ForwardsMutex); std::lock_guard<std::mutex> lock(m_ForwardsMutex);
if(m_ServerForwards.insert( if(m_ServerForwards.insert(
std::make_pair( std::make_pair(

53
I2PTunnel.cpp

@ -514,47 +514,45 @@ namespace client
void I2PUDPServerTunnel::HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) void I2PUDPServerTunnel::HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
{ {
std::lock_guard<std::mutex> lock(m_SessionsMutex); std::lock_guard<std::mutex> lock(m_SessionsMutex);
auto & session = ObtainUDPSession(from, toPort, fromPort); auto session = ObtainUDPSession(from, toPort, fromPort);
session.IPSocket.send_to(boost::asio::buffer(buf, len), m_Endpoint); session->IPSocket.send_to(boost::asio::buffer(buf, len), m_Endpoint);
session.LastActivity = i2p::util::GetMillisecondsSinceEpoch(); session->LastActivity = i2p::util::GetMillisecondsSinceEpoch();
} }
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();
std::remove_if(m_Sessions.begin(), m_Sessions.end(), [now, delta](const UDPSession & u) -> bool { std::remove_if(m_Sessions.begin(), m_Sessions.end(), [now, delta](const UDPSession * u) -> bool {
return now - u.LastActivity >= delta; return now - u->LastActivity >= delta;
}); });
} }
UDPSession & I2PUDPServerTunnel::ObtainUDPSession(const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort) UDPSession * I2PUDPServerTunnel::ObtainUDPSession(const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort)
{ {
auto ih = from.GetIdentHash(); auto ih = from.GetIdentHash();
for ( UDPSession & s : m_Sessions ) { for ( UDPSession * s : m_Sessions ) {
if ( s.Identity == ih) { if ( s->Identity == ih) {
/** found existing */ /** found existing */
return s; return s;
} }
} }
/** create new */ /** create new */
boost::asio::ip::udp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"), 0); boost::asio::ip::udp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"), 0);
m_Sessions.push_back(UDPSession(m_Service, ep, m_LocalDest, m_Endpoint, ih, localPort, remotePort)); m_Sessions.push_back(new UDPSession(ep, m_LocalDest, m_Endpoint, ih, localPort, remotePort));
auto & s = m_Sessions.back(); return m_Sessions.back();
s.SendEndpoint = s.IPSocket.local_endpoint();
return s;
} }
UDPSession::UDPSession(boost::asio::io_service & ios, boost::asio::ip::udp::endpoint localEndpoint, const std::shared_ptr<i2p::client::ClientDestination> & localDestination, boost::asio::ip::udp::endpoint endpoint, const i2p::data::IdentHash to, uint16_t ourPort, uint16_t theirPort) : UDPSession::UDPSession(boost::asio::ip::udp::endpoint localEndpoint, const std::shared_ptr<i2p::client::ClientDestination> & localDestination, boost::asio::ip::udp::endpoint endpoint, const i2p::data::IdentHash to, uint16_t ourPort, uint16_t theirPort) :
m_Destination(localDestination.get()), m_Destination(localDestination->GetDatagramDestination()),
IPSocket(ios, localEndpoint), m_Service(localDestination->GetService()),
IPSocket(localDestination->GetService(), localEndpoint),
Identity(to), Identity(to),
SendEndpoint(endpoint), SendEndpoint(endpoint),
LastActivity(i2p::util::GetMillisecondsSinceEpoch()), LastActivity(i2p::util::GetMillisecondsSinceEpoch()),
LocalPort(ourPort), LocalPort(ourPort),
RemotePort(theirPort) RemotePort(theirPort)
{ {
IPSocket.local_endpoint();
Receive(); Receive();
} }
@ -570,22 +568,24 @@ namespace client
if(!ecode) { if(!ecode) {
LogPrint(eLogDebug, "UDPSession: forward ", len, "B from ", FromEndpoint); LogPrint(eLogDebug, "UDPSession: forward ", len, "B from ", FromEndpoint);
LastActivity = i2p::util::GetMillisecondsSinceEpoch(); LastActivity = i2p::util::GetMillisecondsSinceEpoch();
m_Destination->GetService().post([&, len] () { uint8_t * data = new uint8_t[len];
auto dgram = m_Destination->GetDatagramDestination(); memcpy(data, m_Buffer, len);
if (dgram) { m_Service.post([&,len, data] () {
dgram->SendDatagramTo(m_Buffer, len, Identity, 0, 0); m_Destination->SendDatagramTo(data, len, Identity, 0, 0);
} delete data;
}); });
Receive(); Receive();
} else { } else {
LogPrint(eLogError, "UDPSession: ", ecode.message()); LogPrint(eLogError, "UDPSession: ", ecode.message());
} }
} }
I2PUDPServerTunnel::I2PUDPServerTunnel(const std::string & name, std::shared_ptr<i2p::client::ClientDestination> localDestination, boost::asio::ip::udp::endpoint forwardTo, uint16_t port, boost::asio::io_service & service) :
I2PUDPServerTunnel::I2PUDPServerTunnel(const std::string & name, std::shared_ptr<i2p::client::ClientDestination> localDestination, boost::asio::ip::udp::endpoint forwardTo, uint16_t port) :
LocalPort(port), LocalPort(port),
m_Endpoint(forwardTo), m_Endpoint(forwardTo)
m_Service(service)
{ {
m_LocalDest = localDestination; m_LocalDest = localDestination;
m_LocalDest->Start(); m_LocalDest->Start();
@ -606,14 +606,13 @@ namespace client
m_LocalDest->Start(); m_LocalDest->Start();
} }
I2PUDPClientTunnel::I2PUDPClientTunnel(const std::string & name, const std::string &remoteDest, boost::asio::ip::udp::endpoint localEndpoint, std::shared_ptr<i2p::client::ClientDestination> localDestination, uint16_t remotePort, boost::asio::io_service & service) : I2PUDPClientTunnel::I2PUDPClientTunnel(const std::string & name, const std::string &remoteDest, boost::asio::ip::udp::endpoint localEndpoint, std::shared_ptr<i2p::client::ClientDestination> localDestination, uint16_t remotePort) :
m_Session(nullptr), m_Session(nullptr),
m_RemoteDest(remoteDest), m_RemoteDest(remoteDest),
m_RemoteIdent(nullptr), m_RemoteIdent(nullptr),
m_LocalDest(localDestination), m_LocalDest(localDestination),
m_LocalEndpoint(localEndpoint), m_LocalEndpoint(localEndpoint),
m_ResolveThread(nullptr), m_ResolveThread(nullptr),
m_Service(service),
LocalPort(localEndpoint.port()), LocalPort(localEndpoint.port()),
RemotePort(remotePort), RemotePort(remotePort),
m_cancel_resolve(false) m_cancel_resolve(false)
@ -650,7 +649,7 @@ namespace client
// delete existing session // delete existing session
if(m_Session) delete m_Session; if(m_Session) delete m_Session;
boost::asio::ip::udp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"), 0); boost::asio::ip::udp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"), 0);
m_Session = new UDPSession(m_Service, m_LocalEndpoint, m_LocalDest, ep, *m_RemoteIdent, LocalPort, RemotePort); m_Session = new UDPSession(m_LocalEndpoint, m_LocalDest, ep, *m_RemoteIdent, LocalPort, RemotePort);
} }
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)

17
I2PTunnel.h

@ -140,7 +140,8 @@ namespace client
struct UDPSession struct UDPSession
{ {
i2p::client::ClientDestination * m_Destination; i2p::datagram::DatagramDestination * m_Destination;
boost::asio::io_service & m_Service;
boost::asio::ip::udp::socket IPSocket; boost::asio::ip::udp::socket IPSocket;
i2p::data::IdentHash Identity; i2p::data::IdentHash Identity;
boost::asio::ip::udp::endpoint FromEndpoint; boost::asio::ip::udp::endpoint FromEndpoint;
@ -151,32 +152,31 @@ namespace client
uint16_t RemotePort; uint16_t RemotePort;
uint8_t m_Buffer[I2P_UDP_MAX_MTU]; uint8_t m_Buffer[I2P_UDP_MAX_MTU];
uint8_t * m_Forward;
UDPSession(boost::asio::io_service & ios, boost::asio::ip::udp::endpoint localEndpoint, const std::shared_ptr<i2p::client::ClientDestination> & localDestination, boost::asio::ip::udp::endpoint remote, const i2p::data::IdentHash ident, uint16_t ourPort, uint16_t theirPort); UDPSession(boost::asio::ip::udp::endpoint localEndpoint, const std::shared_ptr<i2p::client::ClientDestination> & localDestination, boost::asio::ip::udp::endpoint remote, const i2p::data::IdentHash ident, uint16_t ourPort, uint16_t theirPort);
void HandleReceived(const boost::system::error_code & ecode, std::size_t len); void HandleReceived(const boost::system::error_code & ecode, std::size_t len);
void Receive(); void Receive();
}; };
/** server side udp tunnel, many i2p inbound to 1 ip outbound */ /** server side udp tunnel, many i2p inbound to 1 ip outbound */
class I2PUDPServerTunnel class I2PUDPServerTunnel
{ {
public: public:
I2PUDPServerTunnel(const std::string & name, std::shared_ptr<i2p::client::ClientDestination> localDestination, boost::asio::ip::udp::endpoint forwardTo, uint16_t port, boost::asio::io_service & service); I2PUDPServerTunnel(const std::string & name, std::shared_ptr<i2p::client::ClientDestination> localDestination, boost::asio::ip::udp::endpoint forwardTo, uint16_t port);
~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();
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);
UDPSession & ObtainUDPSession(const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort); UDPSession * ObtainUDPSession(const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort);
private: private:
const uint16_t LocalPort; const uint16_t LocalPort;
boost::asio::ip::udp::endpoint m_Endpoint; boost::asio::ip::udp::endpoint m_Endpoint;
std::mutex m_SessionsMutex; std::mutex m_SessionsMutex;
std::vector<UDPSession> m_Sessions; std::vector<UDPSession*> m_Sessions;
boost::asio::io_service & m_Service;
std::shared_ptr<i2p::client::ClientDestination> m_LocalDest; std::shared_ptr<i2p::client::ClientDestination> m_LocalDest;
uint8_t m_Buffer[I2P_UDP_MAX_MTU]; uint8_t m_Buffer[I2P_UDP_MAX_MTU];
}; };
@ -184,7 +184,7 @@ namespace client
class I2PUDPClientTunnel class I2PUDPClientTunnel
{ {
public: public:
I2PUDPClientTunnel(const std::string & name, const std::string &remoteDest, boost::asio::ip::udp::endpoint localEndpoint, std::shared_ptr<i2p::client::ClientDestination> localDestination, uint16_t remotePort, boost::asio::io_service & service); I2PUDPClientTunnel(const std::string & name, const std::string &remoteDest, boost::asio::ip::udp::endpoint localEndpoint, std::shared_ptr<i2p::client::ClientDestination> localDestination, uint16_t remotePort);
~I2PUDPClientTunnel(); ~I2PUDPClientTunnel();
void Start(); void Start();
private: private:
@ -196,7 +196,6 @@ 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::io_service & m_Service;
uint16_t LocalPort; uint16_t LocalPort;
uint16_t RemotePort; uint16_t RemotePort;
bool m_cancel_resolve; bool m_cancel_resolve;

Loading…
Cancel
Save