Coder Social home page Coder Social logo

haskell / network Goto Github PK

View Code? Open in Web Editor NEW
319.0 32.0 185.0 1.94 MB

Low-level networking interface

Home Page: http://hackage.haskell.org/package/network

License: Other

Haskell 89.50% C 6.67% Makefile 0.12% Shell 2.97% M4 0.74%
haskell network socket

network's Introduction

GitHub Actions status

To build this package directly from git, you must run autoreconf -i. And then use cabal configure; cabal build or stack build.

Support Policy

GHC

The network package support 3 major versions of GHC only. This means that the current stable version and two previous stable versions are supported.

Windows

We use MSYS to build this package on Windows. To use the network package on Cygwin, use stack.

Coding

.hs files

If you need C macros created by "configure" or CALLCONV/SAFE_ON_WIN, put

#include "HsNetDef.h"

"HsNet.h" does now work well since Mac's cpp sucks.

.hsc files

If you need #peek, #poke and others, create a .hsc file with

#include "HsNet.h"

HsNet.h includes HsNefDef.h and necessary C structures. Unfortunately, hsc2hs does not convert C macros. So, if you use CALLCONV/SAFE_ON_WIN, the following is also necessary:

##include "HsNetDef.h"

network's People

Contributors

23skidoo avatar andreasabel avatar archaephyrryx avatar bmillwood avatar bos avatar bsl avatar complyue avatar dcoutts avatar eborden avatar enolan avatar fumieval avatar ggreif avatar gklyne avatar gregorycollins avatar hasufell avatar hreinhardt avatar hs-viktor avatar hvr avatar igfoo avatar infinity0 avatar joeyadams avatar kazu-yamamoto avatar kfish avatar mistuke avatar ndmitchell avatar nominolo avatar ppetr avatar rblaze avatar singpolyma avatar tibbe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

network's Issues

Error in Internal.hsc Non-exhaustive patterns in case, aborts server

I have a Yesod webserver running that reliably aborts (after running a while) on an error in Network.hsc:

Last output:

HostIPv4
NimbusYesod: Network/Socket/Internal.hsc:(292,3)-(308,61): Non-exhaustive patterns in case

This is on Mac OSX 10.6.8
ghc is version 7.0.3
Network is version 2.3.0.11

Won't install through cabal install on Windows 7

