<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div dir="ltr"></div><div dir="ltr">Hi Aleksej,</div><div dir="ltr"><br></div><div dir="ltr">DragonFly doesn’t support the ‘<span style="-webkit-text-size-adjust: auto;">IPV6_V6ONLY’ socket option, and thus no support of IPv4-mapped IPv6 address.</span></div><div dir="ltr"><br></div><div dir="ltr">So a dual-stack program must create one IPv4 socket *and* another IPv6 socket.</div><div dir="ltr"><br></div><div dir="ltr">See also the ip6(4) man page:</div><div dir="ltr"><a href="https://man.dragonflybsd.org/?command=ip6&section=ANY">https://man.dragonflybsd.org/?command=ip6&section=ANY</a></div><div dir="ltr"><br></div><div dir="ltr">— </div><div dir="ltr">Aaron</div><div dir="ltr"><br><blockquote type="cite">On Feb 22, 2023, at 06:10, Aleksej Lebedev <root@zta.lk> wrote:<br><br></blockquote></div><blockquote type="cite"><div dir="ltr"><span>Hi,</span><br><span></span><br><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><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><span>On DragonFly the first way works (of course) but the second option doesn't seem to:</span><br><span></span><br><span>$ cat test_bind.c </span><br><span>#include <stdio.h></span><br><span>#include <stdlib.h></span><br><span>#include <netinet/in.h></span><br><span>#include <sys/types.h></span><br><span>#include <sys/socket.h></span><br><span>#include <arpa/inet.h></span><br><span></span><br><span>void die(const char *s) { perror(s); exit(1); }</span><br><span></span><br><span>int main()</span><br><span>{</span><br><span>  struct sockaddr_in sa;</span><br><span>  int s, r;</span><br><span></span><br><span>  s = socket(PF_INET, SOCK_DGRAM, 0);</span><br><span></span><br><span>  r = inet_pton(AF_INET, "176.9.104.141", &sa.sin_addr);</span><br><span>  if (r == INADDR_NONE) die("inet_pton");</span><br><span></span><br><span>  sa.sin_family = AF_INET;</span><br><span>  sa.sin_port = 53;</span><br><span></span><br><span>  r = bind(s, (const struct sockaddr *)&sa, sizeof sa);</span><br><span>  if (r != 0) die("bind");</span><br><span></span><br><span>}</span><br><span>$ cc test_bind.c && a.out</span><br><span>$ echo $?</span><br><span>0</span><br><span></span><br><span>$ cat test_bind6.c </span><br><span>#include <stdio.h></span><br><span>#include <stdlib.h></span><br><span>#include <netinet/in.h></span><br><span>#include <sys/types.h></span><br><span>#include <sys/socket.h></span><br><span>#include <arpa/inet.h></span><br><span></span><br><span>void die(const char *s) { perror(s); exit(1); }</span><br><span></span><br><span>int main()</span><br><span>{</span><br><span>  struct sockaddr_in6 sa;</span><br><span>  int s, r;</span><br><span></span><br><span>  s = socket(PF_INET6, SOCK_DGRAM, 0);</span><br><span></span><br><span>  r = inet_pton(AF_INET6, "::ffff:176.9.104.141", &sa.sin6_addr);</span><br><span>  if (r == INADDR_NONE) die("inet_pton");</span><br><span></span><br><span>  sa.sin6_family = AF_INET6;</span><br><span>  sa.sin6_port = 53;</span><br><span></span><br><span>  r = bind(s, (const struct sockaddr *)&sa, sizeof sa);</span><br><span>  if (r != 0) die("bind");</span><br><span></span><br><span>}</span><br><span>$ cc test_bind6.c && ./a.out</span><br><span>bind: Can't assign requested address</span><br><span>$ echo $?</span><br><span>1</span><br><span></span><br><span>On Linux both versions work.</span><br><span></span><br><span>--</span><br><span>Aleksej Lebedev</span><br></div></blockquote></body></html>