diff options
Diffstat (limited to 'src/Erebos/Discovery.hs')
-rw-r--r-- | src/Erebos/Discovery.hs | 94 |
1 files changed, 56 insertions, 38 deletions
diff --git a/src/Erebos/Discovery.hs b/src/Erebos/Discovery.hs index d098f98..2fb0ffe 100644 --- a/src/Erebos/Discovery.hs +++ b/src/Erebos/Discovery.hs @@ -32,8 +32,9 @@ import Erebos.ICE #endif import Erebos.Identity import Erebos.Network +import Erebos.Object import Erebos.Service -import Erebos.Storage +import Erebos.Storable #ifndef ENABLE_ICE_SUPPORT @@ -46,8 +47,8 @@ type IceRemoteInfo = Stored Object data DiscoveryService = DiscoverySelf [ Text ] (Maybe Int) | DiscoveryAcknowledged [ Text ] (Maybe Text) (Maybe Word16) (Maybe Text) (Maybe Word16) - | DiscoverySearch Ref - | DiscoveryResult Ref [ Text ] + | DiscoverySearch (Either Ref RefDigest) + | DiscoveryResult (Either Ref RefDigest) [ Text ] | DiscoveryConnectionRequest DiscoveryConnection | DiscoveryConnectionResponse DiscoveryConnection @@ -67,13 +68,13 @@ defaultDiscoveryAttributes = DiscoveryAttributes } data DiscoveryConnection = DiscoveryConnection - { dconnSource :: Ref - , dconnTarget :: Ref + { dconnSource :: Either Ref RefDigest + , dconnTarget :: Either Ref RefDigest , dconnAddress :: Maybe Text , dconnIceInfo :: Maybe IceRemoteInfo } -emptyConnection :: Ref -> Ref -> DiscoveryConnection +emptyConnection :: Either Ref RefDigest -> Either Ref RefDigest -> DiscoveryConnection emptyConnection dconnSource dconnTarget = DiscoveryConnection {..} where dconnAddress = Nothing @@ -92,9 +93,9 @@ instance Storable DiscoveryService where storeMbInt "stun-port" stunPort storeMbText "turn-server" turnServer storeMbInt "turn-port" turnPort - DiscoverySearch ref -> storeRawRef "search" ref - DiscoveryResult ref addr -> do - storeRawRef "result" ref + DiscoverySearch edgst -> either (storeRawRef "search") (storeRawWeak "search") edgst + DiscoveryResult edgst addr -> do + either (storeRawRef "result") (storeRawWeak "result") edgst mapM_ (storeText "address") addr DiscoveryConnectionRequest conn -> storeConnection "request" conn DiscoveryConnectionResponse conn -> storeConnection "response" conn @@ -102,8 +103,8 @@ instance Storable DiscoveryService where where storeConnection ctype DiscoveryConnection {..} = do storeText "connection" $ ctype - storeRawRef "source" dconnSource - storeRawRef "target" dconnTarget + either (storeRawRef "source") (storeRawWeak "source") dconnSource + either (storeRawRef "target") (storeRawWeak "target") dconnTarget storeMbText "address" dconnAddress storeMbRef "ice-info" dconnIceInfo @@ -123,9 +124,15 @@ instance Storable DiscoveryService where <*> loadMbInt "stun-port" <*> loadMbText "turn-server" <*> loadMbInt "turn-port" - , DiscoverySearch <$> loadRawRef "search" + , DiscoverySearch <$> msum + [ Left <$> loadRawRef "search" + , Right <$> loadRawWeak "search" + ] , DiscoveryResult - <$> loadRawRef "result" + <$> msum + [ Left <$> loadRawRef "result" + , Right <$> loadRawWeak "result" + ] <*> loadTexts "address" , loadConnection "request" DiscoveryConnectionRequest , loadConnection "response" DiscoveryConnectionResponse @@ -134,8 +141,14 @@ instance Storable DiscoveryService where loadConnection ctype ctor = do ctype' <- loadText "connection" guard $ ctype == ctype' - dconnSource <- loadRawRef "source" - dconnTarget <- loadRawRef "target" + dconnSource <- msum + [ Left <$> loadRawRef "source" + , Right <$> loadRawWeak "source" + ] + dconnTarget <- msum + [ Left <$> loadRawRef "target" + , Right <$> loadRawWeak "target" + ] dconnAddress <- loadMbText "address" dconnIceInfo <- loadMbRef "ice-info" return $ ctor DiscoveryConnection {..} @@ -240,17 +253,18 @@ instance Service DiscoveryService where , dpsTurnServer = toIceServer turnServer turnPort } - DiscoverySearch ref -> do - dpeer <- M.lookup (refDigest ref) . dgsPeers <$> svcGetGlobal - replyPacket $ DiscoveryResult ref $ maybe [] dpAddress dpeer + DiscoverySearch edgst -> do + dpeer <- M.lookup (either refDigest id edgst) . dgsPeers <$> svcGetGlobal + replyPacket $ DiscoveryResult edgst $ maybe [] dpAddress dpeer - DiscoveryResult ref [] -> do - svcPrint $ "Discovery: " ++ show (refDigest ref) ++ " not found" + DiscoveryResult edgst [] -> do + svcPrint $ "Discovery: " ++ show (either refDigest id edgst) ++ " not found" - DiscoveryResult ref addrs -> do - let dgst = refDigest ref + 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 @@ -264,8 +278,15 @@ instance Service DiscoveryService where ice <- iceCreateSession config PjIceSessRoleControlling $ \ice -> do rinfo <- iceRemoteInfo ice + -- Try to promote weak ref to normal one for older peers: + edgst' <- case edgst of + Left r -> return (Left r) + Right d -> refFromDigest st d >>= \case + Just r -> return (Left r) + Nothing -> return (Right d) + res <- runExceptT $ sendToPeer discoveryPeer $ - DiscoveryConnectionRequest (emptyConnection (storedRef $ idData self) ref) { dconnIceInfo = Just rinfo } + DiscoveryConnectionRequest (emptyConnection (Left $ storedRef $ idData self) edgst') { dconnIceInfo = Just rinfo } case res of Right _ -> return () Left err -> putStrLn $ "Discovery: failed to send connection request: " ++ err @@ -294,7 +315,7 @@ instance Service DiscoveryService where DiscoveryConnectionRequest conn -> do self <- svcSelf let rconn = emptyConnection (dconnSource conn) (dconnTarget conn) - if refDigest (dconnTarget conn) `elem` identityDigests self + if either refDigest id (dconnTarget conn) `elem` identityDigests self then if #ifdef ENABLE_ICE_SUPPORT -- request for us, create ICE sesssion @@ -318,7 +339,7 @@ instance Service DiscoveryService where else do -- request to some of our peers, relay - mbdp <- M.lookup (refDigest $ dconnTarget conn) . dgsPeers <$> svcGetGlobal + mbdp <- M.lookup (either refDigest id $ dconnTarget conn) . dgsPeers <$> svcGetGlobal case mbdp of Nothing -> replyPacket $ DiscoveryConnectionResponse rconn Just dp @@ -329,7 +350,7 @@ instance Service DiscoveryService where DiscoveryConnectionResponse conn -> do self <- svcSelf dpeers <- dgsPeers <$> svcGetGlobal - if refDigest (dconnSource conn) `elem` identityDigests self + if either refDigest id (dconnSource conn) `elem` identityDigests self then do -- response to our request, try to connect to the peer server <- asks svcServer @@ -340,10 +361,10 @@ instance Service DiscoveryService where peer <- liftIO $ serverPeer server (addrAddress saddr) let upd dp = dp { dpPeer = Just peer } svcModifyGlobal $ \s -> s - { dgsPeers = M.alter (Just . upd . fromMaybe emptyPeer) (refDigest $ dconnTarget conn) $ dgsPeers s } + { dgsPeers = M.alter (Just . upd . fromMaybe emptyPeer) (either refDigest id $ dconnTarget conn) $ dgsPeers s } #ifdef ENABLE_ICE_SUPPORT - | Just dp <- M.lookup (refDigest $ dconnTarget conn) dpeers + | Just dp <- M.lookup (either refDigest id $ dconnTarget conn) dpeers , Just ice <- dpIceSession dp , Just rinfo <- dconnIceInfo conn -> do liftIO $ iceConnect ice rinfo $ void $ serverPeerIce server ice @@ -352,7 +373,7 @@ instance Service DiscoveryService where | otherwise -> svcPrint $ "Discovery: connection request failed" else do -- response to relayed request - case M.lookup (refDigest $ dconnSource conn) dpeers of + case M.lookup (either refDigest id $ dconnSource conn) dpeers of Just dp | Just dpeer <- dpPeer dp -> do sendToPeer dpeer $ DiscoveryConnectionResponse conn _ -> svcPrint $ "Discovery: failed to relay connection response" @@ -360,7 +381,6 @@ instance Service DiscoveryService where serviceNewPeer = do server <- asks svcServer peer <- asks svcPeer - st <- getStorage let addrToText saddr = do ( addr, port ) <- IP.fromSockAddr saddr @@ -380,9 +400,7 @@ instance Service DiscoveryService where when (not $ null addrs) $ do sendToPeer peer $ DiscoverySelf addrs Nothing forM_ searchingFor $ \dgst -> do - liftIO (refFromDigest st dgst) >>= \case - Just ref -> sendToPeer peer $ DiscoverySearch ref - Nothing -> return () + sendToPeer peer $ DiscoverySearch (Right dgst) #ifdef ENABLE_ICE_SUPPORT serviceStopServer _ _ _ pstates = do @@ -415,17 +433,17 @@ getIceConfig = do #endif -discoverySearch :: (MonadIO m, MonadError String m) => Server -> Ref -> m () -discoverySearch server ref = do +discoverySearch :: (MonadIO m, MonadError e m, FromErebosError e) => Server -> RefDigest -> m () +discoverySearch server dgst = do peers <- liftIO $ getCurrentPeerList server match <- forM peers $ \peer -> do peerIdentity peer >>= \case PeerIdentityFull pid -> do - return $ refDigest ref `elem` identityDigests pid + return $ dgst `elem` identityDigests pid _ -> return False when (not $ or match) $ do modifyServiceGlobalState server (Proxy @DiscoveryService) $ \s -> (, ()) s - { dgsSearchingFor = S.insert (refDigest ref) $ dgsSearchingFor s + { dgsSearchingFor = S.insert dgst $ dgsSearchingFor s } forM_ peers $ \peer -> do - sendToPeer peer $ DiscoverySearch ref + sendToPeer peer $ DiscoverySearch $ Right dgst |