When I tried to 'cabal install network' I've got this message:
Resolving dependencies...
Configuring network-2.4.0.1...
checking build system type... i686-pc-mingw32
checking host system type... i686-pc-mingw32
checking for gcc... no
checking for cc... no
checking for cl.exe... no
configure: error: no acceptable C compiler found in $PATH
See `config.log' for more details.
cabal: Error: some packages failed to install:
network-2.4.0.1 failed during the configure step. The exception was:
ExitFailure 1
I use Windows 7 + Haskell Platform 2012.2.0.0
gcc is on my %PATH%. The same message appears for 2.4.0.1 and 2.3.1.0 versions.

Linking error on OS X

I get this error on OS X Mountain Lion, both with apple-gcc42 (a real GCC) and clang:

$ ./Setup build --verbose
Reading parameters from ./network.buildinfo
creating dist/build
creating dist/build/autogen
Building network-2.4.1.2...
Preprocessing library network-2.4.1.2...
Building library...
creating dist/build
/usr/local/bin/ghc --make -fbuilding-cabal-package -O -odir dist/build -hidir dist/build -stubdir dist/build -i -idist/build -i. -idist/build/autogen -Idist/build/autogen -Idist/build -Iinclude -optP-include -optPdist/build/autogen/cabal_macros.h -package-name network-2.4.1.2 -hide-all-packages -package-db dist/package.conf.inplace -package-id base-4.6.0.1-6c351d70a24d3e96f315cba68f3acf57 -package-id bytestring-0.10.0.2-bf7aaeef3f644374cd7d5a9066cd9017 -package-id parsec-3.1.3-31f41d4929a43eb168e503c7714610f3 -package-id unix-2.6.0.1-52dff7c48cc7e568e08270242805b644 -XHaskell98 -XCPP -XDeriveDataTypeable -XForeignFunctionInterface -XTypeSynonymInstances Network Network.BSD Network.Socket Network.Socket.ByteString Network.Socket.ByteString.Lazy Network.Socket.Internal Network.URI Network.Socket.ByteString.IOVec Network.Socket.ByteString.MsgHdr Network.Socket.ByteString.Internal Network.Socket.Types -DCALLCONV=ccall -fwarn-tabs
Building C Sources...
creating dist/build
/usr/local/bin/ghc -c -odir dist/build -Idist/build -Iinclude -optc-DCALLCONV=ccall -optc-O2 -package-db dist/package.conf.inplace -package-id base-4.6.0.1-6c351d70a24d3e96f315cba68f3acf57 -package-id bytestring-0.10.0.2-bf7aaeef3f644374cd7d5a9066cd9017 -package-id parsec-3.1.3-31f41d4929a43eb168e503c7714610f3 -package-id unix-2.6.0.1-52dff7c48cc7e568e08270242805b644 cbits/ancilData.c
creating dist/build
/usr/local/bin/ghc -c -odir dist/build -Idist/build -Iinclude -optc-DCALLCONV=ccall -optc-O2 -package-db dist/package.conf.inplace -package-id base-4.6.0.1-6c351d70a24d3e96f315cba68f3acf57 -package-id bytestring-0.10.0.2-bf7aaeef3f644374cd7d5a9066cd9017 -package-id parsec-3.1.3-31f41d4929a43eb168e503c7714610f3 -package-id unix-2.6.0.1-52dff7c48cc7e568e08270242805b644 cbits/HsNet.c
Linking...
/usr/bin/ar -r -s dist/build/libHSnetwork-2.4.1.2.a dist/build/Network.o dist/build/Network/BSD.o dist/build/Network/Socket.o dist/build/Network/Socket/ByteString.o dist/build/Network/Socket/ByteString/Lazy.o dist/build/Network/Socket/Internal.o dist/build/Network/URI.o dist/build/Network/Socket/ByteString/IOVec.o dist/build/Network/Socket/ByteString/MsgHdr.o dist/build/Network/Socket/ByteString/Internal.o dist/build/Network/Socket/Types.o dist/build/cbits/ancilData.o dist/build/cbits/HsNet.o
/usr/bin/ld -x -arch x86_64 -r -o dist/build/HSnetwork-2.4.1.2.o dist/build/Network.o dist/build/Network/BSD.o dist/build/Network/Socket.o dist/build/Network/Socket/ByteString.o dist/build/Network/Socket/ByteString/Lazy.o dist/build/Network/Socket/Internal.o dist/build/Network/URI.o dist/build/Network/Socket/ByteString/IOVec.o dist/build/Network/Socket/ByteString/MsgHdr.o dist/build/Network/Socket/ByteString/Internal.o dist/build/Network/Socket/Types.o dist/build/cbits/ancilData.o dist/build/cbits/HsNet.o
duplicate symbol _my_inet_ntoa in:
    dist/build/cbits/ancilData.o
    dist/build/cbits/HsNet.o
duplicate symbol _hsnet_getnameinfo in:
    dist/build/cbits/ancilData.o
    dist/build/cbits/HsNet.o
duplicate symbol _hsnet_getaddrinfo in:
    dist/build/cbits/ancilData.o
    dist/build/cbits/HsNet.o
duplicate symbol _hsnet_freeaddrinfo in:
    dist/build/cbits/ancilData.o
    dist/build/cbits/HsNet.o
ld: 4 duplicate symbols for architecture x86_64

The configure output is:

$ ./Setup configure --user --verbose
Configuring network-2.4.1.2...
Dependency base >=3 && <5: using base-4.6.0.1
Dependency bytestring -any: using bytestring-0.10.0.2
Dependency parsec >=3.0: using parsec-3.1.3
Dependency unix >=2: using unix-2.6.0.1
Using Cabal-1.16.0 compiled by ghc-7.6
Using compiler: ghc-7.6.3
Using install prefix: /Users/iv/.cabal
Binaries installed in: /Users/iv/.cabal/bin
Libraries installed in: /Users/iv/.cabal/lib/network-2.4.1.2/ghc-7.6.3
Private binaries installed in: /Users/iv/.cabal/libexec
Data files installed in: /Users/iv/.cabal/share/network-2.4.1.2
Documentation installed in: /Users/iv/.cabal/share/doc/network-2.4.1.2
No alex found
Using ar found on system at: /usr/bin/ar
No c2hs found
No cpphs found
No ffihugs found
Using gcc version 4.2.1 found on system at: /usr/bin/gcc
Using ghc version 7.6.3 found on system at: /usr/local/bin/ghc
Using ghc-pkg version 7.6.3 found on system at: /usr/local/bin/ghc-pkg
No greencard found
Using haddock version 2.13.2 found on system at: /usr/local/bin/haddock
No happy found
No hmake found
Using hpc version 0.6 found on system at: /usr/local/bin/hpc
Using hsc2hs version 0.67 found on system at: /usr/local/bin/hsc2hs
No hscolour found
No hugs found
No jhc found
Using ld found on system at: /usr/bin/ld
No lhc found
No lhc-pkg found
No nhc98 found
Using pkg-config version 0.28 found on system at: /usr/local/bin/pkg-config
Using ranlib found on system at: /usr/bin/ranlib
Using strip found on system at: /usr/bin/strip
Using tar found on system at: /usr/bin/tar
No uhc found
sh configure --with-compiler=ghc --with-gcc=/usr/bin/gcc
checking build system type... i386-apple-darwin12.4.1
checking host system type... i386-apple-darwin12.4.1
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for an ANSI C-conforming const... yes
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking fcntl.h usability... yes
checking fcntl.h presence... yes
checking for fcntl.h... yes
checking limits.h usability... yes
checking limits.h presence... yes
checking for limits.h... yes
checking for stdlib.h... (cached) yes
checking for sys/types.h... (cached) yes
checking for unistd.h... (cached) yes
checking winsock2.h usability... no
checking winsock2.h presence... no
checking for winsock2.h... no
checking ws2tcpip.h usability... no
checking ws2tcpip.h presence... no
checking for ws2tcpip.h... no
checking wspiapi.h usability... no
checking wspiapi.h presence... no
checking for wspiapi.h... no
checking arpa/inet.h usability... yes
checking arpa/inet.h presence... yes
checking for arpa/inet.h... yes
checking netdb.h usability... yes
checking netdb.h presence... yes
checking for netdb.h... yes
checking netinet/in.h usability... yes
checking netinet/in.h presence... yes
checking for netinet/in.h... yes
checking netinet/tcp.h usability... yes
checking netinet/tcp.h presence... yes
checking for netinet/tcp.h... yes
checking sys/socket.h usability... yes
checking sys/socket.h presence... yes
checking for sys/socket.h... yes
checking sys/uio.h usability... yes
checking sys/uio.h presence... yes
checking for sys/uio.h... yes
checking sys/un.h usability... yes
checking sys/un.h presence... yes
checking for sys/un.h... yes
checking for readlink... yes
checking for symlink... yes
checking for struct msghdr.msg_control... yes
checking for struct msghdr.msg_accrights... no
checking for struct sockaddr.sa_len... yes
checking for in_addr_t in netinet/in.h... yes
checking for SO_PEERCRED and struct ucred in sys/socket.h... no
checking for _head_libws2_32_a in -lws2_32... no
checking for getaddrinfo... yes
checking for gai_strerror... yes
checking whether AI_ADDRCONFIG is declared... yes
checking whether AI_ALL is declared... yes
checking whether AI_NUMERICSERV is declared... yes
checking whether AI_V4MAPPED is declared... yes
checking whether IPV6_V6ONLY is declared... yes
checking for sendfile in sys/sendfile.h... no
checking for sendfile in sys/socket.h... yes
checking for gethostent... yes
checking for accept4... no
configure: creating ./config.status
config.status: creating network.buildinfo
config.status: creating include/HsNetworkConfig.h
config.status: include/HsNetworkConfig.h is unchanged
Reading parameters from ./network.buildinfo

ghc --info output:


> ghc --info
 [("Project name","The Glorious Glasgow Haskell Compilation System")
 ,("GCC extra via C opts"," -fwrapv")
 ,("C compiler command","/usr/bin/gcc")
 ,("C compiler flags"," -m64 -fno-stack-protector  -m64")
 ,("ar command","/usr/bin/ar")
 ,("ar flags","clqs")
 ,("ar supports at file","NO")
 ,("touch command","touch")
 ,("dllwrap command","/bin/false")
 ,("windres command","/bin/false")
 ,("perl command","/usr/bin/perl")
 ,("target os","OSDarwin")
 ,("target arch","ArchX86_64")
 ,("target word size","8")
 ,("target has GNU nonexec stack","False")
 ,("target has .ident directive","True")
 ,("target has subsections via symbols","True")
 ,("LLVM llc command","llc")
 ,("LLVM opt command","opt")
 ,("Project version","7.6.3")
 ,("Booter version","7.4.2")
 ,("Stage","2")
 ,("Build platform","x86_64-apple-darwin")
 ,("Host platform","x86_64-apple-darwin")
 ,("Target platform","x86_64-apple-darwin")
 ,("Have interpreter","YES")
 ,("Object splitting supported","YES")
 ,("Have native code generator","YES")
 ,("Support SMP","YES")
 ,("Unregisterised","NO")
 ,("Tables next to code","YES")
 ,("RTS ways","l debug  thr thr_debug thr_l thr_p dyn debug_dyn thr_dyn thr_debug_dyn")
 ,("Leading underscore","YES")
 ,("Debug on","False")
 ,("LibDir","/usr/local/Cellar/ghc/7.6.3/lib/ghc-7.6.3")
 ,("Global Package DB","/usr/local/Cellar/ghc/7.6.3/lib/ghc-7.6.3/package.conf.d")
 ,("Gcc Linker flags","[\"-m64\"]")
 ,("Ld Linker flags","[\"-arch\",\"x86_64\"]")
 ]

I'd be glad to provide any further debugging assistance.

ghci "Unable to load package" error

GHC Version: 7.6.3
OS: Red Hat Enterprise Linux Client release 5.5 (Tikanga)
Network Version: network-2.4.1.2
I get the following error while running some code in ghci

Loading package hxt-unicode-9.0.2 ... linking ... done.
Loading package network-2.4.1.2 ... linking ... <interactive>: /tools/linux-x86_64/ghc/7.6.3//lib/network-2.4.1.2/ghc-7.6.3/HSnetwork-2.4.1.2.o: unknown symbol `ghc_wrapper_d2dh_fcntl'
ghc: unable to load package `network-2.4.1.2'

The same code works when compiled into an executable.

Apologies if this is not the correct forum for this issue.

Don't conditionally define datatypes etc

The network package conditionally defines things depending on the capabilities of the platform, e.g.:

data Family
    =
[...]
#ifdef AF_INET6
    | AF_INET6            -- Internet Protocol version 6
#endif
[...]

This makes it impossible to write portable programs. Please instead define the datatypes etc unconditionally, and change the code so that, for example, it throws an exception if an unsupported family is used, and perhaps also provide functions like

supportedFamily :: Family -> Bool

UnixSocket handled strangely by connectTo and accept

If connectTo is used with a UnixSocket, it completely ignores the hostname argument. Which is good because there's nothing sensible to put in there, but bad because you have to fill it with a useless value (e.g. undefined), and this isn't at all mentioned in the docs.

When Network.accept is used with a socket from Network.listenOn with a UnixSocket argument, the host is filled with garbage and the port is always 65535. This is highly worrying:

module NetworkTest where

import Control.Exception

import Network
import System.IO

path :: String
path = "/tmp/networktest.sock"

server :: IO ()
server = bracket (listenOn (UnixSocket path)) close $ \s ->
  bracket (accept s) (\(h,_,_) -> hClose h) $ \(h,them,themport) ->
    putStrLn $ "Connection from: " ++ show (them,themport)

client :: IO ()
client = bracket (connectTo undefined (UnixSocket path)) hClose $ \h ->
  return ()
ghci> forkIO server
ThreadId 173
ghci> client
Connection from: ("rkov-chain-0.0.3.1ry-0\228\US\DC2\t\SO",65535)

I have no idea what is being printed here but it doesn't look safe.

listenOn should accept an IP parameter

listenOn takes the port to listen on, but not the IP address. Attempting to bind to all addresses can fail with limited privileges, and may not be desirable in any case. An alternative would be

listenOn' host (PortNumber port) = do
    proto <- getProtocolNumber "tcp"
    bracketOnError
        (socket AF_INET Stream proto)
        (sClose)
        (\sock -> do
            setSocketOption sock ReuseAddr 1
            bindSocket sock (SockAddrInet port host)
            listen sock maxListenQueue
            return sock
        )

PortNumber exports constructor, probably shouldn't

I spent about half an hour trying to figure out why creating a socket with PortNum 8000 didn't actually open up a socket on port 8000. Instead, it mangles the input (I believe, converting it to network byte order?):

sock <- socket AF_INET Stream 0
setSocketOption sock ReuseAddr 1
print $ (SockAddrInet (PortNum port) iNADDR_ANY)
bindSocket sock (SockAddrInet (fromIntegral port) iNADDR_ANY)
listen sock 2

This opens up my socket on some port in the 16000s (not on port 8000 as expected).

It seems that the proper way to convert an Int to a PortNumber is via fromIntegral. However, there is nothing in the documentation that says this. And worse yet, the constructor for PortNumber is exported. As the only information on this type is that it is a newtype'd Word16, you would think that you just pass the port you want.

Hopefully we can save some poor soul the frustration in the future by not exporting the ctor.

getAddrInfo segfaults when AI_NUMERICSERV is used

This example segfaults on OS X:

$ ghci -package network
GHCi, version 7.6.2: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package array-0.4.0.1 ... linking ... done.
Loading package deepseq-1.3.0.1 ... linking ... done.
Loading package bytestring-0.10.0.2 ... linking ... done.
Loading package transformers-0.3.0.0 ... linking ... done.
Loading package mtl-2.1.2 ... linking ... done.
Loading package text-0.11.2.3 ... linking ... done.
Loading package parsec-3.1.3 ... linking ... done.
Loading package old-locale-1.0.0.5 ... linking ... done.
Loading package time-1.4.0.1 ... linking ... done.
Loading package unix-2.6.0.1 ... linking ... done.
Loading package network-2.4.1.0 ... linking ... done.
ghci> import Network.Socket
ghci> let hints = defaultHints { addrFlags = [AI_NUMERICSERV] }
ghci> getAddrInfo (Just hints) (Just "localhost") Nothing
Segmentation fault: 11

The segfault disappears if AI_NUMERICSERV is removed from addrFlags.

The length of the iov array created by sendMany may exceed UIO_MAXIOV

When sending large payloads (the boundary is somewhere between 33439816 bytes, which is okay, and 33439824 bytes, which is not) the length of the array created by sendMany and then passed to writev goes from 1024 to 1025, at which point writev returns an error which is then thrown as "writev: invalid argument (Invalid argument)" exception.

Network.URI might benefit from being separated into a different package

The Network.URI module is frequently not necessary to people who just want to open a socket of some kind, and conversely one can imagine uses of Network.URI by people who aren't interested in sockets at all (maybe CGI scripts).

With the module in the network package, the socket users have to install parsec, and the URI users have to run a configure script and C compiler etc. for what is essentially pure Haskell. Both might benefit from the Network.URI module being separated into its own package.

configure does not handle cross-compiling

Discovered while cross-compiling for QNX/BB10. The configure step detects LINUX_SENDFILE and ACCEPT4 even though the target does not have them (but the host does). Have to manually edit the output header file for it to work.

No support for "Flags" in recv call

I have a need to recv with the MSG_PEEK flag. If the only reason it's missing is man power then I'll send a patch. Is there any major concern preventing a recvFlags operation?

data Flag = MSG_PEEK | ...
recvWithFlags :: Socket -> [Flag] -> IO String
recvWithFlags :: Socket -> [Flag] -> IO ByteString
recvBufWithFlags :: Socket -> Ptr Word8 -> Int -> [Flag] -> IO Int

Custom exception types could be useful

Ideally, users of the code would never want to read the string inside an exception to find out information about it: that's only useful for showing to humans. So whenever we throw a userError, we're kind of saying "the program has no useful information to give you about what error just happened". I think often this is not the case, and we should either use existing error types more effectively, or create some of our own.

Support checking if a URI is absolute

There is a nice helper to check if a string is an absolute URI (though... it succeeds in some cases where it is not...), but it would be nice to have such a check for URI itself. Like so:

uriIsAbsolute :: URI -> Bool
uriIsAbsolute (URI {
      uriScheme = scheme,
      uriAuthority = Just (URIAuth {uriRegName = reg})
   }) = scheme /= "" && reg /= ""
uriIsAbsolute _ = False

can't build network

I get the following error with ghc 7.0.2 on snow leopard, 64 bit

Preprocessing library network-2.3.0.2...
Socket.hsc: In function ‘main’:
Socket.hsc:1848: error: ‘AI_NUMERICSERV’ undeclared (first use in this function)
Socket.hsc:1848: error: (Each undeclared identifier is reported only once
Socket.hsc:1848: error: for each function it appears in.)

and then the cabal install fails

what might this mean?

Dropping Network.URL

It seems to me that Network.URL should belong to another package. Other modules are in the socket layer but Network.URL is in the application layer. Due to Network.URL, the network library depends on parsec which depends on text. Moving Network.URL to another package makes the network library simpler (and solves dependency hells sometime).

Build-Errors with OpenBSD 5.3

Hi,

recently I tried to build network-2.4.1.2 from cabal. It fails on OpenBSD5.3 amd64

$ cabal install network-2.4.1.2
[...]
checking for sendfile in sys/socket.h... no
checking for gethostent... yes
checking for accept4... no
configure: creating ./config.status
config.status: creating network.buildinfo
config.status: creating include/HsNetworkConfig.h
configure: WARNING: unrecognized options: --with-compiler, --with-gcc
Preprocessing library network-2.4.1.2...
In file included from IOVec.hsc:12:
/usr/include/sys/uio.h:90: error: expected declaration specifiers or '...' before 'off_t'
/usr/include/sys/uio.h:91: error: expected declaration specifiers or '...' before 'off_t'
compiling dist/build/Network/Socket/ByteString/IOVec_hsc_make.c failed (exit code 1)
command was: /usr/bin/gcc -c dist/build/Network/Socket/ByteString/IOVec_hsc_make.c -o dist/build/Network/Socket/ByteString/IOVec_hsc_make.o -fno-pie -nopie -fno-stack-protector -fno-pie -nopie -D__GLASGOW_HASKELL__=704 -Dopenbsd_BUILD_OS -Dopenbsd_HOST_OS -Dx86_64_BUILD_ARCH -Dx86_64_HOST_ARCH -Iinclude -DCALLCONV=ccall -I/usr/local/lib/ghc/unix-2.5.1.1/include -I/usr/local/lib/ghc/bytestring-0.9.2.1/include -I/usr/local/include -I/usr/local/lib/ghc/base-4.5.1.0/include -I/usr/local/lib/ghc/include -I/usr/local/lib/ghc/include/
cabal: user error (Error: some packages failed to install:
network-2.4.1.2 failed during the building phase. The exception was:
ExitFailure 1
)

any ideas what goes wrong?

Can a thread waiting on Network.Socket.accept not be killed on Windows?

-- thread A
t <- forkIO $ do
   _ <- accept listener -- blocks
-- thread B
killThread t

works on Linux (probably also on OS X and FreeBSD) but not on Windows (tried -threaded with +RTS -N4 -RTS etc.).

  • What is the correct way to terminate a thread in this case?
  • Is there a way to fork a thread in a special mode that would allow termination at the point it is blocked on accept?
  • Would it help if A was forked with forkOS rather than forkIO?

The network package exports no functions that work on pointers to memory buffers, its recommendations do not work on Windows

I just opened the following ticket quoted below with GHC: http://hackage.haskell.org/trac/ghc/ticket/6057.


In a cross-platform transport-layer proxy software I am developing, I have this piece of code:

a >- b $ j       -- forks
b >- a $ j       -- forks

where a and b are handles; j is an exception handler and (>-) is a self-forking infinite loop IO that splices data between two handles, defined previously in terms of hGetBufSome and and hPutBuf on Windows.

I just noticed that:

b >- a $ j       -- forks
a >- b $ j       -- forks

behaves differently from:

a >- b $ j       -- forks
b >- a $ j       -- forks

When proxying connections to an SSH server the first one does not show the greeting from the SSH server before receiving user input, the second does show the greeting.

As the two lines immediately fork to their own Haskell threads the blocking must come from the underlying handles.

When I attempted to use hGetBufNonBlocking to avoid the problem I noticed that the docs read: "NOTE: on Windows, this function does not work correctly; it behaves identically to hGetBuf.".

The reason I chose to use handles in the first place was the "Improving I/O Performance over sockets" section in the network package: http://hackage.haskell.org/packages/archive/network/2.3.0.13/doc/html/Network.html.

At this point I am stuck as neither the network package exports functions that work on pointers to pre-allocated memory buffers nor the h---- famiy of functions from System.IO behave as their names suggest.

Defining (>-) in terms of recv and sendAll from Network.Socket.ByteString does solve the problem and both variants behave exactly the same at run time and this is the only correct behaviour as I have no way of knowing or special-casing which application layer protocols expect initiation from which end (client input first or server greeting first).

I am reporting this issue to both here and to the maintainers of the network package on GitHub.

This bug is reported for 7.0.4 but I highly suspect the behavior may still be the same with newer GHC versions.


As one can see from above the problem arises because network attempts to delegate responsibility to System.IO mutating types (sockets) that are under its control to dynamic things that can be anything (handles (file, window, process, ....)) and forcing its users to bear the burden of a whole class of handle-related issues.

  1. handles do not work the same way on all platforms
  2. h*NonBlocking family of functions are not guranteed to not cause further issues even if the particular bug I ticketed gets fixed
  3. recv and sendAll stand as evidence that network as a package has the necessary internals and they do work same way on all platforms.

My issue and feature request now is:

Can network acknowledge its responsibility to exporting functions for receiving and sending socket data using pointers to memory buffers and stops encouraging forcefully mutating sockets into handles exposing its users to all sorts of handle-related problems?

GHC 7.7 compatibility

Seems enough so far:

diff --git a/Network/Socket/Internal.hsc b/Network/Socket/Internal.hsc
index 5731dd5..f06455b 100644
--- a/Network/Socket/Internal.hsc
+++ b/Network/Socket/Internal.hsc
@@ -78,7 +78,11 @@ import Foreign.Storable ( Storable(..) )
 #if defined(HAVE_WINSOCK2_H) && !defined(cygwin32_HOST_OS)
 import Control.Exception ( finally )
 #  if __GLASGOW_HASKELL__
+#    if __GLASGOW_HASKELL__ >=707
+import GHC.IO.Exception ( IOErrorType(..) )
+#    else
 import GHC.IOBase ( IOErrorType(..) )
+#    endif
 #  endif
 import Foreign.C.Types ( CChar )
 import System.IO.Error ( ioeSetErrorString, mkIOError )

"Compatibility with ghc head" patch breaks with GHC 7.0.4

@markwright the patch e25f69d works with GHC 7.4.1 but does not work with GHC 7.0.4.

Preprocessing library network-2.3.0.14...
BSD.hsc:115:23: error: missing binary operator before token "("
BSD.hsc:115:23: error: missing binary operator before token "("
BSD.hsc:115:23: error: missing binary operator before token "("
compiling dist/build/Network/BSD_hsc_make.c failed (exit code 1)
command was: /usr/bin/gcc -c dist/build/Network/BSD_hsc_make.c -o dist/build/Network/BSD_hsc_make.o -fno-stack-protector -fno-stack-protector -D__GLASGOW_HASKELL__=700 -Dlinux_BUILD_OS -Dlinux_HOST_OS -Di386_BUILD_ARCH -Di386_HOST_ARCH -Iinclude -DCALLCONV=ccall -I/ghc7.0.4/lib/ghc-7.0.4/unix-2.4.2.0/include -I/ghc7.0.4/lib/ghc-7.0.4/bytestring-0.9.1.10/include -I/ghc7.0.4/lib/ghc-7.0.4/base-4.3.1.0/include -I/ghc7.0.4/lib/ghc-7.0.4/include -I/ghc7.0.4/lib/ghc-7.0.4/include -I/ghc7.0.4/lib/ghc-7.0.4/include/

Broken build on debian

Hi, I am not able to build network 2.3.0.14 on my debian box, the problem is with sockets:
Internal.hsc: In function ‘main’:
Internal.hsc:257:5: error: ‘struct sockaddr_un’ has no member named ‘sun_len’
Internal.hsc:269:5: error: ‘struct sockaddr_in’ has no member named ‘sin_len’
Internal.hsc:280:5: error: ‘struct sockaddr_in6’ has no member named ‘sin6_len’

The full output of cabal installation follows:

cabal install network
Resolving dependencies...
Configuring network-2.3.0.14...
configure: WARNING: unrecognized options: --with-compiler, --with-gcc
checking whether to use symlinks for manpages... no
checking whether to compress the manpages... no
checking whether to add a package name suffix for the manpages... no
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for inline... inline
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking dirent.h... yes
checking float.h usability... yes
checking float.h presence... yes
checking for float.h... yes
checking values.h usability... yes
checking values.h presence... yes
checking for values.h... yes
checking limits.h usability... yes
checking limits.h presence... yes
checking for limits.h... yes
checking for stdlib.h... (cached) yes
checking for string.h... (cached) yes
checking sys/wait.h usability... yes
checking sys/wait.h presence... yes
checking for sys/wait.h... yes
checking dlfcn.h usability... yes
checking dlfcn.h presence... yes
checking for dlfcn.h... yes
checking sys/param.h usability... yes
checking sys/param.h presence... yes
checking for sys/param.h... yes
checking if the compiler understands -pipe... yes
checking for building with threads... no (default)
checking for sin... no
checking for main in -lieee... yes
checking for main in -linet... no
checking net/errno.h usability... no
checking net/errno.h presence... no
checking for net/errno.h... no
checking for connect... yes
checking for gethostbyname... yes
checking how to build libraries... shared
checking for ranlib... ranlib
checking if 64bit support is requested... no
checking if 64bit Sparc VIS support is requested... no
checking if compiler supports visibility "hidden"... yes
checking if rpath support is requested... yes
checking system version... Linux-3.2.0-2-amd64
checking for dlopen in -ldl... yes
checking for ar... ar
checking for build with symbols... no
checking for required early compiler flags... LARGEFILE64_SOURCE
checking for 64-bit integer type... using long
checking whether byte ordering is bigendian... no
checking for getcwd... yes
checking for opendir... yes
checking for strtol... yes
checking for waitpid... yes
checking for strerror... yes
checking for getwd... yes
checking for wait3... yes
checking for uname... yes
checking for realpath... yes
checking for getaddrinfo... yes
checking for working getaddrinfo... yes
checking sys/modem.h usability... no
checking sys/modem.h presence... no
checking for sys/modem.h... no
checking termios vs. termio vs. sgtty... termios
checking for fd_set in sys/types... yes
checking sys/time.h usability... yes
checking sys/time.h presence... yes
checking for sys/time.h... yes
checking whether time.h and sys/time.h may both be included... yes
checking for gmtime_r... yes
checking for localtime_r... yes
checking for mktime... yes
checking tm_tzadj in struct tm... no
checking tm_gmtoff in struct tm... yes
checking long timezone variable... yes
checking for struct stat.st_blocks... yes
checking for struct stat.st_blksize... yes
checking for blkcnt_t... yes
checking for fstatfs... yes
checking for working memcmp... yes
checking for memmove... yes
checking for strstr... yes
checking proper strstr implementation... ok
checking for strtoul... yes
checking proper strtoul implementation... ok
checking for strtod... yes
checking proper strtod implementation... ok
checking for strtod... (cached) yes
checking for Solaris2.4/Tru64 strtod bugs... ok
checking for mode_t... yes
checking for pid_t... yes
checking for size_t... yes
checking for uid_t in sys/types.h... yes
checking for socklen_t... yes
checking for intptr_t... yes
checking for uintptr_t... yes
checking for opendir... (cached) yes
checking union wait... yes
checking for strncasecmp... yes
checking for BSDgettimeofday... no
checking for gettimeofday... yes
checking for gettimeofday declaration... present
checking whether char is unsigned... no
checking signed char declarations... yes
checking for a putenv() that copies the buffer... no
checking langinfo.h usability... yes
checking langinfo.h presence... yes
checking for langinfo.h... yes
checking whether to use nl_langinfo... yes
checking for chflags... no
checking isnan... yes
checking for fts... no
checking sys/ioctl.h usability... yes
checking sys/ioctl.h presence... yes
checking for sys/ioctl.h... yes
checking sys/filio.h usability... no
checking sys/filio.h presence... no
checking for sys/filio.h... no
checking system version... (cached) Linux-3.2.0-2-amd64
checking FIONBIO vs. O_NONBLOCK for nonblocking I/O... O_NONBLOCK
checking whether to use dll unloading... yes
checking for timezone data... /usr/share/zoneinfo
checking whether to enable DTrace support... no
checking if the C stack grows upwards in memory... no
configure: creating ./config.status
config.status: creating Makefile
config.status: creating dltest/Makefile
config.status: creating tclConfig.sh
configure: WARNING: unrecognized options: --with-compiler, --with-gcc
Building network-2.3.0.14...
Preprocessing library network-2.3.0.14...
Internal.hsc: In function ‘main’:
Internal.hsc:257:5: error: ‘struct sockaddr_un’ has no member named ‘sun_len’
Internal.hsc:269:5: error: ‘struct sockaddr_in’ has no member named ‘sin_len’
Internal.hsc:280:5: error: ‘struct sockaddr_in6’ has no member named ‘sin6_len’
compiling dist/build/Network/Socket/Internal_hsc_make.c failed (exit code 1)
command was: /usr/bin/gcc -c dist/build/Network/Socket/Internal_hsc_make.c -o dist/build/Network/Socket/Internal_hsc_make.o -fno-stack-protector -Wl,--hash-size=31 -Wl,--reduce-memory-overheads -D__GLASGOW_HASKELL
_=704 -Dlinux_BUILD_OS -Dlinux_HOST_OS -Dx86_64_BUILD_ARCH -Dx86_64_HOST_ARCH -Iinclude -I/usr/lib/ghc/unix-2.5.1.0/include -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -I/usr/lib/ghc/bytestring-0.9.2.1/include -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -I/usr/lib/ghc/base-4.5.0.0/include -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -I/usr/lib/ghc/include -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -I/usr/lib/ghc/include/
cabal: Error: some packages failed to install:
network-2.3.0.14 failed during the building phase. The exception was:
ExitFailure 1

Build Error network-2.4.0.0

Building network-2.4.0.0...
Preprocessing library network-2.4.0.0...
[ 1 of 10] Compiling Network.URI ( Network/URI.hs, dist/build/Network/URI.o )

Network/URI.hs:596:25:
Couldn't match expected type Char' with actual typeString'
Expected type: GenParser Char () Char
Actual type: URIParser String
In the first argument of notFollowedBy', namelyregName'
In a stmt of a 'do' block: notFollowedBy regName

Ord instance for SockAddr

Network.Socket.Internal does not derive Ord. An Ord instance would be useful for instance in a UDP multicast client where packets from multiple senders could be interleaved, and hence it would be useful to keep a Map from SockAddr to the data received from those SockAddr (as just one use case).

build error on Centos 5.8: IOV_MAX undeclared

when building version (2.4.0.1) on Centos 5.8 with ghc-7.6.1 I get

Bytestring.hsc:204:5: error: 'IOV_MAX' undeclared

building 2.3.1.1 works (that is the version that gets pulled in for bootstrapping cabal-install)

Configure fails with CC=clang

Verbose output of cabal-install

Reading available packages...
Choosing modular solver.
Resolving dependencies...
Ready to install network-2.4.1.2
Extracting
/home/nagisa/cache/cabal/packages/hackage.haskell.org/network/2.4.1.2/network-2.4.1.2.tar.gz
to /tmp/network-2.4.1.2-31060...
Waiting for install task to finish...
Updating network.cabal with the latest revision from the index.
Configuring network-2.4.1.2...
creating /tmp/network-2.4.1.2-31060/network-2.4.1.2/dist/setup
creating /tmp/network-2.4.1.2-31060/network-2.4.1.2/dist
creating /tmp/network-2.4.1.2-31060/network-2.4.1.2/dist/setup
/usr/bin/ghc --make /tmp/network-2.4.1.2-31060/network-2.4.1.2/dist/setup/setup.hs -o /tmp/network-2.4.1.2-31060/network-2.4.1.2/dist/setup/setup -odir /tmp/network-2.4.1.2-31060/network-2.4.1.2/dist/setup -hidir /tmp/network-2.4.1.2-31060/network-2.4.1.2/dist/setup -i -i/tmp/network-2.4.1.2-31060/network-2.4.1.2 -package Cabal-1.16.0
/tmp/network-2.4.1.2-31060/network-2.4.1.2/dist/setup/setup configure
--verbose=2 --ghc --prefix=/home/nagisa/local --enable-shared
--enable-executable-dynamic --enable-optimization --disable-split-objs
--enable-executable-stripping --user --constraint=unix ==2.6.0.1
--constraint=parsec ==3.1.3 --constraint=bytestring ==0.10.0.2
--constraint=base ==4.6.0.1 --disable-tests --disable-benchmarks
Redirecting build log to {handle:
/home/nagisa/.cabal/logs/network-2.4.1.2.log}
Failed to install network-2.4.1.2
Last 10 lines of the build log ( /home/nagisa/.cabal/logs/network-2.4.1.2.log
):
No uhc found
sh configure --with-compiler=ghc --prefix=/home/nagisa/local
--with-gcc=/usr/bin/gcc
configure: WARNING: unrecognized options: --with-compiler, --with-gcc
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking for gcc... clang
checking whether the C compiler works... no
configure: error: in `/tmp/network-2.4.1.2-31060/network-2.4.1.2':
configure: error: C compiler cannot create executables
See `config.log' for more details
Updating world file...
cabal: Error: some packages failed to install:
network-2.4.1.2 failed during the configure step. The exception was:
ExitFailure 77

c_connect should not be an unsafe foreign import on Windows

This ticket fell by the wayside when the network package switched to github: http://trac.haskell.org/network/ticket/44


On Windows with -threaded, when Network.Socket.connect is called, it blocks the whole RTS until the connection attempt succeeds or fails.

This is because under the hood, it is calling c_connect, an unsafe foreign import:

foreign import CALLCONV unsafe "connect"
  c_connect :: CInt -> Ptr SockAddr -> CInt{-CSockLen???-} -> IO CInt

Unsafe foreign calls block the whole runtime system. Safe foreign calls block only the current thread (but cannot be interrupted by exceptions).

I tested it on Windows with network-2.3.0.8, and Network.Socket.connect does in fact block the whole program. When I changed unsafe to safe and recompiled, it did not block the whole program.

It seems clear that c_connect should be a safe foreign import, at least on Windows with -threaded. Are there any other foreign calls marked safe that could potentially block on Windows?

: stored in the scheme?

I expected:

show $ URI "http" Nothing "" "" ""

to give me http: but instead it gave me http. Further experiments seem to show that it expects the scheme to contain the literal : ... this seems suboptimal. The : is not part of the scheme name, but is part of the construction the URI grammar. I should not be able to get show on a URI to output http//a/a, but I can.

Repository branch layout is a little confusing

So there's some dev work I want to do on network – perhaps resolving one of the issues I've submitted – but I don't know where to start work. There are three branches, master, stable, and develop. I don't know what the relationship is between master and develop, and paradoxically it seems that stable is the most updated.

Would be helpful if the readme could provide some guidance as to where new work should start from :)

Add support for GHC 7.2.1-rc1

The current version dependancy on base is too strict for ghc-7.2.1-rc1's bundled base-4.4.0.0 library, the following patch fixes the stable branch's network-2.3.0.4

diff --git a/network.cabal b/network.cabal
index 3901886..a44c24d 100644
--- a/network.cabal
+++ b/network.cabal
@@ -39,7 +39,7 @@ library
       Network.Socket.ByteString.MsgHdr

   build-depends:
-    base >= 3 && < 4.4,
+    base >= 3 && < 4.5,
     bytestring < 1.0,
     parsec >= 2.0 && < 3.2

Can't use on Windows

In cygwin, after setting the correct path, I was able to build the network library and install it (simple "cabal install network" did the trick). However, it appears to be unusable: simple "Network.withSocketsDo $ return ()" gave me "ghc.exe: unable to load package 'network-2.4.1.2' and ": C:\ghc\network-2.4.1.2\ghc-7.6.2\HSnetwork-2.4.1.2.o: unknown symbol `getWSErrorDescr'"

