summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent/Exchange/Protocol.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/BitTorrent/Exchange/Protocol.hs')
-rw-r--r--src/Network/BitTorrent/Exchange/Protocol.hs66
1 files changed, 65 insertions, 1 deletions
diff --git a/src/Network/BitTorrent/Exchange/Protocol.hs b/src/Network/BitTorrent/Exchange/Protocol.hs
index 8cfcc79d..505f6ac6 100644
--- a/src/Network/BitTorrent/Exchange/Protocol.hs
+++ b/src/Network/BitTorrent/Exchange/Protocol.hs
@@ -34,6 +34,21 @@ module Network.BitTorrent.Exchange.Protocol
34 -- * Regular messages 34 -- * Regular messages
35 , Message(..) 35 , Message(..)
36 , ppMessage 36 , ppMessage
37
38 -- * Exchange control
39 -- ** Peer status
40 , PeerStatus(..)
41 , setChoking, setInterested
42 , initPeerStatus
43
44 -- ** Session status
45 , SessionStatus(..)
46 , initSessionStatus
47 , setClientStatus, setPeerStatus
48 , canUpload, canDownload
49
50 -- ** Defaults
51 , defaultUnchokeSlots
37 ) where 52 ) where
38 53
39import Control.Applicative 54import Control.Applicative
@@ -384,4 +399,53 @@ ppMessage (Piece blk) = "Piece" <+> ppBlock blk
384ppMessage (Cancel ix) = "Cancel" <+> ppBlockIx ix 399ppMessage (Cancel ix) = "Cancel" <+> ppBlockIx ix
385ppMessage (SuggestPiece pix) = "Suggest" <+> int pix 400ppMessage (SuggestPiece pix) = "Suggest" <+> int pix
386ppMessage (RejectRequest ix) = "Reject" <+> ppBlockIx ix 401ppMessage (RejectRequest ix) = "Reject" <+> ppBlockIx ix
387ppMessage msg = text (show msg) \ No newline at end of file 402ppMessage msg = text (show msg)
403
404{-----------------------------------------------------------------------
405 Peer Status
406-----------------------------------------------------------------------}
407
408data PeerStatus = PeerStatus {
409 psChoking :: Bool
410 , psInterested :: Bool
411 }
412
413-- | Any session between peers starts as choking and not interested.
414initPeerStatus :: PeerStatus
415initPeerStatus = PeerStatus True False
416
417setChoking :: Bool -> PeerStatus -> PeerStatus
418setChoking b ps = ps { psChoking = b }
419
420setInterested :: Bool -> PeerStatus -> PeerStatus
421setInterested b ps = ps { psInterested = b }
422
423
424
425data SessionStatus = SessionStatus {
426 seClientStatus :: PeerStatus
427 , sePeerStatus :: PeerStatus
428 }
429
430initSessionStatus :: SessionStatus
431initSessionStatus = SessionStatus initPeerStatus initPeerStatus
432
433setClientStatus :: (PeerStatus -> PeerStatus) -> SessionStatus -> SessionStatus
434setClientStatus f ss = ss { seClientStatus = f (seClientStatus ss) }
435
436setPeerStatus :: (PeerStatus -> PeerStatus) -> SessionStatus -> SessionStatus
437setPeerStatus f ss = ss { sePeerStatus = f (sePeerStatus ss) }
438
439-- | Can the /client/ to upload to the /peer/?
440canUpload :: SessionStatus -> Bool
441canUpload SessionStatus { seClientStatus = client, sePeerStatus = peer} =
442 psInterested peer && not (psChoking client)
443
444-- | Can the /client/ download from the /peer/?
445canDownload :: SessionStatus -> Bool
446canDownload SessionStatus { seClientStatus = client, sePeerStatus = peer } =
447 psInterested client && not (psChoking peer)
448
449-- | Indicates have many peers are allowed to download from the client.
450defaultUnchokeSlots :: Int
451defaultUnchokeSlots = 4 \ No newline at end of file