UDP reception bug in ghc-5.02.1 ?

Sigbjorn Finne sof at galois.com
Thu Dec 13 03:22:40 EST 2001


Hi,

yep, it's a bug in SocketPrim.recvFrom - it's busted in 5.02.1, I'm afraid.
It fails to init the 'fromlen' arg before calling recvfrom() + it doesn't
work with connection-oriented sockets (not that the latter is affecting
you here), which is why it fails to unravel the SockAddr once
recvfrom() returns.  Fixed in the current dev sources.

--sigbjorn

btw, you probably want to add a type signature for 'receiverPort', i.e.,

  receiverPort :: PortNumber

That way you avoid having to define your own intToPortNumber.

----- Original Message ----- 
From: "Rafael Lorandi de Oliveira" <lorandi at asga.com.br>
To: <glasgow-haskell-bugs at haskell.org>
Cc: <rafael.oliveira at sigmabbs.com.br>
Sent: Friday, December 07, 2001 05:08
Subject: UDP reception bug in ghc-5.02.1 ?


> Good morning,
> 
> I am implementing a communication system in Haskell via UDP, and (I 
> think) I've foud a bug in SocketPrim. Would you mind taking a look :-) ?
> 
> Consider the codes "udpSend.hs" and "udpRecv.hs":
> 
> 
> 
> 
> -- udpSend.hs
> -- send "Hello World" to port UDP:1500 of a remote host
> --
> -- compiled and tested with ghc-5.02.1
> -- compile with: ghc -fglasgow-exts --make -package net -o udpSend 
> udpSend.hs
> -- run with: ./udpSend <remoteHost>
> 
> module Main where
> 
> import Word
> import IO
> import System
> import SocketPrim
> import BSD
> 
> receiverPort = 1500
> 
> main :: IO ()
> main = do
> 
>   protoNum <- BSD.getProtocolNumber "udp"
>   sock <- SocketPrim.socket AF_INET Datagram protoNum
> 
>   let sin_port = SocketPrim.aNY_PORT
>       sin_addr = SocketPrim.iNADDR_ANY
>       sockAddr = SocketPrim.SockAddrInet sin_port sin_addr in
>     SocketPrim.bindSocket sock sockAddr
> 
>   args <- System.getArgs
>   hEntry <- BSD.getHostByName (head args)
> 
>   -- SocketPrim doesn't export 'intToPortNumber'. Is there a better way 
> to do this?
>   let sin_port = Main.intToPortNumber receiverPort
>       sin_addr = BSD.hostAddress hEntry
>       sendAddr = SocketPrim.SockAddrInet sin_port sin_addr in
>     SocketPrim.sendTo sock "Hello World" sendAddr
> 
>   return ()
> 
> 
> intToPortNumber :: Int -> PortNumber
> intToPortNumber v = PortNum (htons (fromIntegral v))
> 
> foreign import "htons" unsafe htons :: Word16 -> Word16
> 
> 
> 
> 
> -- udpRecv.hs
> -- listen port UDP:1500 and print received data
> --
> -- compiled and tested with ghc-5.02.1
> -- compile with: ghc -fglasgow-exts --make -package net -o udpRecv 
> udpRecv.hs
> -- run with: ./udpRecv
> 
> module Main where
> 
> import Word
> import IO
> import System
> import SocketPrim
> import BSD
> 
> receiverPort = 1500
> maxMsg = 100
> 
> main :: IO ()
> main = do
> 
>   protoNum <- BSD.getProtocolNumber "udp"
>   sock <- SocketPrim.socket AF_INET Datagram protoNum
> 
>   -- SocketPrim doesn't export 'intToPortNumber'. Is there a better way 
> to do this?
>   let sin_port = Main.intToPortNumber receiverPort
>       sin_addr = SocketPrim.iNADDR_ANY
>       sockAddr = SocketPrim.SockAddrInet sin_port sin_addr in
>     SocketPrim.bindSocket sock sockAddr
> 
>   (recvHello, _, (SockAddrInet sin_port sin_addr)) <- 
> SocketPrim.recvFrom sock maxMsg
> 
>   addr <- SocketPrim.inet_ntoa sin_addr
>   IO.putStrLn ("udpRecv: from " ++ addr ++ ":UDP" ++ (show sin_port) ++ 
> " : " ++ recvHello)
> 
>   return ()
> 
> 
> intToPortNumber :: Int -> PortNumber
> intToPortNumber v = PortNum (htons (fromIntegral v))
> 
> foreign import "htons" unsafe htons :: Word16 -> Word16
> 
> 
> 
> 
> This is what happens in my machine (Debian GNU/Linux 2.2r3 with kernel 
> 2.2.19):
> 
> (terminal #1)
> ...$ ./udpRecv
> (blocking at 'recvFrom')
> 
> (terminal #2)
> ...$ ./udpSend 10.0.10.195
> ...$
> 
> (terminal #1)
> 
> Fail: SocketPrim.hsc:241: Non-exhaustive patterns in case
> 
> ...$
> 
> 
> This happens because "family" enters the case statement with the value 0 
> (zero) in SocketPrim.peekSockAddr.
> 
> If I build C versions of udpSend and udpReceive, I have:
>   - udpSend.c  with  udpSend.c --> OK
>   - udpSend.c  with  udpRecv.hs --> Fail
>   - udpSend.hs  with  udpRecv.c --> OK
> 
> Therefore I think the problem is into the reception application (right?).
> 
> 
> Thanks in advance.
> 
> Best regards,
> Rafael Lorandi de Oliveira
> Development Engineer - R&D
> AsGa S/A
> www.asga.com.br
> 






More information about the Glasgow-haskell-bugs mailing list