@ -54,7 +54,7 @@ namespace llarp
return true ;
}
constexpr auto OutboundContextNumPaths = 2 ;
constexpr auto OutboundContextNumPaths = 4 ;
OutboundContext : : OutboundContext ( const IntroSet & introset , Endpoint * parent )
: path : : Builder { parent - > Router ( ) , OutboundContextNumPaths , parent - > numHops }
@ -64,12 +64,17 @@ namespace llarp
, currentIntroSet { introset }
{
assert ( not introset . intros . empty ( ) ) ;
updatingIntroSet = false ;
for ( const auto & intro : introset . intros )
// pick random first intro
auto it = introset . intros . begin ( ) ;
if ( introset . intros . size ( ) > 1 )
{
if ( m_NextIntro . latency = = 0 s or m_NextIntro . latency > intro . latency )
m_NextIntro = intro ;
CSRNG rng { } ;
it + = std : : uniform_int_distribution < size_t > { 0 , introset . intros . size ( ) - 1 } ( rng ) ;
}
m_NextIntro = * it ;
currentConvoTag . Randomize ( ) ;
lastShift = Now ( ) ;
// add send and connect timeouts to the parent endpoints path alignment timeout
@ -333,6 +338,7 @@ namespace llarp
Encrypted < 64 > tmp ;
tmp . Randomize ( ) ;
SendPacketToRemote ( tmp , ProtocolType : : Control ) ;
m_LastKeepAliveAt = Now ( ) ;
}
bool
@ -348,7 +354,10 @@ namespace llarp
// expunge
SharedSecret discardme ;
if ( not m_DataHandler - > GetCachedSessionKeyFor ( currentConvoTag , discardme ) )
{
LogError ( Name ( ) , " no cached key after sending intro, we are in a fugged state, oh no " ) ;
return true ;
}
}
if ( m_GotInboundTraffic and m_LastInboundTraffic + sendTimeout < = now )
@ -404,21 +413,33 @@ namespace llarp
m_ReadyHooks . clear ( ) ;
}
if ( m_LastInboundTraffic > 0 s and lastGoodSend > 0 s
and now > = sendTimeout + m_LastInboundTraffic )
return true ;
const auto timeout = std : : max ( lastGoodSend , m_LastInboundTraffic ) ;
if ( lastGoodSend > 0 s and now > = timeout + ( sendTimeout / 2 ) )
{
// send a keep alive to keep this session alive
KeepAlive ( ) ;
if ( markedBad )
{
LogWarn ( Name ( ) , " keepalive timeout hit " ) ;
return true ;
}
}
// check for half open state where we can send but we get nothing back
if ( m_LastInboundTraffic = = 0 s and now - createdAt > connectTimeout )
{
LogWarn ( Name ( ) , " half open state, we can send but we got nothing back " ) ;
return true ;
}
// if we are dead return true so we are removed
return timeout > 0 s ? ( now > = timeout & & now - timeout > sendTimeout )
: ( now > = createdAt & & now - createdAt > connectTimeout ) ;
const bool removeIt = timeout > 0 s ? ( now > = timeout & & now - timeout > sendTimeout )
: ( now > = createdAt & & now - createdAt > connectTimeout ) ;
if ( removeIt )
{
LogInfo ( Name ( ) , " session is stale " ) ;
return true ;
}
return false ;
}
void
@ -584,6 +605,25 @@ namespace llarp
}
}
bool
OutboundContext : : ShouldKeepAlive ( llarp_time_t now ) const
{
const auto SendKeepAliveInterval = sendTimeout / 2 ;
if ( not m_GotInboundTraffic )
return false ;
if ( m_LastInboundTraffic = = 0 s )
return false ;
return ( now - m_LastKeepAliveAt ) > = SendKeepAliveInterval ;
}
void
OutboundContext : : Tick ( llarp_time_t now )
{
path : : Builder : : Tick ( now ) ;
if ( ShouldKeepAlive ( now ) )
KeepAlive ( ) ;
}
bool
OutboundContext : : HandleHiddenServiceFrame ( path : : Path_ptr p , const ProtocolFrame & frame )
{