@@ -15,7 +15,7 @@ import Network.Socket
15 ( AddrInfoFlag (AI_PASSIVE), HostName, ServiceName, Socket
15 ( AddrInfoFlag (AI_PASSIVE), HostName, ServiceName, Socket
16 , SocketType (Stream), SocketOption (ReuseAddr)
16 , SocketType (Stream), SocketOption (ReuseAddr)
17 , accept, addrAddress, addrFlags, addrFamily, bindSocket, defaultProtocol
17 , accept, addrAddress, addrFlags, addrFamily, bindSocket, defaultProtocol
18− , getAddrInfo, listen, setSocketOption, socket, withSocketsDo )
18+ , getAddrInfo, listen, setSocketOption, socket, sClose, withSocketsDo )
19import Safe
19import Safe
21import qualified Data.ByteString.Char8 as BS
21import qualified Data.ByteString.Char8 as BS
@@ -23,7 +23,7 @@ import qualified Data.IntMap as IntMap
23import qualified Network.Socket as N
23import qualified Network.Socket as N
24import qualified Network.Socket.ByteString as NBS
24import qualified Network.Socket.ByteString as NBS
26−type Chans = MVar (Int, IntMap (Chan ByteString))
26+type Chans = MVar (Int, IntMap (Chan ByteString, MVar [Socket]))
27type ChanId = Int
27type ChanId = Int
29-- | This deals with several different configuration properties:
29-- | This deals with several different configuration properties:
@@ -51,14 +51,15 @@ mkTransport (TCPConfig _hints host service) = withSocketsDo $ do
51 sock <- socket (addrFamily serverAddr) Stream defaultProtocol
51 sock <- socket (addrFamily serverAddr) Stream defaultProtocol
52 bindSocket sock (addrAddress serverAddr)
52 bindSocket sock (addrAddress serverAddr)
53 listen sock 5
53 listen sock 5
54− forkIO $ procConnections channels sock
54+ _ <- forkIO $ procConnections channels sock
56 return Transport
56 return Transport
57 { newConnectionWith = \_ -> do
57 { newConnectionWith = \_ -> do
58 (chanId, chanMap) <- takeMVar channels
58 (chanId, chanMap) <- takeMVar channels
59 chan <- newChan
59 chan <- newChan
60+ socks <- newMVar [sock]
60− putMVar channels (chanId + 1, IntMap.insert chanId chan chanMap)
61+ putMVar channels (chanId + 1, IntMap.insert chanId (chan, socks) chanMap)
61− return (mkSourceAddr host service chanId, mkTargetEnd chan)
62+ return (mkSourceAddr host service chanId, mkTargetEnd chan socks)
62 , newMulticastWith = undefined
63 , newMulticastWith = undefined
63 , deserialize = \bs ->
64 , deserialize = \bs ->
64 case readMay . BS.unpack $ bs of
65 case readMay . BS.unpack $ bs of
@@ -85,14 +86,16 @@ mkTransport (TCPConfig _hints host service) = withSocketsDo $ do
85 NBS.sendAll sock $ BS.pack . show $ chanId
86 NBS.sendAll sock $ BS.pack . show $ chanId
86 return $ SourceEnd
87 return $ SourceEnd
87 { send = \bss -> NBS.sendMany sock bss
88 { send = \bss -> NBS.sendMany sock bss
89+ , close = sClose sock
90− mkTargetEnd :: Chan ByteString -> TargetEnd
92+ mkTargetEnd :: Chan ByteString -> MVar [Socket] -> TargetEnd
91− mkTargetEnd chan = TargetEnd
93+ mkTargetEnd chan socks = TargetEnd
92 { -- for now we will implement this as a Chan
94 { -- for now we will implement this as a Chan
93 receive = do
95 receive = do
94 bs <- readChan chan
96 bs <- readChan chan
95 return [bs]
97 return [bs]
98+ , closeAll = takeMVar socks >>= mapM_ sClose
98 procConnections :: Chans -> Socket -> IO ()
101 procConnections :: Chans -> Socket -> IO ()
@@ -107,9 +110,11 @@ mkTransport (TCPConfig _hints host service) = withSocketsDo $ do
107 (_, chanMap) <- readMVar chans
110 (_, chanMap) <- readMVar chans
108 case IntMap.lookup chanId chanMap of
111 case IntMap.lookup chanId chanMap of
109 Nothing -> error "procConnections: cannot find chanId"
112 Nothing -> error "procConnections: cannot find chanId"
113+ Just (chan, socks) -> do
114+ modifyMVar_ socks (return . (clientSock :))
110− Just chan -> forkIO $ do
115+ forkIO $ do
111− unless (BS.null bs') $ writeChan chan bs'
116+ unless (BS.null bs') $ writeChan chan bs'
112− procMessages chan clientSock
117+ procMessages chan clientSock
114 procMessages :: Chan ByteString -> Socket -> IO ()
119 procMessages :: Chan ByteString -> Socket -> IO ()
115 procMessages chan sock = forever $ do
120 procMessages chan sock = forever $ do