summaryrefslogtreecommitdiff
path: root/src/Network.hs
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2020-02-05 22:42:05 +0100
committerRoman Smrž <roman.smrz@seznam.cz>2020-02-05 22:42:05 +0100
commit3ed73a0e3ed70452f86e83b287e5bdb1548a867b (patch)
tree65ea11c0f31d33a594812d1b5f3b3f0334c54039 /src/Network.hs
parent8dc945aae35fffd8e64c524b71d7316297721daf (diff)
Network: add "rejected" header type
Diffstat (limited to 'src/Network.hs')
-rw-r--r--src/Network.hs54
1 files changed, 34 insertions, 20 deletions
diff --git a/src/Network.hs b/src/Network.hs
index eb319b2..2644af2 100644
--- a/src/Network.hs
+++ b/src/Network.hs
@@ -71,6 +71,7 @@ data PeerChannel = ChannelWait
data TransportHeaderItem
= Acknowledged PartialRef
+ | Rejected PartialRef
| DataRequest PartialRef
| DataResponse PartialRef
| AnnounceSelf PartialRef
@@ -86,6 +87,7 @@ transportToObject :: TransportHeader -> PartialObject
transportToObject (TransportHeader items) = Rec $ map single items
where single = \case
Acknowledged ref -> (BC.pack "ACK", RecRef ref)
+ Rejected ref -> (BC.pack "REJ", RecRef ref)
DataRequest ref -> (BC.pack "REQ", RecRef ref)
DataResponse ref -> (BC.pack "RSP", RecRef ref)
AnnounceSelf ref -> (BC.pack "ANN", RecRef ref)
@@ -101,6 +103,7 @@ transportFromObject (Rec items) = case catMaybes $ map single items of
titems -> Just $ TransportHeader titems
where single (name, content) = if
| name == BC.pack "ACK", RecRef ref <- content -> Just $ Acknowledged ref
+ | name == BC.pack "REJ", RecRef ref <- content -> Just $ Rejected ref
| name == BC.pack "REQ", RecRef ref <- content -> Just $ DataRequest ref
| name == BC.pack "RSP", RecRef ref <- content -> Just $ DataResponse ref
| name == BC.pack "ANN", RecRef ref <- content -> Just $ AnnounceSelf ref
@@ -254,7 +257,8 @@ startServer origHead logd bhost services = do
| Just header <- transportFromObject obj -> do
forM_ objs $ storeObject $ peerInStorage peer
identity <- readMVar midentity
- handlePacket logd identity secure peer chanSvc header >>= \case
+ let svcs = map someServiceID services
+ handlePacket logd identity secure peer chanSvc svcs header >>= \case
Just peer' -> do
modifyMVar_ peers $ return . M.insert paddr peer'
writeChan chanPeer peer'
@@ -317,9 +321,9 @@ addBody :: Ref -> PacketHandler ()
addBody r = modify $ \ph -> ph { phBody = r : phBody ph }
handlePacket :: (String -> IO ()) -> UnifiedIdentity -> Bool
- -> Peer -> Chan (Peer, ServiceID, Ref)
+ -> Peer -> Chan (Peer, ServiceID, Ref) -> [ServiceID]
-> TransportHeader -> IO (Maybe Peer)
-handlePacket logd identity secure opeer chanSvc (TransportHeader headers) = do
+handlePacket logd identity secure opeer chanSvc svcs (TransportHeader headers) = do
let sidentity = idData identity
DatagramAddress paddr = peerAddress opeer
plaintextRefs = map (refDigest . storedRef) $ concatMap (collectStoredObjects . wrappedLoad) $ concat
@@ -342,12 +346,16 @@ handlePacket logd identity secure opeer chanSvc (TransportHeader headers) = do
liftIO (loadLocalState $ storedStorage $ idData identity)
_ -> return ()
+ Rejected _ -> return ()
+
DataRequest ref
| secure || refDigest ref `elem` plaintextRefs -> do
Right mref <- copyRef (storedStorage sidentity) ref
addHeader $ DataResponse ref
addBody $ mref
- | otherwise -> throwError $ "unauthorized data request for " ++ show ref
+ | otherwise -> do
+ liftIO $ logd $ "unauthorized data request for " ++ show ref
+ addHeader $ Rejected ref
DataResponse ref -> do
liftIO (ioLoadBytes ref) >>= \case
@@ -387,39 +395,45 @@ handlePacket logd identity secure opeer chanSvc (TransportHeader headers) = do
_ -> return ()
TrChannelRequest reqref -> do
- addHeader $ Acknowledged reqref
pst <- gets $ peerStorage . phPeer
- let process = handleChannelRequest identity =<< newWaitingRef pst reqref
+ let process = do
+ addHeader $ Acknowledged reqref
+ handleChannelRequest identity =<< newWaitingRef pst reqref
+ reject = addHeader $ Rejected reqref
+
gets (peerChannel . phPeer) >>= \case
ChannelWait {} -> process
ChannelOurRequest our | refDigest reqref < refDigest (storedRef our) -> process
- | otherwise -> return ()
+ | otherwise -> reject
ChannelPeerRequest {} -> process
- ChannelOurAccept {} -> return ()
+ ChannelOurAccept {} -> reject
ChannelEstablished {} -> process
TrChannelAccept accref -> do
- addHeader $ Acknowledged accref
- let process = handleChannelAccept identity accref
+ let process = do
+ addHeader $ Acknowledged accref
+ handleChannelAccept identity accref
gets (peerChannel . phPeer) >>= \case
ChannelWait {} -> process
ChannelOurRequest {} -> process
ChannelPeerRequest {} -> process
ChannelOurAccept our _ | refDigest accref < refDigest (storedRef our) -> process
- | otherwise -> return ()
+ | otherwise -> addHeader $ Rejected accref
ChannelEstablished {} -> process
ServiceType _ -> return ()
ServiceRef pref
- | not secure -> throwError $ "service packet without secure channeel"
- | Just svc <- lookupServiceType headers -> do
- liftIO (ioLoadBytes pref) >>= \case
- Right _ -> do
- addHeader $ Acknowledged pref
- pst <- gets $ peerStorage . phPeer
- wref <- newWaitingRef pst pref
- updatePeer $ \p -> p { peerServiceQueue = (svc, wref) : peerServiceQueue p }
- Left _ -> throwError $ "missing service object " ++ show pref
+ | not secure -> throwError $ "service packet without secure channel"
+ | Just svc <- lookupServiceType headers -> if
+ | svc `elem` svcs -> do
+ liftIO (ioLoadBytes pref) >>= \case
+ Right _ -> do
+ addHeader $ Acknowledged pref
+ pst <- gets $ peerStorage . phPeer
+ wref <- newWaitingRef pst pref
+ updatePeer $ \p -> p { peerServiceQueue = (svc, wref) : peerServiceQueue p }
+ Left _ -> throwError $ "missing service object " ++ show pref
+ | otherwise -> addHeader $ Rejected pref
| otherwise -> throwError $ "service ref without type"
setupChannel identity