I've tried to follow Neil Mitchell's solution and add "--configure-option --host=i386-unknown-mingw32". No luck: it still produces an unusable library, this time complaining about __imp_WSACleanup.

Module `Network.Socket.ByteString.Lazy' does not export `send'

A user of hosc reported the below on W32.

Sound\OSC\Transport\FD\UDP.hs:9:55:
Module Network.Socket.ByteString.Lazy' does not exportsend'

I now see the documentation says 'Unix only'.

I'm wondering if network could provide a fallback version for W32?

Otherwise it seems each client that sends lazy data need to write the same #ifdef code?

Or always repack to strict before sending?

network-2.3.0.12 fails to build against base < 4.4.0 on Windows

Recent introduction of catchIOError in IPV6_V6ONLY fix in network-2.3.0.12 causes build to fail against base-4.3.1.0:

checking whether IPV6_V6ONLY is declared... yes
checking for sendfile in sys/sendfile.h... no
checking for sendfile in sys/socket.h... no
checking for gethostent... no
configure: creating ./config.status
config.status: creating network.buildinfo
config.status: creating include/HsNetworkConfig.h
Preprocessing library network-2.3.0.12...
Preprocessing test suites for network-2.3.0.12...
Building network-2.3.0.12...
[1 of 8] Compiling Network.URI      ( Network\URI.hs, dist\build\Network\URI.o )
[2 of 8] Compiling Network.Socket.ByteString.Internal ( Network\Socket\ByteString\Internal.hs, dist\build\Network\Socket\ByteString\Internal.o )
[3 of 8] Compiling Network.Socket.Internal ( dist\build\Network\Socket\Internal.hs, dist\build\Network\Socket\Internal.o )

