rust/cargo-c: update to 0.10.7+cargo-0.84.0
[oi-userland.git] / components / network / avahi / patches / 05-resolve-service.patch
blob17cb3180e7f6786eb17eb3d2a5888e4ab77ad39a
1 --- /usr/tmp/clean/avahi-0.6.28/avahi-core/resolve-service.c 2010-08-26 01:51:38.991153000 +0100
2 +++ avahi-0.6.28/avahi-core/resolve-service.c 2011-01-20 12:36:38.289095469 +0000
3 @@ -25,6 +25,10 @@
4 #include <stdio.h>
5 #include <stdlib.h>
7 +#ifdef HAVE_BONJOUR
8 +#include <netinet/in.h> /* for ntohs */
9 +#endif
11 #include <avahi-common/domain.h>
12 #include <avahi-common/timeval.h>
13 #include <avahi-common/malloc.h>
14 @@ -59,9 +63,303 @@
16 AvahiTimeEvent *time_event;
18 +#ifdef HAVE_BONJOUR
19 + uint16_t port;
20 + AvahiTimeEvent *defer_time_event;
21 + char *host;
22 + AvahiWatch *watch;
23 + AvahiWatch *watch_a;
24 + AvahiWatch *watch_a6;
25 + DNSServiceRef client;
26 + DNSServiceRef client_a;
27 + DNSServiceRef client_a6;
28 +#endif
30 AVAHI_LLIST_FIELDS(AvahiSServiceResolver, resolver);
34 +#ifdef HAVE_BONJOUR
35 +static void finish(AvahiSServiceResolver *r, AvahiResolverEvent event ) {
36 + AvahiLookupResultFlags flags;
38 + assert(r);
40 + if (r->time_event) {
41 + avahi_time_event_free(r->time_event);
42 + r->time_event = NULL;
43 + }
45 + flags = 0;
47 + switch (event) {
48 + case AVAHI_RESOLVER_FAILURE:
50 + r->callback(r,
51 + r->interface,
52 + r->protocol,
53 + event,
54 + r->service_name,
55 + r->service_type,
56 + r->domain_name,
57 + NULL,
58 + NULL,
59 + 0,
60 + NULL,
61 + flags,
62 + r->userdata);
63 + break;
65 + case AVAHI_RESOLVER_FOUND: {
66 + AvahiAddress a;
68 + if (r->address_record) {
69 + switch (r->address_record->key->type) {
70 + case AVAHI_DNS_TYPE_A:
71 + a.proto = AVAHI_PROTO_INET;
72 + a.data.ipv4 = r->address_record->data.a.address;
73 + break;
75 + case AVAHI_DNS_TYPE_AAAA:
76 + a.proto = AVAHI_PROTO_INET6;
77 + a.data.ipv6 = r->address_record->data.aaaa.address;
78 + break;
80 + default:
81 + assert(0);
82 + }
83 + }
85 + flags = 0;
86 + if (avahi_domain_equal(r->server->host_name_fqdn, r->host))
87 + flags |= AVAHI_LOOKUP_RESULT_LOCAL;
88 + r->callback(r,
89 + r->interface,
90 + r->protocol,
91 + event,
92 + r->service_name,
93 + r->service_type,
94 + r->domain_name,
95 + r->host,
96 + r->address_record ? &a : NULL,
97 + r->port,
98 + r->txt_record ? r->txt_record->data.txt.string_list : NULL,
99 + flags,
100 + r->userdata);
101 + break;
106 +static void query_record(DNSServiceRef sdRef, const DNSServiceFlags flags, uint32_t ifIndex, DNSServiceErrorType errorCode,
107 + const char *fullname, uint16_t rrtype, uint16_t rrclass, uint16_t rdlen, const void *rdata, uint32_t ttl, void *context)
109 + AvahiSServiceResolver *r = context;
110 + const unsigned char *rd = rdata;
111 + AvahiAddress a;
112 + int changed = 0;
114 + if (r->interface > 0 && ifIndex != r->interface)
115 + return;
116 + if (r->interface <= 0)
117 + r->interface = ifIndex;
119 + switch (rrtype) {
120 + case kDNSServiceType_A:
121 + if (!r->address_record) {
122 + if (!(r->address_record = avahi_record_new_full(r->host, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A, ttl))) {
123 + avahi_server_set_errno(r->server, AVAHI_ERR_NO_MEMORY);
124 + finish(r, AVAHI_RESOLVER_FAILURE);
125 + return;
127 + if (avahi_rdata_parse(r->address_record, rdata, rdlen) != 0) {
128 + avahi_server_set_errno(r->server, AVAHI_ERR_INVALID_PACKET);
129 + finish(r, AVAHI_RESOLVER_FAILURE);
131 + changed = 1;
132 + if (r->protocol == AVAHI_PROTO_UNSPEC)
133 + r->protocol = AVAHI_PROTO_INET;
135 + break;
137 + case kDNSServiceType_A6:
138 + if (!r->address_record) {
139 + if (!(r->address_record = avahi_record_new_full(r->host, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_AAAA, ttl))) {
140 + avahi_server_set_errno(r->server, AVAHI_ERR_NO_MEMORY);
141 + finish(r, AVAHI_RESOLVER_FAILURE);
142 + return;
144 + if (avahi_rdata_parse(r->address_record, rdata, rdlen) != 0) {
145 + avahi_server_set_errno(r->server, AVAHI_ERR_INVALID_PACKET);
146 + finish(r, AVAHI_RESOLVER_FAILURE);
148 + changed = 1;
149 + if (r->protocol == AVAHI_PROTO_UNSPEC)
150 + r->protocol = AVAHI_PROTO_INET6;
152 + break;
153 + default:
154 + abort();
158 + if (changed &&
159 + (r->txt_record || (r->user_flags & AVAHI_LOOKUP_NO_TXT)) &&
160 + r->address_record || (r->user_flags & AVAHI_LOOKUP_NO_ADDRESS)) {
161 + finish(r, AVAHI_RESOLVER_FOUND);
165 +static void resolve_socket_event(AvahiWatch *w, int fd, AvahiWatchEvent events, void *userdata) {
166 + AvahiSServiceResolver *r = userdata;
167 + DNSServiceErrorType ret;
168 + DNSServiceRef client;
170 + assert(w);
171 + assert(fd >= 0);
172 + assert(events & AVAHI_WATCH_IN);
174 + if (fd == DNSServiceRefSockFD(r->client))
175 + client = r->client;
176 + else if (fd == DNSServiceRefSockFD(r->client_a))
177 + client = r->client_a;
178 + else if (fd == DNSServiceRefSockFD(r->client_a6))
179 + client = r->client_a6;
180 + else
181 + assert (0);
183 + ret = DNSServiceProcessResult(client);
184 + if (ret != kDNSServiceErr_NoError) {
185 + if (client == r->client) {
186 + if (r->watch) {
187 + r->server->poll_api->watch_free(r->watch);
188 + r->watch = NULL;
190 + DNSServiceRefDeallocate(r->client);
191 + r->client = NULL;
192 + } else if (client == r->client_a) {
193 + if (r->watch_a) {
194 + r->server->poll_api->watch_free(r->watch_a);
195 + r->watch_a = NULL;
197 + DNSServiceRefDeallocate(r->client_a);
198 + r->client_a = NULL;
199 + } else if (client == r->client_a6) {
200 + if (r->watch_a6) {
201 + r->server->poll_api->watch_free(r->watch_a6);
202 + r->watch_a6 = NULL;
204 + DNSServiceRefDeallocate(r->client_a6);
205 + r->client_a6 = NULL;
207 + avahi_server_set_errno(r->server, AVAHI_ERR_DISCONNECTED);
208 + finish(r, AVAHI_RESOLVER_FAILURE);
212 +static void resolve_reply(DNSServiceRef client, const DNSServiceFlags flags, uint32_t ifIndex, DNSServiceErrorType errorCode,
213 + const char *fullname, const char *host, uint16_t opaqueport, uint16_t txtlen, const char* txtrecord, void *context) {
214 + AvahiSServiceResolver *r = context;
215 + AvahiServer *s = r->server;
216 + DNSServiceErrorType ret;
217 + DNSServiceRef new_client;
219 + if (r->interface > 0 && ifIndex != r->interface)
220 + return;
221 + if (r->interface <= 0)
222 + r->interface = ifIndex;
224 + if (host) {
225 + if (!(r->host = avahi_strdup(host))) {
226 + avahi_server_set_errno(r->server, AVAHI_ERR_NO_MEMORY);
227 + finish(r, AVAHI_RESOLVER_FAILURE);
230 + if (!(r->user_flags & AVAHI_LOOKUP_NO_ADDRESS)) {
231 + if (!r->txt_record) {
232 + if (!(r->txt_record = avahi_record_new_full(r->host, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_TXT, AVAHI_DEFAULT_TTL))) {
233 + avahi_server_set_errno(r->server, AVAHI_ERR_NO_MEMORY);
234 + finish(r, AVAHI_RESOLVER_FAILURE);
235 + return;
238 + if (avahi_rdata_parse(r->txt_record, txtrecord, txtlen) != 0) {
239 + avahi_server_set_errno(r->server, AVAHI_ERR_INVALID_PACKET);
240 + finish(r, AVAHI_RESOLVER_FAILURE);
243 + r->port = ntohs(opaqueport);
244 + if (!(r->user_flags & AVAHI_LOOKUP_NO_ADDRESS)) {
245 + if (r->address_protocol == AVAHI_PROTO_INET || r->address_protocol == AVAHI_PROTO_UNSPEC) {
246 + if (r->client_a) {
247 + if (r->watch_a) {
248 + r->server->poll_api->watch_free(r->watch_a);
249 + r->watch_a = NULL;
251 + DNSServiceRefDeallocate(r->client_a);
252 + r->client_a = NULL;
254 + ret = DNSServiceQueryRecord(&r->client_a, 0, ifIndex, host, kDNSServiceType_A, kDNSServiceClass_IN, query_record, r);
255 + if (ret != kDNSServiceErr_NoError || !r->client_a) {
256 + finish(r, AVAHI_RESOLVER_FAILURE);
257 + return;
259 + r->watch_a = s->poll_api->watch_new(s->poll_api, DNSServiceRefSockFD(r->client_a), AVAHI_WATCH_IN, resolve_socket_event, r);
262 + if (r->address_protocol == AVAHI_PROTO_INET6 || r->address_protocol == AVAHI_PROTO_UNSPEC) {
263 + if (r->client_a6) {
264 + if (r->watch_a6) {
265 + r->server->poll_api->watch_free(r->watch_a6);
266 + r->watch_a6 = NULL;
268 + DNSServiceRefDeallocate(r->client_a6);
269 + r->client_a6 = NULL;
271 + ret = DNSServiceQueryRecord(&r->client_a6, 0, ifIndex, host, kDNSServiceType_A6, kDNSServiceClass_IN, query_record, r);
272 + if (ret != kDNSServiceErr_NoError || !r->client_a6) {
273 + finish(r, AVAHI_RESOLVER_FAILURE);
274 + return;
276 + r->watch_a6 = s->poll_api->watch_new(s->poll_api, DNSServiceRefSockFD(r->client_a6), AVAHI_WATCH_IN, resolve_socket_event, r);
278 + } else {
279 + finish(r, AVAHI_RESOLVER_FOUND);
283 +static void resolve_error_callback(AvahiTimeEvent *e, void *userdata) {
284 + AvahiSServiceResolver *r = userdata;
286 + if (r->defer_time_event) {
287 + avahi_time_event_free(r->defer_time_event);
288 + r->defer_time_event = NULL;
290 + avahi_server_set_errno(r->server, AVAHI_ERR_FAILURE);
291 + finish(r, AVAHI_RESOLVER_FAILURE);
294 +static void avahi_resolve_service_start(AvahiServer *s, AvahiSServiceResolver *r) {
295 + DNSServiceErrorType ret;
297 + ret = DNSServiceResolve(&r->client,
298 + 0,
299 + r->interface == AVAHI_IF_UNSPEC ?
300 + kDNSServiceInterfaceIndexAny :
301 + r->interface,
302 + r->service_name,
303 + r->service_type,
304 + r->domain_name,
305 + resolve_reply,
306 + r);
307 + if (ret != kDNSServiceErr_NoError || !r->client) {
308 + r->defer_time_event = avahi_time_event_new(r->server->time_event_queue, NULL, resolve_error_callback, r);
309 + } else {
310 + r->watch = s->poll_api->watch_new(s->poll_api, DNSServiceRefSockFD(r->client), AVAHI_WATCH_IN, resolve_socket_event, r);
313 +#else
315 static void finish(AvahiSServiceResolver *r, AvahiResolverEvent event) {
316 AvahiLookupResultFlags flags;
318 @@ -140,6 +438,7 @@
322 +#endif
324 static void time_event_callback(AvahiTimeEvent *e, void *userdata) {
325 AvahiSServiceResolver *r = userdata;
326 @@ -163,6 +462,7 @@
327 r->time_event = avahi_time_event_new(r->server->time_event_queue, &tv, time_event_callback, r);
330 +#ifndef HAVE_BONJOUR
331 static void record_browser_callback(
332 AvahiSRecordBrowser*rr,
333 AvahiIfIndex interface,
334 @@ -374,6 +674,7 @@
335 break;
338 +#endif
340 AvahiSServiceResolver *avahi_s_service_resolver_new(
341 AvahiServer *server,
342 @@ -433,6 +734,17 @@
343 r->time_event = NULL;
344 AVAHI_LLIST_PREPEND(AvahiSServiceResolver, resolver, server->service_resolvers, r);
346 +#ifdef HAVE_BONJOUR
347 + r->defer_time_event = NULL;
348 + r->host = NULL;
349 + r->watch = NULL;
350 + r->watch_a = NULL;
351 + r->watch_a6 = NULL;
352 + r->client = NULL;
353 + r->client_a = NULL;
354 + r->client_a6 = NULL;
355 + avahi_resolve_service_start(server, r);
356 +#else
357 k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_SRV);
358 r->record_browser_srv = avahi_s_record_browser_new(server, interface, protocol, k, flags & ~(AVAHI_LOOKUP_NO_TXT|AVAHI_LOOKUP_NO_ADDRESS), record_browser_callback, r);
359 avahi_key_unref(k);
360 @@ -452,6 +764,7 @@
361 return NULL;
364 +#endif
366 start_timeout(r);
368 @@ -482,6 +795,29 @@
369 if (r->address_record)
370 avahi_record_unref(r->address_record);
372 +#ifdef HAVE_BONJOUR
373 + if (r->defer_time_event) {
374 + avahi_time_event_free(r->defer_time_event);
375 + r->defer_time_event = NULL;
378 + if (r->host)
379 + avahi_free(r->host);
381 + if (r->watch)
382 + r->server->poll_api->watch_free(r->watch);
383 + if (r->watch_a)
384 + r->server->poll_api->watch_free(r->watch_a);
385 + if (r->watch_a6)
386 + r->server->poll_api->watch_free(r->watch_a6);
388 + if (r->client)
389 + DNSServiceRefDeallocate (r->client);
390 + if (r->client_a)
391 + DNSServiceRefDeallocate (r->client_a);
392 + if (r->client_a6)
393 + DNSServiceRefDeallocate (r->client_a6);
394 +#endif
395 avahi_free(r->service_name);
396 avahi_free(r->service_type);
397 avahi_free(r->domain_name);