diff options
| author | Roman Smrž <roman.smrz@seznam.cz> | 2026-07-01 21:33:35 +0200 |
|---|---|---|
| committer | Roman Smrž <roman.smrz@seznam.cz> | 2026-07-03 23:30:50 +0200 |
| commit | 472bdf9bd80208daa0d37e465e5662145a9d56c7 (patch) | |
| tree | 1867a8e2d70de2f330bb941525c5b70a1c0442d3 /src/Erebos | |
| parent | 565aac1b9747f50b6c34cee794c63e8edc318208 (diff) | |
Discovery: track our search requests per peer
Diffstat (limited to 'src/Erebos')
| -rw-r--r-- | src/Erebos/Discovery.hs | 78 |
1 files changed, 55 insertions, 23 deletions
diff --git a/src/Erebos/Discovery.hs b/src/Erebos/Discovery.hs index 6e39b8c..d6bff83 100644 --- a/src/Erebos/Discovery.hs +++ b/src/Erebos/Discovery.hs @@ -26,6 +26,8 @@ import Data.Text (Text) import Data.Text qualified as T import Data.Word +import System.Clock + import Text.Read #ifdef ENABLE_ICE_SUPPORT @@ -209,7 +211,8 @@ emptyPeer = DiscoveryPeer } data DiscoveryPeerState = DiscoveryPeerState - { dpsOurTunnelRequests :: [ ( RefDigest, StreamWriter ) ] + { dpsWeAskedFor :: Map RefDigest SearchStatus + , dpsOurTunnelRequests :: [ ( RefDigest, StreamWriter ) ] -- ( original target, our write stream ) , dpsRelayedTunnelRequests :: [ ( RefDigest, ( StreamReader, StreamWriter )) ] -- ( original source, ( from source, to target )) @@ -223,6 +226,9 @@ data DiscoveryGlobalState = DiscoveryGlobalState , dgsSearchingFor :: Set RefDigest } +data SearchStatus + = SearchingSince TimeSpec + instance Service DiscoveryService where serviceID _ = mkServiceID "dd59c89c-69cc-4703-b75b-4ddcd4b3c23c" @@ -231,7 +237,8 @@ instance Service DiscoveryService where type ServiceState DiscoveryService = DiscoveryPeerState emptyServiceState _ = DiscoveryPeerState - { dpsOurTunnelRequests = [] + { dpsWeAskedFor = M.empty + , dpsOurTunnelRequests = [] , dpsRelayedTunnelRequests = [] , dpsStunServer = Nothing , dpsTurnServer = Nothing @@ -311,18 +318,29 @@ instance Service DiscoveryService where " for " <> show (either refDigest id edgst) <> " result [" <> T.unpack (T.intercalate "," $ map toText results) <> "]" - DiscoveryResult _ [] -> do - -- not found - return () - DiscoveryResult edgst addrs -> do let dgst = either refDigest id edgst - -- TODO: check if we really requested that server <- asks svcServer st <- getStorage self <- svcSelf discoveryPeer <- asks svcPeer - let runAsService = runPeerService @DiscoveryService discoveryPeer + pid <- asks svcPeerIdentity + + weAskedFor <- dpsWeAskedFor <$> svcGet + let askedFor = M.member dgst weAskedFor + debugLog $ + "result from " <> show (refDigest $ storedRef $ idData pid) <> + " for " <> show dgst <> ": [" <> T.unpack (T.intercalate "," $ map toText addrs) <> "]" <> + (if askedFor then "" else " (not asked for)") + + when askedFor $ do + let weAskedFor' = M.delete dgst weAskedFor + svcModify $ \s -> s { dpsWeAskedFor = weAskedFor' } + debugLog $ + "remains asked " <> show (refDigest $ storedRef $ idData pid) <> + " for " <> show (M.keys weAskedFor') + + let runAsService = runPeerService @DiscoveryService @IO discoveryPeer let tryAddresses = \case DiscoveryIP ipaddr port : _ -> do @@ -367,12 +385,13 @@ instance Service DiscoveryService where discoverySetupTunnelResponse dgst addr : rest -> do - svcPrint $ "Discovery: unsupported address in result: " ++ T.unpack (toText addr) + debugLog $ "unsupported address in result: " ++ T.unpack (toText addr) tryAddresses rest - [] -> svcPrint $ "Discovery: no (supported) address received for " <> show dgst + [] -> debugLog $ "no (supported) address received for " <> show dgst - tryAddresses addrs + when askedFor $ do + tryAddresses addrs DiscoveryConnectionRequest conn -> do self <- svcSelf @@ -550,8 +569,17 @@ instance Service DiscoveryService where when (not $ null addrs) $ do sendToPeer peer $ DiscoverySelf addrs Nothing - forM_ searchingFor $ \dgst -> do - sendToPeer peer $ DiscoverySearch (Right dgst) + + when (not $ null searchingFor) $ do + forM_ searchingFor $ \dgst -> do + sendToPeer peer $ DiscoverySearch (Right dgst) + + now <- liftIO $ getTime Monotonic + let weAskedFor' = M.fromAscList $ map (, SearchingSince now) $ S.toAscList searchingFor + svcModify $ \s -> s { dpsWeAskedFor = weAskedFor' } + debugLog $ + "we asked new peer " <> show (refDigest $ storedRef $ idData pid) <> + " for " <> show (M.keys weAskedFor') serviceUpdatedPeer = do pid <- asks svcPeerIdentity @@ -622,16 +650,20 @@ discoverySearch server dgst = do return $ dgst `elem` identityDigests pid _ -> return False when (not $ or match) $ do - alreadySearching <- modifyServiceGlobalState server (Proxy @DiscoveryService) $ \s -> - let alreadySearching = S.member dgst $ dgsSearchingFor s - in ( if alreadySearching then s else s - { dgsSearchingFor = S.insert dgst $ dgsSearchingFor s - } - , alreadySearching - ) - when (not alreadySearching) $ do - forM_ peers $ \peer -> do - sendToPeer peer $ DiscoverySearch $ Right dgst + _ <- modifyServiceGlobalState server (Proxy @DiscoveryService) $ \s -> + ( s { dgsSearchingFor = S.insert dgst $ dgsSearchingFor s }, () ) + now <- liftIO $ getTime Monotonic + forM_ peers $ \peer -> do + runPeerService peer $ do + weAskedFor <- dpsWeAskedFor <$> svcGet + when (not $ M.member dgst weAskedFor) $ do + let weAskedFor' = M.insert dgst (SearchingSince now) weAskedFor + svcModify $ \s -> s { dpsWeAskedFor = weAskedFor' } + pid <- asks svcPeerIdentity + debugLog $ + "we asked " <> show (refDigest $ storedRef $ idData pid) <> + " for " <> show dgst <> " " <> show (M.keys weAskedFor') + replyPacket $ DiscoverySearch $ Right dgst data TunnelAddress = TunnelAddress |