Re: Network.Socket endian problem?

2006-12-15 Thread Rich Neswold

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?

2006-12-14 Thread Tomasz Zielonka
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?

2006-12-14 Thread Ferenc Wagner
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?

2006-12-14 Thread Rich Neswold

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?

2006-12-13 Thread Sigbjorn Finne

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?

2006-12-13 Thread Thorkil Naur
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?

2006-12-13 Thread Tomasz Zielonka
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?

2006-12-13 Thread Mark Hills
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?

2006-12-13 Thread Rich Neswold

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?

2006-12-13 Thread Thorkil Naur
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?

2006-12-13 Thread Rich Neswold

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