Как заставить Phoenix слушать IPv6?

Я изо всех сил пытаюсь найти информацию о том, как заставить Phoenix (и Cowboy и Ranch, если уж на то пошло) слушать как IPv4, так и IPv6.

Я использую VPS с Ubuntu 16.04. Он имеет как IPv4, так и IPv6-адрес. При запуске netstat -tulpn показывает, что beam прослушивает только IPv4 с портами, указанными в конфигурации Phoenix. В то время как другие процессы, такие как epmd, могут прослушивать как IPv4, так и IPv6.

Я пытался указать такой порт, как "::4000", в моем config.exs, но он вылетает из-за невозможности анализа как целого числа.

Может ли кто-нибудь указать мне в правильном направлении? Нужно ли мне как-то добавлять собственный слушатель Cowboy?

Я бы предпочел не запускать Nginx перед прослушиванием трафика IPv6.

Конфигурация, которую я пробовал:

config :my_app, MyApp.Endpoint,
  http: [port: "[::]:4000"]

Трассировка стека (похоже, Phoenix ожидает только целочисленный порт):

** (Mix) Could not start application my_app: MyApp.start(:normal, []) returned an error: shutdown: failed to start child: MyApp.Endpoint
    ** (EXIT) shutdown: failed to start child: Phoenix.Endpoint.Server
        ** (EXIT) an exception was raised:
            ** (ArgumentError) argument error
                :erlang.binary_to_integer("[::]:4000")
                (phoenix) lib/phoenix/endpoint/server.ex:32: Phoenix.Endpoint.Server.to_port/1
                (phoenix) lib/phoenix/endpoint/server.ex:28: Phoenix.Endpoint.Server.default/3
                (phoenix) lib/phoenix/endpoint/server.ex:17: anonymous fn/5 in Phoenix.Endpoint.Server.init/1
                (elixir) lib/enum.ex:1623: Enum."-reduce/3-lists^foldl/2-0-"/3
                (phoenix) lib/phoenix/endpoint/server.ex:15: Phoenix.Endpoint.Server.init/1
                (stdlib) supervisor.erl:294: :supervisor.init/1
                (stdlib) gen_server.erl:328: :gen_server.init_it/6
                (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3

Также это Феникс {:phoenix, "~> 1.2.0"} и Ковбой {:cowboy, "~> 1.0"}


person TalkLittle    schedule 21.09.2016    source источник
comment
Вы пробовали что-то вроде [::]:4000? См. RFC 5952, раздел 6, Примечания по комбинированию адресов IPv6 с номерами портов.   -  person Ron Maupin    schedule 21.09.2016
comment
Спасибо за предложение, но он не может проанализировать целое число. Я обновлю вопрос, добавив немного больше информации, включая трассировку стека.   -  person TalkLittle    schedule 21.09.2016
comment
Во-первых, приложение должно поддерживать IPv6. Похоже, что этого приложения нет. Свяжитесь с его разработчиком (разработчиками).   -  person Michael Hampton    schedule 21.09.2016


Ответы (2)


Согласно https://hexdocs.pm/phoenix/endpoint.html, вы также можете использовать только :inet6. Это работает для меня:

config :my_app, MyApp.Endpoint,
  http: [:inet6, port: 4000],
person phunehehe    schedule 16.10.2018
comment
Спасибо за указание на это. Это сработало после объединения нескольких моих PR: github.com/phoenixframework/phoenix/pull /1933 и github.com/phoenixframework/phoenix/pull/1934 :) - person TalkLittle; 17.10.2018

config :my_app, MyApp.Endpoint,
  http: [port: 4000, ip: {0, 0, 0, 0, 0, 0, 0, 0}]

Это говорит Phoenix прослушивать все адреса IPv6. Он также прослушивает IPv4.

Первоначально я думал, что это только для IPv6, поскольку netstat -tulpn показывает beam только как tcp6, а не tcp. Но после тестирования стало ясно, что он также прослушивает IPv4 как «адрес IPv6, сопоставленный с IPv4».

Формат кортежа IP — тип Erlang inet:ip6_address().

person TalkLittle    schedule 21.09.2016