Network\Socket\Internal.hsc:81:1:
    Warning: Module `GHC.IOBase' is deprecated: use GHC.IO instead
[4 of 8] Compiling Network.Socket   ( dist\build\Network\Socket.hs, dist\build\Network\Socket.o )

Network\Socket.hsc:431:13: Not in scope: `catchIOError'
cabal: Error: some packages failed to install:
network-2.3.0.12 failed during the building phase. The exception was:
ExitFailure 1

catchIOError is only availabe in base >= 4.4.0.

using catch satisfies the whole range dependency range on base >= 3 && < 4.6 for network-2.3.0.12.

No ReusePort in network-2.3.0.2

ppavel reports that "network-2.3.0.2 coming with haskell platform 2011.2.0.0 does not have ReusePort? constructor in SocketOption? type under windows".

Configure not generated in 2.3.0.6

Hi,

it seems that the v6only-patch did not fully make it into 2.3.0.6: It is in configure.ac, but not in configure:

$ cabal unpack network-2.3.0.6
Unpacking to network-2.3.0.6/
$ cd network-2.3.0.6/
$ fgrep -ri v6only  .
./Network/Socket.hsc:-- If 'AF_INET6' is used, the 'IPv6Only' socket option is set to 0
./Network/Socket.hsc:#ifdef HAVE_DECL_IPV6_V6ONLY
./Network/Socket.hsc:    when (family == AF_INET6) $ setSocketOption sock IPv6Only 0
./Network/Socket.hsc:#ifdef HAVE_DECL_IPV6_V6ONLY
./Network/Socket.hsc:    | IPv6Only      {- IPV6_V6ONLY -}
./Network/Socket.hsc:#ifdef HAVE_DECL_IPV6_V6ONLY
./Network/Socket.hsc:    IPv6Only     -> #const IPPROTO_IPV6
./Network/Socket.hsc:#ifdef HAVE_DECL_IPV6_V6ONLY
./Network/Socket.hsc:    IPv6Only      -> #const IPV6_V6ONLY
./Network.hs:-- If available, the 'IPv6Only' socket option is set to 0
./Network.hs:    -- handle both IPv4 and IPv6 if v6only is false.
./configure.ac:dnl * test for IPV6_V6ONLY flags that not all implementations have
./configure.ac:AC_CHECK_DECLS([IPV6_V6ONLY])

