diff options
author | Joe Crayne <joe@jerkface.net> | 2019-12-11 03:23:55 -0500 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2020-01-01 23:25:07 -0500 |
commit | 44290a1b44f4b206a1eda866766d4aa11e1ae7b2 (patch) | |
tree | b56cc635c7334d7e6055059a73caa13d1db4c7d5 | |
parent | 6326b4f674b4093c28a8760e53f5a81ad5747a50 (diff) |
Maintain special relay links for connectivity purposes.
-rw-r--r-- | dht/examples/dhtd.hs | 22 | ||||
-rw-r--r-- | dht/src/Network/Tox/Onion/Routes.hs | 28 | ||||
-rw-r--r-- | dht/src/Network/Tox/RelayPinger.hs | 22 |
3 files changed, 46 insertions, 26 deletions
diff --git a/dht/examples/dhtd.hs b/dht/examples/dhtd.hs index 42fcc67b..0f95f562 100644 --- a/dht/examples/dhtd.hs +++ b/dht/examples/dhtd.hs | |||
@@ -100,6 +100,7 @@ import qualified TCPProber as TCP | |||
100 | import Data.Typeable | 100 | import Data.Typeable |
101 | import Network.Tox.ContactInfo as Tox | 101 | import Network.Tox.ContactInfo as Tox |
102 | import Network.Tox.Onion.Routes | 102 | import Network.Tox.Onion.Routes |
103 | import Network.Tox.RelayPinger | ||
103 | import qualified Data.Word64Map as W64 | 104 | import qualified Data.Word64Map as W64 |
104 | import Network.Tox.AggregateSession | 105 | import Network.Tox.AggregateSession |
105 | import qualified Network.Tox.Session as Tox (Session) | 106 | import qualified Network.Tox.Session as Tox (Session) |
@@ -735,16 +736,19 @@ clientSession s@Session{..} sock cnum h = do | |||
735 | | otherwise = [show n, "error!","","",""] | 736 | | otherwise = [show n, "error!","","",""] |
736 | -- otherwise = [show n, "error!",show (IntMap.lookup n rm),show (IntMap.null rm),""] | 737 | -- otherwise = [show n, "error!",show (IntMap.lookup n rm),show (IntMap.null rm),""] |
737 | r = map (uncurry showRecord) rs | 738 | r = map (uncurry showRecord) rs |
739 | (rcnt,relays) <- currentRelays (tcpRelayPinger onionRouter) | ||
738 | return $ do | 740 | return $ do |
739 | hPutClientChunk h $ unlines [ "trampolines(UDP): " ++ show (IntMap.size uts,tcnt,icnt) | 741 | hPutClientChunk h $ unlines |
740 | ++ if tcpmode then "" else " *" | 742 | [ "trampolines(UDP): " ++ show (IntMap.size uts,tcnt,icnt) |
741 | , "trampolines(TCP): " ++ show (IntMap.size tts,ttcnt,ticnt) | 743 | ++ if tcpmode then "" else " *" |
742 | ++ if tcpmode then " *" else "" | 744 | , "trampolines(TCP): " ++ show (IntMap.size tts,ttcnt,ticnt) |
743 | , "active TCP: " ++ show (MM.size tcps) | 745 | ++ if tcpmode then " *" else "" |
744 | , "pending: " ++ show (W64.size pqs) | 746 | , "active TCP: " ++ show (MM.size tcps) |
745 | , "TCP spill,cache,queue: " | 747 | , "pending: " ++ show (W64.size pqs) |
746 | ++ show (PSQ.size tcp_spill, PSQ.size tcp_cache, PSQ.size tcp_queue)] | 748 | , "TCP spill,cache,queue: " |
747 | hPutClient h $ showColumns $ ["","responses","timeouts", "tcp", "age", "version"]:r | 749 | ++ show (PSQ.size tcp_spill, PSQ.size tcp_cache, PSQ.size tcp_queue)] |
750 | hPutClientChunk h $ showColumns $ ["","responses","timeouts", "tcp", "age", "version"]:r | ||
751 | hPutClient h $ unlines $ ("relays: " ++ show rcnt) : map (mappend " " . show) relays | ||
748 | 752 | ||
749 | ("onion", s) | "udp" <- strp $ map toLower s | 753 | ("onion", s) | "udp" <- strp $ map toLower s |
750 | -> cmd0 $ do | 754 | -> cmd0 $ do |
diff --git a/dht/src/Network/Tox/Onion/Routes.hs b/dht/src/Network/Tox/Onion/Routes.hs index c054b99e..d61c721e 100644 --- a/dht/src/Network/Tox/Onion/Routes.hs +++ b/dht/src/Network/Tox/Onion/Routes.hs | |||
@@ -14,6 +14,7 @@ import Network.QueryResponse | |||
14 | import Network.QueryResponse.TCP | 14 | import Network.QueryResponse.TCP |
15 | import Network.Tox.NodeId | 15 | import Network.Tox.NodeId |
16 | import Network.Tox.Onion.Transport as Onion | 16 | import Network.Tox.Onion.Transport as Onion |
17 | import Network.Tox.RelayPinger | ||
17 | import qualified Data.Tox.Relay as TCP | 18 | import qualified Data.Tox.Relay as TCP |
18 | import qualified Network.Tox.TCP as TCP | 19 | import qualified Network.Tox.TCP as TCP |
19 | import qualified TCPProber as TCP | 20 | import qualified TCPProber as TCP |
@@ -88,6 +89,7 @@ data OnionRouter = OnionRouter | |||
88 | , tcpProberThread :: ThreadId | 89 | , tcpProberThread :: ThreadId |
89 | -- | Kademlia table of TCP relays. | 90 | -- | Kademlia table of TCP relays. |
90 | , tcpBucketRefresher :: BucketRefresher NodeId TCP.NodeInfo | 91 | , tcpBucketRefresher :: BucketRefresher NodeId TCP.NodeInfo |
92 | , tcpRelayPinger :: RelayPinger | ||
91 | -- | Debug prints are written to this channel which is then flushed to | 93 | -- | Debug prints are written to this channel which is then flushed to |
92 | -- 'routeLogger'. | 94 | -- 'routeLogger'. |
93 | , routeLog :: TChan String | 95 | , routeLog :: TChan String |
@@ -207,7 +209,8 @@ newOnionRouter crypto perror tcp_enabled = do | |||
207 | writeTChan rlog $ unwords ["Selected TCP Gateway:",show ni,"via",show gw] | 209 | writeTChan rlog $ unwords ["Selected TCP Gateway:",show ni,"via",show gw] |
208 | return gw | 210 | return gw |
209 | } | 211 | } |
210 | or <- atomically $ do | 212 | |
213 | or0 <- atomically $ do | ||
211 | -- chan <- newTChan | 214 | -- chan <- newTChan |
212 | drg <- newTVar drg0 | 215 | drg <- newTVar drg0 |
213 | -- forM_ [0..11] $ \n -> writeTChan chan $ BuildRoute (RouteId n) | 216 | -- forM_ [0..11] $ \n -> writeTChan chan $ BuildRoute (RouteId n) |
@@ -243,12 +246,7 @@ newOnionRouter crypto perror tcp_enabled = do | |||
243 | } | 246 | } |
244 | , tcpMode = tcpmode | 247 | , tcpMode = tcpmode |
245 | , tcpKademliaClient = tcp | 248 | , tcpKademliaClient = tcp |
246 | { TCP.tcpClient = | 249 | , tcpRelayPinger = error "forkRouteBuilder: no RelayPinger specified" |
247 | let c = TCP.tcpClient tcp | ||
248 | in c { clientNet = addHandler perror (handleMessage c) | ||
249 | $ onInbound (updateTCP o) | ||
250 | $ clientNet c } | ||
251 | } | ||
252 | , tcpBucketRefresher = refresher | 250 | , tcpBucketRefresher = refresher |
253 | , routeLog = rlog | 251 | , routeLog = rlog |
254 | , routeThread = error "forkRouteBuilder not invoked (missing onion route builder thread)." | 252 | , routeThread = error "forkRouteBuilder not invoked (missing onion route builder thread)." |
@@ -259,10 +257,21 @@ newOnionRouter crypto perror tcp_enabled = do | |||
259 | , routeLogger = perror | 257 | , routeLogger = perror |
260 | } | 258 | } |
261 | return o | 259 | return o |
260 | pinger <- forkRelayPinger (kademSpace $ refreshKademlia $ tcpBucketRefresher or0) | ||
261 | (TCP.tcpClient tcp) | ||
262 | let or = or0 { tcpRelayPinger = pinger | ||
263 | , tcpKademliaClient = tcp | ||
264 | { TCP.tcpClient = | ||
265 | let c = TCP.tcpClient tcp | ||
266 | in c { clientNet = addHandler perror (handleMessage c) | ||
267 | $ onInbound (updateTCP or) | ||
268 | $ clientNet c } | ||
269 | } | ||
270 | } | ||
262 | return (or,tcptbl) | 271 | return (or,tcptbl) |
263 | 272 | ||
264 | updateTCP :: OnionRouter -> TCP.NodeInfo -> p -> IO () | 273 | updateTCP :: OnionRouter -> TCP.NodeInfo -> p -> IO () |
265 | updateTCP or addr x = | 274 | updateTCP or addr x = do |
266 | let refresher = tcpBucketRefresher or | 275 | let refresher = tcpBucketRefresher or |
267 | kademlia0 = refreshKademlia refresher | 276 | kademlia0 = refreshKademlia refresher |
268 | kademlia = kademlia0 { kademIO = (kademIO kademlia0) | 277 | kademlia = kademlia0 { kademIO = (kademIO kademlia0) |
@@ -275,7 +284,8 @@ updateTCP or addr x = | |||
275 | tblTransition (kademIO kademlia0) tr | 284 | tblTransition (kademIO kademlia0) tr |
276 | } | 285 | } |
277 | } | 286 | } |
278 | in insertNode kademlia addr | 287 | atomically $ bumpRelay (tcpRelayPinger or) addr |
288 | insertNode kademlia addr | ||
279 | 289 | ||
280 | selectGateway :: TVar (R.BucketList TCP.NodeInfo) -> NodeInfo -> STM (Maybe TCP.NodeInfo) | 290 | selectGateway :: TVar (R.BucketList TCP.NodeInfo) -> NodeInfo -> STM (Maybe TCP.NodeInfo) |
281 | selectGateway tbl ni = do | 291 | selectGateway tbl ni = do |
diff --git a/dht/src/Network/Tox/RelayPinger.hs b/dht/src/Network/Tox/RelayPinger.hs index 00c6f65a..5803c89f 100644 --- a/dht/src/Network/Tox/RelayPinger.hs +++ b/dht/src/Network/Tox/RelayPinger.hs | |||
@@ -58,12 +58,15 @@ addRelay :: RelayPinger -> TCP.NodeInfo -> STM () | |||
58 | addRelay (RelayPinger a kad cli que self) ni = do | 58 | addRelay (RelayPinger a kad cli que self) ni = do |
59 | let nid = kademliaLocation kad ni | 59 | let nid = kademliaLocation kad ni |
60 | nidk = decodeAnnounceKey a $ S.encode nid | 60 | nidk = decodeAnnounceKey a $ S.encode nid |
61 | pingit = ScheduledItem $ \a nidk tm -> do | 61 | pingit = ScheduledItem $ \a nidk tm -> return $ do |
62 | scheduleRel a nidk pingit pinginterval -- Reschedule the next ping. | 62 | m <- tcpPing cli ni |
63 | return $ do | 63 | case m of |
64 | _ <- tcpPing cli ni | 64 | Just () -> atomically $ scheduleRel a nidk pingit pinginterval -- Reschedule the next ping. |
65 | -- TODO: Remove after ping timeout? | 65 | Nothing -> do |
66 | return () | 66 | -- dput XMisc $ "relay-ping: Ping timeout for " ++ show ni |
67 | atomically $ modifyTVar' que $ | ||
68 | \(n,q) -> ( (,) $! (if PSQ.member ni q then n - 1 else n) ) | ||
69 | $ PSQ.delete ni q | ||
67 | modifyTVar' que $ \(n,q) -> | 70 | modifyTVar' que $ \(n,q) -> |
68 | ( (,) $! (if PSQ.member ni q then n else n+1) ) | 71 | ( (,) $! (if PSQ.member ni q then n else n+1) ) |
69 | $ PSQ.insert | 72 | $ PSQ.insert |
@@ -85,14 +88,17 @@ bumpRelay :: RelayPinger -> TCP.NodeInfo -> STM () | |||
85 | bumpRelay rp@(RelayPinger a kad cli que self) ni = do | 88 | bumpRelay rp@(RelayPinger a kad cli que self) ni = do |
86 | let nid = kademliaLocation kad ni | 89 | let nid = kademliaLocation kad ni |
87 | (cnt,q) <- readTVar que | 90 | (cnt,q) <- readTVar que |
88 | if cnt < 4 | 91 | if cnt < 4 || PSQ.member ni q |
89 | then addRelay rp ni | 92 | then addRelay rp ni |
90 | else case PSQ.minView q of | 93 | else case PSQ.minView q of |
91 | Nothing -> addRelay rp ni | 94 | Nothing -> addRelay rp ni |
92 | Just (r :-> Down p, q') | 95 | Just (r :-> Down p, q') |
93 | | let pnew = RelayPriority (rankTCPPort ni) (kademliaXor kad self nid) | 96 | | let pnew = RelayPriority (rankTCPPort ni) (kademliaXor kad self nid) |
94 | , pnew < p | 97 | , pnew < p |
95 | -> delRelay rp r >> addRelay rp ni | 98 | -> do |
99 | writeTVar que (3,q') | ||
100 | unschedule a (decodeAnnounceKey a $ S.encode $ kademliaLocation kad r) | ||
101 | addRelay rp ni | ||
96 | _ -> return () | 102 | _ -> return () |
97 | 103 | ||
98 | currentRelays :: RelayPinger -> STM (Int,[TCP.NodeInfo]) | 104 | currentRelays :: RelayPinger -> STM (Int,[TCP.NodeInfo]) |