Elixir/Erlang: :ssl.start 在使用 :reuseaddr, true 在不同的 IP 上启动时返回 :error, :already_listening

Posted

技术标签:

【中文标题】Elixir/Erlang: :ssl.start 在使用 :reuseaddr, true 在不同的 IP 上启动时返回 :error, :already_listening【英文标题】:Elixir/Erlang: :ssl.start returns :error, :already_listening when starting on different IPs using :reuseaddr, trueElixir/Erlang: :ssl.start 在使用 :reuseaddr, true 在不同的 IP 上启动时返回 :error, :already_listening 【发布时间】:2021-06-28 18:52:57 【问题描述】:

我需要在主机的同一端口上的不同 IP 上打开两个 DTLS 套接字。 使用 :gen_udp:reuseaddr, true 可以正常工作。 但不是 :ssl.listen

您可以使用以下命令重现它:

sudo ip addr add ::2 dev lo

然后在iex中

:ssl.start

:ok, socket = :ssl.listen(20_100, [
  :binary,
  :inet6,
  :active, true,
  :reuseaddr, true,
  :protocol, :dtls,
  :ip, 0, 0, 0, 0, 0, 0, 0, 1
])

:ok, socket2 = :ssl.listen(20_100, [
  :binary,
  :inet6,
  :active, true,
  :reuseaddr, true,
  :protocol, :dtls,
  :ip, 0, 0, 0, 0, 0, 0, 0, 2
])

最后一个 :ssl.listen 不会匹配 :error, :already_listening

如何使用 :ssl.listen:reuseaddr 选项在主机的同一端口上的不同 IP 地址上启动两个 DTLS 套接字?

【问题讨论】:

【参考方案1】:

这是一个 Erlang 错误。该问题已在 OTP 23.3 中解决。

https://github.com/erlang/otp/issues/4375

【讨论】:

【参考方案2】:

对于 IPV6,::1/128 是默认分配给环回接口 lo 的唯一地址。

您还需要将::2/128 分配给环回接口。然后第二个:ssl:listen() 就可以了

【讨论】:

这就是我所做的: sudo ip addr add ::2 dev lo 不存在的 IP 的错误消息也不同。 试试 sudo ip -6 addr add ::2/128 dev lo 感谢您的建议。我试过了,还是同样的问题。至少在我的操作系统(Ubuntu 18)上,不需要 -6 选项并用 /128 指定前缀长度。当我使用 ifconfig 查看我的界面时,sudo ip addr add ::2 dev lo 和 ip -6 addr add ::2/128 dev lo 会产生相同的结果。 这真的很奇怪,我可以使用相同的端口创建两个侦听套接字,但使用两个不同的 IP 地址 0,0,0,0,0,0,0,1 和 0 ,0,0,0,0,0,0,2 在 erlang (erl) shell 中,但不在 Elixir (iex) shell 中。

以上是关于Elixir/Erlang: :ssl.start 在使用 :reuseaddr, true 在不同的 IP 上启动时返回 :error, :already_listening的主要内容,如果未能解决你的问题,请参考以下文章

Elixir/Erlang

E1.获取Elixir/Erlang版本信息

Elixir/Erlang 中的命名函数是不是有等效于 __MODULE__ 的方法?

Elixir/Erlang:变量列表与许多其他列表合并时出错

将本地 Elixir/Erlang 连接到 Docker 容器内正在运行的应用程序

在 Elixir/Erlang 中的(本地)Mnesia 实例上实现最佳写入性能