diff options
Diffstat (limited to 'src/Network/DHT/Mainline.hs')
-rw-r--r-- | src/Network/DHT/Mainline.hs | 72 |
1 files changed, 65 insertions, 7 deletions
diff --git a/src/Network/DHT/Mainline.hs b/src/Network/DHT/Mainline.hs index 540b74f9..d7aed430 100644 --- a/src/Network/DHT/Mainline.hs +++ b/src/Network/DHT/Mainline.hs | |||
@@ -1,18 +1,76 @@ | |||
1 | {-# LANGUAGE LambdaCase #-} | 1 | {-# LANGUAGE LambdaCase #-} |
2 | {-# LANGUAGE MultiParamTypeClasses #-} | 2 | {-# LANGUAGE MultiParamTypeClasses #-} |
3 | {-# LANGUAGE DeriveDataTypeable #-} | ||
3 | {-# LANGUAGE TypeFamilies #-} | 4 | {-# LANGUAGE TypeFamilies #-} |
5 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} | ||
4 | module Network.DHT.Mainline where | 6 | module Network.DHT.Mainline where |
5 | 7 | ||
6 | import Network.Socket | 8 | import Data.BEncode as BE |
7 | import Network.RPC | 9 | import Data.Bits |
8 | import Network.KRPC.Message as KRPC | 10 | import Data.ByteString (ByteString) |
9 | import Data.BEncode as BE | 11 | import Data.ByteString.Base16 as Base16 |
10 | import qualified Data.ByteString.Lazy as L | 12 | import qualified Data.ByteString.Char8 as Char8 |
11 | import Network.BitTorrent.Address as BT (NodeId) | 13 | import qualified Data.ByteString.Lazy as L |
14 | import Data.Default | ||
15 | import Data.LargeWord | ||
16 | import Data.Serialize as S | ||
17 | import Data.String | ||
18 | import Data.Typeable | ||
19 | import Network.KRPC.Message as KRPC | ||
20 | import qualified Network.RPC as RPC (NodeId) | ||
21 | ;import Network.RPC as RPC hiding (NodeId) | ||
22 | import Text.PrettyPrint as PP hiding ((<>)) | ||
23 | import Text.PrettyPrint.HughesPJClass hiding (($$), (<>)) | ||
24 | |||
25 | -- | Each node has a globally unique identifier known as the \"node | ||
26 | -- ID.\" | ||
27 | -- | ||
28 | -- Normally, /this/ node id should be saved between invocations | ||
29 | -- of the client software. | ||
30 | newtype NodeId = NodeId Word160 | ||
31 | deriving (Show, Eq, Ord, Typeable, Bits, FiniteBits) | ||
32 | |||
33 | instance BEncode NodeId where | ||
34 | toBEncode (NodeId w) = toBEncode $ S.encode w | ||
35 | fromBEncode bval = fromBEncode bval >>= S.decode | ||
36 | |||
37 | -- | NodeId size in bytes. | ||
38 | nodeIdSize :: Int | ||
39 | nodeIdSize = 20 | ||
40 | |||
41 | |||
42 | -- instance BEncode NodeId where TODO | ||
43 | |||
44 | -- TODO: put this somewhere appropriate | ||
45 | instance (Serialize a, Serialize b) => Serialize (LargeKey a b) where | ||
46 | put (LargeKey lo hi) = put hi >> put lo | ||
47 | get = flip LargeKey <$> get <*> get | ||
48 | |||
49 | instance Serialize NodeId where | ||
50 | get = NodeId <$> get | ||
51 | {-# INLINE get #-} | ||
52 | put (NodeId bs) = put bs | ||
53 | {-# INLINE put #-} | ||
54 | |||
55 | -- | ASCII encoded. | ||
56 | instance IsString NodeId where | ||
57 | fromString str | ||
58 | | length str == nodeIdSize = NodeId (either error id $ S.decode (fromString str :: ByteString)) | ||
59 | | length str == 2 * nodeIdSize = NodeId (either error id $ S.decode (fst $ Base16.decode $ fromString str)) | ||
60 | | otherwise = error "fromString: invalid NodeId length" | ||
61 | {-# INLINE fromString #-} | ||
62 | |||
63 | -- | Meaningless node id, for testing purposes only. | ||
64 | instance Default NodeId where | ||
65 | def = NodeId 0 | ||
66 | |||
67 | -- | base16 encoded. | ||
68 | instance Pretty NodeId where | ||
69 | pPrint (NodeId nid) = PP.text $ Char8.unpack $ Base16.encode $ S.encode nid | ||
12 | 70 | ||
13 | instance Envelope KMessageOf where | 71 | instance Envelope KMessageOf where |
14 | type TransactionID KMessageOf = KRPC.TransactionId | 72 | type TransactionID KMessageOf = KRPC.TransactionId |
15 | type NodeId KMessageOf = BT.NodeId | 73 | type NodeId KMessageOf = Network.DHT.Mainline.NodeId |
16 | 74 | ||
17 | envelopePayload (Q q) = queryArgs q | 75 | envelopePayload (Q q) = queryArgs q |
18 | envelopePayload (R r) = respVals r | 76 | envelopePayload (R r) = respVals r |