-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | TCP instantiation of Network.Transport
--   
--   TCP instantiation of Network.Transport
@package network-transport-tcp
@version 0.5.1


-- | Utility functions for TCP sockets
module Network.Transport.TCP.Internal

-- | Start a server at the specified address.
--   
--   This sets up a server socket for the specified host and port.
--   Exceptions thrown during setup are not caught.
--   
--   Once the socket is created we spawn a new thread which repeatedly
--   accepts incoming connections and executes the given request handler.
--   If any exception occurs the thread terminates and calls the
--   terminationHandler. This exception may occur because of a call to
--   <a>accept</a>, because the thread was explicitly killed, or because of
--   a synchronous exception thrown by the request handler. Typically, you
--   should avoid the last case by catching any relevant exceptions in the
--   request handler.
--   
--   The request handler should spawn threads to handle each individual
--   request or the server will block. Once a thread has been spawned it
--   will be the responsibility of the new thread to close the socket when
--   an exception occurs.
--   
--   The return value includes the port was bound to. This is not always
--   the same port as that given in the argument. For example, binding to
--   port 0 actually binds to a random port, selected by the OS.
forkServer :: HostName -> ServiceName -> Int -> Bool -> (SomeException -> IO ()) -> (Socket -> IO ()) -> IO (ServiceName, ThreadId)

-- | Read a length and then a payload of that length
recvWithLength :: Socket -> IO [ByteString]

-- | Read an exact number of bytes from a socket
--   
--   Throws an I/O exception if the socket closes before the specified
--   number of bytes could be read
recvExact :: Socket -> Int32 -> IO [ByteString]

-- | Receive a 32-bit integer
recvInt32 :: Num a => Socket -> IO a

-- | Close a socket, ignoring I/O exceptions
tryCloseSocket :: Socket -> IO ()


-- | TCP implementation of the transport layer.
--   
--   The TCP implementation guarantees that only a single TCP connection
--   (socket) will be used between endpoints, provided that the addresses
--   specified are canonical. If <i>A</i> connects to <i>B</i> and reports
--   its address as <tt>192.168.0.1:8080</tt> and <i>B</i> subsequently
--   connects tries to connect to <i>A</i> as
--   <tt>client1.local:http-alt</tt> then the transport layer will not
--   realize that the TCP connection can be reused.
--   
--   Applications that use the TCP transport should use
--   <a>withSocketsDo</a> in their main function for Windows compatibility
--   (see <a>Network.Socket</a>).
module Network.Transport.TCP

-- | Create a TCP transport
createTransport :: HostName -> ServiceName -> TCPParameters -> IO (Either IOException Transport)

-- | Parameters for setting up the TCP transport
data TCPParameters
TCPParameters :: Int -> Bool -> Bool -> Bool -> Bool -> Maybe Int -> Maybe Int -> TCPParameters

-- | Backlog for <tt>listen</tt>. Defaults to SOMAXCONN.
[tcpBacklog] :: TCPParameters -> Int

-- | Should we set SO_REUSEADDR on the server socket? Defaults to True.
[tcpReuseServerAddr] :: TCPParameters -> Bool

-- | Should we set SO_REUSEADDR on client sockets? Defaults to True.
[tcpReuseClientAddr] :: TCPParameters -> Bool

-- | Should we set TCP_NODELAY on connection sockets? Defaults to True.
[tcpNoDelay] :: TCPParameters -> Bool

-- | Value of TCP_USER_TIMEOUT in milliseconds
[tcpKeepAlive] :: TCPParameters -> Bool

-- | Should we set TCP_KEEPALIVE on connection sockets?
[tcpUserTimeout] :: TCPParameters -> Maybe Int

-- | A connect timeout for all <a>connect</a> calls of the transport in
--   microseconds
--   
--   This can be overriden for each connect call with
--   'ConnectHints'.'connectTimeout'.
[transportConnectTimeout] :: TCPParameters -> Maybe Int

-- | Default TCP parameters
defaultTCPParameters :: TCPParameters

-- | You should probably not use this function (used for unit testing only)
createTransportExposeInternals :: HostName -> ServiceName -> TCPParameters -> IO (Either IOException (Transport, TransportInternals))

-- | Internal functionality we expose for unit testing
data TransportInternals
TransportInternals :: ThreadId -> (EndPointAddress -> EndPointAddress -> IO Socket) -> TransportInternals

-- | The ID of the thread that listens for new incoming connections
[transportThread] :: TransportInternals -> ThreadId

-- | Find the socket between a local and a remote endpoint
[socketBetween] :: TransportInternals -> EndPointAddress -> EndPointAddress -> IO Socket

-- | Local identifier for an endpoint within this transport
type EndPointId = Word32

-- | Encode end point address
encodeEndPointAddress :: HostName -> ServiceName -> EndPointId -> EndPointAddress

-- | Decode end point address
decodeEndPointAddress :: EndPointAddress -> Maybe (HostName, ServiceName, EndPointId)

-- | Control headers
data ControlHeader

-- | Tell the remote endpoint that we created a new connection
CreatedNewConnection :: ControlHeader

-- | Tell the remote endpoint we will no longer be using a connection
CloseConnection :: ControlHeader

-- | Request to close the connection (see module description)
CloseSocket :: ControlHeader

-- | Message sent to probe a socket
ProbeSocket :: ControlHeader

-- | Acknowledgement of the ProbeSocket message
ProbeSocketAck :: ControlHeader

-- | Response sent by <i>B</i> to <i>A</i> when <i>A</i> tries to connect
data ConnectionRequestResponse

-- | <i>B</i> accepts the connection
ConnectionRequestAccepted :: ConnectionRequestResponse

-- | <i>A</i> requested an invalid endpoint
ConnectionRequestInvalid :: ConnectionRequestResponse

-- | <i>A</i>s request crossed with a request from <i>B</i> (see protocols)
ConnectionRequestCrossed :: ConnectionRequestResponse

-- | We reserve a bunch of connection IDs for control messages
firstNonReservedLightweightConnectionId :: LightweightConnectionId

-- | We reserve some connection IDs for special heavyweight connections
firstNonReservedHeavyweightConnectionId :: HeavyweightConnectionId

-- | Establish a connection to a remote endpoint
--   
--   Maybe throw a TransportError
socketToEndPoint :: EndPointAddress -> EndPointAddress -> Bool -> Bool -> Bool -> Maybe Int -> Maybe Int -> IO (Either (TransportError ConnectErrorCode) (Socket, ConnectionRequestResponse))

-- | Lightweight connection ID (sender allocated)
--   
--   A ConnectionId is the concentation of a <a>HeavyweightConnectionId</a>
--   and a <a>LightweightConnectionId</a>.
type LightweightConnectionId = Word32
instance GHC.Show.Show Network.Transport.TCP.ConnectionRequestResponse
instance GHC.Enum.Bounded Network.Transport.TCP.ConnectionRequestResponse
instance GHC.Enum.Enum Network.Transport.TCP.ConnectionRequestResponse
instance GHC.Show.Show Network.Transport.TCP.ControlHeader
instance GHC.Enum.Bounded Network.Transport.TCP.ControlHeader
instance GHC.Enum.Enum Network.Transport.TCP.ControlHeader
instance GHC.Show.Show Network.Transport.TCP.RequestedBy
instance GHC.Classes.Eq Network.Transport.TCP.RequestedBy
