<!DOCTYPE html><html><head><title></title><style type="text/css">p.MsoNormal,p.MsoNoSpacing{margin:0}</style></head><body><div>Thanks for clarifying. Well, I suspected that's not a bug per se right after sending my email. I noticed a few comments in the kernel source code about ipv6-mapped addresses which lead me to think that my comment might have been wrong.<br></div><div><br></div><div>Interestingly, the problematic code does not require IPV6-only support in the first place. I am talking about fefe-patched djbdns. There is absolutely no need to use INET6 sockets in the code as the server is actually opening multiple sockets per address anyway so why not open INET sockets for ipv4 addresses? I'll fix the code - looks like it's trivial.<br></div><div><br></div><div>Thanks once more.<br></div><div><br></div><div>--<br></div><div>Aleksej Lebedev<br></div><div><br></div><div>On Wed, Feb 22, 2023, at 01:46, Aaron LI wrote:<br></div><blockquote type="cite" id="qt" style=""><div dir="ltr"><br></div><div dir="ltr">Hi Aleksej,<br></div><div dir="ltr"><br></div><div dir="ltr">DragonFly doesn’t support the ‘<span style="-moz-text-size-adjust:auto;">IPV6_V6ONLY’ socket option, and thus no support of IPv4-mapped IPv6 address.</span><br></div><div dir="ltr"><br></div><div dir="ltr">So a dual-stack program must create one IPv4 socket *and* another IPv6 socket.<br></div><div dir="ltr"><br></div><div dir="ltr">See also the ip6(4) man page:<br></div><div dir="ltr"><a href="https://man.dragonflybsd.org/?command=ip6&section=ANY">https://man.dragonflybsd.org/?command=ip6&section=ANY</a><br></div><div dir="ltr"><br></div><div dir="ltr">— <br></div><div dir="ltr">Aaron<br></div><div dir="ltr"><div><br></div><blockquote type="cite"><div>On Feb 22, 2023, at 06:10, Aleksej Lebedev <root@zta.lk> wrote:<br></div></blockquote></div><blockquote type="cite"><div dir="ltr"><div><span>Hi,</span><br></div><div><span></span><br></div><div><span>I think I found a bug in bind(2) or at least the behavior that differs from Linux and is expected to like in Linux.</span><br></div><div><span>On linux instead of creating a PF_INET UDP socket and assigning an ipv4 address I can create PF_INET6 UDP socket and assigning it an ipv4-mapped ipv6 address (i.e. ::ffff:x.x.x.x).</span><br></div><div><span>On DragonFly the first way works (of course) but the second option doesn't seem to:</span><br></div><div><span></span><br></div><div><span>$ cat test_bind.c </span><br></div><div><span>#include <stdio.h></span><br></div><div><span>#include <stdlib.h></span><br></div><div><span>#include <netinet/in.h></span><br></div><div><span>#include <sys/types.h></span><br></div><div><span>#include <sys/socket.h></span><br></div><div><span>#include <arpa/inet.h></span><br></div><div><span></span><br></div><div><span>void die(const char *s) { perror(s); exit(1); }</span><br></div><div><span></span><br></div><div><span>int main()</span><br></div><div><span>{</span><br></div><div><span>  struct sockaddr_in sa;</span><br></div><div><span>  int s, r;</span><br></div><div><span></span><br></div><div><span>  s = socket(PF_INET, SOCK_DGRAM, 0);</span><br></div><div><span></span><br></div><div><span>  r = inet_pton(AF_INET, "176.9.104.141", &sa.sin_addr);</span><br></div><div><span>  if (r == INADDR_NONE) die("inet_pton");</span><br></div><div><span></span><br></div><div><span>  sa.sin_family = AF_INET;</span><br></div><div><span>  sa.sin_port = 53;</span><br></div><div><span></span><br></div><div><span>  r = bind(s, (const struct sockaddr *)&sa, sizeof sa);</span><br></div><div><span>  if (r != 0) die("bind");</span><br></div><div><span></span><br></div><div><span>}</span><br></div><div><span>$ cc test_bind.c && a.out</span><br></div><div><span>$ echo $?</span><br></div><div><span>0</span><br></div><div><span></span><br></div><div><span>$ cat test_bind6.c </span><br></div><div><span>#include <stdio.h></span><br></div><div><span>#include <stdlib.h></span><br></div><div><span>#include <netinet/in.h></span><br></div><div><span>#include <sys/types.h></span><br></div><div><span>#include <sys/socket.h></span><br></div><div><span>#include <arpa/inet.h></span><br></div><div><span></span><br></div><div><span>void die(const char *s) { perror(s); exit(1); }</span><br></div><div><span></span><br></div><div><span>int main()</span><br></div><div><span>{</span><br></div><div><span>  struct sockaddr_in6 sa;</span><br></div><div><span>  int s, r;</span><br></div><div><span></span><br></div><div><span>  s = socket(PF_INET6, SOCK_DGRAM, 0);</span><br></div><div><span></span><br></div><div><span>  r = inet_pton(AF_INET6, "::ffff:176.9.104.141", &sa.sin6_addr);</span><br></div><div><span>  if (r == INADDR_NONE) die("inet_pton");</span><br></div><div><span></span><br></div><div><span>  sa.sin6_family = AF_INET6;</span><br></div><div><span>  sa.sin6_port = 53;</span><br></div><div><span></span><br></div><div><span>  r = bind(s, (const struct sockaddr *)&sa, sizeof sa);</span><br></div><div><span>  if (r != 0) die("bind");</span><br></div><div><span></span><br></div><div><span>}</span><br></div><div><span>$ cc test_bind6.c && ./a.out</span><br></div><div><span>bind: Can't assign requested address</span><br></div><div><span>$ echo $?</span><br></div><div><span>1</span><br></div><div><span></span><br></div><div><span>On Linux both versions work.</span><br></div><div><span></span><br></div><div><span>--</span><br></div><div><span>Aleksej Lebedev</span><br></div></div></blockquote></blockquote><div><br></div></body></html>