WARP DoH breaks "gethostbyname" on Linux

Hi,

When resolving some hostnames, gethostbyname is broken on Linux. This doesn’t affect only the Linux client, since I was able to reproduce the issue from a Docker container running on a Windows host which was running WARP. The getaddrinfo function is not affected by this bug.

To test this, run python3 -c "import socket; print(socket.gethostbyname('test.s3.amazonaws.com'))". When WARP is running, the following exception is raised:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
socket.gaierror: [Errno -5] No address associated with hostname

When testing gethostbyname natively from C, the error is NO_RECOVERY. The man page says A nonrecoverable name server error occurred.. I checked the source code for this and there’s a number of reasons this error could occur and I couldn’t figure out the exact cause.

// TEST C CODE FOR WARP DOH ERRORS
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <limits.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char* argv[])
{
        struct hostent* host = gethostbyname("test.s3.amazonaws.com");
        if (!host) {
                printf("error %d \n", h_errno);
                switch (h_errno) {
                        case HOST_NOT_FOUND:
                                printf("HOST_NOT_FOUND\n");
                                break;
                        case NO_DATA:
                                printf("NO_DATA\n");
                                break;
                        case NO_RECOVERY:
                                printf("NO_RECOVERY\n");
                                break;
                        case TRY_AGAIN:
                                printf("TRY_AGAIN\n");
                                break;
                        default:
                                printf("unknown\n");
                }
        } else {

                printf ("Name: %s \n", host->h_name);
                char* alias = host->h_aliases[0];
                while (alias) {
                        printf ("\tAlias: %s \n", alias);
                        alias++;
                        break;
                }
        }
        struct addrinfo hints = {}, *addrs;
        hints.ai_flags = AI_CANONNAME;
        char port_str[16] = {};
        int err = getaddrinfo("test.s3.amazonaws.com", port_str, &hints, &addrs);
        if (err != 0)
        {
                fprintf(stderr, " %s\n", gai_strerror(err));
        } else {
                char* address[24];
                inet_ntop(AF_INET, &(((struct sockaddr_in *)addrs->ai_addr)->sin_addr), address, 24);
                printf("addr: %s\ncannonname: %s\n", address, addrs->ai_canonname);
        }
}

This also breaks getent hosts test.s3.amazonaws.com which returns no results.

Anyone else experiencing this issue? This makes WARP DoH absolutely unusable on Linux.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.