Browse Source

* make loopback address mapping configurable

* add loopback address mapping to udp server tunnel
pull/771/head
Jeff Becker 8 years ago
parent
commit
76d9f1ea37
  1. 9
      ClientContext.cpp
  2. 1
      ClientContext.h
  3. 52
      I2PTunnel.cpp
  4. 9
      I2PTunnel.h

9
ClientContext.cpp

@ -493,6 +493,7 @@ namespace client
i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
uint32_t maxConns = section.second.get(i2p::stream::I2CP_PARAM_STREAMING_MAX_CONNS_PER_MIN, i2p::stream::DEFAULT_MAX_CONNS_PER_MIN); uint32_t maxConns = section.second.get(i2p::stream::I2CP_PARAM_STREAMING_MAX_CONNS_PER_MIN, i2p::stream::DEFAULT_MAX_CONNS_PER_MIN);
std::string address = section.second.get<std::string> (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1"); std::string address = section.second.get<std::string> (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1");
bool mapToLoopback = section.second.get(I2P_SERVER_TUNNEL_MAPTOLOOPBACK, true);
// I2CP // I2CP
std::map<std::string, std::string> options; std::map<std::string, std::string> options;
@ -512,6 +513,10 @@ namespace client
auto localAddress = boost::asio::ip::address::from_string(address); auto localAddress = boost::asio::ip::address::from_string(address);
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, localAddress, endpoint, port); I2PUDPServerTunnel * serverTunnel = new I2PUDPServerTunnel(name, localDestination, localAddress, endpoint, port);
if(!mapToLoopback) {
LogPrint(eLogInfo, "Clients: disabling loopback address mapping");
}
serverTunnel->SetMapToLoopback(mapToLoopback);
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(
@ -538,7 +543,9 @@ namespace client
LogPrint(eLogInfo, "Clients: Set Max Conns To ", maxConns); LogPrint(eLogInfo, "Clients: Set Max Conns To ", maxConns);
serverTunnel->SetMaxConnsPerMinute(maxConns); serverTunnel->SetMaxConnsPerMinute(maxConns);
if(!mapToLoopback)
LogPrint(eLogInfo, "Clients: disabling loopback address mapping");
serverTunnel->SetMapToLoopback(mapToLoopback);
if (accessList.length () > 0) if (accessList.length () > 0)
{ {

1
ClientContext.h

@ -42,6 +42,7 @@ namespace client
const char I2P_SERVER_TUNNEL_GZIP[] = "gzip"; const char I2P_SERVER_TUNNEL_GZIP[] = "gzip";
const char I2P_SERVER_TUNNEL_WEBIRC_PASSWORD[] = "webircpassword"; const char I2P_SERVER_TUNNEL_WEBIRC_PASSWORD[] = "webircpassword";
const char I2P_SERVER_TUNNEL_ADDRESS[] = "address"; const char I2P_SERVER_TUNNEL_ADDRESS[] = "address";
const char I2P_SERVER_TUNNEL_MAPTOLOOPBACK[] = "maploopback";
class ClientContext class ClientContext
{ {

52
I2PTunnel.cpp

@ -59,24 +59,38 @@ namespace client
Receive (); Receive ();
} }
void I2PTunnelConnection::Connect () static boost::asio::ip::address GetLoopbackAddressFor(const i2p::data::IdentHash & addr)
{ {
I2PTunnelSetSocketOptions(m_Socket); boost::asio::ip::address_v4::bytes_type bytes;
if (m_Socket) { const uint8_t * ident = addr;
#ifdef __linux__ bytes[0] = 127;
memcpy (bytes.data ()+1, ident, 3);
boost::asio::ip::address ourIP = boost::asio::ip::address_v4 (bytes);
return ourIP;
}
static void MapToLoopback(const std::shared_ptr<boost::asio::ip::tcp::socket> & sock, const i2p::data::IdentHash & addr)
{
// bind to 127.x.x.x address // bind to 127.x.x.x address
// where x.x.x are first three bytes from ident // where x.x.x are first three bytes from ident
auto ourIP = GetLoopbackAddressFor(addr);
sock->bind (boost::asio::ip::tcp::endpoint (ourIP, 0));
}
void I2PTunnelConnection::Connect (bool mapToLoopback)
{
I2PTunnelSetSocketOptions(m_Socket);
if (m_Socket) {
#ifdef __linux__
if (m_RemoteEndpoint.address ().is_v4 () && if (m_RemoteEndpoint.address ().is_v4 () &&
m_RemoteEndpoint.address ().to_v4 ().to_bytes ()[0] == 127) m_RemoteEndpoint.address ().to_v4 ().to_bytes ()[0] == 127 && mapToLoopback)
{ {
m_Socket->open (boost::asio::ip::tcp::v4 ()); m_Socket->open (boost::asio::ip::tcp::v4 ());
boost::asio::ip::address_v4::bytes_type bytes; auto ident = m_Stream->GetRemoteIdentity()->GetIdentHash();
const uint8_t * ident = m_Stream->GetRemoteIdentity ()->GetIdentHash (); MapToLoopback(m_Socket, ident);
bytes[0] = 127;
memcpy (bytes.data ()+1, ident, 3);
boost::asio::ip::address ourIP = boost::asio::ip::address_v4 (bytes);
m_Socket->bind (boost::asio::ip::tcp::endpoint (ourIP, 0));
} }
#endif #endif
m_Socket->async_connect (m_RemoteEndpoint, std::bind (&I2PTunnelConnection::HandleConnect, m_Socket->async_connect (m_RemoteEndpoint, std::bind (&I2PTunnelConnection::HandleConnect,
@ -417,7 +431,7 @@ namespace client
I2PServerTunnel::I2PServerTunnel (const std::string& name, const std::string& address, I2PServerTunnel::I2PServerTunnel (const std::string& name, const std::string& address,
int port, std::shared_ptr<ClientDestination> localDestination, int inport, bool gzip): int port, std::shared_ptr<ClientDestination> localDestination, int inport, bool gzip):
I2PService (localDestination), m_Name (name), m_Address (address), m_Port (port), m_IsAccessList (false) I2PService (localDestination), m_MapToLoopback(true), m_Name (name), m_Address (address), m_Port (port), m_IsAccessList (false)
{ {
m_PortDestination = localDestination->CreateStreamingDestination (inport > 0 ? inport : port, gzip); m_PortDestination = localDestination->CreateStreamingDestination (inport > 0 ? inport : port, gzip);
} }
@ -502,7 +516,7 @@ namespace client
{ {
auto conn = std::make_shared<I2PTunnelConnection> (this, stream, std::make_shared<boost::asio::ip::tcp::socket> (GetService ()), GetEndpoint ()); auto conn = std::make_shared<I2PTunnelConnection> (this, stream, std::make_shared<boost::asio::ip::tcp::socket> (GetService ()), GetEndpoint ());
AddHandler (conn); AddHandler (conn);
conn->Connect (); conn->Connect (m_MapToLoopback);
} }
I2PServerTunnelHTTP::I2PServerTunnelHTTP (const std::string& name, const std::string& address, I2PServerTunnelHTTP::I2PServerTunnelHTTP (const std::string& name, const std::string& address,
@ -581,8 +595,15 @@ namespace client
return s; return s;
} }
} }
boost::asio::ip::address addr;
/** create new udp session */ /** create new udp session */
boost::asio::ip::udp::endpoint ep(m_LocalAddress, 0); if(m_LocalAddress.is_loopback() && m_MapToLoopback) {
auto ident = from.GetIdentHash();
addr = GetLoopbackAddressFor(ident);
} else {
addr = m_LocalAddress;
}
boost::asio::ip::udp::endpoint ep(addr, 0);
m_Sessions.push_back(std::make_shared<UDPSession>(ep, m_LocalDest, m_RemoteEndpoint, &ih, localPort, remotePort)); m_Sessions.push_back(std::make_shared<UDPSession>(ep, m_LocalDest, m_RemoteEndpoint, &ih, localPort, remotePort));
auto & back = m_Sessions.back(); auto & back = m_Sessions.back();
return back; return back;
@ -627,6 +648,7 @@ namespace client
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) : boost::asio::ip::address localAddress, boost::asio::ip::udp::endpoint forwardTo, uint16_t port) :
m_MapToLoopback(true),
m_Name(name), m_Name(name),
m_LocalAddress(localAddress), m_LocalAddress(localAddress),
m_RemoteEndpoint(forwardTo) m_RemoteEndpoint(forwardTo)
@ -768,8 +790,6 @@ namespace client
// found convo // found convo
if (len > 0) { if (len > 0) {
LogPrint(eLogDebug, "UDP Client: got ", len, "B from ", from.GetIdentHash().ToBase32()); LogPrint(eLogDebug, "UDP Client: got ", len, "B from ", from.GetIdentHash().ToBase32());
uint8_t sendbuf[len];
memcpy(sendbuf, buf, len);
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();

9
I2PTunnel.h

@ -38,7 +38,7 @@ namespace client
const boost::asio::ip::tcp::endpoint& target, bool quiet = true); // from I2P const boost::asio::ip::tcp::endpoint& target, bool quiet = true); // from I2P
~I2PTunnelConnection (); ~I2PTunnelConnection ();
void I2PConnect (const uint8_t * msg = nullptr, size_t len = 0); void I2PConnect (const uint8_t * msg = nullptr, size_t len = 0);
void Connect (); void Connect (bool mapToLoopback = true);
protected: protected:
@ -201,12 +201,15 @@ namespace client
std::vector<std::shared_ptr<DatagramSessionInfo> > GetSessions(); 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 SetMapToLoopback(bool mapToLoopback = true) { m_MapToLoopback = mapToLoopback; }
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);
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:
bool m_MapToLoopback;
const std::string m_Name; const std::string m_Name;
boost::asio::ip::address m_LocalAddress; boost::asio::ip::address m_LocalAddress;
boost::asio::ip::udp::endpoint m_RemoteEndpoint; boost::asio::ip::udp::endpoint m_RemoteEndpoint;
@ -264,6 +267,8 @@ namespace client
void SetAccessList (const std::set<i2p::data::IdentHash>& accessList); void SetAccessList (const std::set<i2p::data::IdentHash>& accessList);
void SetMapToLoopback(bool mapToLoopback) { m_MapToLoopback = mapToLoopback; }
const std::string& GetAddress() const { return m_Address; } const std::string& GetAddress() const { return m_Address; }
int GetPort () const { return m_Port; }; int GetPort () const { return m_Port; };
uint16_t GetLocalPort () const { return m_PortDestination->GetLocalPort (); }; uint16_t GetLocalPort () const { return m_PortDestination->GetLocalPort (); };
@ -283,7 +288,7 @@ namespace client
virtual void CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream); virtual void CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream);
private: private:
bool m_MapToLoopback;
std::string m_Name, m_Address; std::string m_Name, m_Address;
int m_Port; int m_Port;
boost::asio::ip::tcp::endpoint m_Endpoint; boost::asio::ip::tcp::endpoint m_Endpoint;

Loading…
Cancel
Save