summaryrefslogtreecommitdiff
path: root/Mainline.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2017-07-13 22:30:38 -0400
committerjoe <joe@jerkface.net>2017-07-13 22:30:38 -0400
commit4171673e85049ce1647c669f2fd83652621510eb (patch)
tree6680d3c5ffd302a3bf097c3202f679d619dc9877 /Mainline.hs
parentadc30fe62736d1f4f539a971db681b0a5c552871 (diff)
Mainline DHT rewrite: newClient
Diffstat (limited to 'Mainline.hs')
-rw-r--r--Mainline.hs38
1 files changed, 32 insertions, 6 deletions
diff --git a/Mainline.hs b/Mainline.hs
index e2ab2d7f..d24b3376 100644
--- a/Mainline.hs
+++ b/Mainline.hs
@@ -7,6 +7,8 @@
7module Mainline where 7module Mainline where
8 8
9import Control.Arrow 9import Control.Arrow
10import Control.Concurrent.STM
11import Crypto.Random
10import Data.BEncode as BE 12import Data.BEncode as BE
11import Data.BEncode.BDict as BE 13import Data.BEncode.BDict as BE
12import Data.Bool 14import Data.Bool
@@ -16,6 +18,7 @@ import Data.ByteString as B
16import Data.ByteString.Lazy (toStrict) 18import Data.ByteString.Lazy (toStrict)
17import Data.Data 19import Data.Data
18import Data.IP 20import Data.IP
21import Data.Maybe
19import Data.Monoid 22import Data.Monoid
20import qualified Data.Serialize as S 23import qualified Data.Serialize as S
21import Data.Typeable 24import Data.Typeable
@@ -84,7 +87,7 @@ data Error = Error
84 , errorMessage :: !ByteString -- ^ Human-readable text message. 87 , errorMessage :: !ByteString -- ^ Human-readable text message.
85 } deriving ( Show, Eq, Ord, Typeable, Data, Read ) 88 } deriving ( Show, Eq, Ord, Typeable, Data, Read )
86 89
87newtype TransactionId = TransactionId Word16 90newtype TransactionId = TransactionId ByteString
88 deriving (Eq, Ord, Show, BEncode) 91 deriving (Eq, Ord, Show, BEncode)
89 92
90newtype Method = Method ByteString 93newtype Method = Method ByteString
@@ -145,26 +148,49 @@ encodePacket :: Message BValue -> NodeInfo -> (ByteString, SockAddr)
145encodePacket msg ni = ( toStrict $ BE.encode msg 148encodePacket msg ni = ( toStrict $ BE.encode msg
146 , nodeAddr ni ) 149 , nodeAddr ni )
147 150
151newClient ::
152 SockAddr -> IO (Client String Method TransactionId NodeInfo (Message BValue))
148newClient addr = do 153newClient addr = do
149 udp <- udpTransport addr 154 udp <- udpTransport addr
155 nid <- error "todo: tentative node id"
156 self <- atomically $ newTVar
157 $ NodeInfo nid (fromMaybe (toEnum 0) $ fromSockAddr addr)
158 (fromMaybe 0 $ sockAddrPort addr)
159 -- drg <- getSystemDRG
150 let net = layerTransport parsePacket encodePacket udp 160 let net = layerTransport parsePacket encodePacket udp
151 return net 161 dispatch tbl = DispatchMethods
162 { classifyInbound = classify
163 , lookupHandler = handlers
164 , tableMethods = tbl
165 }
166 mapT = transactionMethods mapMethods gen
167 gen :: Word16 -> (TransactionId, Word16)
168 gen cnt = (TransactionId $ S.encode cnt, cnt+1)
169 map_var <- atomically $ newTVar (0, mempty)
170 return Client
171 { clientNet = net
172 , clientDispatcher = dispatch mapT
173 , clientErrorReporter = ignoreErrors -- TODO
174 , clientPending = map_var
175 , clientAddress = atomically (readTVar self)
176 , clientResponseId = return
177 }
152 178
153classify :: Message BValue -> MessageClass String Method TransactionId 179classify :: Message BValue -> MessageClass String Method TransactionId
154classify (Q { msgID = tid, qryMethod = meth }) = IsQuery meth tid 180classify (Q { msgID = tid, qryMethod = meth }) = IsQuery meth tid
155classify (R { msgID = tid }) = IsResponse tid 181classify (R { msgID = tid }) = IsResponse tid
156 182
157encodePayload () tid self dest b = R (nodeId self) tid (Right $ BE.toBEncode b) (Just $ nodeAddr dest) 183encodePayload tid self dest b = R (nodeId self) tid (Right $ BE.toBEncode b) (Just $ nodeAddr dest)
158 184
159errorPayload () tid self dest e = R (nodeId self) tid (Left e) (Just $ nodeAddr dest) 185errorPayload tid self dest e = R (nodeId self) tid (Left e) (Just $ nodeAddr dest)
160 186
161decodePayload :: BEncode a => Message BValue -> Either String a 187decodePayload :: BEncode a => Message BValue -> Either String a
162decodePayload msg = BE.fromBEncode $ qryPayload msg 188decodePayload msg = BE.fromBEncode $ qryPayload msg
163 189
164handler f = Just $ MethodHandler decodePayload encodePayload f 190handler f = Just $ MethodHandler decodePayload encodePayload f
165 191
166handlers :: Method -> Maybe (MethodHandler String TransactionId NodeInfo (Message BValue) ()) 192handlers :: Method -> Maybe (MethodHandler String TransactionId NodeInfo (Message BValue))
167handlers (Method "ping" ) = handler pingH 193handlers (Method "ping" ) = error "handler pingH"
168handlers (Method "find_node") = error "find_node" 194handlers (Method "find_node") = error "find_node"
169handlers (Method "get_peers") = error "get_peers" 195handlers (Method "get_peers") = error "get_peers"
170handlers (Method meth ) = Just $ MethodHandler decodePayload errorPayload (defaultH meth) 196handlers (Method meth ) = Just $ MethodHandler decodePayload errorPayload (defaultH meth)