summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Network/BitTorrent/Exchange/Session.hs9
-rw-r--r--src/Network/BitTorrent/Exchange/Session/Metadata.hs28
2 files changed, 20 insertions, 17 deletions
diff --git a/src/Network/BitTorrent/Exchange/Session.hs b/src/Network/BitTorrent/Exchange/Session.hs
index 8cbce4e3..6e5d94d6 100644
--- a/src/Network/BitTorrent/Exchange/Session.hs
+++ b/src/Network/BitTorrent/Exchange/Session.hs
@@ -259,7 +259,8 @@ withStatusUpdates m = do
259withMetadataUpdates :: Updates a -> Connected Session a 259withMetadataUpdates :: Updates a -> Connected Session a
260withMetadataUpdates m = do 260withMetadataUpdates m = do
261 Session {..} <- asks connSession 261 Session {..} <- asks connSession
262 liftIO $ runUpdates metadata m 262 addr <- asks connRemoteAddr
263 liftIO $ runUpdates metadata addr m
263 264
264getThisBitfield :: Wire Session Bitfield 265getThisBitfield :: Wire Session Bitfield
265getThisBitfield = do 266getThisBitfield = do
@@ -381,8 +382,7 @@ handleTransfer (Cancel bix) = filterQueue (not . (transferResponse bix))
381 382
382tryRequestMetadataBlock :: Wire Session () 383tryRequestMetadataBlock :: Wire Session ()
383tryRequestMetadataBlock = do 384tryRequestMetadataBlock = do
384 addr <- asks connRemoteAddr 385 mpix <- lift $ withMetadataUpdates Metadata.scheduleBlock
385 mpix <- lift $ withMetadataUpdates (Metadata.scheduleBlock addr)
386 case mpix of 386 case mpix of
387 Nothing -> undefined 387 Nothing -> undefined
388 Just pix -> sendMessage (MetadataRequest pix) 388 Just pix -> sendMessage (MetadataRequest pix)
@@ -395,9 +395,8 @@ handleMetadata (MetadataRequest pix) =
395 mkResponse (Just (piece, total)) = MetadataData piece total 395 mkResponse (Just (piece, total)) = MetadataData piece total
396 396
397handleMetadata (MetadataData {..}) = do 397handleMetadata (MetadataData {..}) = do
398 addr <- asks connRemoteAddr
399 ih <- asks connTopic 398 ih <- asks connTopic
400 lift $ withMetadataUpdates (Metadata.pushBlock addr piece ih) 399 lift $ withMetadataUpdates (Metadata.pushBlock piece ih)
401 tryRequestMetadataBlock 400 tryRequestMetadataBlock
402 401
403handleMetadata (MetadataReject pix) = do 402handleMetadata (MetadataReject pix) = do
diff --git a/src/Network/BitTorrent/Exchange/Session/Metadata.hs b/src/Network/BitTorrent/Exchange/Session/Metadata.hs
index 5d72172a..02c2269f 100644
--- a/src/Network/BitTorrent/Exchange/Session/Metadata.hs
+++ b/src/Network/BitTorrent/Exchange/Session/Metadata.hs
@@ -17,6 +17,7 @@ module Network.BitTorrent.Exchange.Session.Metadata
17 17
18import Control.Concurrent 18import Control.Concurrent
19import Control.Lens 19import Control.Lens
20import Control.Monad.Reader
20import Control.Monad.State 21import Control.Monad.State
21import Data.ByteString as BS 22import Data.ByteString as BS
22import Data.ByteString.Lazy as BL 23import Data.ByteString.Lazy as BL
@@ -43,14 +44,15 @@ makeLenses ''Status
43nullStatus :: Int -> Status 44nullStatus :: Int -> Status
44nullStatus ps = Status [] (Block.empty ps) 45nullStatus ps = Status [] (Block.empty ps)
45 46
46type Updates a = State Status a 47type Updates = ReaderT (PeerAddr IP) (State Status)
47 48
48runUpdates :: MVar Status -> Updates a -> IO a 49runUpdates :: MVar Status -> PeerAddr IP -> Updates a -> IO a
49runUpdates v m = modifyMVar v (return . swap . runState m) 50runUpdates v a m = modifyMVar v (return . swap . runState (runReaderT m a))
50 51
51scheduleBlock :: PeerAddr IP -> Updates (Maybe PieceIx) 52scheduleBlock :: Updates (Maybe PieceIx)
52scheduleBlock addr = do 53scheduleBlock = do
53 bkt <- use bucket 54 addr <- ask
55 bkt <- use bucket
54 case spans metadataPieceSize bkt of 56 case spans metadataPieceSize bkt of
55 [] -> return Nothing 57 [] -> return Nothing
56 ((off, _ ) : _) -> do 58 ((off, _ ) : _) -> do
@@ -61,8 +63,10 @@ scheduleBlock addr = do
61cancelPending :: PieceIx -> Updates () 63cancelPending :: PieceIx -> Updates ()
62cancelPending pix = pending %= L.filter ((pix ==) . snd) 64cancelPending pix = pending %= L.filter ((pix ==) . snd)
63 65
64resetPending :: PeerAddr IP -> Updates () 66resetPending :: Updates ()
65resetPending addr = pending %= L.filter ((addr ==) . fst) 67resetPending = do
68 addr <- ask
69 pending %= L.filter ((addr ==) . fst)
66 70
67parseInfoDict :: BS.ByteString -> InfoHash -> Result InfoDict 71parseInfoDict :: BS.ByteString -> InfoHash -> Result InfoDict
68parseInfoDict chunk topic = 72parseInfoDict chunk topic =
@@ -73,10 +77,10 @@ parseInfoDict chunk topic =
73 Left err -> Left $ "unable to parse infodict " ++ err 77 Left err -> Left $ "unable to parse infodict " ++ err
74 78
75-- todo use incremental parsing to avoid BS.concat call 79-- todo use incremental parsing to avoid BS.concat call
76pushBlock :: PeerAddr IP -> Torrent.Piece BS.ByteString -> InfoHash 80pushBlock :: Torrent.Piece BS.ByteString -> InfoHash -> Updates (Maybe InfoDict)
77 -> Updates (Maybe InfoDict) 81pushBlock Torrent.Piece {..} topic = do
78pushBlock addr Torrent.Piece {..} topic = do 82 addr <- ask
79 p <- use pending 83 p <- use pending
80 when ((addr, pieceIndex) `L.notElem` p) $ error "not requested" 84 when ((addr, pieceIndex) `L.notElem` p) $ error "not requested"
81 cancelPending pieceIndex 85 cancelPending pieceIndex
82 86