diff --git a/src/ZooKeeper.hs b/src/ZooKeeper.hs
--- a/src/ZooKeeper.hs
+++ b/src/ZooKeeper.hs
@@ -7,7 +7,11 @@
   , Res.Resource
 
   , zooGetClientID
+  , zooState
+  , zooRecvTimeout
 
+  , isUnrecoverable
+
   , zooCreate
   , zooSet
   , zooGet
@@ -36,7 +40,6 @@
 import           Control.Monad            (void, when, zipWithM, (<=<))
 import           Data.Bifunctor           (first)
 import           Data.Maybe               (fromMaybe)
-import           Data.Proxy               (Proxy (..))
 import           Foreign.C                (CInt)
 import           Foreign.ForeignPtr       (mallocForeignPtrBytes,
                                            touchForeignPtr, withForeignPtr)
@@ -79,6 +82,16 @@
 zookeeperResInit host timeout mclientid flags =
   Res.initResource (zookeeperInit host timeout mclientid flags) zookeeperClose
 
+-- | Checks if the current zookeeper connection state can't be recovered.
+--
+-- If True, the application must close the zhandle and then try to reconnect.
+isUnrecoverable
+  :: T.ZHandle
+  -- ^ The zookeeper handle obtained by a call to 'zookeeperResInit'
+  -> IO Bool
+  -- ^ Return True if connection is unrecoverable
+isUnrecoverable zh = (< 0) <$> I.c_is_unrecoverable zh
+
 -- | Create a node.
 --
 -- This method will create a node in ZooKeeper. A node can only be created if
@@ -124,7 +137,7 @@
         let cfun = I.c_hs_zoo_acreate' zh path' nullPtr 0 (-1) acl mode
         E.throwZooErrorIfLeft =<< I.withZKAsync csize I.peekRet I.peekData cfun
   where
-    csize = I.csize (Proxy :: Proxy T.StringCompletion)
+    csize = I.csize @T.StringCompletion
 
 -- | Sets the data associated with a node.
 --
@@ -154,7 +167,7 @@
        -- * ZNOAUTH the client does not have permission.
        -- * ZBADVERSION expected version does not match actual version.
 zooSet zh path m_value m_version = CBytes.withCBytesUnsafe path $ \path' -> do
-  let csize = I.csize (Proxy :: Proxy T.StatCompletion)
+  let csize = I.csize @T.StatCompletion
       version = fromMaybe (-1) m_version
   case m_value of
     Just value -> Z.withPrimVectorUnsafe value $ \val' offset len -> do
@@ -184,7 +197,7 @@
        -- * ZNONODE the node does not exist.
        -- * ZNOAUTH the client does not have permission.
 zooGet zh path = CBytes.withCBytesUnsafe path $ \path' ->
-  let csize = I.csize (Proxy :: Proxy T.DataCompletion)
+  let csize = I.csize @T.DataCompletion
       cfunc = I.c_hs_zoo_aget zh path' 0
     in E.throwZooErrorIfLeft =<< I.withZKAsync csize I.peekRet I.peekData cfunc
 
@@ -212,7 +225,7 @@
   -- * ZNOAUTH the client does not have permission.
   -> IO ()
 zooWatchGet zh path watchfn datafn = CBytes.withCBytesUnsafe path $ \path' ->
-  let csize = I.csize (Proxy :: Proxy T.DataCompletion)
+  let csize = I.csize @T.DataCompletion
       watchfn' = watchfn <=< E.throwZooErrorIfLeft
       datafn' = datafn <=< E.throwZooErrorIfLeft
    in I.withZKAsync2
@@ -246,7 +259,7 @@
           -- If Nothing is used the version check will not take place.
           -> IO ()
 zooDelete zh path m_version = CBytes.withCBytesUnsafe path $ \path' ->
-  let csize = I.csize (Proxy :: Proxy T.VoidCompletion)
+  let csize = I.csize @T.VoidCompletion
       cfunc = I.c_hs_zoo_adelete zh path' version
       version = fromMaybe (-1) m_version
    in void $ E.throwZooErrorIfLeft =<< I.withZKAsync csize I.peekRet I.peekData cfunc
@@ -273,7 +286,7 @@
           -- * ZNOAUTH the client does not have permission.
 zooExists zh path =
   CBytes.withCBytesUnsafe path $ \path' ->
