aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2018-08-03 18:55:30 +0200
committerMicael Karlberg <[email protected]>2018-09-18 14:50:18 +0200
commitee2eadd1c61d4237ee4044260665c82edf559228 (patch)
treef9f8a55a9cd149ec6d61080137a07d99a6ed57ed /erts
parent01601a4db44b3adccfbcc07129a4584649252736 (diff)
downloadotp-ee2eadd1c61d4237ee4044260665c82edf559228.tar.gz
otp-ee2eadd1c61d4237ee4044260665c82edf559228.tar.bz2
otp-ee2eadd1c61d4237ee4044260665c82edf559228.zip
[socket-nif] Add support for (recvmsg) control message ipv6_pktinfo
Added support for (recvmsg) control message ipv6_pktinfo, for level = ipv6 and type = pktinfo. This is enabled by setting the socket option: recvpktinfo for level ipv6. Not yet tested! OTP-14831
Diffstat (limited to 'erts')
-rw-r--r--erts/doc/src/socket_usage.xml18
-rw-r--r--erts/emulator/nifs/common/socket_nif.c99
-rw-r--r--erts/preloaded/ebin/socket.beambin64540 -> 64588 bytes
-rw-r--r--erts/preloaded/src/socket.erl7
4 files changed, 103 insertions, 21 deletions
diff --git a/erts/doc/src/socket_usage.xml b/erts/doc/src/socket_usage.xml
index b7459e97fa..9785830637 100644
--- a/erts/doc/src/socket_usage.xml
+++ b/erts/doc/src/socket_usage.xml
@@ -51,7 +51,7 @@
<cell><em>Value Type</em></cell>
<cell><em>Set</em></cell>
<cell><em>Get</em></cell>
- <cell><em>Other</em></cell>
+ <cell><em>Other Requirements and comments</em></cell>
</row>
<row>
<cell>assoc_id</cell>
@@ -90,7 +90,7 @@
<cell><em>Value Type</em></cell>
<cell><em>Set</em></cell>
<cell><em>Get</em></cell>
- <cell><em>Other</em></cell>
+ <cell><em>Other Requirements and comments</em></cell>
</row>
<row>
<cell>acceptcon</cell>
@@ -118,7 +118,7 @@
<cell>integer()</cell>
<cell>yes</cell>
<cell>yes</cell>
- <cell>require admin capability</cell>
+ <cell>requires admin capability</cell>
</row>
<row>
<cell>domain</cell>
@@ -255,7 +255,7 @@
<cell><em>Value Type</em></cell>
<cell><em>Set</em></cell>
<cell><em>Get</em></cell>
- <cell><em>Other</em></cell>
+ <cell><em>Other Requirements and comments</em></cell>
</row>
<row>
<cell>add_membership</cell>
@@ -451,7 +451,7 @@
<cell>boolean()</cell>
<cell>yes</cell>
<cell>yes</cell>
- <cell>require admin capability</cell>
+ <cell>requires admin capability</cell>
</row>
<row>
<cell>ttl</cell>
@@ -476,7 +476,7 @@
<cell><em>Value Type</em></cell>
<cell><em>Set</em></cell>
<cell><em>Get</em></cell>
- <cell><em>Other</em></cell>
+ <cell><em>Other Requirements and comments</em></cell>
</row>
<row>
<cell>addrform</cell>
@@ -621,7 +621,7 @@
<cell><em>Value Type</em></cell>
<cell><em>Set</em></cell>
<cell><em>Get</em></cell>
- <cell><em>Other</em></cell>
+ <cell><em>Other Requirements and comments</em></cell>
</row>
<row>
<cell>congestion</cell>
@@ -653,7 +653,7 @@
<cell><em>Value Type</em></cell>
<cell><em>Set</em></cell>
<cell><em>Get</em></cell>
- <cell><em>Other</em></cell>
+ <cell><em>Other Requirements and comments</em></cell>
</row>
<row>
<cell>cork</cell>
@@ -671,7 +671,7 @@
<cell><em>Value Type</em></cell>
<cell><em>Set</em></cell>
<cell><em>Get</em></cell>
- <cell><em>Other</em></cell>
+ <cell><em>Other Requirements and comments</em></cell>
</row>
<row>
<cell>associnfo</cell>
diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c
index 90b727eff7..f7e59678bb 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -1960,6 +1960,15 @@ static char* encode_cmsghdr_data_ip(ErlNifEnv* env,
size_t dataPos,
size_t dataLen,
ERL_NIF_TERM* eCMsgHdrData);
+#if defined(SOL_IPV6)
+static char* encode_cmsghdr_data_ipv6(ErlNifEnv* env,
+ ERL_NIF_TERM ctrlBuf,
+ int type,
+ unsigned char* dataP,
+ size_t dataPos,
+ size_t dataLen,
+ ERL_NIF_TERM* eCMsgHdrData);
+#endif
extern char* encode_msghdr_flags(ErlNifEnv* env,
SocketDescriptor* descP,
int msgFlags,
@@ -11419,19 +11428,19 @@ char* encode_cmsghdr_type(ErlNifEnv* env,
*eType = esock_atom_tos;
break;
#endif
-
+
#if defined(IP_TTL)
case IP_TTL:
*eType = esock_atom_ttl;
break;
#endif
-
+
#if defined(IP_PKTINFO)
case IP_PKTINFO:
*eType = esock_atom_pktinfo;
break;
#endif
-
+
#if defined(IP_ORIGDSTADDR)
case IP_ORIGDSTADDR:
*eType = esock_atom_origdstaddr;
@@ -11443,17 +11452,23 @@ char* encode_cmsghdr_type(ErlNifEnv* env,
break;
}
break;
-
+
#if defined(SOL_IPV6)
case SOL_IPV6:
switch (type) {
+#if defined(IPV6_PKTINFO)
+ case IPV6_PKTINFO:
+ *eType = esock_atom_pktinfo;
+ break;
+#endif
+
default:
xres = ESOCK_STR_EINVAL;
break;
}
break;
#endif
-
+
case IPPROTO_TCP:
switch (type) {
default:
@@ -11634,13 +11649,13 @@ char* encode_cmsghdr_data(ErlNifEnv* env,
eCMsgHdrData);
break;
- /*
- #if defined(SOL_IPV6)
- case SOL_IPV6:
- xres = encode_cmsghdr_data_ipv6(env, type, dataP, eCMsgHdrData);
- break;
- #endif
- */
+#if defined(SOL_IPV6)
+ case SOL_IPV6:
+ xres = encode_cmsghdr_data_ipv6(env, ctrlBuf, type,
+ dataP, dataPos, dataLen,
+ eCMsgHdrData);
+ break;
+#endif
/*
case IPPROTO_TCP:
@@ -11827,6 +11842,66 @@ char* encode_cmsghdr_data_ip(ErlNifEnv* env,
+/* +++ encode_cmsghdr_data_ipv6 +++
+ *
+ * Encode the data part when protocol = IPv6 of the cmsghdr().
+ *
+ */
+#if defined(SOL_IPV6)
+static
+char* encode_cmsghdr_data_ipv6(ErlNifEnv* env,
+ ERL_NIF_TERM ctrlBuf,
+ int type,
+ unsigned char* dataP,
+ size_t dataPos,
+ size_t dataLen,
+ ERL_NIF_TERM* eCMsgHdrData)
+{
+ char* xres;
+
+ switch (type) {
+#if defined(IPV6_PKTINFO)
+ case IPV6_PKTINFO:
+ {
+ struct in6_pktinfo* pktInfoP = (struct in6_pktinfo*) dataP;
+ ERL_NIF_TERM ifIndex = MKI(env, pktInfoP->ipi6_ifindex);
+ ERL_NIF_TERM addr;
+
+ if ((xres = esock_encode_ip6_address(env,
+ &pktInfoP->ipi6_addr,
+ &addr)) != NULL) {
+ *eCMsgHdrData = esock_atom_undefined;
+ return xres;
+ }
+
+ {
+ ERL_NIF_TERM keys[] = {esock_atom_addr, esock_atom_ifindex};
+ ERL_NIF_TERM vals[] = {addr, ifIndex};
+ unsigned int numKeys = sizeof(keys) / sizeof(ERL_NIF_TERM);
+ unsigned int numVals = sizeof(vals) / sizeof(ERL_NIF_TERM);
+
+ ESOCK_ASSERT( (numKeys == numVals) );
+
+ if (!MKMA(env, keys, vals, numKeys, eCMsgHdrData)) {
+ *eCMsgHdrData = esock_atom_undefined;
+ return ESOCK_STR_EINVAL;
+ }
+ }
+ }
+ break;
+#endif
+
+ default:
+ *eCMsgHdrData = MKSBIN(env, ctrlBuf, dataPos, dataLen);
+ break;
+ }
+
+ return NULL;
+}
+#endif
+
+
+
/* +++ encode_msghdr_flags +++
*
* Encode a list of msghdr_flag().
diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam
index 125191c1d0..5b14af3ad8 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 3d65f52a2b..8af052e149 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -228,6 +228,12 @@
-type ipv6_pmtudisc() :: ip_pmtudisc().
+-type ipv6_pktinfo() :: #{
+ addr := ip6_address(),
+ ifindex := integer()
+ }.
+
+
-type sctp_assoc_id() :: int32().
-type sctp_sndrcvinfo() :: #{
stream := uint16(),
@@ -560,6 +566,7 @@
integer().
-type cmsghdr_data() :: timeval() | % if level = socket and type = timstamp
ip_pktinfo() | % if level = ip and type = pktinfo
+ ipv6_pktinfo() | % if level = ipv6 and type = pktinfo
ip_tos() | % if level = ip and type = tos
integer() | % if level = ip and type = ttl
sockaddr_in4() | % if level = ip and type = origdstaddr