moesocks 0.1.1.0 → 0.1.1.10
raw patch · 11 files changed
+117/−11 lines, 11 files
Files
- CHANGELOG.md +6/−0
- config.json +1/−0
- moesocks.cabal +3/−2
- src/Network/MoeSocks/App.hs +5/−0
- src/Network/MoeSocks/Config.hs +1/−0
- src/Network/MoeSocks/Encrypt.hs +6/−2
- src/Network/MoeSocks/Helper.hs +13/−0
- src/Network/MoeSocks/Internal/Socket.hs +50/−0
- src/Network/MoeSocks/Options.hs +13/−0
- src/Network/MoeSocks/TCP.hs +18/−7
- src/Network/MoeSocks/Type.hs +1/−0
CHANGELOG.md view
@@ -1,3 +1,9 @@+0.1.1.10+--------+* Add TCP Fast Open capability. It can be turned on by adding a + `"fast_open":true` in `config.json` or specifying a `--fast-open` flag in+ the command line argument.+ 0.1.1.0 ------- * Use TCP_NOTSENT_LOWAT option to reduce latency
config.json view
@@ -4,6 +4,7 @@ "local":"localhost", "localPort":1090, "password":"birthday!",+ "fast_open":true, "method":"aes-256-cfb" }
moesocks.cabal view
@@ -1,6 +1,6 @@ name: moesocks category: Network-version: 0.1.1.0+version: 0.1.1.10 license: Apache-2.0 synopsis: A functional firewall killer description: A socks5 proxy using the client / server architecture.@@ -58,10 +58,11 @@ Network.MoeSocks.Common Network.MoeSocks.Config Network.MoeSocks.Constant+ Network.MoeSocks.Encrypt Network.MoeSocks.Helper+ Network.MoeSocks.Internal.Socket Network.MoeSocks.Options Network.MoeSocks.TCP Network.MoeSocks.Type Network.MoeSocks.UDP- Network.MoeSocks.Encrypt
src/Network/MoeSocks/App.hs view
@@ -56,6 +56,7 @@ , ("server_port", "remotePort") , ("local_address", "local") , ("local_port", "localPort")+ , ("fast_open", "fastOpen") ] in@@ -201,6 +202,8 @@ case aAppType of TCP_App -> do info_ - "LT: " <> aID <> " nyaa!"++ setSocket_TCP_FAST_OPEN _localSocket listen _localSocket maxListenQueue let handleLocal _socket = do@@ -271,6 +274,8 @@ setSocketOption _remoteSocket ReuseAddr 1 bindSocket _remoteSocket _remoteAddr + setSocket_TCP_FAST_OPEN _remoteSocket+ listen _remoteSocket maxListenQueue let handleRemote _socket = do
src/Network/MoeSocks/Config.hs view
@@ -19,6 +19,7 @@ , _throttle = False , _throttleSpeed = 8000 -- in Kilobytes , _obfuscationFlushBound = 4096+ , _fastOpen = False }
src/Network/MoeSocks/Encrypt.hs view
@@ -128,7 +128,9 @@ _encrypt = \case S.Nothing -> E.cipherFinalBS _ctx S.Just _bytes -> do- E.cipherUpdateBS _ctx _bytes+ if (_bytes & isn't _Empty)+ then E.cipherUpdateBS _ctx _bytes+ else pure mempty pure _encrypt @@ -140,7 +142,9 @@ _decrypt = \case S.Nothing -> E.cipherFinalBS _ctx S.Just _bytes -> do- E.cipherUpdateBS _ctx _bytes + if (_bytes & isn't _Empty)+ then E.cipherUpdateBS _ctx _bytes + else pure mempty pure _decrypt
src/Network/MoeSocks/Helper.hs view
@@ -20,6 +20,7 @@ import Data.Text (Text) import Data.Text.Lens import Data.Time.Clock+import Network.MoeSocks.Internal.Socket (sendAllFastOpenTo) import Network.Socket hiding (send, recv) import Network.Socket.ByteString import Prelude hiding (take, (-)) @@ -258,6 +259,11 @@ send_ :: Socket -> ByteString -> IO () send_ = sendAll ++sendFast_ :: Socket -> ByteString -> SockAddr -> IO ()+sendFast_ = sendAllFastOpenTo++ sendAllRandom :: Int -> Socket -> ByteString -> IO () sendAllRandom aFlushBound aSocket aBuffer = do _loop aBuffer@@ -421,6 +427,13 @@ _consume 0 `onException` _shutdown pure () ++setSocket_TCP_FAST_OPEN:: Socket -> IO ()+setSocket_TCP_FAST_OPEN aSocket = + let _TCP_FASTOPEN = 23+ _TCP_Option = 6+ in+ setSocketOption aSocket (CustomSockOpt (_TCP_Option, _TCP_FASTOPEN)) 1 setSocket_TCP_NOTSENT_LOWAT :: Socket -> IO () setSocket_TCP_NOTSENT_LOWAT aSocket =
+ src/Network/MoeSocks/Internal/Socket.hs view
@@ -0,0 +1,50 @@+{-# LANGUAGE ForeignFunctionInterface #-}++module Network.MoeSocks.Internal.Socket where++import Control.Monad+import Data.ByteString (ByteString)+import Data.ByteString.Unsafe (unsafeUseAsCStringLen)+import Foreign.C.Types+import Foreign.Ptr (Ptr)+import Network.Socket+import Network.Socket.ByteString+import Network.Socket.Internal (withSockAddr)+import qualified Data.ByteString as S++foreign import ccall unsafe "sendto" c_sendto ::+ CInt -> Ptr a -> CSize -> CInt -> Ptr SockAddr -> CInt -> IO CInt++-- | Send data to the socket. The recipient can be specified+-- explicitly, so the socket need not be in a connected state.+-- Returns the number of bytes sent. Applications are responsible for+-- ensuring that all data has been sent.+sendBufToWithFlag :: Socket -- (possibly) bound/connected Socket+ -> Ptr a -> Int -- Data to send+ -> SockAddr+ -> Int+ -> IO Int -- Number of Bytes sent+sendBufToWithFlag + (MkSocket s _family _stype _protocol _status) ptr nbytes addr flags = do+ withSockAddr addr $ \p_addr sz -> do+ liftM fromIntegral $+ c_sendto s ptr (fromIntegral $ nbytes) (fromIntegral flags)+ p_addr (fromIntegral sz)++sendToWithFlag :: Socket -- ^ Socket+ -> ByteString -- ^ Data to send+ -> SockAddr -- ^ Recipient address+ -> Int+ -> IO Int -- ^ Number of bytes sent+sendToWithFlag sock xs addr flags =+ unsafeUseAsCStringLen xs $ \(str, len) -> + sendBufToWithFlag sock str len addr flags++sendAllFastOpenTo :: Socket -- ^ Socket+ -> ByteString -- ^ Data to send+ -> SockAddr -- ^ Recipient address+ -> IO ()+sendAllFastOpenTo sock xs addr = do+ let _MSG_FASTOPEN = 0x20000000 + sent <- sendToWithFlag sock xs addr _MSG_FASTOPEN+ when (sent < S.length xs) $ sendAllTo sock (S.drop sent xs) addr
src/Network/MoeSocks/Options.hs view
@@ -31,6 +31,13 @@ intParam :: O.Mod O.OptionFields Int -> O.Parser (Maybe Value) intParam = optional . fmap toJSON . option auto +bool_To_Maybe :: Bool -> Maybe Bool+bool_To_Maybe False = Nothing+bool_To_Maybe True = Just True++boolParam :: O.Mod O.FlagFields Bool -> O.Parser (Maybe Value)+boolParam = (fmap . fmap) toJSON . fmap bool_To_Maybe . switch+ optionParser :: O.Parser MoeOptions optionParser = let _c = defaultMoeConfig@@ -118,6 +125,10 @@ & view (from _Text)) "timeout connection in seconds" + _fastOpen = boolParam -+ long "fast-open"+ <> help ("use TCP_FASTOPEN, requires Linux 3.7+")+ _obfuscation :: O.Parser Bool _obfuscation = switch - short 'o'@@ -127,6 +138,7 @@ <> "shadowsocks protocol, at the cost of " <> "about 10-20% performance degradation.") + _verbosity :: O.Parser Priority _verbosity = flag INFO DEBUG - short 'v'@@ -226,6 +238,7 @@ , tag "_method" _method , tag "_timeout" _timeout , tag "_tcpBufferSize" _tcpBufferSize+ , tag "_fastOpen" _fastOpen ] & sequenceA & fmap catMaybes
src/Network/MoeSocks/TCP.hs view
@@ -17,6 +17,7 @@ import Network.Socket hiding (send, recv, recvFrom, sendTo) import Network.Socket.ByteString (recv) import Prelude hiding ((-), take)+import qualified Data.ByteString as S import qualified Data.Strict as S local_Socks5_RequestHandler :: Env@@ -88,7 +89,7 @@ logSA "L remote socket" _initSocket - \(_remoteSocket, _remoteAddress) -> do- connect _remoteSocket _remoteAddress+ {-connect _remoteSocket _remoteAddress-} setSocketSendFast _remoteSocket _localPeerAddr <- getPeerName aSocket@@ -120,14 +121,23 @@ then Just - _c ^. throttleSpeed else Nothing - let sendThread = do- sendBytes _sendChannel _encodeIV- sendBuilderEncrypt _sendChannel _encrypt _header+ _eHeader <- _encrypt - S.Just - builder_To_ByteString _header+ _ePartial <- _encrypt - S.Just _partialBytesAfterClientRequest + let _padding = S.length (_eHeader <> _ePartial) - when (_partialBytesAfterClientRequest & isn't _Empty) -- sendBytesEncrypt _sendChannel _encrypt - _partialBytesAfterClientRequest+ _eInit <- _encrypt . S.Just =<< recv aSocket (4096 + (-_padding)) + let _initBytes = _encodeIV <> _eHeader <> _ePartial <> _eInit++ if _c ^. fastOpen+ then+ sendFast_ _remoteSocket _initBytes _remoteAddress+ else do+ connect _remoteSocket _remoteAddress+ send_ _remoteSocket _initBytes++ let sendThread = do+ let _produce = do produceLoop (info_Id "L --> + Loop") _timeout@@ -151,6 +161,7 @@ ) - pure () + let receiveThread = do _decodeIV <- recv _remoteSocket (_cipherBox ^. ivLength) _decrypt <- _cipherBox ^. decryptBuilder - _decodeIV
src/Network/MoeSocks/Type.hs view
@@ -61,6 +61,7 @@ , _throttle :: Bool , _throttleSpeed :: Double , _obfuscationFlushBound :: Int -- should be greater then MTU+ , _fastOpen :: Bool } deriving (Show, Eq, Generic)