summaryrefslogtreecommitdiff
path: root/src/Network
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network')
-rw-r--r--src/Network/BitTorrent/Client.hs33
-rw-r--r--src/Network/BitTorrent/Client/Swarm.hs49
-rw-r--r--src/Network/BitTorrent/Tracker/Wai.hs2
3 files changed, 80 insertions, 4 deletions
diff --git a/src/Network/BitTorrent/Client.hs b/src/Network/BitTorrent/Client.hs
index fc2b904a..a6151857 100644
--- a/src/Network/BitTorrent/Client.hs
+++ b/src/Network/BitTorrent/Client.hs
@@ -1,16 +1,21 @@
1module Network.BitTorrent.Client 1module Network.BitTorrent.Client
2 ( Options (..) 2 ( Options (..)
3 , Client (..) 3 , Client
4 , newClient
5 , addTorrent
4 ) where 6 ) where
5 7
8import Control.Concurrent.STM
6import Data.Default 9import Data.Default
7import Data.Function 10import Data.Function
11import Data.HashMap.Strict as HM
8import Data.Ord 12import Data.Ord
9import Data.Text 13import Data.Text
10import Network 14import Network
11 15
12import Data.Torrent 16import Data.Torrent
13import Data.Torrent.InfoHash 17import Data.Torrent.InfoHash
18import Network.BitTorrent.Client.Swarm
14import Network.BitTorrent.Core 19import Network.BitTorrent.Core
15import Network.BitTorrent.Exchange.Message 20import Network.BitTorrent.Exchange.Message
16 21
@@ -19,6 +24,7 @@ data Options = Options
19 { fingerprint :: Fingerprint 24 { fingerprint :: Fingerprint
20 , name :: Text 25 , name :: Text
21 , port :: PortNumber 26 , port :: PortNumber
27 , extensions :: [Extension]
22 } 28 }
23 29
24instance Default Options where 30instance Default Options where
@@ -26,11 +32,14 @@ instance Default Options where
26 { fingerprint = def 32 { fingerprint = def
27 , name = "hs-bittorrent" 33 , name = "hs-bittorrent"
28 , port = 6882 34 , port = 6882
35 , extensions = []
29 } 36 }
30 37
31data Client = Client 38data Client = Client
32 { clientPeerId :: !PeerId 39 { clientPeerId :: !PeerId
33 , allowedExtensions :: !Caps 40 , clientListenerPort :: !PortNumber
41 , allowedExtensions :: !Caps
42 , torrents :: TVar (HashMap InfoHash Swarm)
34 } 43 }
35 44
36instance Eq Client where 45instance Eq Client where
@@ -38,3 +47,21 @@ instance Eq Client where
38 47
39instance Ord Client where 48instance Ord Client where
40 compare = comparing clientPeerId 49 compare = comparing clientPeerId
50
51newClient :: Options -> IO Client
52newClient Options {..} = do
53 pid <- genPeerId
54 ts <- newTVarIO HM.empty
55 return Client
56 { clientPeerId = pid
57 , clientListenerPort = port
58 , allowedExtensions = toCaps extensions
59 , torrents = ts
60 }
61
62addTorrent :: Torrent -> Client -> IO ()
63addTorrent t Client {..} = do
64 leecher <- newLeecher clientPeerId clientListenerPort t
65 let ih = idInfoHash (tInfoDict t)
66 atomically $ modifyTVar' torrents (HM.insert ih leecher)
67 askPeers leecher >>= print \ No newline at end of file
diff --git a/src/Network/BitTorrent/Client/Swarm.hs b/src/Network/BitTorrent/Client/Swarm.hs
new file mode 100644
index 00000000..a9dca048
--- /dev/null
+++ b/src/Network/BitTorrent/Client/Swarm.hs
@@ -0,0 +1,49 @@
1module Network.BitTorrent.Client.Swarm
2 ( Swarm
3 , newLeecher
4 , askPeers
5 ) where
6
7import Data.Default
8import Network
9
10import Data.Torrent
11import Data.Torrent.InfoHash
12import Network.BitTorrent.Core
13import Network.BitTorrent.Tracker.Message
14import Network.BitTorrent.Tracker.RPC as RPC
15
16
17data Swarm = Swarm
18 { swarmTopic :: InfoHash
19 , thisPeerId :: PeerId
20 , listenerPort :: PortNumber
21 , trackerConn :: Tracker
22-- , infoDict ::
23 }
24
25newLeecher :: PeerId -> PortNumber -> Torrent -> IO Swarm
26newLeecher pid port Torrent {..} = do
27 tracker <- connect tAnnounce
28 return Swarm
29 { swarmTopic = idInfoHash tInfoDict
30 , thisPeerId = pid
31 , listenerPort = port
32 , trackerConn = tracker
33 }
34
35getAnnounceQuery :: Swarm -> AnnounceQuery
36getAnnounceQuery Swarm {..} = AnnounceQuery
37 { reqInfoHash = swarmTopic
38 , reqPeerId = thisPeerId
39 , reqPort = listenerPort
40 , reqProgress = def
41 , reqIP = Nothing
42 , reqNumWant = Nothing
43 , reqEvent = Nothing
44 }
45
46askPeers :: Swarm -> IO [PeerAddr]
47askPeers s @ Swarm {..} = do
48 AnnounceInfo {..} <- RPC.announce (getAnnounceQuery s) trackerConn
49 return (getPeerList respPeers)
diff --git a/src/Network/BitTorrent/Tracker/Wai.hs b/src/Network/BitTorrent/Tracker/Wai.hs
index c43c7a3a..69510fa0 100644
--- a/src/Network/BitTorrent/Tracker/Wai.hs
+++ b/src/Network/BitTorrent/Tracker/Wai.hs
@@ -79,7 +79,7 @@ getAnnounceR = undefined
79getScrapeR :: TrackerSettings -> ScrapeQuery -> ResourceT IO ScrapeInfo 79getScrapeR :: TrackerSettings -> ScrapeQuery -> ResourceT IO ScrapeInfo
80getScrapeR = undefined 80getScrapeR = undefined
81 81
82-- content-type: "text/plain" ? 82-- content-type: "text/plain"!
83tracker :: TrackerSettings -> Application 83tracker :: TrackerSettings -> Application
84tracker settings Request {..} 84tracker settings Request {..}
85 | requestMethod /= methodGet 85 | requestMethod /= methodGet