Browse Source

Merge pull request #662 from majestrate/merge-recent-udp-tunnel

Merge recent udp tunnel changes
pull/663/head
Jeff 8 years ago committed by GitHub
parent
commit
c64aaade70
  1. 10
      .gitignore
  2. 29
      Datagram.cpp
  3. 10
      Datagram.h
  4. 5
      Destination.cpp
  5. 16
      I2PTunnel.cpp
  6. 2
      I2PTunnel.h
  7. 5
      Makefile.mingw
  8. 4
      appveyor.yml

10
.gitignore vendored

@ -14,7 +14,7 @@ netDb
autom4te.cache autom4te.cache
.deps .deps
stamp-h1 stamp-h1
Makefile #Makefile
config.h config.h
config.h.in~ config.h.in~
config.log config.log
@ -238,3 +238,11 @@ pip-log.txt
# Sphinx # Sphinx
docs/_build docs/_build
/androidIdea/ /androidIdea/
# emacs files
*~
*\#*
# gdb files
.gdb_history

29
Datagram.cpp

@ -12,8 +12,10 @@ namespace i2p
namespace datagram namespace datagram
{ {
DatagramDestination::DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner): DatagramDestination::DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner):
m_Owner (owner.get()), m_Receiver (nullptr) m_Owner (owner.get()),
m_Receiver (nullptr)
{ {
m_Identity.FromBase64 (owner->GetIdentity()->ToBase64());
} }
DatagramDestination::~DatagramDestination () DatagramDestination::~DatagramDestination ()
@ -24,16 +26,16 @@ namespace datagram
void DatagramDestination::SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident, uint16_t fromPort, uint16_t toPort) void DatagramDestination::SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident, uint16_t fromPort, uint16_t toPort)
{ {
auto owner = m_Owner; auto owner = m_Owner;
auto i = owner->GetIdentity(); std::vector<uint8_t> v(MAX_DATAGRAM_SIZE);
uint8_t buf[MAX_DATAGRAM_SIZE]; uint8_t * buf = v.data();
auto identityLen = i->ToBuffer (buf, MAX_DATAGRAM_SIZE); auto identityLen = m_Identity.ToBuffer (buf, MAX_DATAGRAM_SIZE);
uint8_t * signature = buf + identityLen; uint8_t * signature = buf + identityLen;
auto signatureLen = i->GetSignatureLen (); auto signatureLen = m_Identity.GetSignatureLen ();
uint8_t * buf1 = signature + signatureLen; uint8_t * buf1 = signature + signatureLen;
size_t headerLen = identityLen + signatureLen; size_t headerLen = identityLen + signatureLen;
memcpy (buf1, payload, len); memcpy (buf1, payload, len);
if (i->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) if (m_Identity.GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1)
{ {
uint8_t hash[32]; uint8_t hash[32];
SHA256(buf1, len, hash); SHA256(buf1, len, hash);
@ -48,7 +50,7 @@ namespace datagram
} }
void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort,uint8_t * const &buf, size_t len)
{ {
i2p::data::IdentityEx identity; i2p::data::IdentityEx identity;
size_t identityLen = identity.FromBuffer (buf, len); size_t identityLen = identity.FromBuffer (buf, len);
@ -121,7 +123,7 @@ namespace datagram
if (m_Sessions.empty ()) return; if (m_Sessions.empty ()) return;
auto now = i2p::util::GetMillisecondsSinceEpoch(); auto now = i2p::util::GetMillisecondsSinceEpoch();
LogPrint(eLogDebug, "DatagramDestination: clean up sessions"); LogPrint(eLogDebug, "DatagramDestination: clean up sessions");
std::lock_guard<std::mutex> lock(m_SessionsMutex); std::unique_lock<std::mutex> lock(m_SessionsMutex);
// for each session ... // for each session ...
for (auto it = m_Sessions.begin (); it != m_Sessions.end (); ) for (auto it = m_Sessions.begin (); it != m_Sessions.end (); )
{ {
@ -270,13 +272,16 @@ namespace datagram
bool DatagramSession::ShouldUpdateRoutingPath() const bool DatagramSession::ShouldUpdateRoutingPath() const
{ {
bool dead = m_RoutingSession == nullptr || m_RoutingSession->GetSharedRoutingPath () == nullptr;
auto now = i2p::util::GetMillisecondsSinceEpoch (); auto now = i2p::util::GetMillisecondsSinceEpoch ();
// we need to rotate paths becuase the routing path is too old // we need to rotate paths becuase the routing path is too old
if (now - m_LastPathChange >= DATAGRAM_SESSION_PATH_SWITCH_INTERVAL) return true; // if (now - m_LastPathChange >= DATAGRAM_SESSION_PATH_SWITCH_INTERVAL) return true;
// too fast switching paths
if (now - m_LastPathChange < DATAGRAM_SESSION_PATH_MIN_LIFETIME ) return false;
// our path looks dead so we need to rotate paths // our path looks dead so we need to rotate paths
if (now - m_LastSuccess >= DATAGRAM_SESSION_PATH_TIMEOUT) return true; if (now - m_LastSuccess >= DATAGRAM_SESSION_PATH_TIMEOUT) return !dead;
// if we have a routing session and routing path we don't need to switch paths // if we have a routing session and routing path we don't need to switch paths
return m_RoutingSession != nullptr && m_RoutingSession->GetSharedRoutingPath () != nullptr; return dead;
} }
@ -291,7 +296,7 @@ namespace datagram
if(currentLease) // if we have a lease return true if it's about to expire otherwise return false if(currentLease) // if we have a lease return true if it's about to expire otherwise return false
return currentLease->ExpiresWithin( DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW, DATAGRAM_SESSION_LEASE_HANDOVER_FUDGE ); return currentLease->ExpiresWithin( DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW, DATAGRAM_SESSION_LEASE_HANDOVER_FUDGE );
// we have no current lease, we should switch // we have no current lease, we should switch
return true; return currentLease == nullptr;
} }
std::shared_ptr<i2p::garlic::GarlicRoutingPath> DatagramSession::GetNextRoutingPath() std::shared_ptr<i2p::garlic::GarlicRoutingPath> DatagramSession::GetNextRoutingPath()

10
Datagram.h

@ -22,14 +22,15 @@ namespace datagram
// milliseconds for max session idle time // milliseconds for max session idle time
const uint64_t DATAGRAM_SESSION_MAX_IDLE = 10 * 60 * 1000; const uint64_t DATAGRAM_SESSION_MAX_IDLE = 10 * 60 * 1000;
// milliseconds for how long we try sticking to a dead routing path before trying to switch // milliseconds for how long we try sticking to a dead routing path before trying to switch
const uint64_t DATAGRAM_SESSION_PATH_TIMEOUT = 5000; const uint64_t DATAGRAM_SESSION_PATH_TIMEOUT = 10 * 1000;
// milliseconds interval a routing path is used before switching // milliseconds interval a routing path is used before switching
const uint64_t DATAGRAM_SESSION_PATH_SWITCH_INTERVAL = 60 * 1000; const uint64_t DATAGRAM_SESSION_PATH_SWITCH_INTERVAL = 20 * 60 * 1000;
// milliseconds before lease expire should we try switching leases // milliseconds before lease expire should we try switching leases
const uint64_t DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW = 10 * 1000; const uint64_t DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW = 10 * 1000;
// milliseconds fudge factor for leases handover // milliseconds fudge factor for leases handover
const uint64_t DATAGRAM_SESSION_LEASE_HANDOVER_FUDGE = 1000; const uint64_t DATAGRAM_SESSION_LEASE_HANDOVER_FUDGE = 1000;
// milliseconds minimum time between path switches
const uint64_t DATAGRAM_SESSION_PATH_MIN_LIFETIME = 5 * 1000;
class DatagramSession class DatagramSession
{ {
@ -133,13 +134,14 @@ namespace datagram
std::shared_ptr<I2NPMessage> CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort); std::shared_ptr<I2NPMessage> CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort);
void HandleDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); void HandleDatagram (uint16_t fromPort, uint16_t toPort, uint8_t *const& buf, size_t len);
/** find a receiver by port, if none by port is found try default receiever, otherwise returns nullptr */ /** find a receiver by port, if none by port is found try default receiever, otherwise returns nullptr */
Receiver FindReceiver(uint16_t port); Receiver FindReceiver(uint16_t port);
private: private:
i2p::client::ClientDestination * m_Owner; i2p::client::ClientDestination * m_Owner;
i2p::data::IdentityEx m_Identity;
Receiver m_Receiver; // default Receiver m_Receiver; // default
std::mutex m_SessionsMutex; std::mutex m_SessionsMutex;
std::map<i2p::data::IdentHash, std::shared_ptr<DatagramSession> > m_Sessions; std::map<i2p::data::IdentHash, std::shared_ptr<DatagramSession> > m_Sessions;

5
Destination.cpp

@ -203,10 +203,7 @@ namespace client
if (ls && !ls->IsExpired ()) if (ls && !ls->IsExpired ())
{ {
ls->PopulateLeases (); // since we don't store them in netdb ls->PopulateLeases (); // since we don't store them in netdb
{ m_RemoteLeaseSets[ident] = ls;
std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
m_RemoteLeaseSets[ident] = ls;
}
return ls; return ls;
} }
} }

