ouroboros-network-framework
Safe HaskellNone
LanguageHaskell2010

Ouroboros.Network.Snocket

Synopsis

Snocket Interface

newtype Accept (m :: Type -> Type) fd addr Source #

Named pipes and Berkeley sockets have different API when accepting a connection. For named pipes the file descriptor created by createNamedPipe is supposed to be used for the first connected client. Named pipe accept loop looks this way:

acceptLoop k = do
  h <- createNamedPipe name
  connectNamedPipe h
  -- h is now in connected state
  forkIO (k h)
  acceptLoop k

For Berkeley sockets equivalent loop starts by creating a socket which accepts connections and accept returns a new socket in connected state

acceptLoop k = do
    s <- socket ...
    bind s address
    listen s
    loop s
  where
    loop s = do
      (s' , _addr') <- accept s
      -- s' is in connected state
      forkIO (k s')
      loop s

To make common API for both we use a recursive type Accept, see berkeleyAccept below. Creation of a socket / named pipe is part of Snocket, but this means we need to have different recursion step for named pipe & sockets. For sockets its recursion step will always return accept syscall; for named pipes the first callback will reuse the file descriptor created by open and only subsequent calls will create a new file descriptor by createNamedPipe, see namedPipeSnocket.

Constructors

Accept 

Fields

Instances

Instances details
Functor m => Bifunctor (Accept m) Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Methods

bimap :: (a -> b) -> (c -> d) -> Accept m a c -> Accept m b d #

first :: (a -> b) -> Accept m a c -> Accept m b c #

second :: (b -> c) -> Accept m a b -> Accept m a c #

Functor m => Functor (Accept m fd) Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Methods

fmap :: (a -> b) -> Accept m fd a -> Accept m fd b #

(<$) :: a -> Accept m fd b -> Accept m fd a #

data Accepted fd addr where Source #

Constructors

AcceptFailure :: forall fd addr. !SomeException -> Accepted fd addr 
Accepted :: forall fd addr. !fd -> !addr -> Accepted fd addr 

Instances

Instances details
Bifoldable Accepted Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Methods

bifold :: Monoid m => Accepted m m -> m #

bifoldMap :: Monoid m => (a -> m) -> (b -> m) -> Accepted a b -> m #

bifoldr :: (a -> c -> c) -> (b -> c -> c) -> c -> Accepted a b -> c #

bifoldl :: (c -> a -> c) -> (c -> b -> c) -> c -> Accepted a b -> c #

Bifunctor Accepted Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Methods

bimap :: (a -> b) -> (c -> d) -> Accepted a c -> Accepted b d #

first :: (a -> b) -> Accepted a c -> Accepted b c #

second :: (b -> c) -> Accepted a b -> Accepted a c #

Functor (Accepted fd) Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Methods

fmap :: (a -> b) -> Accepted fd a -> Accepted fd b #

(<$) :: a -> Accepted fd b -> Accepted fd a #

data AddressFamily addr where Source #

We support either sockets or named pipes.

There are three families of addresses: SocketFamily used for Berkeley sockets, LocalFamily used for LocalAddresses (either Unix sockets or Windows named pipe addresses), and TestFamily for testing purposes.

LocalFamily requires LocalAddress, this is needed to provide path of the opened Win32 HANDLE.

Constructors

SocketFamily :: !Family -> AddressFamily SockAddr 
LocalFamily :: !LocalAddress -> AddressFamily LocalAddress 
TestFamily :: forall addr1. AddressFamily (TestAddress addr1)

Using a newtype wrapper TestAddress makes pattern matches on AddressFamily complete, e.g. it makes AddressFamily injective: AddressFamily addr == AddressFamily addr' then addr == addr'. .

Instances

Instances details
Show addr => Show (AddressFamily addr) Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Methods

showsPrec :: Int -> AddressFamily addr -> ShowS #

show :: AddressFamily addr -> String #

showList :: [AddressFamily addr] -> ShowS #

Eq addr => Eq (AddressFamily addr) Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Methods

(==) :: AddressFamily addr -> AddressFamily addr -> Bool #

(/=) :: AddressFamily addr -> AddressFamily addr -> Bool #

data Snocket (m :: Type -> Type) fd addr Source #

Abstract communication interface that can be used by more than Socket. Snockets are polymorphic over monad which is used, this feature is useful for testing and/or simulations.

Constructors

Snocket 

Fields

  • getLocalAddr :: fd -> m addr

    Get local address of a file descriptor.

    For Berkeley sockets: getSocketName is used.

    For named pipes: a file name is returned which was used when the file descriptor was opened.

  • getRemoteAddr :: fd -> m addr

    Get remote address of a file descriptor.

    For Berkeley sockets: getPeerName is used.

    For named pipes: either an empty string (open) or file name (openToConnect) which was used to open the file descriptor is returned.

  • addrFamily :: addr -> AddressFamily addr

    Get address family of an address.

  • open :: AddressFamily addr -> m fd

    Open a file descriptor (socket / namedPipe).

    For Berkeley sockets: socket is used.

    For named pipes: createNamedPipe is used.

  • openToConnect :: addr -> m fd

    A way to create fd to pass to connect.

    For Berkeley sockets: this the same as open.

    For named pipes: it will use CreateFile syscall.

    NOTE: For named pipes, one must pass the LocalAddress of the named pipe to connect to. This call will open this file as required by the semantics of named pipes.

  • connect :: fd -> addr -> m ()

    connect is only needed for Berkeley sockets, for named pipes it is no-op.

  • bind :: fd -> addr -> m ()

    bind is only needed for Berkeley sockets, for named pipes it is no-op.

  • listen :: fd -> m ()

    listen is only needed for Berkeley sockets, for named pipes it is no-op.

  • accept :: fd -> m (Accept m fd addr)

    Accept loop for Berkeley sockets and named pipes.

    For Berkeley sockets: calling runAccept calls accept, while accept just returns Accept without any IO.

    For named pipes: accept calls connectNamedPipe on the file descriptor passed to it; then each subsequent runAccept creates a new file descriptor and calls ConnectNamedPipe on it.

  • close :: fd -> m ()

    Close a file descriptor opened with open or openToConnect.

Socket based Snockets

socketSnocket Source #

Arguments

:: IOManager

IOManager interface. We use it when we create a new socket and when we accept a connection.

Though it could be used in open, but that is going to be used in a bracket so it's better to keep it simple.

-> SocketSnocket 

Create a Snocket for the given Family. In the bind method set ReuseAddr and ReusePort.

Local Snockets

type LocalSnocket = Snocket IO LocalSocket LocalAddress Source #

System dependent LocalSnocket

localSnocket :: IOManager -> LocalSnocket Source #

Create a LocalSnocket.

On Windows, there is no way to get path associated to a named pipe. To go around this, the address passed to open via LocalFamily will be referenced by LocalSocket.

newtype LocalSocket Source #

System dependent LocalSnocket type

Constructors

LocalSocket 

Fields

Instances

Instances details
Generic LocalSocket Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Associated Types

type Rep LocalSocket 
Instance details

Defined in Ouroboros.Network.Snocket

Show LocalSocket Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Eq LocalSocket Source # 
Instance details

Defined in Ouroboros.Network.Snocket

type Rep LocalSocket Source # 
Instance details

Defined in Ouroboros.Network.Snocket

newtype LocalAddress Source #

Local address, on Unix is associated with AF_UNIX family, on

Windows with `named-pipes`.

Constructors

LocalAddress 

Instances

Instances details
Generic LocalAddress Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Associated Types

type Rep LocalAddress 
Instance details

Defined in Ouroboros.Network.Snocket

type Rep LocalAddress = D1 ('MetaData "LocalAddress" "Ouroboros.Network.Snocket" "ouroboros-network-framework-0.14.0.0-inplace" 'True) (C1 ('MetaCons "LocalAddress" 'PrefixI 'True) (S1 ('MetaSel ('Just "getFilePath") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 FilePath)))
Show LocalAddress Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Eq LocalAddress Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Ord LocalAddress Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Hashable LocalAddress Source # 
Instance details

Defined in Ouroboros.Network.Snocket

type Rep LocalAddress Source # 
Instance details

Defined in Ouroboros.Network.Snocket

type Rep LocalAddress = D1 ('MetaData "LocalAddress" "Ouroboros.Network.Snocket" "ouroboros-network-framework-0.14.0.0-inplace" 'True) (C1 ('MetaCons "LocalAddress" 'PrefixI 'True) (S1 ('MetaSel ('Just "getFilePath") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 FilePath)))

newtype TestAddress addr Source #

Constructors

TestAddress 

Fields

Instances

Instances details
NFData addr => NFData (TestAddress addr) Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Methods

rnf :: TestAddress addr -> () #

Generic (TestAddress addr) Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Associated Types

type Rep (TestAddress addr) 
Instance details

Defined in Ouroboros.Network.Snocket

type Rep (TestAddress addr) = D1 ('MetaData "TestAddress" "Ouroboros.Network.Snocket" "ouroboros-network-framework-0.14.0.0-inplace" 'True) (C1 ('MetaCons "TestAddress" 'PrefixI 'True) (S1 ('MetaSel ('Just "getTestAddress") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 addr)))

Methods

from :: TestAddress addr -> Rep (TestAddress addr) x #

to :: Rep (TestAddress addr) x -> TestAddress addr #

Show addr => Show (TestAddress addr) Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Methods

showsPrec :: Int -> TestAddress addr -> ShowS #

show :: TestAddress addr -> String #

showList :: [TestAddress addr] -> ShowS #

Eq addr => Eq (TestAddress addr) Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Methods

(==) :: TestAddress addr -> TestAddress addr -> Bool #

(/=) :: TestAddress addr -> TestAddress addr -> Bool #

Ord addr => Ord (TestAddress addr) Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Methods

compare :: TestAddress addr -> TestAddress addr -> Ordering #

(<) :: TestAddress addr -> TestAddress addr -> Bool #

(<=) :: TestAddress addr -> TestAddress addr -> Bool #

(>) :: TestAddress addr -> TestAddress addr -> Bool #

(>=) :: TestAddress addr -> TestAddress addr -> Bool #

max :: TestAddress addr -> TestAddress addr -> TestAddress addr #

min :: TestAddress addr -> TestAddress addr -> TestAddress addr #

Hashable addr => Hashable (TestAddress addr) Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Methods

hashWithSalt :: Int -> TestAddress addr -> Int #

hash :: TestAddress addr -> Int #

Typeable addr => NoThunks (TestAddress addr) Source # 
Instance details

Defined in Ouroboros.Network.Snocket

type Rep (TestAddress addr) Source # 
Instance details

Defined in Ouroboros.Network.Snocket

type Rep (TestAddress addr) = D1 ('MetaData "TestAddress" "Ouroboros.Network.Snocket" "ouroboros-network-framework-0.14.0.0-inplace" 'True) (C1 ('MetaCons "TestAddress" 'PrefixI 'True) (S1 ('MetaSel ('Just "getTestAddress") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 addr)))

data FileDescriptor Source #

Socket file descriptor.

Instances

Instances details
Generic FileDescriptor Source # 
Instance details

Defined in Ouroboros.Network.Snocket

Associated Types

type Rep FileDescriptor 
Instance details

Defined in Ouroboros.Network.Snocket

type Rep FileDescriptor = D1 ('MetaData "FileDescriptor" "Ouroboros.Network.Snocket" "ouroboros-network-framework-0.14.0.0-inplace" 'True) (C1 ('MetaCons "FileDescriptor" 'PrefixI 'True) (S1 ('MetaSel ('Just "getFileDescriptor") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int)))
Show FileDescriptor Source # 
Instance details

Defined in Ouroboros.Network.Snocket

type Rep FileDescriptor Source # 
Instance details

Defined in Ouroboros.Network.Snocket

type Rep FileDescriptor = D1 ('MetaData "FileDescriptor" "Ouroboros.Network.Snocket" "ouroboros-network-framework-0.14.0.0-inplace" 'True) (C1 ('MetaCons "FileDescriptor" 'PrefixI 'True) (S1 ('MetaSel ('Just "getFileDescriptor") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int)))

socketFileDescriptor :: Socket -> IO FileDescriptor Source #

We use unsafeFdSocket but FileDescriptor constructor is not exposed. This forbids any usage of FileDescriptor (at least in a straightforward way) using any low level functions which operate on file descriptors.

for testing

invalidFileDescriptor :: FileDescriptor Source #

invalidFileDescriptor - when we need something for testing/simulation

Re-exports

newtype MakeBearer (m :: Type -> Type) fd #

Constructors

MakeBearer 

Fields