summaryrefslogtreecommitdiff
path: root/dht/src/Network/BitTorrent/Tracker/Transport.hs
diff options
context:
space:
mode:
Diffstat (limited to 'dht/src/Network/BitTorrent/Tracker/Transport.hs')
-rw-r--r--dht/src/Network/BitTorrent/Tracker/Transport.hs76
1 files changed, 76 insertions, 0 deletions
diff --git a/dht/src/Network/BitTorrent/Tracker/Transport.hs b/dht/src/Network/BitTorrent/Tracker/Transport.hs
new file mode 100644
index 00000000..60cb832d
--- /dev/null
+++ b/dht/src/Network/BitTorrent/Tracker/Transport.hs
@@ -0,0 +1,76 @@
1{-# LANGUAGE TupleSections #-}
2module Network.BitTorrent.Tracker.Transport where
3
4import Control.Concurrent.STM
5import Crypto.Random
6import Data.ByteString (ByteString)
7import Data.Functor.Contravariant
8import Data.IntMap.Strict (IntMap)
9import qualified Data.Serialize as S
10import Network.Socket
11
12import Data.QueryResponse.Table
13import Data.TableMethods
14import Network.Address
15import Network.BitTorrent.Tracker.Message
16import Network.QueryResponse as QR
17
18parseTracker :: ByteString -> SockAddr -> Either String (Transaction Request, SockAddr)
19parseTracker bs saddr = fmap (, saddr) $ S.decode bs
20
21encodeTracker :: Transaction Response -> SockAddr -> (ByteString, SockAddr)
22encodeTracker resp saddr = (S.encode resp,saddr)
23
24type Handler = MethodHandlerA String TransactionId SockAddr (Transaction Request) (Transaction Response)
25
26type Client = QR.ClientA String MessageId TransactionId SockAddr (Transaction Request) (Transaction Response)
27
28handlers :: MessageId -> Maybe Handler
29handlers ConnectId = Nothing
30handlers AnnounceId = Nothing
31handlers ScrapeId = Nothing
32handlers ErrorId = Nothing
33handlers _ = Nothing
34
35methodOfRequest :: Request -> MessageId
36methodOfRequest Connect {} = ConnectId
37methodOfRequest Announce {} = AnnounceId
38methodOfRequest Scrape {} = ScrapeId
39
40classify :: Transaction Request -> MessageClass String MessageId TransactionId SockAddr (Transaction Request)
41classify qry = IsQuery (methodOfRequest $ request qry) (transIdQ qry)
42
43dispatch :: DRG g =>
44 DispatchMethodsA
45 (g, IntMap (Maybe (Transaction Response) -> IO ()))
46 String
47 MessageId
48 TransactionId
49 SockAddr
50 (Transaction Request)
51 (Transaction Response)
52dispatch = DispatchMethods
53 { classifyInbound = classify
54 , lookupHandler = handlers
55 , tableMethods = transactionMethods (contramap fromEnum intMapMethods) genTransactionId
56 }
57
58newClient :: ErrorReporter SockAddr (Transaction Request) MessageId TransactionId String
59 -> TransportA String SockAddr (Transaction Request) (Transaction Response)
60 -> IO (ClientA String
61 MessageId
62 TransactionId
63 SockAddr
64 (Transaction Request)
65 (Transaction Response))
66newClient err net = do
67 drg <- drgNew
68 state <- newTVarIO (drg, mempty)
69 return QR.Client
70 { clientNet = net
71 , clientDispatcher = dispatch
72 , clientErrorReporter = err
73 , clientPending = state
74 , clientAddress = const $ return localhost4
75 , clientResponseId = return
76 }