anchor.diff:              %% Since send data may have been lost, and there is no room
               %% in this API to inform the caller, we at least close
               %% the socket in the write direction
  -%%%    ?DBG(Result),
  +            %%
  +            %% ?DBG(Result),
               case Reason of
                   econnreset ->
                       case maps:get(show_econnreset, Meta) of
  
positive.code:      | sockaddrs(IPs, TP, Domain)].
  
  %% -------------------------------------------------------------------------
  
  setopts_split(FilterTags, Opts) ->
      setopts_split(FilterTags, Opts, [], []).
  %%
  setopts_split(_FilterTags, [], True, False) ->
      {reverse(True), reverse(False)};
  setopts_split(FilterTags, [Opt | Opts], True, False) ->
      %% ?DBG({FilterTags, Opt}),
      Opt_1 = conv_setopt(Opt),
      case member(FilterTags, setopt_categories(Opt_1)) of
          true ->
              setopts_split(FilterTags, Opts, [Opt_1 | True], False);
          false ->
              setopts_split(FilterTags, Opts, True, [Opt_1 | False])
      end.
  
  
  %% Set operation on atom sets that are atoms or maps with atom tags.
  %% Returns true if sets have at least one common member, false otherwise.
  %% X is atom() or map(), Y is map().
  member(X, Y) when is_atom(X), is_map(Y) ->
      case Y of
          #{X := _} -> true;
          #{} -> false
      end;
  member(X, Y) when is_map(X), is_map(Y) ->
      maps:fold(
        fun (_, _, true) -> true;
            (Key, _, false) -> maps:is_key(Key, Y)
        end, false, X).
  
  
  conv_setopt(binary) -> {mode, binary};
  conv_setopt(list) -> {mode, list};
  conv_setopt(inet) -> {tcp_module, inet_tcp};
  conv_setopt(inet6) -> {tcp_module, inet6_tcp};
  conv_setopt(local) -> {tcp_module, local_tcp};
  conv_setopt(Other) -> Other.
  
  %% Socket options
  
  socket_setopt(Socket, {raw, Level, Key, Value}) ->
      socket:setopt_native(Socket, {Level,Key}, Value);
  socket_setopt(Socket, {raw, {Level, Key, Value}}) ->
      socket:setopt_native(Socket, {Level,Key}, Value);
  socket_setopt(Socket, {Tag, Value}) ->
      %% ?DBG({Tag, Value}),
      case socket_opt() of
          #{Tag := {Domain, _} = Opt} when is_atom(Domain) ->
              %% ?DBG(Opt),
              %% socket:setopt(Socket, otp, debug, true),
              Res = socket:setopt(Socket, Opt, socket_setopt_value(Tag, Value)),
              %% socket:setopt(Socket, otp, debug, false),
              Res;
  
          #{Tag := DomainProps} when is_list(DomainProps) ->
              %% We need to lookup the domain of the socket,
              %% so we can select which one to use.                            
              %% ?DBG(Opt0),
              case socket:getopt(Socket, otp, domain) of
                  {ok, Domain} ->
                      case lists:keysearch(Domain, 1, DomainProps) of
                          {value, {Domain, Level, OptKey}} ->
                              Opt = {Level, OptKey},
                              %% _ = socket:setopt(Socket, otp, debug, true),
                              Res = socket:setopt(Socket,
                                                  Opt,
                                                  socket_setopt_value(Tag,
                                                                      Value)),
                              %% _ = socket:setopt(Socket, otp, debug, false),
                              Res;
                          false ->
                              {error, einval}
                      end;
                  {error, _} ->
                      {error, einval}
              end;
  
          #{} ->
              {error, einval}
      end.
  
  socket_setopt_value(linger, {OnOff, Linger}) ->
      #{onoff => OnOff, linger => Linger};
  socket_setopt_value(_Tag, Value) -> Value.
  
  socket_getopt(Socket, {raw, Level, Key, ValueSpec}) ->
      socket:getopt_native(Socket, {Level,Key}, ValueSpec);
  socket_getopt(Socket, {raw, {Level, Key, ValueSpec}}) ->
      socket:getopt_native(Socket, {Level,Key}, ValueSpec);
  socket_getopt(Socket, Tag) when is_atom(Tag) ->
      case socket_opt() of
          #{Tag := {Domain, _} = Opt} when is_atom(Domain) ->
              %% ?DBG({'socket_getopt - match', Tag}),
              %% _ = socket:setopt(Socket, otp, debug, true),
              Res = socket:getopt(Socket, Opt),
              %% ?DBG({'socket_getopt - result', Res}),
              %% _ = socket:setopt(Socket, otp, debug, false),
              socket_getopt_value(Tag, Res);
  
          #{Tag := DomainProps} when is_list(DomainProps) ->
              %% We need to lookup the domain of the socket,
              %% so we can select which one to use.                            
              %% ?DBG({'socket_getopt - match', Tag, DomainProps}),
              case socket:getopt(Socket, otp, domain) of
                  {ok, Domain} ->
                      %% ?DBG({'socket_getopt - domain', Tag, Domain}),
                      case lists:keysearch(Domain, 1, DomainProps) of
                          {value, {Domain, Level, OptKey}} ->
                              %% ?DBG({'socket_getopt - ok domain', Tag, Level, OptKey}),
                              Opt  = {Level, OptKey},
                              %% _ = socket:setopt(Socket, otp, debug, true),
                              Res = socket:getopt(Socket, Opt),
                              %% _ = socket:setopt(Socket, otp, debug, false),
                              %% ?DBG({'socket_getopt - result', Res}),
                              socket_getopt_value(Tag, Res);
                          false ->
                              %% ?DBG({'socket_getopt - invalid domain', Tag, Domain, DomainProps}),
                              {error, einval}
                      end;
                  {error, _DReason} ->
                      %% ?DBG({'socket_getopt - unknown domain', Tag, _DReason}),
                      {error, einval}
              end;
  
          #{} = __X__ ->
              %% ?DBG({'socket_getopt - no match - 2', Tag, __X__}),
              {error, einval}
      end.
  
  socket_getopt_value(linger, {ok, #{onoff := OnOff, linger := Linger}}) ->
      {ok, {OnOff, Linger}};
  socket_getopt_value(pktoptions, {ok, PktOpts0}) when is_list(PktOpts0) ->
      PktOpts = [{Type, Value} || #{type := Type, value := Value} <- PktOpts0],
      {ok, PktOpts};
  socket_getopt_value(_Tag, {ok, _Value} = Ok) -> Ok;
  socket_getopt_value(_Tag, {error, _} = Error) -> Error.
  
  socket_copy_opt(Socket, Tag, TargetSocket) when is_atom(Tag) ->
      case socket_opt() of
          #{Tag := Opt} ->
  	    case socket:is_supported(options, Opt) of
  		true ->
  		    case socket:getopt(Socket, Opt) of
  
negative.code:     case Result of
  	%% We should really return the rest data rather then just ignoring it.
  	%% In the case we get a timeout when sending and 'send_timeout_close'
  	%% is set true, we close the connection and only return the timeout.
  	%% Otherwise we return the full error.
          {error, {timeout = Reason, RestData}} = E when is_binary(RestData) ->
  	    case maps:get(send_timeout_close, Meta) of
  