可以使用mDNS解析为本地链接地址吗?

时间:2019-05-28 22:18:41

标签: linux ipv6 mdns

在先前有关IPv6本地链接地址的讨论中,我看到一条评论:

  

有人会争辩说,对于任何类型的地址,都不应使用地址代替主机名。使用mDNS映射到本地链接地址可以正常工作。

讨论的上下文是在使用本地链接地址时需要指定接口。

我发现上述评论令人惊讶,因为我没想到mDNS提供链接信息,因此我没想到它会“正常工作”。我构造了一个简单的测试(如下),以查看getaddrinfo提供的信息是否包含链接,并且发现了以下内容:

  • 将地址和链接(例如:fe80::a:a:a:a%wlp3s0)传递到getaddrinfo会导致sockaddr_in6,其中sin6_scope_id设置为3(我的wlan卡的索引) )。这表明getaddrinfo可以提供链接信息。

  • 传递仅mDNS可解析的主机名(解析为相同的链接本地地址)会导致sockaddr_in6,其中sin6_scope_id设置为0,即未指定链接

  • 此外,我已经确认,当mDNS解析链接本地地址时,依赖于getaddrinfo来指定链接的包括SSH在内的程序将失败。但是,如果明确指定了IP地址和链接,它们将成功。


以上评论是否有误,或者我在测试此方法时是否犯了错误? mDNS可以解析为链接本地地址并指定链接吗?

作为参考,我正在Debian Buster Linux 4.19.0-5-amd647版本上进行测试

我的nsswitch.conf包含

hosts:          files mdns4_minimal [NOTFOUND=return] dns myhostname

Testcode.c:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>


int main(int arg_count, char ** args)
{
    struct addrinfo hints, *servinfo, *p;

    for (int i=1; i<arg_count; i++)
    {
        memset(&hints, 0, sizeof hints);
        hints.ai_family = AF_INET6; // to force IPv6
        hints.ai_socktype = SOCK_STREAM;
        printf("Checking %s\n", args[i]);
        if (getaddrinfo(args[i], "https", &hints, &servinfo)) {
            perror("getaddrinfo");
            continue;
        }

        for(p = servinfo; p != NULL; p = p->ai_next) {
            struct sockaddr_in6 * address = ((struct sockaddr_in6 *)p->ai_addr);
            printf("family %d scope %d\n", address->sin6_family, address->sin6_scope_id);
        }
        freeaddrinfo(servinfo);
    }

    return 0;
}

0 个答案:

没有答案
相关问题