-    let csize = I.csize (Proxy :: Proxy T.StatCompletion)
+    let csize = I.csize @T.StatCompletion
         cfunc = I.c_hs_zoo_aexists zh path' 0
      in E.throwZooErrorIfLeft' (== E.CZNONODE) =<< I.withZKAsync csize I.peekRet I.peekData cfunc
 
@@ -315,7 +328,7 @@
   -- * ZNOAUTH the client does not have permission.
   -> IO ()
 zooWatchExists zh path watchfn statfn =
-  let csize = I.csize (Proxy :: Proxy T.StatCompletion)
+  let csize = I.csize @T.StatCompletion
       watchfn' = watchfn <=< E.throwZooErrorIfLeft
       statfn' = statfn <=< E.throwZooErrorIfLeft' (== E.CZNONODE)
    in CBytes.withCBytesUnsafe path $ \path' ->
@@ -346,7 +359,7 @@
   -- * ZNONODE the node does not exist.
   -- * ZNOAUTH the client does not have permission.
 zooGetChildren zh path = CBytes.withCBytesUnsafe path $ \path' -> do
-  let csize = I.csize (Proxy :: Proxy T.StringsCompletion)
+  let csize = I.csize @T.StringsCompletion
       cfunc = I.c_hs_zoo_aget_children zh path' 0
     in E.throwZooErrorIfLeft =<< I.withZKAsync csize I.peekRet I.peekData cfunc
 
@@ -382,7 +395,7 @@
   -- * ZNOAUTH the client does not have permission.
   -> IO ()
 zooWatchGetChildren zh path watchfn stringsfn =
-  let csize = I.csize (Proxy :: Proxy T.StringsCompletion)
+  let csize = I.csize @T.StringsCompletion
       watchfn' = watchfn <=< E.throwZooErrorIfLeft
       stringsfn' = stringsfn <=< E.throwZooErrorIfLeft
    in CBytes.withCBytesUnsafe path $ \path' ->
@@ -415,7 +428,7 @@
   -- * ZNONODE the node does not exist.
   -- * ZNOAUTH the client does not have permission.
 zooGetChildren2 zh path = CBytes.withCBytesUnsafe path $ \path' -> do
-  let csize = I.csize (Proxy :: Proxy T.StringsStatCompletion)
+  let csize = I.csize @T.StringsStatCompletion
       cfunc = I.c_hs_zoo_aget_children2 zh path' 0
     in E.throwZooErrorIfLeft =<< I.withZKAsync csize I.peekRet I.peekData cfunc
 
@@ -450,7 +463,7 @@
   -- * ZNOAUTH the client does not have permission.
   -> IO ()
 zooWatchGetChildren2 zh path watchfn strsStatfn =
-  let csize = I.csize (Proxy :: Proxy T.StringsStatCompletion)
+  let csize = I.csize @T.StringsStatCompletion
       watchfn' = watchfn <=< E.throwZooErrorIfLeft
       stringsfn' = strsStatfn <=< E.throwZooErrorIfLeft
    in CBytes.withCBytesUnsafe path $ \path' ->
@@ -464,6 +477,17 @@
 zooGetClientID :: T.ZHandle -> IO T.ClientID
 zooGetClientID = I.c_zoo_client_id
 
+-- | Get the state of the zookeeper connection
+--
+-- The return valud will be one of the State Consts
+zooState :: T.ZHandle  -> IO T.ZooState
+zooState = I.c_zoo_state
+
+-- | Return the timeout for this session, only valid if the connections
+-- is currently connected (ie. last watcher state is ZOO_CONNECTED_STATE). This
+-- value may change after a server re-connect.
+zooRecvTimeout :: T.ZHandle  -> IO CInt
+zooRecvTimeout = I.c_zoo_recv_timeout
 -------------------------------------------------------------------------------
 
 -- | Atomically commits multiple zookeeper operations.
@@ -479,7 +503,7 @@
   -> IO [T.ZooOpResult]
 zooMulti zh ops = do
   let len = length ops
