File 2212-erts-esock-More-fixes-of-encode-of-various-socket-ad.patch of Package erlang
From 302403462170496b8b1531b2498e4a3aa67e4331 Mon Sep 17 00:00:00 2001
From: Micael Karlberg <bmk@erlang.org>
Date: Fri, 1 Apr 2022 16:37:36 +0200
Subject: [PATCH 2/5] [erts|esock] More fixes of encode of various socket
address types
OTP-18020
---
erts/emulator/nifs/common/prim_socket_nif.c | 4 +
erts/emulator/nifs/common/socket_int.h | 8 ++
erts/emulator/nifs/common/socket_util.c | 138 ++++++++++++++------
3 files changed, 109 insertions(+), 41 deletions(-)
diff --git a/erts/emulator/nifs/common/prim_socket_nif.c b/erts/emulator/nifs/common/prim_socket_nif.c
index dce01beee6..fce1072bbd 100644
--- a/erts/emulator/nifs/common/prim_socket_nif.c
+++ b/erts/emulator/nifs/common/prim_socket_nif.c
@@ -3976,6 +3976,7 @@ static const struct in6_addr in6addr_loopback =
GLOBAL_ATOM_DECL(addrform); \
GLOBAL_ATOM_DECL(add_membership); \
GLOBAL_ATOM_DECL(add_source_membership); \
+ GLOBAL_ATOM_DECL(alen); \
GLOBAL_ATOM_DECL(allmulti); \
GLOBAL_ATOM_DECL(any); \
GLOBAL_ATOM_DECL(appletlk); \
@@ -4066,6 +4067,7 @@ static const struct in6_addr in6addr_loopback =
GLOBAL_ATOM_DECL(ifindex); \
GLOBAL_ATOM_DECL(igmp); \
GLOBAL_ATOM_DECL(implink); \
+ GLOBAL_ATOM_DECL(index); \
GLOBAL_ATOM_DECL(inet); \
GLOBAL_ATOM_DECL(inet6); \
GLOBAL_ATOM_DECL(infiniband); \
@@ -4120,6 +4122,7 @@ static const struct in6_addr in6addr_loopback =
GLOBAL_ATOM_DECL(multicast_ttl); \
GLOBAL_ATOM_DECL(name); \
GLOBAL_ATOM_DECL(netrom); \
+ GLOBAL_ATOM_DECL(nlen); \
GLOBAL_ATOM_DECL(noarp); \
GLOBAL_ATOM_DECL(nodelay); \
GLOBAL_ATOM_DECL(nodefrag); \
@@ -4207,6 +4210,7 @@ static const struct in6_addr in6addr_loopback =
GLOBAL_ATOM_DECL(set_peer_primary_addr); \
GLOBAL_ATOM_DECL(simplex); \
GLOBAL_ATOM_DECL(slave); \
+ GLOBAL_ATOM_DECL(slen); \
GLOBAL_ATOM_DECL(sndbuf); \
GLOBAL_ATOM_DECL(sndbufforce); \
GLOBAL_ATOM_DECL(sndlowat); \
diff --git a/erts/emulator/nifs/common/socket_int.h b/erts/emulator/nifs/common/socket_int.h
index 4193f676b9..95b2c6c22f 100644
--- a/erts/emulator/nifs/common/socket_int.h
+++ b/erts/emulator/nifs/common/socket_int.h
@@ -60,6 +60,10 @@
#include <sys/un.h>
#endif
+#ifdef HAVE_NET_IF_DL_H
+#include <net/if_dl.h>
+#endif
+
#ifdef HAVE_NETPACKET_PACKET_H
#include <netpacket/packet.h>
#endif
@@ -192,6 +196,7 @@ typedef long ssize_t;
GLOBAL_ATOM_DEF(addrform); \
GLOBAL_ATOM_DEF(add_membership); \
GLOBAL_ATOM_DEF(add_source_membership); \
+ GLOBAL_ATOM_DEF(alen); \
GLOBAL_ATOM_DEF(allmulti); \
GLOBAL_ATOM_DEF(any); \
GLOBAL_ATOM_DEF(appletlk); \
@@ -282,6 +287,7 @@ typedef long ssize_t;
GLOBAL_ATOM_DEF(ifindex); \
GLOBAL_ATOM_DEF(igmp); \
GLOBAL_ATOM_DEF(implink); \
+ GLOBAL_ATOM_DEF(index); \
GLOBAL_ATOM_DEF(inet); \
GLOBAL_ATOM_DEF(inet6); \
GLOBAL_ATOM_DEF(infiniband); \
@@ -336,6 +342,7 @@ typedef long ssize_t;
GLOBAL_ATOM_DEF(multicast_ttl); \
GLOBAL_ATOM_DEF(name); \
GLOBAL_ATOM_DEF(netrom); \
+ GLOBAL_ATOM_DEF(nlen); \
GLOBAL_ATOM_DEF(noarp); \
GLOBAL_ATOM_DEF(nodelay); \
GLOBAL_ATOM_DEF(nodefrag); \
@@ -423,6 +430,7 @@ typedef long ssize_t;
GLOBAL_ATOM_DEF(set_peer_primary_addr); \
GLOBAL_ATOM_DEF(simplex); \
GLOBAL_ATOM_DEF(slave); \
+ GLOBAL_ATOM_DEF(slen); \
GLOBAL_ATOM_DEF(sndbuf); \
GLOBAL_ATOM_DEF(sndbufforce); \
GLOBAL_ATOM_DEF(sndlowat); \
diff --git a/erts/emulator/nifs/common/socket_util.c b/erts/emulator/nifs/common/socket_util.c
index 744cf02161..f4d34dd4db 100644
--- a/erts/emulator/nifs/common/socket_util.c
+++ b/erts/emulator/nifs/common/socket_util.c
@@ -91,6 +91,12 @@ static void esock_encode_packet_addr_tuple(ErlNifEnv* env,
unsigned char* addr,
ERL_NIF_TERM* eAddr);
+#if defined(HAVE_NET_IF_DL_H) && defined(AF_LINK)
+static void esock_encode_sockaddr_dl(ErlNifEnv* env,
+ struct sockaddr_dl* sockAddrP,
+ SOCKLEN_T addrLen,
+ ERL_NIF_TERM* eSockAddr);
+#endif
static void esock_encode_sockaddr_native(ErlNifEnv* env,
struct sockaddr* sa,
SOCKLEN_T len,
@@ -124,6 +130,16 @@ static void make_sockaddr_ll(ErlNifEnv* env,
ERL_NIF_TERM addr,
ERL_NIF_TERM* sa);
#endif
+#if defined(HAVE_NET_IF_DL_H) && defined(AF_LINK)
+static void make_sockaddr_dl(ErlNifEnv* env,
+ ERL_NIF_TERM index,
+ ERL_NIF_TERM type,
+ ERL_NIF_TERM nlen,
+ ERL_NIF_TERM alen,
+ ERL_NIF_TERM slen,
+ ERL_NIF_TERM data,
+ ERL_NIF_TERM* sa);
+#endif
#ifdef HAS_AF_LOCAL
static SOCKLEN_T sa_local_length(int l, struct sockaddr_un* sa);
#endif
@@ -483,7 +499,7 @@ void esock_encode_sockaddr(ErlNifEnv* env,
break;
#endif
-#if defined(AF_LINK)
+#if defined(HAVE_NET_IF_DL_H) && defined(AF_LINK)
case AF_LINK:
/*
* macOS (Darwin Kernel Version 21.4.0):
@@ -522,8 +538,7 @@ void esock_encode_sockaddr(ErlNifEnv* env,
*/
// len = SALEN(addrLen, sizeof(struct sockaddr_dl));
len = SALEN(addrLen, sockAddrP->dl.sdl_len);
- esock_encode_sockaddr_dl(env, &sockAddrP->dl,
- len, esock_atom_link, eSockAddr);
+ esock_encode_sockaddr_dl(env, &sockAddrP->dl, len, eSockAddr);
break;
#endif
@@ -976,6 +991,10 @@ void esock_encode_sockaddr_un(ErlNifEnv* env,
ERL_NIF_TERM ePath;
size_t n, m;
+ UDBG( ("SUTIL", "esock_encode_sockaddr_un -> entry with"
+ "\r\n. addrLen: %d"
+ "\r\n", addrLen) );
+
n = sockAddrP->sun_path - (char *)sockAddrP; // offsetof
if (addrLen >= n) {
n = addrLen - n; // sun_path length
@@ -1041,6 +1060,10 @@ void esock_encode_sockaddr_ll(ErlNifEnv* env,
{
ERL_NIF_TERM eProto, eIfIdx, eHaType, ePktType, eAddr;
+ UDBG( ("SUTIL", "esock_encode_sockaddr_ll -> entry with"
+ "\r\n. addrLen: %d"
+ "\r\n", addrLen) );
+
if (addrLen >= sizeof(struct sockaddr_ll)) {
/* protocol - the standard ethernet protocol type */
@@ -1092,7 +1115,7 @@ void esock_encode_sockaddr_ll(ErlNifEnv* env,
* data: binary()
*/
-#if defined(AF_LINK)
+#if defined(HAVE_NET_IF_DL_H) && defined(AF_LINK)
extern
void esock_encode_sockaddr_dl(ErlNifEnv* env,
struct sockaddr_dl* sockAddrP,
@@ -1102,28 +1125,32 @@ void esock_encode_sockaddr_dl(ErlNifEnv* env,
ERL_NIF_TERM eindex, etype, enlen, ealen, eslen, edata;
SOCKLEN_T dlen;
+ UDBG( ("SUTIL", "esock_encode_sockaddr_dl -> entry with"
+ "\r\n. addrLen: %d"
+ "\r\n", addrLen) );
+
/* There is a minumum length (defined by the size of the data field) */
if (addrLen >= sizeof(struct sockaddr_dl)) {
/* index - if != 0, system given index for interface */
- eindex = MKUI(env, sockAddrP->dl.sdl_index);
+ eindex = MKUI(env, sockAddrP->sdl_index);
/* type - interface type */
- etype = MKUI(env, sockAddrP->dl.sdl_type);
+ etype = MKUI(env, sockAddrP->sdl_type);
/* nlen - interface name length, no trailing 0 reqd. */
- enlen = MKUI(env, sockAddrP->dl.sdl_nlen);
+ enlen = MKUI(env, sockAddrP->sdl_nlen);
/* alen - link level address length */
- ealen = MKUI(env, sockAddrP->dl.sdl_alen);
+ ealen = MKUI(env, sockAddrP->sdl_alen);
/* slen - ink layer selector length */
- eslen = MKUI(env, sockAddrP->dl.sdl_slen);
+ eslen = MKUI(env, sockAddrP->sdl_slen);
/* data - minimum work area, can be larger; *
* contains both if name and ll address */
- dlen = addrLen - (CHARP(sockAddrP->dl.sdl_data)) - CHARP(sockAddrP));
- edata = esock_make_new_binary(env, &sockAddrP->dl.sdl_data, dlen);
+ dlen = addrLen - (CHARP(sockAddrP->sdl_data) - CHARP(sockAddrP));
+ edata = esock_make_new_binary(env, &sockAddrP->sdl_data, dlen);
make_sockaddr_dl(env,
eindex, etype, enlen, ealen, eslen, edata,
@@ -2016,8 +2043,17 @@ void esock_encode_sockaddr_native(ErlNifEnv* env,
size_t size;
ERL_NIF_TERM eData;
- size = ((char*)addr + len) - (char*)&addr->sa_data;
- eData = esock_make_new_binary(env, &addr->sa_data, size);
+ UDBG( ("SUTIL", "esock_encode_sockaddr_native -> entry with"
+ "\r\n. len: %d"
+ "\r\n. eFamily: %T"
+ "\r\n", len, eFamily) );
+
+ if (len > 0) {
+ size = ((char*)addr + len) - (char*)&addr->sa_data;
+ eData = esock_make_new_binary(env, &addr->sa_data, size);
+ } else {
+ eData = esock_make_new_binary(env, &addr->sa_data, 0);
+ }
{
ERL_NIF_TERM keys[] = {esock_atom_family, esock_atom_addr};
@@ -2030,24 +2066,6 @@ void esock_encode_sockaddr_native(ErlNifEnv* env,
}
-/* Encode as #{family := atom() | integer(), addr := undefined}
- * assuming at least the ->family field can be accessed
- * and the rest is unknown.
- */
-static
-void esock_encode_sockaddr_undef(ErlNifEnv* env,
- ERL_NIF_TERM eFamily,
- ERL_NIF_TERM* eSockAddr)
-{
- ERL_NIF_TERM keys[] = {esock_atom_family, esock_atom_addr};
- ERL_NIF_TERM vals[] = {eFamily, esock_atom_undefined};
- size_t numKeys = NUM(keys);
-
- ESOCK_ASSERT( numKeys == NUM(vals) );
- ESOCK_ASSERT( MKMA(env, keys, vals, numKeys, eSockAddr) );
-}
-
-
/* Encode as a raw binary() regarding the whole address
* structure as a blob
*/
@@ -2055,6 +2073,10 @@ static void esock_encode_sockaddr_broken(ErlNifEnv* env,
struct sockaddr* addr,
SOCKLEN_T len,
ERL_NIF_TERM* eSockAddr) {
+ UDBG( ("SUTIL", "esock_encode_sockaddr_broken -> entry with"
+ "\r\n. len: %d"
+ "\r\n", len) );
+
*eSockAddr = esock_make_new_binary(env, addr, len);
}
@@ -2617,17 +2639,51 @@ void make_sockaddr_ll(ErlNifEnv* env,
ERL_NIF_TERM* sa)
{
ERL_NIF_TERM keys[] = {esock_atom_family,
- esock_atom_protocol,
- esock_atom_ifindex,
- esock_atom_hatype,
- esock_atom_pkttype,
- esock_atom_addr};
+ esock_atom_protocol,
+ esock_atom_ifindex,
+ esock_atom_hatype,
+ esock_atom_pkttype,
+ esock_atom_addr};
ERL_NIF_TERM vals[] = {esock_atom_packet,
- proto,
- ifindex,
- hatype,
- pkttype,
- addr};
+ proto,
+ ifindex,
+ hatype,
+ pkttype,
+ addr};
+ size_t numKeys = NUM(keys);
+
+ ESOCK_ASSERT( numKeys == NUM(vals) );
+ ESOCK_ASSERT( MKMA(env, keys, vals, numKeys, sa) );
+}
+#endif
+
+
+/* Construct the Link-Level socket address */
+#if defined(HAVE_NET_IF_DL_H) && defined(AF_LINK)
+static
+void make_sockaddr_dl(ErlNifEnv* env,
+ ERL_NIF_TERM index,
+ ERL_NIF_TERM type,
+ ERL_NIF_TERM nlen,
+ ERL_NIF_TERM alen,
+ ERL_NIF_TERM slen,
+ ERL_NIF_TERM data,
+ ERL_NIF_TERM* sa)
+{
+ ERL_NIF_TERM keys[] = {esock_atom_family,
+ esock_atom_index,
+ esock_atom_type,
+ esock_atom_nlen,
+ esock_atom_alen,
+ esock_atom_slen,
+ esock_atom_data};
+ ERL_NIF_TERM vals[] = {esock_atom_link,
+ index,
+ type,
+ nlen,
+ alen,
+ slen,
+ data};
size_t numKeys = NUM(keys);
ESOCK_ASSERT( numKeys == NUM(vals) );
--
2.34.1