Пример #1
0
static void lookup_drop_cname(AvahiSRBLookup *l, AvahiIfIndex interface, AvahiProtocol protocol, AvahiLookupFlags flags, AvahiRecord *r) {
    AvahiKey *k;
    AvahiSRBLookup *n = NULL;
    AvahiRList *rl;

    assert(r->key->clazz == AVAHI_DNS_CLASS_IN);
    assert(r->key->type == AVAHI_DNS_TYPE_CNAME);

    k = avahi_key_new(r->data.ptr.name, l->record_browser->key->clazz, l->record_browser->key->type);

    for (rl = l->cname_lookups; rl; rl = rl->rlist_next) {
        n = rl->data;

        assert(n);

        if ((n->interface == AVAHI_IF_UNSPEC || n->interface == interface) &&
            (n->interface == AVAHI_PROTO_UNSPEC || n->protocol == protocol) &&
            n->flags == flags &&
            avahi_key_equal(n->key, k))
            break;
    }

    avahi_key_unref(k);

    if (rl) {
        l->cname_lookups = avahi_rlist_remove_by_link(l->cname_lookups, rl);
        lookup_unref(n);
    }
}
Пример #2
0
static int lookup_go(AvahiSRBLookup *l) {
    int n = 0;
    assert(l);

    if (l->record_browser->dead)
        return 0;

    lookup_ref(l);

    /* Browse the cache for the root request */
    n = lookup_scan_cache(l);

    /* Start the lookup */
    if (!l->record_browser->dead && l->ref > 1) {

        if ((l->flags & AVAHI_LOOKUP_USE_MULTICAST) || n == 0)
            /* We do no start a query if the cache contained entries and we're on wide area */

            if (lookup_start(l) < 0)
                n = -1;
    }

    lookup_unref(l);

    return n;
}
Пример #3
0
static void lookup_unref(AvahiSRBLookup *l) {
    assert(l);
    assert(l->ref >= 1);

    if (--l->ref >= 1)
        return;

    AVAHI_LLIST_REMOVE(AvahiSRBLookup, lookups, l->record_browser->lookups, l);
    l->record_browser->n_lookups --;

    if (l->wide_area) {
        avahi_wide_area_lookup_free(l->wide_area);
        l->wide_area = NULL;
    }

    if (l->multicast) {
        avahi_multicast_lookup_free(l->multicast);
        l->multicast = NULL;
    }

    while (l->cname_lookups) {
        lookup_unref(l->cname_lookups->data);
        l->cname_lookups = avahi_rlist_remove_by_link(l->cname_lookups, l->cname_lookups);
    }

    avahi_key_unref(l->key);
    avahi_free(l);
}
Пример #4
0
static void lookup_llmnr_callback(
    AvahiLLMNRLookupEngine *e,
    AvahiIfIndex interface,
    AvahiProtocol protocol,
    AvahiBrowserEvent event,
    AvahiLookupResultFlags flags,
    AvahiRecord *r,
    void *userdata) {

    AvahiSRBLookup *l = userdata;
    AvahiSRecordBrowser *b;

    assert(e);
    assert(l);
/*    assert(AVAHI_IF_VALID(idx) && idx != -1);
    assert(AVAHI_PROTO_VALID(protocol) && protocol != -1);*/

    b = l->record_browser;

    if (b->dead)
        return;

    lookup_ref(l);

    switch(event) {
        case AVAHI_BROWSER_NEW:
            assert(r);

            if (r->key->clazz == AVAHI_DNS_CLASS_IN &&
                r->key->type == AVAHI_DNS_TYPE_CNAME)

                lookup_handle_cname(l, interface, protocol, b->flags, r);
            else
                /* We are discrading packets originating from our own interface/s
                or should we accept them? TODO AVAHI_LOOKUP_RESULT_LOCAL*/
                b->callback(b, interface, protocol, event, r, flags, b->userdata);

            break;

        case AVAHI_BROWSER_REMOVE:
        case AVAHI_BROWSER_CACHE_EXHAUSTED:
            abort();

        case AVAHI_BROWSER_ALL_FOR_NOW:
            b->callback(b, interface, protocol, event, NULL, flags, b->userdata);
            break;

        case AVAHI_BROWSER_FAILURE:
            /* This event states that LLMNR query has been sent three times on specified
            interface and protocol and we don't have any records available */
            /*b->callback(b, interface, protocol, event, NULL, flags, b->userdata);
            lookup_ref(l);*/
            abort();

    }

    lookup_unref(l);
}
Пример #5
0
static void lookup_wide_area_callback(
    AvahiWideAreaLookupEngine *e,
    AvahiBrowserEvent event,
    AvahiLookupResultFlags flags,
    AvahiRecord *r,
    void *userdata) {

    AvahiSRBLookup *l = userdata;
    AvahiSRecordBrowser *b;

    assert(e);
    assert(l);
    assert(l->ref >= 1);

    b = l->record_browser;

    if (b->dead)
        return;

    lookup_ref(l);

    switch (event) {
        case AVAHI_BROWSER_NEW:
            assert(r);

            if (r->key->clazz == AVAHI_DNS_CLASS_IN &&
                r->key->type == AVAHI_DNS_TYPE_CNAME)
                /* It's a CNAME record, so let's follow it. We only follow it on wide area DNS! */
                lookup_handle_cname(l, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AVAHI_LOOKUP_USE_WIDE_AREA, r);
            else {
                /* It's a normal record, so let's call the user callback */
                assert(avahi_key_equal(r->key, l->key));

                b->callback(b, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, event, r, flags, b->userdata);
            }
            break;

        case AVAHI_BROWSER_REMOVE:
        case AVAHI_BROWSER_CACHE_EXHAUSTED:
            /* Not defined for wide area DNS */
            abort();

        case AVAHI_BROWSER_ALL_FOR_NOW:
        case AVAHI_BROWSER_FAILURE:

            b->callback(b, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, event, NULL, flags, b->userdata);
            break;
    }

    lookup_unref(l);

}
Пример #6
0
static void browser_cancel(AvahiSRecordBrowser *b) {
    assert(b);

    if (b->root_lookup) {
        lookup_unref(b->root_lookup);
        b->root_lookup = NULL;
    }

    if (b->defer_time_event) {
        avahi_time_event_free(b->defer_time_event);
        b->defer_time_event = NULL;
    }
}
Пример #7
0
static void lookup_handle_cname(AvahiSRBLookup *l, AvahiIfIndex interface, AvahiProtocol protocol, AvahiLookupFlags flags, AvahiRecord *r) {
    AvahiKey *k;
    AvahiSRBLookup *n;

    assert(l);
    assert(r);

    assert(r->key->clazz == AVAHI_DNS_CLASS_IN);
    assert(r->key->type == AVAHI_DNS_TYPE_CNAME);

    k = avahi_key_new(r->data.ptr.name, l->record_browser->key->clazz, l->record_browser->key->type);
    n = lookup_add(l->record_browser, interface, protocol, flags, k);
    avahi_key_unref(k);

    if (!n) {
        avahi_log_debug(__FILE__": Failed to create SRBLookup.");
        return;
    }

    l->cname_lookups = avahi_rlist_prepend(l->cname_lookups, lookup_ref(n));

    lookup_go(n);
    lookup_unref(n);
}
Пример #8
0
static void lookup_multicast_callback(
    AvahiMulticastLookupEngine *e,
    AvahiIfIndex interface,
    AvahiProtocol protocol,
    AvahiBrowserEvent event,
    AvahiLookupResultFlags flags,
    AvahiRecord *r,
    void *userdata) {

    AvahiSRBLookup *l = userdata;
    AvahiSRecordBrowser *b;

    assert(e);
    assert(l);

    b = l->record_browser;

    if (b->dead)
        return;

    lookup_ref(l);

    switch (event) {
        case AVAHI_BROWSER_NEW:
            assert(r);

            if (r->key->clazz == AVAHI_DNS_CLASS_IN &&
                r->key->type == AVAHI_DNS_TYPE_CNAME)
                /* It's a CNAME record, so let's follow it. We allow browsing on both multicast and wide area. */
                lookup_handle_cname(l, interface, protocol, b->flags, r);
            else {
                /* It's a normal record, so let's call the user callback */

                if (avahi_server_is_record_local(b->server, interface, protocol, r))
                    flags |= AVAHI_LOOKUP_RESULT_LOCAL;

                b->callback(b, interface, protocol, event, r, flags, b->userdata);
            }
            break;

        case AVAHI_BROWSER_REMOVE:
            assert(r);

            if (r->key->clazz == AVAHI_DNS_CLASS_IN &&
                r->key->type == AVAHI_DNS_TYPE_CNAME)
                /* It's a CNAME record, so let's drop that query! */
                lookup_drop_cname(l, interface, protocol, 0, r);
            else {
                /* It's a normal record, so let's call the user callback */
                assert(avahi_key_equal(b->key, l->key));

                b->callback(b, interface, protocol, event, r, flags, b->userdata);
            }
            break;

        case AVAHI_BROWSER_ALL_FOR_NOW:

            b->callback(b, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, event, NULL, flags, b->userdata);
            break;

        case AVAHI_BROWSER_CACHE_EXHAUSTED:
        case AVAHI_BROWSER_FAILURE:
            /* Not defined for multicast DNS */
            abort();

    }

    lookup_unref(l);
}