Why not always use inet:gethostbyname ?
Folks, why not always rely on system hostname resolver? Do I miss some specific usage scenario which requires usage of inet_res?
I believe that https://github.com/benoitc/hackney/blob/436f7b279771100097f967b86d96c55a79c8cc14/src/hackney_happy.erl#L126 could be simplified to just
case (catch inet:gethostbyname(Hostname, InetType)) of
{'ok', #hostent{h_addr_list=AddrList}} ->
lists:usort(AddrList);
_ ->
[]
Here are details on the issue I have: I'm working on organizig local dev environment based on Docker/Podman compose.
The problem I'm trying to solve is how to make some services working inside compose environment and outside environment at the same time.
Idea is to use magic hostname such as dev.local and use it in URL of all HTTP services, no matters where they are running.
On the dev workstations this magic host is suppose to be added into /etc/hosts
127.0.0.1 dev.local
::1 dev.local
This solution is almost working. The only issue I have is with components based on HTTPoison/hackney. For some reason hackney is trying to resolve host names in URL over DNS first and only then is falling back to the system resolver. And here we come to another "feature" of Docker Desktop: it over its internal DNS server for some reason returns records from the system /etc/hosts. Leading to that the magic host is resolving to 127.0.0.1 over DNS and to 192.168.65.254 over system resolver.
iex(registry@96282b60e624)3> :inet.getaddr(~c'dev.local', :inet)
{:ok, {192, 168, 65, 254}}
iex(registry@d7a9ee9a5a2d)1> :inet_res.getbyname(~c'dev.local', :a)
{:ok, {:hostent, ~c"dev.local", [], :inet, 4, [{127, 0, 0, 1}]}}
iex(registry@d7a9ee9a5a2d)2>
I'm having a similar issue where inet_res is not correctly resolving docker hosts while I'm connected to Wi-Fi
Example:
iex(1)> :inet_res.getbyname(~c'auth0', :a)
{:ok,
{:hostent, ~c"auth0.homenet.telecomitalia.it", [], :inet, 4, [{127, 0, 0, 1}]}}
iex(2)> :inet.getaddr(~c'auth0', :inet)
{:ok, {172, 20, 0, 3}}
This means that while calling curl auth0 (auth0 being the container in the same network) works fine, hackney returns :econnrefused
iex(5)> :hackney.get(~c"http://auth0", [], [], [])
{:error, :econnrefused}
inet_res does work fine if I disable my internet connection though:
iex(1)> :inet_res.getbyname(~c'auth0', :a)
{:ok, {:hostent, ~c"auth0", [], :inet, 4, [{172, 20, 0, 3}]}}
EDIT: From looking at it more closely it seems this is because my router has a search domain (even thought my network settings do not specify one) and it might trip this part of the doc:
This function uses resolver option search that is a list of domain names. If the name to resolve contains no dots, it is prepended to each domain name in the search list, and they are tried in order. If the name contains dots, it is first tried as an absolute name and if that fails, the search list is used. If the name has a trailing dot, it is supposed to be an absolute name and the search list is not used.
Removing the search domain from the router did fix the issue for me, but it still feels like a bug
to handle happy eyeball. I've no issue with docker myself, how do you set networking with docker?
Hi @benoitc .
My idea was to use special hostname such as dev.local as an unified URL for components running inside compose env and on the host. For this purpuses I'm using extra_hosts pointing to the host-gateway - a magic entry, a feature of Docker Desktop for Mac/Windows - letting containers break trough the host network:
extra_hosts:
- "dev.local:host-gateway"
Docker desktop is injecting this entry into /etc/hosts in every containers having extra_hosts entry:
root@docker-desktop:/usr/src/app# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00:: ip6-localnet
ff00:: ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.65.254 dev.local
root@docker-desktop:/usr/src/app#
Then having
127.0.0.1 dev.local
::1 dev.local
in /etc/hosts on the host makes dev.local :
- resolvable as 127.0.0.1 on the host
- in a container: 2.1 resolveble as 192.168.65.254 when using :inet.getaddr() (taking this entry from container' /etc/hosts) 2.2 resolveble as 127.0.0.1 over DNS (:inet_res.getbyname() or so on)