Parse ipv6 for tunnelinfo and server info command line

Former-commit-id: d7bcced397720389fb4da443ddd941831513b337
Former-commit-id: b7149720d33e78efd5455744a97d8f1a44b3a0f0 [formerly 36a0a27cfcb71103e448f59798e7a94e695134fe] [formerly 0a6f2fd33a77e7af032ebbb2f5d20c90515d678e [formerly a01c762112ae5e08e25ff0b55d5cb8b543be7d88 [formerly a01c762112ae5e08e25ff0b55d5cb8b543be7d88 [formerly a01c762112ae5e08e25ff0b55d5cb8b543be7d88 [formerly dd1f0518c5440a2e1a390773fadfc6d7965fa4a8]]]]]
Former-commit-id: 0ba7fc235b47ce11f95c838d4ff1b0ea396fef9c [formerly 7e47b8adcb79aba97189a9e99083d266a258a336]
Former-commit-id: d9d60c9432d6a2ea42db3d1f63542a93b7185ed5
Former-commit-id: f3371f67d2e2a1cb8e366c6d98309c567c9b7225
Former-commit-id: dcadeb51e476ba89773351476ebb0bad1b44400d
Former-commit-id: 61f7fcf1a8c815013fda41321ea240e309a7cc87 [formerly 4d19a57259fe8c341f5f76016d5cbe3a33494874]
Former-commit-id: 53d69bcf8a69464e3e0d53a1d6c6b79c2d718da8
This commit is contained in:
Romain GERARD 2020-01-04 16:39:05 +01:00
parent 8ca1ed9fb3
commit 3d0b3383e9
2 changed files with 39 additions and 9 deletions

View file

@ -88,27 +88,56 @@ parseServerInfo server [] = server
parseServerInfo server ('w':'s':':':'/':'/':xs) = parseServerInfo (server {Main.useTls = False, Main.port = 80}) xs
parseServerInfo server ('w':'s':'s':':':'/':'/':xs) = parseServerInfo (server {Main.useTls = True, Main.port = 443}) xs
parseServerInfo server (':':prt) = server {Main.port = toPort prt}
parseServerInfo server ('[':xs) = parseServerInfo (server {Main.host = BC.unpack . BC.init . fst $ BC.spanEnd (/= ']') (BC.pack xs)}) (BC.unpack . snd $ BC.spanEnd (/= ']') (BC.pack xs))
parseServerInfo server hostPath = parseServerInfo (server {Main.host = takeWhile (/= ':') hostPath}) (dropWhile (/= ':') hostPath)
parseTunnelInfo :: String -> TunnelInfo
parseTunnelInfo str = mk $ BC.unpack <$> BC.split ':' (BC.pack str)
parseTunnelInfo strr = do
let str = BC.pack strr
if BC.count ']' str <= 0 then
mkIPv4 $ BC.unpack <$> BC.split ':' str
else
mkIPv6 $ str
where
mk [lPort, host, rPort] = TunnelInfo {localHost = "127.0.0.1", Main.localPort = toPort lPort, remoteHost = host, remotePort = toPort rPort}
mk [bind,lPort, host,rPort] = TunnelInfo {localHost = bind, Main.localPort = toPort lPort, remoteHost = host, remotePort = toPort rPort}
mk _ = error $ "Invalid tunneling information `" ++ str ++ "`, please use format [BIND:]PORT:HOST:PORT"
mkIPv4 [lPort, host, rPort] = TunnelInfo {localHost = "127.0.0.1", Main.localPort = toPort lPort, remoteHost = host, remotePort = toPort rPort}
mkIPv4 [bind,lPort, host,rPort] = TunnelInfo {localHost = bind, Main.localPort = toPort lPort, remoteHost = host, remotePort = toPort rPort}
mkIPv4 _ = error $ "Invalid tunneling information `" ++ strr ++ "`, please use format [BIND:]PORT:HOST:PORT"
mkIPv6 str = do
let !(localHost, remain) = if BC.head str == '[' then
BC.drop 2 <$> BC.span (/= ']') (BC.drop 1 str)
else if BC.head str < '0' || BC.head str > '9' then
BC.drop 1 <$> BC.span (/= ':') str
else
("", str)
let (remain, rPort) = first BC.init . BC.spanEnd (/= ':') $ str
let (remain2, remoteHost) = if BC.last remain == ']' then
first (BC.init . BC.init) $ BC.spanEnd (/= '[') (BC.init remain)
else
first BC.init $ BC.spanEnd (/= ':') remain
let (remain3, lPort) = BC.spanEnd (/= ':') $ remain2
if remain3 == mempty then
TunnelInfo {localHost = "::1", Main.localPort = toPort (BC.unpack lPort), remoteHost = (BC.unpack remoteHost), remotePort = toPort (BC.unpack rPort)}
else
let localHost = BC.filter (\c -> c /= '[' && c /= ']') (BC.init remain3) in
TunnelInfo {localHost = BC.unpack localHost, Main.localPort = toPort (BC.unpack lPort), remoteHost = (BC.unpack remoteHost), remotePort = toPort (BC.unpack rPort)}
parseRestrictTo :: String -> ((ByteString, Int) -> Bool)
parseRestrictTo "" = const True
parseRestrictTo str = let (!h, !p) = fromMaybe (error "Invalid Parameter restart") parse
parseRestrictTo str = let !(!h, !p) = fromMaybe (error "Invalid Parameter restart") parse
in (\(!hst, !port) -> hst == h && port == p)
where
parse = do
let ret = BC.unpack <$> BC.split ':' (BC.pack str)
guard (length ret == 2)
portNumber <- readMay $ ret !! 1 :: Maybe Int
return (BC.pack (head ret), portNumber)
let (host, port) = BC.spanEnd (/= ':') (BC.pack str)
guard (host /= mempty)
portNumber <- readMay . BC.unpack $ port :: Maybe Int
return $! (BC.filter (\c -> c /= '[' && c /= ']') (BC.init host), portNumber)
parseProxyInfo :: String -> Maybe ProxySettings
parseProxyInfo str = do

View file

@ -1,6 +1,7 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE StrictData #-}
module Types where