Safe Haskell | None |
---|---|
Language | Haskell2010 |
Socket.Stream
Contents
Synopsis
- data SendException :: Interruptibility -> Type where
- data ReceiveException :: Interruptibility -> Type where
- data ConnectException :: Family -> Interruptibility -> Type where
- ConnectFirewalled :: ConnectException d i
- ConnectFileDescriptorLimit :: ConnectException d i
- ConnectNetworkUnreachable :: ConnectException (Internet v) i
- ConnectHostUnreachable :: ConnectException (Internet v) i
- ConnectEphemeralPortsExhausted :: ConnectException d i
- ConnectRefused :: ConnectException d i
- ConnectTimeout :: ConnectException d i
- ConnectProtocolType :: ConnectException Unix i
- ConnectInterrupted :: ConnectException d Interruptible
- data SocketException :: Type where
- data AcceptException :: Interruptibility -> Type where
- data CloseException :: Type where
- newtype Connection = Connection Fd
Exceptions
data SendException :: Interruptibility -> Type where Source #
Constructors
SendShutdown :: SendException i | The local socket has already shutdown its writing channel.
Consequently, sending is no longer possible. This can happen
even if the process does not |
SendReset :: SendException i | The peer reset the connection. |
SendInterrupted :: !Int -> SendException Interruptible | STM-style interrupt (much safer than C-style interrupt).
This provides the number of bytes sent before the interrupt
happened. For |
Instances
data ReceiveException :: Interruptibility -> Type where Source #
Recoverable exceptions that can occur while receiving data on a stream socket.
Discussion
The recv man page explicitly documents these:
EAGAIN
/EAGAIN
: Not possible after using event manager to wait.EBADF
: Prevented by this library.ECONNREFUSED
: Not sure if this is possible. Currently treated as an unrecoverable exception.EFAULT
: Not recoverable. API consumer has misusedAddr
.EINTR
: Prevented by this library. Unsafe FFI is not interruptible.EINVAL
: Prevented by this library.ENOMEM
: Not recoverable.ENOTCONN
: Prevented by this library.ENOTSOCK
: Prevented by this library.
The man page includes a disclaimer: "Additional errors may be generated
and returned from the underlying protocol modules". One such error
when dealing with stream sockets in ECONNRESET
. One scenario where
this happens is when the process running on the peer terminates ungracefully
and the operating system on the peer cleans up by sending a reset.
Constructors
ReceiveShutdown :: ReceiveException i | The peer shutdown its writing channel. (zero-length chunk) |
ReceiveReset :: ReceiveException i | The peer reset the connection. ( |
ReceiveInterrupted :: !Int -> ReceiveException Interruptible | STM-style interrupt (much safer than C-style interrupt)
This provides the number of bytes received before the interrupt
happened. For |
ReceiveHostUnreachable :: ReceiveException i | The peer was unreachable. ( |
Instances
data ConnectException :: Family -> Interruptibility -> Type where Source #
Recoverable exceptions that can occur while connecting to a peer. This includes both failures while opening the socket and failures while connecting to the peer.
Discussion
In its API for connecting to a peer, this library combines the step of
creating a socket with the step of connecting to the peer. In other words,
the end user never gets access to an unconnected stream socket.
Consequently, the connection exceptions correspond to the socket
errors EMFILE
and ENFILE
as well as the connect
errors ECONNREFUSED
, EACCES
/EPERM
, ETIMEDOUT
, ENETUNREACH
, and
EADDRNOTAVAIL
.
Somewhat surprisingly, EADDRINUSE
is not included in the list of connect
error codes we recognize as recoverable. The
accept man page
describes EADDRINUSE
as "Local address is already in use". However,
it is unclear what this means. The caller of connect
does not provide
an internet socket address. If ephemeral ports are exhausted, connect
will error with EADDRNOTAVAIL
. An unresolved
Stack Overflow question
calls into question whether or not it is actually possible for this
error to happen with an internet domain socket. The author has decided
to omit any checks for it. This means that, if it does ever happen,
it will cause a SocketUnrecoverableException
to be thrown. The Linux
cognoscenti are encouraged to open an issue if they have more information
about the circumstances under which this exception can occur.
Although both the POSIX spec and the linux man page list ENETUNREACH
as an error code that is possible for any type of socket, this library
author does not believe that this error code can happen when calling
connect
on a unix domain socket. Open an issue if this in incorrect.
Constructors
ConnectFirewalled :: ConnectException d i | Either the connection was blocked by a local firewall rule or it
was blocked because it was to a broadcast address. Sadly, these
two errors are not distinguished by the Linux sockets API.
( |
ConnectFileDescriptorLimit :: ConnectException d i | A limit on the number of open file descriptors has been reached.
This could be the per-process limit or the system limit.
( |
ConnectNetworkUnreachable :: ConnectException (Internet v) i | The network is unreachable. ( |
ConnectHostUnreachable :: ConnectException (Internet v) i | No valid routing table entry matches the destination address.
( |
ConnectEphemeralPortsExhausted :: ConnectException d i | All port numbers in the ephemeral port range are currently in
use. ( |
ConnectRefused :: ConnectException d i | No one is listening on the remote address. ( |
ConnectTimeout :: ConnectException d i | Timeout while attempting connection. The server may be too busy
to accept new connections. Note that stock Linux configuration has
timeout at
appropriately 20 seconds.
Users interested in timing out more quickly are encouraged to
use |
ConnectProtocolType :: ConnectException Unix i | Remote socket does not match the local socket type. ( |
ConnectInterrupted :: ConnectException d Interruptible | STM-style interrupt (much safer than C-style interrupt) |
Instances
data SocketException :: Type where Source #
Recoverable exceptions that happen when establishing an internet-domain stream listener or datagram socket.
Discussion
The recoverable exceptions that we encounter with stream sockets (established
with socket
-bind
-listen
) and datagram sockets (established with
socket
-bind
) are the exact same exceptions. Consequently, we reuse
the same type in both case. It is a little unfortunate since the name
ListenException
would be more appropriate for stream sockets. But
the code reuse is worth the naming quibble.
Constructors
SocketPermissionDenied :: SocketException | The address is protected, and the user is not the superuser. This most
commonly happens when trying to bind to a port below 1024. On Linux,
When it is necessary to bind to such a port on Linux, consider using the
CAP_NET_BIND_SERVICE
capability instead of running the process as root. ( |
SocketAddressInUse :: SocketException | The given address is already in use. ( |
SocketEphemeralPortsExhausted :: SocketException | The port number was specified as zero, but upon attempting to
bind to an ephemeral port, it was determined that all port numbers
numbers in the ephemeral port range are currently in use.
( |
SocketFileDescriptorLimit :: SocketException | A limit on the number of open file descriptors has been reached.
This could be the per-process limit or the system limit.
( |
Instances
Show SocketException Source # | |
Defined in Socket.IPv4 Methods showsPrec :: Int -> SocketException -> ShowS # show :: SocketException -> String # showList :: [SocketException] -> ShowS # | |
Exception SocketException Source # | |
Defined in Socket.IPv4 Methods toException :: SocketException -> SomeException # |
data AcceptException :: Interruptibility -> Type where Source #
Recoverable exceptions that can occur while accepting an inbound connection.
Constructors
AcceptConnectionAborted :: AcceptException i | The peer reset the connection before the running process
accepted it. This is not typically treated as fatal. The
process may continue accepting connections. ( |
AcceptFileDescriptorLimit :: AcceptException i | A limit on the number of open file descriptors has been reached.
This could be the per-process limit or the system limit.
( |
AcceptFirewalled :: AcceptException i | Firewall rules forbid connection. ( |
AcceptInterrupted :: AcceptException Interruptible | STM-style interrupt (much safer than C-style interrupt) |
Instances
data CloseException :: Type where Source #
Constructors
ClosePeerContinuedSending :: CloseException | After the local process shut down the writing channel, it was expecting the peer to do the same. However, the peer sent more data instead. If this happens, the local process does still close the socket. However, it must send a TCP reset to accomplish this since there is still unread data in the receive buffer. This can happen if the peer is misbehaving or if the consumer
of the |
Instances
Eq CloseException Source # | |
Defined in Socket.Stream Methods (==) :: CloseException -> CloseException -> Bool # (/=) :: CloseException -> CloseException -> Bool # | |
Ord CloseException Source # | |
Defined in Socket.Stream Methods compare :: CloseException -> CloseException -> Ordering # (<) :: CloseException -> CloseException -> Bool # (<=) :: CloseException -> CloseException -> Bool # (>) :: CloseException -> CloseException -> Bool # (>=) :: CloseException -> CloseException -> Bool # max :: CloseException -> CloseException -> CloseException # min :: CloseException -> CloseException -> CloseException # | |
Show CloseException Source # | |
Defined in Socket.Stream Methods showsPrec :: Int -> CloseException -> ShowS # show :: CloseException -> String # showList :: [CloseException] -> ShowS # | |
Exception CloseException Source # | |
Defined in Socket.Stream Methods toException :: CloseException -> SomeException # |