socket
An extensible socket library.
https://github.com/lpeterse/haskell-socket
Version on this page: | 0.8.3.0 |
LTS Haskell 22.36: | 0.8.3.0@rev:1 |
Stackage Nightly 2023-12-26: | 0.8.3.0@rev:1 |
Latest on Hackage: | 0.8.3.0@rev:1 |
socket-0.8.3.0@sha256:03d88d2401c0709cc04fdd73509e20356595c1248bbbe2492ee712e552f3af71,3294
Module documentation for 0.8.3.0
- System
- System.Socket
- System.Socket.Family
- System.Socket.Protocol
- System.Socket.Type
- System.Socket.Unsafe
- System.Socket
socket
Motivation
This library aims to expose a minimal and cross-platform interface for BSD style networking code.
Implementation Philosophy
-
Every operation and every flag exposed should be supported with same semantics on every platform. If this cannot be guaranteed it should be supplied by another (extension) package.
-
Absolutely no conditional exports.
-
No
#ifdef
madness in the Haskell sources. The Haskell binding code uses the FFI to reference platform dependant C functions for each operation. If a platform is not POSIX compliant (i.e. Windows) equivalent functionality is implemented by using whatever the platform specific building blocks are.
Platform Support
Linux
Platform is fully supported. Each commit and release is automatically tested with Travis CI and several versions of GHC.
Windows
Fully supported on Windows7 (maybe Vista) or higher :-)
GHC’s runtime system on Windows does not offer an event notification mechanism for sockets. The original network library suffers from this, too. For example, connection attempts are non-interruptible etc. The approach taken to circumvent this in this library is to poll the non-blocking sockets with increasing delay. This guarantees interruptibility and fairness between different threads. It allows for decent throughput while also keeping CPU consumption on a moderate level if a socket has not seen events for a longer period of time (maximum of 1 second delay after 20 polling iterations). The only drawback is potentially reduced response time of your application. The good part: Heavy load (e.g. connection requests or incoming traffic) will reduce this problem. Eventually your accepting thread won’t wait at all if there are several connection requests queued.
This workaround may be removed if someone is willing to sacrifice to improve the IO manager on Windows.
Each commit and release is automatically tested with AppVeyor continuous integration.
MacOS
Working, but not regularly tested.
Please report when it is no longer working on MacOS.
Dependencies
- base
- bytestring
Tests
The project uses tasty for testing.
There are two test suites: default
and threaded
which share the same
code. The only difference is that one is compiled against GHC’s single threaded
RTS and the other against the multi-threaded one. Run cabal test
or stack test
to execute both in sequence.
Changes
0.8.3.0 Lars Petersen [email protected] 2020-06-29
- Updates Stack LTS to 16.3
0.8.2.0 Lars Petersen [email protected] 2018-10-31
- Issue 61: Fixed unexpected
IOError
bubbling up fromthreadWaitSTM
. - Added message flag
msgPeek
(MSG_PEEK).
0.8.1.0 Lars Petersen [email protected] 2018-08-13
- Issue 51: Add a
getAddress
operation for getting the local socket address. - Marked
System.Socket.Type.Stream.receiveAll
as deprecated. This is a preparation for a name reuse in upcoming 0.9.0.0. - Removed dead code (
Message
type). - Added error code
ePermissionDenied
.
0.8.0.1 Lars Petersen [email protected] 2017-02-25
- Issue 47: Fixed haddock documentation.
- Issue 46: Export
KeepAlive
socket option in the main module.
0.8.0.0 Lars Petersen [email protected] 2017-02-25
-
Issue 26: Show instances for
SocketException
andAddressInfoException
no longer usestrerror()
andgai_strerror()
, but simply show the name of the error code. Linking togai_strerror()
was problematic on Windows andstrerror()
was not thread-safe on Linux. -
Issue 38: Added SO_KEEPALIVE as
System.Socket.KeepAlive
. -
Issue 37: Added TCP_NODELAY as
System.Socket.Protocol.TCP.NoDelay
. -
Issue 40: Changed allocation function to malloPlainForeignPtr. This mechanism used in the ByteString library is heavily optimised and 2 - 2.5 times faster than the previous implementation. See https://github.com/lpeterse/haskell-socket/pull/40 for details.
-
Issue 31: Added a
Default
protocol type. -
Issue 27: Fixed a memory leak that manifested when interrupting threads waiting on socket events.
-
Issue 25: The
awaitEvent: invalid argument
was caused by the forked-off thread inthreadWaitRead
. The new code introduced by the changes caused by issue 27 catches and swallows this exception in a sane way. -
Renamed
unsafeSocketWaitRead/Write/Connected
towaitRead/Write/Connected
as these operations are not really unsafe, just internal. The operation signatures changed due to issue 27. Also, documented Windows specific implementation details. -
The
connect
operation does no longer hold the lock on the socket while waiting for connection establishment. -
Refactored and adapted the
accept
operation for changes caused by issue 27. Operation semantics shouldn’t have changed. -
Made
SocketAddress
an associated data family and added aStorable (SocketAddress f)
constraint to theFamily
class. This allows omitting theStorable
in socket operations (Family
suffices now). It should be compatible with all existing code and not require any changes.
0.7.0.0 Lars Petersen [email protected] 2016-11-13
-
Added function
sendAllLazy
andsendAllBuilder
. Changed the signature and semantics ofsendAll
(thus the major version bump). -
The
MessageFlags
constructor is now exported (kudos to Shea Levy for noting that this is necessary when writing extension libraries). -
GHC 8 introduces a built-in alignment macro which is now used when present. This prevents re-definition warnings.
-
Fixed implicit function declaration warning concerning accept4. Defining
GNU_SOURCE
in the header file declaresaccept4
when present (see man accept4).
0.6.2.0 Lars Petersen [email protected] 2016-08-15
- Added functions for constructing internet addresses without the need for IO
(
inetAddressToTuple
,inetAddressFromTuple
,inet6AddressToTuple
,inet6AddressFromTuple
) as proposed by Erik Rantapaa.
0.6.1.0 Lars Petersen [email protected] 2016-08-11
-
A potential race condition has been fixed (issue #18):
c_get_last_error
was supposed to return the error code of the last operation (if any). On Linux et.al. it just returnederrno
whereas on Windows it wrapped a call toWSAGetLastError
. The problem was that the value oferrno
andWSAGetLastError
is only valid when sampled immediately after the failed call. This could not be easily guaranteed the way it was implemented: GHC’s RTS is potentially allowed to interrupt the thread between the failed call and the call toc_get_last_error
(although this is very unlikely when no memory allocation is necessary). The content oferrno
might have been reset of overridden by another thread. The solution for this is that all FFI calls now take a pointer with a reserved memory location (allocated on the stack, so it’s quite cheap) and the C functions immediately save the errno (if necessary). Theunsafe ccall
s are guaranteed to be uninterruptible. -
All tests have been ported to
tasty
as previously proposed by Roman Cheplyaka. -
Fixed
connect
operation to usegetsockopt
with SO_ERROR to determine socket connection status / error code instead of issuing a second connection attempt (see issue #15). On Windows, the solution is a bit more difficult:getsockopt
return 0 unless the operation has either succeeded or failed. Unfortunately, there did not exist a mechanism to wait for this condition (GHC’s IO manager lacks this feature). This has been circumvented by callingselect
for the socket with minimal timeout several times with an exponential back-off. Tests have been added to validate different aspects of this.
0.6.0.1 Lars Petersen [email protected] 2016-04-10
- Adapted the
AddrInfo
test suite to not depend on specific name resolution features that aren’t available in achroot()
environment (see issue #12).
0.6.0.0 Lars Petersen [email protected] 2016-03-26
- Improved and adapted documentation.
- Merged
GetSocketOption
andSetSocketOption
to one single type classSocketOption
. getNameInfo
now returnsNameInfo
instead of a tuple.- Added all theoretically possible
SocketExceptions
. - The type class
GetNameInfo
has been renamed toHasNameInfo
. - The type class
GetAddressInfo
has been renamed toHasAddressInfo
. - Removed operation
withConnectedSocket
without replacement. It should not be part of this minimal library. Its code can be retrieved from the repository if needed. - The operations
sendAll
andreceiveAll
are now exported throughSystem.Socket.Type.Stream
and no longer trough the main module. They are very specific, solely stream-oriented and just wrappers around the basic operations. Such operations shouldn’t pollute the main module. - Issue #10: Ben Gamari reported that the associated type
SocketAddress
is not injective which would lead to compilation failure on GHC 8.* . This is fixed by using a data family instead.
0.5.3.0 Lars Petersen [email protected] 2015-08-09
- Added a test for
eOperationNotSupported
(try to listen on a UDP socket). - Niklas Hambüchen added
eOperationNotSupported
.
0.5.2.0 Lars Petersen [email protected] 2015-07-08
- Don’t set
msgNoSignal
automatically withsend
andsendTo
. This implicit behaviour is a bad design decision. The implications of this change are rather limited. The behaviour/correctness of an application is only affected if it hooked SIGPIPE. GHC’s RTS by default ignores SIGPIPE since #1619. You’re still advised to adapt your applications to usemsgNoSignal
explicitly when writing on stream oriented sockets. Otherwise the RTS gets unnecessarily interrupted. This is harmless, but annoying and not desired when developing high-performance applications. - Define
msgNoSignal
as 0 if not available and documented this behaviour. - Added new exception value
ePipe
.
0.5.1.0 Lars Petersen [email protected] 2015-06-22
- Exposed
unsafeGetSocketOption
andunsafeSetSocketOption
. - Exposed
socketWaitRead
andsocketWaitWrite
throughSystem.Socket.Unsafe
.
0.5.0.0 Lars Petersen [email protected] 2015-06-19
- Introduced newtypes
Port
,FlowInfo
andScopeId
in Inet6 family. - Renamed nearly everything in response to very constructive criticism by Bryan O’Sullivan. This is a breaking change (sorry about that). I felt this was the last chance to get this straight before the library gets widely adopted. Additional kudos to @ignorantone and @whatsthepoint.
- Issue #7: Typo in documentation of inaddrNONE and inaddrBROADCAST. Kudos to Michael Fox.
0.4.0.1 Lars Petersen [email protected] 2015-06-17
- tar-ball did not contain relevant source files.
0.4.0.0 Lars Petersen [email protected] 2015-06-16
- Changed semantics of
connect
operation. It now blocks until a connection has either has been established or failed. - Added
SO_ERROR
socket option. - Added
eALREADY
exception constant. - Added
eISCONN
exception constant. - Added
eNOTCONN
exception constant. - Added convenience operation
withConnectedSocket
. - Added
eNETUNREACH
exception constant. - Added new operation
recvAll
and changedsendAll
to lazyByteString
. - Added new socket option IPV6_V6ONLY.
- Removed untested socket option SO_ACCEPTCONN.
- Correctly defining AI_ flags on Windows (MinGW doesn’t although they are all well support on Vista or higher).
- Got all tests passing on Windows 7.
0.3.0.1 Lars Petersen [email protected] 2015-06-07
- Fixed documentation of eaiNONAME.
- Fixed typo in .cabal file in reference to cbits file.
0.3.0.0 Lars Petersen [email protected] 2015-06-07
AddrInfoFlags
andNameInfoFlags
are now instances ofBits
.- Dropped all sendmsg/recvmsg related operations (harden the core first!)
- Dropped support for UNIX socket (will be separate package
socket-unix
) - Renamed type function
Address
toSockAddr
. - Added GetAddrInfo and GetNameInfo classes.
- Dropped support for SCTP (will be separate package
socket-sctp
) - Added support for RAW sockets.
- Started to support Windows (still unfinished).
- New operation
recvRecord
. - ReceiveMsg now returns a strict
ByteString
. - New operations
sendV
,sendToV
. - Restricted getAddrInfo and getNameInfo and added
getAddrInfo6
andgetNameInfo6
- Added address family types INET, INET6 and UNIX (API breaking change)
- Hide
SockAddrIn6
address constructor - Hide
SockAddrIn
address constructor - Added
recvMsg
operation - Fixed unsafeSend, unsafeSendTo and unsafeSendMsg (they were waiting for a read event instead of waiting for writing)
- Use
aiStrError
values in Show instance - Added
aiStrError
function - Added constants for AddrInfoException
- Changed definitin of AddrInfoException
- Added
sendAllMsg
operation - Added
sendMsg
operation (+ some types and internals)
0.2.0.0 Lars Petersen [email protected] 2015-05-29
- Added a sendAll operation
- Exposed the Socket constructor
- Added
getNameInfo
operation - Added msgWAITALL and fixed serious bug regarding all other MsgFlags
- Nicer Show instances for SockAddrIn and SockAddrIn6
- Hiding internal modules
- Added
getAddrInfo
operation
0.1.0.1 Lars Petersen [email protected] 2015-05-28
- Added CHANGELOG.md
- Removed
threadWaitReadMVar
andthreadWaitWriteMVar
- Import
Data.Monoid
inSystem.Socket.Unsafe
to support older Preludes
0.1.0.0 Lars Petersen [email protected] 2015-05-28
- Initial release