I guess you need to run autoconf and re-upload. (And I guess I should check package changes more thoroughly before uploading them to Debian...)

Timeout socket options are unusable

The setSockOpt API only allows setting options that take a CInt, but the RecvTimeOut option (for example) translates to SO_RCVTIMEO which expects a struct timeval. In my opinion it doesn't make any sense to mirror the underlying setsockopt C function with just one Haskell function; getsockopt is just as bad.

The underlying foreign import has a Ptr CInt argument, but the C function uses void*, so a Ptr a would probably be more appropriate. But this doesn't make a great deal of difference since it's not exported anyway.

While I'm here, does it really make sense to have an API that changes based on which computer it's compiled on? It's not a very helpful error message.

Make network I/O interruptible on Windows

Currently, for Windows with the threaded RTS, network I/O is done with blocking FFI calls. Since FFI calls can't be interrupted, network I/O can't be interrupted. The following example illustrates the problem:

-- Compile on Windows with -threaded
import Control.Concurrent
import Network
import System.IO
import System.Timeout

server sock = do
    (h, host, port) <- accept sock
    putStrLn $ "server: accepted connection from " ++ host ++ ":" ++ show port
    threadDelay 20000000 -- Make client recv block for a long time
    hPutStrLn h "Thank you for your patience"

client = do
    h <- connectTo "localhost" $ PortNumber 1234
    putStrLn "client: connected to server"
    m <- timeout 5000000 $ hGetLine h
    case m of
        Nothing   -> putStrLn "client: hGetLine took too long"
        Just line -> putStrLn $ "client: received " ++ show line

