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