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