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-8
IDNs with a C or Lua program. This Linux C program [7] will do so
via glibc's getaddrinfo(). For platforms without glibc such as the
BSDs, ports of the libidn library [1] are available.

Microsoft provides IdnToAscii() [2] for use with Windows 7 and it
looks 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 Apple
approaches network name internationalization. iOS 10 and
macOS Sierra will try to query a given UTF-8 name via DNS. If
the server doesn't have an entry for the UTF-8 name, it
converts to punycode and tries again.

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


[1] https://www.gnu.org/software/libidn/
[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");

int main() {
   setlocale(LC_ALL, "");

More information about the Gemini mailing list