main = withSocketsDo $ do
    sock <- listenOn $ PortNumber 1234
    _ <- forkIO $ server sock
    client

Here, timeout doesn't really work. It does eventually time out, but only after the server finally sends data, waking up the blocking system call.

If you compile on Windows without -threaded, the timeout does work, but the operation isn't actually canceled.

This is a real problem for networked programs that need to run unattended for long periods of time. If a host becomes unresponsive, it can cause unexpected blockage. Working around this problem is difficult and annoying.


Windows does not seem to have a scalable socket polling facility like epoll or kqueue. Here are some of our options:

From what I've read, I/O completion ports is the most efficient and scalable concurrent I/O facility on Windows. However, some problems make it difficult to use:

  • Need to use system functions that support overlapped I/O, such as ConnectEx, AcceptEx, WSARecv, etc. Some of these functions have hidden surprises. For example, ConnectEx requires the socket to be initially bound, and requires setting the SO_UPDATE_CONNECT_CONTEXT socket option before shutdown will work properly.

  • Overlapped I/O is sensitive to the calling thread:

    • When a thread exits, all pending overlapped I/O issued by that thread is canceled.
    • CancelIo cancels all pending I/O issued by the calling thread for a given handle. CancelIoEx lets you specify the operation to cancel, but it requires Windows Vista or later.

    It is possible to work around this by sending I/O requests to worker threads. However, this means two thread context switches per operation. To avoid this, we'd need to integrate completion port handling into GHC's scheduler.

