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