libpurple/protocols/bonjour/mdns_win32.c

changeset 30824
5cdb0deaaa9b
parent 29796
919370cb1540
child 30825
87a79bbdc985
--- 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;

mercurial