diff options
Diffstat (limited to 'src/Network')
-rw-r--r-- | src/Network/BitTorrent/Client.hs | 33 | ||||
-rw-r--r-- | src/Network/BitTorrent/Client/Swarm.hs | 49 | ||||
-rw-r--r-- | src/Network/BitTorrent/Tracker/Wai.hs | 2 |
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 @@ | |||
1 | module Network.BitTorrent.Client | 1 | module Network.BitTorrent.Client |
2 | ( Options (..) | 2 | ( Options (..) |
3 | , Client (..) | 3 | , Client |
4 | , newClient | ||
5 | , addTorrent | ||
4 | ) where | 6 | ) where |
5 | 7 | ||
8 | import Control.Concurrent.STM | ||
6 | import Data.Default | 9 | import Data.Default |
7 | import Data.Function | 10 | import Data.Function |
11 | import Data.HashMap.Strict as HM | ||
8 | import Data.Ord | 12 | import Data.Ord |
9 | import Data.Text | 13 | import Data.Text |
10 | import Network | 14 | import Network |
11 | 15 | ||
12 | import Data.Torrent | 16 | import Data.Torrent |
13 | import Data.Torrent.InfoHash | 17 | import Data.Torrent.InfoHash |
18 | import Network.BitTorrent.Client.Swarm | ||
14 | import Network.BitTorrent.Core | 19 | import Network.BitTorrent.Core |
15 | import Network.BitTorrent.Exchange.Message | 20 | import 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 | ||
24 | instance Default Options where | 30 | instance 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 | ||
31 | data Client = Client | 38 | data 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 | ||
36 | instance Eq Client where | 45 | instance Eq Client where |
@@ -38,3 +47,21 @@ instance Eq Client where | |||
38 | 47 | ||
39 | instance Ord Client where | 48 | instance Ord Client where |
40 | compare = comparing clientPeerId | 49 | compare = comparing clientPeerId |
50 | |||
51 | newClient :: Options -> IO Client | ||
52 | newClient 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 | |||
62 | addTorrent :: Torrent -> Client -> IO () | ||
63 | addTorrent 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 @@ | |||
1 | module Network.BitTorrent.Client.Swarm | ||
2 | ( Swarm | ||
3 | , newLeecher | ||
4 | , askPeers | ||
5 | ) where | ||
6 | |||
7 | import Data.Default | ||
8 | import Network | ||
9 | |||
10 | import Data.Torrent | ||
11 | import Data.Torrent.InfoHash | ||
12 | import Network.BitTorrent.Core | ||
13 | import Network.BitTorrent.Tracker.Message | ||
14 | import Network.BitTorrent.Tracker.RPC as RPC | ||
15 | |||
16 | |||
17 | data Swarm = Swarm | ||
18 | { swarmTopic :: InfoHash | ||
19 | , thisPeerId :: PeerId | ||
20 | , listenerPort :: PortNumber | ||
21 | , trackerConn :: Tracker | ||
22 | -- , infoDict :: | ||
23 | } | ||
24 | |||
25 | newLeecher :: PeerId -> PortNumber -> Torrent -> IO Swarm | ||
26 | newLeecher 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 | |||
35 | getAnnounceQuery :: Swarm -> AnnounceQuery | ||
36 | getAnnounceQuery 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 | |||
46 | askPeers :: Swarm -> IO [PeerAddr] | ||
47 | askPeers 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 | |||
79 | getScrapeR :: TrackerSettings -> ScrapeQuery -> ResourceT IO ScrapeInfo | 79 | getScrapeR :: TrackerSettings -> ScrapeQuery -> ResourceT IO ScrapeInfo |
80 | getScrapeR = undefined | 80 | getScrapeR = undefined |
81 | 81 | ||
82 | -- content-type: "text/plain" ? | 82 | -- content-type: "text/plain"! |
83 | tracker :: TrackerSettings -> Application | 83 | tracker :: TrackerSettings -> Application |
84 | tracker settings Request {..} | 84 | tracker settings Request {..} |
85 | | requestMethod /= methodGet | 85 | | requestMethod /= methodGet |