splice-0.2: Socket to Socket Data Splicing

Safe HaskellSafe-Infered

Network.Socket.Splice

Contents

Description

This library implements efficient socket to socket data transfer loops for proxy servers.

On Linux, it uses 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 that allocates a constant-sized memory buffer before it enters an inner loop which then uses hGetBufSome and hPutBuf; this avoids lots of tiny allocations as would otherwise be caused by recv and sendAll functions from Network.Socket.ByteString.

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.

It is an infinite loop that is intended to be used with forkIO:

 void . forkIO . try_ $ splice 1024 sourceSocket targetSocket
 void . forkIO . try_ $ splice 1024 targetSocket sourceSocket

spliceSource

Arguments

:: ChunkSize

Chunk size.

-> Socket

Source socket.

-> Socket

Target socket.

-> IO ()

Infinite loop.

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

On Linux this happens in kernel space with zero copying between kernel and user spaces.

On other operating systems, a portable implementation utilizes a user space buffer and works on handles instead of file descriptors.

type ChunkSize = Word32Source

The numeric type used to recommend chunk sizes for moving data between sockets used by both the Linux splice and the portable implementation of splice.

zeroCopySource

Arguments

:: Bool

True: uses zero-copy system calls; otherwise: portable.

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

Combinators for Exception Handling

try_Source

Arguments

:: IO ()

The action to run which can throw any exception.

-> IO ()

The new action where exceptions are silenced.

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

Linux splice() Components

These are available only on Linux and will be moved to a different namespace in later releases. Their names will stay the same.

c_spliceSource

Arguments

:: Fd

fd_in

-> Ptr Int64

off_in

-> Fd

fd_out

-> Ptr Int64

off_out

-> Word32

len

-> Word

flags

-> IO Int32

number of bytes moved or -1 on error

Moves data between two file descriptors without copying between kernel address space and user address space. It transfers up to len bytes of data from the file descriptor fd_in to the file file descriptor fd_out, where one of the descriptors must refer to a pipe.

c_splice is NOT a loop and needs to called repeatedly. For an example, see the source code of splice.

sPLICE_F_MOVE :: WordSource

Attempt to move pages instead of copying. This is only a hint to the kernel: pages may stil be copied if the kernel cannot move the pages from the pipe, or if the pipe buffers don't refer to full pages.

sPLICE_F_MORE :: WordSource

More data will be coming in a subsequent splice. This is a helpful hint when fd_out refers to a socket.

sPLICE_F_NONBLOCK :: WordSource

Do not block on I/O. This makes the splice pipe operations nonblocking, but splice() may nevertheless block because the file descriptors that are spliced to/from may block (unless they have the O_NONBLOCK flag set).