splice-0.5: Socket to Socket Data Splicing (supports all operating systems)

Safe HaskellSafe-Infered

Network.Socket.Splice

Contents

Description

This library implements most efficient socket to socket data transfer loops for proxy servers on each operating system.

On GNU/Linux, it uses and exposes the zero-copy splice() system call: http://kerneltrap.org/node/6505.

On all other operating systems, it currently falls back to a portable Haskell implementation – which allocates a single memory buffer in user address space, then enters an inner loop that uses hGetBufSome and hPutBuf. This avoids lots of tiny allocations as would otherwise be caused by recv and sendAll from the bytestring package.

Synopsis

Cross-platform API for Socket to Socket Data Transfer Loops

splice is the cross-platform API for continous, uni-directional data transfer between two network sockets.

splice and its implementation primitives hSplice and fdSplice are infinite loops that are intended to be used with exception handlers and forkIO.

Initiate bi-directional continuous data transfer between two sockets:
 void . forkIO . tryWith handler $ splice 1024 (sourceSocket, _) (targetSocket, _)
 void . forkIO . tryWith handler $ splice 1024 (targetSocket, _) (sourceSocket, _)

where handler is an IO action that would do the necessary clean up – such as ensuring the sockets are closed and any resources that may be associated with the sockets are properly disposed of.

spliceSource

Arguments

:: ChunkSize

chunk size.

-> (Socket, Maybe Handle)

source socket and possibly its opened handle.

-> (Socket, Maybe Handle)

target socket and possibly its opened handle.

-> IO ()

infinite loop.

Pipes data from one socket to another in an infinite loop.

splice currently has two implementations:

on GNU/Linux using fdSplice
 splice len (sIn, _       ) (sOut, _        ) = ... fdSplice ...
on all other operating systems using hSplice
 splice len (_  , Just hIn) (_   , Just hOut) = ... hSplice  ...
Notes
  • fdSplice and fdSplice implementation of splice are only available on GNU/Linux.
  • hSplice is always available and the hSplice implementation of splice can be forced on GNU/Linux by defining the portable flag at compile time.

type ChunkSize = ChunkSizeSource

The numeric type to recommend chunk sizes for moving data between sockets used by both zero-copy and portable implementations of splice.

zeroCopySource

Arguments

:: Bool

True if splice uses zero-copy system calls; otherwise, false.

Indicates whether splice uses zero-copy system calls or the portable user space Haskell implementation.

Combinators for Exception Handling

tryWithSource

Arguments

:: (SomeException -> IO a)

exception handler.

-> IO a

action to run which can throw any exception.

-> IO a

new action where all exceptions are handled by a single.

Similar to try but used when an obvious exception is expected and can be handled easily. Unlike finally exceptions are not rethrown once handled.

try_Source

Arguments

:: IO ()

action to run which can throw any exception.

-> IO ()

new action where exceptions are silenced.

Similar to try but used when an obvious exception is expected which can be safely ignored.

Implementation Primitives

Infinite loops used in the cross-platform implementation of splice.

hSplice :: Int -> Handle -> Handle -> IO ()Source

The portable Haskell loop.

  1. allocates a single memory buffer in user address space
  2. uses it until the loop terminates by exception
  3. frees the buffer and returns

fdSplice :: ChunkSize -> Fd -> Fd -> IO ()Source

GNU/Linux splice() system call loop.

  1. creates a pipe in kernel address space
  2. uses it until the loop terminates by exception
  3. closes the pipe and returns