-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | High-level network sockets -- -- This library provides a high-level abstraction for network sockets. It -- uses Haskell2010 (along with GADTs) without typeclasses to ensure that -- consumers of the API can only call appropriate functions on a socket. -- Exceptions are tracked in the types of functions and returned to the -- caller with Either. The caller is free to handle these -- gracefully or to throw them. This library only throws exceptions when -- it detects that it has misused the operating system's sockets API -- (open an issue for this) or when the caller asks for a -- negatively-sized slice of a buffer (such exceptions are unrecoverable -- and indicate a mistake in the code consuming this API). @package sockets @version 0.3.0.0 -- | Internet datagram sockets without a fixed destination. module Socket.Datagram.IPv4.Undestined -- | A connectionless datagram socket that may communicate with many -- different endpoints on a datagram-by-datagram basis. newtype Socket Socket :: Fd -> Socket -- | An endpoint for an IPv4 socket, connection, or listener. Everything is -- in host byte order, and the user is not responisble for performing any -- conversions. data Endpoint Endpoint :: !IPv4 -> !Word16 -> Endpoint [$sel:address:Endpoint] :: Endpoint -> !IPv4 [$sel:port:Endpoint] :: Endpoint -> !Word16 data Message Message :: {-# UNPACK #-} !Endpoint -> !ByteArray -> Message [remote] :: Message -> {-# UNPACK #-} !Endpoint [payload] :: Message -> !ByteArray -- | Open a socket and run the supplied callback on it. This closes the -- socket when the callback finishes or when an exception is thrown. Do -- not return the socket from the callback. This leads to undefined -- behavior. If the address 0.0.0.0 is used, the socket receives -- on all network interfaces. If the port 0 is used, an unused port is -- chosen by the operating system. The callback provides the chosen port -- (or if the user specified a non-zero port, the chosen port will be -- that value). withSocket :: Endpoint -> (Socket -> Word16 -> IO a) -> IO (Either SocketException a) -- | Send a slice of a bytearray to the specified endpoint. send :: Socket -> Endpoint -> ByteArray -> Int -> Int -> IO (Either SocketException ()) -- | Send a slice of a bytearray to the specified endpoint. sendMutableByteArraySlice :: Socket -> Endpoint -> MutableByteArray RealWorld -> Int -> Int -> IO (Either (SendException 'Uninterruptible) ()) -- | Receive a datagram into a freshly allocated bytearray. receiveByteArray :: Socket -> Int -> IO (Either (ReceiveException 'Uninterruptible) Message) -- | Receive a datagram into a mutable byte array, ignoring information -- about the remote endpoint. Returns the actual number of bytes present -- in the datagram. Precondition: buffer_length - offset >= -- max_datagram_length. receiveMutableByteArraySlice_ :: Socket -> MutableByteArray RealWorld -> Int -> Int -> IO (Either SocketException Int) -- | Receive up to the specified number of datagrams into freshly allocated -- byte arrays. When there are many datagrams present on the receive -- buffer, this is more efficient than calling receive -- repeatedly. The array is guaranteed to have at least one message. -- -- The byte arrays in the resulting messages are always pinned. receiveMany :: Socket -> Int -> Int -> IO (Either SocketException (Array Message)) -- | This has the same behavior as receiveMany. However, it also -- takes an STM action that it attempts to run while the event -- manager is waiting for the socket to be ready for a reads. If the -- supplied action finishes first, this abandons the attempt to receive -- datagrams and returns Left ReceptionAbandoned. receiveManyUnless :: STM () -> Socket -> Int -> Int -> IO (Either SocketException (Array Message)) -- | Represents any unexpected behaviors that a function working on a -- socket, connection, or listener can exhibit. data SocketException -- | The datagram did not fit in the buffer. This can happen while sending. -- The field is the size of the number of bytes in the datagram that were -- successfully copied into the send buffer. SentMessageTruncated :: !Int -> SocketException -- | The datagram did not fit in the buffer. This can happen while -- receiving. The field is the original size of the datagram that was was -- truncated while copying it into the buffer. ReceivedMessageTruncated :: !Int -> SocketException -- | The socket address was not the expected size. This exception indicates -- a bug in this library or (less likely) in the operating system. SocketAddressSize :: SocketException -- | The socket address had an unexpected family. This exception indicates -- a bug in this library or (less likely) in the operating system. The -- int argument is the actual family found in the socket address. SocketAddressFamily :: !CInt -> SocketException -- | The option value was not the expected size. This exception indicates a -- bug in this library or (less likely) in the operating system. OptionValueSize :: SocketException -- | The user requested a negative number of bytes in a call to a receive -- function. NegativeBytesRequested :: SocketException -- | This happens when the Unless variant of a function is used -- and the STM action completes before the socket is ready for a -- read. ReceptionAbandoned :: SocketException -- | The remote end sent more data when it was expected to send a shutdown. RemoteNotShutdown :: SocketException -- | The remote end has shutdown its side of the full-duplex connection. -- This can happen receive is called on a stream socket. This is -- not necessarily a bad thing. Many protocols use shutdown to indicate -- that no more data is available. These protocols can be contrasted with -- protocols that send a length representing a number of expected bytes. RemoteShutdown :: SocketException -- | Any error code from the operating system that this library does not -- expect or recognize. Consult your operating system manual for details -- about the error code. ErrorCode :: !CInt -> SocketException -- | Internet datagram sockets without a fixed destination. The user may -- spoof the source address and may specify the packet ID. An application -- must have CAP_NET_RAW or be running as root to use the -- functions in this module. module Socket.Datagram.IPv4.Spoof -- | A socket that send datagrams with spoofed source IP addresses. It -- cannot receive datagrams. newtype Socket Socket :: Fd -> Socket -- | An endpoint for an IPv4 socket, connection, or listener. Everything is -- in host byte order, and the user is not responisble for performing any -- conversions. data Endpoint Endpoint :: !IPv4 -> !Word16 -> Endpoint [$sel:address:Endpoint] :: Endpoint -> !IPv4 [$sel:port:Endpoint] :: Endpoint -> !Word16 data Message Message :: {-# UNPACK #-} !Endpoint -> !ByteArray -> Message [remote] :: Message -> {-# UNPACK #-} !Endpoint [payload] :: Message -> !ByteArray -- | Open a socket and run the supplied callback on it. This closes the -- socket when the callback finishes or when an exception is thrown. Do -- not return the socket from the callback. This leads to undefined -- behavior. The user cannot specify an endpoint since the socket cannot -- receive traffic. withSocket :: (Socket -> IO a) -> IO (Either SocketException a) -- | Send a slice of a bytearray to the specified endpoint. sendMutableByteArray :: Socket -> Endpoint -> Endpoint -> MutableByteArray RealWorld -> Int -> Int -> IO (Either (SendException 'Uninterruptible) ()) data SocketException :: Type -- | Permission to create a raw socket was denied. The process needs the -- capability CAP_NET_RAW, or it must be run as root. [SocketPermissionDenied] :: SocketException -- | A limit on the number of open file descriptors has been reached. This -- could be the per-process limit or the system limit. (EMFILE -- and ENFILE) [SocketFileDescriptorLimit] :: SocketException data SendException :: Interruptibility -> Type -- | The datagram did not fit in the buffer. The field is the number of -- bytes that were successfully copied into the send buffer. The datagram -- does still get sent when this happens. [SendTruncated] :: !Int -> SendException i -- | Attempted to send to a broadcast address. [SendBroadcasted] :: SendException i -- | STM-style interrupt (much safer than C-style interrupt) [SendInterrupted] :: SendException 'Interruptible instance GHC.Show.Show Socket.Datagram.IPv4.Spoof.Socket instance GHC.Classes.Ord Socket.Datagram.IPv4.Spoof.Socket instance GHC.Classes.Eq Socket.Datagram.IPv4.Spoof.Socket instance GHC.Show.Show Socket.Datagram.IPv4.Spoof.SocketException instance GHC.Exception.Type.Exception Socket.Datagram.IPv4.Spoof.SocketException module Socket.Stream.IPv4 -- | A socket that listens for incomming connections. data Listener -- | A connection-oriented stream socket. data Connection -- | An endpoint for an IPv4 socket, connection, or listener. Everything is -- in host byte order, and the user is not responisble for performing any -- conversions. data Endpoint Endpoint :: !IPv4 -> !Word16 -> Endpoint [$sel:address:Endpoint] :: Endpoint -> !IPv4 [$sel:port:Endpoint] :: Endpoint -> !Word16 withListener :: Endpoint -> (Listener -> Word16 -> IO a) -> IO (Either SocketException a) -- | Accept a connection on the listener and run the supplied callback on -- it. This closes the connection when the callback finishes or if an -- exception is thrown. Since this function blocks the thread until the -- callback finishes, it is only suitable for stream socket clients that -- handle one connection at a time. The variant -- forkAcceptedUnmasked is preferrable for servers that need to -- handle connections concurrently (most use cases). withAccepted :: Listener -> (Either CloseException () -> a -> IO b) -> (Connection -> Endpoint -> IO a) -> IO (Either (AcceptException 'Uninterruptible) b) -- | Establish a connection to a server. withConnection :: Endpoint -> (Either CloseException () -> a -> IO b) -> (Connection -> IO a) -> IO (Either (ConnectException 'Uninterruptible) b) -- | Accept a connection on the listener and run the supplied callback in a -- new thread. Prefer forkAcceptedUnmasked unless the masking -- state needs to be preserved for the callback. Such a situation seems -- unlikely to the author. forkAccepted :: Listener -> (Either CloseException () -> a -> IO ()) -> (Connection -> Endpoint -> IO a) -> IO (Either (AcceptException 'Uninterruptible) ThreadId) -- | Accept a connection on the listener and run the supplied callback in a -- new thread. The masking state is set to Unmasked when running -- the callback. Typically, a is instantiated to (). forkAcceptedUnmasked :: Listener -> (Either CloseException () -> a -> IO ()) -> (Connection -> Endpoint -> IO a) -> IO (Either (AcceptException 'Uninterruptible) ThreadId) -- | Accept a connection on the listener and run the supplied callback in a -- new thread. The masking state is set to Unmasked when running -- the callback. Typically, a is instantiated to (). -- --
-- (isReady,deregister) <- threadWaitReadSTM fd -- shouldReceive <- atomically $ do -- readTVar abandon >>= \case -- True -> do -- isReady -- modifyTVar' counter (+1) -- pure True -- False -> pure False ---- -- This eliminates the window for the race condition. If a connection is -- accepted, the counter is guaranteed to be incremented _before_ -- abandon becomes True. However, this code would be -- more simple and would perform better if GHC's event manager used TVar -- instead of STM. interruptibleForkAcceptedUnmasked :: TVar Int -> TVar Bool -> Listener -> (Either CloseException () -> a -> IO ()) -> (Connection -> Endpoint -> IO a) -> IO (Either (AcceptException 'Interruptible) ThreadId) sendByteArray :: Connection -> ByteArray -> IO (Either (SendException 'Uninterruptible) ()) sendByteArraySlice :: Connection -> ByteArray -> Int -> Int -> IO (Either (SendException 'Uninterruptible) ()) sendMutableByteArray :: Connection -> MutableByteArray RealWorld -> IO (Either (SendException 'Uninterruptible) ()) sendMutableByteArraySlice :: Connection -> MutableByteArray RealWorld -> Int -> Int -> IO (Either (SendException 'Uninterruptible) ()) interruptibleSendByteArray :: TVar Bool -> Connection -> ByteArray -> IO (Either (SendException 'Interruptible) ()) interruptibleSendByteArraySlice :: TVar Bool -> Connection -> ByteArray -> Int -> Int -> IO (Either (SendException 'Interruptible) ()) interruptibleSendMutableByteArraySlice :: TVar Bool -> Connection -> MutableByteArray RealWorld -> Int -> Int -> IO (Either (SendException 'Interruptible) ()) -- | Receive exactly the given number of bytes. If the remote application -- shuts down its end of the connection before sending the required -- number of bytes, this returns Left -- ReceiveShutdown. receiveByteArray :: Connection -> Int -> IO (Either (ReceiveException 'Uninterruptible) ByteArray) -- | Receive up to the given number of bytes. If the remote application -- shuts down its end of the connection instead of sending any bytes, -- this returns Left (SocketException Receive -- RemoteShutdown). receiveBoundedByteArray :: Connection -> Int -> IO (Either (ReceiveException 'Uninterruptible) ByteArray) -- | Receive up to the given number of bytes, using the given array and -- starting at the given offset. receiveBoundedMutableByteArraySlice :: Connection -> Int -> MutableByteArray RealWorld -> Int -> IO (Either (ReceiveException 'Uninterruptible) Int) -- | Receive a number of bytes exactly equal to the size of the mutable -- byte array. If the remote application shuts down its end of the -- connection before sending the required number of bytes, this returns -- Left (SocketException Receive -- RemoteShutdown). receiveMutableByteArray :: Connection -> MutableByteArray RealWorld -> IO (Either (ReceiveException 'Uninterruptible) ()) -- | Variant of receiveByteArray that support STM-style interrupts. interruptibleReceiveByteArray :: TVar Bool -> Connection -> Int -> IO (Either (ReceiveException 'Interruptible) ByteArray) -- | Receive up to the given number of bytes, using the given array and -- starting at the given offset. This can be interrupted by the -- completion of an STM transaction. interruptibleReceiveBoundedMutableByteArraySlice :: TVar Bool -> Connection -> Int -> MutableByteArray RealWorld -> Int -> IO (Either (ReceiveException 'Interruptible) Int) data SendException :: Interruptibility -> Type -- | The local socket has already shutdown its writing channel. -- Consequently, sending is no longer possible. This can happen even if -- the process does not shutdown the socket. If the peer decides -- to close the connection, the local operating system will -- shutdown both the reading and writing channels. (EPIPE) [SendShutdown] :: SendException i -- | The peer reset the connection. [SendReset] :: SendException i -- | STM-style interrupt (much safer than C-style interrupt) [SendInterrupted] :: SendException 'Interruptible -- | Recoverable exceptions that can occur while receiving data on a stream -- socket. -- --