Pushed some further updates. tcp_connect/3 now fetches the address info first and then tries the returned addresses in order until one connects. If none connects it re-throws the exception of the first attempt. It seems Linux first returns the IPv6 addresses. I have no clue whether this is a coincident or design.
Also pushed an updated to the http package, so we can now do this to get a HTTP server listening on all interfaces to IPv6.
For the inet6 experts: The IPv6 address is captured in struct in6_addr. So far, so good and all agree. They also all agree this struct contains a union of three members that provide an 8-bit, 16-bit and 32-bit view on the 128-bit IPv6 address. Only Windows, Linux and MacOS seem to disagree on how to call the union and how to call the three members thereof. They all provide the s6_addr macro to get the 8-bit view, but there seems no agreement way to get the 16 bit view which I use from Prolog as that that matches the notation as close as possible. Linux provides s6_addr16 for the 16-bit view, but Windows calls this s6_word and Apple doesn’t define the macro at all And there are more operating systems …
Should I use s6_addr and combine/split these myself to get the 16 bit view? They are in “network byte” order, which is why we need ntohs() to get the 16-bit integers from the 16 bit view.
I don’t know enough to give any sensible answer, so instead asked ChatGPT.
Me
The IPv6 address is captured in struct in6_addr. So far, so good and all agree. They also all agree this struct contains a union of three members that provide an 8-bit, 16-bit and 32-bit view on the 128-bit IPv6 address. Only Windows, Linux and MacOS seem to disagree on how to call the union and how to call the three members thereof. They all provide the s6_addr macro to get the 8-bit view, but there seems no agreement way to get the 16 bit view which I use from Prolog as that that matches the notation as close as possible. Linux provides s6_addr16 for the 16-bit view, but Windows calls this s6_word and Apple doesn’t define the macro at all And there are more operating systems …
Should I use s6_addr and combine/split these myself to get the 16 bit view? They are in “network byte” order, which is why we need ntohs() to get the 16-bit integers from the 16 bit view.
ChatGPT
It is recommended to use the standard macros provided by each operating system to access the 16-bit view of the IPv6 address in struct in6_addr, as the naming conventions may differ between different operating systems. On Linux, use the s6_addr16 macro, on Windows use s6_word, and on Apple systems you may need to define the macro yourself. It is necessary to use the ntohs() function to convert the 16-bit values from network byte order to host byte order.
If this is of no value, let me know and I will delete it.
Is there a portable way across many operating systems to solve this?
ChatGPT
Unfortunately, there is no portable way across many operating systems to access the 16-bit view of the IPv6 address in struct in6_addr. Different operating systems may have different naming conventions for the macros and there is no standardization. If portability is a concern, it might be better to implement the necessary macro definitions in your code and use the same macro names across all platforms, or to manually split the 128-bit address into 16-bit values yourself and convert them with ntohs().
I won’t delete it. It is pretty accurate and reflects what I found as well. The real question is how to solve this in a portable way however is not answered. These are just 3 of the many OSes SWI-Prolog runs on. Ok, they are the most popular and the only three for which we create official releases, but still …
… and still, I’m impressed by ChatGPT. Despite it sometimes weird failures