how to listen on a specific IP using the network library
I would really like to modify happstack so that you can specific what IP address to listen on.
So I think I want a function like:
listenOnAddr :: SockAddr -> IO Socket
The problem is that the user might want to specify IPv4 or IPv6 address. But support for IPv6 is only conditionally compiled into the network library.
I can not figure out how to write my code so that it will compile regardless of whether network was compiled with ipv6 enabled.
I got this far:
import qualified Control.Exception as Exception
import Network.BSD (getProtocolNumber)
listenOnAddr :: Family -> SocketType -> SockAddr -> IO Socket
listenOnAddr fam typ sockAddr =
do proto <- getProtocolNumber "tcp"
(socket fam typ proto)
(\sock -> do
setSocketOption sock ReuseAddr 1
bindSocket sock sockAddr
listen sock maxListenQueue
But I am not sure how to modify it to calculate 'fam' and 'typ' from 'sockAddr' with out making my code depend on IPv6 being enabled.
If I was adding this function directly to the network package, there would be no problem. I could just use:
But in a 3rd party library IPV6_SOCKET_SUPPORT is not defined. I could copy the autoconf code into my library -- but there is no guarantee that my library and the network library were compiled with the same value for IPV6_SOCKET_SUPPORT.
In happstack we use a really horrible trick involving template haskell where we see if the SockAddrInet6 constructor exists at compile time and conditionally compile different versions of the code that way. But it is really ugly. We defined supportsIPv6 here:
It wouldn't be that bad if we could actually use the [| |] mechanism. But we can't because it won't compile when ipv6 support is not enabled due to '(S.SockAddrInet6 _ _ ha _) -> showHostAddress6 ha'.
Any suggestions? At this point I am thinking that the best solution is to add a new function to network, since it is not trivial to do it anywhere else in a portable way, and it seems like a fairly useful and common operation?
Re: how to listen on a specific IP using the network library
On Mar 15, 2010, at 12:09 PM, Jeremy Shaw wrote:
> In happstack we use a really horrible trick involving template
> haskell where we see if the SockAddrInet6 constructor exists at
> compile time and conditionally compile different versions of the
> code that way. But it is really ugly.
Maybe a simpler code generator would be a better fit, since this task
isn't really parametrized over types? I'm not familiar with cabal
really -- can you drop down to bash? Can you run an arbitrary
program? Or at least one in the cwd? Or at the very least, one you
just built? If so, a simple bash script (or Haskell program) can emit
valid Haskell to compile. It can (potentially) be as simple as
concatenating your IPv6 instances/data to the end of the "default"
Haskell-Cafe mailing list
[hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe