aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2018-08-01 19:42:32 +0200
committerMicael Karlberg <[email protected]>2018-09-18 14:50:18 +0200
commit90a150771faa3cf01e82919b0c17854de9987783 (patch)
tree5ad6c69f9ec4e569bba3da11df10d379faaba537 /lib
parent25c38eff5c1e8d4dc6325afa62031874e23262dc (diff)
downloadotp-90a150771faa3cf01e82919b0c17854de9987783.tar.gz
otp-90a150771faa3cf01e82919b0c17854de9987783.tar.bz2
otp-90a150771faa3cf01e82919b0c17854de9987783.zip
[socket-nif] Processing of more cmsg headers
Added processing or more cmsg headers (for more options). Now (also) supports: socket:timestamp. Also various fixes and cleanups. For some reason calling getopt(Sock, 0, {13, int}) (or similar) fails with badarg even though the nif-function (nif_getopt) actually returns a valid value (for instance: {ok, 0}). OTP-14831
Diffstat (limited to 'lib')
-rw-r--r--lib/kernel/test/socket_server.erl123
1 files changed, 83 insertions, 40 deletions
diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl
index a804078917..f252be1683 100644
--- a/lib/kernel/test/socket_server.erl
+++ b/lib/kernel/test/socket_server.erl
@@ -21,17 +21,19 @@
-module(socket_server).
-export([
- start/0, start/4,
- start_tcp/0, start_tcp/1, start_tcp/2,
- start_tcp4/0, start_tcp4/1, start_tcp6/0, start_tcp6/1,
- start_udp/0, start_udp/1, start_udp/2,
- start_udp4/0, start_udp4/1, start_udp6/0, start_udp6/1,
+ start/0, start/5,
+ start_tcp/0, start_tcp/1, start_tcp/3,
+ start_tcp4/0, start_tcp4/1, start_tcp4/2,
+ start_tcp6/0, start_tcp6/1, start_tcp6/2,
+ start_udp/0, start_udp/1, start_udp/3,
+ start_udp4/0, start_udp4/1, start_udp4/2,
+ start_udp6/0, start_udp6/1, start_udp6/2,
start_sctp/0, start_sctp/1
]).
-define(LIB, socket_lib).
--record(manager, {socket, peek, acceptors, handler_id, handlers}).
+-record(manager, {socket, msg, peek, acceptors, handler_id, handlers}).
-record(acceptor, {id, socket, manager}).
-record(handler, {socket, peek, msg, type, manager}).
@@ -50,16 +52,22 @@ start_tcp4() ->
start_tcp4(false).
start_tcp4(Peek) ->
- start_tcp(inet, Peek).
+ start_tcp4(false, Peek).
+
+start_tcp4(UseMsg, Peek) ->
+ start_tcp(inet, UseMsg, Peek).
start_tcp6() ->
start_tcp6(false).
start_tcp6(Peek) ->
- start_tcp(inet6, Peek).
+ start_tcp6(false, Peek).
+
+start_tcp6(UseMsg, Peek) ->
+ start_tcp(inet6, UseMsg, Peek).
-start_tcp(Domain, Peek) when is_boolean(Peek) ->
- start(Domain, stream, tcp, Peek).
+start_tcp(Domain, UseMsg, Peek) when is_boolean(UseMsg) andalso is_boolean(Peek) ->
+ start(Domain, stream, tcp, UseMsg, Peek).
start_udp() ->
start_udp4().
@@ -71,28 +79,34 @@ start_udp4() ->
start_udp4(false).
start_udp4(Peek) ->
- start_udp(inet, Peek).
+ start_udp4(false, Peek).
+
+start_udp4(UseMsg, Peek) ->
+ start_udp(inet, UseMsg, Peek).
start_udp6() ->
- start_udp6(false).
+ start_udp6(false, false).
start_udp6(Peek) ->
- start_udp(inet6, Peek).
+ start_udp6(false, Peek).
+
+start_udp6(UseMsg, Peek) ->
+ start_udp(inet6, UseMsg, Peek).
-start_udp(Domain, Peek) when is_boolean(Peek) ->
- start(Domain, dgram, udp, Peek).
+start_udp(Domain, UseMsg, Peek) when is_boolean(UseMsg) andalso is_boolean(Peek) ->
+ start(Domain, dgram, udp, UseMsg, Peek).
start_sctp() ->
start_sctp(inet).
start_sctp(Domain) when ((Domain =:= inet) orelse (Domain =:= inet6)) ->
- start(Domain, seqpacket, sctp, false).
+ start(Domain, seqpacket, sctp, true, false).
-start(Domain, Type, Proto, Peek) ->
+start(Domain, Type, Proto, UseMsg, Peek) ->
put(sname, "starter"),
i("try start manager"),
- {Pid, MRef} = manager_start(Domain, Type, Proto, Peek),
+ {Pid, MRef} = manager_start(Domain, Type, Proto, UseMsg, Peek),
i("manager (~p) started", [Pid]),
loop(Pid, MRef).
@@ -107,8 +121,8 @@ loop(Pid, MRef) ->
%% =========================================================================
-manager_start(Domain, Type, Proto, Peek) ->
- spawn_monitor(fun() -> manager_init(Domain, Type, Proto, Peek) end).
+manager_start(Domain, Type, Proto, UseMsg, Peek) ->
+ spawn_monitor(fun() -> manager_init(Domain, Type, Proto, UseMsg, Peek) end).
manager_start_handler(Pid, Sock) ->
manager_request(Pid, {start_handler, Sock}).
@@ -123,19 +137,20 @@ manager_reply(Pid, Ref, Reply) ->
?LIB:reply(manager, Pid, Ref, Reply).
-manager_init(Domain, Type, Proto, Peek) ->
+manager_init(Domain, Type, Proto, UseMsg, Peek) ->
put(sname, "manager"),
- do_manager_init(Domain, Type, Proto, Peek).
+ do_manager_init(Domain, Type, Proto, UseMsg, Peek).
-do_manager_init(Domain, stream = Type, Proto, Peek) ->
+do_manager_init(Domain, stream = Type, Proto, UseMsg, Peek) ->
i("try start acceptor(s)"),
{Sock, Acceptors} = manager_stream_init(Domain, Type, Proto),
manager_loop(#manager{socket = Sock,
+ msg = UseMsg,
peek = Peek,
acceptors = Acceptors,
handler_id = 1,
handlers = []});
-do_manager_init(Domain, dgram = Type, Proto, Peek) ->
+do_manager_init(Domain, dgram = Type, Proto, UseMsg, Peek) ->
i("try open socket"),
case socket:open(Domain, Type, Proto) of
{ok, Sock} ->
@@ -179,11 +194,12 @@ do_manager_init(Domain, dgram = Type, Proto, Peek) ->
{ok, Name} -> f("~p", [Name]);
{error, R} -> f("error: ~p", [R])
end]),
- case handler_start(1, true, Sock, Peek) of
+ case handler_start(1, Sock, UseMsg, Peek) of
{ok, {Pid, MRef}} ->
i("handler (~p) started", [Pid]),
handler_continue(Pid),
manager_loop(#manager{peek = Peek,
+ msg = UseMsg,
handler_id = 2, % Just in case
handlers = [{1, Pid, MRef}]});
{error, SReason} ->
@@ -196,7 +212,7 @@ do_manager_init(Domain, dgram = Type, Proto, Peek) ->
"~n ~p", [OReason]),
exit({failed_open_socket, OReason})
end;
-do_manager_init(Domain, seqpacket = Type, sctp = Proto, _Peek) ->
+do_manager_init(Domain, seqpacket = Type, sctp = Proto, _UseMsg, _Peek) ->
%% This is as far as I have got with SCTP at the moment...
case socket:open(Domain, Type, Proto) of
{ok, Sock} ->
@@ -248,9 +264,9 @@ do_manager_init(Domain, seqpacket = Type, sctp = Proto, _Peek) ->
{error, Reason} ->
exit({failed_open, Reason})
end;
-do_manager_init(Domain, raw = Type, Proto, Peek) when is_integer(Proto) ->
- do_manager_init(Domain, Type, {raw, Proto}, Peek);
-do_manager_init(Domain, raw = Type, Proto, _Peek) ->
+do_manager_init(Domain, raw = Type, Proto, UseMsg, Peek) when is_integer(Proto) ->
+ do_manager_init(Domain, Type, {raw, Proto}, UseMsg, Peek);
+do_manager_init(Domain, raw = Type, Proto, _UseMsg, _Peek) ->
case socket:open(Domain, Type, Proto) of
{ok, Sock} ->
i("(sctp) socket opened: "
@@ -401,11 +417,12 @@ manager_handle_down(#manager{acceptors = Acceptors,
manager_handle_request(#manager{peek = Peek,
+ msg = UseMsg,
handler_id = HID,
handlers = Handlers} = M, Pid, Ref,
{start_handler, Sock}) ->
i("try start handler (~w)", [HID]),
- case handler_start(HID, false, Sock, Peek) of
+ case handler_start(HID, Sock, UseMsg, Peek) of
{ok, {HPid, HMRef}} ->
i("handler ~w started", [HID]),
manager_reply(Pid, Ref, {ok, HPid}),
@@ -564,10 +581,10 @@ acceptor_handle_accept_success(#acceptor{manager = Manager}, Sock) ->
%% =========================================================================
-handler_start(ID, Msg, Sock, Peek) ->
+handler_start(ID, Sock, UseMsg, Peek) ->
Self = self(),
H = {Pid, _} = spawn_monitor(fun() ->
- handler_init(Self, ID, Msg, Peek, Sock)
+ handler_init(Self, ID, UseMsg, Peek, Sock)
end),
receive
{handler, Pid, ok} ->
@@ -720,7 +737,16 @@ handler_init(Manager, ID, Msg, Peek, Sock) ->
RtHdr, AuthHdr, HopLimit, HopOpts, DstOpts, FlowInfo,
UHops]),
- SIP =
+ %% ok = socket:setopt(Sock, otp, debug, true),
+ %% case socket:getopt(Sock, 0, {13, int}) of
+ %% {ok, Val} ->
+ %% i("PktOpts ok: ~p", [Val]);
+ %% {error, Reason} ->
+ %% e("PktOpts err: ~p", [Reason])
+ %% end,
+ %% ok = socket:setopt(Sock, otp, debug, false),
+ SSO = fun(O, V) -> soso(Sock, O, V) end,
+ SIP4 =
fun(O, V) ->
if
(Type =:= dgram) ->
@@ -729,8 +755,10 @@ handler_init(Manager, ID, Msg, Peek, Sock) ->
ok
end
end,
+ SSO(timestamp, true),
+ SIP4(pktinfo, true),
ok = soip(Sock, recvtos, true),
- SIP(recvttl, true),
+ SIP4(recvttl, true),
ok = soip(Sock, recvorigdstaddr, true),
handler_loop(#handler{msg = Msg,
@@ -743,8 +771,8 @@ handler_init(Manager, ID, Msg, Peek, Sock) ->
so(Sock, Lvl, Opt, Val) ->
ok = socket:setopt(Sock, Lvl, Opt, Val).
-%% soso(Sock, Opt, Val) ->
-%% so(Sock, socket, Opt, Val).
+soso(Sock, Opt, Val) ->
+ so(Sock, socket, Opt, Val).
soip(Sock, Opt, Val) ->
so(Sock, ip, Opt, Val).
@@ -791,16 +819,29 @@ handler_loop(H) ->
recv(#handler{peek = true, socket = Sock, type = stream}) ->
peek_recv(Sock);
-recv(#handler{peek = false, socket = Sock, type = stream}) ->
- do_recv(Sock);
+recv(#handler{socket = Sock, msg = true, type = stream}) ->
+ case socket:recvmsg(Sock) of
+ {ok, #{addr := undefined = Source,
+ iov := [Data],
+ ctrl := CMsgHdrs,
+ flags := Flags}} ->
+ i("received message: "
+ "~n CMsgHdrs: ~p"
+ "~n Flags: ~p", [CMsgHdrs, Flags]),
+ {ok, {Source, Data}};
+ {ok, X} ->
+ e("received *unexpected* message: "
+ "~n ~p", [X]),
+ {error, {unexpected, X}};
+ {error, _} = ERROR ->
+ ERROR
+ end;
recv(#handler{socket = Sock, msg = true, type = dgram}) ->
- %% ok = socket:setopt(Sock, otp, debug, true),
case socket:recvmsg(Sock) of
{ok, #{addr := Source,
iov := [Data],
ctrl := CMsgHdrs,
flags := Flags}} ->
- %% ok = socket:setopt(Sock, otp, debug, false),
i("received message: "
"~n CMsgHdrs: ~p"
"~n Flags: ~p", [CMsgHdrs, Flags]),
@@ -810,6 +851,8 @@ recv(#handler{socket = Sock, msg = true, type = dgram}) ->
{error, _} = ERROR ->
ERROR
end;
+recv(#handler{peek = false, socket = Sock, type = stream}) ->
+ do_recv(Sock);
recv(#handler{peek = Peek, socket = Sock, type = dgram})
when (Peek =:= true) ->
%% ok = socket:setopt(Sock, otp, debug, true),