From c14eca1d556926677dc03357c248dc4cf3dc38ed Mon Sep 17 00:00:00 2001
From: Micael Karlberg <bmk@erlang.org>
Date: Tue, 18 Sep 2018 12:43:02 +0200
Subject: [socket-nif] Added (more) tests for [recv|send]msg

Added some more tests for sendmsg (with cmsghdr).

OTP-14831
---
 lib/kernel/test/socket_client.erl | 44 ++++++++++++++++++++++++++++++++++-----
 lib/kernel/test/socket_server.erl | 16 ++++++++++----
 2 files changed, 51 insertions(+), 9 deletions(-)

(limited to 'lib')

diff --git a/lib/kernel/test/socket_client.erl b/lib/kernel/test/socket_client.erl
index 56424457e0..58d70b6181 100644
--- a/lib/kernel/test/socket_client.erl
+++ b/lib/kernel/test/socket_client.erl
@@ -28,7 +28,7 @@
 
 -define(LIB, socket_lib).
 
--record(client, {socket, type, dest, msg_id = 1}).
+-record(client, {socket, msg = true, type, dest, msg_id = 1}).
 
 start(Port) ->
     start_tcp(Port).
@@ -190,7 +190,9 @@ do_init(Domain, stream = Type, Proto) ->
     i("try (socket) bind"),
     case socket:bind(Sock, any) of
         {ok, _P} ->
-            ok = socket:setopt(Sock, ip, tos, mincost),
+            ok = socket:setopt(Sock, socket, timestamp, true),
+            ok = socket:setopt(Sock, ip,     tos,       mincost),
+            ok = socket:setopt(Sock, ip,     recvtos,   true),
             Sock;
         {error, BReason} ->
             throw({bind, BReason})
@@ -205,6 +207,10 @@ do_init(Domain, dgram = Type, Proto) ->
            end,
     case socket:bind(Sock, any) of
         {ok, _} ->
+            ok = socket:setopt(Sock, socket, timestamp, true),
+            ok = socket:setopt(Sock, ip,     tos,       mincost),
+            ok = socket:setopt(Sock, ip,     recvtos,   true),
+            ok = socket:setopt(Sock, ip,     recvttl,   true),
             Sock;
         {error, BReason} ->
             throw({bind, BReason})
@@ -286,15 +292,43 @@ send(#client{socket = Sock, type = dgram, dest = Dest}, Msg) ->
             ERROR
     end.
 
-recv(#client{socket = Sock, type = stream}) ->
+recv(#client{socket = Sock, type = stream, msg = false}) ->
     case socket:recv(Sock) of
         {ok, Msg} ->
             {ok, {undefined, Msg}};
         {error, _} = ERROR ->
             ERROR
     end;
-recv(#client{socket = Sock, type = dgram}) ->
-    socket:recvfrom(Sock).
+recv(#client{socket = Sock, type = stream, msg = true}) ->
+    case socket:recvmsg(Sock) of
+        %% An iov of length 1 is an simplification...
+        {ok, #{addr  := undefined = Source,
+               iov   := [Msg],
+               ctrl  := CMsgHdrs,
+               flags := Flags}} ->
+            i("received message: "
+              "~n   CMsgHdr: ~p"
+              "~n   Flags:   ~p", [CMsgHdrs, Flags]),
+            {ok, {Source, Msg}};
+        {error, _} = ERROR ->
+            ERROR
+    end;
+recv(#client{socket = Sock, type = dgram, msg = false}) ->
+    socket:recvfrom(Sock);
+recv(#client{socket = Sock, type = dgram, msg = true}) ->
+    case socket:recvmsg(Sock) of
+        {ok, #{addr  := Source,
+               iov   := [Msg],
+               ctrl  := CMsgHdrs,
+               flags := Flags}} ->
+            i("received message: "
+              "~n   CMsgHdr: ~p"
+              "~n   Flags:   ~p", [CMsgHdrs, Flags]),
+            {ok, {Source, Msg}};
+        {error, _} = ERROR ->
+            ERROR
+    end.
+        
 
 
 which_addr(_Domain, []) ->
diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl
index b43642131b..ea2bdc8e0d 100644
--- a/lib/kernel/test/socket_server.erl
+++ b/lib/kernel/test/socket_server.erl
@@ -901,13 +901,21 @@ peek_recvfrom(Sock, BufSz) ->
 
 
 send(#handler{socket = Sock, msg = true, type = stream}, Msg, _) ->
-    MsgHdr = #{iov => [Msg]},
-    socket:sendmsg(Sock, MsgHdr);
+    CMsgHdr  = #{level => ip, type => tos, data => reliability},
+    CMsgHdrs = [CMsgHdr],
+    MsgHdr   = #{iov => [Msg], ctrl => CMsgHdrs},
+    %% socket:setopt(Sock, otp, debug, true),
+    Res = socket:sendmsg(Sock, MsgHdr),
+    %% socket:setopt(Sock, otp, debug, false),
+    Res;
 send(#handler{socket = Sock, type = stream}, Msg, _) ->
     socket:send(Sock, Msg);
 send(#handler{socket = Sock, msg = true, type = dgram}, Msg, Dest) ->
-    MsgHdr = #{addr => Dest,
-               iov  => [Msg]},
+    CMsgHdr  = #{level => ip, type => tos, data => reliability},
+    CMsgHdrs = [CMsgHdr],
+    MsgHdr   = #{addr => Dest,
+                 iov  => [Msg],
+                 ctrl => CMsgHdrs},
     %% ok = socket:setopt(Sock, otp, debug, true),
     Res = socket:sendmsg(Sock, MsgHdr),
     %% ok = socket:setopt(Sock, otp, debug, false),
-- 
cgit v1.2.3