diff --git a/app/Main.hs b/app/Main.hs index 572de7a..a91bfac 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -25,6 +25,7 @@ data WsTunnel = WsTunnel , udpMode :: Bool , udpTimeout :: Int , proxy :: String + , soMark :: Int , serverMode :: Bool , restrictTo :: String , verbose :: Bool @@ -62,6 +63,8 @@ cmdLine = WsTunnel &= typ "String" &= groupname "Client options" , proxy = def &= explicit &= name "p" &= name "httpProxy" &= help "If set, will use this proxy to connect to the server" &= typ "USER:PASS@HOST:PORT" + , soMark = def &= explicit &= name "soMark" + &= help "(linux only) Mark network packet with SO_MARK sockoption with the specified value" &= typ "int" , wsTunnelServer = def &= argPos 0 &= typ "ws[s]://wstunnelServer[:port]" , serverMode = def &= explicit &= name "server" @@ -173,6 +176,7 @@ main = do then Logger.VERBOSE else Logger.NORMAL) + _ <- writeIORef sO_MARK_Value (soMark cfg) runApp cfg serverInfo putStrLn "Goodbye !" return () diff --git a/src/Tunnel.hs b/src/Tunnel.hs index cf4b951..e0fd81a 100644 --- a/src/Tunnel.hs +++ b/src/Tunnel.hs @@ -44,6 +44,8 @@ rrunTCPClient cfg app = bracket (s,addr) <- N.getSocketFamilyTCP (N.getHost cfg) (N.getPort cfg) (N.getAddrFamily cfg) N.setSocketOption s N.RecvBuffer defaultRecvBufferSize N.setSocketOption s N.SendBuffer defaultSendBufferSize + so_mark_val <- readIORef sO_MARK_Value + when (N.isSupportedSocketOption sO_MARK) (N.setSocketOption s sO_MARK so_mark_val) return (s,addr) ) (\r -> catch (N.close $ fst r) (\(_ :: SomeException) -> return ())) diff --git a/src/Types.hs b/src/Types.hs index 839ea63..ae6c49c 100644 --- a/src/Types.hs +++ b/src/Types.hs @@ -35,6 +35,13 @@ defaultRecvBufferSize = unsafeDupablePerformIO $ defaultSendBufferSize :: Int defaultSendBufferSize = defaultRecvBufferSize +sO_MARK :: N.SocketOption +sO_MARK = N.CustomSockOpt (fromIntegral 1, fromIntegral 36) -- https://elixir.bootlin.com/linux/latest/source/arch/alpha/include/uapi/asm/socket.h#L64 + +{-# NOINLINE sO_MARK_Value #-} +sO_MARK_Value :: IORef Int +sO_MARK_Value = unsafeDupablePerformIO $ (newIORef 131072) + data Protocol = UDP | TCP | STDIO | SOCKS5 deriving (Show, Read, Eq) data StdioAppData = StdioAppData