summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-11-28 21:10:25 -0500
committerJoe Crayne <joe@jerkface.net>2020-01-01 22:50:28 -0500
commit05f443e31b52de18e6e2dd3b7b7bd599f28e4a6f (patch)
treedb434da1f23caab25929c4c137f4af6b00e032fc
parent62be467e38b5919baeed90784ac1b62a3e256649 (diff)
Prefer IPv4 when parsing TCP nodes JSON.
-rw-r--r--dht/src/Data/Tox/Msg.hs2
-rw-r--r--dht/src/Data/Tox/Relay.hs22
-rw-r--r--dht/src/DebugUtil.hs3
-rw-r--r--dht/src/Network/QueryResponse/TCP.hs13
-rw-r--r--dht/src/Network/Tox/NodeId.hs16
5 files changed, 47 insertions, 9 deletions
diff --git a/dht/src/Data/Tox/Msg.hs b/dht/src/Data/Tox/Msg.hs
index 66ec6eb1..8819faa7 100644
--- a/dht/src/Data/Tox/Msg.hs
+++ b/dht/src/Data/Tox/Msg.hs
@@ -97,6 +97,7 @@ deriving instance (Show (Pkt a))
97 97
98type CryptoMessage = DSum Pkt Identity 98type CryptoMessage = DSum Pkt Identity
99 99
100msgID :: DSum Pkt Identity -> SomeMsg
100msgID (Pkt mid :=> Identity _) = M mid 101msgID (Pkt mid :=> Identity _) = M mid
101 102
102-- TODO 103-- TODO
@@ -227,6 +228,7 @@ fromEnum8 = fromIntegral . fromEnum
227 228
228data LossyOrLossless = Lossless | Lossy deriving (Eq,Ord,Enum,Show,Bounded) 229data LossyOrLossless = Lossless | Lossy deriving (Eq,Ord,Enum,Show,Bounded)
229 230
231someLossyness :: SomeMsg -> LossyOrLossless
230someLossyness (M m) = lossyness m 232someLossyness (M m) = lossyness m
231 233
232lossyness :: KnownNat n => Msg n t -> LossyOrLossless 234lossyness :: KnownNat n => Msg n t -> LossyOrLossless
diff --git a/dht/src/Data/Tox/Relay.hs b/dht/src/Data/Tox/Relay.hs
index c563db8d..f28a1685 100644
--- a/dht/src/Data/Tox/Relay.hs
+++ b/dht/src/Data/Tox/Relay.hs
@@ -16,7 +16,9 @@ import Data.Data
16import Data.Functor.Contravariant 16import Data.Functor.Contravariant
17import Data.Hashable 17import Data.Hashable
18import qualified Data.HashMap.Strict as HashMap 18import qualified Data.HashMap.Strict as HashMap
19import Data.List
19import Data.Monoid 20import Data.Monoid
21import Data.Ord
20import Data.Serialize 22import Data.Serialize
21import qualified Data.Vector as Vector 23import qualified Data.Vector as Vector
22import Data.Word 24import Data.Word
@@ -217,13 +219,27 @@ instance ToJSON NodeInfo where
217 tbl 219 tbl
218 x -> x -- Shouldn't happen. 220 x -> x -- Shouldn't happen.
219 221
222tcpPortScore :: Word16 -> Word16
223tcpPortScore 443 = 0
224tcpPortScore 80 = 0
225tcpPortScore 3389 = 1
226tcpPortScore _ = 2
227
220instance FromJSON NodeInfo where 228instance FromJSON NodeInfo where
221 parseJSON json = do 229 parseJSON json = do
222 udp <- parseJSON json 230 -- Instead of using ordinary parseJSON to parse the udp node,
231 -- we are using a variation that prefers IPv4 over IPv6.
232 -- The rationale is that must lans without UDP will be using
233 -- IPv4.
234 udp <- UDP.nodeInfoFromJSON True json
223 port <- case json of 235 port <- case json of
224 JSON.Object v -> do 236 JSON.Object v -> do
225 portnum:_ <- v JSON..: "tcp_ports" 237 ps <- v JSON..: "tcp_ports"
226 return (fromIntegral (portnum :: Word16)) 238 if Prelude.null (ps :: [Word16])
239 then fail "TCP.NodeInfo: missing tcp port"
240 else do
241 let portnum = minimumBy (comparing tcpPortScore) ps
242 return (fromIntegral portnum)
227 _ -> fail "TCP.NodeInfo: Expected JSON object." 243 _ -> fail "TCP.NodeInfo: Expected JSON object."
228 return $ NodeInfo udp port 244 return $ NodeInfo udp port
229 245
diff --git a/dht/src/DebugUtil.hs b/dht/src/DebugUtil.hs
index e7a10397..96ab8cc5 100644
--- a/dht/src/DebugUtil.hs
+++ b/dht/src/DebugUtil.hs
@@ -25,7 +25,8 @@ showColumns rows = do
25 " " ++ concat (zipWith (printf "%-*s") (init ws) (init fs)) ++ last fs ++ "\n" 25 " " ++ concat (zipWith (printf "%-*s") (init ws) (init fs)) ++ last fs ++ "\n"
26 26
27 27
28threadReport :: Bool -> IO String 28threadReport :: Bool -- ^ False to summarize search threads.
29 -> IO String
29threadReport want_ss = do 30threadReport want_ss = do
30 threads <- threadsInformation 31 threads <- threadsInformation
31 tm <- getCurrentTime 32 tm <- getCurrentTime
diff --git a/dht/src/Network/QueryResponse/TCP.hs b/dht/src/Network/QueryResponse/TCP.hs
index fdca86b4..45ff73a6 100644
--- a/dht/src/Network/QueryResponse/TCP.hs
+++ b/dht/src/Network/QueryResponse/TCP.hs
@@ -27,6 +27,7 @@ import System.IO
27import System.IO.Error 27import System.IO.Error
28 28
29import DebugTag 29import DebugTag
30import DebugUtil
30import DPut 31import DPut
31import Connection.Tcp (socketFamily) 32import Connection.Tcp (socketFamily)
32import qualified Data.MinMaxPSQ as MM 33import qualified Data.MinMaxPSQ as MM
@@ -104,7 +105,13 @@ acquireConnection mvar tcpcache stream addr bDoCon = do
104 return h) 105 return h)
105 $ \e -> return Nothing 106 $ \e -> return Nothing
106 ret <- fmap join $ forM mh $ \h -> do 107 ret <- fmap join $ forM mh $ \h -> do
107 st <- streamHello stream addr h 108 mst <- catchIOError (Just <$> streamHello stream addr h)
109 (\e -> return Nothing)
110 case mst of
111 Nothing -> do
112 atomically $ modifyTVar' (lru tcpcache) $ MM.delete (TCPAddress $ streamAddr stream addr)
113 return Nothing
114 Just st -> do
108 dput XTCP $ "TCP Connected! " ++ show (streamAddr stream addr) 115 dput XTCP $ "TCP Connected! " ++ show (streamAddr stream addr)
109 signal <- newTVarIO False 116 signal <- newTVarIO False
110 let showAddr a = show (streamAddr stream a) 117 let showAddr a = show (streamAddr stream a)
@@ -129,6 +136,10 @@ acquireConnection mvar tcpcache stream addr bDoCon = do
129 now <- getPOSIXTime 136 now <- getPOSIXTime
130 forM_ (zip [1..] $ MM.toList c) $ \(i,MM.Binding (TCPAddress addr) r (Down tm)) -> do 137 forM_ (zip [1..] $ MM.toList c) $ \(i,MM.Binding (TCPAddress addr) r (Down tm)) -> do
131 dput XTCP $ unwords [show i ++ ".", "Still connected:", show addr, show (now - tm), showStat r] 138 dput XTCP $ unwords [show i ++ ".", "Still connected:", show addr, show (now - tm), showStat r]
139 mreport <- timeout 10000000 $ threadReport False -- XXX: Paranoid timeout
140 case mreport of
141 Just treport -> dput XTCP treport
142 Nothing -> dput XTCP "TCP ERROR: threadReport timed out."
132 hClose h 143 hClose h
133 let v = TCPSession 144 let v = TCPSession
134 { tcpHandle = h 145 { tcpHandle = h
diff --git a/dht/src/Network/Tox/NodeId.hs b/dht/src/Network/Tox/NodeId.hs
index 9a9c893a..e0169199 100644
--- a/dht/src/Network/Tox/NodeId.hs
+++ b/dht/src/Network/Tox/NodeId.hs
@@ -39,6 +39,7 @@ module Network.Tox.NodeId
39 , ToxProgress(..) 39 , ToxProgress(..)
40 , parseToken32 40 , parseToken32
41 , showToken32 41 , showToken32
42 , nodeInfoFromJSON
42 ) where 43 ) where
43 44
44import Control.Applicative 45import Control.Applicative
@@ -52,7 +53,7 @@ import Crypto.Error
52#endif 53#endif
53 54
54import Crypto.PubKey.Curve25519 55import Crypto.PubKey.Curve25519
55import qualified Data.Aeson as JSON 56import qualified Data.Aeson.Types as JSON
56 ;import Data.Aeson (FromJSON, ToJSON, (.=)) 57 ;import Data.Aeson (FromJSON, ToJSON, (.=))
57import Data.Bits.ByteString () 58import Data.Bits.ByteString ()
58import qualified Data.ByteArray as BA 59import qualified Data.ByteArray as BA
@@ -251,13 +252,20 @@ instance ToJSON NodeInfo where
251 , "port" .= (fromIntegral port :: Int) 252 , "port" .= (fromIntegral port :: Int)
252 ] 253 ]
253instance FromJSON NodeInfo where 254instance FromJSON NodeInfo where
254 parseJSON (JSON.Object v) = do 255 parseJSON = nodeInfoFromJSON False
256
257nodeInfoFromJSON :: Bool -> JSON.Value
258 -> JSON.Parser NodeInfo
259nodeInfoFromJSON prefer4 (JSON.Object v) = do
255 nidstr <- v JSON..: "public_key" 260 nidstr <- v JSON..: "public_key"
256 ip6str <- v JSON..:? "ipv6" 261 ip6str <- v JSON..:? "ipv6"
257 ip4str <- v JSON..:? "ipv4" 262 ip4str <- v JSON..:? "ipv4"
258 portnum <- v JSON..: "port" 263 portnum <- v JSON..: "port"
259 ip <- maybe empty (return . IPv6) (ip6str >>= readMaybe) 264 ip <- if prefer4
260 <|> maybe empty (return . IPv4) (ip4str >>= readMaybe) 265 then maybe empty (return . IPv4) (ip4str >>= readMaybe)
266 <|> maybe empty (return . IPv6) (ip6str >>= readMaybe)
267 else maybe empty (return . IPv6) (ip6str >>= readMaybe)
268 <|> maybe empty (return . IPv4) (ip4str >>= readMaybe)
261 let (bs,_) = Base16.decode (C8.pack nidstr) 269 let (bs,_) = Base16.decode (C8.pack nidstr)
262 enid = Base64.decode (C8.pack $ 'A' : map (nmtoken64 False) nidstr) 270 enid = Base64.decode (C8.pack $ 'A' : map (nmtoken64 False) nidstr)
263 idbs <- (guard (B.length bs == 32) >> return bs) 271 idbs <- (guard (B.length bs == 32) >> return bs)