summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--OnionRouter.hs56
-rw-r--r--Presence/Chat.hs2
-rw-r--r--TCPProber.hs2
-rw-r--r--ToxManager.hs8
-rw-r--r--examples/dhtd.hs35
-rw-r--r--src/Data/Torrent.hs18
-rw-r--r--src/Data/Tox/Onion.hs1
-rw-r--r--src/Network/BitTorrent/MainlineDHT.hs2
-rw-r--r--src/Network/Kademlia/Search.hs62
-rw-r--r--src/Network/Tox/Crypto/Transport.hs28
-rw-r--r--src/Network/Tox/DHT/Handlers.hs5
-rw-r--r--src/Network/Tox/Onion/Handlers.hs2
-rw-r--r--src/Network/Tox/TCP.hs8
-rw-r--r--stack.ghc-8.6.yaml1
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.
120timeoutForRoute :: RouteRecord -> Int 120timeoutForRoute :: RouteRecord -> Int
121timeoutForRoute RouteRecord{ responseCount = 0 } = 4000000 121timeoutForRoute RouteRecord{ responseCount = 0 } = 4000000
122timeoutForRoute RouteRecord{ responseCount = _ } = 10000000 122timeoutForRoute RouteRecord{ responseCount = _ } = 12000000
123 123
124freshRoute :: POSIXTime -> OnionRoute -> Maybe RouteRecord -> Maybe RouteRecord 124freshRoute :: POSIXTime -> OnionRoute -> Maybe RouteRecord -> Maybe RouteRecord
125freshRoute birthday r mrec = Just $ RouteRecord 125freshRoute birthday r mrec = Just $ RouteRecord
@@ -157,18 +157,31 @@ newOnionRouter :: TransportCrypto
157 (MVar (OnionMessage Identity))))) 157 (MVar (OnionMessage Identity)))))
158newOnionRouter crypto perror = do 158newOnionRouter 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 ()
631hookBucketList kademlia bkts0 or TrampolineSet{..} (RoutingTransition ni Accepted) = do 649hookBucketList 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
679ipkey (IPClass k) = fromIntegral k 697ipkey (IPClass k) = fromIntegral k
680 698
681nodeClass :: NodeInfo -> IPClass 699nodeClass :: NodeInfo -> IPClass
682nodeClass = ipClass. nodeAddr 700nodeClass = ipClass . nodeAddr
683 701
684ipClass :: SockAddr -> IPClass 702ipClass :: SockAddr -> IPClass
685ipClass= either ipClass' ipClass' . either4or6 703ipClass= 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
49instance Semigroup MembershipEffect
50
49instance Monoid MembershipEffect where 51instance 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 ()
266forkSearch method nid DHTQuery{qsearch,qshowTok,qshowR} dhtSearches dhtBuckets tid kvar = do 266forkSearch 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
382makeLensesFor 382makeLensesFor
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
471makeLensesFor 471makeLensesFor
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.
700makeLensesFor [("piPieceLength", "pieceLength")] ''PieceInfo 700makeLensesFor [("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
906makeLensesFor 906makeLensesFor
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
708instance Sized DataToRoute where 709instance 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
1081nodeSearch :: MainlineClient -> Search NodeId (IP, PortNumber) () NodeInfo NodeInfo 1083nodeSearch :: 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
37data SearchState nid addr tok ni r = SearchState 48data 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
65newSearch :: ( Ord addr 67newSearch :: ( 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)
80newSearch (Search space nAddr qry) target ns = do 82newSearch 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
113searchAlpha :: Int
114searchAlpha = 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.
125searchK :: Int
126searchK = 16
127
128sendQuery :: forall addr nid tok ni r. 115sendQuery :: 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) =
174searchIsFinished :: ( PSQKey nid 164searchIsFinished :: ( 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
177searchIsFinished SearchState{ ..} = do 167searchIsFinished 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)
199search sch buckets target result = do 189search 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
292erCompat :: String -> a 292erCompat :: String -> a
293erCompat lens = error $ "Use of '" ++ lens ++ "' lens on incompatible CryptoMessage type" 293erCompat 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
340groupChatID :: (Functor f, HasGroupChatID x) => (GroupChatId -> f GroupChatId) -> (x -> f x) 340groupChatID :: (Functor f, HasGroupChatID x) => (GroupChatId -> f GroupChatId) -> (x -> f x)
341groupChatID = lens getGroupChatID setGroupChatID 341groupChatID = 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
374groupNumber :: (Functor f, HasGroupNumber x) => (Word16 -> f Word16) -> (x -> f x) 374groupNumber :: (Functor f, HasGroupNumber x) => (Word16 -> f Word16) -> (x -> f x)
375groupNumber = lens getGroupNumber setGroupNumber 375groupNumber = 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
398groupNumberToJoin :: (Functor f, HasGroupNumberToJoin x) => (GroupNumber -> f GroupNumber) -> (x -> f x) 398groupNumberToJoin :: (Functor f, HasGroupNumberToJoin x) => (GroupNumber -> f GroupNumber) -> (x -> f x)
399groupNumberToJoin = lens getGroupNumberToJoin setGroupNumberToJoin 399groupNumberToJoin = 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
422peerNumber :: (Functor f, HasPeerNumber x) => (Word16 -> f Word16) -> (x -> f x) 422peerNumber :: (Functor f, HasPeerNumber x) => (Word16 -> f Word16) -> (x -> f x)
423peerNumber = lens getPeerNumber setPeerNumber 423peerNumber = 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
446messageNumber :: (Functor f, HasMessageNumber x) => (Word32 -> f Word32) -> (x -> f x) 446messageNumber :: (Functor f, HasMessageNumber x) => (Word32 -> f Word32) -> (x -> f x)
447messageNumber = lens getMessageNumber setMessageNumber 447messageNumber = 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
472messageName :: (Functor f, HasMessageName x) => (MessageName -> f MessageName) -> (x -> f x) 472messageName :: (Functor f, HasMessageName x) => (MessageName -> f MessageName) -> (x -> f x)
473messageName = lens getMessageName setMessageName 473messageName = 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
518word16 :: (Functor f, AsWord16 x) => (Word16 -> f Word16) -> (x -> f x) 518word16 :: (Functor f, AsWord16 x) => (Word16 -> f Word16) -> (x -> f x)
519word16 = lens toWord16 (\_ x -> fromWord16 x) 519word16 = 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
564messageType :: (Functor f, HasMessageType x) => (MessageType -> f MessageType) -> (x -> f x) 564messageType :: (Functor f, HasMessageType x) => (MessageType -> f MessageType) -> (x -> f x)
565messageType = lens getMessageType setMessageType 565messageType = 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
593messageData :: (Functor f, HasMessageData x) => (MessageData -> f MessageData) -> (x -> f x) 593messageData :: (Functor f, HasMessageData x) => (MessageData -> f MessageData) -> (x -> f x)
594messageData = lens getMessageData setMessageData 594messageData = 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
625title :: (Functor f, HasTitle x) => (Text -> f Text) -> (x -> f x) 625title :: (Functor f, HasTitle x) => (Text -> f Text) -> (x -> f x)
626title = lens getTitle setTitle 626title = 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
657message :: (Functor f, HasMessage x) => (Text -> f Text) -> (x -> f x) 657message :: (Functor f, HasMessage x) => (Text -> f Text) -> (x -> f x)
658message = lens getMessage setMessage 658message = 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
679name :: (Functor f, HasTitle x) => (Text -> f Text) -> (x -> f x) 679name :: (Functor f, HasTitle x) => (Text -> f Text) -> (x -> f x)
680name = lens getTitle setTitle 680name = 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
224announceSerializer :: (TransactionId -> OnionDestination r -> STM (OnionDestination r, Int)) 226announceSerializer :: (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:
9flags: {} 9flags: {}
10extra-package-dbs: [] 10extra-package-dbs: []
11extra-deps: 11extra-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