diff options
author | joe <joe@jerkface.net> | 2017-07-15 04:04:58 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2017-07-15 04:04:58 -0400 |
commit | 49a69e47a6c856e4d2566016325095ac62e6c3ea (patch) | |
tree | e835d18ce60ef23ebeb504cfce8f3c9a0dff43c8 /Mainline.hs | |
parent | 0242b32be66d93d64fff18e7d322a6bbdd59bd1e (diff) |
Generate mainline node id, canonize ips in peer store.
Diffstat (limited to 'Mainline.hs')
-rw-r--r-- | Mainline.hs | 55 |
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 | ||
81 | putNodeInfo4 :: NodeInfo -> S.Put | 81 | putNodeInfo4 :: NodeInfo -> S.Put |
82 | putNodeInfo4 (NodeInfo (NodeId nid) (IPv4 ip) port) | 82 | putNodeInfo4 (NodeInfo (NodeId nid) ip port) |
83 | = S.putByteString nid >> S.put ip >> S.put port | 83 | | IPv4 ip4 <- ip = put4 ip4 |
84 | putNodeInfo4 _ = 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 | ||
86 | getNodeInfo6 :: S.Get NodeInfo | 89 | getNodeInfo6 :: S.Get NodeInfo |
87 | getNodeInfo6 = NodeInfo <$> (NodeId <$> S.getBytes 20) | 90 | getNodeInfo6 = NodeInfo <$> (NodeId <$> S.getBytes 20) |
@@ -255,7 +258,8 @@ newSwarmsDatabase = do | |||
255 | type RoutingInfo = Info NodeInfo NodeId | 258 | type RoutingInfo = Info NodeInfo NodeId |
256 | 259 | ||
257 | data Routing = Routing | 260 | data 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)) |
264 | newClient addr = do | 268 | newClient 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. |
379 | is4mapped :: IPv6 -> Bool | 383 | is4mapped :: IPv6 -> Bool |
380 | is4mapped ip | 384 | is4mapped 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 | ||
389 | un4map :: IPv6 -> Maybe IPv4 | ||
390 | un4map 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 | |||
385 | prefer4or6 :: NodeInfo -> Maybe WantIP -> WantIP | 397 | prefer4or6 :: NodeInfo -> Maybe WantIP -> WantIP |
386 | prefer4or6 addr iptyp = fromMaybe (ipFamily $ nodeIP addr) iptyp | 398 | prefer4or6 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 | ||