NixOS / nix

Nix, the purely functional package manager
https://nixos.org/
GNU Lesser General Public License v2.1
12.53k stars 1.5k forks source link

mDNS not resolving with libgit2 #9576

Open PAI5REECHO opened 10 months ago

PAI5REECHO commented 10 months ago

Describe the bug

I can't use nix with my local git server

Steps To Reproduce

$ cat /etc/nsswitch.conf
passwd:    files systemd
group:     files [success=merge] systemd
shadow:    files

hosts:     mdns4 [NOTFOUND=return] files dns
networks:  files

ethers:    files
services:  files
protocols: files
rpc:       files

$ avahi-resolve-host-name git.test.local
git.test.local  192.168.1.123

$ ping -c 1 git.test.local
PING git.test.local (192.168.1.123) 56(84) bytes of data.
64 bytes from git.test.local (192.168.1.123): icmp_seq=1 ttl=64 time=0.690 ms

--- git.test.local ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.690/0.690/0.690/0.000 ms

$ curl -I https://git.test.local
HTTP/2 200
alt-svc: h3=":443"; ma=2592000
date: Sat, 09 Dec 2023 22:58:43 GMT
...

$ git clone https://git.home.local/test/test
Cloning into 'test'...
...
Resolving deltas: 100% (53/53), done.

$ nix flake show 'git+https://git.test.local/test/test.git'
warning: could not read HEAD ref from repo at 'https://git.test.local/test/test.git', using 'master'
error:
       … while fetching the input 'git+https://git.test.local/test/test.git'

       error: fetching 'refs/heads/master:refs/heads/master' from 'https://git.test.local/test/test.git': failed to resolve address for git.test.local: Name or service not known

$ getent hosts git.test.local
192.168.1.123  git.test.local

$ host git.test.local
Host git.test.local not found: 3(NXDOMAIN)

Expected behavior

I should be able to fetch from my local git server using nix just I can with git

nix-env --version output

$ nix run -- --version
nix (Nix) 2.20.0pre20231209_dirty

Additional context It fails here: https://github.com/libgit2/libgit2/blob/45fd9ed7ae1a9b74b957ef4f337bc3c8b3df01b5/src/libgit2/remote.c#L1254 Maybe libgit2 isn't configured properly?

(lldb) expression error
(int) $17 = -1
(lldb) thread backtrace 
* thread #1, name = 'nix', stop reason = instruction step over
  * frame #0: 0x00007ffff679d9a6 libgit2.so.1.8`git_smart__connect(transport=0x00000000009dcac0, url="https://git.test.local", direction=<unavailable>, connect_opts=0x00007fffffff7fc0) at smart.c:171:5
    frame #1: 0x00007ffff6779ca6 libgit2.so.1.8`git_remote_connect_ext(remote=0x0000000000812060, direction=GIT_DIRECTION_FETCH, given_opts=0x00007fffffff8110) at remote.c:963:15
    frame #2: 0x00007ffff677a551 libgit2.so.1.8`connect_or_reset_options(remote=0x0000000000812060, direction=0, opts=0x00007fffffff8110) at remote.c:1254:10
    frame #3: 0x00007ffff677c1b1 libgit2.so.1.8`git_remote_fetch(remote=0x0000000000812060, refspecs=0x00007fffffff8290, opts=0x00007fffffff8300, reflog_message=0x0000000000000000) at remote.c:1371:15
    frame #4: 0x00007ffff7a225e3 libnixfetchers.so`nix::GitRepoImpl::fetch(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) + 707
    frame #5: 0x00007ffff7a43d2a libnixfetchers.so`nix::fetchers::GitInputScheme::getAccessor(nix::ref<nix::Store>, nix::fetchers::Input const&) const + 5866
    frame #6: 0x00007ffff7a083e8 libnixfetchers.so`nix::fetchers::InputScheme::fetch(nix::ref<nix::Store>, nix::fetchers::Input const&) + 120
    frame #7: 0x00007ffff7a0b244 libnixfetchers.so`nix::fetchers::Input::fetch(nix::ref<nix::Store>) const + 164
    frame #8: 0x00007ffff7d13621 libnixexpr.so`nix::FlakeRef::fetchTree(nix::ref<nix::Store>) const + 97
    frame #9: 0x00007ffff7d0161f libnixexpr.so`nix::flake::fetchOrSubstituteTree(nix::EvalState&, nix::FlakeRef const&, bool, std::vector<std::pair<nix::FlakeRef, std::pair<nix::StorePath, nix::FlakeRef> >, std::allocator<std::pair<nix::FlakeRef, std::pair<nix::StorePath, nix::FlakeRef> > > >&) + 1231
    frame #10: 0x00007ffff7d03b74 libnixexpr.so`nix::flake::getFlake(nix::EvalState&, nix::FlakeRef const&, bool, std::vector<std::pair<nix::FlakeRef, std::pair<nix::StorePath, nix::FlakeRef> >, std::allocator<std::pair<nix::FlakeRef, std::pair<nix::StorePath, nix::FlakeRef> > > >&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >) + 84
    frame #11: 0x00007ffff7d04fc8 libnixexpr.so`nix::flake::getFlake(nix::EvalState&, nix::FlakeRef const&, bool, std::vector<std::pair<nix::FlakeRef, std::pair<nix::StorePath, nix::FlakeRef> >, std::allocator<std::pair<nix::FlakeRef, std::pair<nix::StorePath, nix::FlakeRef> > > >&) + 56
    frame #12: 0x00007ffff7d05295 libnixexpr.so`nix::flake::lockFlake(nix::EvalState&, nix::FlakeRef const&, nix::flake::LockFlags const&) + 197
    frame #13: 0x0000000000566fd5 nix`FlakeCommand::lockFlake() + 325
    frame #14: 0x000000000057cc76 nix`CmdFlakeShow::run(nix::ref<nix::Store>) + 102
    frame #15: 0x00007ffff78fa397 libnixcmd.so`nix::StoreCommand::run() + 55
    frame #16: 0x000000000059566a nix`nix::mainWrapped(int, char**) + 6410
    frame #17: 0x00007ffff7f378fa libnixmain.so`nix::handleExceptions(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::function<void ()>) + 234
    frame #18: 0x00000000004655e7 nix`main + 151
    frame #19: 0x00007ffff6d5cb0e libc.so.6`__libc_start_call_main + 126
    frame #20: 0x00007ffff6d5cbc9 libc.so.6`__libc_start_main@@GLIBC_2.34 + 137
    frame #21: 0x000000000046a0a5 nix`_start + 37

Priorities

Add :+1: to issues you find important.

roberth commented 10 months ago

I don't see a suitable function in the libgit2 documentation.

Closest thing is git_url_resolve_cb, but that seems to just rewrite the URL, and putting an IP address there would affect TLS and the Host header adversely. So we can't seem to affect DNS resolution through the libgit2 interfaces.

In the code I find socket_connect, which seems to be where they start to resolve the name, and p_getaddrinfo might be the normal getaddrinfo or not, depending on NO_ADDRINFO, but I don't think you're running Nix on an Amiga...

So getaddrinfo is involved. It doesn't seem that the hints are wrong, as no specific address family is required by socket_connect. I assume this is on NixOS? I'm not sure of the intricacies of how glibc is configured to do mDNS. Maybe ask in a NixOS channel?

tomberek commented 10 months ago

A good summary of nsswitch support is here: https://flokli.de/posts/2022-11-18-nsncd/

Basically, loading an arbitrary .so is problematic when there is no expectation of using the same glibc system-wide.