summaryrefslogtreecommitdiff
path: root/src/Network/DHT/Mainline.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/DHT/Mainline.hs')
-rw-r--r--src/Network/DHT/Mainline.hs72
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 #-}
4module Network.DHT.Mainline where 6module Network.DHT.Mainline where
5 7
6import Network.Socket 8import Data.BEncode as BE
7import Network.RPC 9import Data.Bits
8import Network.KRPC.Message as KRPC 10import Data.ByteString (ByteString)
9import Data.BEncode as BE 11import Data.ByteString.Base16 as Base16
10import qualified Data.ByteString.Lazy as L 12import qualified Data.ByteString.Char8 as Char8
11import Network.BitTorrent.Address as BT (NodeId) 13import qualified Data.ByteString.Lazy as L
14import Data.Default
15import Data.LargeWord
16import Data.Serialize as S
17import Data.String
18import Data.Typeable
19import Network.KRPC.Message as KRPC
20import qualified Network.RPC as RPC (NodeId)
21 ;import Network.RPC as RPC hiding (NodeId)
22import Text.PrettyPrint as PP hiding ((<>))
23import 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.
30newtype NodeId = NodeId Word160
31 deriving (Show, Eq, Ord, Typeable, Bits, FiniteBits)
32
33instance BEncode NodeId where
34 toBEncode (NodeId w) = toBEncode $ S.encode w
35 fromBEncode bval = fromBEncode bval >>= S.decode
36
37-- | NodeId size in bytes.
38nodeIdSize :: Int
39nodeIdSize = 20
40
41
42-- instance BEncode NodeId where TODO
43
44-- TODO: put this somewhere appropriate
45instance (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
49instance Serialize NodeId where
50 get = NodeId <$> get
51 {-# INLINE get #-}
52 put (NodeId bs) = put bs
53 {-# INLINE put #-}
54
55-- | ASCII encoded.
56instance 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.
64instance Default NodeId where
65 def = NodeId 0
66
67-- | base16 encoded.
68instance Pretty NodeId where
69 pPrint (NodeId nid) = PP.text $ Char8.unpack $ Base16.encode $ S.encode nid
12 70
13instance Envelope KMessageOf where 71instance 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