packages feed

network 2.6.3.6 → 2.7.0.0

raw patch · 11 files changed

+432/−201 lines, 11 filesdep +directory

Dependencies added: directory

Files

CHANGELOG.md view
@@ -1,6 +1,20 @@-## Version 2.6.3.6- * Removed unnecessary withMVar, which caused locking on close.-   [#330](https://github.com/haskell/network/pull/330)+## Version 2.7.0.0+ * Obsoleting the Network module.+ * Obsoleting the Network.BSD module.+ * Obsoleting APIs: MkSocket, htonl, ntohl,+              getPeerCred, getPeerEid,+              send, sendTo, recv, recvFrom, recvLen,+              inet_addr, inet_ntoa,+              isConnected, isBound, isListening, isReadable, isWritable,+              aNY_PORT, iNADDR_ANY, iN6ADDR_ANY, sOMAXCONN,+	      sOL_SOCKET, sCM_RIGHTS,+              packFamily, unpackFamily, packSocketType+ * Do not closeFd within sendFd+   [#271](https://github.com/haskell/network/pull/271)+ * Exporting ifNameToIndex and ifIndexToName from Network.Socket.+ * New APIs: setCloseOnExecIfNeeded, getCloseOnExec and getNonBlock+ * New APIs: isUnixDomainSocketAvailable and getPeerCredential+ * socketPair, sendFd and recvFd are exported even on Windows.  ## Version 2.6.3.5  * Reverting "Do not closeFd within sendFd"
Network.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} {-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}+{-# OPTIONS_HADDOCK hide #-} ----------------------------------------------------------------------------- -- | -- Module      :  Network@@ -25,7 +26,7 @@ #define IPV6_SOCKET_SUPPORT 1 #endif -module Network+module Network {-# DEPRECATED "The high level Network interface is no longer supported. Please use Network.Socket." #-}     (     -- * Basic data types       Socket
Network/BSD.hsc view
@@ -1,4 +1,6 @@ {-# LANGUAGE CPP, ForeignFunctionInterface #-}+{-# OPTIONS_HADDOCK hide #-}+{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-} ----------------------------------------------------------------------------- -- | -- Module      :  Network.BSD@@ -16,7 +18,7 @@  #include "HsNet.h" -module Network.BSD+module Network.BSD  {-# DEPRECATED "This platform dependent module is no longer supported." #-}     (     -- * Host names       HostName@@ -102,7 +104,7 @@ #if defined(HAVE_WINSOCK2_H) import Foreign.C.Types ( CShort ) #endif-import Foreign.C.Types ( CInt(..), CUInt(..), CULong(..), CSize(..) )+import Foreign.C.Types ( CInt(..), CULong(..), CSize(..) ) import Foreign.Ptr (Ptr, nullPtr) import Foreign.Storable (Storable(..)) import Foreign.Marshal.Array (allocaArray0, peekArray0)@@ -512,24 +514,6 @@   setNetworkEntry stayOpen   getEntries (getNetworkEntry) (endNetworkEntry) #endif---- ------------------------------------------------------------------------------ Interface names--#if defined(HAVE_IF_NAMETOINDEX)---- returns the index of the network interface corresponding to the name ifname.-ifNameToIndex :: String -> IO (Maybe Int)-ifNameToIndex ifname = do-  index <- withCString ifname c_if_nametoindex-  -- On failure zero is returned. We'll return Nothing.-  return $ if index == 0 then Nothing else Just $ fromIntegral index--foreign import CALLCONV safe "if_nametoindex"-   c_if_nametoindex :: CString -> IO CUInt--#endif-  -- Mutex for name service lockdown 
Network/Socket.hsc view
@@ -1,5 +1,6 @@ {-# LANGUAGE CPP, ScopedTypeVariables, RecordWildCards #-} {-# OPTIONS_GHC -fno-warn-orphans #-}+{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-} ----------------------------------------------------------------------------- -- | -- Module      :  Network.Socket@@ -10,13 +11,9 @@ -- Stability   :  provisional -- Portability :  portable ----- The "Network.Socket" module is for when you want full control over--- sockets.  Essentially the entire C socket API is exposed through--- this module; in general the operations follow the behaviour of the C--- functions of the same name (consult your favourite Unix networking book).------ A higher level interface to networking operations is provided--- through the module "Network".+-- This is the main module of the network package supposed to be+-- used with either "Network.Socket.ByteString" or+-- "Network.Socket.ByteString.Lazy" for sending/receiving. -- -- Here are two minimal example programs using the TCP/IP protocol: a -- server that echoes all data that it receives back (servicing only@@ -48,6 +45,10 @@ -- >         sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr) -- >         setSocketOption sock ReuseAddr 1 -- >         bind sock (addrAddress addr)+-- >         -- If the prefork technique is not used,+-- >         -- set CloseOnExec for the security reasons.+-- >         let fd = fdSocket sock+-- >         setCloseOnExecIfNeeded fd -- >         listen sock 10 -- >         return sock -- >     loop sock = forever $ do@@ -95,121 +96,125 @@  module Network.Socket     (-    -- * Types-      Socket(..)-    , Family(..)-    , isSupportedFamily+    -- * Initialisation+      withSocketsDo+    -- * Address information+    , getAddrInfo+    -- ** Types+    , HostName+    , ServiceName+    , AddrInfo(..)+    , defaultHints+    -- ** Flags+    , AddrInfoFlag(..)+    , addrInfoFlagImplemented+    -- * Socket operations+    , connect+    , bind+    , listen+    , accept+    -- ** Closing+    , close+    , shutdown+    , ShutdownCmd(..)+    -- * Socket options+    , SocketOption(..)+    , isSupportedSocketOption+    , getSocketOption+    , setSocketOption+    -- * Socket+    , Socket(..)+    , socket+    , fdSocket+    , mkSocket+    , socketToHandle+    -- ** Types of Socket     , SocketType(..)     , isSupportedSocketType+    -- ** Family+    , Family(..)+    , isSupportedFamily+    -- ** Protocol number+    , ProtocolNumber+    , defaultProtocol+    -- * Socket address     , SockAddr(..)     , isSupportedSockAddr-    , SocketStatus(..)+    , getPeerName+    , getSocketName+    -- ** Host address     , HostAddress     , hostAddressToTuple     , tupleToHostAddress #if defined(IPV6_SOCKET_SUPPORT)+    -- ** Host address6     , HostAddress6     , hostAddress6ToTuple     , tupleToHostAddress6+    -- ** Flow Info     , FlowInfo+    -- ** Scope ID     , ScopeID+# if defined(HAVE_IF_NAMETOINDEX)+    , ifNameToIndex+    , ifIndexToName+# endif #endif-    , htonl-    , ntohl-    , ShutdownCmd(..)-    , ProtocolNumber-    , defaultProtocol+    -- ** Port number     , PortNumber(..)-    -- PortNumber is used non-abstractly in Network.BSD.  ToDo: remove-    -- this use and make the type abstract.--    -- * Address operations--    , HostName-    , ServiceName-+    , defaultPort+    , socketPort+    -- * UNIX-domain socket+    , isUnixDomainSocketAvailable+    , socketPair+    , sendFd+    , recvFd+    , getPeerCredential #if defined(IPV6_SOCKET_SUPPORT)-    , AddrInfo(..)--    , AddrInfoFlag(..)-    , addrInfoFlagImplemented--    , defaultHints--    , getAddrInfo-+    -- * Name information     , NameInfoFlag(..)-     , getNameInfo #endif--    -- * Socket operations-    , socket-#if defined(DOMAIN_SOCKET_SUPPORT)-    , socketPair-#endif-    , connect-    , bind-    , listen-    , accept-    , getPeerName-    , getSocketName--#if defined(HAVE_STRUCT_UCRED) || defined(HAVE_GETPEEREID)-    -- get the credentials of our domain socket peer.-    , getPeerCred-#if defined(HAVE_GETPEEREID)-    , getPeerEid-#endif-#endif--    , socketPort--    , socketToHandle--    -- ** Sending and receiving data-    -- *** Sending and receiving with String-    -- $sendrecv+    -- * Low level operations+    , setCloseOnExecIfNeeded+    , getCloseOnExec+    , setNonBlockIfNeeded+    , getNonBlock+    -- * Sending and receiving data+    , sendBuf+    , recvBuf+    , sendBufTo+    , recvBufFrom+    -- * Special constants+    , maxListenQueue+    -- * Deprecated+    -- ** Deprecated sending and receiving     , send     , sendTo     , recv     , recvFrom     , recvLen--    -- *** Sending and receiving with a buffer-    , sendBuf-    , recvBuf-    , sendBufTo-    , recvBufFrom--    -- ** Misc+    -- ** Deprecated address functions+    , htonl+    , ntohl     , inet_addr     , inet_ntoa--    , shutdown-    , close--    -- ** Predicates on sockets+    -- ** Deprecated socket operations+    , bindSocket+    , sClose+    -- ** Deprecated socket status+    , SocketStatus(..) -- fixme     , isConnected     , isBound     , isListening     , isReadable     , isWritable--    -- * Socket options-    , SocketOption(..)-    , isSupportedSocketOption-    , getSocketOption-    , setSocketOption--    -- * File descriptor transmission-#ifdef DOMAIN_SOCKET_SUPPORT-    , sendFd-    , recvFd--#endif--    -- * Special constants+    , sIsConnected+    , sIsBound+    , sIsListening+    , sIsReadable+    , sIsWritable+    -- ** Deprecated special constants     , aNY_PORT     , iNADDR_ANY #if defined(IPV6_SOCKET_SUPPORT)@@ -220,35 +225,18 @@ #ifdef SCM_RIGHTS     , sCM_RIGHTS #endif-    , maxListenQueue--    -- * Initialisation-    , withSocketsDo--    -- * Very low level operations-    -- in case you ever want to get at the underlying file descriptor..-    , fdSocket-    , mkSocket-    , setNonBlockIfNeeded--    -- * Deprecated aliases-    -- $deprecated-aliases-    , bindSocket-    , sClose-    , sIsConnected-    , sIsBound-    , sIsListening-    , sIsReadable-    , sIsWritable--    -- * Internal--    -- | The following are exported ONLY for use in the BSD module and-    -- should not be used anywhere else.-+    -- ** Decrecated internal functions     , packFamily     , unpackFamily     , packSocketType+    -- ** Decrecated UNIX-domain functions+#if defined(HAVE_STRUCT_UCRED) || defined(HAVE_GETPEEREID)+    -- get the credentials of our domain socket peer.+    , getPeerCred+#if defined(HAVE_GETPEEREID)+    , getPeerEid+#endif+#endif     ) where  import Data.Bits@@ -260,7 +248,7 @@ import Foreign.Storable (Storable(..)) import Foreign.C.Error import Foreign.C.String (CString, withCString, withCStringLen, peekCString, peekCStringLen)-import Foreign.C.Types (CUInt, CChar)+import Foreign.C.Types (CUInt(..), CChar) import Foreign.C.Types (CInt(..), CSize(..)) import Foreign.Marshal.Alloc ( alloca, allocaBytes ) import Foreign.Marshal.Array ( peekArray )@@ -269,6 +257,7 @@ import System.IO import Control.Monad (liftM, when) +import qualified Control.Exception as E import Control.Concurrent.MVar import Data.Typeable import System.IO.Error@@ -281,7 +270,6 @@ import GHC.Conc (closeFdWith) ##endif # if defined(mingw32_HOST_OS)-import qualified Control.Exception as E import GHC.Conc (asyncDoProc) import GHC.IO.FD (FD(..), readRawBufferPtr, writeRawBufferPtr) import Foreign (FunPtr)@@ -350,6 +338,7 @@    withSocketsDo $ return ()    return $ MkSocket fd fam sType pNum mStat +-- | Obtaining the file descriptor from a socket. fdSocket :: Socket -> CInt fdSocket (MkSocket fd _ _ _ _) = fd @@ -405,11 +394,7 @@ -- -- >>> let hints = defaultHints { addrFlags = [AI_NUMERICHOST, AI_NUMERICSERV], addrSocketType = Stream } -- >>> addr:_ <- getAddrInfo (Just hints) (Just "127.0.0.1") (Just "5000")--- >>> sock@(MkSocket _ fam stype _ _) <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)--- >>> fam--- AF_INET--- >>> stype--- Stream+-- >>> sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr) -- >>> bind sock (addrAddress addr) -- >>> getSocketName sock -- 127.0.0.1:5000@@ -442,11 +427,11 @@ -- family, socket type, and protocol number.  Address family, socket -- type, and protocol number are as for the 'socket' function above. -- Availability: Unix.-#if defined(DOMAIN_SOCKET_SUPPORT) socketPair :: Family              -- Family Name (usually AF_INET or AF_INET6)            -> SocketType          -- Socket Type (usually Stream)            -> ProtocolNumber      -- Protocol Number            -> IO (Socket, Socket) -- unnamed and connected.+#if defined(DOMAIN_SOCKET_SUPPORT) socketPair family stype protocol = do     allocaBytes (2 * sizeOf (1 :: CInt)) $ \ fdArr -> do     c_stype <- packSocketTypeOrThrow "socketPair" stype@@ -463,23 +448,87 @@  foreign import ccall unsafe "socketpair"   c_socketpair :: CInt -> CInt -> CInt -> Ptr CInt -> IO CInt+#else+socketPair _ _ _ = error "Network.Socket.socketPair" #endif --- | Set the socket to nonblocking, if applicable to this platform.------ Depending on the platform this is required when using sockets from file--- descriptors that are passed in through 'recvFd' or other means.+-----------------------------------------------------------------------------++#if defined(mingw32_HOST_OS)+#else+fGetFd :: CInt+fGetFd = #const F_GETFD+fGetFl :: CInt+fGetFl = #const F_GETFL+fdCloexec :: CInt+fdCloexec = #const FD_CLOEXEC+oNonBlock :: CInt+oNonBlock = #const O_NONBLOCK+# if defined(HAVE_ACCEPT4)+sockNonBlock :: CInt+sockNonBlock = #const SOCK_NONBLOCK+sockCloexec :: CInt+sockCloexec = #const SOCK_CLOEXEC+# endif+#endif++-- | Set the nonblocking flag on Unix.+--   On Windows, nothing is done. setNonBlockIfNeeded :: CInt -> IO () setNonBlockIfNeeded fd =     System.Posix.Internals.setNonBlockingFD fd True +-- | Set the close_on_exec flag on Unix.+--   On Windows, nothing is done.+--+--   Since 2.7.0.0.+setCloseOnExecIfNeeded :: CInt -> IO ()+#if defined(mingw32_HOST_OS)+setCloseOnExecIfNeeded _ = return ()+#else+setCloseOnExecIfNeeded fd = System.Posix.Internals.setCloseOnExec fd+#endif++#if !defined(mingw32_HOST_OS)+foreign import ccall unsafe "fcntl"+  c_fcntl_read  :: CInt -> CInt -> CInt -> IO CInt+#endif++-- | Get the nonblocking flag.+--   On Windows, this function always returns 'False'.+--+--   Since 2.7.0.0.+getCloseOnExec :: CInt -> IO Bool+#if defined(mingw32_HOST_OS)+getCloseOnExec _ = return False+#else+getCloseOnExec fd = do+    flags <- c_fcntl_read fd fGetFd 0+    let ret = flags .&. fdCloexec+    return (ret /= 0)+#endif++-- | Get the close_on_exec flag.+--   On Windows, this function always returns 'False'.+--+--   Since 2.7.0.0.+getNonBlock :: CInt -> IO Bool+#if defined(mingw32_HOST_OS)+getNonBlock _ = return False+#else+getNonBlock fd = do+    flags <- c_fcntl_read fd fGetFl 0+    let ret = flags .&. oNonBlock+    return (ret /= 0)+#endif+ ----------------------------------------------------------------------------- -- Binding a socket  -- | Bind the socket to an address. The socket must not already be -- bound.  The 'Family' passed to @bind@ must be the -- same as that passed to 'socket'.  If the special port number--- 'aNY_PORT' is passed then the system assigns the next available+-- 'defaultPort' is passed then the system assigns the next available -- use port. bind :: Socket    -- Unconnected Socket            -> SockAddr  -- Address to Bind to@@ -578,8 +627,7 @@        -> IO (Socket,                   -- Readable Socket               SockAddr)                 -- Peer details -accept sock@(MkSocket s family stype protocol status) = do- currentStatus <- readMVar status+accept sock@(MkSocket s family stype protocol status) = withMVar status $ \currentStatus -> do  if not $ isAcceptable family stype currentStatus    then      ioError $ userError $@@ -608,11 +656,12 @@ # ifdef HAVE_ACCEPT4      new_sock <- throwSocketErrorIfMinus1RetryMayBlock "Network.Socket.accept"                         (threadWaitRead (fromIntegral s))-                        (c_accept4 s sockaddr ptr_len (#const SOCK_NONBLOCK))+                        (c_accept4 s sockaddr ptr_len (sockNonBlock .|. sockCloexec)) # else      new_sock <- throwSocketErrorWaitRead sock "Network.Socket.accept"                         (c_accept s sockaddr ptr_len)      setNonBlockIfNeeded new_sock+     setCloseOnExecIfNeeded new_sock # endif /* HAVE_ACCEPT4 */ #endif      addr <- peekSockAddr sockaddr@@ -651,7 +700,7 @@ -- -- NOTE: blocking on Windows unless you compile with -threaded (see -- GHC ticket #1129)-{-# WARNING sendTo "Use sendTo defined in \"Network.Socket.ByteString\"" #-}+{-# DEPRECATED sendTo "Use sendTo defined in \"Network.Socket.ByteString\"" #-} sendTo :: Socket        -- (possibly) bound/connected Socket        -> String        -- Data to send        -> SockAddr@@ -683,7 +732,7 @@ -- -- NOTE: blocking on Windows unless you compile with -threaded (see -- GHC ticket #1129)-{-# WARNING recvFrom "Use recvFrom defined in \"Network.Socket.ByteString\"" #-}+{-# DEPRECATED recvFrom "Use recvFrom defined in \"Network.Socket.ByteString\"" #-} recvFrom :: Socket -> Int -> IO (String, Int, SockAddr) recvFrom sock nbytes =   allocaBytes nbytes $ \ptr -> do@@ -732,7 +781,7 @@ -- responsible for ensuring that all data has been sent. -- -- Sending data to closed socket may lead to undefined behaviour.-{-# WARNING send "Use send defined in \"Network.Socket.ByteString\"" #-}+{-# DEPRECATED send "Use send defined in \"Network.Socket.ByteString\"" #-} send :: Socket  -- Bound/Connected Socket      -> String  -- Data to send      -> IO Int  -- Number of Bytes sent@@ -780,11 +829,11 @@ -- closed its half side of the connection. -- -- Receiving data from closed socket may lead to undefined behaviour.-{-# WARNING recv "Use recv defined in \"Network.Socket.ByteString\"" #-}+{-# DEPRECATED recv "Use recv defined in \"Network.Socket.ByteString\"" #-} recv :: Socket -> Int -> IO String recv sock l = fst <$> recvLen sock l -{-# WARNING recvLen "Use recv defined in \"Network.Socket.ByteString\" with \"Data.Bytestring.length\"" #-}+{-# DEPRECATED recvLen "Use recv defined in \"Network.Socket.ByteString\" with \"Data.Bytestring.length\"" #-} recvLen :: Socket -> Int -> IO (String, Int) recvLen sock nbytes =      allocaBytes nbytes $ \ptr -> do@@ -1046,7 +1095,36 @@        fromIntegral `liftM` peek ptr_v  +-- | Getting process ID, user ID and group ID for UNIX-domain sockets.+--+--   This is implemented with SO_PEERCRED on Linux and getpeereid()+--   on BSD variants. Unfortunately, on some BSD variants+--   getpeereid() returns unexpected results, rather than an error,+--   for AF_INET sockets. It is the user's responsibility to make sure+--   that the socket is a UNIX-domain socket.+--   Also, on some BSD variants, getpeereid() does not return credentials+--   for sockets created via 'socketPair', only separately created and then+--   explicitly connected UNIX-domain sockets work on such systems.+--+--   Since 2.7.0.0.+getPeerCredential :: Socket -> IO (Maybe CUInt, Maybe CUInt, Maybe CUInt)+#ifdef HAVE_STRUCT_UCRED+getPeerCredential sock = do+    (pid, uid, gid) <- getPeerCred sock+    if uid == maxBound then+        return (Nothing, Nothing, Nothing)+      else+        return (Just pid, Just uid, Just gid)+#elif defined(HAVE_GETPEEREID)+getPeerCredential sock = E.handle (\(E.SomeException _) -> return (Nothing,Nothing,Nothing)) $ do+    (uid, gid) <- getPeerEid sock+    return (Nothing, Just uid, Just gid)+#else+getPeerCredential _ = return (Nothing, Nothing, Nothing)+#endif+ #if defined(HAVE_STRUCT_UCRED) || defined(HAVE_GETPEEREID)+{-# DEPRECATED getPeerCred "Use getPeerCredential instead" #-} -- | Returns the processID, userID and groupID of the socket's peer. -- -- Only available on platforms that support SO_PEERCRED or GETPEEREID(3)@@ -1071,6 +1149,7 @@ #endif  #ifdef HAVE_GETPEEREID+{-# DEPRECATED getPeerEid "Use getPeerCredential instead" #-} -- | The getpeereid() function returns the effective user and group IDs of the -- peer connected to a UNIX-domain socket getPeerEid :: Socket -> IO (CUInt, CUInt)@@ -1086,43 +1165,59 @@ #endif #endif +-- | Whether or not UNIX-domain sockets are available.+--+--   Since 3.0.0.0.+isUnixDomainSocketAvailable :: Bool+#if defined(DOMAIN_SOCKET_SUPPORT)+isUnixDomainSocketAvailable = True+#else+isUnixDomainSocketAvailable = False+#endif+ ##if !(MIN_VERSION_base(4,3,1)) closeFdWith closer fd = closer fd ##endif -#if defined(DOMAIN_SOCKET_SUPPORT) -- sending/receiving ancillary socket data; low-level mechanism -- for transmitting file descriptors, mainly. sendFd :: Socket -> CInt -> IO ()+#if defined(DOMAIN_SOCKET_SUPPORT) sendFd sock outfd = do-  _ <- ($) throwSocketErrorWaitWrite sock "Network.Socket.sendFd" $-     c_sendFd (fdSocket sock) outfd-   -- Note: If Winsock supported FD-passing, thi would have been-   -- incorrect (since socket FDs need to be closed via closesocket().)-  closeFd outfd+  _ <- throwSocketErrorWaitWrite sock "Network.Socket.sendFd" $ c_sendFd (fdSocket sock) outfd+  return ()+foreign import ccall SAFE_ON_WIN "sendFd" c_sendFd :: CInt -> CInt -> IO CInt+#else+sendFd _ _ = error "Network.Socket.sendFd"+#endif  -- | Receive a file descriptor over a domain socket. Note that the resulting -- file descriptor may have to be put into non-blocking mode in order to be -- used safely. See 'setNonBlockIfNeeded'. recvFd :: Socket -> IO CInt+#if defined(DOMAIN_SOCKET_SUPPORT) recvFd sock = do   theFd <- throwSocketErrorWaitRead sock "Network.Socket.recvFd" $                c_recvFd (fdSocket sock)   return theFd--foreign import ccall SAFE_ON_WIN "sendFd" c_sendFd :: CInt -> CInt -> IO CInt foreign import ccall SAFE_ON_WIN "recvFd" c_recvFd :: CInt -> IO CInt-+#else+recvFd _ = error "Network.Socket.recvFd" #endif  -- --------------------------------------------------------------------------- -- Utility Functions +{-# DEPRECATED aNY_PORT "Use defaultPort instead" #-} aNY_PORT :: PortNumber aNY_PORT = 0 +defaultPort :: PortNumber+defaultPort = 0+ -- | The IPv4 wild card address. +{-# DEPRECATED iNADDR_ANY "Use getAddrInfo instead" #-} iNADDR_ANY :: HostAddress iNADDR_ANY = htonl (#const INADDR_ANY) @@ -1131,20 +1226,27 @@ -- | Converts the from network byte order to host byte order. foreign import CALLCONV unsafe "ntohl" ntohl :: Word32 -> Word32 +{-# DEPRECATED htonl "Use getAddrInfo instead" #-}+{-# DEPRECATED ntohl "Use getAddrInfo instead" #-}+ #if defined(IPV6_SOCKET_SUPPORT) -- | The IPv6 wild card address. +{-# DEPRECATED iN6ADDR_ANY "Use getAddrInfo instead" #-} iN6ADDR_ANY :: HostAddress6 iN6ADDR_ANY = (0, 0, 0, 0) #endif +{-# DEPRECATED sOMAXCONN "Use maxListenQueue instead" #-} sOMAXCONN :: Int sOMAXCONN = #const SOMAXCONN +{-# DEPRECATED sOL_SOCKET "This is not necessary anymore" #-} sOL_SOCKET :: Int sOL_SOCKET = #const SOL_SOCKET  #ifdef SCM_RIGHTS+{-# DEPRECATED sCM_RIGHTS "This is not necessary anymore" #-} sCM_RIGHTS :: Int sCM_RIGHTS = #const SCM_RIGHTS #endif@@ -1203,6 +1305,7 @@ isConnected (MkSocket _ _ _ _ status) = do     value <- readMVar status     return (value == Connected)+{-# DEPRECATED isConnected "SocketStatus will be removed" #-}  -- ----------------------------------------------------------------------------- -- Socket Predicates@@ -1211,19 +1314,23 @@ isBound (MkSocket _ _ _ _ status) = do     value <- readMVar status     return (value == Bound)+{-# DEPRECATED isBound "SocketStatus will be removed" #-}  isListening :: Socket -> IO Bool isListening (MkSocket _ _ _  _ status) = do     value <- readMVar status     return (value == Listening)+{-# DEPRECATED isListening "SocketStatus will be removed" #-}  isReadable  :: Socket -> IO Bool isReadable (MkSocket _ _ _ _ status) = do     value <- readMVar status     return (value == Listening || value == Connected)+{-# DEPRECATED isReadable "SocketStatus will be removed" #-}  isWritable  :: Socket -> IO Bool isWritable = isReadable -- sort of.+{-# DEPRECATED isWritable "SocketStatus will be removed" #-}  isAcceptable :: Family -> SocketType -> SocketStatus -> Bool #if defined(DOMAIN_SOCKET_SUPPORT)@@ -1233,10 +1340,12 @@ isAcceptable AF_UNIX _ _ = False #endif isAcceptable _ _ status = status == Connected || status == Listening+{-# DEPRECATED isAcceptable "SocketStatus will be removed" #-}  -- ----------------------------------------------------------------------------- -- Internet address manipulation routines: +{-# DEPRECATED inet_addr "Use \"getNameInfo\" instead" #-} inet_addr :: String -> IO HostAddress inet_addr ipstr = withSocketsDo $ do    withCString ipstr $ \str -> do@@ -1246,6 +1355,7 @@       "Network.Socket.inet_addr: Malformed address: " ++ ipstr     else return had  -- network byte order +{-# DEPRECATED inet_ntoa "Use \"getNameInfo\" instead" #-} inet_ntoa :: HostAddress -> IO String inet_ntoa haddr = withSocketsDo $ do   pstr <- c_inet_ntoa haddr@@ -1323,8 +1433,8 @@     | AI_NUMERICSERV     -- | If no 'HostName' value is provided, the network     --   address in each 'SockAddr'-    --   will be left as a "wild card", i.e. as either 'iNADDR_ANY'-    --   or 'iN6ADDR_ANY'.  This is useful for server applications that+    --   will be left as a "wild card".+    --   This is useful for server applications that     --   will accept connections from any client.     | AI_PASSIVE     -- | If an IPv6 lookup is performed, and no IPv6@@ -1758,32 +1868,55 @@ sClose :: Socket -> IO () sClose = close -{-# DEPRECATED sIsConnected "use 'isConnected'" #-}+{-# DEPRECATED sIsConnected "SocketStatus will be removed" #-} --- | Deprecated alias for 'isConnected'. sIsConnected :: Socket -> IO Bool sIsConnected = isConnected -{-# DEPRECATED sIsBound "use 'isBound'" #-}+{-# DEPRECATED sIsBound "SocketStatus will be removed" #-} --- | Deprecated alias for 'isBound'. sIsBound :: Socket -> IO Bool sIsBound = isBound -{-# DEPRECATED sIsListening "use 'isListening'" #-}+{-# DEPRECATED sIsListening "SocketStatus will be removed" #-} --- | Deprecated alias for 'isListening'. sIsListening :: Socket -> IO Bool sIsListening = isListening -{-# DEPRECATED sIsReadable "use 'isReadable'" #-}+{-# DEPRECATED sIsReadable "SocketStatus will be removed" #-} --- | Deprecated alias for 'isReadable'. sIsReadable  :: Socket -> IO Bool sIsReadable = isReadable -{-# DEPRECATED sIsWritable "use 'isWritable'" #-}+{-# DEPRECATED sIsWritable "SocketStatus will be removed" #-} --- | Deprecated alias for 'isWritable'. sIsWritable  :: Socket -> IO Bool sIsWritable = isWritable++#if defined(HAVE_IF_NAMETOINDEX)+-- | Returns the index corresponding to the interface name.+--+--   Since 2.7.0.0.+ifNameToIndex :: String -> IO (Maybe Int)+ifNameToIndex ifname = do+  index <- withCString ifname c_if_nametoindex+  -- On failure zero is returned. We'll return Nothing.+  return $ if index == 0 then Nothing else Just $ fromIntegral index++-- | Returns the interface name corresponding to the index.+--+--   Since 2.7.0.0.+ifIndexToName :: Int -> IO (Maybe String)+ifIndexToName ifn = allocaBytes 16 $ \ptr -> do -- 16 == IFNAMSIZ+    r <- c_if_indextoname (fromIntegral ifn) ptr+    if r == nullPtr then+        return Nothing+      else+        Just <$> peekCString ptr++foreign import CALLCONV safe "if_nametoindex"+   c_if_nametoindex :: CString -> IO CUInt++foreign import CALLCONV safe "if_indextoname"+   c_if_indextoname :: CUInt -> CString -> IO CString+#endif
Network/Socket/ByteString.hsc view
@@ -1,3 +1,4 @@+{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-} {-# LANGUAGE CPP, ForeignFunctionInterface #-}  #include "HsNet.h"@@ -263,7 +264,7 @@  -- | @withIOVec cs f@ executes the computation @f@, passing as argument a pair -- consisting of a pointer to a temporarily allocated array of pointers to--- 'IOVec' made from @cs@ and the number of pointers (@length cs@).+-- IOVec made from @cs@ and the number of pointers (@length cs@). -- /Unix only/. withIOVec :: [ByteString] -> ((Ptr IOVec, Int) -> IO a) -> IO a withIOVec cs f =
Network/Socket/ByteString/Lazy/Posix.hs view
@@ -1,3 +1,4 @@+{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-} {-# LANGUAGE BangPatterns #-} module Network.Socket.ByteString.Lazy.Posix     (
Network/Socket/Types.hsc view
@@ -72,18 +72,7 @@ import Foreign.Ptr import Foreign.Storable --- | Represents a socket.  The fields are, respectively:------   * File descriptor---   * Socket family---   * Socket type---   * Protocol number---   * Status flag------   If you are calling the 'MkSocket' constructor directly you should ensure---   you have called 'Network.withSocketsDo' and that the file descriptor is---   in non-blocking mode. See 'Network.Socket.setNonBlockIfNeeded'.---+-- | A socket data type. --  'Socket's are not GCed unless they are closed by 'close'. data Socket   = MkSocket@@ -94,6 +83,8 @@             (MVar SocketStatus)  -- Status Flag   deriving Typeable +{-# DEPRECATED MkSocket "'MkSocket' will not be available in version 3.0.0.0 or later. Use fdSocket instead" #-}+ sockFd :: Socket -> CInt sockFd       (MkSocket n _ _ _ _) = n @@ -133,6 +124,8 @@   | Closed              -- ^ Closed was closed by 'close'     deriving (Eq, Show, Typeable) +{-# DEPRECATED SocketStatus "SocketStatus will be removed" #-}+ ----------------------------------------------------------------------------- -- Socket types @@ -191,6 +184,8 @@ #endif     _ -> Nothing +{-# DEPRECATED packSocketType "packSocketType will not be available in version 3.0.0.0 or later." #-}+ packSocketType :: SocketType -> CInt packSocketType stype = fromMaybe (error errMsg) (packSocketType' stype)   where@@ -310,6 +305,8 @@     | AF_CAN              -- Controller Area Network       deriving (Eq, Ord, Read, Show) +{-# DEPRECATED packFamily "packFamily will not be available in version 3.0.0.0 or later." #-}+ packFamily :: Family -> CInt packFamily f = case packFamily' f of     Just fam -> fam@@ -526,6 +523,8 @@  --------- ---------- +{-# DEPRECATED unpackFamily "unpackFamily will not be available in version 3.0.0.0 or later." #-}+ unpackFamily :: CInt -> Family unpackFamily f = case f of         (#const AF_UNSPEC) -> AF_UNSPEC@@ -807,11 +806,11 @@ -- to type cast the Internet socket address into a struct sockaddr. -- Instances of the structure for different families might *not* be -- the same size. Same casting is required of other families of--- sockets such as Xerox NS. Similarly for Unix domain sockets.+-- sockets such as Xerox NS. Similarly for UNIX-domain sockets.  -- To represent these socket addresses in Haskell-land, we do what BSD -- didn't do, and use a union/algebraic type for the different--- families. Currently only Unix domain sockets and the Internet+-- families. Currently only UNIX-domain sockets and the Internet -- families are supported.  #if defined(IPV6_SOCKET_SUPPORT)
configure.ac view
@@ -1,4 +1,4 @@-AC_INIT([Haskell network package], [2.6.3.6], [libraries@haskell.org], [network])+AC_INIT([Haskell network package], [2.7.0.0], [libraries@haskell.org], [network])  ac_includes_default="$ac_includes_default #ifdef HAVE_SYS_SOCKET_H@@ -101,7 +101,7 @@ fi  dnl ---------------------------------------------------dnl * test for GETPEEREID(3)+dnl * test for GETPEEREID(3)  dnl -------------------------------------------------- AC_MSG_CHECKING(for getpeereid in unistd.h) AC_CHECK_FUNC( getpeereid, AC_DEFINE([HAVE_GETPEEREID], [1], [Define to 1 if you have getpeereid.] ))
examples/EchoServer.hs view
@@ -23,6 +23,10 @@     open addr = do         sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)         setSocketOption sock ReuseAddr 1+        -- If the prefork technique is not used,+        -- set CloseOnExec for the security reasons.+        let fd = fdSocket sock+        setCloseOnExecIfNeeded fd         bind sock (addrAddress addr)         listen sock 10         return sock
network.cabal view
@@ -1,5 +1,5 @@ name:           network-version:        2.6.3.6+version:        2.7.0.0 license:        BSD3 license-file:   LICENSE maintainer:     Kazu Yamamoto, Evan Borden@@ -84,6 +84,7 @@   build-depends:     base < 5,     bytestring,+    directory,     HUnit,     network,     hspec
tests/SimpleSpec.hs view
@@ -13,6 +13,7 @@ import qualified Data.ByteString.Char8 as C import Network.Socket hiding (send, sendTo, recv, recvFrom) import Network.Socket.ByteString+import System.Directory import System.Timeout (timeout)  import Test.Hspec@@ -119,6 +120,44 @@               getSocketOption sock UserTimeout `shouldReturn` 2000               close sock +    -- On various BSD systems the peer credentials are exchanged during+    -- connect(), and this does not happen with `socketpair()`.  Therefore,+    -- we must actually set up a listener and connect, rather than use a+    -- socketpair().+    --+    describe "getPeerCredential" $ do+        it "can return something" $ do+            when isUnixDomainSocketAvailable $ do+                -- It would be useful to check that we did not get garbage+                -- back, but rather the actual uid of the test program.  For+                -- that we'd need System.Posix.User, but that is not available+                -- under Windows.  For now, accept the risk that we did not get+                -- the right answer.+                --+                let client sock = do+                        (_, uid, _) <- getPeerCredential sock+                        uid `shouldNotBe` Nothing+                    server (sock, _) = do+                        (_, uid, _) <- getPeerCredential sock+                        uid `shouldNotBe` Nothing+                unixTest client server+        {- The below test fails on many *BSD systems, because the getsockopt()+           call that underlies getpeereid() does not have the same meaning for+           all address families, but the C-library was not checking that the+           provided sock is an AF_UNIX socket.  This will fixed some day, but+           we should not fail on those systems in the mean-time.  The upstream+           C-library fix is to call getsockname() and check the address family+           before calling `getpeereid()`.  We could duplicate that in our own+           code, and then this test would work on those platforms that have+           `getpeereid()` and not the SO_PEERCRED socket option.++        it "return nothing for non-UNIX-domain socket" $ do+            when isUnixDomainSocketAvailable $ do+                s <- socket AF_INET Stream defaultProtocol+                cred1 <- getPeerCredential s+                cred1 `shouldBe` (Nothing,Nothing,Nothing)+        -}+     describe "getAddrInfo" $ do         it "works for IPv4 address" $ do             let hints = defaultHints { addrFlags = [AI_NUMERICHOST, AI_ADDRCONFIG] }@@ -143,12 +182,47 @@ testMsg :: ByteString testMsg = "This is a test message." +unixAddr :: String+unixAddr = "/tmp/network-test"+ ------------------------------------------------------------------------ -- Test helpers  -- | Establish a connection between client and server and then run -- 'clientAct' and 'serverAct', in different threads.  Both actions -- get passed a connected 'Socket', used for communicating between+-- client and server.  'unixTest' makes sure that the 'Socket' is+-- closed after the actions have run.+unixTest :: (Socket -> IO a) -> ((Socket, SockAddr) -> IO b) -> IO ()+unixTest clientAct serverAct = do+    test clientSetup clientAct serverSetup server+  where+    clientSetup = do+        sock <- socket AF_UNIX Stream defaultProtocol+        connect sock (SockAddrUnix unixAddr)+        return sock++    serverSetup = do+        sock <- socket AF_UNIX Stream defaultProtocol+        unlink unixAddr -- just in case+        bind sock (SockAddrUnix unixAddr)+        listen sock 1+        return sock++    server sock = E.bracket (accept sock) (killClientSock . fst) serverAct++    unlink file = do+        exist <- doesFileExist file+        when exist $ removeFile file++    killClientSock sock = do+        shutdown sock ShutdownBoth+        close sock+        unlink unixAddr++-- | Establish a connection between client and server and then run+-- 'clientAct' and 'serverAct', in different threads.  Both actions+-- get passed a connected 'Socket', used for communicating between -- client and server.  'tcpTest' makes sure that the 'Socket' is -- closed after the actions have run. tcpTest :: (Socket -> IO a) -> (Socket -> IO b) -> IO ()@@ -161,6 +235,11 @@         serverPort <- readMVar portVar         addr:_ <- getAddrInfo (Just hints) (Just serverAddr) (Just $ show serverPort)         sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)+#if !defined(mingw32_HOST_OS)+        let fd = fdSocket sock+        getNonBlock fd `shouldReturn` True+        getCloseOnExec fd `shouldReturn` False+#endif         connect sock $ addrAddress addr         return sock @@ -171,7 +250,16 @@               }         addr:_ <- getAddrInfo (Just hints) (Just serverAddr) Nothing         sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)+        let fd = fdSocket sock+#if !defined(mingw32_HOST_OS)+        getNonBlock fd `shouldReturn` True+        getCloseOnExec fd `shouldReturn` False+#endif         setSocketOption sock ReuseAddr 1+        setCloseOnExecIfNeeded fd+#if !defined(mingw32_HOST_OS)+        getCloseOnExec fd `shouldReturn` True+#endif         bind sock $ addrAddress addr         listen sock 1         serverPort <- socketPort sock@@ -180,6 +268,11 @@      server sock = do         (clientSock, _) <- accept sock+#if !defined(mingw32_HOST_OS)+        let fd = fdSocket clientSock+        getNonBlock fd `shouldReturn` True+        getCloseOnExec fd `shouldReturn` True+#endif         _ <- serverAct clientSock         close clientSock