From 1685c44c5592fb3043bcf6d29ddd3d7659e8346b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Wed, 22 Jan 2020 21:51:57 +0100 Subject: Announce identity update to current peers --- src/Identity.hs | 3 ++- src/Network.hs | 35 +++++++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/Identity.hs b/src/Identity.hs index ce987b2..dcf0ca4 100644 --- a/src/Identity.hs +++ b/src/Identity.hs @@ -16,6 +16,7 @@ module Identity ( displayIdentity, ) where +import Control.Arrow import Control.Monad import Control.Monad.Except import qualified Control.Monad.Identity as I @@ -49,7 +50,7 @@ type ComposedIdentity = Identity [] type UnifiedIdentity = Identity I.Identity instance Eq UnifiedIdentity where - (==) = (==) `on` idData + (==) = (==) `on` (idData &&& idUpdates) data IdentityData = IdentityData { iddPrev :: [Stored (Signed IdentityData)] diff --git a/src/Network.hs b/src/Network.hs index 89034da..09cbea1 100644 --- a/src/Network.hs +++ b/src/Network.hs @@ -172,10 +172,29 @@ startServer origHead logd bhost services = do return sock loop sock = do - let announce identity = do + void $ forkIO $ forever $ do + readMVar midentity >>= \identity -> do st <- derivePartialStorage storage baddr:_ <- getAddrInfo (Just $ defaultHints { addrSocketType = Datagram }) (Just bhost) (Just discoveryPort) void $ sendTo sock (BL.toStrict $ serializeObject $ transportToObject $ TransportHeader [ AnnounceSelf $ partialRef st $ storedRef $ idData identity ]) (addrAddress baddr) + threadDelay $ announceIntervalSeconds * 1000 * 1000 + + let announceUpdate identity = do + st <- derivePartialStorage storage + let plaintext = BL.toStrict $ serializeObject $ transportToObject $ TransportHeader $ + (AnnounceSelf $ partialRef st $ storedRef $ idData identity) : + map (AnnounceUpdate . partialRef st . storedRef) (idUpdates identity) + + ps <- readMVar peers + forM_ ps $ \case + peer + | PeerIdentityFull _ <- peerIdentity peer + , ChannelEstablished ch <- peerChannel peer + , DatagramAddress paddr <- peerAddress peer + -> runExceptT (channelEncrypt ch plaintext) >>= \case + Right ctext -> void $ sendTo (peerSocket peer) ctext paddr + Left err -> logd $ "Failed to encrypt data: " ++ err + | otherwise -> return () let shareState self shared peer | PeerIdentityFull pid <- peerIdentity peer @@ -185,15 +204,11 @@ startServer origHead logd bhost services = do Right () -> return () | otherwise = return () - void $ forkIO $ forever $ do - announce =<< readMVar midentity - threadDelay $ announceIntervalSeconds * 1000 * 1000 - watchHead origHead $ \h -> do let idt = headLocalIdentity h changedId <- modifyMVar midentity $ \cur -> return (idt, cur /= idt) - when changedId $ announce idt + when changedId $ announceUpdate idt let shared = lsShared $ load $ headRef h changedShared <- modifyMVar mshared $ \cur -> @@ -520,6 +535,7 @@ handleChannelAccept identity accref = do sendIdentityUpdate :: UnifiedIdentity -> PacketHandler () sendIdentityUpdate self = do ist <- gets $ peerInStorage . phPeer + addHeader $ AnnounceSelf $ partialRef ist $ storedRef $ idData $ self mapM_ addHeader . map (AnnounceUpdate . partialRef ist . storedRef) . idUpdates $ self @@ -539,6 +555,12 @@ handleIdentityUpdate :: PacketHandler () handleIdentityUpdate = do peer <- gets phPeer case (peerIdentity peer, peerIdentityUpdate peer) of + (PeerIdentityRef wref, _) -> checkWaitingRef wref >>= \case + Just ref | Just pid <- validateIdentity $ wrappedLoad ref -> do + updatePeer $ \p -> p { peerIdentity = PeerIdentityFull pid } + handleIdentityUpdate + _ -> return () + (PeerIdentityFull pid, wrefs@(_:_)) -> do (wrefs', upds) <- fmap partitionEithers $ forM wrefs $ \wref -> checkWaitingRef wref >>= \case Just upd -> return $ Right $ wrappedLoad upd @@ -547,6 +569,7 @@ handleIdentityUpdate = do { peerIdentity = PeerIdentityFull $ updateOwners upds pid , peerIdentityUpdate = wrefs' } + _ -> return () -- cgit v1.2.3