Mercurial > pidgin
comparison libpurple/protocols/bonjour/mdns_win32.c @ 21979:26648115261c
Improve error handling, particularly the debug output. I was hoping that this would provide some debug output that could be used to figure out how to detect and disconnect when the mdnsResponder crashes, but that doesn't appear to be the case.
author | Daniel Atallah <daniel.atallah@gmail.com> |
---|---|
date | Fri, 04 Jan 2008 01:09:13 +0000 |
parents | 41959f031322 |
children | 71d18f5adbba |
comparison
equal
deleted
inserted
replaced
21978:4795260eb0bd | 21979:26648115261c |
---|---|
121 uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, | 121 uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, |
122 uint16_t rrtype, uint16_t rrclass, uint16_t rdlen, const void *rdata, | 122 uint16_t rrtype, uint16_t rrclass, uint16_t rdlen, const void *rdata, |
123 uint32_t ttl, void *context) | 123 uint32_t ttl, void *context) |
124 { | 124 { |
125 | 125 |
126 if (kDNSServiceErr_NoError != errorCode) { | 126 if (errorCode != kDNSServiceErr_NoError) { |
127 purple_debug_error("bonjour", "record query - callback error.\n"); | 127 purple_debug_error("bonjour", "record query - callback error.\n"); |
128 /* TODO: Probably should remove the buddy when this happens */ | 128 /* TODO: Probably should remove the buddy when this happens */ |
129 } else if (flags & kDNSServiceFlagsAdd) { | 129 } else if (flags & kDNSServiceFlagsAdd) { |
130 if (rrtype == kDNSServiceType_TXT) { | 130 if (rrtype == kDNSServiceType_TXT) { |
131 /* New Buddy */ | 131 /* New Buddy */ |
166 if (!hosts || !hosts->data) { | 166 if (!hosts || !hosts->data) { |
167 purple_debug_error("bonjour", "host resolution - callback error.\n"); | 167 purple_debug_error("bonjour", "host resolution - callback error.\n"); |
168 delete_buddy = TRUE; | 168 delete_buddy = TRUE; |
169 } else { | 169 } else { |
170 struct sockaddr_in *addr = g_slist_nth_data(hosts, 1); | 170 struct sockaddr_in *addr = g_slist_nth_data(hosts, 1); |
171 DNSServiceErrorType errorCode; | |
171 | 172 |
172 /* finally, set up the continuous txt record watcher, and add the buddy to purple */ | 173 /* finally, set up the continuous txt record watcher, and add the buddy to purple */ |
173 | 174 |
174 if (kDNSServiceErr_NoError == DNSServiceQueryRecord(&args->res_data->txt_query, kDNSServiceFlagsLongLivedQuery, | 175 errorCode = DNSServiceQueryRecord(&args->res_data->txt_query, kDNSServiceFlagsLongLivedQuery, |
175 kDNSServiceInterfaceIndexAny, args->full_service_name, kDNSServiceType_TXT, | 176 kDNSServiceInterfaceIndexAny, args->full_service_name, kDNSServiceType_TXT, |
176 kDNSServiceClass_IN, _mdns_record_query_callback, args->bb)) { | 177 kDNSServiceClass_IN, _mdns_record_query_callback, args->bb); |
177 | 178 if (errorCode == kDNSServiceErr_NoError) { |
178 const char *ip = inet_ntoa(addr->sin_addr); | 179 const char *ip = inet_ntoa(addr->sin_addr); |
179 | 180 |
180 purple_debug_info("bonjour", "Found buddy %s at %s:%d\n", args->bb->name, ip, args->bb->port_p2pj); | 181 purple_debug_info("bonjour", "Found buddy %s at %s:%d\n", args->bb->name, ip, args->bb->port_p2pj); |
181 | 182 |
182 | 183 |
186 args->res_data->txt_query_handler = purple_input_add(DNSServiceRefSockFD(args->res_data->txt_query), | 187 args->res_data->txt_query_handler = purple_input_add(DNSServiceRefSockFD(args->res_data->txt_query), |
187 PURPLE_INPUT_READ, _mdns_handle_event, args->res_data->txt_query); | 188 PURPLE_INPUT_READ, _mdns_handle_event, args->res_data->txt_query); |
188 | 189 |
189 bonjour_buddy_add_to_purple(args->bb, NULL); | 190 bonjour_buddy_add_to_purple(args->bb, NULL); |
190 } else { | 191 } else { |
191 purple_debug_error("bonjour", "Unable to set up record watcher for buddy %s\n", args->bb->name); | 192 purple_debug_error("bonjour", "Unable to set up record watcher for buddy %s (%d)\n", args->bb->name, errorCode); |
192 delete_buddy = TRUE; | 193 delete_buddy = TRUE; |
193 } | 194 } |
194 | 195 |
195 } | 196 } |
196 | 197 |
237 purple_input_remove(args->resolver_handler); | 238 purple_input_remove(args->resolver_handler); |
238 args->resolver_handler = 0; | 239 args->resolver_handler = 0; |
239 DNSServiceRefDeallocate(args->resolver); | 240 DNSServiceRefDeallocate(args->resolver); |
240 args->resolver = NULL; | 241 args->resolver = NULL; |
241 | 242 |
242 if (kDNSServiceErr_NoError != errorCode) | 243 if (errorCode != kDNSServiceErr_NoError) |
243 purple_debug_error("bonjour", "service resolver - callback error.\n"); | 244 purple_debug_error("bonjour", "service resolver - callback error.\n"); |
244 else { | 245 else { |
245 /* set more arguments, and start the host resolver */ | 246 /* set more arguments, and start the host resolver */ |
246 | 247 |
247 if ((args->query = | 248 if ((args->query = |
284 static void DNSSD_API | 285 static void DNSSD_API |
285 _mdns_service_register_callback(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode, | 286 _mdns_service_register_callback(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode, |
286 const char *name, const char *regtype, const char *domain, void *context) { | 287 const char *name, const char *regtype, const char *domain, void *context) { |
287 | 288 |
288 /* TODO: deal with collision */ | 289 /* TODO: deal with collision */ |
289 if (kDNSServiceErr_NoError != errorCode) | 290 if (errorCode != kDNSServiceErr_NoError) |
290 purple_debug_error("bonjour", "service advertisement - callback error (%d).\n", errorCode); | 291 purple_debug_error("bonjour", "service advertisement - callback error (%d).\n", errorCode); |
291 else | 292 else |
292 purple_debug_info("bonjour", "service advertisement - callback.\n"); | 293 purple_debug_info("bonjour", "service advertisement - callback.\n"); |
293 } | 294 } |
294 | 295 |
296 _mdns_service_browse_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, | 297 _mdns_service_browse_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, |
297 DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context) | 298 DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context) |
298 { | 299 { |
299 PurpleAccount *account = (PurpleAccount*)context; | 300 PurpleAccount *account = (PurpleAccount*)context; |
300 | 301 |
301 if (kDNSServiceErr_NoError != errorCode) | 302 if (errorCode != kDNSServiceErr_NoError) |
302 purple_debug_error("bonjour", "service browser - callback error\n"); | 303 purple_debug_error("bonjour", "service browser - callback error (%d)\n", errorCode); |
303 else if (flags & kDNSServiceFlagsAdd) { | 304 else if (flags & kDNSServiceFlagsAdd) { |
304 /* A presence service instance has been discovered... check it isn't us! */ | 305 /* A presence service instance has been discovered... check it isn't us! */ |
305 if (purple_utf8_strcasecmp(serviceName, account->username) != 0) { | 306 if (purple_utf8_strcasecmp(serviceName, account->username) != 0) { |
307 DNSServiceErrorType resErrorCode; | |
306 /* OK, lets go ahead and resolve it to add to the buddy list */ | 308 /* OK, lets go ahead and resolve it to add to the buddy list */ |
307 ResolveCallbackArgs *args = g_new0(ResolveCallbackArgs, 1); | 309 ResolveCallbackArgs *args = g_new0(ResolveCallbackArgs, 1); |
308 | 310 |
309 purple_debug_info("bonjour", "Received new record for '%s' on iface %u (%s, %s)\n", | 311 purple_debug_info("bonjour", "Received new record for '%s' on iface %u (%s, %s)\n", |
310 serviceName, interfaceIndex, regtype ? regtype : "", | 312 serviceName, interfaceIndex, regtype ? regtype : "", |
311 replyDomain ? replyDomain : ""); | 313 replyDomain ? replyDomain : ""); |
312 | 314 |
313 if (kDNSServiceErr_NoError == DNSServiceResolve(&args->resolver, 0, 0, serviceName, regtype, | 315 resErrorCode = DNSServiceResolve(&args->resolver, 0, 0, serviceName, regtype, |
314 replyDomain, _mdns_service_resolve_callback, args)) { | 316 replyDomain, _mdns_service_resolve_callback, args); |
317 if (resErrorCode == kDNSServiceErr_NoError) { | |
315 GSList *tmp = pending_buddies; | 318 GSList *tmp = pending_buddies; |
316 PurpleBuddy *pb; | 319 PurpleBuddy *pb; |
317 BonjourBuddy* bb = NULL; | 320 BonjourBuddy* bb = NULL; |
318 Win32SvcResolverData *rd; | 321 Win32SvcResolverData *rd; |
319 Win32BuddyImplData *idata; | 322 Win32BuddyImplData *idata; |
360 | 363 |
361 /* get a file descriptor for this service ref, and add it to the input list */ | 364 /* get a file descriptor for this service ref, and add it to the input list */ |
362 fd = DNSServiceRefSockFD(args->resolver); | 365 fd = DNSServiceRefSockFD(args->resolver); |
363 args->resolver_handler = purple_input_add(fd, PURPLE_INPUT_READ, _mdns_handle_event, args->resolver); | 366 args->resolver_handler = purple_input_add(fd, PURPLE_INPUT_READ, _mdns_handle_event, args->resolver); |
364 } else { | 367 } else { |
365 purple_debug_error("bonjour", "service browser - failed to resolve service.\n"); | 368 purple_debug_error("bonjour", "service browser - failed to resolve service. (%d)\n", resErrorCode); |
366 g_free(args); | 369 g_free(args); |
367 } | 370 } |
368 } | 371 } |
369 } else { | 372 } else { |
370 PurpleBuddy *pb = NULL; | 373 PurpleBuddy *pb = NULL; |
430 } | 433 } |
431 | 434 |
432 gboolean _mdns_publish(BonjourDnsSd *data, PublishType type, GSList *records) { | 435 gboolean _mdns_publish(BonjourDnsSd *data, PublishType type, GSList *records) { |
433 TXTRecordRef dns_data; | 436 TXTRecordRef dns_data; |
434 gboolean ret = TRUE; | 437 gboolean ret = TRUE; |
435 DNSServiceErrorType set_ret = kDNSServiceErr_NoError; | 438 DNSServiceErrorType errorCode = kDNSServiceErr_NoError; |
436 Win32SessionImplData *idata = data->mdns_impl_data; | 439 Win32SessionImplData *idata = data->mdns_impl_data; |
437 | 440 |
438 g_return_val_if_fail(idata != NULL, FALSE); | 441 g_return_val_if_fail(idata != NULL, FALSE); |
439 | 442 |
440 TXTRecordCreate(&dns_data, 256, NULL); | 443 TXTRecordCreate(&dns_data, 256, NULL); |
441 | 444 |
442 while (records) { | 445 while (records) { |
443 PurpleKeyValuePair *kvp = records->data; | 446 PurpleKeyValuePair *kvp = records->data; |
444 set_ret = TXTRecordSetValue(&dns_data, kvp->key, strlen(kvp->value), kvp->value); | 447 errorCode = TXTRecordSetValue(&dns_data, kvp->key, strlen(kvp->value), kvp->value); |
445 if (set_ret != kDNSServiceErr_NoError) | 448 if (errorCode != kDNSServiceErr_NoError) |
446 break; | 449 break; |
447 records = records->next; | 450 records = records->next; |
448 } | 451 } |
449 | 452 |
450 if (set_ret != kDNSServiceErr_NoError) { | 453 if (errorCode != kDNSServiceErr_NoError) { |
451 purple_debug_error("bonjour", "Unable to allocate memory for text record.\n"); | 454 purple_debug_error("bonjour", "Unable to allocate memory for text record.(%d)\n", errorCode); |
452 ret = FALSE; | 455 ret = FALSE; |
453 } else { | 456 } else { |
454 DNSServiceErrorType err = kDNSServiceErr_NoError; | |
455 | |
456 /* OK, we're done constructing the text record, (re)publish the service */ | 457 /* OK, we're done constructing the text record, (re)publish the service */ |
457 | 458 |
458 switch (type) { | 459 switch (type) { |
459 case PUBLISH_START: | 460 case PUBLISH_START: |
460 purple_debug_info("bonjour", "Registering presence on port %d\n", data->port_p2pj); | 461 purple_debug_info("bonjour", "Registering presence on port %d\n", data->port_p2pj); |
461 err = DNSServiceRegister(&idata->presence_svc, 0, 0, purple_account_get_username(data->account), ICHAT_SERVICE, | 462 errorCode = DNSServiceRegister(&idata->presence_svc, 0, 0, purple_account_get_username(data->account), ICHAT_SERVICE, |
462 NULL, NULL, htons(data->port_p2pj), TXTRecordGetLength(&dns_data), TXTRecordGetBytesPtr(&dns_data), | 463 NULL, NULL, htons(data->port_p2pj), TXTRecordGetLength(&dns_data), TXTRecordGetBytesPtr(&dns_data), |
463 _mdns_service_register_callback, NULL); | 464 _mdns_service_register_callback, NULL); |
464 break; | 465 break; |
465 | 466 |
466 case PUBLISH_UPDATE: | 467 case PUBLISH_UPDATE: |
467 purple_debug_info("bonjour", "Updating presence.\n"); | 468 purple_debug_info("bonjour", "Updating presence.\n"); |
468 err = DNSServiceUpdateRecord(idata->presence_svc, NULL, 0, TXTRecordGetLength(&dns_data), TXTRecordGetBytesPtr(&dns_data), 0); | 469 errorCode = DNSServiceUpdateRecord(idata->presence_svc, NULL, 0, TXTRecordGetLength(&dns_data), TXTRecordGetBytesPtr(&dns_data), 0); |
469 break; | 470 break; |
470 } | 471 } |
471 | 472 |
472 if (err != kDNSServiceErr_NoError) { | 473 if (errorCode != kDNSServiceErr_NoError) { |
473 purple_debug_error("bonjour", "Failed to publish presence service.\n"); | 474 purple_debug_error("bonjour", "Failed to publish presence service.(%d)\n", errorCode); |
474 ret = FALSE; | 475 ret = FALSE; |
475 } else if (type == PUBLISH_START) { | 476 } else if (type == PUBLISH_START) { |
476 /* We need to do this because according to the Apple docs: | 477 /* We need to do this because according to the Apple docs: |
477 * "the client is responsible for ensuring that DNSServiceProcessResult() is called | 478 * "the client is responsible for ensuring that DNSServiceProcessResult() is called |
478 * whenever there is a reply from the daemon - the daemon may terminate its connection | 479 * whenever there is a reply from the daemon - the daemon may terminate its connection |
486 TXTRecordDeallocate(&dns_data); | 487 TXTRecordDeallocate(&dns_data); |
487 return ret; | 488 return ret; |
488 } | 489 } |
489 | 490 |
490 gboolean _mdns_browse(BonjourDnsSd *data) { | 491 gboolean _mdns_browse(BonjourDnsSd *data) { |
492 DNSServiceErrorType errorCode; | |
491 Win32SessionImplData *idata = data->mdns_impl_data; | 493 Win32SessionImplData *idata = data->mdns_impl_data; |
492 | 494 |
493 g_return_val_if_fail(idata != NULL, FALSE); | 495 g_return_val_if_fail(idata != NULL, FALSE); |
494 | 496 |
495 if (DNSServiceBrowse(&idata->browser_svc, 0, 0, ICHAT_SERVICE, NULL, | 497 errorCode = DNSServiceBrowse(&idata->browser_svc, 0, 0, ICHAT_SERVICE, NULL, |
496 _mdns_service_browse_callback, data->account) | 498 _mdns_service_browse_callback, data->account); |
497 == kDNSServiceErr_NoError) { | 499 if (errorCode == kDNSServiceErr_NoError) { |
498 idata->browser_handler = purple_input_add(DNSServiceRefSockFD(idata->browser_svc), | 500 idata->browser_handler = purple_input_add(DNSServiceRefSockFD(idata->browser_svc), |
499 PURPLE_INPUT_READ, _mdns_handle_event, idata->browser_svc); | 501 PURPLE_INPUT_READ, _mdns_handle_event, idata->browser_svc); |
500 return TRUE; | 502 return TRUE; |
501 } | 503 } else |
504 purple_debug_error("bonjour", "Error registering Local Link presence browser. (%d)\n", errorCode); | |
505 | |
502 | 506 |
503 return FALSE; | 507 return FALSE; |
504 } | 508 } |
505 | 509 |
506 void _mdns_stop(BonjourDnsSd *data) { | 510 void _mdns_stop(BonjourDnsSd *data) { |
524 data->mdns_impl_data = NULL; | 528 data->mdns_impl_data = NULL; |
525 } | 529 } |
526 | 530 |
527 gboolean _mdns_set_buddy_icon_data(BonjourDnsSd *data, gconstpointer avatar_data, gsize avatar_len) { | 531 gboolean _mdns_set_buddy_icon_data(BonjourDnsSd *data, gconstpointer avatar_data, gsize avatar_len) { |
528 Win32SessionImplData *idata = data->mdns_impl_data; | 532 Win32SessionImplData *idata = data->mdns_impl_data; |
529 DNSServiceErrorType err = kDNSServiceErr_NoError; | 533 DNSServiceErrorType errorCode = kDNSServiceErr_NoError; |
530 | 534 |
531 g_return_val_if_fail(idata != NULL, FALSE); | 535 g_return_val_if_fail(idata != NULL, FALSE); |
532 | 536 |
533 if (avatar_data != NULL && idata->buddy_icon_rec == NULL) { | 537 if (avatar_data != NULL && idata->buddy_icon_rec == NULL) { |
534 purple_debug_info("bonjour", "Setting new buddy icon.\n"); | 538 purple_debug_info("bonjour", "Setting new buddy icon.\n"); |
535 err = DNSServiceAddRecord(idata->presence_svc, &idata->buddy_icon_rec, | 539 errorCode = DNSServiceAddRecord(idata->presence_svc, &idata->buddy_icon_rec, |
536 0, kDNSServiceType_NULL, avatar_len, avatar_data, 0); | 540 0, kDNSServiceType_NULL, avatar_len, avatar_data, 0); |
537 } else if (avatar_data != NULL) { | 541 } else if (avatar_data != NULL) { |
538 purple_debug_info("bonjour", "Updating existing buddy icon.\n"); | 542 purple_debug_info("bonjour", "Updating existing buddy icon.\n"); |
539 err = DNSServiceUpdateRecord(idata->presence_svc, idata->buddy_icon_rec, | 543 errorCode = DNSServiceUpdateRecord(idata->presence_svc, idata->buddy_icon_rec, |
540 0, avatar_len, avatar_data, 0); | 544 0, avatar_len, avatar_data, 0); |
541 } else if (idata->buddy_icon_rec != NULL) { | 545 } else if (idata->buddy_icon_rec != NULL) { |
542 purple_debug_info("bonjour", "Removing existing buddy icon.\n"); | 546 purple_debug_info("bonjour", "Removing existing buddy icon.\n"); |
543 DNSServiceRemoveRecord(idata->presence_svc, idata->buddy_icon_rec, 0); | 547 errorCode = DNSServiceRemoveRecord(idata->presence_svc, idata->buddy_icon_rec, 0); |
544 idata->buddy_icon_rec = NULL; | 548 idata->buddy_icon_rec = NULL; |
545 } | 549 } |
546 | 550 |
547 if (err != kDNSServiceErr_NoError) | 551 if (errorCode != kDNSServiceErr_NoError) { |
548 purple_debug_error("bonjour", "Error (%d) setting buddy icon record.\n", err); | 552 purple_debug_error("bonjour", "Error (%d) setting buddy icon record.\n", errorCode); |
549 | 553 return FALSE; |
550 return (err == kDNSServiceErr_NoError); | 554 } |
555 | |
556 return TRUE; | |
551 } | 557 } |
552 | 558 |
553 void _mdns_init_buddy(BonjourBuddy *buddy) { | 559 void _mdns_init_buddy(BonjourBuddy *buddy) { |
554 buddy->mdns_impl_data = g_new0(Win32BuddyImplData, 1); | 560 buddy->mdns_impl_data = g_new0(Win32BuddyImplData, 1); |
555 } | 561 } |
587 idata->null_query_handler = 0; | 593 idata->null_query_handler = 0; |
588 DNSServiceRefDeallocate(idata->null_query); | 594 DNSServiceRefDeallocate(idata->null_query); |
589 idata->null_query = NULL; | 595 idata->null_query = NULL; |
590 } | 596 } |
591 | 597 |
592 DNSServiceConstructFullName(svc_name, buddy->name, ICHAT_SERVICE, "local"); | 598 if (DNSServiceConstructFullName(svc_name, buddy->name, ICHAT_SERVICE, "local") != 0) |
593 if (kDNSServiceErr_NoError == DNSServiceQueryRecord(&idata->null_query, 0, kDNSServiceInterfaceIndexAny, svc_name, | 599 purple_debug_error("bonjour", "Unable to construct full name to retrieve buddy icon for %s.\n", buddy->name); |
594 kDNSServiceType_NULL, kDNSServiceClass_IN, _mdns_record_query_callback, buddy)) { | 600 else { |
595 idata->null_query_handler = purple_input_add(DNSServiceRefSockFD(idata->null_query), | 601 DNSServiceErrorType errorCode = DNSServiceQueryRecord(&idata->null_query, 0, kDNSServiceInterfaceIndexAny, |
596 PURPLE_INPUT_READ, _mdns_handle_event, idata->null_query); | 602 svc_name, kDNSServiceType_NULL, kDNSServiceClass_IN, _mdns_record_query_callback, buddy); |
597 } | 603 if (errorCode == kDNSServiceErr_NoError) |
598 | 604 idata->null_query_handler = purple_input_add(DNSServiceRefSockFD(idata->null_query), |
599 } | 605 PURPLE_INPUT_READ, _mdns_handle_event, idata->null_query); |
600 | 606 else |
607 purple_debug_error("bonjour", "Unable to query buddy icon record for %s. (%d)\n", buddy->name, errorCode); | |
608 } | |
609 | |
610 } | |
611 |