[MLton] INetSock problems, hton/ntoh usage

Vesa Karvonen vesa.a.j.k at gmail.com
Mon Mar 26 04:06:59 PST 2007


As has been reported earlier

  http://mlton.org/pipermail/mlton/2007-March/029675.html
  http://mlton.org/pipermail/mlton/2006-December/029465.html

the net code of MLton has been broken for some time.  Trying to get my
smlbot running, I took a look at the code.

The port number of a socket is a 16-bit integer (the sin_port field of
struct sockaddr_in).  OTOH, the current net code in MLton represents port
numbers as C_Int.t values which usually aren't 16-bit integers.  So,
inside the Net structure of MLton, the wrong hton/ntoh conversion (namely
htonl/ntohl) gets chosen.  AFAICT, the conversion should be done on the
lower 16-bits only.  Below is patch that should fix the problem.  Note
that I changed names from ntoh -> ntohs and hton -> htons to make it more
apparent that the functions only work on the lower 16-bits.

-Vesa Karvonen

Index: basis-library/net/net-serv-db.sml
===================================================================
--- basis-library/net/net-serv-db.sml	(revision 5450)
+++ basis-library/net/net-serv-db.sml	(working copy)
@@ -38,7 +38,7 @@
                             end
                        else List.rev aliases
                    val aliases = fill (0, [])
-                   val port = Net.C_Int.ntoh (Prim.getEntryPort ())
+                   val port = Net.C_Int.ntohs (Prim.getEntryPort ())
                    val protocol = CUtil.C_String.toString
(Prim.getEntryProto ())
                  in
                    SOME (T {name = name,
@@ -55,7 +55,7 @@
           | NONE => get (Prim.getByNameNull (NullString.nullTerm name))
         fun getByPort (port, proto) =
           let
-            val port = Net.C_Int.hton (C_Int.fromInt port)
+            val port = Net.C_Int.htons (C_Int.fromInt port)
           in
             case proto of
                NONE => get (Prim.getByPortNull port)
Index: basis-library/net/net.sml
===================================================================
--- basis-library/net/net.sml	(revision 5450)
+++ basis-library/net/net.sml	(working copy)
@@ -9,37 +9,37 @@
    struct
       structure Prim = PrimitiveFFI.Net

-      structure Word32 =
+      structure Int64 =
          struct
-            val hton = Prim.htonl
-            val ntoh = Prim.ntohl
+            val htons =
+               Primitive.IntWordConv.zextdFromWord16ToInt64
+               o Prim.htons
+               o Primitive.IntWordConv.zextdFromInt64ToWord16
+            val ntohs =
+               Primitive.IntWordConv.zextdFromWord16ToInt64
+               o Prim.ntohs
+               o Primitive.IntWordConv.zextdFromInt64ToWord16
          end
-      structure Word16 =
-         struct
-            val hton = Prim.htons
-            val ntoh = Prim.ntohs
-         end
-
       structure Int32 =
          struct
-            val hton =
-               Primitive.IntWordConv.idFromWord32ToInt32
-               o Word32.hton
-               o Primitive.IntWordConv.idFromInt32ToWord32
-            val ntoh =
-               Primitive.IntWordConv.idFromWord32ToInt32
-               o Word32.ntoh
-               o Primitive.IntWordConv.idFromInt32ToWord32
+            val htons =
+               Primitive.IntWordConv.zextdFromWord16ToInt32
+               o Prim.htons
+               o Primitive.IntWordConv.zextdFromInt32ToWord16
+            val ntohs =
+               Primitive.IntWordConv.zextdFromWord16ToInt32
+               o Prim.ntohs
+               o Primitive.IntWordConv.zextdFromInt32ToWord16
          end
       structure Int16 =
          struct
-            val hton =
-               Primitive.IntWordConv.idFromWord16ToInt16
-               o Word16.hton
+            val htons =
+               Primitive.IntWordConv.idFromWord16ToInt16
+               o Prim.htons
                o Primitive.IntWordConv.idFromInt16ToWord16
-            val ntoh =
-               Primitive.IntWordConv.idFromWord16ToInt16
-               o Word16.ntoh
+            val ntohs =
+               Primitive.IntWordConv.idFromWord16ToInt16
+               o Prim.ntohs
                o Primitive.IntWordConv.idFromInt16ToWord16
          end

@@ -50,22 +50,22 @@
                   C_Int_ChooseIntN
                   (type 'a t = 'a -> 'a
                    val fInt8 = fn _ => raise Fail "Net.C_Int.hton: fInt8"
-                   val fInt16 = Int16.hton
-                   val fInt32 = Int32.hton
-                   val fInt64 = fn _ => raise Fail "Net.C_Int.hton: fInt64")
+                   val fInt16 = Int16.htons
+                   val fInt32 = Int32.htons
+                   val fInt64 = Int64.htons)
             in
-               val hton = S.f
+               val htons = S.f
             end
             local
                structure S =
                   C_Int_ChooseIntN
                   (type 'a t = 'a -> 'a
                    val fInt8 = fn _ => raise Fail "Net.C_Int.ntoh: fInt8"
-                   val fInt16 = Int16.ntoh
-                   val fInt32 = Int32.ntoh
-                   val fInt64 = fn _ => raise Fail "Net.C_Int.ntoh: fInt64")
+                   val fInt16 = Int16.ntohs
+                   val fInt32 = Int32.ntohs
+                   val fInt64 = Int64.ntohs)
             in
-               val ntoh = S.f
+               val ntohs = S.f
             end
          end
    end
Index: basis-library/net/inet-sock.sml
===================================================================
--- basis-library/net/inet-sock.sml	(revision 5450)
+++ basis-library/net/inet-sock.sml	(working copy)
@@ -20,14 +20,13 @@
       fun toAddr (in_addr, port) =
          let
             val port = C_Int.fromInt port
-            val port = Net.C_Int.hton port
          in
             if C_Int.< (port, 0) orelse C_Int.>= (port, 0x10000)
                then PosixError.raiseSys PosixError.inval
                else let
                        val (sa, salen, finish) = Socket.new_sock_addr ()
                        val _ = Prim.toAddr
(NetHostDB.inAddrToWord8Vector in_addr,
-                                            port, sa, salen)
+                                            Net.C_Int.htons port, sa, salen)
                     in
                        finish ()
                     end
@@ -39,7 +38,7 @@
         let
           val () = Prim.fromAddr (Socket.unpackSockAddr sa)
           val port = Prim.getPort ()
-          val port = Net.C_Int.ntoh port
+          val port = Net.C_Int.ntohs port
           val port = C_Int.toInt port
           val (ia, finish) = NetHostDB.new_in_addr ()
           val _ = Prim.getInAddr (NetHostDB.preInAddrToWord8Array ia)
Index: basis-library/net/net.sig
===================================================================
--- basis-library/net/net.sig	(revision 5450)
+++ basis-library/net/net.sig	(working copy)
@@ -9,7 +9,7 @@
    sig
       structure C_Int :
          sig
-            val hton: C_Int.t -> C_Int.t
-            val ntoh: C_Int.t -> C_Int.t
+            val htons: C_Int.t -> C_Int.t
+            val ntohs: C_Int.t -> C_Int.t
          end
    end



More information about the MLton mailing list