diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,14 @@
+0.1.1.20
+--------
+* Implement TFO in remote. If your browser and the website your are visiting
+  both support TFO, you can enjoy TFO all the way through. This could lead to a
+  huge reduction of latency.
+
 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.
+* Add TCP Fast Open (TFO) capability. It can be turned on by adding a 
+  `"fast_open":true` field in `config.json` or specifying a `--fast-open` flag
+  in the command line arguments.
 
 0.1.1.0
 -------
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
 MoeSocks is greatly inspired by [shadowsocks] and can be used in place of it.
 
 Installation
-------------
+============
 
 * Need `GHC 7.10.2` and `cabal-install`.
       
@@ -28,7 +28,8 @@
 * Add `~/.cabal/bin` to your `$PATH`, if you haven't already.
 
 Usage
------
+=====
+
 * Download a sample [config.json] to your current path
 
 * Edit `config.json` to fit your setup (at least the `remote` and `password`
@@ -58,7 +59,8 @@
 
 
 Features
---------
+========
+
 * Socks5 proxy service, obviously
 * TCP port forwarding
 * UDP port forwarding, for example `-U 5300:8.8.8.8:53`
@@ -67,18 +69,49 @@
 * Socks5 service on local can be turned off
 * Understand shadowsocks' configuration file
 
-Not working
------------
+Drawbacks
+==========
+
 * UDP over Socks5 is not implemented
 * More then 2 times slower then the original Python implementation (measured at
   20M/s vs 43M/s on an Intel P8800, using the AES-256-CFB method)
 
-Planning features
-------------------
-* None
 
+TCP Fast Open (TFO)
+====================
+
+## [TFO] means faster response in this case
+
+Both local and remote will use TFO when instructed. If your browser and the
+website your are visiting both support TFO, you can enjoy TFO all the way
+through. This could lead to a huge reduction of latency.
+
+## Enable TFO in your OS runtime. 
+
+On Linux 3.7+, you could check the availability of TFO using:
+
+    cat /proc/sys/net/ipv4/tcp_fastopen
+
+On Linux 3.7+, to enable TFO (as root):
+
+    echo 3 > /proc/sys/net/ipv4/tcp_fastopen
+
+## Enable TFO in MoeSocks
+
+TFO can be turned on by adding a `"fast_open":true` field in
+`config.json` or specifying a `--fast-open` flag in the command line arguments.
+
+## Verify
+
+Use `tcpdump` on the `remotePort`, you should see that the first packet `SYN`
+will carry the initial data with it. An example command is:
+
+    tcpdump port 8388 -i any -X -v
+
+
 Credits
--------
+=======
+
 * [shadowsocks] greatly inspired MoeSocks.
   Shadowsocks introduced a ground breaking design and implementation to bypass
   Internet censorship in China. 
@@ -87,7 +120,8 @@
   the internal of shadowsocks was gained by reading rnons's implementation.
 
 License
---------
+=======
+
 Copyright 2015 Jinjing Wang
 
 Licensed under the Apache License, Version 2.0 (the "License");
@@ -107,4 +141,4 @@
 [shadowsocks-haskell]:https://github.com/rnons/shadowsocks-haskell
 [config.json]:https://raw.githubusercontent.com/nfjinjing/moesocks/master/config.json
 [#10590]:https://ghc.haskell.org/trac/ghc/ticket/10590
-
+[TFO]:https://en.wikipedia.org/wiki/TCP_Fast_Open
diff --git a/moesocks.cabal b/moesocks.cabal
--- a/moesocks.cabal
+++ b/moesocks.cabal
@@ -1,6 +1,6 @@
 name:               moesocks
 category:           Network
-version:            0.1.1.10
+version:            0.1.1.20
 license:            Apache-2.0
 synopsis:           A functional firewall killer
 description:        A socks5 proxy using the client / server architecture.
diff --git a/src/Network/MoeSocks/Encrypt.hs b/src/Network/MoeSocks/Encrypt.hs
--- a/src/Network/MoeSocks/Encrypt.hs
+++ b/src/Network/MoeSocks/Encrypt.hs
@@ -24,6 +24,7 @@
 import Data.Text.Strict.Lens (utf8)
 import OpenSSL (withOpenSSL)
 import OpenSSL.EVP.Cipher (getCipherByName, CryptoMode(..))
+import OpenSSL.EVP.Internal (cipherIvLength)
 import OpenSSL.Random (randBytes)
 import Prelude hiding ((-))
 import qualified Data.ByteString as S
@@ -53,21 +54,21 @@
 
 type MaybeT_IO = ExceptT () IO
 
-methods :: Map Text (KeyLength, IV_Length)
+methods :: Map Text KeyLength
 methods = fromList
-    [ ("aes-128-cfb", (16, 16))
-    , ("aes-192-cfb", (24, 16))
-    , ("aes-256-cfb", (32, 16))
-    , ("bf-cfb", (16, 8))
-    , ("camellia-128-cfb", (16, 16))
-    , ("camellia-192-cfb", (24, 16))
-    , ("camellia-256-cfb", (32, 16))
-    , ("cast5-cfb", (16, 8))
-    , ("des-cfb", (8, 8))
-    , ("idea-cfb", (16, 8))
-    , ("rc2-cfb", (16, 8))
-    , ("rc4", (16, 0))
-    , ("seed-cfb", (16, 16))
+    [ ("aes-128-cfb"      , 16)
+    , ("aes-192-cfb"      , 24)
+    , ("aes-256-cfb"      , 32)
+    , ("bf-cfb"           , 16)
+    , ("camellia-128-cfb" , 16)
+    , ("camellia-192-cfb" , 24)
+    , ("camellia-256-cfb" , 32)
+    , ("cast5-cfb"        , 16)
+    , ("des-cfb"          , 8 )
+    , ("idea-cfb"         , 16)
+    , ("rc2-cfb"          , 16)
+    , ("rc4"              , 16)
+    , ("seed-cfb"         , 16)
     ]
 
 
@@ -114,8 +115,9 @@
 initCipherBox' :: Text -> Text -> MaybeT_IO CipherBox
 initCipherBox' aMethod aPassword = do
   _method <- mio - getCipherByName - aMethod ^. _Text
+  let _IV_Length = cipherIvLength _method
 
-  (_keyLength, _IV_Length) <- getMaybe - methods ^? ix aMethod
+  _keyLength  <- getMaybe - methods ^? ix aMethod
 
   let _hashed = hashKey (review utf8 aPassword) _keyLength _IV_Length
       _IV_Maker = randBytes _IV_Length
diff --git a/src/Network/MoeSocks/Internal/Socket.hs b/src/Network/MoeSocks/Internal/Socket.hs
--- a/src/Network/MoeSocks/Internal/Socket.hs
+++ b/src/Network/MoeSocks/Internal/Socket.hs
@@ -19,12 +19,12 @@
 -- 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
+sendBufToWithFlagNoRetry :: Socket    -- (possibly) bound/connected Socket
           -> Ptr a -> Int  -- Data to send
           -> SockAddr
           -> Int
           -> IO Int            -- Number of Bytes sent
-sendBufToWithFlag 
+sendBufToWithFlagNoRetry 
   (MkSocket s _family _stype _protocol _status) ptr nbytes addr flags = do
    withSockAddr addr $ \p_addr sz -> do
     liftM fromIntegral $
@@ -38,7 +38,7 @@
        -> IO Int      -- ^ Number of bytes sent
 sendToWithFlag sock xs addr flags =
     unsafeUseAsCStringLen xs $ \(str, len) -> 
-      sendBufToWithFlag sock str len addr flags
+      sendBufToWithFlagNoRetry sock str len addr flags
 
 sendAllFastOpenTo :: Socket      -- ^ Socket
           -> ByteString  -- ^ Data to send
diff --git a/src/Network/MoeSocks/TCP.hs b/src/Network/MoeSocks/TCP.hs
--- a/src/Network/MoeSocks/TCP.hs
+++ b/src/Network/MoeSocks/TCP.hs
@@ -89,10 +89,8 @@
     
     logSA "L remote socket" _initSocket - 
       \(_remoteSocket, _remoteAddress) -> do
-      {-connect _remoteSocket _remoteAddress-}
       setSocketSendFast _remoteSocket
 
-      _localPeerAddr <- getPeerName aSocket
       _remoteSocketName <- getSocketName _remoteSocket
       
       when shouldReplyClient - do
@@ -100,6 +98,7 @@
         send_ aSocket - builder_To_ByteString _connectionReplyBuilder
       
 
+      _localPeerAddr <- getPeerName aSocket
       let _msg = showRelay _localPeerAddr _clientRequest
       
       info_ - "LT: " <> _msg
@@ -137,7 +136,6 @@
                 send_ _remoteSocket _initBytes
 
             let sendThread = do
-
                   let _produce = do
                                     produceLoop (info_Id "L --> + Loop")
                                       _timeout
@@ -217,24 +215,37 @@
                                           aSocket
   
   logSA "R target socket" (initTarget _clientRequest) - \_r -> do
-    let (_targetSocket, _targetSocketAddress) = _r 
-        (_addr, _) = sockAddr_To_Pair _targetSocketAddress
+    let (_targetSocket, _targetAddress) = _r 
+        (_addr, _) = sockAddr_To_Pair _targetAddress
         _forbidden_IP = _options ^. forbidden_IP
 
     debug_ - "checking: " <> show _addr <> " ? " <> show _forbidden_IP
     withCheckedForbidden_IP_List _addr _forbidden_IP - do
-      connect _targetSocket _targetSocketAddress
       setSocketSendFast _targetSocket
 
-      _remotePeerAddr <- getPeerName aSocket
-      _targetPeerAddr <- getPeerName _targetSocket
+      let _initBytes = _leftOverBytes
+      let _connectNormal = do
+            connect _targetSocket _targetAddress
+            send_ _targetSocket _initBytes
 
+      if _c ^. fastOpen
+        then
+          sendFast_ _targetSocket _initBytes _targetAddress
+           {-`onException` -}
+            {-( do-}
+              {-error_ - "TCP Fast Open not availabe for: " <> show _targetSocket-}
+              {-_connectNormal-}
+            {-)-}
+        else do
+          _connectNormal
+      
+      _remotePeerAddr <- getPeerName aSocket
       let _msg = showRelay _remotePeerAddr _clientRequest
 
       info_ - "RT: " <> _msg
-
+      
       let 
-          handleTarget _leftOverBytes __targetSocket = do
+          handleTarget __targetSocket = do
             _sendChannel <- newTBQueueIO - _c ^. tcpBufferSize
             _receiveChannel <- newTBQueueIO - _c ^. tcpBufferSize
 
@@ -249,10 +260,6 @@
                     else Nothing
 
             let sendThread = do
-                  when (_leftOverBytes & isn't _Empty) -
-                    atomically - writeTBQueue _sendChannel - 
-                                  S.Just _leftOverBytes
-
                   let _produce = do
                                     produceLoop (info_Id "R --> + Loop")
                                       _timeout
@@ -310,4 +317,4 @@
               (Just - info_Id "R -->", sendThread)
               (Just - info_Id "R <--", receiveThread)
             
-      handleTarget _leftOverBytes _targetSocket
+      handleTarget _targetSocket
