Bug in network library,
uncaught exception when dealing with ipv6 sockets
Thomas Hartman
tphyahoo at gmail.com
Thu Jan 8 11:20:05 EST 2009
And here's a refinement, without that ugly undefined cluttering things up:
#if defined(IPV6_SOCKET_SUPPORT)
accept sock@(MkSocket _ AF_INET6 _ _ _) = do
(sock', addr@((SockAddrInet port haddr) )) <- Socket.accept sock
(Just peer) <- catchIO ( return . fst =<< getNameInfo [] True False addr )
(\e -> return . Just =<< inet_ntoa haddr )
handle <- socketToHandle sock' ReadWriteMode
(PortNumber port) <- socketPort sock'
return (handle, peer, port)
#endif
2009/1/8 Thomas Hartman <tphyahoo at gmail.com>:
> There is an uncaught exception in the network library which is causing
> my HAppS demo website
>
> http://happstutorial.com
>
> to crash every couple of days. This has affected other people using
> HAppS as well, as described on postings to the HAppS users list.
>
> The bug, and workarounds, is described at
>
> http://code.google.com/p/happs/issues/detail?id=40
>
> This message is to suggest a fix for the issue.
>
> The problem seems to me to be localized in the following bit of code,
> from -- http://hackage.haskell.org/packages/archive/network/2.2.0.1/doc/html/src/Network.html#accept
>
> ***************************
>
> #if defined(IPV6_SOCKET_SUPPORT)
> accept sock@(MkSocket _ AF_INET6 _ _ _) = do
>
> (sock', addr) <- Socket.accept sock
>
> (Just peer, _) <- getNameInfo [] True False addr
>
>
> handle <- socketToHandle sock' ReadWriteMode
> (PortNumber port) <- socketPort sock'
>
>
> return (handle, peer, port)
>
> #endif
> ***************************
>
> The problem is that getNameInfo can give rise to an IO exception,
> which should be caught at the library level. An exception IS caught at
> the library level when fetching peer for ipv4 packets, as follows.
> Since the code can never crash when fetching peer for ipv4 packets, it
> seems to me it shouldn't be allowed to crash when fetching peer for
> ipv6 packets either.
>
> ip v4 packet code:
>
> ***************************
> accept sock@(MkSocket _ AF_INET _ _ _) = do
> ~(sock', (SockAddrInet port haddr)) <- Socket.accept sock
> peer <- catchIO
> (do
> (HostEntry peer _ _ _) <- getHostByAddr AF_INET haddr
> return peer
> )
> (\e -> inet_ntoa haddr)
> -- if getHostByName fails, we fall back to the IP address
> handle <- socketToHandle sock' ReadWriteMode
> return (handle, peer, port)
> ***************************
>
> My suggestion for fixing for ipv6 is as follows, basically having
> similar error catching as for ipv4.
>
> ***************************
>
> #if defined(IPV6_SOCKET_SUPPORT)
> accept sock@(MkSocket _ AF_INET6 _ _ _) = do
> (sock', addr@((SockAddrInet port haddr) )) <- Socket.accept sock
> (Just peer, _) <- catchIO ( getNameInfo [] True False addr )
> (\e -> do peerAsIp <- inet_ntoa haddr
> return (Just peerAsIp, undefined))
>
>
> handle <- socketToHandle sock' ReadWriteMode
> (PortNumber port) <- socketPort sock'
> return (handle, peer, port)
> #endif
>
> ***************************
>
> Des this seem reasonable?
>
> Of course, please advise if I should repost this issue to the ghc
> bugtracker, or similar.
>
> Thanks also to Matt Elder for being very generous with his time in
> helping me diagnose this. And also thanks to the others on the
> above-linked HAppS bug thread.
>
> Thomas.
>
More information about the Libraries
mailing list