2

我有一个服务器应用程序在 LAN 上的设备上运行,可通过 DNS-SD(即 Zeroconf/Bonjour/Avahi)发现。也在 LAN 上的客户端设备连接到此服务器。我无法控制使用什么应用程序连接到我的服务器应用程序,但我知道他们很可能使用 DNS-SD 和 mDNS 来发现并连接到服务器。仅在给定 C 或 C++ 中的 IP 地址的情况下,如何检索标识这些客户端设备的链接本地域名​​?

根据RFC 6762 Multicast DNS - Section 4. Reverse Address Mapping :
"Like ".local.",IPv4 和 IPv6 反向映射域也被定义为链路本地...因为此域下的名称对应于 IPv4 链路-本地地址,本地链接是查找与这些名称有关的信息的最佳位置是合乎逻辑的。”

所以理论上,应该可以通过IP地址查找链接本地域名​​。有谁知道怎么做?也许我没有在正确的地方寻找,但我没有在 Bonjour 文档中看到对此的 API 调用。

4

1 回答 1

1

我最终通过 Apple 的 Bonjour Dev 邮件列表得到了这个问题的答案。

根据奎因“爱斯基摩人!” ,您可以这样做:

static void DNSCallback(
    DNSServiceRef                       sdRef,
    DNSServiceFlags                     flags,
    uint32_t                            interfaceIndex,
    DNSServiceErrorType                 errorCode,
    const char                          *fullname,
    uint16_t                            rrtype,
    uint16_t                            rrclass,
    uint16_t                            rdlen,
    const void                          *rdata,
    uint32_t                            ttl,
    void                                *context
)
{
    const uint8_t *     cursor;

    fprintf(stderr, "DNSCallback\n");
    assert(rrtype == kDNSServiceType_PTR);
    assert(rrclass == kDNSServiceClass_IN);
    cursor = (const uint8_t *) rdata;
    while ( *cursor != 0 ) {
        fprintf(stderr, "%.*s.", (int) *cursor, cursor + 1);
        cursor += *cursor + 1;
    }
    fprintf(stderr, "\n");
}

static void SocketCallBack(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
{
    DNSServiceErrorType err;

    fprintf(stderr, "SocketCallBack\n");

    err = DNSServiceProcessResult(((AppDelegate *) info)->sdRef);
    fprintf(stderr, "err = %d\n", (int) err);
}

- (IBAction)testAction:(id)sender
{
    DNSServiceErrorType err;
    int                 sock;
    CFSocketRef         cfSock;

    fprintf(stderr, "-[AppDelegate testAction:]\n");

    assert(self->sdRef == NULL);

    err = DNSServiceQueryRecord(
        &self->sdRef,
        kDNSServiceFlagsForceMulticast,
        0,
        "9.40.0.10.in-addr.arpa.",
        kDNSServiceType_PTR,
        kDNSServiceClass_IN,
        DNSCallback,
        self
    );
    fprintf(stderr, "err = %d\n", (int) err);

    sock = DNSServiceRefSockFD(self->sdRef);
    fprintf(stderr, "sock = %d\n", sock);

    CFSocketContext context = { 0, self, NULL, NULL, NULL };

    cfSock = CFSocketCreateWithNative(NULL, sock, kCFSocketReadCallBack, SocketCallBack, &context);
    assert(cfSock != NULL);

    CFRunLoopSourceRef rls;
    rls = CFSocketCreateRunLoopSource(NULL, cfSock, 0);
    assert(rls != NULL);

    CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
}

此示例将查找 IP 地址 10.0.40.9 的链接本地主机名。IP 地址以相反的顺序插入。

于 2013-10-14T03:06:03.400 回答