Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hydra-notify: enable IPv6 support #1395

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

hydra-notify: enable IPv6 support #1395

wants to merge 1 commit into from

Conversation

fogti
Copy link

@fogti fogti commented Jul 20, 2024

HTTP::Server::PSGI uses the ipv6 flag to decide between
IO::Socket::INET and IO::Socket::IP
(https://metacpan.org/dist/Plack/source/lib/HTTP/Server/PSGI.pm#L80-84)
and (from IO/Socket/IP.pm):

CIO::Socket::IP - Family-neutral IP socket supporting both IPv4 and IPv6

so setting the ipv6 flag makes it support both IPv4 and IPv6.

Fixes #1394

HTTP::Server::PSGI uses the `ipv6` flag to decide between
  `IO::Socket::INET` and `IO::Socket::IP`
  (https://metacpan.org/dist/Plack/source/lib/HTTP/Server/PSGI.pm#L80-84)
and (from IO/Socket/IP.pm):
> C<IO::Socket::IP> - Family-neutral IP socket supporting both IPv4 and IPv6
so setting the `ipv6` flag makes it support both IPv4 and IPv6.

Fixes NixOS#1394
@benaryorg
Copy link

I just compiled a version of hydra with a patch setting the flag, but it seems like it doesn't quite work that way:

Starting the Prometheus exporter, listening on http://127.0.0.1:9199/metrics.
failed to listen to port 9199: Invalid argument at /nix/store/vs5db18kx919dgbnz1akfq4d5wf28m5f-hydra-perl-deps/lib/perl5/site_perl/5.38.2/HTTP/Server/PSGI.pm line 103.

@fogti
Copy link
Author

fogti commented Jul 20, 2024

I tested using:

use strict;
use warnings;
use HTTP::Server::PSGI;

my $server = HTTP::Server::PSGI->new(
    host => '::1', 
   # host => '127.0.0.1', # alternatively
    port => 8080,
    timeout => 1,
    ipv6 => 1,
);

my $app = sub {
  return [
    '200',
    [ 'Content-Type' => 'text/html' ],
    [ 42 ],
  ];
};

$server->run($app);

for me, both IPv4 and IPv6 appear to work, I'm using perl 5.38.2 and Plack 1.5.100.
so idk what's wrong here.

switching ipv6 => 1 on and off results in some differences, IO::Socket::IP parses /etc/protocols and /etc/nsswitch.conf and does appear to request some info via NetLink: sendto(3, [{nlmsg_len=20, nlmsg_type=0x16 /* NLMSG_??? */, nlmsg_flags=NLM_F_REQUEST|0x300, nlmsg_seq=1721465735, nlmsg_pid=0}, "\x00\x00\x00\x00"], 20, 0, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, 12) = 20

@fogti
Copy link
Author

fogti commented Jul 20, 2024

It might be useful to invoke the hydra-notify service in strace, to look where it goes wrong (I have no Hydra running here, and setting one up just to test this doesn't seem worth it)

@benaryorg
Copy link

benaryorg commented Jul 20, 2024

This is what happens after reading /etc/protocols:

[pid 1465031] 14:58:57.292905 socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE) = 4
[pid 1465031] 14:58:57.292940 bind(4, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, 12) = 0
[pid 1465031] 14:58:57.292970 getsockname(4, {sa_family=AF_NETLINK, nl_pid=1465031, nl_groups=00000000}, [12]) = 0
[pid 1465031] 14:58:57.293005 sendto(4, [{nlmsg_len=20, nlmsg_type=RTM_GETADDR, nlmsg_flags=NLM_F_REQUEST|NLM_F_DUMP, nlmsg_seq=1721487537, nlmsg_pid=0}, {ifa_family=AF_UNSPEC, ...}], 20, 0, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, 12) = 20
[pid 1465031] 14:58:57.293118 recvmsg(4, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=[{nlmsg_len=76, nlmsg_type=RTM_NEWADDR, nlmsg_flags=NLM_F_MULTI, nlmsg_seq=1721487537, nlmsg_pid=1465031}, {ifa_family=AF_INET, ifa_prefixlen=8, ifa_flags=IFA_F_PERMANENT, ifa_scope=RT_SCOPE_HOST, ifa_index=if_nametoindex("lo")}, [[{nla_len=8, nla_type=IFA_ADDRESS}, inet_addr("127.0.0.1")], [{nla_len=8, nla_type=IFA_LOCAL}, inet_addr("127.0.0.1")], [{nla_len=7, nla_type=IFA_LABEL}, "lo"], [{nla_len=8, nla_type=IFA_FLAGS}, IFA_F_PERMANENT], [{nla_len=20, nla_type=IFA_CACHEINFO}, {ifa_prefered=4294967295, ifa_valid=4294967295, cstamp=1553, tstamp=1553}]]], iov_len=4096}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 76
[pid 1465031] 14:58:57.293200 recvmsg(4, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=[[{nlmsg_len=80, nlmsg_type=RTM_NEWADDR, nlmsg_flags=NLM_F_MULTI, nlmsg_seq=1721487537, nlmsg_pid=1465031}, {ifa_family=AF_INET6, ifa_prefixlen=128, ifa_flags=IFA_F_PERMANENT, ifa_scope=RT_SCOPE_HOST, ifa_index=if_nametoindex("lo")}, [[{nla_len=20, nla_type=IFA_ADDRESS}, inet_pton(AF_INET6, "::1")], [{nla_len=20, nla_type=IFA_CACHEINFO}, {ifa_prefered=4294967295, ifa_valid=4294967295, cstamp=1553, tstamp=1553}], [{nla_len=8, nla_type=IFA_FLAGS}, IFA_F_PERMANENT], [{nla_len=5, nla_type=IFA_PROTO}, "\x01"]]], [{nlmsg_len=72, nlmsg_type=RTM_NEWADDR, nlmsg_flags=NLM_F_MULTI, nlmsg_seq=1721487537, nlmsg_pid=1465031}, {ifa_family=AF_INET6, ifa_prefixlen=64, ifa_flags=0, ifa_scope=RT_SCOPE_UNIVERSE, ifa_index=if_nametoindex("eth0")}, [[{nla_len=20, nla_type=IFA_ADDRESS}, inet_pton(AF_INET6, "2001:41d0:303:192:216:3eff:fe29:dd82")], [{nla_len=20, nla_type=IFA_CACHEINFO}, {ifa_prefered=1766, ifa_valid=3566, cstamp=1984, tstamp=3233695}], [{nla_len=8, nla_type=IFA_FLAGS}, IFA_F_MANAGETEMPADDR|IFA_F_NOPREFIXROUTE]]], [{nlmsg_len=80, nlmsg_type=RTM_NEWADDR, nlmsg_flags=NLM_F_MULTI, nlmsg_seq=1721487537, nlmsg_pid=1465031}, {ifa_family=AF_INET6, ifa_prefixlen=64, ifa_flags=IFA_F_PERMANENT, ifa_scope=RT_SCOPE_LINK, ifa_index=if_nametoindex("eth0")}, [[{nla_len=20, nla_type=IFA_ADDRESS}, inet_pton(AF_INET6, "fe80::216:3eff:fe29:dd82")], [{nla_len=20, nla_type=IFA_CACHEINFO}, {ifa_prefered=4294967295, ifa_valid=4294967295, cstamp=1553, tstamp=1553}], [{nla_len=8, nla_type=IFA_FLAGS}, IFA_F_PERMANENT], [{nla_len=5, nla_type=IFA_PROTO}, "\x03"]]]], iov_len=4096}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 232
[pid 1465031] 14:58:57.293356 recvmsg(4, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=[{nlmsg_len=20, nlmsg_type=NLMSG_DONE, nlmsg_flags=NLM_F_MULTI, nlmsg_seq=1721487537, nlmsg_pid=1465031}, 0], iov_len=4096}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 20
[pid 1465031] 14:58:57.293446 socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 5
[pid 1465031] 14:58:57.293514 connect(5, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = 0
[pid 1465031] 14:58:57.293574 sendto(5, "\2\0\0\0\r\0\0\0\6\0\0\0hosts\0", 18, MSG_NOSIGNAL, NULL, 0) = 18
[pid 1465031] 14:58:57.293669 poll([{fd=5, events=POLLIN|POLLERR|POLLHUP}], 1, 5000) = 1 ([{fd=5, revents=POLLIN|POLLHUP}])
[pid 1465031] 14:58:57.293729 recvmsg(5, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="", iov_len=6}, {iov_base="", iov_len=8}], msg_iovlen=2, msg_controllen=0, msg_flags=MSG_CMSG_CLOEXEC}, MSG_CMSG_CLOEXEC) = 0
[pid 1465031] 14:58:57.293765 close(5)  = 0
[pid 1465031] 14:58:57.293795 close(4)  = 0
[pid 1465031] 14:58:57.293890 write(2, "failed to listen to port 9199: Invalid argument at /nix/store/vs5db18kx919dgbnz1akfq4d5wf28m5f-hydra-perl-deps/lib/perl5/site_perl/5.38.2/HTTP/Server/PSGI.pm line 103.\n", 168) = 168

Don't ask me what that nscd request is about, considering it mentions hosts I would assume that it's the equivalent of getent hosts but then again, shouldn't there be an address listed with that.…

So with the "Invalid argument" not actually being a syscall returning EINVAL I am confused.
I also wonder why my route table is read, which seems wildly inappropriate for binding to a socket (which should just be binding and then maybe responding no an error, but I see no bind here other than the AF_NETLINK one which.… what?).

Exactly the same thing happens when binding to 0.0.0.0.

@Mic92
Copy link
Member

Mic92 commented Aug 21, 2024

For ipv6, glibc needs to look at interfaces (netlink) to figure out things like interface identifier. That's why you see that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

hydra-notify prometheus metrics with IPv6
3 participants