WSAEventSelect, in tandem with RegisterWaitForSingleObject, can be used to poll sockets, and scales up to roughly 25,000 concurrent waits. The downside is that WSAEventSelect automatically puts the socket in nonblocking mode, and cancels any other WSAEventSelect operations on the same socket. This means we would need to coordinate the waits.

select is the least scalable option, but is easiest to implement. The issue with select is that it can't be interrupted asynchronously. Potential workarounds:

  • Call select over and over with a timeout.
  • Create a dummy socket, pass it to select, and close the socket to wake up the select call. This is a little dangerous, though. If we close the socket before select begins, another thread may allocate a socket with the newly-freed descriptor number.

Here's what I plan to do:

  • Switch to nonblocking sockets on Windows. Poll by calling select, from a forkIO, again and again with a timeout.
  • Use the new polling facility throughout the Network.Socket API (most of the preliminary work has already been done).
  • Implement our own IODevice and BufferedIO instances in the network package, at least for Windows.

Using select isn't the most efficient solution, but it's the easiest to implement. I currently don't have the time or the need to implement the I/O completion port approach.

Fails on Windows w/o MSYS

cabal: The package has a './configure' script. This requires a Unix compatibility toolchain such as MinGW+MSYS or Cygwin.

There are some solutions over the Internet (like this one http://www.haskell.org/pipermail/haskell-cafe/2012-February/099633.html) but none worked for me. MSYS can't connect to mingw installed in the path with spaces in it, which is the default one for Haskell Platform, and which is the only one used by Agda installer.

  1. Wouldn't it be smart to eradicate the use of GNU toolchain to keep the library cross-platform?
  2. If configure is a strictly must-use tool, shouldn't we ask to include MSYS into Haskell Platform with proper default setup?

Build broken for GHC 6.10

The dependencies for the network package state "base >= 3", so I assume it's supposed to build with 6.10. But currently it fails due to an unrecognized flag in a pragma:

Preprocessing library network-2.4.0.0...
Internal.hsc: In function ‘main’:
Internal.hsc:199:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long unsigned int’ [-Wformat]
Preprocessing test suites for network-2.4.0.0...
Building network-2.4.0.0...
Network/Socket.hsc:2:15-58:
    unknown flag in  {-# OPTIONS #-} pragma: -fno-warn-unused-do-bind
cabal: Error: some packages failed to install:
network-2.4.0.0 failed during the building phase. The exception was:
ExitFailure 1

I think this could be fixed by moving the -fno-warn-unused-do-bind flag into the .cabal file, and guarding it with a version check.

Alternatively, if GHC 6.10 is no longer supported, please update the minimum base version so an older version of "network" will be selected.

Unescaping URI doesn't recreate unicode characters

Since 23c1007 (see #51), unicode characters in strings are escaped the way browsers do: encode as UTF8, and use the bytes from that to percent-encode. However, during unescaping no UTF8-decoding is done. This means that (decode . encode) is not the identity, and results in malformed strings. For example, if I take the string from test case testEscapeURIString06 and unescape it, I get:

> putStrLn $ unEscapeString (escapeURIString isUnescapedInURIComponent "helloø©日本")
helloø©��

Ordered instance for SockAddr

When working with UDP sockets I like to have a Map or Set to keep track of addresses. SockAddr doesn't, however, define an Ordered interface by default .

Is there a good reason against it or could it be considered to add it?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.