aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-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
4 files changed, 77 insertions, 2 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)...