summaryrefslogtreecommitdiff
path: root/src/Network
diff options
context:
space:
mode:
authorSam Truzjan <pxqr.sta@gmail.com>2013-12-05 05:23:24 +0400
committerSam Truzjan <pxqr.sta@gmail.com>2013-12-05 05:23:24 +0400
commit7680dbe4eea3c4882e67cef01d6c7aded8639c13 (patch)
treed3c69ce47b802a362effbb669f04b7de017d37af /src/Network
parent0ce121bd180c5d06280c6c1c2caac96d39e5ddc4 (diff)
Keep track inflight set in assembler
Diffstat (limited to 'src/Network')
-rw-r--r--src/Network/BitTorrent/Exchange/Assembler.hs95
1 files changed, 39 insertions, 56 deletions
diff --git a/src/Network/BitTorrent/Exchange/Assembler.hs b/src/Network/BitTorrent/Exchange/Assembler.hs
index a490d2dc..b1a80c9b 100644
--- a/src/Network/BitTorrent/Exchange/Assembler.hs
+++ b/src/Network/BitTorrent/Exchange/Assembler.hs
@@ -1,82 +1,65 @@
1module Network.BitTorrent.Exchange.Assembler 1module Network.BitTorrent.Exchange.Assembler
2 ( Assembler 2 ( Assembler
3 , insert
4
5 -- * Query
6 , pendingPieces
7 , completeBlocks
8 , incompleteBlocks
9 ) where 3 ) where
10 4
5import Control.Applicative
11import Data.IntMap.Strict as IM 6import Data.IntMap.Strict as IM
7import Data.List as L
12import Data.Maybe 8import Data.Maybe
9
13import Data.Torrent.Piece 10import Data.Torrent.Piece
14import Data.Torrent.Block 11import Network.BitTorrent.Exchange.Block
12
15 13
16type PieceMap = IntMap 14type PieceMap = IntMap
17 15
18-- TODO move to Data.Torrent.Piece ?
19-- assembler is also a block selector?
20data Assembler a = Assembler 16data Assembler a = Assembler
21 { piecePending :: PieceMap [Block a] 17 { inflightSet :: PieceMap [BlockIx]
18 , piecePending :: PieceMap [Block a]
22 , pieceInfo :: PieceInfo 19 , pieceInfo :: PieceInfo
23 } 20 }
24 21
25
26data Result a 22data Result a
27 = Assembled (Piece a) 23 = Assembled (Piece a)
28 | Failed PieceIx 24 | Corrupted PieceIx
25 | NotRequested PieceIx
26 | Overlapped BlockIx
29 27
30-- | You should check if a returned by peer block is actually have 28empty :: PieceInfo -> Assembler a
31-- been requested and in-flight. This is needed to avoid "I send 29empty = Assembler IM.empty IM.empty
32-- random corrupted block" attacks.
33insert :: Block a -> Assembler a -> (Assembler a, Maybe (Result a))
34insert Block {..} Assembler {..} = undefined
35-- updateWithKey bixPiece
36 30
37pendingPieces :: Assembler a -> [PieceIx] 31inflightPieces :: Assembler a -> [PieceIx]
38pendingPieces Assembler {..} = keys piecePending 32inflightPieces Assembler {..} = keys piecePending
39 33
40completeBlocks :: Assembler a -> PieceIx -> [Block a] 34completeBlocks :: PieceIx -> Assembler a -> [Block a]
41completeBlocks Assembler {..} pix = fromMaybe [] $ IM.lookup pix piecePending 35completeBlocks pix Assembler {..} = fromMaybe [] $ IM.lookup pix piecePending
42 36
43incompleteBlocks :: Assembler a -> PieceIx -> [BlockIx] 37incompleteBlocks :: PieceIx -> Assembler a -> [BlockIx]
44incompleteBlocks = undefined 38incompleteBlocks = undefined
45 39
46-- TODO merge BlockSelector with Assembler? 40nextBlock :: Assembler a -> Maybe (Assembler a, BlockIx)
47data BlockSelector a = BlockSelector 41nextBlock Assembler {..} = undefined
48 { assembler :: Assembler a -- we do not select already transfered blocks
49 , inflightSet :: Set BlockIx -- we do not select blocks in flight
50 }
51
52insert :: BlockSelector -> (BlockSelector a, Maybe (Result a))
53insert = undefined
54
55 42
56data StorageAdapter = StorageAdapter 43allowPiece :: PieceIx -> Assembler a -> Assembler a
57 { bitfield :: Bitfield 44allowPiece = undefined
58 , requestQ :: Queue PieceIx
59 }
60-- we do select 'incompleteBlocks' that is not in flight
61 45
62--assembler :: Assembler -> Conduit (Block a) (Result a) 46insert' :: Block a -> [Block a] -> [Block a]
63--assembler = undefined 47insert' a (x : xs) = undefined
64 48
65-- by priority 49insertBlock :: Block a -> [Block a] -> Either [Block a] (Piece a)
66-- foreign request queue (max queue size) 50insertBlock = undefined
67-- assembler block information (max queue size)
68-- selection strategies (bitfields)
69 51
70-- when in flight queue is full we do not use selector 52inserta :: Block a -> PieceMap [Block a] -> (PieceMap [Block a], Maybe (Piece a))
71-- in flight queue information (max queue size) 53inserta = undefined
72
73-- piece select is used when
74data PieceSelector = Selector
75 { forceQueue :: TVar (Queue PieceIx)
76 , forcePendingQueue :: TVar (Queue PieceIx)
77 , assembler :: TVar Assembler
78 , strategy :: Bool
79 }
80 54
81select :: Selector -> (Selector, PieceIx) 55-- | You should check if a returned by peer block is actually have
82select = undefined \ No newline at end of file 56-- been requested and in-flight. This is needed to avoid "I send
57-- random corrupted block" attacks.
58insert :: Block a -> Assembler a -> (Assembler a, Maybe (Result a))
59insert blk @ Block {..} a @ Assembler {..}
60 = let (pending, mpiece) = inserta blk piecePending
61 in (Assembler inflightSet pending pieceInfo, f <$> mpiece)
62 where
63 f p = undefined
64-- | checkPieceLazy pieceInfo p = Assembled p
65-- | otherwise = Corrupted ixPiece