summaryrefslogtreecommitdiff
path: root/src/Erebos/Discovery.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Erebos/Discovery.hs')
-rw-r--r--src/Erebos/Discovery.hs94
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