Home | History | Annotate | Download | only in patches
      1  11510  padraig --- /usr/tmp/clean/avahi-0.6.12/avahi-core/resolve-host-name.c	2006-03-02 01:30:17.000000000 +0000
      2  11510  padraig +++ avahi-0.6.12/avahi-core/resolve-host-name.c	2006-08-28 14:38:21.577853000 +0100
      3  11510  padraig @@ -24,6 +24,7 @@
      4  11510  padraig  #endif
      5  11510  padraig  
      6  11510  padraig  #include <stdlib.h>
      7  11510  padraig +#include <stdio.h>
      8  11510  padraig  
      9  11510  padraig  #include <avahi-common/domain.h>
     10  11510  padraig  #include <avahi-common/timeval.h>
     11  11510  padraig @@ -52,6 +53,15 @@
     12  11510  padraig  
     13  11510  padraig      AvahiTimeEvent *time_event;
     14  11510  padraig  
     15  11510  padraig +#ifdef HAVE_BONJOUR
     16  11510  padraig +    AvahiTimeEvent *defer_time_event;
     17  11510  padraig +    AvahiWatch *watch_a;
     18  11510  padraig +    AvahiWatch *watch_a6;
     19  11510  padraig +    AvahiLookupFlags lookup_flags;
     20  11510  padraig +    DNSServiceRef client_a;
     21  11510  padraig +    DNSServiceRef client_a6;
     22  11510  padraig +#endif
     23  11510  padraig +
     24  11510  padraig      AVAHI_LLIST_FIELDS(AvahiSHostNameResolver, resolver);
     25  11510  padraig  };
     26  11510  padraig  
     27  11510  padraig @@ -96,6 +106,168 @@
     28  11510  padraig      }
     29  11510  padraig  }
     30  11510  padraig  
     31  11510  padraig +#ifdef HAVE_BONJOUR 
     32  11510  padraig +static void resolve_socket_event(AvahiWatch *w, int fd, AvahiWatchEvent events,
     33  11510  padraig +void *userdata) {
     34  11510  padraig +    AvahiSHostNameResolver *r = userdata;
     35  11510  padraig +    DNSServiceErrorType ret;
     36  11510  padraig +    DNSServiceRef client;
     37  11510  padraig +
     38  11510  padraig +    assert(w);
     39  11510  padraig +    assert(fd >= 0);
     40  11510  padraig +    assert(events & AVAHI_WATCH_IN);
     41  11510  padraig +
     42  11510  padraig +    if (fd == DNSServiceRefSockFD(r->client_a))
     43  11510  padraig +        client = r->client_a;
     44  11510  padraig +    else if (fd == DNSServiceRefSockFD(r->client_a6))
     45  11510  padraig +        client = r->client_a6;
     46  11510  padraig +    else
     47  11510  padraig +        assert (0);
     48  11510  padraig +
     49  11510  padraig +    ret = DNSServiceProcessResult(client);
     50  11510  padraig +    if (ret != kDNSServiceErr_NoError) {
     51  11510  padraig +        if (client == r->client_a) {
     52  11510  padraig +            if (r->watch_a) {
     53  11510  padraig +                r->server->poll_api->watch_free(r->watch_a);
     54  11510  padraig +                r->watch_a = NULL;
     55  11510  padraig +            }
     56  11510  padraig +            DNSServiceRefDeallocate(r->client_a);
     57  11510  padraig +            r->client_a = NULL;
     58  11510  padraig +        } else if (client == r->client_a6) {
     59  11510  padraig +            if (r->watch_a6) {
     60  11510  padraig +                r->server->poll_api->watch_free(r->watch_a6);
     61  11510  padraig +                r->watch_a6 = NULL;
     62  11510  padraig +            }
     63  11510  padraig +            DNSServiceRefDeallocate(r->client_a6);
     64  11510  padraig +            r->client_a6 = NULL;
     65  11510  padraig +        }
     66  11510  padraig +        avahi_server_set_errno(r->server, AVAHI_ERR_DISCONNECTED);
     67  11510  padraig +        finish(r, AVAHI_RESOLVER_FAILURE);
     68  11510  padraig +    }
     69  11510  padraig +}
     70  11510  padraig +
     71  11510  padraig +static void resolve_reply(DNSServiceRef client, DNSServiceFlags flags, uint32_t IfIndex, DNSServiceErrorType errorCode, const char *fullname, uint16_t rrtype, uint16_t rrclass, uint16_t rdlen, const void* rdata, uint32_t ttl, void *context) {
     72  11510  padraig +    AvahiSHostNameResolver *r = context;
     73  11510  padraig +    const unsigned char *rd = rdata;
     74  11510  padraig +    AvahiAddress a;
     75  11510  padraig +
     76  11510  padraig +    assert(rrtype == kDNSServiceType_A || rrtype == kDNSServiceType_A6);
     77  11510  padraig +    if (!flags & kDNSServiceFlagsAdd)
     78  11510  padraig +        /* this is a remove event  so ignore*/
     79  11510  padraig +        return;
     80  11510  padraig +
     81  11510  padraig +    if (r->interface > 0  && IfIndex != r->interface)
     82  11510  padraig +        return;
     83  11510  padraig +    if (r->interface <= 0)
     84  11510  padraig +       r->interface = IfIndex;
     85  11510  padraig +
     86  11510  padraig +    /* 
     87  11510  padraig +     * Using Bonjour we cannot determine whether result was obtained from
     88  11510  padraig +     * multicast ot unicast query
     89  11510  padraig +     */
     90  11510  padraig +    r->flags = 0;
     91  11510  padraig +
     92  11510  padraig +    switch (rrtype) {
     93  11510  padraig +        case kDNSServiceType_A:
     94  11510  padraig +            if (r->protocol == AVAHI_PROTO_UNSPEC)
     95  11510  padraig +                r->protocol = AVAHI_PROTO_INET;
     96  11510  padraig +            else if (r->protocol != AVAHI_PROTO_INET)
     97  11510  padraig +                return;
     98  11510  padraig +
     99  11510  padraig +            if (!r->address_record) {
    100  11510  padraig +                if (!(r->address_record = avahi_record_new_full(r->host_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A, ttl))) {
    101  11510  padraig +                    avahi_server_set_errno(r->server, AVAHI_ERR_NO_MEMORY);
    102  11510  padraig +                    finish(r, AVAHI_RESOLVER_FAILURE);
    103  11510  padraig +                    return;
    104  11510  padraig +                }
    105  11510  padraig +                if (avahi_rdata_parse(r->address_record, rdata, rdlen) != 0) {
    106  11510  padraig +                    avahi_server_set_errno(r->server, AVAHI_ERR_INVALID_PACKET);
    107  11510  padraig +                    finish(r, AVAHI_RESOLVER_FAILURE);
    108  11510  padraig +                }
    109  11510  padraig +            }
    110  11510  padraig +            break;
    111  11510  padraig +        case kDNSServiceType_A6:
    112  11510  padraig +            if (r->protocol == AVAHI_PROTO_UNSPEC)
    113  11510  padraig +                r->protocol = AVAHI_PROTO_INET6;
    114  11510  padraig +            else if (r->protocol != AVAHI_PROTO_INET6)
    115  11510  padraig +                return;
    116  11510  padraig +            if (!r->address_record) {
    117  11510  padraig +                if (!(r->address_record = avahi_record_new_full(r->host_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_AAAA, ttl))) {
    118  11510  padraig +                    avahi_server_set_errno(r->server, AVAHI_ERR_NO_MEMORY);
    119  11510  padraig +                    finish(r, AVAHI_RESOLVER_FAILURE);
    120  11510  padraig +                    return;
    121  11510  padraig +                }
    122  11510  padraig +                if (avahi_rdata_parse(r->address_record, rdata, rdlen) != 0) {
    123  11510  padraig +                    avahi_server_set_errno(r->server, AVAHI_ERR_INVALID_PACKET);
    124  11510  padraig +                    finish(r, AVAHI_RESOLVER_FAILURE);
    125  11510  padraig +                    return;
    126  11510  padraig +                }
    127  11510  padraig +            }
    128  11510  padraig +            break;
    129  11510  padraig +        default:
    130  11510  padraig +            abort();
    131  11510  padraig +    }
    132  11510  padraig +    finish(r, AVAHI_RESOLVER_FOUND);
    133  11510  padraig +}
    134  11510  padraig +
    135  11510  padraig +static void resolve_error_callback(AvahiTimeEvent *e, void *userdata) {
    136  11510  padraig +    AvahiSHostNameResolver *r = userdata;
    137  11510  padraig +
    138  11510  padraig +    if (r->defer_time_event) {
    139  11510  padraig +        avahi_time_event_free(r->defer_time_event);
    140  11510  padraig +        r->defer_time_event = NULL;
    141  11510  padraig +    }
    142  11510  padraig +    avahi_server_set_errno(r->server, AVAHI_ERR_FAILURE);
    143  11510  padraig +    finish(r, AVAHI_RESOLVER_FAILURE);
    144  11510  padraig +}
    145  11510  padraig +
    146  11510  padraig +static void avahi_resolve_host_name_start(AvahiSHostNameResolver *r, AvahiProtocol aprotocol)
    147  11510  padraig +{
    148  11510  padraig +    DNSServiceErrorType ret;
    149  11510  padraig +    DNSServiceFlags flags;
    150  11510  padraig +
    151  11510  padraig +    if (r->flags == AVAHI_LOOKUP_USE_MULTICAST)
    152  11510  padraig +        flags = kDNSServiceFlagsForceMulticast;
    153  11510  padraig +
    154  11510  padraig +    if (aprotocol == AVAHI_PROTO_INET || aprotocol == AVAHI_PROTO_UNSPEC) {
    155  11510  padraig +        ret = DNSServiceQueryRecord(&r->client_a,
    156  11510  padraig +                                    flags,
    157  11510  padraig +                                    r->interface == AVAHI_IF_UNSPEC ?
    158  11510  padraig +                                        kDNSServiceInterfaceIndexAny :
    159  11510  padraig +                                        r->interface,
    160  11510  padraig +                                    r->host_name,
    161  11510  padraig +                                    kDNSServiceType_A,
    162  11510  padraig +                                    kDNSServiceClass_IN,
    163  11510  padraig +                                    resolve_reply,
    164  11510  padraig +                                    r);
    165  11510  padraig +        if (ret != kDNSServiceErr_NoError || !r->client_a) {
    166  11510  padraig +            r->defer_time_event = avahi_time_event_new(r->server->time_event_queue, NULL, resolve_error_callback, r);
    167  11510  padraig +           return;
    168  11510  padraig +        } else {
    169  11510  padraig +            r->watch_a = r->server->poll_api->watch_new(r->server->poll_api, DNSServiceRefSockFD(r->client_a), AVAHI_WATCH_IN, resolve_socket_event, r);
    170  11510  padraig +        }
    171  11510  padraig +    }
    172  11510  padraig +    if (aprotocol == AVAHI_PROTO_INET6 || aprotocol == AVAHI_PROTO_UNSPEC) {
    173  11510  padraig +        ret = DNSServiceQueryRecord(&r->client_a6,
    174  11510  padraig +                                    flags,
    175  11510  padraig +                                    r->interface == AVAHI_IF_UNSPEC ?
    176  11510  padraig +                                        kDNSServiceInterfaceIndexAny :
    177  11510  padraig +                                        r->interface,
    178  11510  padraig +                                    r->host_name,
    179  11510  padraig +                                    kDNSServiceType_AAAA,
    180  11510  padraig +                                    kDNSServiceClass_IN,
    181  11510  padraig +                                    resolve_reply,
    182  11510  padraig +                                    r);
    183  11510  padraig +        if (ret != kDNSServiceErr_NoError || !r->client_a6) {
    184  11510  padraig +            r->defer_time_event = avahi_time_event_new(r->server->time_event_queue, NULL, resolve_error_callback, r);
    185  11510  padraig +           return;
    186  11510  padraig +        } else {
    187  11510  padraig +            r->watch_a6 = r->server->poll_api->watch_new(r->server->poll_api, DNSServiceRefSockFD(r->client_a6), AVAHI_WATCH_IN, resolve_socket_event, r);
    188  11510  padraig +        }
    189  11510  padraig +    }
    190  11510  padraig +}
    191  11510  padraig +#endif
    192  11510  padraig +
    193  11510  padraig  static void time_event_callback(AvahiTimeEvent *e, void *userdata) {
    194  11510  padraig      AvahiSHostNameResolver *r = userdata;
    195  11510  padraig      
    196  11510  padraig @@ -118,6 +290,7 @@
    197  11510  padraig      r->time_event = avahi_time_event_new(r->server->time_event_queue, &tv, time_event_callback, r);
    198  11510  padraig  }
    199  11510  padraig  
    200  11510  padraig +#ifndef HAVE_BONJOUR
    201  11510  padraig  static void record_browser_callback(
    202  11510  padraig      AvahiSRecordBrowser*rr,
    203  11510  padraig      AvahiIfIndex interface,
    204  11510  padraig @@ -202,6 +375,7 @@
    205  11510  padraig              break;
    206  11510  padraig      }
    207  11510  padraig  }
    208  11510  padraig +#endif
    209  11510  padraig  
    210  11510  padraig  AvahiSHostNameResolver *avahi_s_host_name_resolver_new(
    211  11510  padraig      AvahiServer *server,
    212  11510  padraig @@ -248,6 +422,15 @@
    213  11510  padraig  
    214  11510  padraig      r->record_browser_aaaa = r->record_browser_a = NULL;
    215  11510  padraig  
    216  11510  padraig +#ifdef HAVE_BONJOUR
    217  11510  padraig +    r->defer_time_event = NULL;
    218  11510  padraig +    r->watch_a = NULL;
    219  11510  padraig +    r->watch_a6 = NULL;
    220  11510  padraig +    r->client_a = NULL;
    221  11510  padraig +    r->client_a6 = NULL;
    222  11510  padraig +    r->lookup_flags = flags;
    223  11510  padraig +    avahi_resolve_host_name_start (r, aprotocol);
    224  11510  padraig +#else
    225  11510  padraig      if (aprotocol == AVAHI_PROTO_INET || aprotocol == AVAHI_PROTO_UNSPEC) {
    226  11510  padraig          k = avahi_key_new(host_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A);
    227  11510  padraig          r->record_browser_a = avahi_s_record_browser_new(server, interface, protocol, k, flags, record_browser_callback, r);
    228  11510  padraig @@ -267,6 +450,7 @@
    229  11510  padraig      }
    230  11510  padraig  
    231  11510  padraig      assert(r->record_browser_aaaa || r->record_browser_a);
    232  11510  padraig +#endif
    233  11510  padraig  
    234  11510  padraig      start_timeout(r);
    235  11510  padraig      
    236  11510  padraig @@ -294,6 +478,23 @@
    237  11510  padraig      if (r->address_record)
    238  11510  padraig          avahi_record_unref(r->address_record);
    239  11510  padraig      
    240  11510  padraig +#ifdef HAVE_BONJOUR
    241  11510  padraig +    if (r->defer_time_event) {
    242  11510  padraig +        avahi_time_event_free(r->defer_time_event);
    243  11510  padraig +        r->defer_time_event = NULL;
    244  11510  padraig +    }
    245  11510  padraig +
    246  11510  padraig +    if (r->watch_a)
    247  11510  padraig +       r->server->poll_api->watch_free(r->watch_a);
    248  11510  padraig +    if (r->watch_a6)
    249  11510  padraig +       r->server->poll_api->watch_free(r->watch_a6);
    250  11510  padraig +
    251  11510  padraig +    if (r->client_a)
    252  11510  padraig +        DNSServiceRefDeallocate(r->client_a);
    253  11510  padraig +    if (r->client_a6)
    254  11510  padraig +        DNSServiceRefDeallocate(r->client_a6);
    255  11510  padraig +#endif
    256  11510  padraig +
    257  11510  padraig      avahi_free(r->host_name);
    258  11510  padraig      avahi_free(r);
    259  11510  padraig  }
    260