summaryrefslogtreecommitdiff
path: root/Mainline.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2017-07-15 04:04:58 -0400
committerjoe <joe@jerkface.net>2017-07-15 04:04:58 -0400
commit49a69e47a6c856e4d2566016325095ac62e6c3ea (patch)
treee835d18ce60ef23ebeb504cfce8f3c9a0dff43c8 /Mainline.hs
parent0242b32be66d93d64fff18e7d322a6bbdd59bd1e (diff)
Generate mainline node id, canonize ips in peer store.
Diffstat (limited to 'Mainline.hs')
-rw-r--r--Mainline.hs55
1 files changed, 36 insertions, 19 deletions
diff --git a/Mainline.hs b/Mainline.hs
index 19646aeb..42b0be97 100644
--- a/Mainline.hs
+++ b/Mainline.hs
@@ -79,9 +79,12 @@ getNodeInfo4 = NodeInfo <$> (NodeId <$> S.getBytes 20)
79 <*> S.get 79 <*> S.get
80 80
81putNodeInfo4 :: NodeInfo -> S.Put 81putNodeInfo4 :: NodeInfo -> S.Put
82putNodeInfo4 (NodeInfo (NodeId nid) (IPv4 ip) port) 82putNodeInfo4 (NodeInfo (NodeId nid) ip port)
83 = S.putByteString nid >> S.put ip >> S.put port 83 | IPv4 ip4 <- ip = put4 ip4
84putNodeInfo4 _ = return () 84 | IPv6 ip6 <- ip , Just ip4 <- un4map ip6 = put4 ip4
85 | otherwise = return ()
86 where
87 put4 ip4 = S.putByteString nid >> S.put ip4 >> S.put port
85 88
86getNodeInfo6 :: S.Get NodeInfo 89getNodeInfo6 :: S.Get NodeInfo
87getNodeInfo6 = NodeInfo <$> (NodeId <$> S.getBytes 20) 90getNodeInfo6 = NodeInfo <$> (NodeId <$> S.getBytes 20)
@@ -255,7 +258,8 @@ newSwarmsDatabase = do
255type RoutingInfo = Info NodeInfo NodeId 258type RoutingInfo = Info NodeInfo NodeId
256 259
257data Routing = Routing 260data Routing = Routing
258 { routing4 :: !( TVar (Maybe RoutingInfo) ) 261 { tentativeId :: NodeId
262 , routing4 :: !( TVar (Maybe RoutingInfo) )
259 , routing6 :: !( TVar (Maybe RoutingInfo) ) 263 , routing6 :: !( TVar (Maybe RoutingInfo) )
260 } 264 }
261 265
@@ -263,11 +267,11 @@ newClient ::
263 SockAddr -> IO (Client String Method TransactionId NodeInfo (Message BValue)) 267 SockAddr -> IO (Client String Method TransactionId NodeInfo (Message BValue))
264newClient addr = do 268newClient addr = do
265 udp <- udpTransport addr 269 udp <- udpTransport addr
266 nid <- error "todo: tentative node id" 270 nid <- NodeId <$> getRandomBytes 20
267 self <- atomically $ newTVar 271 self <- atomically $ newTVar
268 $ NodeInfo nid (fromMaybe (toEnum 0) $ fromSockAddr addr) 272 $ NodeInfo nid (fromMaybe (toEnum 0) $ fromSockAddr addr)
269 (fromMaybe 0 $ sockAddrPort addr) 273 (fromMaybe 0 $ sockAddrPort addr)
270 routing <- atomically $ Routing <$> newTVar Nothing <*> newTVar Nothing 274 routing <- atomically $ Routing nid <$> newTVar Nothing <*> newTVar Nothing
271 swarms <- newSwarmsDatabase 275 swarms <- newSwarmsDatabase
272 let net = onInbound grok $ layerTransport parsePacket encodePacket udp 276 let net = onInbound grok $ layerTransport parsePacket encodePacket udp
273 grok _ _ = do 277 grok _ _ = do
@@ -378,10 +382,18 @@ pingH _ Ping = return Pong
378-- as defined in RFC 4291. 382-- as defined in RFC 4291.
379is4mapped :: IPv6 -> Bool 383is4mapped :: IPv6 -> Bool
380is4mapped ip 384is4mapped ip
381 | [0,0,0,0,0,0,0xffff,_] <- fromIPv6 ip 385 | [0,0,0,0,0,0xffff,_,_] <- fromIPv6 ip
382 = True 386 = True
383 | otherwise = False 387 | otherwise = False
384 388
389un4map :: IPv6 -> Maybe IPv4
390un4map ip
391 | [0,0,0,0,0,0xffff,x,y] <- fromIPv6 ip
392 = Just $ toIPv4
393 $ map (.&. 0xFF)
394 [x `shiftR` 8, x, y `shiftR` 8, y ]
395 | otherwise = Nothing
396
385prefer4or6 :: NodeInfo -> Maybe WantIP -> WantIP 397prefer4or6 :: NodeInfo -> Maybe WantIP -> WantIP
386prefer4or6 addr iptyp = fromMaybe (ipFamily $ nodeIP addr) iptyp 398prefer4or6 addr iptyp = fromMaybe (ipFamily $ nodeIP addr) iptyp
387 399
@@ -399,9 +411,9 @@ findNodeH routing addr (FindNode node iptyp) = do
399 return $ NodeFound ks ks6 411 return $ NodeFound ks ks6
400 where 412 where
401 go var = do 413 go var = do
402 let myid = error "TODO myid" :: NodeId 414 let myid = tentativeId routing :: NodeId
403 k = error "TODO k" :: Int 415 k = R.defaultK :: Int
404 nobkts = error "TODO nobkts" :: Int 416 nobkts = R.defaultBucketCount :: Int
405 nfo <- atomically $ readTVar var 417 nfo <- atomically $ readTVar var
406 let tbl = maybe (R.nullTable myid nobkts) R.myBuckets nfo 418 let tbl = maybe (R.nullTable myid nobkts) R.myBuckets nfo
407 return $ R.kclosest nodeId k node tbl 419 return $ R.kclosest nodeId k node tbl
@@ -567,12 +579,17 @@ announceH (SwarmsDatabase peers toks _) naddr announcement = do
567 >>= bool (Left <$> return (Error ProtocolError "invalid parameter: token")) 579 >>= bool (Left <$> return (Error ProtocolError "invalid parameter: token"))
568 (Right <$> go) 580 (Right <$> go)
569 where 581 where
570 go = do 582 go = atomically $ do
571 let annPort = if impliedPort announcement 583 modifyTVar' peers
572 then nodePort naddr 584 $ insertPeer (topic announcement) (announcedName announcement)
573 else port announcement 585 $ PeerAddr
574 peerAddr = PeerAddr Nothing (nodeIP naddr) annPort 586 { peerId = Nothing
575 atomically 587 -- Avoid storing IPv4-mapped addresses.
576 $ modifyTVar' peers 588 , peerHost = case nodeIP naddr of
577 $ insertPeer (topic announcement) (announcedName announcement) peerAddr 589 IPv6 ip6 | Just ip4 <- un4map ip6 -> IPv4 ip4
578 return Announced 590 a -> a
591 , peerPort = if impliedPort announcement
592 then nodePort naddr
593 else port announcement
594 }
595 return Announced