How to compare PortNumbers or Bug in Network.Socket?

Hello, I want to compare two PortNumber-Values from the Network.Socket module and I think I've experienced some unexpected behavior of the derived ordering methods. I'm using the ghc-6.10.1 and the network library 2.2.0.1 on a x86 32-Bit machine. The following program creates two pairs of PortNumber values and compares them with each other. module Main(main) where import Network.Socket -- Block A p1 :: PortNumber p1 = fromIntegral 9000 p2 :: PortNumber p2 = fromIntegral 10000 -- Block B pp1 :: PortNumber pp1 = PortNum 9000 pp2 :: PortNumber pp2 = PortNum 10000 main :: IO () main = do putStrLn $ "A - " ++ (show $ p1 > p2) putStrLn $ "B - " ++ (show $ pp1 > pp2) On my machine, I get the result: A - True A - False At the first glance, it seemed to me, that there is a bug in the fromIntegral Implementation. But after I looked into the code, I saw that fromIntegral calls the system function "htons" to change the byte order from my machine to the network byte order, which on my machine is different. Because of this the values 9000 and 10000 are transferred, so that their ordering changes. Block B preservers this ordering, because the Constructor PortNum does not call htons, but since the byte order is wrong, I cannot use pp1 and pp2 to address port 9000 and 10000. As a work around, I could convert two PortNumbers back to Int-Values before comparing them, but I think the ordering functions for the PortNumber-Type do not work as expected. Or am I wrong? Stefan Schmidt

On Thu, Mar 12, 2009 at 2:44 PM, Stefan Schmidt < stefanschmidt42@googlemail.com> wrote:
As a work around, I could convert two PortNumbers back to Int-Values before comparing them, but I think the ordering functions for the PortNumber-Type do not work as expected. Or am I wrong?
You're right. Arguably the port numbers shouldn't have their endianness switched until the need actually arises (passed into bind or the like). However, it's also arguably the case that you shouldn't care about port number ordering. That smells dodgy to me.

On Thu, 2009-03-12 at 14:56 -0700, Bryan O'Sullivan wrote:
However, it's also arguably the case that you shouldn't care about port number ordering. That smells dodgy to me.
Port ranges aren't that uncommon.
--
Philippa Cowderoy

Philippa Cowderoy wrote:
On Thu, 2009-03-12 at 14:56 -0700, Bryan O'Sullivan wrote:
However, it's also arguably the case that you shouldn't care about port number ordering. That smells dodgy to me. Port ranges aren't that uncommon.
That's exactly were I need the comparison. I'm writing a program which takes a range of port numbers and tries to open a socket with the first available port number. The whole thing is part of a distributed system and I cannot specify just a single port number because I could already been taken. Stefan

On Thu, Mar 12, 2009 at 5:32 PM, Stefan Schmidt
Philippa Cowderoy wrote:
On Thu, 2009-03-12 at 14:56 -0700, Bryan O'Sullivan wrote:
However, it's also arguably the case that you shouldn't care about port number ordering. That smells dodgy to me.
Port ranges aren't that uncommon.
That's exactly were I need the comparison. I'm writing a program which takes a range of port numbers and tries to open a socket with the first available port number. The whole thing is part of a distributed system and I cannot specify just a single port number because I could already been taken.
Stefan
So the Ord instance is wrong for the PortNumber type? Well, maybe not wrong. But not as useful as it could be. Antoine

On Thu, Mar 12, 2009 at 8:45 PM, Antoine Latter
So the Ord instance is wrong for the PortNumber type? Well, maybe not wrong.
It's out and out wrong. You get different results on machines of different endianness. Now, this begs the question of why not just simply use an unwrapped Word16 instead :-)
participants (4)
-
Antoine Latter
-
Bryan O'Sullivan
-
Philippa Cowderoy
-
Stefan Schmidt