diff options
author | joe <joe@jerkface.net> | 2017-07-17 23:17:50 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2017-07-17 23:17:50 -0400 |
commit | 745a4dd8826f474ac7cabd9897744f86fe5a9142 (patch) | |
tree | 91a51220dd88633abc9b21fd4791f0f054a2467f /Mainline.hs | |
parent | 156caf1027ebf46b6fae97fbfa5664e9c417eea4 (diff) |
Implement clientAddress for Mainline DHT.
Diffstat (limited to 'Mainline.hs')
-rw-r--r-- | Mainline.hs | 54 |
1 files changed, 38 insertions, 16 deletions
diff --git a/Mainline.hs b/Mainline.hs index 818150b4..ef452f7d 100644 --- a/Mainline.hs +++ b/Mainline.hs | |||
@@ -32,19 +32,21 @@ import Data.IP | |||
32 | import Data.List | 32 | import Data.List |
33 | import Data.Maybe | 33 | import Data.Maybe |
34 | import Data.Monoid | 34 | import Data.Monoid |
35 | import Data.Ord | ||
35 | import qualified Data.Serialize as S | 36 | import qualified Data.Serialize as S |
36 | import Data.Set (Set) | 37 | import Data.Set (Set) |
37 | import Data.Torrent | 38 | import Data.Torrent |
38 | import Data.Typeable | 39 | import Data.Typeable |
39 | import Data.Word | 40 | import Data.Word |
40 | import Network.Address (Address, fromSockAddr, setPort, | 41 | import Network.Address (Address, fromSockAddr, setPort, |
41 | sockAddrPort, toSockAddr) | 42 | sockAddrPort, toSockAddr, testIdBit) |
42 | import Network.BitTorrent.DHT.ContactInfo as Peers | 43 | import Network.BitTorrent.DHT.ContactInfo as Peers |
43 | import Network.BitTorrent.DHT.Token as Token | 44 | import Network.BitTorrent.DHT.Token as Token |
44 | import qualified Network.DHT.Routing as R | 45 | import qualified Network.DHT.Routing as R |
45 | ;import Network.DHT.Routing (Info, Timestamp, getTimestamp) | 46 | ;import Network.DHT.Routing (Info, Timestamp, getTimestamp) |
46 | import Network.QueryResponse | 47 | import Network.QueryResponse |
47 | import Network.Socket | 48 | import Network.Socket |
49 | import Kademlia | ||
48 | 50 | ||
49 | newtype NodeId = NodeId ByteString | 51 | newtype NodeId = NodeId ByteString |
50 | deriving (Eq,Ord,Show,ByteArrayAccess, BEncode, Bits) | 52 | deriving (Eq,Ord,Show,ByteArrayAccess, BEncode, Bits) |
@@ -258,9 +260,9 @@ newSwarmsDatabase = do | |||
258 | type RoutingInfo = Info NodeInfo NodeId | 260 | type RoutingInfo = Info NodeInfo NodeId |
259 | 261 | ||
260 | data Routing = Routing | 262 | data Routing = Routing |
261 | { tentativeId :: NodeId | 263 | { tentativeId :: NodeInfo |
262 | , routing4 :: !( TVar (Maybe RoutingInfo) ) | 264 | , routing4 :: !( TVar (R.BucketList NodeInfo) ) |
263 | , routing6 :: !( TVar (Maybe RoutingInfo) ) | 265 | , routing6 :: !( TVar (R.BucketList NodeInfo) ) |
264 | } | 266 | } |
265 | 267 | ||
266 | newClient :: | 268 | newClient :: |
@@ -268,10 +270,16 @@ newClient :: | |||
268 | newClient addr = do | 270 | newClient addr = do |
269 | udp <- udpTransport addr | 271 | udp <- udpTransport addr |
270 | nid <- NodeId <$> getRandomBytes 20 | 272 | nid <- NodeId <$> getRandomBytes 20 |
271 | self <- atomically $ newTVar | 273 | let tenative_info = NodeInfo |
272 | $ NodeInfo nid (fromMaybe (toEnum 0) $ fromSockAddr addr) | 274 | { nodeId = nid |
273 | (fromMaybe 0 $ sockAddrPort addr) | 275 | , nodeIP = fromMaybe (toEnum 0) $ fromSockAddr addr |
274 | routing <- atomically $ Routing nid <$> newTVar Nothing <*> newTVar Nothing | 276 | , nodePort = fromMaybe 0 $ sockAddrPort addr |
277 | } | ||
278 | routing <- atomically $ do | ||
279 | let nobkts = R.defaultBucketCount :: Int | ||
280 | tbl4 <- newTVar $ R.nullTable (comparing nodeId) tenative_info nobkts | ||
281 | tbl6 <- newTVar $ R.nullTable (comparing nodeId) tenative_info nobkts | ||
282 | return $ Routing tenative_info tbl4 tbl6 | ||
275 | swarms <- newSwarmsDatabase | 283 | swarms <- newSwarmsDatabase |
276 | let net = onInbound (updateRouting routing) | 284 | let net = onInbound (updateRouting routing) |
277 | $ layerTransport parsePacket encodePacket | 285 | $ layerTransport parsePacket encodePacket |
@@ -298,7 +306,11 @@ newClient addr = do | |||
298 | , clientDispatcher = dispatch mapT | 306 | , clientDispatcher = dispatch mapT |
299 | , clientErrorReporter = ignoreErrors -- TODO | 307 | , clientErrorReporter = ignoreErrors -- TODO |
300 | , clientPending = map_var | 308 | , clientPending = map_var |
301 | , clientAddress = atomically (readTVar self) | 309 | , clientAddress = \maddr -> atomically $ do |
310 | let var = case flip prefer4or6 Nothing <$> maddr of | ||
311 | Just Want_IP6 -> routing6 routing | ||
312 | _ -> routing4 routing | ||
313 | R.selfNode <$> readTVar var | ||
302 | , clientResponseId = return | 314 | , clientResponseId = return |
303 | } | 315 | } |
304 | 316 | ||
@@ -308,8 +320,22 @@ defaultHandler meth = MethodHandler decodePayload errorPayload returnError | |||
308 | returnError :: NodeInfo -> BValue -> IO Error | 320 | returnError :: NodeInfo -> BValue -> IO Error |
309 | returnError _ _ = return $ Error MethodUnknown ("Unknown method " <> meth) | 321 | returnError _ _ = return $ Error MethodUnknown ("Unknown method " <> meth) |
310 | 322 | ||
323 | mainlineKademlia :: Kademlia NodeId NodeInfo | ||
324 | mainlineKademlia = Kademlia quietInsertions | ||
325 | mainlineSpace | ||
326 | (vanillaIO (error "var") $ error "pingProbe") | ||
327 | |||
328 | mainlineSpace :: R.KademliaSpace NodeId NodeInfo | ||
329 | mainlineSpace = R.KademliaSpace | ||
330 | { R.kademliaLocation = nodeId | ||
331 | , R.kademliaTestBit = testIdBit | ||
332 | , R.kademliaXor = xor | ||
333 | } | ||
334 | |||
335 | |||
311 | updateRouting :: Routing -> NodeInfo -> Message BValue -> IO () | 336 | updateRouting :: Routing -> NodeInfo -> Message BValue -> IO () |
312 | updateRouting routing naddr _ = do | 337 | updateRouting routing naddr _ = do |
338 | error "todo" insertNode | ||
313 | -- TODO Update kademlia table. | 339 | -- TODO Update kademlia table. |
314 | -- TODO Update external ip address and update BEP-42 node id. | 340 | -- TODO Update external ip address and update BEP-42 node id. |
315 | return () | 341 | return () |
@@ -413,13 +439,9 @@ findNodeH routing addr (FindNode node iptyp) = do | |||
413 | ks6 <- bool (return []) (go $ routing6 routing) (preferred /= Want_IP4) | 439 | ks6 <- bool (return []) (go $ routing6 routing) (preferred /= Want_IP4) |
414 | return $ NodeFound ks ks6 | 440 | return $ NodeFound ks ks6 |
415 | where | 441 | where |
416 | go var = do | 442 | go var = R.kclosest nodeId k node <$> atomically (readTVar var) |
417 | let myid = tentativeId routing :: NodeId | 443 | k = R.defaultK |
418 | k = R.defaultK :: Int | 444 | |
419 | nobkts = R.defaultBucketCount :: Int | ||
420 | nfo <- atomically $ readTVar var | ||
421 | let tbl = maybe (R.nullTable myid nobkts) R.myBuckets nfo | ||
422 | return $ R.kclosest nodeId k node tbl | ||
423 | 445 | ||
424 | data GetPeers = GetPeers InfoHash (Maybe WantIP) | 446 | data GetPeers = GetPeers InfoHash (Maybe WantIP) |
425 | 447 | ||