aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2018-07-26 11:07:05 +0200
committerMicael Karlberg <[email protected]>2018-09-18 14:50:18 +0200
commit6b01561dc13a0152f56da0a2c61ad88236f87de7 (patch)
tree83541c84c02ddb1b3ab978a351e688401de1d535
parent8ed757c8df2df54e19e67ca0a0734cd5a0f9ab23 (diff)
downloadotp-6b01561dc13a0152f56da0a2c61ad88236f87de7.tar.gz
otp-6b01561dc13a0152f56da0a2c61ad88236f87de7.tar.bz2
otp-6b01561dc13a0152f56da0a2c61ad88236f87de7.zip
[socket-nif] Add support for socket (level ip) option sendsrcaddr
Added support for ip level socket option SENDSRCADDR. This option requires sendmsg to actually use, so we cannot test this fully at the moment. OTP-14831
-rw-r--r--erts/doc/src/socket_usage.xml11
-rw-r--r--erts/emulator/nifs/common/socket_nif.c59
-rw-r--r--erts/preloaded/ebin/socket.beambin59660 -> 59768 bytes
-rw-r--r--erts/preloaded/src/socket.erl9
-rw-r--r--lib/kernel/test/socket_server.erl12
5 files changed, 84 insertions, 7 deletions
diff --git a/erts/doc/src/socket_usage.xml b/erts/doc/src/socket_usage.xml
index f69aa75820..933341bd35 100644
--- a/erts/doc/src/socket_usage.xml
+++ b/erts/doc/src/socket_usage.xml
@@ -35,6 +35,10 @@
<p>The socket interface (module) is basically an "thin" layer on top of
the OS socket interface. It is assumed that, unless you have special needs,
gen_[tcp|udp|sctp] should be sufficent. </p>
+ <p>Note that just because we have a documented and described option,
+ it does <em>not</em> mean that the OS supports it. So its recommended
+ that the user reads the platform specific documentation for the
+ option used. </p>
</section>
<section>
@@ -429,6 +433,13 @@
<cell>type = raw</cell>
</row>
<row>
+ <cell>sendsrcaddr</cell>
+ <cell>boolean()</cell>
+ <cell>yes</cell>
+ <cell>yes</cell>
+ <cell>none</cell>
+ </row>
+ <row>
<cell>tos</cell>
<cell>ip_tos()</cell>
<cell>yes</cell>
diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c
index 4ba94f4f60..13250349db 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -540,6 +540,7 @@ typedef union {
#define SOCKET_OPT_IP_RECVTTL 26
#define SOCKET_OPT_IP_RETOPTS 27
#define SOCKET_OPT_IP_ROUTER_ALERT 28
+#define SOCKET_OPT_IP_SENDSRCADDR 29 // Same as IP_RECVDSTADDR?
#define SOCKET_OPT_IP_TOS 30
#define SOCKET_OPT_IP_TRANSPARENT 31
#define SOCKET_OPT_IP_TTL 32
@@ -1218,6 +1219,11 @@ static ERL_NIF_TERM nsetopt_lvl_ip_router_alert(ErlNifEnv* env,
SocketDescriptor* descP,
ERL_NIF_TERM eVal);
#endif
+#if defined(IP_SENDSRCADDR)
+static ERL_NIF_TERM nsetopt_lvl_ip_sendsrcaddr(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal);
+#endif
#if defined(IP_TOS)
static ERL_NIF_TERM nsetopt_lvl_ip_tos(ErlNifEnv* env,
SocketDescriptor* descP,
@@ -1640,6 +1646,10 @@ static ERL_NIF_TERM ngetopt_lvl_ip_retopts(ErlNifEnv* env,
static ERL_NIF_TERM ngetopt_lvl_ip_router_alert(ErlNifEnv* env,
SocketDescriptor* descP);
#endif
+#if defined(IP_SENDSRCADDR)
+static ERL_NIF_TERM ngetopt_lvl_ip_sendsrcaddr(ErlNifEnv* env,
+ SocketDescriptor* descP);
+#endif
#if defined(IP_TOS)
static ERL_NIF_TERM ngetopt_lvl_ip_tos(ErlNifEnv* env,
SocketDescriptor* descP);
@@ -5125,6 +5135,12 @@ ERL_NIF_TERM nsetopt_lvl_ip(ErlNifEnv* env,
break;
#endif
+#if defined(IP_SENDSRCADDR)
+ case SOCKET_OPT_IP_SENDSRCADDR:
+ result = nsetopt_lvl_ip_sendsrcaddr(env, descP, eVal);
+ break;
+#endif
+
#if defined(IP_TOS)
case SOCKET_OPT_IP_TOS:
result = nsetopt_lvl_ip_tos(env, descP, eVal);
@@ -5808,6 +5824,25 @@ ERL_NIF_TERM nsetopt_lvl_ip_router_alert(ErlNifEnv* env,
#endif
+/* nsetopt_lvl_ip_sendsrcaddr - Level IP SENDSRCADDR option
+ */
+#if defined(IP_SENDSRCADDR)
+static
+ERL_NIF_TERM nsetopt_lvl_ip_sendsrcaddr(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal)
+{
+#if defined(SOL_IP)
+ int level = SOL_IP;
+#else
+ int level = IPPROTO_IP;
+#endif
+
+ return nsetopt_bool_opt(env, descP, level, IP_SENDSRCADDR, eVal);
+}
+#endif
+
+
/* nsetopt_lvl_ip_tos - Level IP TOS option
*/
#if defined(IP_TOS)
@@ -8418,6 +8453,12 @@ ERL_NIF_TERM ngetopt_lvl_ip(ErlNifEnv* env,
break;
#endif
+#if defined(IP_SENDSRCADDR)
+ case SOCKET_OPT_IP_SENDSRCADDR:
+ result = ngetopt_lvl_ip_sendsrcaddr(env, descP);
+ break;
+#endif
+
#if defined(IP_TOS)
case SOCKET_OPT_IP_TOS:
result = ngetopt_lvl_ip_tos(env, descP);
@@ -8846,6 +8887,24 @@ ERL_NIF_TERM ngetopt_lvl_ip_router_alert(ErlNifEnv* env,
#endif
+/* ngetopt_lvl_ip_sendsrcaddr - Level IP SENDSRCADDR option
+ */
+#if defined(IP_SENDSRCADDR)
+static
+ERL_NIF_TERM ngetopt_lvl_ip_sendsrcaddr(ErlNifEnv* env,
+ SocketDescriptor* descP)
+{
+#if defined(SOL_IP)
+ int level = SOL_IP;
+#else
+ int level = IPPROTO_IP;
+#endif
+
+ return ngetopt_bool_opt(env, descP, level, IP_SENDSRCADDR);
+}
+#endif
+
+
/* ngetopt_lvl_ip_tos - Level IP TOS option
*/
#if defined(IP_TOS)
diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam
index 90cb657178..b2bd8f2728 100644
--- a/erts/preloaded/ebin/socket.beam
+++ b/erts/preloaded/ebin/socket.beam
Binary files differ
diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl
index 68b7d3f4b0..1983c993a5 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -638,11 +638,11 @@
-define(SOCKET_OPT_IP_RECVTTL, 26).
-define(SOCKET_OPT_IP_RETOPTS, 27).
-define(SOCKET_OPT_IP_ROUTER_ALERT, 28).
-%% -define(SOCKET_OPT_IP_SNDSRCADDR, 29).
+-define(SOCKET_OPT_IP_SENDSRCADDR, 29). % FreeBSD
-define(SOCKET_OPT_IP_TOS, 30).
-define(SOCKET_OPT_IP_TRANSPARENT, 31).
-define(SOCKET_OPT_IP_TTL, 32).
--define(SOCKET_OPT_IP_UNBLOCK_SOURCE, 33).
+-define(SOCKET_OPT_IP_UNBLOCK_SOURCE, 33).
-define(SOCKET_OPT_IPV6_ADDRFORM, 1).
-define(SOCKET_OPT_IPV6_ADD_MEMBERSHIP, 2).
@@ -2316,6 +2316,9 @@ enc_setopt_value(ip, retopts, V, _D, _T, _P)
enc_setopt_value(ip, router_alert, V, _D, _T, _P)
when is_integer(V) ->
V;
+enc_setopt_value(ip, sendsrcaddr, V, _D, _T, _P)
+ when is_boolean(V) ->
+ V;
enc_setopt_value(ip, tos, V, _D, _T, _P)
when (V =:= lowdelay) orelse
(V =:= throughput) orelse
@@ -2776,6 +2779,8 @@ enc_sockopt_key(ip = _L, retopts = _Opt, _Dir, _D, T, _P) when (T =/= stream) ->
?SOCKET_OPT_IP_RETOPTS;
enc_sockopt_key(ip, router_alert = _Opt, _Dir, _D, raw = _T, _P) ->
?SOCKET_OPT_IP_ROUTER_ALERT;
+enc_sockopt_key(ip, sendsrcaddr = _Opt, _Dir, _D, _T, _P) ->
+ ?SOCKET_OPT_IP_SENDSRCADDR;
%% On FreeBSD it specifies that this option is only valid
%% for stream, dgram and "some" raw sockets...
%% No such condition on linux (in the man page)...
diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl
index 3dad94b751..88b63ecf2d 100644
--- a/lib/kernel/test/socket_server.erl
+++ b/lib/kernel/test/socket_server.erl
@@ -644,6 +644,7 @@ handler_init(Manager, ID, Peek, Sock) ->
RecvTOS = GIP4(recvtos),
RecvTTL = GIP4(recvttl), % not stream
RetOpts = GIP4(retopts), % not stream
+ SendSrcAddr = GIP4(sendsrcaddr),
TOS = GIP4(tos),
Transparent = GIP4(transparent),
TTL = GIP4(ttl),
@@ -691,6 +692,7 @@ handler_init(Manager, ID, Peek, Sock) ->
"~n (ip) Recv TOS: ~s"
"~n (ip) Recv TTL: ~s"
"~n (ip) Ret Opts: ~s"
+ "~n (ip) Send Src Addr: ~s"
"~n (ip) TOS: ~s"
"~n (ip) Transparent: ~s"
"~n (ip) TTL: ~s"
@@ -713,7 +715,7 @@ handler_init(Manager, ID, Peek, Sock) ->
FreeBind, MTU, MTUDisc, MALL, MIF4, MLoop4, MTTL,
NF, PktInfo,RecvErr4,
RecvIF, RecvOPTS, RecvOrigDstAddr, RecvTOS, RecvTTL, RetOpts,
- TOS, Transparent, TTL,
+ SendSrcAddr, TOS, Transparent, TTL,
MHops, MIF6, MLoop6, RecvErr6, RecvPktInfo,
RtHdr, AuthHdr, HopLimit, HopOpts, DstOpts, FlowInfo,
UHops]),
@@ -724,14 +726,14 @@ handler_init(Manager, ID, Peek, Sock) ->
socket = Sock})
end.
-so(Sock, Lvl, Opt, Val) ->
- ok = socket:setopt(Sock, Lvl, Opt, Val).
+%% so(Sock, Lvl, Opt, Val) ->
+%% ok = socket:setopt(Sock, Lvl, Opt, Val).
%% soso(Sock, Opt, Val) ->
%% so(Sock, socket, Opt, Val).
-soip(Sock, Opt, Val) ->
- so(Sock, ip, Opt, Val).
+%% soip(Sock, Opt, Val) ->
+%% so(Sock, ip, Opt, Val).
%% soipv6(Sock, Opt, Val) ->
%% so(Sock, ipv6, Opt, Val).