diff options
-rw-r--r-- | OnionRouter.hs | 56 | ||||
-rw-r--r-- | Presence/Chat.hs | 2 | ||||
-rw-r--r-- | TCPProber.hs | 2 | ||||
-rw-r--r-- | ToxManager.hs | 8 | ||||
-rw-r--r-- | examples/dhtd.hs | 35 | ||||
-rw-r--r-- | src/Data/Torrent.hs | 18 | ||||
-rw-r--r-- | src/Data/Tox/Onion.hs | 1 | ||||
-rw-r--r-- | src/Network/BitTorrent/MainlineDHT.hs | 2 | ||||
-rw-r--r-- | src/Network/Kademlia/Search.hs | 62 | ||||
-rw-r--r-- | src/Network/Tox/Crypto/Transport.hs | 28 | ||||
-rw-r--r-- | src/Network/Tox/DHT/Handlers.hs | 5 | ||||
-rw-r--r-- | src/Network/Tox/Onion/Handlers.hs | 2 | ||||
-rw-r--r-- | src/Network/Tox/TCP.hs | 8 | ||||
-rw-r--r-- | stack.ghc-8.6.yaml | 1 |
14 files changed, 136 insertions, 94 deletions
diff --git a/OnionRouter.hs b/OnionRouter.hs index ddccb531..96381e7f 100644 --- a/OnionRouter.hs +++ b/OnionRouter.hs | |||
@@ -113,13 +113,13 @@ data RouteRecord = RouteRecord | |||
113 | -- they are deemed non working. This is because, due to network conditions, | 113 | -- they are deemed non working. This is because, due to network conditions, |
114 | -- there may be a large number of newly created paths that do not work and so | 114 | -- there may be a large number of newly created paths that do not work and so |
115 | -- trying them a lot would make finding a working path take much longer. The | 115 | -- trying them a lot would make finding a working path take much longer. The |
116 | -- timeout for a confirmed path (from which a response was received) is 10 | 116 | -- timeout for a confirmed path (from which a response was received) is 12 |
117 | -- seconds with 4 tries without a response. A confirmed path has a maximum | 117 | -- seconds with 4 tries without a response. A confirmed path has a maximum |
118 | -- lifetime of 1200 seconds to make possible deanonimization attacks more | 118 | -- lifetime of 1200 seconds to make possible deanonimization attacks more |
119 | -- difficult. | 119 | -- difficult. |
120 | timeoutForRoute :: RouteRecord -> Int | 120 | timeoutForRoute :: RouteRecord -> Int |
121 | timeoutForRoute RouteRecord{ responseCount = 0 } = 4000000 | 121 | timeoutForRoute RouteRecord{ responseCount = 0 } = 4000000 |
122 | timeoutForRoute RouteRecord{ responseCount = _ } = 10000000 | 122 | timeoutForRoute RouteRecord{ responseCount = _ } = 12000000 |
123 | 123 | ||
124 | freshRoute :: POSIXTime -> OnionRoute -> Maybe RouteRecord -> Maybe RouteRecord | 124 | freshRoute :: POSIXTime -> OnionRoute -> Maybe RouteRecord -> Maybe RouteRecord |
125 | freshRoute birthday r mrec = Just $ RouteRecord | 125 | freshRoute birthday r mrec = Just $ RouteRecord |
@@ -157,18 +157,31 @@ newOnionRouter :: TransportCrypto | |||
157 | (MVar (OnionMessage Identity))))) | 157 | (MVar (OnionMessage Identity))))) |
158 | newOnionRouter crypto perror = do | 158 | newOnionRouter crypto perror = do |
159 | drg0 <- drgNew | 159 | drg0 <- drgNew |
160 | (rlog,pq) <- atomically $ (,) <$> newTChan <*> newTVar W64.empty | 160 | (rlog,pq,rm) <- atomically $ do |
161 | rlog <- newTChan | ||
162 | pq <- newTVar W64.empty | ||
163 | rm <- newArray (0,11) Nothing | ||
164 | return (rlog,pq,rm) | ||
161 | ((tbl,tcptbl),tcp) <- do | 165 | ((tbl,tcptbl),tcp) <- do |
162 | (tcptbl, client) <- TCP.newClient crypto Left $ \case | 166 | (tcptbl, client) <- TCP.newClient crypto Left $ \case |
163 | Left v -> void . tryPutMVar v | 167 | Left v -> void . tryPutMVar v |
164 | Right v -> \case | 168 | Right v -> \case |
165 | TCP.OnionPacketResponse x@(OnionAnnounceResponse n8 n24 _) -> do | 169 | TCP.OnionPacketResponse x@(OnionAnnounceResponse n8 n24 _) -> do |
166 | mod <- lookupSender' pq rlog localhost4 n8 | 170 | mod <- lookupSender' pq rlog localhost4 n8 |
171 | perror $ "TCP announce response from " ++ show mod | ||
167 | forM_ mod $ \od -> do | 172 | forM_ mod $ \od -> do |
168 | Onion.decrypt crypto x od >>= \case | 173 | Onion.decrypt crypto x od >>= \case |
169 | Right (y,_) -> void $ tryPutMVar v y | 174 | Right (y,_) -> do perror $ "decrypted announce response, sending " ++ show y |
175 | let | ||
176 | RouteId rid = fromMaybe (routeId (nodeId (onionNodeInfo od))) | ||
177 | $ onionRouteSpec od | ||
178 | Nonce8 w8 = n8 | ||
179 | atomically $ do | ||
180 | modifyTVar' pq (W64.delete w8) | ||
181 | modifyArray rm (fmap gotResponse) rid | ||
182 | void $ tryPutMVar v y | ||
170 | _ -> return () | 183 | _ -> return () |
171 | _ -> return () | 184 | x -> perror $ "Unexpected TCP query result: " ++ show x |
172 | 185 | ||
173 | let addr = SockAddrInet 0 0 | 186 | let addr = SockAddrInet 0 0 |
174 | tentative_udp = NodeInfo | 187 | tentative_udp = NodeInfo |
@@ -185,13 +198,15 @@ newOnionRouter crypto perror = do | |||
185 | return $ (,) (tbl,tcptbl) TCP.TCPClient | 198 | return $ (,) (tbl,tcptbl) TCP.TCPClient |
186 | { tcpCrypto = crypto | 199 | { tcpCrypto = crypto |
187 | , tcpClient = client | 200 | , tcpClient = client |
188 | , tcpGetGateway = selectGateway tbl | 201 | , tcpGetGateway = \ni -> do |
202 | gw <- selectGateway tbl ni | ||
203 | writeTChan rlog $ unwords ["Selected TCP Gateway:",show ni,"via",show gw] | ||
204 | return gw | ||
189 | } | 205 | } |
190 | or <- atomically $ do | 206 | or <- atomically $ do |
191 | -- chan <- newTChan | 207 | -- chan <- newTChan |
192 | drg <- newTVar drg0 | 208 | drg <- newTVar drg0 |
193 | -- forM_ [0..11] $ \n -> writeTChan chan $ BuildRoute (RouteId n) | 209 | -- forM_ [0..11] $ \n -> writeTChan chan $ BuildRoute (RouteId n) |
194 | rm <- newArray (0,11) Nothing | ||
195 | tn <- newTVar IntMap.empty | 210 | tn <- newTVar IntMap.empty |
196 | ti <- newTVar HashMap.empty | 211 | ti <- newTVar HashMap.empty |
197 | tc <- newTVar 0 | 212 | tc <- newTVar 0 |
@@ -204,7 +219,7 @@ newOnionRouter crypto perror = do | |||
204 | tbl | 219 | tbl |
205 | (TCP.nodeSearch prober tcp) | 220 | (TCP.nodeSearch prober tcp) |
206 | (fmap (maybe False $ const True) . TCP.tcpPing (TCP.tcpClient tcp)) | 221 | (fmap (maybe False $ const True) . TCP.tcpPing (TCP.tcpClient tcp)) |
207 | tcpmode <- newTVar False | 222 | tcpmode <- newTVar True |
208 | let o = OnionRouter | 223 | let o = OnionRouter |
209 | { pendingRoutes = pr | 224 | { pendingRoutes = pr |
210 | , onionDRG = drg | 225 | , onionDRG = drg |
@@ -360,9 +375,9 @@ selectTrampolines or = do | |||
360 | ( "ONION Discarding insecure trampolines:" : (either (map show) (map show) ns)) | 375 | ( "ONION Discarding insecure trampolines:" : (either (map show) (map show) ns)) |
361 | myThreadId >>= flip labelThread ("OnionRouter.selectTrampolines.sleep") | 376 | myThreadId >>= flip labelThread ("OnionRouter.selectTrampolines.sleep") |
362 | case ns of | 377 | case ns of |
363 | Left [_,_,_] -> threadDelay 1000000 -- wait 1 second if we failed the distinct3by predicate. | 378 | Left [_,_,_] -> threadDelay 1000000 -- (tcp) wait 1 second if we failed the distinct3by predicate. |
364 | Right [_,_,_] -> threadDelay 1000000 -- wait 1 second if we failed the distinct3by predicate. | 379 | Right [_,_,_] -> threadDelay 1000000 -- (udp) wait 1 second if we failed the distinct3by predicate. |
365 | _ -> threadDelay 5000000 -- wait 5 seconds if insufficient nodes. | 380 | _ -> threadDelay 5000000 -- wait 5 seconds if insufficient nodes. |
366 | myThreadId >>= flip labelThread ("OnionRouter.selectTrampolines") | 381 | myThreadId >>= flip labelThread ("OnionRouter.selectTrampolines") |
367 | selectTrampolines or | 382 | selectTrampolines or |
368 | Right ns -> do | 383 | Right ns -> do |
@@ -443,11 +458,14 @@ handleEvent getnodes or e@(BuildRoute (RouteId rid)) = do | |||
443 | let asel = sel .&. 0x3 | 458 | let asel = sel .&. 0x3 |
444 | bsel = shiftR sel 2 .&. 0x3 | 459 | bsel = shiftR sel 2 .&. 0x3 |
445 | csel = shiftR sel 4 .&. 0x3 | 460 | csel = shiftR sel 4 .&. 0x3 |
461 | cycle' [] = [] | ||
462 | cycle' ns = cycle ns | ||
463 | sendq :: Word8 -> NodeId -> Int -> IO (Maybe NodeInfo) | ||
446 | sendq s q ni | 464 | sendq s q ni |
447 | | Right ts <- mts = fmap (listToMaybe . drop (fromIntegral s)) <$> getnodes q (ts !! ni) | 465 | | Right ts <- mts = (>>= (listToMaybe . drop (fromIntegral s) . cycle')) <$> getnodes q (ts !! ni) |
448 | | Left ts <- mts = case ni of | 466 | | Left ts <- mts = case ni of |
449 | 0 -> return $ Just $ Just $ TCP.udpNodeInfo (ts !! 0) | 467 | 0 -> return $ Just $ TCP.udpNodeInfo (ts !! 0) |
450 | n -> fmap (listToMaybe . drop (fromIntegral s) . (\(ns,_,_)->ns)) | 468 | n -> (>>= (listToMaybe . drop (fromIntegral s) . (\(ns,_,_)->cycle' ns))) |
451 | <$> TCP.getUDPNodes (tcpKademliaClient or) q (TCP.udpNodeInfo $ ts !! n) | 469 | <$> TCP.getUDPNodes (tcpKademliaClient or) q (TCP.udpNodeInfo $ ts !! n) |
452 | sendqs = do | 470 | sendqs = do |
453 | forkIO $ sendq asel aq 0 >>= atomically . writeTVar av . Just | 471 | forkIO $ sendq asel aq 0 >>= atomically . writeTVar av . Just |
@@ -458,7 +476,7 @@ handleEvent getnodes or e@(BuildRoute (RouteId rid)) = do | |||
458 | tm <- timeout 20000000 $ atomically $ do -- Wait for all 3 results. | 476 | tm <- timeout 20000000 $ atomically $ do -- Wait for all 3 results. |
459 | rs <- catMaybes <$> sequence [readTVar av,readTVar bv,readTVar cv] | 477 | rs <- catMaybes <$> sequence [readTVar av,readTVar bv,readTVar cv] |
460 | case rs of [_,_,_] -> do | 478 | case rs of [_,_,_] -> do |
461 | return $ catMaybes $ catMaybes rs | 479 | return $ catMaybes $ rs |
462 | -- self <- IntMap.lookup (-1) <$> readTVar (trampolineNodes or) | 480 | -- self <- IntMap.lookup (-1) <$> readTVar (trampolineNodes or) |
463 | -- return $ maybe (catMaybes rs) (\x -> [x,x,x]) self | 481 | -- return $ maybe (catMaybes rs) (\x -> [x,x,x]) self |
464 | _ -> retry | 482 | _ -> retry |
@@ -629,7 +647,7 @@ hookBucketList :: Show ni => | |||
629 | -> RoutingTransition ni | 647 | -> RoutingTransition ni |
630 | -> STM () | 648 | -> STM () |
631 | hookBucketList kademlia bkts0 or TrampolineSet{..} (RoutingTransition ni Accepted) = do | 649 | hookBucketList kademlia bkts0 or TrampolineSet{..} (RoutingTransition ni Accepted) = do |
632 | s <- do | 650 | (s,antibias) <- do |
633 | drg0 <- readTVar (onionDRG or) | 651 | drg0 <- readTVar (onionDRG or) |
634 | bkts <- readTVar bkts0 | 652 | bkts <- readTVar bkts0 |
635 | let antibias = 2 ^ bucketNumber kademlia (kademliaLocation kademlia ni) bkts | 653 | let antibias = 2 ^ bucketNumber kademlia (kademliaLocation kademlia ni) bkts |
@@ -641,7 +659,7 @@ hookBucketList kademlia bkts0 or TrampolineSet{..} (RoutingTransition ni Accepte | |||
641 | let self = (thisNode bkts) { nodeIP = read "127.0.0.1" } | 659 | let self = (thisNode bkts) { nodeIP = read "127.0.0.1" } |
642 | modifyTVar' setNodes (IntMap.insert (-1) self) | 660 | modifyTVar' setNodes (IntMap.insert (-1) self) |
643 | -} | 661 | -} |
644 | return s | 662 | return (s::Int,antibias) |
645 | -- debias via stochastic filter | 663 | -- debias via stochastic filter |
646 | when (s == 0) $ do | 664 | when (s == 0) $ do |
647 | ns <- readTVar setIDs -- (trampolineIds or) | 665 | ns <- readTVar setIDs -- (trampolineIds or) |
@@ -649,7 +667,7 @@ hookBucketList kademlia bkts0 or TrampolineSet{..} (RoutingTransition ni Accepte | |||
649 | Just _ -> return () | 667 | Just _ -> return () |
650 | Nothing -> do | 668 | Nothing -> do |
651 | cnt <- readTVar setCount | 669 | cnt <- readTVar setCount |
652 | writeTChan (routeLog or) $ "ONION trampoline Accepted " ++ unwords [show cnt, show ni] | 670 | writeTChan (routeLog or) $ "ONION trampoline Accepted " ++ unwords ["s="++show (s,antibias),show cnt, show ni] |
653 | modifyTVar' setIDs (HashMap.insert (kademliaLocation kademlia ni) cnt) | 671 | modifyTVar' setIDs (HashMap.insert (kademliaLocation kademlia ni) cnt) |
654 | modifyTVar' setNodes (IntMap.insert cnt ni) | 672 | modifyTVar' setNodes (IntMap.insert cnt ni) |
655 | writeTVar setCount (succ cnt) | 673 | writeTVar setCount (succ cnt) |
@@ -679,7 +697,7 @@ ipkey :: IPClass -> Int | |||
679 | ipkey (IPClass k) = fromIntegral k | 697 | ipkey (IPClass k) = fromIntegral k |
680 | 698 | ||
681 | nodeClass :: NodeInfo -> IPClass | 699 | nodeClass :: NodeInfo -> IPClass |
682 | nodeClass = ipClass. nodeAddr | 700 | nodeClass = ipClass . nodeAddr |
683 | 701 | ||
684 | ipClass :: SockAddr -> IPClass | 702 | ipClass :: SockAddr -> IPClass |
685 | ipClass= either ipClass' ipClass' . either4or6 | 703 | ipClass= either ipClass' ipClass' . either4or6 |
diff --git a/Presence/Chat.hs b/Presence/Chat.hs index b7343b5a..883f40ea 100644 --- a/Presence/Chat.hs +++ b/Presence/Chat.hs | |||
@@ -46,6 +46,8 @@ data MembershipEffect = MembershipEffect { fromMembership :: Membership | |||
46 | | InvalidMembershipEffect | 46 | | InvalidMembershipEffect |
47 | deriving (Eq,Ord,Read,Show) | 47 | deriving (Eq,Ord,Read,Show) |
48 | 48 | ||
49 | instance Semigroup MembershipEffect | ||
50 | |||
49 | instance Monoid MembershipEffect where | 51 | instance Monoid MembershipEffect where |
50 | mempty = NoMembershipEffect | 52 | mempty = NoMembershipEffect |
51 | MembershipEffect a x `mappend` MembershipEffect y b | 53 | MembershipEffect a x `mappend` MembershipEffect y b |
diff --git a/TCPProber.hs b/TCPProber.hs index 8059fea7..db6d0217 100644 --- a/TCPProber.hs +++ b/TCPProber.hs | |||
@@ -167,4 +167,6 @@ nodeSearch prober tcp = Search | |||
167 | { searchSpace = TCP.tcpSpace | 167 | { searchSpace = TCP.tcpSpace |
168 | , searchNodeAddress = TCP.nodeIP &&& TCP.tcpPort | 168 | , searchNodeAddress = TCP.nodeIP &&& TCP.tcpPort |
169 | , searchQuery = getNodes prober tcp | 169 | , searchQuery = getNodes prober tcp |
170 | , searchAlpha = 8 | ||
171 | , searchK = 16 | ||
170 | } | 172 | } |
diff --git a/ToxManager.hs b/ToxManager.hs index 01403d9d..dceb9210 100644 --- a/ToxManager.hs +++ b/ToxManager.hs | |||
@@ -115,8 +115,8 @@ toxman ssvar announcer toxbkts tox presence = ToxManager | |||
115 | if not (Map.null rs) | 115 | if not (Map.null rs) |
116 | then return (acnt,Nothing) | 116 | then return (acnt,Nothing) |
117 | else return (acnt,Just $ \nid -> foldr interweave [] | 117 | else return (acnt,Just $ \nid -> foldr interweave [] |
118 | . map (R.kclosest (searchSpace (toxQSearch tox)) | 118 | . map (R.kclosest (searchSpace $ toxQSearch tox) |
119 | searchK | 119 | (searchK $ toxQSearch tox) |
120 | nid) | 120 | nid) |
121 | <$> mapM (readTVar . snd) toxbkts) | 121 | <$> mapM (readTVar . snd) toxbkts) |
122 | 122 | ||
@@ -575,7 +575,7 @@ nearNodes tox nid = do | |||
575 | bkts6 <- readTVar $ routing6 $ toxRouting tox | 575 | bkts6 <- readTVar $ routing6 $ toxRouting tox |
576 | let nss = | 576 | let nss = |
577 | map | 577 | map |
578 | (R.kclosest (searchSpace (toxQSearch tox)) searchK nid) | 578 | (R.kclosest (searchSpace $ toxQSearch tox) (searchK $ toxQSearch tox) nid) |
579 | [bkts4, bkts6] | 579 | [bkts4, bkts6] |
580 | return $ foldr interweave [] nss | 580 | return $ foldr interweave [] nss |
581 | 581 | ||
@@ -591,7 +591,7 @@ startConnecting0 tx them contact reason = do | |||
591 | let nearNodes nid = do | 591 | let nearNodes nid = do |
592 | bkts4 <- readTVar $ routing4 $ toxRouting tox | 592 | bkts4 <- readTVar $ routing4 $ toxRouting tox |
593 | bkts6 <- readTVar $ routing6 $ toxRouting tox | 593 | bkts6 <- readTVar $ routing6 $ toxRouting tox |
594 | let nss = map (R.kclosest (searchSpace (toxQSearch tox)) searchK nid) | 594 | let nss = map (R.kclosest (searchSpace $ toxQSearch tox) (searchK $ toxQSearch tox) nid) |
595 | [bkts4,bkts6] | 595 | [bkts4,bkts6] |
596 | return $ foldr interweave [] nss | 596 | return $ foldr interweave [] nss |
597 | wanted <- atomically $ (==Just TryingToConnect) <$> readTVar (contactPolicy contact) | 597 | wanted <- atomically $ (==Just TryingToConnect) <$> readTVar (contactPolicy contact) |
diff --git a/examples/dhtd.hs b/examples/dhtd.hs index d014a611..96cfbe0e 100644 --- a/examples/dhtd.hs +++ b/examples/dhtd.hs | |||
@@ -264,7 +264,7 @@ forkSearch :: | |||
264 | -> TVar (Maybe (IO ())) | 264 | -> TVar (Maybe (IO ())) |
265 | -> STM () | 265 | -> STM () |
266 | forkSearch method nid DHTQuery{qsearch,qshowTok,qshowR} dhtSearches dhtBuckets tid kvar = do | 266 | forkSearch method nid DHTQuery{qsearch,qshowTok,qshowR} dhtSearches dhtBuckets tid kvar = do |
267 | ns <- R.kclosest (searchSpace qsearch) searchK nid <$> readTVar dhtBuckets | 267 | ns <- R.kclosest (searchSpace qsearch) (searchK qsearch) nid <$> readTVar dhtBuckets |
268 | st <- newSearch qsearch nid ns | 268 | st <- newSearch qsearch nid ns |
269 | results <- newTVar Set.empty | 269 | results <- newTVar Set.empty |
270 | let storeResult r = modifyTVar' results (Set.insert (qshowR r)) | 270 | let storeResult r = modifyTVar' results (Set.insert (qshowR r)) |
@@ -674,7 +674,8 @@ clientSession s@Session{..} sock cnum h = do | |||
674 | hPutClient h $ "Showing " ++ show tag ++ " messages." | 674 | hPutClient h $ "Showing " ++ show tag ++ " messages." |
675 | 675 | ||
676 | 676 | ||
677 | ("onion", s) -> cmd0 $ do | 677 | ("onion", s) | "" <- strp $ map toLower s |
678 | -> cmd0 $ do | ||
678 | now <- getPOSIXTime | 679 | now <- getPOSIXTime |
679 | join $ atomically $ do | 680 | join $ atomically $ do |
680 | rm <- IntMap.fromList . catMaybes . map (\(i,m) -> fmap (i,) m) <$> getAssocs (routeMap onionRouter) | 681 | rm <- IntMap.fromList . catMaybes . map (\(i,m) -> fmap (i,) m) <$> getAssocs (routeMap onionRouter) |
@@ -690,10 +691,14 @@ clientSession s@Session{..} sock cnum h = do | |||
690 | tcp_spill <- readTVar (TCP.probeSpill $ tcpProber onionRouter) | 691 | tcp_spill <- readTVar (TCP.probeSpill $ tcpProber onionRouter) |
691 | tcp_cache <- readTVar (TCP.probeCache $ tcpProber onionRouter) | 692 | tcp_cache <- readTVar (TCP.probeCache $ tcpProber onionRouter) |
692 | tcp_queue <- readTVar (TCP.probeQueue $ tcpProber onionRouter) | 693 | tcp_queue <- readTVar (TCP.probeQueue $ tcpProber onionRouter) |
694 | tcpmode <- readTVar (tcpMode onionRouter) | ||
693 | let showRecord :: Int -> Int -> [String] | 695 | let showRecord :: Int -> Int -> [String] |
694 | showRecord n wanted_ver | 696 | showRecord n wanted_ver |
695 | | Just RouteRecord{responseCount,timeoutCount,routeVersion,routeBirthTime} <- IntMap.lookup n rm | 697 | | Just RouteRecord{responseCount,timeoutCount,routeVersion,routeBirthTime |
696 | = [ show n, show responseCount, show timeoutCount, show (now-routeBirthTime) | 698 | ,storedRoute=Tox.OnionRoute{routeRelayPort}} <- IntMap.lookup n rm |
699 | = [ show n, show responseCount, show timeoutCount | ||
700 | , maybe "" show routeRelayPort | ||
701 | , show (now - routeBirthTime) | ||
697 | , if routeVersion >= wanted_ver | 702 | , if routeVersion >= wanted_ver |
698 | then show routeVersion | 703 | then show routeVersion |
699 | else show routeVersion ++ "(pending)" ] | 704 | else show routeVersion ++ "(pending)" ] |
@@ -701,11 +706,23 @@ clientSession s@Session{..} sock cnum h = do | |||
701 | r = map (uncurry showRecord) rs | 706 | r = map (uncurry showRecord) rs |
702 | return $ do | 707 | return $ do |
703 | hPutClientChunk h $ unlines [ "trampolines(UDP): " ++ show (IntMap.size ts,tcnt,icnt) | 708 | hPutClientChunk h $ unlines [ "trampolines(UDP): " ++ show (IntMap.size ts,tcnt,icnt) |
709 | ++ if tcpmode then "" else " *" | ||
704 | , "trampolines(TCP): " ++ show (IntMap.size tts,ttcnt,ticnt) | 710 | , "trampolines(TCP): " ++ show (IntMap.size tts,ttcnt,ticnt) |
711 | ++ if tcpmode then " *" else "" | ||
705 | , "pending: " ++ show (W64.size pqs) | 712 | , "pending: " ++ show (W64.size pqs) |
706 | , "TCP spill,cache,queue: " | 713 | , "TCP spill,cache,queue: " |
707 | ++ show (PSQ.size tcp_spill, PSQ.size tcp_cache, PSQ.size tcp_queue)] | 714 | ++ show (PSQ.size tcp_spill, PSQ.size tcp_cache, PSQ.size tcp_queue)] |
708 | hPutClient h $ showColumns $ ["","responses","timeouts", "age", "version"]:r | 715 | hPutClient h $ showColumns $ ["","responses","timeouts", "tcp", "age", "version"]:r |
716 | |||
717 | ("onion", s) | "udp" <- strp $ map toLower s | ||
718 | -> cmd0 $ do | ||
719 | atomically $ writeTVar (tcpMode onionRouter) False | ||
720 | hPutClient h "Onion routes: UDP." | ||
721 | |||
722 | ("onion", s) | "tcp" <- strp $ map toLower s | ||
723 | -> cmd0 $ do | ||
724 | atomically $ writeTVar (tcpMode onionRouter) True | ||
725 | hPutClient h "Onion routes: TCP." | ||
709 | 726 | ||
710 | ("g", s) | Just DHT{..} <- Map.lookup netname dhts | 727 | ("g", s) | Just DHT{..} <- Map.lookup netname dhts |
711 | -> cmd0 $ do | 728 | -> cmd0 $ do |
@@ -884,7 +901,7 @@ clientSession s@Session{..} sock cnum h = do | |||
884 | akey | 901 | akey |
885 | (AnnounceMethod qsearch asend | 902 | (AnnounceMethod qsearch asend |
886 | (\nid -> R.kclosest (searchSpace qsearch) | 903 | (\nid -> R.kclosest (searchSpace qsearch) |
887 | searchK | 904 | (searchK qsearch) |
888 | nid | 905 | nid |
889 | <$> readTVar dhtBuckets) | 906 | <$> readTVar dhtBuckets) |
890 | (announceTarget dta) | 907 | (announceTarget dta) |
@@ -910,7 +927,7 @@ clientSession s@Session{..} sock cnum h = do | |||
910 | akey | 927 | akey |
911 | (SearchMethod qsearch (asend pub) | 928 | (SearchMethod qsearch (asend pub) |
912 | (\nid -> R.kclosest (searchSpace qsearch) | 929 | (\nid -> R.kclosest (searchSpace qsearch) |
913 | searchK | 930 | (searchK qsearch) |
914 | nid | 931 | nid |
915 | <$> readTVar dhtBuckets) | 932 | <$> readTVar dhtBuckets) |
916 | (announceTarget dta) | 933 | (announceTarget dta) |
@@ -1514,7 +1531,9 @@ initTox opts ssvar keysdb mbxmpp invc = case porttox opts of | |||
1514 | , dhtQuery = Map.singleton "node" DHTQuery | 1531 | , dhtQuery = Map.singleton "node" DHTQuery |
1515 | { qsearch = TCP.nodeSearch tcpprober tcpclient | 1532 | { qsearch = TCP.nodeSearch tcpprober tcpclient |
1516 | , qhandler = \ni nid -> do | 1533 | , qhandler = \ni nid -> do |
1517 | ns <- R.kclosest (searchSpace $ TCP.nodeSearch tcpprober tcpclient) searchK nid | 1534 | ns <- R.kclosest (searchSpace $ TCP.nodeSearch tcpprober tcpclient) |
1535 | (searchK $ TCP.nodeSearch tcpprober tcpclient) | ||
1536 | nid | ||
1518 | <$> atomically (readTVar $ refreshBuckets tcpRefresher) | 1537 | <$> atomically (readTVar $ refreshBuckets tcpRefresher) |
1519 | return (ns,ns,Just ()) | 1538 | return (ns,ns,Just ()) |
1520 | , qshowR = show -- TCP.NodeInfo | 1539 | , qshowR = show -- TCP.NodeInfo |
diff --git a/src/Data/Torrent.hs b/src/Data/Torrent.hs index 69461488..32c709be 100644 --- a/src/Data/Torrent.hs +++ b/src/Data/Torrent.hs | |||
@@ -42,7 +42,7 @@ module Data.Torrent | |||
42 | , FileOffset | 42 | , FileOffset |
43 | , FileSize | 43 | , FileSize |
44 | , FileInfo (..) | 44 | , FileInfo (..) |
45 | #ifdef VERSION_lens | 45 | #ifdef USE_lens |
46 | , fileLength | 46 | , fileLength |
47 | , filePath | 47 | , filePath |
48 | , fileMD5Sum | 48 | , fileMD5Sum |
@@ -50,7 +50,7 @@ module Data.Torrent | |||
50 | 50 | ||
51 | -- ** Layout info | 51 | -- ** Layout info |
52 | , LayoutInfo (..) | 52 | , LayoutInfo (..) |
53 | #ifdef VERSION_lens | 53 | #ifdef USE_lens |
54 | , singleFile | 54 | , singleFile |
55 | , multiFile | 55 | , multiFile |
56 | , rootDirName | 56 | , rootDirName |
@@ -90,7 +90,7 @@ module Data.Torrent | |||
90 | -- ** Piece control | 90 | -- ** Piece control |
91 | , HashList (..) | 91 | , HashList (..) |
92 | , PieceInfo (..) | 92 | , PieceInfo (..) |
93 | #ifdef VERSION_lens | 93 | #ifdef USE_lens |
94 | , pieceLength | 94 | , pieceLength |
95 | , pieceHashes | 95 | , pieceHashes |
96 | #endif | 96 | #endif |
@@ -102,7 +102,7 @@ module Data.Torrent | |||
102 | 102 | ||
103 | -- * Info dictionary | 103 | -- * Info dictionary |
104 | , InfoDict (..) | 104 | , InfoDict (..) |
105 | #ifdef VERSION_lens | 105 | #ifdef USE_lens |
106 | , infohash | 106 | , infohash |
107 | , layoutInfo | 107 | , layoutInfo |
108 | , pieceInfo | 108 | , pieceInfo |
@@ -115,7 +115,7 @@ module Data.Torrent | |||
115 | -- * Torrent file | 115 | -- * Torrent file |
116 | , Torrent(..) | 116 | , Torrent(..) |
117 | 117 | ||
118 | #ifdef VERSION_lens | 118 | #ifdef USE_lens |
119 | -- ** Lenses | 119 | -- ** Lenses |
120 | , announce | 120 | , announce |
121 | , announceList | 121 | , announceList |
@@ -378,7 +378,7 @@ data FileInfo a = FileInfo { | |||
378 | , Functor, Foldable | 378 | , Functor, Foldable |
379 | ) | 379 | ) |
380 | 380 | ||
381 | #ifdef VERSION_lens | 381 | #ifdef USE_lens |
382 | makeLensesFor | 382 | makeLensesFor |
383 | [ ("fiLength", "fileLength") | 383 | [ ("fiLength", "fileLength") |
384 | , ("fiMD5Sum", "fileMD5Sum") | 384 | , ("fiMD5Sum", "fileMD5Sum") |
@@ -467,7 +467,7 @@ data LayoutInfo | |||
467 | , liDirName :: !BS.ByteString | 467 | , liDirName :: !BS.ByteString |
468 | } deriving (Show, Read, Eq, Typeable) | 468 | } deriving (Show, Read, Eq, Typeable) |
469 | 469 | ||
470 | #ifdef VERSION_lens | 470 | #ifdef USE_lens |
471 | makeLensesFor | 471 | makeLensesFor |
472 | [ ("liFile" , "singleFile" ) | 472 | [ ("liFile" , "singleFile" ) |
473 | , ("liFiles" , "multiFile" ) | 473 | , ("liFiles" , "multiFile" ) |
@@ -695,7 +695,7 @@ data PieceInfo = PieceInfo | |||
695 | -- ^ Concatenation of all 20-byte SHA1 hash values. | 695 | -- ^ Concatenation of all 20-byte SHA1 hash values. |
696 | } deriving (Show, Read, Eq, Typeable) | 696 | } deriving (Show, Read, Eq, Typeable) |
697 | 697 | ||
698 | #ifdef VERSION_lens | 698 | #ifdef USE_lens |
699 | -- | Number of bytes in each piece. | 699 | -- | Number of bytes in each piece. |
700 | makeLensesFor [("piPieceLength", "pieceLength")] ''PieceInfo | 700 | makeLensesFor [("piPieceLength", "pieceLength")] ''PieceInfo |
701 | 701 | ||
@@ -902,7 +902,7 @@ data Torrent = Torrent | |||
902 | -- encrypted SHA-1 hash of the info dictionary). | 902 | -- encrypted SHA-1 hash of the info dictionary). |
903 | } deriving (Show, Eq, Typeable) | 903 | } deriving (Show, Eq, Typeable) |
904 | 904 | ||
905 | #ifdef VERSION_lens | 905 | #ifdef USE_lens |
906 | makeLensesFor | 906 | makeLensesFor |
907 | [ ("tAnnounce" , "announce" ) | 907 | [ ("tAnnounce" , "announce" ) |
908 | , ("tAnnounceList", "announceList") | 908 | , ("tAnnounceList", "announceList") |
diff --git a/src/Data/Tox/Onion.hs b/src/Data/Tox/Onion.hs index 85a9d21e..bd802c75 100644 --- a/src/Data/Tox/Onion.hs +++ b/src/Data/Tox/Onion.hs | |||
@@ -704,6 +704,7 @@ data DataToRoute = DataToRoute | |||
704 | { dataFromKey :: PublicKey -- Real public key of sender | 704 | { dataFromKey :: PublicKey -- Real public key of sender |
705 | , dataToRoute :: Encrypted OnionData -- (Word8,ByteString) -- DHTPK 0x9c | 705 | , dataToRoute :: Encrypted OnionData -- (Word8,ByteString) -- DHTPK 0x9c |
706 | } | 706 | } |
707 | deriving Show | ||
707 | 708 | ||
708 | instance Sized DataToRoute where | 709 | instance Sized DataToRoute where |
709 | size = ConstSize 32 <> contramap dataToRoute size | 710 | size = ConstSize 32 <> contramap dataToRoute size |
diff --git a/src/Network/BitTorrent/MainlineDHT.hs b/src/Network/BitTorrent/MainlineDHT.hs index a29657af..6f47e38f 100644 --- a/src/Network/BitTorrent/MainlineDHT.hs +++ b/src/Network/BitTorrent/MainlineDHT.hs | |||
@@ -1076,6 +1076,8 @@ mainlineSearch qry = Search | |||
1076 | { searchSpace = mainlineSpace | 1076 | { searchSpace = mainlineSpace |
1077 | , searchNodeAddress = nodeIP &&& nodePort | 1077 | , searchNodeAddress = nodeIP &&& nodePort |
1078 | , searchQuery = qry | 1078 | , searchQuery = qry |
1079 | , searchAlpha = 8 | ||
1080 | , searchK = 16 | ||
1079 | } | 1081 | } |
1080 | 1082 | ||
1081 | nodeSearch :: MainlineClient -> Search NodeId (IP, PortNumber) () NodeInfo NodeInfo | 1083 | nodeSearch :: MainlineClient -> Search NodeId (IP, PortNumber) () NodeInfo NodeInfo |
diff --git a/src/Network/Kademlia/Search.hs b/src/Network/Kademlia/Search.hs index d3aaae28..e87a8618 100644 --- a/src/Network/Kademlia/Search.hs +++ b/src/Network/Kademlia/Search.hs | |||
@@ -32,36 +32,38 @@ data Search nid addr tok ni r = Search | |||
32 | { searchSpace :: KademliaSpace nid ni | 32 | { searchSpace :: KademliaSpace nid ni |
33 | , searchNodeAddress :: ni -> addr | 33 | , searchNodeAddress :: ni -> addr |
34 | , searchQuery :: nid -> ni -> IO (Maybe ([ni], [r], Maybe tok)) | 34 | , searchQuery :: nid -> ni -> IO (Maybe ([ni], [r], Maybe tok)) |
35 | , searchAlpha :: Int -- α = 8 | ||
36 | -- | 'searchK' should be larger than 'searchAlpha'. How much larger depends on | ||
37 | -- how fast the queries are. For Tox's much slower onion-routed queries, we | ||
38 | -- need to ensure that closer non-responding queries don't completely push out | ||
39 | -- farther away queries. | ||
40 | -- | ||
41 | -- For BitTorrent, setting them both 8 was not an issue, but that is no longer | ||
42 | -- supported because now the number of remembered informants is now the | ||
43 | -- difference between these two numbers. So, if searchK = 16 and searchAlpha = | ||
44 | -- 4, then the number of remembered query responses is 12. | ||
45 | , searchK :: Int -- K = 16 | ||
35 | } | 46 | } |
36 | 47 | ||
37 | data SearchState nid addr tok ni r = SearchState | 48 | data SearchState nid addr tok ni r = SearchState |
38 | {- | ||
39 | { searchParams :: Search nid addr ni r | ||
40 | |||
41 | , searchTarget :: nid | ||
42 | -- | This action will be performed at least once on each search result. | ||
43 | -- It may be invoked multiple times since different nodes may report the | ||
44 | -- same result. If the action returns 'False', the search will be | ||
45 | -- aborted, otherwise it will continue until it is decided that we've | ||
46 | -- asked the closest K nodes to the target. | ||
47 | , searchResult :: r -> STM Bool | ||
48 | |||
49 | -} | ||
50 | |||
51 | { -- | The number of pending queries. Incremented before any query is sent | 49 | { -- | The number of pending queries. Incremented before any query is sent |
52 | -- and decremented when we get a reply. | 50 | -- and decremented when we get a reply. |
53 | searchPendingCount :: TVar Int | 51 | searchPendingCount :: TVar Int |
54 | -- | Nodes scheduled to be queried. | 52 | -- | Nodes scheduled to be queried (roughly at most K). |
55 | , searchQueued :: TVar (MinMaxPSQ ni nid) | 53 | , searchQueued :: TVar (MinMaxPSQ ni nid) |
56 | -- | The nearest (K - α) nodes that issued a reply. | 54 | -- | The nearest (K - α) nodes that issued a reply. |
55 | -- | ||
56 | -- α is the maximum number of simultaneous queries. | ||
57 | , searchInformant :: TVar (MinMaxPSQ' ni nid (Maybe tok)) | 57 | , searchInformant :: TVar (MinMaxPSQ' ni nid (Maybe tok)) |
58 | -- | This tracks already-queried addresses so we avoid bothering them | 58 | -- | This tracks already-queried addresses so we avoid bothering them |
59 | -- again. XXX: We could probably keep only the pending queries in this | 59 | -- again. XXX: We could probably keep only the pending queries in this |
60 | -- set. It also can be a bounded 'MinMaxPSQ', although searchAlpha | 60 | -- set. It also can be a bounded 'MinMaxPSQ', although searchAlpha |
61 | -- should limit the number of outstanding queries. | 61 | -- should limit the number of outstanding queries. |
62 | , searchVisited :: TVar (Set addr) | 62 | , searchVisited :: TVar (Set addr) |
63 | , searchSpec :: Search nid addr tok ni r | ||
63 | } | 64 | } |
64 | 65 | ||
66 | |||
65 | newSearch :: ( Ord addr | 67 | newSearch :: ( Ord addr |
66 | , PSQKey nid | 68 | , PSQKey nid |
67 | , PSQKey ni | 69 | , PSQKey ni |
@@ -77,7 +79,7 @@ newSearch :: ( Ord addr | |||
77 | -> nid | 79 | -> nid |
78 | -> [ni] -- Initial nodes to query. | 80 | -> [ni] -- Initial nodes to query. |
79 | -> STM (SearchState nid addr tok ni r) | 81 | -> STM (SearchState nid addr tok ni r) |
80 | newSearch (Search space nAddr qry) target ns = do | 82 | newSearch s@(Search space nAddr qry _ _) target ns = do |
81 | c <- newTVar 0 | 83 | c <- newTVar 0 |
82 | q <- newTVar $ MM.fromList | 84 | q <- newTVar $ MM.fromList |
83 | $ map (\n -> n :-> kademliaXor space target (kademliaLocation space n)) | 85 | $ map (\n -> n :-> kademliaXor space target (kademliaLocation space n)) |
@@ -85,7 +87,7 @@ newSearch (Search space nAddr qry) target ns = do | |||
85 | i <- newTVar MM.empty | 87 | i <- newTVar MM.empty |
86 | v <- newTVar Set.empty | 88 | v <- newTVar Set.empty |
87 | return -- (Search space nAddr qry) , r , target | 89 | return -- (Search space nAddr qry) , r , target |
88 | ( SearchState c q i v ) | 90 | ( SearchState c q i v s ) |
89 | 91 | ||
90 | -- | Discard a value from a key-priority-value tuple. This is useful for | 92 | -- | Discard a value from a key-priority-value tuple. This is useful for |
91 | -- swaping items from a "MinMaxPSQ'" to a "MinMaxPSQ". | 93 | -- swaping items from a "MinMaxPSQ'" to a "MinMaxPSQ". |
@@ -110,21 +112,6 @@ reset nearestNodes qsearch target st = do | |||
110 | writeTVar (searchPendingCount st) 0 | 112 | writeTVar (searchPendingCount st) 0 |
111 | return st | 113 | return st |
112 | 114 | ||
113 | searchAlpha :: Int | ||
114 | searchAlpha = 8 | ||
115 | |||
116 | -- | 'searchK' should be larger than 'searchAlpha'. How much larger depends on | ||
117 | -- how fast the queries are. For Tox's much slower onion-routed queries, we | ||
118 | -- need to ensure that closer non-responding queries don't completely push out | ||
119 | -- farther away queries. | ||
120 | -- | ||
121 | -- For BitTorrent, setting them both 8 was not an issue, but that is no longer | ||
122 | -- supported because now the number of remembered informants is now the | ||
123 | -- difference between these two numbers. So, if searchK = 16 and searchAlpha = | ||
124 | -- 4, then the number of remembered query responses is 12. | ||
125 | searchK :: Int | ||
126 | searchK = 16 | ||
127 | |||
128 | sendQuery :: forall addr nid tok ni r. | 115 | sendQuery :: forall addr nid tok ni r. |
129 | ( Ord addr | 116 | ( Ord addr |
130 | , PSQKey nid | 117 | , PSQKey nid |
@@ -159,8 +146,11 @@ sendQuery Search{..} searchTarget searchResult sch@SearchState{..} (ni :-> d) = | |||
159 | | otherwise = MM.insertTake k n ( kademliaXor searchSpace searchTarget | 146 | | otherwise = MM.insertTake k n ( kademliaXor searchSpace searchTarget |
160 | $ kademliaLocation searchSpace n ) | 147 | $ kademliaLocation searchSpace n ) |
161 | q | 148 | q |
149 | |||
162 | qsize0 <- MM.size <$> readTVar searchQueued | 150 | qsize0 <- MM.size <$> readTVar searchQueued |
163 | let qsize = if qsize0 < searchK then searchK else qsize0 | 151 | let qsize = if qsize0 < searchK then searchK else qsize0 -- Allow searchQueued to grow |
152 | -- only when there's fewer than | ||
153 | -- K elements. | ||
164 | modifyTVar searchQueued $ \q -> foldr (insertFoundNode qsize) q ns | 154 | modifyTVar searchQueued $ \q -> foldr (insertFoundNode qsize) q ns |
165 | modifyTVar searchInformant $ MM.insertTake' (searchK - searchAlpha) ni tok d | 155 | modifyTVar searchInformant $ MM.insertTake' (searchK - searchAlpha) ni tok d |
166 | flip fix rs $ \loop -> \case | 156 | flip fix rs $ \loop -> \case |
@@ -174,13 +164,13 @@ sendQuery Search{..} searchTarget searchResult sch@SearchState{..} (ni :-> d) = | |||
174 | searchIsFinished :: ( PSQKey nid | 164 | searchIsFinished :: ( PSQKey nid |
175 | , PSQKey ni | 165 | , PSQKey ni |
176 | ) => SearchState nid addr tok ni r -> STM Bool | 166 | ) => SearchState nid addr tok ni r -> STM Bool |
177 | searchIsFinished SearchState{ ..} = do | 167 | searchIsFinished SearchState{..} = do |
178 | q <- readTVar searchQueued | 168 | q <- readTVar searchQueued |
179 | cnt <- readTVar searchPendingCount | 169 | cnt <- readTVar searchPendingCount |
180 | informants <- readTVar searchInformant | 170 | informants <- readTVar searchInformant |
181 | return $ cnt == 0 | 171 | return $ cnt == 0 |
182 | && ( MM.null q | 172 | && ( MM.null q |
183 | || ( MM.size informants >= (searchK - searchAlpha) | 173 | || ( MM.size informants >= (searchK searchSpec - searchAlpha searchSpec) |
184 | && ( PSQ.prio (fromJust $ MM.findMax informants) | 174 | && ( PSQ.prio (fromJust $ MM.findMax informants) |
185 | <= PSQ.prio (fromJust $ MM.findMin q)))) | 175 | <= PSQ.prio (fromJust $ MM.findMin q)))) |
186 | 176 | ||
@@ -197,7 +187,7 @@ search :: | |||
197 | , Show nid | 187 | , Show nid |
198 | ) => Search nid addr tok ni r -> R.BucketList ni -> nid -> (r -> STM Bool) -> IO (SearchState nid addr tok ni r) | 188 | ) => Search nid addr tok ni r -> R.BucketList ni -> nid -> (r -> STM Bool) -> IO (SearchState nid addr tok ni r) |
199 | search sch buckets target result = do | 189 | search sch buckets target result = do |
200 | let ns = R.kclosest (searchSpace sch) searchK target buckets | 190 | let ns = R.kclosest (searchSpace sch) (searchK sch) target buckets |
201 | st <- atomically $ newSearch sch target ns | 191 | st <- atomically $ newSearch sch target ns |
202 | forkIO $ searchLoop sch target result st | 192 | forkIO $ searchLoop sch target result st |
203 | return st | 193 | return st |
@@ -218,7 +208,7 @@ searchLoop sch@Search{..} target result s@SearchState{..} = do | |||
218 | found <- MM.minView <$> readTVar searchQueued | 208 | found <- MM.minView <$> readTVar searchQueued |
219 | case found of | 209 | case found of |
220 | Just (ni :-> d, q) | 210 | Just (ni :-> d, q) |
221 | | -- If there's fewer than /k/ informants and there's any | 211 | | -- If there's fewer than /k - α/ informants and there's any |
222 | -- node we haven't yet got a response from. | 212 | -- node we haven't yet got a response from. |
223 | (MM.size informants < searchK - searchAlpha) && (cnt > 0 || not (MM.null q)) | 213 | (MM.size informants < searchK - searchAlpha) && (cnt > 0 || not (MM.null q)) |
224 | -- Or there's no informants yet at all. | 214 | -- Or there's no informants yet at all. |
diff --git a/src/Network/Tox/Crypto/Transport.hs b/src/Network/Tox/Crypto/Transport.hs index 2c13e168..a18b550d 100644 --- a/src/Network/Tox/Crypto/Transport.hs +++ b/src/Network/Tox/Crypto/Transport.hs | |||
@@ -44,7 +44,7 @@ module Network.Tox.Crypto.Transport | |||
44 | , HasMessage(..) | 44 | , HasMessage(..) |
45 | , HasMessageType(..) | 45 | , HasMessageType(..) |
46 | -- lenses | 46 | -- lenses |
47 | #ifdef VERSION_lens | 47 | #ifdef USE_lens |
48 | , groupNumber, groupNumberToJoin, peerNumber, messageNumber | 48 | , groupNumber, groupNumberToJoin, peerNumber, messageNumber |
49 | , messageName, messageData, name, title, message, messageType | 49 | , messageName, messageData, name, title, message, messageType |
50 | #endif | 50 | #endif |
@@ -288,7 +288,7 @@ putCryptoMessage seqno (Pkt t :=> Identity x) = do | |||
288 | putPacket seqno x | 288 | putPacket seqno x |
289 | 289 | ||
290 | 290 | ||
291 | #ifdef VERSION_lens | 291 | #ifdef USE_lens |
292 | erCompat :: String -> a | 292 | erCompat :: String -> a |
293 | erCompat lens = error $ "Use of '" ++ lens ++ "' lens on incompatible CryptoMessage type" | 293 | erCompat lens = error $ "Use of '" ++ lens ++ "' lens on incompatible CryptoMessage type" |
294 | #endif | 294 | #endif |
@@ -336,7 +336,7 @@ instance HasGroupChatID CryptoMessage where | |||
336 | setGroupChatID _ _= error "setGroupChatID on non-groupchat message." | 336 | setGroupChatID _ _= error "setGroupChatID on non-groupchat message." |
337 | -} | 337 | -} |
338 | 338 | ||
339 | #ifdef VERSION_lens | 339 | #ifdef USE_lens |
340 | groupChatID :: (Functor f, HasGroupChatID x) => (GroupChatId -> f GroupChatId) -> (x -> f x) | 340 | groupChatID :: (Functor f, HasGroupChatID x) => (GroupChatId -> f GroupChatId) -> (x -> f x) |
341 | groupChatID = lens getGroupChatID setGroupChatID | 341 | groupChatID = lens getGroupChatID setGroupChatID |
342 | #endif | 342 | #endif |
@@ -370,7 +370,7 @@ instance HasGroupNumber CryptoMessage where | |||
370 | setGroupNumber _ _ = error "setGroupNumber on CryptoMessage without group number field." | 370 | setGroupNumber _ _ = error "setGroupNumber on CryptoMessage without group number field." |
371 | -} | 371 | -} |
372 | 372 | ||
373 | #ifdef VERSION_lens | 373 | #ifdef USE_lens |
374 | groupNumber :: (Functor f, HasGroupNumber x) => (Word16 -> f Word16) -> (x -> f x) | 374 | groupNumber :: (Functor f, HasGroupNumber x) => (Word16 -> f Word16) -> (x -> f x) |
375 | groupNumber = lens getGroupNumber setGroupNumber | 375 | groupNumber = lens getGroupNumber setGroupNumber |
376 | #endif | 376 | #endif |
@@ -394,7 +394,7 @@ instance HasGroupNumberToJoin CryptoMessage where | |||
394 | setGroupNumberToJoin _ _ = error "setGroupNumberToJoin on CryptoMessage without group number (to join) field." | 394 | setGroupNumberToJoin _ _ = error "setGroupNumberToJoin on CryptoMessage without group number (to join) field." |
395 | -} | 395 | -} |
396 | 396 | ||
397 | #ifdef VERSION_lens | 397 | #ifdef USE_lens |
398 | groupNumberToJoin :: (Functor f, HasGroupNumberToJoin x) => (GroupNumber -> f GroupNumber) -> (x -> f x) | 398 | groupNumberToJoin :: (Functor f, HasGroupNumberToJoin x) => (GroupNumber -> f GroupNumber) -> (x -> f x) |
399 | groupNumberToJoin = lens getGroupNumberToJoin setGroupNumberToJoin | 399 | groupNumberToJoin = lens getGroupNumberToJoin setGroupNumberToJoin |
400 | #endif | 400 | #endif |
@@ -418,7 +418,7 @@ instance HasPeerNumber CryptoMessage where | |||
418 | setPeerNumber _ _ = error "setPeerNumber on CryptoMessage without peer number field." | 418 | setPeerNumber _ _ = error "setPeerNumber on CryptoMessage without peer number field." |
419 | -} | 419 | -} |
420 | 420 | ||
421 | #ifdef VERSION_lens | 421 | #ifdef USE_lens |
422 | peerNumber :: (Functor f, HasPeerNumber x) => (Word16 -> f Word16) -> (x -> f x) | 422 | peerNumber :: (Functor f, HasPeerNumber x) => (Word16 -> f Word16) -> (x -> f x) |
423 | peerNumber = lens getPeerNumber setPeerNumber | 423 | peerNumber = lens getPeerNumber setPeerNumber |
424 | #endif | 424 | #endif |
@@ -442,7 +442,7 @@ instance HasMessageNumber CryptoMessage where | |||
442 | setMessageNumber _ _ = error "setMessageNumber on CryptoMessage without message number field." | 442 | setMessageNumber _ _ = error "setMessageNumber on CryptoMessage without message number field." |
443 | -} | 443 | -} |
444 | 444 | ||
445 | #ifdef VERSION_lens | 445 | #ifdef USE_lens |
446 | messageNumber :: (Functor f, HasMessageNumber x) => (Word32 -> f Word32) -> (x -> f x) | 446 | messageNumber :: (Functor f, HasMessageNumber x) => (Word32 -> f Word32) -> (x -> f x) |
447 | messageNumber = lens getMessageNumber setMessageNumber | 447 | messageNumber = lens getMessageNumber setMessageNumber |
448 | #endif | 448 | #endif |
@@ -468,7 +468,7 @@ instance HasMessageName CryptoMessage where | |||
468 | setMessageName _ _ = error "setMessageName on CryptoMessage without message name field." | 468 | setMessageName _ _ = error "setMessageName on CryptoMessage without message name field." |
469 | -} | 469 | -} |
470 | 470 | ||
471 | #ifdef VERSION_lens | 471 | #ifdef USE_lens |
472 | messageName :: (Functor f, HasMessageName x) => (MessageName -> f MessageName) -> (x -> f x) | 472 | messageName :: (Functor f, HasMessageName x) => (MessageName -> f MessageName) -> (x -> f x) |
473 | messageName = lens getMessageName setMessageName | 473 | messageName = lens getMessageName setMessageName |
474 | #endif | 474 | #endif |
@@ -514,7 +514,7 @@ instance AsWord64 MessageType where | |||
514 | fromWord64 x | x < 1024, x .|. 0x0200 == 0x0200 = GrpMsg (toEnum8 ((x - 512) `div` 256)) (toEnum8 x) | 514 | fromWord64 x | x < 1024, x .|. 0x0200 == 0x0200 = GrpMsg (toEnum8 ((x - 512) `div` 256)) (toEnum8 x) |
515 | fromWord64 x = error "Not clear how to convert Word64 to MessageType" | 515 | fromWord64 x = error "Not clear how to convert Word64 to MessageType" |
516 | 516 | ||
517 | #ifdef VERSION_lens | 517 | #ifdef USE_lens |
518 | word16 :: (Functor f, AsWord16 x) => (Word16 -> f Word16) -> (x -> f x) | 518 | word16 :: (Functor f, AsWord16 x) => (Word16 -> f Word16) -> (x -> f x) |
519 | word16 = lens toWord16 (\_ x -> fromWord16 x) | 519 | word16 = lens toWord16 (\_ x -> fromWord16 x) |
520 | #endif | 520 | #endif |
@@ -559,7 +559,7 @@ instance HasMessageType CryptoData where | |||
559 | setMessageType cd@(CryptoData { bufferData=bd }) typ = cd { bufferData=setMessageType bd typ } | 559 | setMessageType cd@(CryptoData { bufferData=bd }) typ = cd { bufferData=setMessageType bd typ } |
560 | -} | 560 | -} |
561 | 561 | ||
562 | #ifdef VERSION_lens | 562 | #ifdef USE_lens |
563 | -- | This lens should always succeed on CryptoMessage | 563 | -- | This lens should always succeed on CryptoMessage |
564 | messageType :: (Functor f, HasMessageType x) => (MessageType -> f MessageType) -> (x -> f x) | 564 | messageType :: (Functor f, HasMessageType x) => (MessageType -> f MessageType) -> (x -> f x) |
565 | messageType = lens getMessageType setMessageType | 565 | messageType = lens getMessageType setMessageType |
@@ -589,7 +589,7 @@ instance HasMessageData CryptoMessage where | |||
589 | setMessageData _ _ = error "setMessageData on CryptoMessage without message data field." | 589 | setMessageData _ _ = error "setMessageData on CryptoMessage without message data field." |
590 | -} | 590 | -} |
591 | 591 | ||
592 | #ifdef VERSION_lens | 592 | #ifdef USE_lens |
593 | messageData :: (Functor f, HasMessageData x) => (MessageData -> f MessageData) -> (x -> f x) | 593 | messageData :: (Functor f, HasMessageData x) => (MessageData -> f MessageData) -> (x -> f x) |
594 | messageData = lens getMessageData setMessageData | 594 | messageData = lens getMessageData setMessageData |
595 | #endif | 595 | #endif |
@@ -621,7 +621,7 @@ instance HasTitle CryptoMessage where | |||
621 | setTitle _ _ = error "setTitle on CryptoMessage without title field." | 621 | setTitle _ _ = error "setTitle on CryptoMessage without title field." |
622 | -} | 622 | -} |
623 | 623 | ||
624 | #ifdef VERSION_lens | 624 | #ifdef USE_lens |
625 | title :: (Functor f, HasTitle x) => (Text -> f Text) -> (x -> f x) | 625 | title :: (Functor f, HasTitle x) => (Text -> f Text) -> (x -> f x) |
626 | title = lens getTitle setTitle | 626 | title = lens getTitle setTitle |
627 | #endif | 627 | #endif |
@@ -653,7 +653,7 @@ instance HasMessage CryptoMessage where | |||
653 | setMessage _ _ = error "setMessage on CryptoMessage without message field." | 653 | setMessage _ _ = error "setMessage on CryptoMessage without message field." |
654 | -} | 654 | -} |
655 | 655 | ||
656 | #ifdef VERSION_lens | 656 | #ifdef USE_lens |
657 | message :: (Functor f, HasMessage x) => (Text -> f Text) -> (x -> f x) | 657 | message :: (Functor f, HasMessage x) => (Text -> f Text) -> (x -> f x) |
658 | message = lens getMessage setMessage | 658 | message = lens getMessage setMessage |
659 | #endif | 659 | #endif |
@@ -675,7 +675,7 @@ instance HasName CryptoMessage where | |||
675 | setName _ _ = error "setName on CryptoMessage without name field." | 675 | setName _ _ = error "setName on CryptoMessage without name field." |
676 | -} | 676 | -} |
677 | 677 | ||
678 | #ifdef VERSION_lens | 678 | #ifdef USE_lens |
679 | name :: (Functor f, HasTitle x) => (Text -> f Text) -> (x -> f x) | 679 | name :: (Functor f, HasTitle x) => (Text -> f Text) -> (x -> f x) |
680 | name = lens getTitle setTitle | 680 | name = lens getTitle setTitle |
681 | #endif | 681 | #endif |
diff --git a/src/Network/Tox/DHT/Handlers.hs b/src/Network/Tox/DHT/Handlers.hs index 2fbac5d3..afdf2cc3 100644 --- a/src/Network/Tox/DHT/Handlers.hs +++ b/src/Network/Tox/DHT/Handlers.hs | |||
@@ -195,6 +195,8 @@ newRouting addr crypto update4 update6 = do | |||
195 | { searchSpace = toxSpace | 195 | { searchSpace = toxSpace |
196 | , searchNodeAddress = nodeIP &&& nodePort | 196 | , searchNodeAddress = nodeIP &&& nodePort |
197 | , searchQuery = \_ _ -> return Nothing | 197 | , searchQuery = \_ _ -> return Nothing |
198 | , searchAlpha = 1 | ||
199 | , searchK = 2 | ||
198 | } | 200 | } |
199 | tbl4 <- newTVar $ R.nullTable (comparing nodeId) (\s -> hashWithSalt s . nodeId) tentative_info4 R.defaultBucketCount | 201 | tbl4 <- newTVar $ R.nullTable (comparing nodeId) (\s -> hashWithSalt s . nodeId) tentative_info4 R.defaultBucketCount |
200 | tbl6 <- newTVar $ R.nullTable (comparing nodeId) (\s -> hashWithSalt s . nodeId) tentative_info6 R.defaultBucketCount | 202 | tbl6 <- newTVar $ R.nullTable (comparing nodeId) (\s -> hashWithSalt s . nodeId) tentative_info6 R.defaultBucketCount |
@@ -524,4 +526,7 @@ nodeSearch client cbvar = Search | |||
524 | { searchSpace = toxSpace | 526 | { searchSpace = toxSpace |
525 | , searchNodeAddress = nodeIP &&& nodePort | 527 | , searchNodeAddress = nodeIP &&& nodePort |
526 | , searchQuery = getNodes client cbvar | 528 | , searchQuery = getNodes client cbvar |
529 | , searchAlpha = 8 | ||
530 | , searchK = 16 | ||
531 | |||
527 | } | 532 | } |
diff --git a/src/Network/Tox/Onion/Handlers.hs b/src/Network/Tox/Onion/Handlers.hs index a16508cd..52cc298d 100644 --- a/src/Network/Tox/Onion/Handlers.hs +++ b/src/Network/Tox/Onion/Handlers.hs | |||
@@ -219,6 +219,8 @@ toxidSearch getTimeout crypto client = Search | |||
219 | { searchSpace = toxSpace | 219 | { searchSpace = toxSpace |
220 | , searchNodeAddress = nodeIP &&& nodePort | 220 | , searchNodeAddress = nodeIP &&& nodePort |
221 | , searchQuery = getRendezvous getTimeout crypto client | 221 | , searchQuery = getRendezvous getTimeout crypto client |
222 | , searchAlpha = 3 | ||
223 | , searchK = 6 | ||
222 | } | 224 | } |
223 | 225 | ||
224 | announceSerializer :: (TransactionId -> OnionDestination r -> STM (OnionDestination r, Int)) | 226 | announceSerializer :: (TransactionId -> OnionDestination r -> STM (OnionDestination r, Int)) |
diff --git a/src/Network/Tox/TCP.hs b/src/Network/Tox/TCP.hs index 1111d3b8..a7881c24 100644 --- a/src/Network/Tox/TCP.hs +++ b/src/Network/Tox/TCP.hs | |||
@@ -191,15 +191,15 @@ getUDPNodes' tcp seeking dst0 = do | |||
191 | n24 <- transportNewNonce (tcpCrypto tcp) | 191 | n24 <- transportNewNonce (tcpCrypto tcp) |
192 | return (b,c,n24) | 192 | return (b,c,n24) |
193 | let (dst,gateway') = if UDP.nodeId dst0 == nodeId gateway | 193 | let (dst,gateway') = if UDP.nodeId dst0 == nodeId gateway |
194 | then ( dst0 { UDP.nodeIP = fromJust $ fromSockAddr localhost4 } | 194 | then ( dst0 { UDP.nodeIP = fromJust $ Network.Address.fromSockAddr localhost4 } |
195 | , gateway { udpNodeInfo = (udpNodeInfo gateway) | 195 | , gateway { udpNodeInfo = (udpNodeInfo gateway) |
196 | { UDP.nodeIP = fromJust $ fromSockAddr localhost4 }}) | 196 | { UDP.nodeIP = fromJust $ Network.Address.fromSockAddr localhost4 }}) |
197 | else (dst0,gateway) | 197 | else (dst0,gateway) |
198 | wrap2 <- lookupNonceFunction (tcpCrypto tcp) b (UDP.id2key $ UDP.nodeId dst) | 198 | wrap2 <- lookupNonceFunction (tcpCrypto tcp) b (UDP.id2key $ UDP.nodeId dst) |
199 | wrap1 <- lookupNonceFunction (tcpCrypto tcp) c (UDP.id2key $ nodeId gateway) | 199 | wrap1 <- lookupNonceFunction (tcpCrypto tcp) c (UDP.id2key $ nodeId gateway) |
200 | wrap0 <- lookupNonceFunction (tcpCrypto tcp) (transportSecret $ tcpCrypto tcp) (UDP.id2key $ UDP.nodeId dst) | 200 | wrap0 <- lookupNonceFunction (tcpCrypto tcp) (transportSecret $ tcpCrypto tcp) (UDP.id2key $ UDP.nodeId dst) |
201 | let meth = MethodSerializer -- MethodSerializer Nonce8 NodeInfo RelayPacket meth AnnounceRequest (Either String AnnounceResponse) | 201 | let meth = MethodSerializer -- MethodSerializer Nonce8 NodeInfo RelayPacket meth AnnounceRequest (Either String AnnounceResponse) |
202 | { methodTimeout = \tid addr -> return (addr,8000000) -- 8 second timeout | 202 | { methodTimeout = \tid addr -> return (addr,12000000) -- 12 second timeout |
203 | , method = () -- meth | 203 | , method = () -- meth |
204 | , wrapQuery = \n8 src gateway x -> | 204 | , wrapQuery = \n8 src gateway x -> |
205 | OnionPacket n24 $ Addressed (UDP.nodeAddr dst) | 205 | OnionPacket n24 $ Addressed (UDP.nodeAddr dst) |
@@ -274,7 +274,7 @@ newClient crypto store load = do | |||
274 | , tableMethods = transactionMethods' store load (contramap (\(Nonce8 w64) -> w64) w64MapMethods) | 274 | , tableMethods = transactionMethods' store load (contramap (\(Nonce8 w64) -> w64) w64MapMethods) |
275 | $ first (either error Nonce8 . decode) . randomBytesGenerate 8 | 275 | $ first (either error Nonce8 . decode) . randomBytesGenerate 8 |
276 | } | 276 | } |
277 | , clientErrorReporter = logErrors | 277 | , clientErrorReporter = logErrors { reportTimeout = reportTimeout ignoreErrors } |
278 | , clientPending = map_var | 278 | , clientPending = map_var |
279 | , clientAddress = \_ -> return $ NodeInfo | 279 | , clientAddress = \_ -> return $ NodeInfo |
280 | { udpNodeInfo = either error id $ UDP.nodeInfo (UDP.key2id $ transportPublic crypto) (SockAddrInet 0 0) | 280 | { udpNodeInfo = either error id $ UDP.nodeInfo (UDP.key2id $ transportPublic crypto) (SockAddrInet 0 0) |
diff --git a/stack.ghc-8.6.yaml b/stack.ghc-8.6.yaml index 1aa127cb..65555e0a 100644 --- a/stack.ghc-8.6.yaml +++ b/stack.ghc-8.6.yaml | |||
@@ -9,6 +9,7 @@ packages: | |||
9 | flags: {} | 9 | flags: {} |
10 | extra-package-dbs: [] | 10 | extra-package-dbs: [] |
11 | extra-deps: | 11 | extra-deps: |
12 | - rank2classes-1.1.0.1 | ||
12 | - cryptonite-0.23 | 13 | - cryptonite-0.23 |
13 | - reference-0.1 | 14 | - reference-0.1 |
14 | - git: https://github.com/afcady/hs-avahi.git | 15 | - git: https://github.com/afcady/hs-avahi.git |