@@ -63,15 +63,17 @@ import qualified Data.ByteString.Char8 as B
63import qualified Data.ByteString.Lazy as L
63import qualified Data.ByteString.Lazy as L
64import Network (sClose, Socket)
64import Network (sClose, Socket)
65import Network.Socket
65import Network.Socket
66− ( accept, SockAddr (SockAddrInet), Family (AF_INET)
66+ ( accept, Family (..)
67− , SocketType (Stream), listen, bindSocket, setSocketOption
67+ , SocketType (Stream), listen, bindSocket, setSocketOption, maxListenQueue
68− , SocketOption (ReuseAddr), iNADDR_ANY, inet_addr, SockAddr (SockAddrInet)
68+ , SockAddr, SocketOption (ReuseAddr)
69+ , AddrInfo(..), AddrInfoFlag(..), defaultHints, getAddrInfo
70import qualified Network.Socket
71import qualified Network.Socket
71import qualified Network.Socket.ByteString as Sock
72import qualified Network.Socket.ByteString as Sock
72import Control.Exception
73import Control.Exception
73 ( bracket, finally, Exception, SomeException, catch
74 ( bracket, finally, Exception, SomeException, catch
74 , fromException, AsyncException (ThreadKilled)
75 , fromException, AsyncException (ThreadKilled)
76import Control.Concurrent (forkIO)
78import Control.Concurrent (forkIO)
77import qualified Data.Char as C
79import qualified Data.Char as C
@@ -112,13 +114,26 @@ import Network.Socket (withSocketsDo)
113bindPort :: Int -> String -> IO Socket
115bindPort :: Int -> String -> IO Socket
114bindPort p s = do
116bindPort p s = do
115− sock <- Network.Socket.socket AF_INET Stream 0
117+ let hints = defaultHints { addrFlags = [AI_PASSIVE
116− h <- if s == "*" then return iNADDR_ANY else inet_addr s
118+ , AI_NUMERICSERV
117− let addr = SockAddrInet (fromIntegral p) h
119+ , AI_NUMERICHOST]
120+ , addrSocketType = Stream }
121+ host = if s == "*" then Nothing else Just s
122+ port = Just . show $ p
123+ addrs <- getAddrInfo (Just hints) host port
124+ -- Choose an IPv6 socket if exists. This ensures the socket can
125+ -- handle both IPv4 and IPv6 if v6only is false.
126+ let addrs' = filter (\x -> addrFamily x == AF_INET6) addrs
127+ addr = if null addrs' then head addrs else head addrs'
129+ (Network.Socket.socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr))
118− setSocketOption sock ReuseAddr 1
132+ setSocketOption sock ReuseAddr 1
119− bindSocket sock addr
133+ bindSocket sock (addrAddress addr)
120− listen sock 150
134+ listen sock maxListenQueue
121− return sock
135+ return sock
123-- | Run an 'Application' on the given port. This calls 'runSettings' with
138-- | Run an 'Application' on the given port. This calls 'runSettings' with
124-- 'defaultSettings'.
139-- 'defaultSettings'.