diff --git a/Network/Socket/Msg.hs b/Network/Socket/Msg.hs
--- a/Network/Socket/Msg.hs
+++ b/Network/Socket/Msg.hs
@@ -15,6 +15,7 @@
 import Control.Applicative
 import Control.Monad (void)
 import qualified Data.ByteString as B
+import qualified Data.ByteString.Unsafe as BU
 import Data.Maybe (isNothing, fromJust)
 import Network.Socket
 import Network.Socket.Internal (peekSockAddr,pokeSockAddr,sizeOfSockAddr,throwSocketErrorWaitRead,throwSocketErrorWaitWrite)
@@ -43,29 +44,28 @@
 -- |Sends the data contained in the bytestring to the specified address.
 -- The last argument is a list of control parameters (see cmsg(3) for details).
 sendMsg :: Socket -> B.ByteString -> SockAddr -> [CMsg] -> IO ()
-sendMsg sock@(MkSocket sockfd _ _ _ _) bytes sa cmsgs = allocaBytes bufSz $ \bufPtr -> do
+sendMsg sock@(MkSocket sockfd _ _ _ _) bytes sa cmsgs = void $ allocaBytes bufSz $ \bufPtr -> do
+        zeroBytes bufPtr bufSz
         let saPtr = castPtr bufPtr
         let iovPtr = plusPtr saPtr $ sizeOfSockAddr sa
         let msgPtr = plusPtr iovPtr $ sizeOf (undefined :: IOVec)
         let auxPtr = plusPtr msgPtr $ sizeOf (undefined :: MsgHdr)
 
-        let msghdr = MsgHdr { msgName = saPtr
-                            , msgNameLen = fromIntegral $ sizeOfSockAddr sa
-                            , msgIov = iovPtr
-                            , msgIovLen = 1
-                            , msgControl = auxPtr
-                            , msgControlLen = fromIntegral auxSz
-                            , msgFlags = 0 }
-        poke msgPtr msghdr
+        poke msgPtr MsgHdr { msgName = saPtr
+                           , msgNameLen = fromIntegral $ sizeOfSockAddr sa
+                           , msgIov = iovPtr
+                           , msgIovLen = 1
+                           , msgControl = auxPtr
+                           , msgControlLen = fromIntegral auxSz
+                           , msgFlags = 0 }
         pokeCMsgs msgPtr cmsgs
         pokeSockAddr saPtr sa
 
-        void $
 # if !defined(__HUGS__) 
-            throwSocketErrorWaitWrite sock "sendMsg" $
+        throwSocketErrorWaitWrite sock "sendMsg" $
 # endif
-                B.useAsCStringLen bytes $ \(p,len) ->
-                    poke iovPtr (IOVec p $ fromIntegral len) >> c_sendmsg sockfd msgPtr 0
+            BU.unsafeUseAsCStringLen bytes $ \(p,len) ->
+                poke iovPtr (IOVec p $ fromIntegral len) >> c_sendmsg sockfd msgPtr 0
     where
         auxSz = sum $ map cmsgSpace cmsgs
         bufSz = sum [auxSz, sizeOfSockAddr sa, sizeOf (undefined :: MsgHdr), sizeOf (undefined :: IOVec)]
diff --git a/Network/Socket/Msg/CMsg.hsc b/Network/Socket/Msg/CMsg.hsc
--- a/Network/Socket/Msg/CMsg.hsc
+++ b/Network/Socket/Msg/CMsg.hsc
@@ -20,9 +20,9 @@
 import Network.Socket (HostAddress)
 
 data CMsg = CMsg
-    { cmsgLevel :: Int
-    , cmsgType  :: Int
-    , cmsgData  :: B.ByteString
+    { cmsgLevel :: !Int
+    , cmsgType  :: !Int
+    , cmsgData  :: !B.ByteString
     }
 
 instance Show CMsg where
@@ -61,9 +61,9 @@
 
 #ifdef IP_PKTINFO
 data IpPktInfo = IpPktInfo
-    { ipi_ifindex   :: Word32
-    , ipi_spec_dst  :: HostAddress
-    , ipi_addr      :: HostAddress
+    { ipi_ifindex   :: !Word32
+    , ipi_spec_dst  :: !HostAddress
+    , ipi_addr      :: !HostAddress
     } deriving (Show)
 
 instance Binary IpPktInfo where
diff --git a/Network/Socket/Msg/CMsgHdr.hsc b/Network/Socket/Msg/CMsgHdr.hsc
--- a/Network/Socket/Msg/CMsgHdr.hsc
+++ b/Network/Socket/Msg/CMsgHdr.hsc
@@ -21,8 +21,10 @@
 
 import Control.Applicative
 import qualified Data.ByteString as B
+import qualified Data.ByteString.Unsafe as BU
 import Data.Maybe (isNothing,fromJust)
 import Foreign.C.Types (CUInt(..),CInt(..),CSize(..))
+import Foreign.Marshal.Unsafe (unsafeLocalState)
 import Foreign.Marshal.Utils (copyBytes)
 import Foreign.Ptr (Ptr,castPtr,nullPtr)
 import Foreign.Storable (Storable(..))
@@ -30,10 +32,10 @@
 type CSockLen = CUInt   -- The way it is defined somewhere in bits/types.h
 
 data CMsgHdr = CMsgHdr
-    { cmsghdrLen       :: CSockLen
-    , cmsghdrLevel  :: CInt
-    , cmsghdrType   :: CInt
-    }
+    { cmsghdrLen       :: !CSockLen
+    , cmsghdrLevel  :: !CInt
+    , cmsghdrType   :: !CInt
+    } deriving (Show)
 
 instance Storable CMsgHdr where
     sizeOf _ = (#const sizeof(struct cmsghdr))
@@ -54,14 +56,23 @@
 -- are constant and thus we do not have to use IO monad.
 
 foreign import ccall unsafe "cmsg_firsthdr"
-  c_cmsg_firsthdr :: Ptr MsgHdr -> Ptr CMsgHdr
+  _c_cmsg_firsthdr :: Ptr MsgHdr -> IO (Ptr CMsgHdr)
 
 foreign import ccall unsafe "cmsg_nexthdr"
-  c_cmsg_nexthdr :: Ptr MsgHdr -> Ptr CMsgHdr -> Ptr CMsgHdr
+  _c_cmsg_nexthdr :: Ptr MsgHdr -> Ptr CMsgHdr -> IO (Ptr CMsgHdr)
 
 foreign import ccall unsafe "cmsg_data"
-  c_cmsg_data :: Ptr CMsgHdr -> Ptr ()
+  _c_cmsg_data :: Ptr CMsgHdr -> IO (Ptr ())
 
+c_cmsg_firsthdr :: Ptr MsgHdr -> Ptr CMsgHdr
+c_cmsg_firsthdr = unsafeLocalState . _c_cmsg_firsthdr
+
+c_cmsg_nexthdr :: Ptr MsgHdr -> Ptr CMsgHdr -> Ptr CMsgHdr
+c_cmsg_nexthdr pm = unsafeLocalState . _c_cmsg_nexthdr pm
+
+c_cmsg_data :: Ptr CMsgHdr -> Ptr ()
+c_cmsg_data = unsafeLocalState . _c_cmsg_data
+
 foreign import ccall unsafe "cmsg_space"
   c_cmsg_space :: CSize -> CSize
 
@@ -98,7 +109,7 @@
 pokeCMsg pHdr cmsg = do
         poke pHdr cmsghdr
         let dptr = castPtr $ c_cmsg_data pHdr
-        B.useAsCStringLen (cmsgData cmsg) $ \(bptr,len) -> copyBytes dptr bptr len
+        BU.unsafeUseAsCStringLen (cmsgData cmsg) $ \(bptr,len) -> copyBytes dptr bptr len
     where
         cmsghdr = CMsgHdr { cmsghdrLen = fromIntegral $ cmsgLen cmsg
                           , cmsghdrLevel = fromIntegral $ cmsgLevel cmsg
diff --git a/Network/Socket/Msg/IOVec.hsc b/Network/Socket/Msg/IOVec.hsc
--- a/Network/Socket/Msg/IOVec.hsc
+++ b/Network/Socket/Msg/IOVec.hsc
@@ -11,9 +11,9 @@
 #include <sys/uio.h>
 
 data IOVec = IOVec
-    { iovBase :: Ptr CChar
-    , iovLen :: CSize
-    }
+    { iovBase :: !(Ptr CChar)
+    , iovLen :: !CSize
+    } deriving (Show)
 
 instance Storable IOVec where
   sizeOf _ = (#const sizeof(struct iovec))
@@ -22,7 +22,7 @@
   peek p = do
     base <- (#peek struct iovec, iov_base) p
     len <- (#peek struct iovec, iov_len) p
-    return $ IOVec base len
+    return $! IOVec base len
 
   poke p iov = do
     (#poke struct iovec, iov_base) p (iovBase iov)
diff --git a/Network/Socket/Msg/Internal.hs b/Network/Socket/Msg/Internal.hs
--- a/Network/Socket/Msg/Internal.hs
+++ b/Network/Socket/Msg/Internal.hs
@@ -3,11 +3,13 @@
 module Network.Socket.Msg.Internal
     ( c_sendmsg
     , c_recvmsg
+    , zeroBytes
     ) where
 
 import Network.Socket.Msg.MsgHdr (MsgHdr)
 
-import Foreign.C.Types (CInt(..))
+import Control.Monad (void)
+import Foreign.C.Types (CInt(..),CSize(..))
 import Foreign.Ptr (Ptr)
 import System.Posix.Types (CSsize(..))
 
@@ -16,3 +18,9 @@
 
 foreign import ccall unsafe "recvmsg"
   c_recvmsg :: CInt -> Ptr MsgHdr -> CInt -> IO CSsize
+
+foreign import ccall unsafe "memset"
+  c_memset :: Ptr a -> CInt -> CSize -> IO CSize
+
+zeroBytes :: Ptr a -> Int -> IO ()
+zeroBytes p s = void $ c_memset p 0 $ fromIntegral s
diff --git a/Network/Socket/Msg/MsgHdr.hsc b/Network/Socket/Msg/MsgHdr.hsc
--- a/Network/Socket/Msg/MsgHdr.hsc
+++ b/Network/Socket/Msg/MsgHdr.hsc
@@ -19,14 +19,14 @@
 import Network.Socket.Msg.IOVec (IOVec)
 
 data MsgHdr = MsgHdr
-    { msgName       :: Ptr SockAddr
-    , msgNameLen    :: CSize
-    , msgIov        :: Ptr IOVec
-    , msgIovLen     :: CSize
-    , msgControl    :: Ptr ()
-    , msgControlLen :: CSize
-    , msgFlags      :: CInt
-    }
+    { msgName       :: !(Ptr SockAddr)
+    , msgNameLen    :: !CSize
+    , msgIov        :: !(Ptr IOVec)
+    , msgIovLen     :: !CSize
+    , msgControl    :: !(Ptr ())
+    , msgControlLen :: !CSize
+    , msgFlags      :: !CInt
+    } deriving (Show)
 
 instance Storable MsgHdr where
   sizeOf _ = (#const sizeof(struct msghdr))
@@ -40,7 +40,7 @@
     control <- (#peek struct msghdr, msg_control) p
     controlLen <- (#peek struct msghdr, msg_controllen) p
     flags <- (#peek struct msghdr, msg_flags) p
-    return $ MsgHdr name nameLen iov iovLen control controlLen flags
+    return $! MsgHdr name nameLen iov iovLen control controlLen flags
 
   poke p mh = do
     (#poke struct msghdr, msg_name) p (msgName mh)
diff --git a/network-msg.cabal b/network-msg.cabal
--- a/network-msg.cabal
+++ b/network-msg.cabal
@@ -1,5 +1,5 @@
 name: network-msg
-version: 0.3
+version: 0.4
 category: Network
 build-type: Simple 
 cabal-version: >= 1.6
@@ -29,7 +29,7 @@
     unix
 
   extensions: CPP, ForeignFunctionInterface
-  ghc-options: -Wall -fwarn-tabs
+  ghc-options: -Wall -fwarn-tabs -O2
 
 source-repository head
   type: git
