sockets-0.4.0.0: High-level network sockets

Safe HaskellNone
LanguageHaskell2010

Socket.Stream

Contents

Synopsis

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 shutdown the socket. If the peer decides to close the connection, the local operating system will shutdown both the reading and writing channels. (EPIPE)

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 sendOnce, this will always be zero, but for send, it may be any non-negative number less than the number of bytes the caller intended to send.

data ReceiveException :: Interruptibility -> Type where Source #

Recoverable exceptions that can occur while receiving data on a stream socket.

Discussion

Expand

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 misused Addr.
  • 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. (ECONNRESET)

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 receiveOnce, this will always be zero, but for receiveExactly and receiveBetween, it may be any non-negative number less than the number of bytes the caller intended to receive.

ReceiveHostUnreachable :: ReceiveException i

The peer was unreachable. (EHOSTUNREACH)

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

Expand

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. (EACCES/EPERM)

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. (EMFILE and ENFILE)

ConnectNetworkUnreachable :: ConnectException (Internet v) i

The network is unreachable. (ENETUNREACH)

ConnectHostUnreachable :: ConnectException (Internet v) i

No valid routing table entry matches the destination address. (EHOSTUNREACH)

ConnectEphemeralPortsExhausted :: ConnectException d i

All port numbers in the ephemeral port range are currently in use. (EADDRNOTAVAIL).

ConnectRefused :: ConnectException d i

No one is listening on the remote address. (ECONNREFUSED)

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 registerDelay with the interruptible variants of the connection functions in this library. (ETIMEDOUT)

ConnectProtocolType :: ConnectException Unix i

Remote socket does not match the local socket type. (EPROTOTYPE)

ConnectInterrupted :: ConnectException d Interruptible

STM-style interrupt (much safer than C-style interrupt)

data SocketException :: Type where Source #

Recoverable exceptions that happen when establishing an internet-domain stream listener or datagram socket.

Discussion

Expand

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. (EACCES)

SocketAddressInUse :: SocketException

The given address is already in use. (EADDRINUSE with specified port)

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. (EADDRINUSE with unspecified port)

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. (EMFILE and ENFILE)

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. (ECONNABORTED)

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. (EMFILE and ENFILE)

AcceptFirewalled :: AcceptException i

Firewall rules forbid connection. (EPERM)

AcceptInterrupted :: AcceptException Interruptible

STM-style interrupt (much safer than C-style interrupt)

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 sockets API has incorrectly implemented a protocol living above layer 4 of the OSI model.

Connection

newtype Connection Source #

A connection-oriented stream socket.

Constructors

Connection Fd