-      completionSize = I.csize (Proxy :: Proxy T.VoidCompletion)
+      completionSize = I.csize @T.VoidCompletion
       chunkPtr ptr size = map (\i -> ptr `plusPtr` (i * size)) [0..len-1]
 
   mbai@(Z.MutableByteArray mbai#) <- Z.newPinnedByteArray (I.zooOpSize * len)
diff --git a/src/ZooKeeper/Internal/FFI.hsc b/src/ZooKeeper/Internal/FFI.hsc
--- a/src/ZooKeeper/Internal/FFI.hsc
+++ b/src/ZooKeeper/Internal/FFI.hsc
@@ -5,15 +5,17 @@
 
 import           Control.Concurrent
 import           Control.Exception
-import           Control.Monad            (void)
-import           Data.Version             (Version, makeVersion)
+import           Control.Monad                (void)
+import           Data.Version                 (Version, makeVersion,
+                                               parseVersion)
 import           Data.Word
 import           Foreign.C
 import           Foreign.ForeignPtr
 import           Foreign.Ptr
 import           Foreign.StablePtr
 import           GHC.Conc
-import           GHC.Stack                (HasCallStack)
+import           GHC.Stack                    (HasCallStack)
+import           Text.ParserCombinators.ReadP (readP_to_S)
 import           Z.Foreign
 
 import           ZooKeeper.Exception
@@ -30,7 +32,9 @@
                          , (#const ZOO_PATCH_VERSION)
                          ]
 #else
-zooVersion = [0, 0, 0]  -- unsupported
+zooVersion = case readP_to_S parseVersion (#const_str ZOO_VERSION) of
+               [_, _, (r, _)] -> r
+               otherwise      -> makeVersion [0, 0, 0]  -- unsupported
 #endif
 
 foreign import ccall unsafe "hs_zk.h &logLevel"
@@ -55,6 +59,12 @@
 foreign import ccall unsafe "hs_zk.h zoo_client_id"
   c_zoo_client_id :: ZHandle -> IO ClientID
 
+foreign import ccall unsafe "hs_zk.h zoo_state"
+  c_zoo_state :: ZHandle -> IO ZooState
+
+foreign import ccall unsafe "hs_zk.h zoo_recv_timeout"
+  c_zoo_recv_timeout :: ZHandle -> IO CInt
+
 foreign import ccall unsafe "hs_zk.h hs_zoo_acreate"
   c_hs_zoo_acreate
     :: ZHandle
@@ -201,6 +211,9 @@
 
 foreign import ccall unsafe "hs_zk.h zoo_check_op_init"
   c_zoo_check_op_init :: Ptr CZooOp -> BA## Word8 -> CInt -> IO ()
+
+foreign import ccall unsafe "hs_zk.h is_unrecoverable"
+  c_is_unrecoverable :: ZHandle -> IO CInt
 
 -------------------------------------------------------------------------------
 -- Helpers
diff --git a/src/ZooKeeper/Internal/Types.hsc b/src/ZooKeeper/Internal/Types.hsc
--- a/src/ZooKeeper/Internal/Types.hsc
+++ b/src/ZooKeeper/Internal/Types.hsc
@@ -1,11 +1,11 @@
-{-# LANGUAGE CPP #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE CPP                 #-}
 
 module ZooKeeper.Internal.Types where
 
 import           Control.Exception (bracket_)
 import           Control.Monad     (forM)
 import           Data.Int
-import           Data.Proxy        (Proxy (..))
 import           Foreign
 import           Foreign.C
 import           Numeric           (showHex)
@@ -314,7 +314,7 @@
 
 class Completion a where
   {-# MINIMAL csize, peekRet, peekData #-}
-  csize :: Proxy a -> Int
+  csize :: Int
   peekRet :: Ptr a -> IO CInt
   peekData :: Ptr a -> IO a
 
@@ -322,7 +322,7 @@
   deriving Show
 
 instance Completion StringCompletion where
-  csize _ = (#size hs_string_completion_t)
+  csize = (#size hs_string_completion_t)
   peekRet ptr = (#peek hs_string_completion_t, rc) ptr
   peekData ptr = do
     value_ptr <- (#peek hs_string_completion_t, value) ptr
@@ -335,7 +335,7 @@
   } deriving (Show, Eq)
 
 instance Completion DataCompletion where
-  csize _ = (#size hs_data_completion_t)
+  csize = (#size hs_data_completion_t)
   peekRet ptr = (#peek hs_data_completion_t, rc) ptr
   peekData ptr = do
     val_ptr <- (#peek hs_data_completion_t, value) ptr
@@ -351,7 +351,7 @@
   deriving (Show, Eq)
 
 instance Completion StatCompletion where
-  csize _ = (#size hs_stat_completion_t)
+  csize = (#size hs_stat_completion_t)
   peekRet ptr = (#peek hs_stat_completion_t, rc) ptr
   peekData ptr = do
     stat_ptr <- (#peek hs_stat_completion_t, stat) ptr
@@ -361,7 +361,7 @@
 newtype VoidCompletion = VoidCompletion ()
 
 instance Completion VoidCompletion where
-  csize _ = (#size hs_void_completion_t)
+  csize = (#size hs_void_completion_t)
   peekRet ptr = (#peek hs_stat_completion_t, rc) ptr
   peekData _ = return $ VoidCompletion ()
 
@@ -370,7 +370,7 @@
   deriving Show
 
 instance Completion StringsCompletion where
-  csize _ = (#size hs_strings_completion_t)
+  csize = (#size hs_strings_completion_t)
   peekRet ptr = (#peek hs_strings_completion_t, rc) ptr
   peekData ptr = do
     strs_ptr <- (#peek hs_strings_completion_t, strings) ptr
@@ -383,7 +383,7 @@
   } deriving Show
 
 instance Completion StringsStatCompletion where
-  csize _ = (#size hs_strings_stat_completion_t)
+  csize = (#size hs_strings_stat_completion_t)
   peekRet ptr = (#peek hs_strings_stat_completion_t, rc) ptr
   peekData ptr = do
     strs_ptr <- (#peek hs_strings_stat_completion_t, strings) ptr
diff --git a/src/ZooKeeper/Types.hs b/src/ZooKeeper/Types.hs
--- a/src/ZooKeeper/Types.hs
+++ b/src/ZooKeeper/Types.hs
@@ -19,6 +19,8 @@
   , I.StringsCompletion (..)
   , I.StringsStatCompletion (..)
 
+  , I.Stat (..)
+
   , I.ZooEvent
   , pattern I.ZooCreateEvent
   , pattern I.ZooDeleteEvent
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -21,9 +21,9 @@
 smoke :: ZHandle -> Spec
 smoke zh = do
   describe "ZooKeeper.zooVersion" $ do
-    it "version should be 3.4.*" $ do
+    it "version should be 3.4.* - 3.6.*" $ do
       zooVersion `shouldSatisfy` (>= makeVersion [3, 4, 0])
-      zooVersion `shouldSatisfy` (< makeVersion [3, 5, 0])
+      zooVersion `shouldSatisfy` (< makeVersion [3, 8, 0])
 
   describe "zookeeper get set" $ do
     it "set some value to a node and get it" $ do
@@ -69,6 +69,14 @@
       void $ zooCreate zh "/y" Nothing zooOpenAclUnsafe ZooPersistent
       unStrVec . strsCompletionValues <$> zooGetChildren zh "/y" `shouldReturn` []
       zooDelete zh "/y" Nothing `shouldReturn` ()
+
+  describe "ZooKeeper.zooState" $ do
+    it "test get state" $ do
+      zooState zh `shouldReturn` ZooConnectedState
+
+  describe "ZooKeeper.zooRecvTimeout" $ do
+    it "test receive timeout" $ do
+      zooRecvTimeout zh `shouldReturn` 5000
 
 multiSpec :: ZHandle -> Spec
 multiSpec zh = describe "ZooKeeper.zooMulti" $ do
diff --git a/zoovisitor.cabal b/zoovisitor.cabal
--- a/zoovisitor.cabal
+++ b/zoovisitor.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.2
 name:               zoovisitor
-version:            0.1.0.0
+version:            0.1.1.0
 synopsis:
   A haskell binding to Apache Zookeeper C library(mt) using Haskell Z project.
 
@@ -12,7 +12,7 @@
 copyright:          Copyright (c)
 author:             mu
 maintainer:         mu@laxcat.xyz
-tested-with:        GHC ==8.8.4 || ==8.10.3 || ==9.0.1
+tested-with:        GHC ==8.8.4 || ==8.10.4 || ==9.0.1
 category:           Database
 homepage:           https://github.com/ZHaskell/zoovisitor
 bug-reports:        https://github.com/ZHaskell/zoovisitor/issues
