Re: Network.Socket endian problem?
On 12/14/06, Tomasz Zielonka <[EMAIL PROTECTED]> wrote: On Thu, Dec 14, 2006 at 05:22:43PM +0100, Ferenc Wagner wrote: > Tomasz Zielonka <[EMAIL PROTECTED]> writes: > > > Who agrees with me that it would be nice if network libraries used host > > byte order in their interface? Or at least they could use an abstract > > data type, whose byte order would be unobservable. > > Why is this trapdoor present in the C library? I don't know. Maybe for efficiency? The only mention I could find related to this is in W. Richards Stevens' "Unix Network Programming": "In theory an implementation could store the fields in a socket address structure in host byte order and then convert to and from the network byte order when moving the fields to and from the protocol headers, saving us from having to worry about this detail. But both history and Posix.1g specify that certain fields in the socket address structures be maintained in network byte order." Not very satisfactory. But even if the socket address details were hidden, the data itself may require a certain endianness. The htonl(), et al. functions assist in this detail for C programmers. I didn't see any functions in the Haskell Network or Marshall libraries that help Haskell programmers write out network byte order values. I didn't check any third party libraries yet. -- Rich AIM : rnezzy ICQ : 174908475 ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Network.Socket endian problem?
On Thu, Dec 14, 2006 at 05:22:43PM +0100, Ferenc Wagner wrote: > Tomasz Zielonka <[EMAIL PROTECTED]> writes: > > > On Wed, Dec 13, 2006 at 03:54:59PM -0600, Mark Hills wrote: > >> It does expect the address to be in network byte order instead of host > >> byte order, which is usually done using htons and htonl. This seems to > >> do what you want (running SUSE 10.1 on an Intel box): > > > > Who agrees with me that it would be nice if network libraries used host > > byte order in their interface? Or at least they could use an abstract > > data type, whose byte order would be unobservable. > > Why is this trapdoor present in the C library? I don't know. Maybe for efficiency? Best regards Tomasz ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Network.Socket endian problem?
Tomasz Zielonka <[EMAIL PROTECTED]> writes: > On Wed, Dec 13, 2006 at 03:54:59PM -0600, Mark Hills wrote: >> It does expect the address to be in network byte order instead of host >> byte order, which is usually done using htons and htonl. This seems to >> do what you want (running SUSE 10.1 on an Intel box): > > Who agrees with me that it would be nice if network libraries used host > byte order in their interface? Or at least they could use an abstract > data type, whose byte order would be unobservable. Why is this trapdoor present in the C library? -- Feri. ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Network.Socket endian problem?
On 12/13/06, Sigbjorn Finne <[EMAIL PROTECTED]> wrote: as you've time-consumingly discovered, Network.Socket.HostAddress is represented in network byte order (something that's not well documented, and a potential trap.) You may want to consider using Network.Socket.inet_addr as a constructor. Thanks to everyone for their help and suggestions. I agree, however, with Tomasz that the address should be in host byte order to the application. At the very least, the port value and the address should use the same byte ordering. For now, I'll use inet_addr as a constructor. Thanks again. -- Rich AIM : rnezzy ICQ : 174908475 ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Network.Socket endian problem?
Hi, as you've time-consumingly discovered, Network.Socket.HostAddress is represented in network byte order (something that's not well documented, and a potential trap.) You may want to consider using Network.Socket.inet_addr as a constructor. --sigbjorn Rich Neswold wrote: Hello, I've written a program that uses UDP as its communication with other processes. It was built with GHC 6.4.1 on MacOS 10.4 (PowerPC) and works fine. When I moved the code to a Linux box (i386) and built it with GHC 6.6, it didn't work. The problems turns out to be, apparently, an endian problem. The socket is created with the following snippet: allocSocket :: IO Socket allocSocket = do { s <- socket AF_INET Datagram 0 ; handle (\e -> sClose s >> throwIO e) $ do { connect s (SockAddrInet 6802 0x7f01) ; return s } } On the Macintosh, the socket only receives packets from 127.0.0.1:6802, which is correct (and works). On the Linux machine, the socket only accepts packets from 1.0.0.127:6802. The data constructor SockAddrInet doesn't swap the bytes of the address (although it correctly swaps the bytes of the port number!) Changing the data constructor call to (SockAddrInet 6802 0x017f) makes it work on Linux, but not on MacOS 10.4. (You can see what the socket is bound to, on Linux, with "netstat -aun".) I don't have access to GHC 6.4.1 on a Linux box to determine whether this is a regression in 6.6 or simply an overlooked detail. Should I file a PR? Am I doing something wrong? ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Network.Socket endian problem?
Hello, It appears that you already got an answer to your question that I hope you can use. So just for completeness: On my PPC Mac OS X 10.4, both ghc-6.4.1 and ghc-6.6 produce results similar to the one you report for OSX. And on my Suse Linux, both ghc-6.4.1 and ghc-6.6 produce results ("wrong") similar to the one you report for your Linux/i386. So nothing indicates that this is a problem caused by differences between ghc versions. Best regards Thorkil On Wednesday 13 December 2006 22:04, Rich Neswold wrote: > ... > If you run the program on OSX, you can check the bound address while > it's waiting for a keystroke. Type "netstat -an -f inet | grep 6802" > to see. I get: > > udp4 0 0 127.0.0.1.61704127.0.0.1.6802 > > which is correct. When I run this program on Linux/i386, I get: > > udp0 0 (anonymized):334121.0.0.127:6802 > ESTABLISHED ... ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Network.Socket endian problem?
On Wed, Dec 13, 2006 at 03:54:59PM -0600, Mark Hills wrote: > It does expect the address to be in network byte order instead of host > byte order, which is usually done using htons and htonl. This seems to > do what you want (running SUSE 10.1 on an Intel box): Who agrees with me that it would be nice if network libraries used host byte order in their interface? Or at least they could use an abstract data type, whose byte order would be unobservable. Best regards Tomasz ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Network.Socket endian problem?
Rich Neswold wrote: > On 12/13/06, Thorkil Naur <[EMAIL PROTECTED]> wrote: >> I am not an expert on sockets, but I have both a Linux installation >> and a PPC >> Mac OS X 10.4 with both ghc-6.4.1 and ghc-6.6. So if you allow me some >> additional details (such as complete program texts), perhaps I can >> perform >> some useful experiments under your conductance. > > I can reproduce it with the following: > >> module Main >>where >> >> import Control.Exception >> import Network.Socket >> import System.IO >> >> allocSocket :: IO Socket >> allocSocket = >> do { s <- socket AF_INET Datagram 0 >>; handle (\e -> sClose s >> throwIO e) $ >> do { connect s (SockAddrInet 6802 0x7f01) >>; return s >>} >>} >> >> main :: IO () >> main = withSocketsDo $ do { s <- allocSocket >> ; getChar >> ; sClose s >> } > > If you run the program on OSX, you can check the bound address while > it's waiting for a keystroke. Type "netstat -an -f inet | grep 6802" > to see. I get: > >udp4 0 0 127.0.0.1.61704127.0.0.1.6802 > > which is correct. When I run this program on Linux/i386, I get: > >udp0 0 (anonymized):334121.0.0.127:6802 > ESTABLISHED > > (I removed my IP address.) The second bound address, however, is > wrong: the octets are in the wrong order. Notice, though, that the > port number is correct! > > Thanks for looking into this! > It does expect the address to be in network byte order instead of host byte order, which is usually done using htons and htonl. This seems to do what you want (running SUSE 10.1 on an Intel box): {-# OPTIONS -fglasgow-exts #-} module Main where import Control.Exception import Network.Socket import System.IO import Data.Word(Word32) foreign import ccall unsafe "htonl" htonl :: Word32 -> Word32 allocSocket :: IO Socket allocSocket = do { s <- socket AF_INET Datagram 0 ; handle (\e -> sClose s >> throwIO e) $ do { connect s (SockAddrInet 6802 (htonl 0x7f01)) ; return s } } main :: IO () main = withSocketsDo $ do { s <- allocSocket ; getChar ; sClose s } The main change is with importing "htonl" to convert to the right byte ordering (the other is adding the OPTIONS comment). I'm not that familiar with GHC yet, so maybe there is something that does this that is also available outside this module that I'm unaware of. It seems that iNADDR_ANY uses this internally to get the proper address format. It also looks like 6802 is converted into a PortNumber behind the scenes, which involves using htons, making it correct on both machines. Mark ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Network.Socket endian problem?
On 12/13/06, Thorkil Naur <[EMAIL PROTECTED]> wrote: I am not an expert on sockets, but I have both a Linux installation and a PPC Mac OS X 10.4 with both ghc-6.4.1 and ghc-6.6. So if you allow me some additional details (such as complete program texts), perhaps I can perform some useful experiments under your conductance. I can reproduce it with the following: module Main where import Control.Exception import Network.Socket import System.IO allocSocket :: IO Socket allocSocket = do { s <- socket AF_INET Datagram 0 ; handle (\e -> sClose s >> throwIO e) $ do { connect s (SockAddrInet 6802 0x7f01) ; return s } } main :: IO () main = withSocketsDo $ do { s <- allocSocket ; getChar ; sClose s } If you run the program on OSX, you can check the bound address while it's waiting for a keystroke. Type "netstat -an -f inet | grep 6802" to see. I get: udp4 0 0 127.0.0.1.61704127.0.0.1.6802 which is correct. When I run this program on Linux/i386, I get: udp0 0 (anonymized):334121.0.0.127:6802 ESTABLISHED (I removed my IP address.) The second bound address, however, is wrong: the octets are in the wrong order. Notice, though, that the port number is correct! Thanks for looking into this! -- Rich AIM : rnezzy ICQ : 174908475 ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Network.Socket endian problem?
Hello, I am not an expert on sockets, but I have both a Linux installation and a PPC Mac OS X 10.4 with both ghc-6.4.1 and ghc-6.6. So if you allow me some additional details (such as complete program texts), perhaps I can perform some useful experiments under your conductance. Best regards Thorkil On Wednesday 13 December 2006 19:29, Rich Neswold wrote: > ... > I've written a program that uses UDP as its communication with other > processes. It was built with GHC 6.4.1 on MacOS 10.4 (PowerPC) and > works fine. When I moved the code to a Linux box (i386) and built it > with GHC 6.6, it didn't work. > ... > I don't have access to GHC 6.4.1 on a Linux box to determine whether > this is a regression in 6.6 or simply an overlooked detail. Should I > file a PR? Am I doing something wrong? > ... ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Network.Socket endian problem?
Hello, I've written a program that uses UDP as its communication with other processes. It was built with GHC 6.4.1 on MacOS 10.4 (PowerPC) and works fine. When I moved the code to a Linux box (i386) and built it with GHC 6.6, it didn't work. The problems turns out to be, apparently, an endian problem. The socket is created with the following snippet: allocSocket :: IO Socket allocSocket = do { s <- socket AF_INET Datagram 0 ; handle (\e -> sClose s >> throwIO e) $ do { connect s (SockAddrInet 6802 0x7f01) ; return s } } On the Macintosh, the socket only receives packets from 127.0.0.1:6802, which is correct (and works). On the Linux machine, the socket only accepts packets from 1.0.0.127:6802. The data constructor SockAddrInet doesn't swap the bytes of the address (although it correctly swaps the bytes of the port number!) Changing the data constructor call to (SockAddrInet 6802 0x017f) makes it work on Linux, but not on MacOS 10.4. (You can see what the socket is bound to, on Linux, with "netstat -aun".) I don't have access to GHC 6.4.1 on a Linux box to determine whether this is a regression in 6.6 or simply an overlooked detail. Should I file a PR? Am I doing something wrong? -- Rich AIM : rnezzy ICQ : 174908475 ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users