defmodule SNet.Addr do @moduledoc""" Helper module for getting our IP addresses. Runs an agent that gets our public IPv4 address on the internet and stores it. """ use Agent require Logger def start_link(_) do Agent.start_link(__MODULE__, :init, [], name: __MODULE__) end def init() do Application.ensure_all_started(:inets) Application.ensure_all_started(:ssl) case :httpc.request('http://api.ipify.org') do {:ok, {_, _, body}} -> {:ok, addr} = :inet.parse_address body Logger.info "Public IP address: #{body}" [addr] _ -> Logger.info "Could not get public IP address" [] end end @doc""" Reteurn the list of IPv4 address for our network interfaces. """ def get_if_inet4 do {:ok, ifs} = :inet.getifaddrs for {_, opts} <- ifs, {:addr, addr} <- opts, tuple_size(addr) == 4, addr != {127,0,0,1} do addr end end @doc""" Return our public IPv4 address as observed by an external API provider (`ipify.org`) """ def get_pub_inet4 do Agent.get(__MODULE__, &(&1)) end @doc""" Get all our IPv4 addresses. """ def get_all_inet4 do addrset = for x <- get_if_inet4() ++ get_pub_inet4(), into: %MapSet{}, do: x MapSet.to_list addrset end @doc""" Determines if an IP address is ours or not. """ def is_local?({:inet, ip, port}) do port == Application.get_env(:shard, :port) and (ip == {127,0,0,1} or ip in get_all_inet4()) end end