From 01601a4db44b3adccfbcc07129a4584649252736 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Fri, 3 Aug 2018 15:08:30 +0200 Subject: [socket-nif] Add more data types (with doc) and (C) debug Add more debug printouts for the new sendmsg. Also added new (erlang) types with doc. OTP-14831 --- erts/doc/src/socket.xml | 12 +++++++ erts/emulator/nifs/common/socket_nif.c | 16 ++++++++- erts/preloaded/ebin/socket.beam | Bin 64304 -> 64540 bytes erts/preloaded/src/socket.erl | 64 +++++++++++++++++++++------------ lib/kernel/test/socket_server.erl | 3 ++ 5 files changed, 72 insertions(+), 23 deletions(-) diff --git a/erts/doc/src/socket.xml b/erts/doc/src/socket.xml index 93a3a8172e..b11b68cba5 100644 --- a/erts/doc/src/socket.xml +++ b/erts/doc/src/socket.xml @@ -146,6 +146,9 @@ + + + @@ -179,12 +182,21 @@ + + + + + + + + + diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c index 0d584306f1..90b727eff7 100644 --- a/erts/emulator/nifs/common/socket_nif.c +++ b/erts/emulator/nifs/common/socket_nif.c @@ -3770,7 +3770,8 @@ ERL_NIF_TERM nif_sendmsg(ErlNifEnv* env, res = nsendmsg(env, descP, sendRef, eMsgHdr, flags); - SGDBG( ("SOCKET", "nif_sendmsg -> done with result: " + SSDBG( descP, + ("SOCKET", "nif_sendmsg -> done with result: " "\r\n %T" "\r\n", res) ); @@ -3808,6 +3809,8 @@ ERL_NIF_TERM nsendmsg(ErlNifEnv* env, /* We don't need the address */ + SSDBG( descP, ("SOCKET", "nsendmsg -> connected: no address\r\n") ); + msgHdr.msg_name = NULL; msgHdr.msg_namelen = 0; @@ -3820,6 +3823,11 @@ ERL_NIF_TERM nsendmsg(ErlNifEnv* env, sys_memzero((char *) msgHdr.msg_name, msgHdr.msg_namelen); if (!GET_MAP_VAL(env, eMsgHdr, esock_atom_addr, &eAddr)) return esock_make_error(env, esock_atom_einval); + + SSDBG( descP, ("SOCKET", "nsendmsg -> not connected: " + "\r\n %T" + "\r\n", eAddr) ); + if ((xres = esock_decode_sockaddr(env, eAddr, msgHdr.msg_name, &msgHdr.msg_namelen)) != NULL) @@ -3836,6 +3844,8 @@ ERL_NIF_TERM nsendmsg(ErlNifEnv* env, if (!GET_LIST_LEN(env, eIOV, &iovLen) && (iovLen > 0)) return esock_make_error(env, esock_atom_einval); + SSDBG( descP, ("SOCKET", "nsendmsg -> iov length: %d\r\n", iovLen) ); + iovBins = MALLOC(iovLen * sizeof(ErlNifBinary)); ESOCK_ASSERT( (iovBins != NULL) ); @@ -3866,6 +3876,10 @@ ERL_NIF_TERM nsendmsg(ErlNifEnv* env, msgHdr.msg_iovlen = iovLen; + SSDBG( descP, ("SOCKET", + "nsendmsg -> total (iov) data size: %d\r\n", dataSize) ); + + /* Decode the ctrl and initiate that part of the msghdr */ if (ctrlBuf != NULL) { if ((xres = decode_cmsghdrs(env, descP, diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam index f84b9b8369..125191c1d0 100644 Binary files a/erts/preloaded/ebin/socket.beam and b/erts/preloaded/ebin/socket.beam differ diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl index 1459ee4869..3d65f52a2b 100644 --- a/erts/preloaded/src/socket.erl +++ b/erts/preloaded/src/socket.erl @@ -99,6 +99,8 @@ ip_pktinfo/0, ipv6_mreq/0, ipv6_pmtudisc/0, + sctp_assoc_id/0, + sctp_sndrcvinfo/0, sctp_event_subscribe/0, sctp_assocparams/0, sctp_initmsg/0, @@ -116,7 +118,8 @@ uint8/0, uint16/0, uint20/0, - uint32/0 + uint32/0, + int32/0 ]). @@ -124,6 +127,7 @@ -type uint16() :: 0..16#FFFF. -type uint20() :: 0..16#FFFFF. -type uint32() :: 0..16#FFFFFFFF. +-type int32() :: -2147483648..2147483647. %% We support only a subset of all domains. @@ -171,6 +175,12 @@ -type timeval() :: #{sec := integer(), usec := integer()}. +-type ip_pktinfo() :: #{ + ifindex := non_neg_integer(), % Interface Index + spec_dst := ip4_address(), % Local Address + addr := ip4_address() % Header Destination address + }. + %% If the integer value is used its up to the caller to ensure its valid! -type ip_tos() :: lowdeley | throughput | @@ -208,16 +218,29 @@ %% slist: List of source addresses -type ip_msfilter_mode() :: include | exclude. --type ip_msfilter() :: #{multiaddr => ip4_address(), - interface => ip4_address(), - mode => ip_msfilter_mode(), - slist => [ip4_address()]}. +-type ip_msfilter() :: #{multiaddr := ip4_address(), + interface := ip4_address(), + mode := ip_msfilter_mode(), + slist := [ip4_address()]}. -type ipv6_mreq() :: #{multiaddr := ip6_address(), interface := non_neg_integer()}. -type ipv6_pmtudisc() :: ip_pmtudisc(). +-type sctp_assoc_id() :: int32(). +-type sctp_sndrcvinfo() :: #{ + stream := uint16(), + ssn := uint16(), + flags := uint16(), + ppid := uint16(), + context := uint16(), + timetolive := uint16(), + tsn := uint16(), + cumtsn := uint16(), + assoc_id := sctp_assoc_id() + }. + -type sctp_event_subscribe() :: #{data_in := boolean(), association := boolean(), address := boolean(), @@ -229,7 +252,7 @@ authentication := boolean(), sender_dry := boolean()}. --type sctp_assocparams() :: #{assoc_id := integer(), +-type sctp_assocparams() :: #{assoc_id := sctp_assoc_id(), max_rxt := uint16(), num_peer_dests := uint16(), peer_rwnd := uint32(), @@ -242,7 +265,7 @@ max_init_timeo := uint16() }. --type sctp_rtoinfo() :: #{assoc_id := integer(), +-type sctp_rtoinfo() :: #{assoc_id := sctp_assoc_id(), initial := uint32(), max := uint32(), min := uint32()}. @@ -510,32 +533,29 @@ %% *Optional* target address %% Used on an unconnected socket to specify the %% target address for a datagram. - addr => sockaddr(), + addr := sockaddr(), - iov => [binary()], + iov := [binary()], %% The maximum size of the control buffer is platform %% specific. It is the users responsibility to ensure %% that its not exceeded. - ctrl => [cmsghdr()], + ctrl := [cmsghdr()], %% Only valid with recvmsg - flags => msghdr_flags() + flags := msghdr_flags() }. %% We are able to (completely) decode *some* control message headers. %% Even if we are able to decode both level and type, we may not be %% able to decode the data, in which case it will be a binary. --type ip_pktinfo() :: #{ - ifindex => non_neg_integer(), % Interface Index - spec_dst => ip4_address(), % Local Address - addr => ip4_address() % Header Destination address - }. + -type cmsghdr_level() :: socket | protocol() | integer(). -type cmsghdr_type() :: timestamp | - rights | - credentials | + pktinfo | tos | ttl | + rights | + credentials | origdstaddr | integer(). -type cmsghdr_data() :: timeval() | % if level = socket and type = timstamp @@ -545,9 +565,9 @@ sockaddr_in4() | % if level = ip and type = origdstaddr binary(). -type cmsghdr() :: #{ - level => cmsghdr_level(), - type => cmsghdr_type(), - data => cmsghdr_data() + level := cmsghdr_level(), + type := cmsghdr_type(), + data := cmsghdr_data() }. -define(SOCKET_DOMAIN_LOCAL, 1). @@ -1476,6 +1496,7 @@ do_sendmsg(SockRef, MsgHdr, EFlags, Timeout) -> ensure_msghdr(#{iov := IOV} = M) when is_list(IOV) andalso (IOV =/= []) -> M#{iov := erlang:iolist_to_iovec(IOV)}; + %% M; ensure_msghdr(_) -> einval(). @@ -1887,7 +1908,6 @@ do_recvfrom(SockRef, BufSz, EFlags, Timeout) -> end. - %% --------------------------------------------------------------------------- %% diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl index 34f354be32..b43642131b 100644 --- a/lib/kernel/test/socket_server.erl +++ b/lib/kernel/test/socket_server.erl @@ -915,6 +915,9 @@ send(#handler{socket = Sock, msg = true, type = dgram}, Msg, Dest) -> send(#handler{socket = Sock, type = dgram}, Msg, Dest) -> socket:sendto(Sock, Msg, Dest). +%% filler() -> +%% list_to_binary(lists:duplicate(2048, " FILLER ")). + %% ========================================================================= -- cgit v1.2.3