comparison libpurple/protocols/bonjour/mdns_win32.c @ 19573:affacee881e8

Fix a couple potential leaks and prevent the avahi record resolver from being freed multiple times. Thanks to Lennart from the Avahi team for suggestions on how to improve the avahi implementation.
author Daniel Atallah <daniel.atallah@gmail.com>
date Sun, 02 Sep 2007 17:54:44 +0000
parents 649ac48fce1d
children 941965d6fd88
comparison
equal deleted inserted replaced
19572:cfc4e56a6a1e 19573:affacee881e8
77 uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, 77 uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname,
78 uint16_t rrtype, uint16_t rrclass, uint16_t rdlen, const void *rdata, 78 uint16_t rrtype, uint16_t rrclass, uint16_t rdlen, const void *rdata,
79 uint32_t ttl, void *context) 79 uint32_t ttl, void *context)
80 { 80 {
81 81
82 if (kDNSServiceErr_NoError != errorCode) 82 if (kDNSServiceErr_NoError != errorCode) {
83 purple_debug_error("bonjour", "record query - callback error.\n"); 83 purple_debug_error("bonjour", "record query - callback error.\n");
84 else if (flags & kDNSServiceFlagsAdd) 84 /* TODO: Probably should remove the buddy when this happens */
85 { 85 } else if (flags & kDNSServiceFlagsAdd) {
86 if (rrtype == kDNSServiceType_TXT) { 86 if (rrtype == kDNSServiceType_TXT) {
87 /* New Buddy */ 87 /* New Buddy */
88 BonjourBuddy *buddy = (BonjourBuddy*) context; 88 BonjourBuddy *bb = (BonjourBuddy*) context;
89 _mdns_parse_text_record(buddy, rdata, rdlen); 89 _mdns_parse_text_record(bb, rdata, rdlen);
90 bonjour_buddy_add_to_purple(buddy); 90 bonjour_buddy_add_to_purple(bb, NULL);
91 } else if (rrtype == kDNSServiceType_NULL) { 91 } else if (rrtype == kDNSServiceType_NULL) {
92 /* Buddy Icon response */ 92 /* Buddy Icon response */
93 BonjourBuddy *buddy = (BonjourBuddy*) context; 93 BonjourBuddy *bb = (BonjourBuddy*) context;
94 Win32BuddyImplData *idata = buddy->mdns_impl_data; 94 Win32BuddyImplData *idata = bb->mdns_impl_data;
95 95
96 g_return_if_fail(idata != NULL); 96 g_return_if_fail(idata != NULL);
97 97
98 bonjour_buddy_got_buddy_icon(buddy, rdata, rdlen); 98 bonjour_buddy_got_buddy_icon(bb, rdata, rdlen);
99 99
100 /* We've got what we need; stop listening */ 100 /* We've got what we need; stop listening */
101 purple_input_remove(idata->null_query_handler); 101 purple_input_remove(idata->null_query_handler);
102 idata->null_query_handler = 0; 102 idata->null_query_handler = 0;
103 DNSServiceRefDeallocate(idata->null_query); 103 DNSServiceRefDeallocate(idata->null_query);
108 108
109 static void 109 static void
110 _mdns_resolve_host_callback(GSList *hosts, gpointer data, const char *error_message) 110 _mdns_resolve_host_callback(GSList *hosts, gpointer data, const char *error_message)
111 { 111 {
112 ResolveCallbackArgs* args = (ResolveCallbackArgs*)data; 112 ResolveCallbackArgs* args = (ResolveCallbackArgs*)data;
113 113 BonjourBuddy* bb = args->buddy;
114 if (!hosts || !hosts->data) 114
115 if (!hosts || !hosts->data) {
115 purple_debug_error("bonjour", "host resolution - callback error.\n"); 116 purple_debug_error("bonjour", "host resolution - callback error.\n");
116 else { 117 bonjour_buddy_delete(bb);
118 } else {
117 struct sockaddr_in *addr = (struct sockaddr_in*)g_slist_nth_data(hosts, 1); 119 struct sockaddr_in *addr = (struct sockaddr_in*)g_slist_nth_data(hosts, 1);
118 BonjourBuddy* buddy = args->buddy; 120 Win32BuddyImplData *idata = bb->mdns_impl_data;
119 Win32BuddyImplData *idata = buddy->mdns_impl_data;
120 121
121 g_return_if_fail(idata != NULL); 122 g_return_if_fail(idata != NULL);
122 123
123 buddy->ip = g_strdup(inet_ntoa(addr->sin_addr)); 124 g_free(bb->ip);
125 bb->ip = g_strdup(inet_ntoa(addr->sin_addr));
124 126
125 /* finally, set up the continuous txt record watcher, and add the buddy to purple */ 127 /* finally, set up the continuous txt record watcher, and add the buddy to purple */
126 128
127 if (kDNSServiceErr_NoError == DNSServiceQueryRecord(&idata->txt_query, kDNSServiceFlagsLongLivedQuery, 129 if (kDNSServiceErr_NoError == DNSServiceQueryRecord(&idata->txt_query, kDNSServiceFlagsLongLivedQuery,
128 kDNSServiceInterfaceIndexAny, args->full_service_name, kDNSServiceType_TXT, 130 kDNSServiceInterfaceIndexAny, args->full_service_name, kDNSServiceType_TXT,
129 kDNSServiceClass_IN, _mdns_record_query_callback, buddy)) { 131 kDNSServiceClass_IN, _mdns_record_query_callback, bb)) {
130 132
131 purple_debug_info("bonjour", "Found buddy %s at %s:%d\n", buddy->name, buddy->ip, buddy->port_p2pj); 133 purple_debug_info("bonjour", "Found buddy %s at %s:%d\n", bb->name, bb->ip, bb->port_p2pj);
132 134
133 idata->txt_query_handler = purple_input_add(DNSServiceRefSockFD(idata->txt_query), 135 idata->txt_query_handler = purple_input_add(DNSServiceRefSockFD(idata->txt_query),
134 PURPLE_INPUT_READ, _mdns_handle_event, idata->txt_query); 136 PURPLE_INPUT_READ, _mdns_handle_event, idata->txt_query);
135 137
136 bonjour_buddy_add_to_purple(buddy); 138 bonjour_buddy_add_to_purple(bb, NULL);
137 } else 139 } else
138 bonjour_buddy_delete(buddy); 140 bonjour_buddy_delete(bb);
139 141
140 } 142 }
141 143
142 /* free the hosts list*/ 144 /* free the hosts list*/
143 g_slist_free(hosts); 145 g_slist_free(hosts);
200 static void DNSSD_API 202 static void DNSSD_API
201 _mdns_service_browse_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, 203 _mdns_service_browse_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
202 DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context) 204 DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context)
203 { 205 {
204 PurpleAccount *account = (PurpleAccount*)context; 206 PurpleAccount *account = (PurpleAccount*)context;
205 PurpleBuddy *gb = NULL; 207 PurpleBuddy *pb = NULL;
206 208
207 if (kDNSServiceErr_NoError != errorCode) 209 if (kDNSServiceErr_NoError != errorCode)
208 purple_debug_error("bonjour", "service browser - callback error"); 210 purple_debug_error("bonjour", "service browser - callback error");
209 else if (flags & kDNSServiceFlagsAdd) { 211 else if (flags & kDNSServiceFlagsAdd) {
210 /* A presence service instance has been discovered... check it isn't us! */ 212 /* A presence service instance has been discovered... check it isn't us! */
211 if (g_ascii_strcasecmp(serviceName, account->username) != 0) { 213 if (purple_utf8_strcasecmp(serviceName, account->username) != 0) {
212 /* OK, lets go ahead and resolve it to add to the buddy list */ 214 /* OK, lets go ahead and resolve it to add to the buddy list */
213 ResolveCallbackArgs *args = g_new0(ResolveCallbackArgs, 1); 215 ResolveCallbackArgs *args = g_new0(ResolveCallbackArgs, 1);
214 args->buddy = bonjour_buddy_new(serviceName, account); 216 args->buddy = bonjour_buddy_new(serviceName, account);
215 217
216 if (kDNSServiceErr_NoError != DNSServiceResolve(&args->resolver, 0, 0, serviceName, regtype, replyDomain, _mdns_service_resolve_callback, args)) { 218 if (kDNSServiceErr_NoError != DNSServiceResolve(&args->resolver, 0, 0, serviceName, regtype,
219 replyDomain, _mdns_service_resolve_callback, args)) {
217 bonjour_buddy_delete(args->buddy); 220 bonjour_buddy_delete(args->buddy);
218 g_free(args); 221 g_free(args);
219 purple_debug_error("bonjour", "service browser - failed to resolve service.\n"); 222 purple_debug_error("bonjour", "service browser - failed to resolve service.\n");
220 } else { 223 } else {
221 /* get a file descriptor for this service ref, and add it to the input list */ 224 /* get a file descriptor for this service ref, and add it to the input list */
224 } 227 }
225 } 228 }
226 } else { 229 } else {
227 /* A peer has sent a goodbye packet, remove them from the buddy list */ 230 /* A peer has sent a goodbye packet, remove them from the buddy list */
228 purple_debug_info("bonjour", "service browser - remove notification\n"); 231 purple_debug_info("bonjour", "service browser - remove notification\n");
229 gb = purple_find_buddy(account, serviceName); 232 pb = purple_find_buddy(account, serviceName);
230 if (gb != NULL) { 233 if (pb != NULL)
231 bonjour_buddy_delete(gb->proto_data); 234 purple_blist_remove_buddy(pb);
232 purple_blist_remove_buddy(gb);
233 }
234 } 235 }
235 } 236 }
236 237
237 /**************************** 238 /****************************
238 * mdns_interface functions * 239 * mdns_interface functions *