-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | An extensible socket library. -- -- This library is a minimal cross-platform interface for BSD style -- networking. @package socket @version 0.8.3.0 module System.Socket.Family.Inet -- | The Internet Protocol version 4. data Inet -- | To avoid errors with endianess it was decided to keep this type -- abstract. -- -- Use inetAddressFromTuple and inetAddressToTuple for -- constructing and deconstructing custom addresses. -- -- Hint: Use the Storable instance. It exposes it exactly as found -- within an IP packet (big endian if you insist on interpreting it as a -- number). -- -- Another hint: Use getAddressInfo for parsing and suppress -- nameserver lookups: -- --
-- > getAddressInfo (Just "127.0.0.1") Nothing aiNumericHost :: IO [AddressInfo Inet Stream TCP]
-- [AddressInfo {addressInfoFlags = AddressInfoFlags 4, socketAddress = SocketAddressInet {inetAddress = InetAddress 127.0.0.1, inetPort = InetPort 0}, canonicalName = Nothing}]
--
data InetAddress
data InetPort
-- | The SocketAddress type is a data family. This allows to
-- provide different data constructors depending on the socket family
-- without knowing all of them in advance or the need to extend this core
-- library.
--
-- -- SocketAddressInet inetLoopback 8080 :: SocketAddress Inet -- SocketAddressInet6 inet6Loopback 8080 0 0 :: SocketAddress Inet6 --data family SocketAddress f -- | Constructs a custom InetAddress. -- --
-- inetAddressFromTuple (127,0,0,1) == inetLoopback --inetAddressFromTuple :: (Word8, Word8, Word8, Word8) -> InetAddress -- | Deconstructs an InetAddress. inetAddressToTuple :: InetAddress -> (Word8, Word8, Word8, Word8) -- |
-- 224.0.0.1 --inetAllHostsGroup :: InetAddress -- |
-- 0.0.0.0 --inetAny :: InetAddress -- |
-- 255.255.255.255 --inetBroadcast :: InetAddress -- |
-- 127.0.0.1 --inetLoopback :: InetAddress -- |
-- 224.0.0.255 --inetMaxLocalGroup :: InetAddress -- |
-- 255.255.255.255 --inetNone :: InetAddress -- |
-- 224.0.0.0 --inetUnspecificGroup :: InetAddress instance GHC.Real.Integral System.Socket.Family.Inet.InetPort instance GHC.Enum.Enum System.Socket.Family.Inet.InetPort instance GHC.Real.Real System.Socket.Family.Inet.InetPort instance GHC.Num.Num System.Socket.Family.Inet.InetPort instance GHC.Show.Show System.Socket.Family.Inet.InetPort instance GHC.Classes.Ord System.Socket.Family.Inet.InetPort instance GHC.Classes.Eq System.Socket.Family.Inet.InetPort instance GHC.Classes.Eq System.Socket.Family.Inet.InetAddress instance GHC.Show.Show (System.Socket.Internal.Socket.SocketAddress System.Socket.Family.Inet.Inet) instance GHC.Classes.Eq (System.Socket.Internal.Socket.SocketAddress System.Socket.Family.Inet.Inet) instance System.Socket.Internal.Socket.Family System.Socket.Family.Inet.Inet instance Foreign.Storable.Storable System.Socket.Family.Inet.InetPort instance GHC.Show.Show System.Socket.Family.Inet.InetAddress instance Foreign.Storable.Storable System.Socket.Family.Inet.InetAddress instance Foreign.Storable.Storable (System.Socket.Internal.Socket.SocketAddress System.Socket.Family.Inet.Inet) module System.Socket.Family.Inet6 -- | The Internet Protocol version 6. data Inet6 -- | To avoid errors with endianess it was decided to keep this type -- abstract. -- -- Use inet6AddressFromTuple and inet6AddressToTuple for -- constructing and deconstructing custom addresses. -- -- Hint: Use the Storable instance. It exposes it exactly as found -- within an IP packet (big endian if you insist on interpreting it as a -- number). -- -- Another hint: Use getAddressInfo for parsing and suppress -- nameserver lookups: -- --
-- > getAddressInfo (Just "::1") Nothing aiNumericHost :: IO [AddressInfo SocketAddressInet6 Stream TCP]
-- [AddressInfo {
-- addressInfoFlags = AddressInfoFlags 4,
-- socketAddress = SocketAddressInet6 {inet6Address = Inet6Address 0000:0000:0000:0000:0000:0000:0000:0001, inet6Port = Inet6Port 0, inet6FlowInfo = Inet6FlowInfo 0, inet6ScopeId = Inet6ScopeId 0},
-- canonicalName = Nothing }]
--
data Inet6Address
data Inet6Port
data Inet6FlowInfo
data Inet6ScopeId
-- | The SocketAddress type is a data family. This allows to
-- provide different data constructors depending on the socket family
-- without knowing all of them in advance or the need to extend this core
-- library.
--
-- -- SocketAddressInet inetLoopback 8080 :: SocketAddress Inet -- SocketAddressInet6 inet6Loopback 8080 0 0 :: SocketAddress Inet6 --data family SocketAddress f -- | Constructs a custom Inet6Address. -- --
-- inet6AddressFromTuple (0,0,0,0,0,0,0,1) == inet6Loopback --inet6AddressFromTuple :: (Word16, Word16, Word16, Word16, Word16, Word16, Word16, Word16) -> Inet6Address -- | Deconstructs an Inet6Address. inet6AddressToTuple :: Inet6Address -> (Word16, Word16, Word16, Word16, Word16, Word16, Word16, Word16) -- |
-- :: --inet6Any :: Inet6Address -- |
-- ::1 --inet6Loopback :: Inet6Address -- |
-- IPV6_V6ONLY --data V6Only V6Only :: Bool -> V6Only instance GHC.Show.Show System.Socket.Family.Inet6.V6Only instance GHC.Classes.Ord System.Socket.Family.Inet6.V6Only instance GHC.Classes.Eq System.Socket.Family.Inet6.V6Only instance GHC.Real.Integral System.Socket.Family.Inet6.Inet6ScopeId instance GHC.Enum.Enum System.Socket.Family.Inet6.Inet6ScopeId instance GHC.Real.Real System.Socket.Family.Inet6.Inet6ScopeId instance GHC.Num.Num System.Socket.Family.Inet6.Inet6ScopeId instance GHC.Show.Show System.Socket.Family.Inet6.Inet6ScopeId instance GHC.Classes.Ord System.Socket.Family.Inet6.Inet6ScopeId instance GHC.Classes.Eq System.Socket.Family.Inet6.Inet6ScopeId instance GHC.Real.Integral System.Socket.Family.Inet6.Inet6FlowInfo instance GHC.Enum.Enum System.Socket.Family.Inet6.Inet6FlowInfo instance GHC.Real.Real System.Socket.Family.Inet6.Inet6FlowInfo instance GHC.Num.Num System.Socket.Family.Inet6.Inet6FlowInfo instance GHC.Show.Show System.Socket.Family.Inet6.Inet6FlowInfo instance GHC.Classes.Ord System.Socket.Family.Inet6.Inet6FlowInfo instance GHC.Classes.Eq System.Socket.Family.Inet6.Inet6FlowInfo instance GHC.Real.Integral System.Socket.Family.Inet6.Inet6Port instance GHC.Enum.Enum System.Socket.Family.Inet6.Inet6Port instance GHC.Real.Real System.Socket.Family.Inet6.Inet6Port instance GHC.Num.Num System.Socket.Family.Inet6.Inet6Port instance GHC.Show.Show System.Socket.Family.Inet6.Inet6Port instance GHC.Classes.Ord System.Socket.Family.Inet6.Inet6Port instance GHC.Classes.Eq System.Socket.Family.Inet6.Inet6Port instance GHC.Classes.Eq System.Socket.Family.Inet6.Inet6Address instance GHC.Show.Show (System.Socket.Internal.Socket.SocketAddress System.Socket.Family.Inet6.Inet6) instance GHC.Classes.Eq (System.Socket.Internal.Socket.SocketAddress System.Socket.Family.Inet6.Inet6) instance System.Socket.Internal.SocketOption.SocketOption System.Socket.Family.Inet6.V6Only instance System.Socket.Internal.Socket.Family System.Socket.Family.Inet6.Inet6 instance Foreign.Storable.Storable System.Socket.Family.Inet6.Inet6ScopeId instance Foreign.Storable.Storable System.Socket.Family.Inet6.Inet6FlowInfo instance Foreign.Storable.Storable System.Socket.Family.Inet6.Inet6Port instance GHC.Show.Show System.Socket.Family.Inet6.Inet6Address instance Foreign.Storable.Storable System.Socket.Family.Inet6.Inet6Address instance Foreign.Storable.Storable (System.Socket.Internal.Socket.SocketAddress System.Socket.Family.Inet6.Inet6) module System.Socket.Protocol.Default data Default instance System.Socket.Internal.Socket.Protocol System.Socket.Protocol.Default.Default module System.Socket.Protocol.TCP data TCP -- | If set to True, disable the Nagle's algorithm. -- --
-- {-# LANGUAGE OverloadedStrings #-}
-- module Main where
--
-- import Control.Exception ( bracket, catch )
-- import Control.Monad ( forever )
--
-- import System.Socket
-- import System.Socket.Family.Inet6
-- import System.Socket.Type.Stream
-- import System.Socket.Protocol.TCP
--
-- main :: IO ()
-- main = bracket
-- ( socket :: IO (Socket Inet6 Stream TCP) )
-- ( \s-> do
-- close s
-- putStrLn "Listening socket closed."
-- )
-- ( \s-> do
-- setSocketOption s (ReuseAddress True)
-- setSocketOption s (V6Only False)
-- bind s (SocketAddressInet6 inet6Any 8080 0 0)
-- listen s 5
-- putStrLn "Listening socket ready..."
-- forever $ acceptAndHandle s `catch` \e-> print (e :: SocketException)
-- )
--
-- acceptAndHandle :: Socket Inet6 Stream TCP -> IO ()
-- acceptAndHandle s = bracket
-- ( accept s )
-- ( \(p, addr)-> do
-- close p
-- putStrLn $ "Closed connection to " ++ show addr
-- )
-- ( \(p, addr)-> do
-- putStrLn $ "Accepted connection from " ++ show addr
-- sendAll p "Hello world!" msgNoSignal
-- )
--
module System.Socket
-- | A generic socket type. Use socket to create a new socket.
--
-- The socket is just an MVar-wrapped file descriptor. The
-- Socket constructor is exported trough the unsafe module in
-- order to make this library easily extensible, but it is usually not
-- necessary nor advised to work directly on the file descriptor. If you
-- do, the following rules must be obeyed:
--
--
-- SocketAddressInet inetLoopback 8080 :: SocketAddress Inet
-- SocketAddressInet6 inet6Loopback 8080 0 0 :: SocketAddress Inet6
--
data family SocketAddress f;
}
-- | The number designating this Family on the specific platform.
-- This method is only exported for implementing extension libraries.
--
-- This function shall yield the values of constants like
-- AF_INET, AF_INET6 etc.
familyNumber :: Family f => f -> CInt
-- | The Type determines properties of the transport layer and the
-- semantics of basic socket operations.
--
-- The instances supplied by this library are Raw (no transport
-- layer), Stream (for unframed binary streams, e.g. TCP),
-- Datagram (for datagrams of limited length, e.g. UDP) and
-- SequentialPacket (for framed messages of arbitrary length, e.g.
-- SCTP).
class Type t
-- | This number designates this Type on the specific platform. This
-- method is only exported for implementing extension libraries.
--
-- The function shall yield the values of constants like
-- SOCK_STREAM, SOCK_DGRAM etc.
typeNumber :: Type t => t -> CInt
-- | The Protocol determines the transport protocol to use.
--
-- Use Default to let the operating system choose a transport
-- protocol compatible with the socket's Type.
class Protocol p
-- | This number designates this Protocol on the specific platform.
-- This method is only exported for implementing extension libraries.
--
-- The function shall yield the values of constants like
-- IPPROTO_TCP, IPPROTO_UDP etc.
protocolNumber :: Protocol p => p -> CInt
-- | Creates a new socket.
--
-- Whereas the underlying POSIX socket operation takes 3 parameters, this
-- library encodes this information in the type variables. This rules out
-- several kinds of errors and especially simplifies the handling of
-- addresses (by using associated data families). Examples:
--
-- -- -- create an IPv4-UDP-datagram socket -- sock <- socket :: IO (Socket Inet Datagram UDP) -- -- create an IPv6-TCP-streaming socket -- sock6 <- socket :: IO (Socket Inet6 Stream TCP) -- -- create an IPv6-streaming socket with default protocol (usually TCP) -- sock6 <- socket :: IO (Socket Inet6 Strem Default) ---- --
-- result <- bracket (socket :: IO (Socket Inet6 Stream TCP)) close $ \sock-> do -- somethingWith sock -- your computation here -- return somethingelse ---- --
-- > (socket :: IO (Socket Inet Stream TCP)) >>= getAddress
-- SocketAddressInet {inetAddress = InetAddress 0.0.0.0, inetPort = InetPort 0}
--
--
--
-- getAddressInfo (Just "www.haskell.org") (Just "https") mempty :: IO [AddressInfo Inet Stream TCP]
-- > [AddressInfo {addressInfoFlags = AddressInfoFlags 0, socketAddress = SocketAddressInet {inetAddress = InetAddress 162.242.239.16, inetPort = InetPort 443}, canonicalName = Nothing}]
--
--
--
-- > getAddressInfo (Just "www.haskell.org") (Just "80") aiV4Mapped :: IO [AddressInfo Inet6 Stream TCP]
-- [AddressInfo {
-- addressInfoFlags = AddressInfoFlags 8,
-- socketAddress = SocketAddressInet6 {inet6Address = Inet6Address 2400:cb00:2048:0001:0000:0000:6ca2:cc3c, inet6Port = Inet6Port 80, inet6FlowInfo = Inet6FlowInfo 0, inet6ScopeId = Inet6ScopeId 0},
-- canonicalName = Nothing }]
--
--
--
-- > getAddressInfo (Just "darcs.haskell.org") Nothing aiV4Mapped :: IO [AddressInfo Inet6 Stream TCP]
-- [AddressInfo {
-- addressInfoFlags = AddressInfoFlags 8,
-- socketAddress = SocketAddressInet6 {inet6Address = Inet6Address 0000:0000:0000:0000:0000:ffff:17fd:e1ad, inet6Port = Inet6Port 0, inet6FlowInfo = Inet6FlowInfo 0, inet6ScopeId = Inet6ScopeId 0},
-- canonicalName = Nothing }]
-- > getAddressInfo (Just "darcs.haskell.org") Nothing mempty :: IO [AddressInfo Inet6 Stream TCP]
-- *** Exception: AddressInfoException "Name or service not known"
--
getAddressInfo :: (HasAddressInfo f, Type t, Protocol p) => Maybe ByteString -> Maybe ByteString -> AddressInfoFlags -> IO [AddressInfo f t p]
-- | A NameInfo consists of host and service name.
data NameInfo
NameInfo :: ByteString -> ByteString -> NameInfo
[hostName] :: NameInfo -> ByteString
[serviceName] :: NameInfo -> ByteString
-- | This class is for address families that support reverse name
-- resolution.
class (Family f) => HasNameInfo f
-- | (Reverse-)map an address back to a human-readable host- and service
-- name.
--
-- The operation throws AddressInfoExceptions.
--
--
-- > getNameInfo (SocketAddressInet inetLoopback 80) mempty
-- NameInfo {hostName = "localhost.localdomain", serviceName = "http"}
--
getNameInfo :: HasNameInfo f => SocketAddress f -> NameInfoFlags -> IO NameInfo
-- | SocketOptions allow to read and write certain properties of a
-- socket.
--
-- -- mconcat [msgNoSignal, msgWaitAll] ---- -- Use the Bits instance to check whether a flag is set: -- --
-- if flags .&. msgEndOfRecord /= mempty then ... --newtype MessageFlags MessageFlags :: CInt -> MessageFlags -- |
-- MSG_NOSIGNAL ---- -- Suppresses the generation of PIPE signals when writing to a -- socket that is no longer connected. -- -- Although this flag is POSIX, it is not available on all platforms. Try -- --
-- msgNoSignal /= mempty ---- -- in order to check whether this flag is defined on a certain platform. -- It is safe to just use this constant even if it might not have effect -- on a certain target platform. The platform independence of this flag -- is therefore fulfilled to some extent. -- -- Some more explanation on the platform specific behaviour: -- --
-- MSG_EOR ---- -- Used by SequentialPacket to mark record boundaries. Consult the -- POSIX standard for details. -- | Warning: Untested: Use at your own risk! msgEndOfRecord :: MessageFlags -- |
-- MSG_OOB ---- -- Used to send and receive out-of-band data. Consult the relevant -- standards for details. -- | Warning: Untested: Use at your own risk! msgOutOfBand :: MessageFlags -- |
-- MSG_WAITALL ---- -- A receive call shall not return unless the requested number of -- bytes becomes available. -- | Warning: Untested: Use at your own risk! msgWaitAll :: MessageFlags -- |
-- MSG_PEEK ---- -- A receive shall not actually remove the received data from the -- input buffer. msgPeek :: MessageFlags -- | Use the Monoid instance to combine several flags: -- --
-- mconcat [aiAddressConfig, aiV4Mapped] --data AddressInfoFlags -- | AI_ADDRCONFIG: aiAddressConfig :: AddressInfoFlags -- | AI_ALL: Return both IPv4 (as v4-mapped IPv6 address) and IPv6 -- addresses when aiV4Mapped is set independent of whether IPv6 -- addresses exist for this name. aiAll :: AddressInfoFlags -- | AI_CANONNAME: aiCanonicalName :: AddressInfoFlags -- | AI_NUMERICHOST: aiNumericHost :: AddressInfoFlags -- | AI_NUMERICSERV: aiNumericService :: AddressInfoFlags -- | AI_PASSIVE: aiPassive :: AddressInfoFlags -- | AI_V4MAPPED: Return mapped IPv4 addresses if no IPv6 -- addresses could be found or if aiAll flag is set. aiV4Mapped :: AddressInfoFlags -- | Use the Monoid instance to combine several flags: -- --
-- mconcat [niNameRequired, niNoFullyQualifiedDomainName] --data NameInfoFlags -- | NI_NAMEREQD: Throw an exception if the hostname cannot be -- determined. niNameRequired :: NameInfoFlags -- | NI_DGRAM: Service is datagram based (i.e. UDP) rather -- than stream based (i.e. TCP). niDatagram :: NameInfoFlags -- | NI_NOFQDN: Return only the hostname part of the fully -- qualified domain name for local hosts. niNoFullyQualifiedDomainName :: NameInfoFlags -- | NI_NUMERICHOST: Return the numeric form of the host address. niNumericHost :: NameInfoFlags -- | NI_NUMERICSERV: Return the numeric form of the service -- address. niNumericService :: NameInfoFlags -- | Contains the error code that can be matched against. -- -- Hint: Use guards or MultiWayIf to match against specific -- exceptions: -- --
-- if | e == eAddressInUse -> ... -- | e == eAddressNotAvailable -> ... -- | otherwise -> ... --newtype SocketException SocketException :: CInt -> SocketException -- | No error. eOk :: SocketException -- | Interrupted system call. -- -- NOTE: This exception shall not be thrown by any public operation in -- this library, but is handled internally. eInterrupted :: SocketException -- | Bad file descriptor. eBadFileDescriptor :: SocketException -- | Permission denied. ePermissionDenied :: SocketException -- | Invalid argument. eInvalid :: SocketException -- | Broken pipe. ePipe :: SocketException -- | Resource temporarily unavailable. -- -- NOTE: This exception shall not be thrown by any public operation in -- this library, but is handled internally. eWouldBlock :: SocketException -- | Resource temporarily unavailable. eAgain :: SocketException -- | Socket operation on non-socket. -- -- NOTE: This should be ruled out by the type system. eNotSocket :: SocketException -- | Destination address required. eDestinationAddressRequired :: SocketException -- | Message too long. eMessageSize :: SocketException -- | Protocol wrong type for socket. eProtocolType :: SocketException -- | Protocol not available. eNoProtocolOption :: SocketException -- | Protocol not supported. eProtocolNotSupported :: SocketException -- | Socket type not supported. eSocketTypeNotSupported :: SocketException -- | Operation not supported. eOperationNotSupported :: SocketException -- | Protocol family not supported. eProtocolFamilyNotSupported :: SocketException -- | Address family not supported by protocol. eAddressFamilyNotSupported :: SocketException -- | Address already in use. eAddressInUse :: SocketException -- | Cannot assign requested address. eAddressNotAvailable :: SocketException -- | Network is down. eNetworkDown :: SocketException -- | Network is unreachable. eNetworkUnreachable :: SocketException -- | Network dropped connection on reset. eNetworkReset :: SocketException -- | Software caused connection abort. eConnectionAborted :: SocketException -- | Connection reset by peer. eConnectionReset :: SocketException -- | No buffer space available. eNoBufferSpace :: SocketException -- | Transport endpoint is already connected. eIsConnected :: SocketException -- | Transport endpoint is not connected. eNotConnected :: SocketException -- | Cannot send after transport endpoint shutdown. eShutdown :: SocketException -- | Too many references: cannot splice. eTooManyReferences :: SocketException -- | Connection timed out. eTimedOut :: SocketException -- | Connection refused. eConnectionRefused :: SocketException -- | Host is down. eHostDown :: SocketException -- | No route to host. eHostUnreachable :: SocketException -- | Operation already in progress. -- -- NOTE: This exception shall not be thrown by any public operation in -- this library, but is handled internally. eAlready :: SocketException -- | Operation now in progress eInProgress :: SocketException -- | Contains the error code that can be matched against. -- -- Hint: Use guards or MultiWayIf to match against specific -- exceptions: -- --
-- if | e == eaiFail -> ... -- | e == eaiNoName -> ... -- | otherwise -> ... --newtype AddressInfoException AddressInfoException :: CInt -> AddressInfoException -- |
-- AddressInfoException "Temporary failure in name resolution" --eaiAgain :: AddressInfoException -- |
-- AddressInfoException "Bad value for ai_flags" --eaiBadFlags :: AddressInfoException -- |
-- AddressInfoException "Non-recoverable failure in name resolution" --eaiFail :: AddressInfoException -- |
-- AddressInfoException "ai_family not supported" --eaiFamily :: AddressInfoException -- |
-- AddressInfoException "Memory allocation failure" --eaiMemory :: AddressInfoException -- |
-- AddressInfoException "No such host is known" --eaiNoName :: AddressInfoException -- |
-- AddressInfoException "ai_socktype not supported" --eaiSocketType :: AddressInfoException -- |
-- AddressInfoException "Servname not supported for ai_socktype" --eaiService :: AddressInfoException -- |
-- AddressInfoException "System error" --eaiSystem :: AddressInfoException module System.Socket.Type.Stream data Stream -- | Sends a whole ByteString with as many system calls as necessary -- and returns the bytes sent (in this case just the ByteStrings -- length). sendAll :: Socket f Stream p -> ByteString -> MessageFlags -> IO Int -- | Like sendAll, but operates on lazy ByteStrings. -- -- It uses sendAll internally to send all chunks sequentially. The -- lock on the socket is acquired for each chunk separately, so the -- socket can be read from in an interleaving fashion. sendAllLazy :: Socket f Stream p -> ByteString -> MessageFlags -> IO Int64 -- | Sends a whole Builder without allocating ByteStrings. If -- performance is an issue, this operation should be preferred over all -- other solutions for sending stream data. -- -- The operation allocates a single buffer of the given size on -- entry and reuses this buffer until the whole Builder has been -- sent. The count of all bytes sent is returned as there is no other -- efficient way to determine a Builders size without actually -- building it. sendAllBuilder :: Socket f Stream p -> Int -> Builder -> MessageFlags -> IO Int64 -- | Like receive, but operates on lazy ByteStrings and -- continues until either an empty part has been received (peer closed -- the connection) or given buffer limit has been exceeded or an -- exception occured. -- --