💾 Archived View for rawtext.club › ~sloum › geminilist › 006145.gmi captured on 2023-09-28 at 16:53:47. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2021-11-30)

-=-=-=-=-=-=-

<-- back to the mailing list

C program to resolve UTF-8 IDNs

Scot gmi1 at scotdoyle.com

Thu Mar 18 01:19:40 GMT 2021

- - - - - - - - - - - - - - - - - - - 

Hi Sean,

I think you were wondering whether it's possible to resolve UTF-8IDNs with a C or Lua program. This Linux C program [7] will do sovia glibc's getaddrinfo(). For platforms without glibc such as theBSDs, ports of the libidn library [1] are available.

Microsoft provides IdnToAscii() [2] for use with Windows 7 and itlooks as if they support automatic conversion to punycode [3]in their implemenation of getaddrinfo() as of Windows 8.

Slides 30 through 48 of this presentation [4] describe how Appleapproaches network name internationalization. iOS 10 andmacOS Sierra will try to query a given UTF-8 name via DNS. Ifthe server doesn't have an entry for the UTF-8 name, itconverts to punycode and tries again.

Android 2.3 has the java.net.IDN package [5] for convertingIDNs and Android 7.0 has android.icu.text.IDNA [6].

Thoughts?Scot

[1] https://www.gnu.org/software/libidn/[2] https://docs.microsoft.com/en-us/windows/win32/api/winnls/nf-winnls-idntoascii[3] https://docs.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfo[4] https://devstreaming-cdn.apple.com/videos/wwdc/2016/714urluxe140lardrb7/714/714_networking_for_the_modern_internet.pdf?dl=1[5] https://developer.android.com/reference/kotlin/java/net/IDN[6] https://developer.android.com/reference/android/icu/text/IDNA

[7] Public domain example C program to resolve UTF-8 IDNs

define _GNU_SOURCE#include <locale.h>#include <netdb.h>#include <stdio.h>#include <string.h>#include <arpa/inet.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/types.h>

define ADDR_LEN 1024

void show_ip(char *name) {   struct addrinfo filter, *info;   char address[ADDR_LEN];   void *addr;   memset (&filter, 0, sizeof(filter));   filter.ai_family = PF_UNSPEC;   filter.ai_socktype = SOCK_STREAM;   filter.ai_flags = AI_IDN;   if (getaddrinfo (name, NULL, &filter, &info) == 0) {     printf ("\nHost: %s\n", name);     while (info) {       if (info-

ai_family == AF_INET) {         addr = &((struct sockaddr_in *) info-
ai_addr)-
sin_addr;         inet_ntop (AF_INET, addr, address, ADDR_LEN);         printf ("  IPv4 address: %s\n", address);       } else if (info-
ai_family == AF_INET6) {         addr = &((struct sockaddr_in6 *) info-
ai_addr)-
sin6_addr;         inet_ntop (AF_INET6, addr, address, ADDR_LEN);         printf ("  IPv6 address: %s\n", address);       }       info = info-
ai_next;     }   } else     perror ("getaddrinfo");   freeaddrinfo(info);}

int main() {   setlocale(LC_ALL, "");   show_ip("蛸.jp");   show_ip("xn--td2a.jp");   show_ip("gémeaux.bortzmeyer.org");   show_ip("xn--gmeaux-bva.bortzmeyer.org");   show_ip("café.mozz.us");   show_ip("xn--caf-dma.mozz.us");}