Mercurial > pidgin.yaz
diff libpurple/protocols/bonjour/mdns_win32.c @ 31017:014a58e994da
Use DNSServiceGetAddrInfo() from dns_sd.h to resolve the IP for remote bonjour
users on Win32 instead of the libpurple resolving API. This way, we make sure
we're using the same interface as we received the presence notification on.
There is also some debug message improvement and using constants instead of
magic numbers in this commit.
author | Daniel Atallah <daniel.atallah@gmail.com> |
---|---|
date | Mon, 04 Oct 2010 00:35:26 +0000 |
parents | 927e01ad06ae |
children | 9c8b28dc6656 |
line wrap: on
line diff
--- a/libpurple/protocols/bonjour/mdns_win32.c Sat Oct 02 23:04:49 2010 +0000 +++ b/libpurple/protocols/bonjour/mdns_win32.c Mon Oct 04 00:35:26 2010 +0000 @@ -25,7 +25,6 @@ #include "buddy.h" #include "mdns_interface.h" #include "dns_sd_proxy.h" -#include "dnsquery.h" #include "mdns_common.h" static GSList *pending_buddies = NULL; @@ -65,7 +64,6 @@ BonjourBuddy *bb; Win32SvcResolverData *res_data; gchar *full_service_name; - PurpleDnsQueryData *dns_query; } ResolveCallbackArgs; @@ -135,7 +133,7 @@ { if (errorCode != kDNSServiceErr_NoError) { - purple_debug_error("bonjour", "record query - callback error.\n"); + purple_debug_error("bonjour", "record query - callback error (%d).\n", errorCode); /* TODO: Probably should remove the buddy when this happens */ } else if (flags & kDNSServiceFlagsAdd) { if (rrtype == kDNSServiceType_TXT) { @@ -161,14 +159,22 @@ } } -static void -_mdns_resolve_host_callback(GSList *hosts, gpointer data, const char *error_message) +static void DNSSD_API +_mdns_resolve_host_callback(DNSServiceRef sdRef, DNSServiceFlags flags, + uint32_t interfaceIndex, DNSServiceErrorType errorCode, + const char *hostname, const struct sockaddr *address, + uint32_t ttl, void *context) { - ResolveCallbackArgs *args = (ResolveCallbackArgs*) data; + ResolveCallbackArgs *args = (ResolveCallbackArgs*) context; Win32BuddyImplData *idata = args->bb->mdns_impl_data; gboolean delete_buddy = FALSE; PurpleBuddy *pb = NULL; + purple_input_remove(args->resolver_query->input_handler); + DNSServiceRefDeallocate(args->resolver_query->sdRef); + g_free(args->resolver_query); + args->resolver_query = NULL; + if ((pb = purple_find_buddy(args->account, args->res_data->name))) { if (pb->proto_data != args->bb) { purple_debug_error("bonjour", "Found purple buddy for %s not matching bonjour buddy record.", @@ -181,12 +187,10 @@ goto cleanup; } - if (!hosts || !hosts->data) { - purple_debug_error("bonjour", "host resolution - callback error.\n"); + if (errorCode != kDNSServiceErr_NoError) { + purple_debug_error("bonjour", "host resolution - callback error (%d).\n", errorCode); delete_buddy = TRUE; } else { - struct sockaddr_in *addr = g_slist_nth_data(hosts, 1); - DNSServiceErrorType errorCode; DNSServiceRef txt_query_sr; /* finally, set up the continuous txt record watcher, and add the buddy to purple */ @@ -194,7 +198,7 @@ kDNSServiceInterfaceIndexAny, args->full_service_name, kDNSServiceType_TXT, kDNSServiceClass_IN, _mdns_record_query_callback, args->bb); if (errorCode == kDNSServiceErr_NoError) { - const char *ip = inet_ntoa(addr->sin_addr); + const char *ip = inet_ntoa(((struct sockaddr_in *) address)->sin_addr); purple_debug_info("bonjour", "Found buddy %s at %s:%d\n", args->bb->name, ip, args->bb->port_p2pj); @@ -218,13 +222,6 @@ cleanup: - /* free the hosts list*/ - while (hosts != NULL) { - hosts = g_slist_remove(hosts, hosts->data); - g_free(hosts->data); - hosts = g_slist_remove(hosts, hosts->data); - } - if (delete_buddy) { idata->resolvers = g_slist_remove(idata->resolvers, args->res_data); _cleanup_resolver_data(args->res_data); @@ -259,17 +256,20 @@ /* remove the input fd and destroy the service ref */ purple_input_remove(args->resolver_query->input_handler); DNSServiceRefDeallocate(args->resolver_query->sdRef); - g_free(args->resolver_query); - args->resolver_query = NULL; if (errorCode != kDNSServiceErr_NoError) - purple_debug_error("bonjour", "service resolver - callback error.\n"); + purple_debug_error("bonjour", "service resolver - callback error. (%d)\n", errorCode); else { + DNSServiceRef getaddrinfo_sr; /* set more arguments, and start the host resolver */ - - if ((args->dns_query = - purple_dnsquery_a(hosttarget, port, _mdns_resolve_host_callback, args)) != NULL) { - + errorCode = DNSServiceGetAddrInfo(&getaddrinfo_sr, 0, interfaceIndex, + kDNSServiceProtocol_IPv4, hosttarget, _mdns_resolve_host_callback, args); + if (errorCode != kDNSServiceErr_NoError) + purple_debug_error("bonjour", "service resolver - host resolution failed.\n"); + else { + args->resolver_query->sdRef = getaddrinfo_sr; + args->resolver_query->input_handler = purple_input_add(DNSServiceRefSockFD(getaddrinfo_sr), + PURPLE_INPUT_READ, _mdns_handle_event, args->resolver_query); args->full_service_name = g_strdup(fullname); /* TODO: Should this be per resolver? */ @@ -277,12 +277,14 @@ /* We don't want to hit the cleanup code */ return; - } else - purple_debug_error("bonjour", "service resolver - host resolution failed.\n"); + } } /* If we get this far, clean up */ + g_free(args->resolver_query); + args->resolver_query = NULL; + idata->resolvers = g_slist_remove(idata->resolvers, args->res_data); _cleanup_resolver_data(args->res_data); @@ -334,7 +336,7 @@ serviceName, interfaceIndex, regtype ? regtype : "", replyDomain ? replyDomain : ""); - resErrorCode = DNSServiceResolve(&resolver_sr, 0, 0, serviceName, regtype, + resErrorCode = DNSServiceResolve(&resolver_sr, 0, interfaceIndex, serviceName, regtype, replyDomain, _mdns_service_resolve_callback, args); if (resErrorCode == kDNSServiceErr_NoError) { GSList *tmp = pending_buddies; @@ -483,7 +485,8 @@ switch (type) { case PUBLISH_START: purple_debug_info("bonjour", "Registering presence on port %d\n", data->port_p2pj); - errorCode = DNSServiceRegister(&presence_sr, 0, 0, purple_account_get_username(data->account), LINK_LOCAL_RECORD_NAME, + errorCode = DNSServiceRegister(&presence_sr, kDNSServiceInterfaceIndexAny, + 0, purple_account_get_username(data->account), LINK_LOCAL_RECORD_NAME, NULL, NULL, htons(data->port_p2pj), TXTRecordGetLength(&dns_data), TXTRecordGetBytesPtr(&dns_data), _mdns_service_register_callback, NULL); break; @@ -522,8 +525,9 @@ g_return_val_if_fail(idata != NULL, FALSE); - errorCode = DNSServiceBrowse(&browser_sr, 0, 0, LINK_LOCAL_RECORD_NAME, NULL, - _mdns_service_browse_callback, data->account); + errorCode = DNSServiceBrowse(&browser_sr, 0, kDNSServiceInterfaceIndexAny, + LINK_LOCAL_RECORD_NAME, NULL,_mdns_service_browse_callback, + data->account); if (errorCode == kDNSServiceErr_NoError) { idata->browser_query = g_new(DnsSDServiceRefHandlerData, 1); idata->browser_query->sdRef = browser_sr;