File 7757-erts-inet-drv-Fixed-add-membership.patch of Package erlang

From 348ef05e8ed36923a72c5a739f445e4f3cafa795 Mon Sep 17 00:00:00 2001
From: Micael Karlberg <bmk@erlang.org>
Date: Tue, 12 Mar 2024 17:58:12 +0100
Subject: [PATCH] [erts|inet-drv] Fixed add-membership

Fixed a (probable) copy-and-paste bug for the option
add_membership. When domain = inet6 it used drop_membership
type instead.
---
 erts/emulator/drivers/common/inet_drv.c | 17 +++++++++++++++--
 lib/kernel/src/gen_udp.erl              |  4 ++++
 lib/kernel/src/inet.erl                 |  8 +++++---
 lib/kernel/src/inet6_udp.erl            |  7 +++++++
 4 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 66a5f77d5d..e7bfbcc3eb 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -7412,7 +7412,7 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)
             else if (ival == INET_AF_INET6) {
                 proto = IPPROTO_IPV6;
 #if defined(INET_ADD_MEMBERSHIP)
-                type  = INET_DROP_MEMBERSHIP;
+                type  = INET_ADD_MEMBERSHIP;
 #else
                 return -1;
 #endif
@@ -10596,6 +10596,8 @@ which is always 255 across all platforms */
 static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf,
 			     ErlDrvSizeT len, char** rbuf, ErlDrvSizeT rsize)
 {
+    int save_errno = 0;
+
     switch (cmd) {
 
     case INET_REQ_GETSTAT: {
@@ -11030,8 +11032,19 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf,
 	     (desc->sfamily, &local, &buf, &len)) != NULL)
 	    return ctl_xerror(xerror, rbuf, rsize);
 
+        DDBG(desc,
+             ("INET-DRV-DBG[%d][%d,%T] inet_ctl -> try bind\r\n",
+              __LINE__, desc->s, driver_caller(desc->port)) );
+
 	if (IS_SOCKET_ERROR(sock_bind(desc->s,(struct sockaddr*) &local, len))) {
-	    return ctl_error(sock_errno(), rbuf, rsize);
+
+            save_errno = sock_errno();
+
+            DDBG(desc,
+                 ("INET-DRV-DBG[%d][%d,%T] inet_ctl -> bind failed: %d\r\n",
+                  __LINE__, desc->s, driver_caller(desc->port), save_errno) );
+
+	    return ctl_error(save_errno, rbuf, rsize);
         }
 
 	desc->state = INET_STATE_OPEN;
diff --git a/lib/kernel/src/gen_udp.erl b/lib/kernel/src/gen_udp.erl
index e74ec05b23..9fd14fd6a6 100644
--- a/lib/kernel/src/gen_udp.erl
+++ b/lib/kernel/src/gen_udp.erl
@@ -153,6 +153,7 @@ open(Port) ->
       Reason :: system_limit | inet:posix().
 
 open(Port, Opts0) ->
+    %% ?DBG(['entry', {port, Port}, {opts0, Opts0}]),
     case inet:gen_udp_module(Opts0) of
 	{?MODULE, Opts} ->
 	    open1(Port, Opts);
@@ -161,8 +162,11 @@ open(Port, Opts0) ->
     end.
 
 open1(Port, Opts0) ->
+    %% ?DBG(['entry', {port, Port}, {opts0, Opts0}]),
     {Mod, Opts} = inet:udp_module(Opts0),
+    %% ?DBG([{mod, Mod}, {opts, Opts}]),
     {ok, UP} = Mod:getserv(Port),
+    %% ?DBG([{up, UP}]),
     Mod:open(UP, Opts).
     
 
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index fa826d761f..04493568af 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -1901,6 +1901,7 @@ open_opts(Fd_or_OpenOpts, BAddr, BPort, Opts, Protocol, Family, Type, Module) ->
 	end,
     case prim_inet:open(Protocol, Family, Type, OpenOpts) of
 	{ok,S} ->
+            %% ?DBG(['prim_inet:open', {s, S}]),
             open_setopts(S, BAddr, BPort, Opts, Module);
         Error ->
             Error
@@ -1910,13 +1911,14 @@ open_opts(Fd_or_OpenOpts, BAddr, BPort, Opts, Protocol, Family, Type, Module) ->
 %%
 open_setopts(S, BAddr, BPort, Opts, Module) ->
     %% ?DBG([{s, S}, {baddr, BAddr}, {bport, BPort}, {opts, Opts}, {mod, Module}]),
+    %% ok = prim_inet:setopts(S, [{debug, true}]),
     case prim_inet:setopts(S, Opts) of
         ok when BAddr =:= undefined ->
-            %% ?DBG("register socket"),
+            %% ?DBG("ok -> register socket"),
             inet_db:register_socket(S, Module),
             {ok,S};
         ok ->
-            %% ?DBG("try bind"),
+            %% ?DBG("ok -> try bind"),
             try bind(S, BAddr, BPort) of
                 {ok, _} ->
                     %% ?DBG("bound"),
@@ -1933,7 +1935,7 @@ open_setopts(S, BAddr, BPort, Opts, Module) ->
                     erlang:raise(BC, BE, BS)
             end;
         Error  ->
-            %% ?DBG(["setopts error", {error, Error}]),
+            %% ?DBG(["error", {error, Error}]),
             prim_inet:close(S),
             Error
     end.
diff --git a/lib/kernel/src/inet6_udp.erl b/lib/kernel/src/inet6_udp.erl
index d6647768e9..dae3ef45e1 100644
--- a/lib/kernel/src/inet6_udp.erl
+++ b/lib/kernel/src/inet6_udp.erl
@@ -33,6 +33,8 @@
 -define(TYPE,   dgram).
 
 
+%% -define(DBG(T), erlang:display({{self(), ?MODULE, ?LINE, ?FUNCTION_NAME}, T})).
+
 %% inet_udp port lookup
 getserv(Port) when is_integer(Port) -> {ok, Port};
 getserv(Name) when is_atom(Name) -> inet:getservbyname(Name, ?PROTO).
@@ -49,6 +51,7 @@ open(Port) -> open(Port, []).
 
 -spec open(_, _) -> {ok, port()} | {error, atom()}.
 open(Port, Opts) ->
+    %% ?DBG(['entry', {port, Port}, {opts, Opts}]),
     case inet:udp_options(
 	   [{port,Port} | Opts],
 	   ?MODULE) of
@@ -62,6 +65,10 @@ open(Port, Opts) ->
           when is_map(BAddr); % sockaddr_in()
                ?port(BPort), ?ip6(BAddr);
                ?port(BPort), BAddr =:= undefined ->
+            %% ?DBG(['udp-options',
+            %%       {fd, Fd},
+            %%       {baddr, BAddr}, {bport, BPort},
+            %%       {sock_opts, SockOpts}]),
 	    inet:open_bind(
 	      Fd, BAddr, BPort, SockOpts, ?PROTO, ?FAMILY, ?TYPE, ?MODULE);
 	{ok, _} -> exit(badarg)
-- 
2.35.3

openSUSE Build Service is sponsored by