16
I2PTunnel.cpp

@ -559,23 +559,23 @@ namespace client
} }
/** create new udp session */ /** create new udp session */
boost::asio::ip::udp::endpoint ep(m_LocalAddress, 0); boost::asio::ip::udp::endpoint ep(m_LocalAddress, 0);
m_Sessions.push_back(new UDPSession(ep, m_LocalDest, m_RemoteEndpoint, ih, localPort, remotePort)); m_Sessions.push_back(new UDPSession(ep, m_LocalDest, m_RemoteEndpoint, &ih, localPort, remotePort));
return m_Sessions.back(); return m_Sessions.back();
} }
UDPSession::UDPSession(boost::asio::ip::udp::endpoint localEndpoint, UDPSession::UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
const std::shared_ptr<i2p::client::ClientDestination> & localDestination, const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
boost::asio::ip::udp::endpoint endpoint, const i2p::data::IdentHash to, boost::asio::ip::udp::endpoint endpoint, const i2p::data::IdentHash * to,
uint16_t ourPort, uint16_t theirPort) : uint16_t ourPort, uint16_t theirPort) :
m_Destination(localDestination->GetDatagramDestination()), m_Destination(localDestination->GetDatagramDestination()),
m_Service(localDestination->GetService()), m_Service(localDestination->GetService()),
IPSocket(localDestination->GetService(), localEndpoint), IPSocket(localDestination->GetService(), localEndpoint),
Identity(to),
SendEndpoint(endpoint), SendEndpoint(endpoint),
LastActivity(i2p::util::GetMillisecondsSinceEpoch()), LastActivity(i2p::util::GetMillisecondsSinceEpoch()),
LocalPort(ourPort), LocalPort(ourPort),
RemotePort(theirPort) RemotePort(theirPort)
{ {
memcpy(Identity, to->data(), 32);
Receive(); Receive();
} }
@ -592,13 +592,7 @@ namespace client
{ {
LogPrint(eLogDebug, "UDPSession: forward ", len, "B from ", FromEndpoint); LogPrint(eLogDebug, "UDPSession: forward ", len, "B from ", FromEndpoint);
LastActivity = i2p::util::GetMillisecondsSinceEpoch(); LastActivity = i2p::util::GetMillisecondsSinceEpoch();
uint8_t * data = new uint8_t[len]; m_Destination->SendDatagramTo(m_Buffer, len, Identity, 0, 0);
memcpy(data, m_Buffer, len);
m_Service.post([&,len, data] () {
m_Destination->SendDatagramTo(data, len, Identity, 0, 0);
delete [] data;
});
Receive(); Receive();
} else { } else {
LogPrint(eLogError, "UDPSession: ", ecode.message()); LogPrint(eLogError, "UDPSession: ", ecode.message());
@ -727,7 +721,7 @@ namespace client
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_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)

2
I2PTunnel.h

@ -155,7 +155,7 @@ namespace client
UDPSession(boost::asio::ip::udp::endpoint localEndpoint, UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
const std::shared_ptr<i2p::client::ClientDestination> & localDestination, const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
boost::asio::ip::udp::endpoint remote, const i2p::data::IdentHash ident, boost::asio::ip::udp::endpoint remote, const i2p::data::IdentHash * ident,
uint16_t ourPort, uint16_t theirPort); 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();

5
Makefile.mingw

@ -44,5 +44,10 @@ else
CPU_FLAGS = -msse CPU_FLAGS = -msse
endif endif
ifeq ($(USE_ASLR),yes)
LDFLAGS += -Wl,--nxcompat -Wl,--high-entropy-va \
-Wl,--dynamicbase,--export-all-symbols
endif
obj/%.o : %.rc obj/%.o : %.rc
$(WINDRES) -i $< -o $@ $(WINDRES) -i $< -o $@

4
appveyor.yml

@ -142,9 +142,9 @@ install:
- if not defined msvc ( - if not defined msvc (
C:\msys64\usr\bin\bash -lc "pacman --needed --noconfirm -Sy bash pacman pacman-mirrors msys2-runtime msys2-runtime-devel cmake" C:\msys64\usr\bin\bash -lc "pacman --needed --noconfirm -Sy bash pacman pacman-mirrors msys2-runtime msys2-runtime-devel cmake"
&& if "%x64%" == "1" ( && if "%x64%" == "1" (
C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-x86_64-openssl mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc" C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-x86_64-openssl mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc mingw-w64-x86_64-extra-cmake-modules"
) else ( ) else (
C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-openssl mingw-w64-i686-boost mingw-w64-i686-miniupnpc" C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-openssl mingw-w64-i686-boost mingw-w64-i686-miniupnpc mingw-w64-i686-extra-cmake-modules"
) )
) )
cache: cache:

Loading…
Cancel
Save