summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent
diff options
context:
space:
mode:
authorSam T <pxqr.sta@gmail.com>2013-06-10 05:42:15 +0400
committerSam T <pxqr.sta@gmail.com>2013-06-10 05:42:15 +0400
commit7313c139eb5a75edf4fca36e5d0f401584ab7502 (patch)
treea89ada3cb1b4fe19f76ed8d80e04115b78ada406 /src/Network/BitTorrent
parentf2ebdc9e4b0ad69a5a878c8e14b4e1a6bd34a831 (diff)
~ Sketch of high level API.
Diffstat (limited to 'src/Network/BitTorrent')
-rw-r--r--src/Network/BitTorrent/Exchange.hs137
-rw-r--r--src/Network/BitTorrent/Extension.hs4
2 files changed, 116 insertions, 25 deletions
diff --git a/src/Network/BitTorrent/Exchange.hs b/src/Network/BitTorrent/Exchange.hs
index 425ed2a3..4fe90cda 100644
--- a/src/Network/BitTorrent/Exchange.hs
+++ b/src/Network/BitTorrent/Exchange.hs
@@ -6,27 +6,34 @@
6-- Portability : portable 6-- Portability : portable
7-- 7--
8{-# LANGUAGE DoAndIfThenElse #-} 8{-# LANGUAGE DoAndIfThenElse #-}
9{-# LANGUAGE GeneralizedNewtypeDeriving #-}
10{-# LANGUAGE MultiParamTypeClasses #-}
11{-# LANGUAGE RecordWildCards #-}
9module Network.BitTorrent.Exchange 12module Network.BitTorrent.Exchange
10 ( 13 ( P2P, withPeer
11 -- * Session
12 PeerSession, newLeacher, newSeeder
13 ) where 14 ) where
14 15
15import Control.Applicative 16import Control.Applicative
16import Control.Concurrent 17import Control.Concurrent
17import Control.Concurrent.STM 18import Control.Concurrent.STM
19import Control.Exception
20import Control.Monad.Reader
21import Control.Monad.State
22
18import Data.IORef 23import Data.IORef
19import Data.Function 24import Data.Function
20import Data.Ord 25import Data.Ord
21import Data.Set as S 26import Data.Set as S
22 27
23import Data.Conduit 28import Data.Conduit as C
24import Data.Conduit.Cereal 29import Data.Conduit.Cereal
25import Data.Conduit.Network 30import Data.Conduit.Network
26import Data.Serialize 31import Data.Serialize as S
32
33import Network
27 34
28import Network.BitTorrent.Exchange.Selection as PW 35import Network.BitTorrent.Exchange.Selection
29import Network.BitTorrent.Exchange.Protocol as PW 36import Network.BitTorrent.Exchange.Protocol
30 37
31import Network.BitTorrent.Internal 38import Network.BitTorrent.Internal
32import Network.BitTorrent.Extension 39import Network.BitTorrent.Extension
@@ -38,29 +45,113 @@ import Data.Torrent
38 P2P monad 45 P2P monad
39-----------------------------------------------------------------------} 46-----------------------------------------------------------------------}
40 47
41{- 48type PeerWire = ConduitM Message Message IO
42type P2P = Reader PeerSession (ConduitM Message Message IO) 49
50waitMessage :: PeerWire Message
51waitMessage = await >>= maybe waitMessage return
52
53signalMessage :: Message -> PeerWire ()
54signalMessage = C.yield
43 55
44conduit :: Socket -> P2P a -> IO a 56newtype P2P a = P2P {
45conduit sock p2p = 57 runP2P :: ReaderT PeerSession PeerWire a
58 } deriving (Monad, MonadReader PeerSession, MonadIO)
59
60instance MonadState Bitfield P2P where
61
62runConduit :: Socket -> Conduit Message IO Message -> IO ()
63runConduit sock p2p =
46 sourceSocket sock $= 64 sourceSocket sock $=
47 conduitGet get $= 65 conduitGet S.get $=
48 messageLoop p2p $= 66 forever p2p $=
49 conduitPut put $$ 67 conduitPut S.put $$
50 sinkSocket sock 68 sinkSocket sock
51 69
52messageLoop :: P2P () -> P2P () 70withPeer :: SwarmSession -> PeerAddr -> P2P () -> IO ()
53messageLoop = undefined 71withPeer se addr p2p =
54 72 withPeerSession se addr $ \(sock, pses) -> do
55runP2P :: SSession -> PeerAddr -> P2P a -> IO a 73 runConduit sock (runReaderT (runP2P p2p) pses)
56runP2P se addr p2p = withPeer se addr $ conduit messageLoop
57 74
58data Event = Available 75data Event = Available Bitfield
59 | Want 76 | Want
60 | Block 77 | Block
61 78
62{- 79
80
63waitForEvent :: P2P Event 81waitForEvent :: P2P Event
82waitForEvent = P2P (ReaderT nextEvent)
83 where
84 nextEvent se @ PeerSession {..} = waitMessage >>= diff
85 where
86 -- diff finds difference between
87 diff KeepAlive = do
88 signalMessage KeepAlive
89 nextEvent se
90
91 handleMessage Choke = do
92 SessionStatus {..} <- liftIO $ readIORef peerSessionStatus
93 if psChoking sePeerStatus
94 then nextEvent se
95 else undefined
96
97 handleMessage Unchoke = return $ Available BF.difference
98
99 handleMessage Interested = return undefined
100 handleMessage NotInterested = return undefined
101
102 handleMessage (Have ix) = do
103 pc <- liftIO $ getPieceCount se
104 haveMessage $ have ix (haveNone pc) -- TODO singleton
105
106 handleMessage (Bitfield bf) = undefined
107 handleMessage (Request bix) = do
108 undefined
109
110 handleMessage (Piece blk) = undefined
111 handleMessage (Port _)
112 = checkExtension msg ExtDHT $ do
113 undefined
114
115 handleMessage msg @ HaveAll
116 = checkExtension msg ExtFast $ do
117 pc <- liftIO $ getPieceCount se
118 haveMessage (haveAll pc)
119
120 handleMessage msg @ HaveNone
121 = checkExtension msg ExtFast $ do
122 pc <- liftIO $ getPieceCount se
123 haveMessage (haveNone pc)
124
125 handleMessage msg @ (SuggestPiece ix)
126 = checkExtension msg ExtFast $ do
127 undefined
128
129 handleMessage msg @ (RejectRequest ix)
130 = checkExtension msg ExtFast $ do
131 undefined
132
133 handleMessage msg @ (AllowedFast pix)
134 = checkExtension msg ExtFast $ do
135 undefined
136
137 haveMessage bf = do
138 cbf <- liftIO $ readIORef $ clientBitfield swarmSession
139 if undefined -- ix `member` bf
140 then nextEvent se
141 else return $ Available diff
142
143 checkExtension msg requredExtension action
144 | requredExtension `elem` enabledExtensions = action
145 | otherwise = liftIO $ throwIO $ userError errorMsg
146 where
147 errorMsg = show (ppExtension requredExtension)
148 ++ "not enabled, but peer sent"
149 ++ show (ppMessage msg)
150
151
152
153getPieceCount :: PeerSession -> IO PieceCount
154getPieceCount = undefined
155
64signalEvent :: Event -> P2P () 156signalEvent :: Event -> P2P ()
65-} 157signalEvent = undefined
66-} \ No newline at end of file
diff --git a/src/Network/BitTorrent/Extension.hs b/src/Network/BitTorrent/Extension.hs
index 0526ace7..13a30581 100644
--- a/src/Network/BitTorrent/Extension.hs
+++ b/src/Network/BitTorrent/Extension.hs
@@ -12,8 +12,8 @@
12-- 12--
13{-# LANGUAGE OverloadedStrings #-} 13{-# LANGUAGE OverloadedStrings #-}
14module Network.BitTorrent.Extension 14module Network.BitTorrent.Extension
15 ( Capabilities, ppCaps, defaultCaps, enabledCaps 15 ( Capabilities, ppCaps, defaultCaps, enabledCaps
16 , Extension, ppExtension, encodeExts, decodeExts 16 , Extension(..), ppExtension, encodeExts, decodeExts
17 ) where 17 ) where
18 18
19import Data.Bits 19import Data.Bits