diff options
author | Joe Crayne <joe@jerkface.net> | 2019-11-28 21:10:25 -0500 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2020-01-01 22:50:28 -0500 |
commit | 05f443e31b52de18e6e2dd3b7b7bd599f28e4a6f (patch) | |
tree | db434da1f23caab25929c4c137f4af6b00e032fc | |
parent | 62be467e38b5919baeed90784ac1b62a3e256649 (diff) |
Prefer IPv4 when parsing TCP nodes JSON.
-rw-r--r-- | dht/src/Data/Tox/Msg.hs | 2 | ||||
-rw-r--r-- | dht/src/Data/Tox/Relay.hs | 22 | ||||
-rw-r--r-- | dht/src/DebugUtil.hs | 3 | ||||
-rw-r--r-- | dht/src/Network/QueryResponse/TCP.hs | 13 | ||||
-rw-r--r-- | dht/src/Network/Tox/NodeId.hs | 16 |
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 | ||
98 | type CryptoMessage = DSum Pkt Identity | 98 | type CryptoMessage = DSum Pkt Identity |
99 | 99 | ||
100 | msgID :: DSum Pkt Identity -> SomeMsg | ||
100 | msgID (Pkt mid :=> Identity _) = M mid | 101 | msgID (Pkt mid :=> Identity _) = M mid |
101 | 102 | ||
102 | -- TODO | 103 | -- TODO |
@@ -227,6 +228,7 @@ fromEnum8 = fromIntegral . fromEnum | |||
227 | 228 | ||
228 | data LossyOrLossless = Lossless | Lossy deriving (Eq,Ord,Enum,Show,Bounded) | 229 | data LossyOrLossless = Lossless | Lossy deriving (Eq,Ord,Enum,Show,Bounded) |
229 | 230 | ||
231 | someLossyness :: SomeMsg -> LossyOrLossless | ||
230 | someLossyness (M m) = lossyness m | 232 | someLossyness (M m) = lossyness m |
231 | 233 | ||
232 | lossyness :: KnownNat n => Msg n t -> LossyOrLossless | 234 | lossyness :: 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 | |||
16 | import Data.Functor.Contravariant | 16 | import Data.Functor.Contravariant |
17 | import Data.Hashable | 17 | import Data.Hashable |
18 | import qualified Data.HashMap.Strict as HashMap | 18 | import qualified Data.HashMap.Strict as HashMap |
19 | import Data.List | ||
19 | import Data.Monoid | 20 | import Data.Monoid |
21 | import Data.Ord | ||
20 | import Data.Serialize | 22 | import Data.Serialize |
21 | import qualified Data.Vector as Vector | 23 | import qualified Data.Vector as Vector |
22 | import Data.Word | 24 | import 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 | ||
222 | tcpPortScore :: Word16 -> Word16 | ||
223 | tcpPortScore 443 = 0 | ||
224 | tcpPortScore 80 = 0 | ||
225 | tcpPortScore 3389 = 1 | ||
226 | tcpPortScore _ = 2 | ||
227 | |||
220 | instance FromJSON NodeInfo where | 228 | instance 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 | ||
28 | threadReport :: Bool -> IO String | 28 | threadReport :: Bool -- ^ False to summarize search threads. |
29 | -> IO String | ||
29 | threadReport want_ss = do | 30 | threadReport 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 | |||
27 | import System.IO.Error | 27 | import System.IO.Error |
28 | 28 | ||
29 | import DebugTag | 29 | import DebugTag |
30 | import DebugUtil | ||
30 | import DPut | 31 | import DPut |
31 | import Connection.Tcp (socketFamily) | 32 | import Connection.Tcp (socketFamily) |
32 | import qualified Data.MinMaxPSQ as MM | 33 | import 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 | ||
44 | import Control.Applicative | 45 | import Control.Applicative |
@@ -52,7 +53,7 @@ import Crypto.Error | |||
52 | #endif | 53 | #endif |
53 | 54 | ||
54 | import Crypto.PubKey.Curve25519 | 55 | import Crypto.PubKey.Curve25519 |
55 | import qualified Data.Aeson as JSON | 56 | import qualified Data.Aeson.Types as JSON |
56 | ;import Data.Aeson (FromJSON, ToJSON, (.=)) | 57 | ;import Data.Aeson (FromJSON, ToJSON, (.=)) |
57 | import Data.Bits.ByteString () | 58 | import Data.Bits.ByteString () |
58 | import qualified Data.ByteArray as BA | 59 | import 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 | ] |
253 | instance FromJSON NodeInfo where | 254 | instance FromJSON NodeInfo where |
254 | parseJSON (JSON.Object v) = do | 255 | parseJSON = nodeInfoFromJSON False |
256 | |||
257 | nodeInfoFromJSON :: Bool -> JSON.Value | ||
258 | -> JSON.Parser NodeInfo | ||
259 | nodeInfoFromJSON 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) |