Skip to content

Commit

Permalink
Add MiniUPNP nat discovery wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
Samuel committed Jun 14, 2022
1 parent 0ac4cf8 commit fb15f07
Show file tree
Hide file tree
Showing 13 changed files with 77 additions and 1,385 deletions.
2 changes: 1 addition & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ config :archethic, ArchethicWeb.FaucetController,
# -----Start-of-Networking-configs-----

config :archethic, Archethic.Networking.IPLookup.NATDiscovery,
provider: Archethic.Networking.IPLookup.NATDiscovery.UPnPv1
provider: Archethic.Networking.IPLookup.NATDiscovery.MiniUPNP

config :archethic, Archethic.Networking.IPLookup.RemoteDiscovery,
provider: Archethic.Networking.IPLookup.RemoteDiscovery.IPIFY
Expand Down
49 changes: 9 additions & 40 deletions lib/archethic/networking/ip_lookup/nat_discovery.ex
Original file line number Diff line number Diff line change
@@ -1,55 +1,24 @@
defmodule Archethic.Networking.IPLookup.NATDiscovery do
@moduledoc """
Provide abstraction over :natupnp_v1, :natupnp_v2, :natpmp
Provide implementation to discover ip address using NAT
"""

alias Archethic.Networking.IPLookup.Impl

alias __MODULE__.UPnPv1
alias __MODULE__.UPnPv2
alias __MODULE__.PMP

require Logger

@behaviour Impl
def get_node_ip() do
provider = provider()
do_get_node_ip(provider)
end

defp do_get_node_ip(provider) do
case provider.get_node_ip() do
{:ok, ip} ->
{:ok, ip}

{:error, reason} ->
Logger.error(
"Cannot use the provider #{provider} for IP Lookup - reason: #{inspect(reason)}"
)

fallback(provider, reason)
end
end

defp fallback(UPnPv1, _reason) do
do_get_node_ip(UPnPv2)
end

defp fallback(UPnPv2, _reason) do
do_get_node_ip(PMP)
end

defp fallback(PMP, reason) do
{:error, reason}
@spec get_node_ip() :: {:ok, :inet.ip_address()} | {:error, any()}
def get_node_ip do
provider().get_node_ip()
end

defp fallback(_provider, reason) do
{:error, reason}
@spec open_port(non_neg_integer()) :: :ok | :error
def open_port(port) do
provider().open_port(port)
end

defp provider() do
defp provider do
:archethic
|> Application.get_env(__MODULE__, [])
|> Keyword.get(:provider, UPnPv1)
|> Keyword.get(:provider, __MODULE__.MiniUPNP)
end
end
65 changes: 65 additions & 0 deletions lib/archethic/networking/ip_lookup/nat_discovery/miniupnp.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
defmodule Archethic.Networking.IPLookup.NATDiscovery.MiniUPNP do
@moduledoc false

require Logger

@upnpc Application.app_dir(:archethic, "priv/c_dist/upnpc")

@spec get_node_ip() :: {:ok, :inet.ip_address()} | {:error, any()}
def get_node_ip do
case System.cmd(@upnpc, ["-s"]) do
{output, 0} ->
[[_, ip]] = Regex.scan(~r/ExternalIPAddress = ([0-9.]*)/, output, capture: :all)

ip
|> to_charlist()
|> :inet.parse_address()

{_, status} ->
{:error, status}
end
end

@spec open_port(non_neg_integer()) :: :ok | :error
def open_port(port) do
# {:ok, [{local_ip, _, _} | _]} = :inet.getif()

local_ip =
case System.cmd(@upnpc, ["-s"]) do
{output, 0} ->
[[_, ip]] = Regex.scan(~r/Local LAN ip address : ([0-9.]*)/, output, capture: :all)

ip
|> to_charlist()
|> :inet.parse_address()
|> elem(1)

{_, status} ->
{:error, status}
end

opts = [
# Add redirection
"-a",
# Local ip
local_ip |> :inet.ntoa() |> to_string(),
# Local opened port
"#{port}",
# Remote port to open
"#{port}",
# Protocol
"tcp",
# Lifetime
"0"
]

case System.cmd(@upnpc, opts) do
{_, 0} ->
{:ok, port}

{reason, _status} ->
Logger.debug(reason)
:error
end
end
end
14 changes: 0 additions & 14 deletions lib/archethic/networking/ip_lookup/nat_discovery/pmp.ex

This file was deleted.

14 changes: 0 additions & 14 deletions lib/archethic/networking/ip_lookup/nat_discovery/upnp_v1.ex

This file was deleted.

14 changes: 0 additions & 14 deletions lib/archethic/networking/ip_lookup/nat_discovery/upnp_v2.ex

This file was deleted.

16 changes: 2 additions & 14 deletions lib/archethic/networking/port_forwarding.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ defmodule Archethic.Networking.PortForwarding do
Logger.info("Port must be open manually")
port

{:error, _} ->
:error ->
Logger.error("Cannot publish the port #{port}")
fallback(port, force?)
end
Expand All @@ -39,19 +39,7 @@ defmodule Archethic.Networking.PortForwarding do
Application.get_env(:archethic, __MODULE__, []) |> Keyword.get(:enabled, true)
end

defp do_try_open_port(port), do: assign_port([:natupnp_v1, :natupnp_v2, :natpmp], port)

defp assign_port([], _), do: {:error, :port_unassigned}

defp assign_port([protocol_module | protocol_modules], port) do
with {:ok, router_ip} <- protocol_module.discover(),
{:ok, _, internal_port, _, _} <-
protocol_module.add_port_mapping(router_ip, :tcp, port, port, 0) do
{:ok, internal_port}
else
{:error, _} -> assign_port(protocol_modules, port)
end
end
defp do_try_open_port(port), do: NATDiscovery.open_port(port)

defp fallback(port, _force? = true) do
case do_try_open_port(0) do
Expand Down
6 changes: 0 additions & 6 deletions src/nat/nat.erl

This file was deleted.

6 changes: 0 additions & 6 deletions src/nat/nat.hrl

This file was deleted.

74 changes: 0 additions & 74 deletions src/nat/nat_lib.erl

This file was deleted.

Loading

0 comments on commit fb15f07

Please sign in to comment.