comparison src/protocols/bonjour/dns_sd.c @ 11539:5a2c38d33eb4

[gaim-migrate @ 13794] Formatting and whitespace committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Wed, 14 Sep 2005 02:58:30 +0000
parents f8a447af7494
children 8004885fabbe
comparison
equal deleted inserted replaced
11538:5c6c2e893803 11539:5a2c38d33eb4
21 #include "buddy.h" 21 #include "buddy.h"
22 #include "debug.h" 22 #include "debug.h"
23 23
24 // Private data 24 // Private data
25 25
26 typedef struct _dns_sd_packet{ 26 typedef struct _dns_sd_packet
27 gchar* name; 27 {
28 gchar* txtvers; 28 gchar *name;
29 gchar* version; 29 gchar *txtvers;
30 gchar* first; 30 gchar *version;
31 gchar* last; 31 gchar *first;
32 gchar *last;
32 gint port_p2pj; 33 gint port_p2pj;
33 gchar* phsh; 34 gchar *phsh;
34 gchar* status; 35 gchar *status;
35 gchar* message; 36 gchar *message;
36 gchar* email; 37 gchar *email;
37 gchar* vc; 38 gchar *vc;
38 gchar* jid; 39 gchar *jid;
39 gchar* AIM; 40 gchar *AIM;
40 }dns_sd_packet; 41 } dns_sd_packet;
41 42
42 // End private data 43 // End private data
43 44
44 // Private functions 45 // Private functions
45 46
46 static sw_result HOWL_API _publish_reply(sw_discovery discovery, 47 static sw_result HOWL_API
47 sw_discovery_oid oid, sw_discovery_publish_status status, sw_opaque extra) 48 _publish_reply(sw_discovery discovery, sw_discovery_oid oid,
48 { 49 sw_discovery_publish_status status, sw_opaque extra)
49 gaim_debug_warning("bonjour", "_publish_reply --> Start\n"); 50 {
51 gaim_debug_warning("bonjour", "_publish_reply --> Start\n");
52
50 // Check the answer from the mDNS daemon 53 // Check the answer from the mDNS daemon
51 switch(status){ 54 switch (status)
55 {
52 case SW_DISCOVERY_PUBLISH_STARTED : 56 case SW_DISCOVERY_PUBLISH_STARTED :
53 gaim_debug_info("bonjour", "_publish_reply --> Service started\n"); 57 gaim_debug_info("bonjour", "_publish_reply --> Service started\n");
54 break; 58 break;
55 case SW_DISCOVERY_PUBLISH_STOPPED : 59 case SW_DISCOVERY_PUBLISH_STOPPED :
56 gaim_debug_info("bonjour", "_publish_reply --> Service stopped\n"); 60 gaim_debug_info("bonjour", "_publish_reply --> Service stopped\n");
60 break; 64 break;
61 case SW_DISCOVERY_PUBLISH_INVALID : 65 case SW_DISCOVERY_PUBLISH_INVALID :
62 gaim_debug_info("bonjour", "_publish_reply --> Service invalid\n"); 66 gaim_debug_info("bonjour", "_publish_reply --> Service invalid\n");
63 break; 67 break;
64 } 68 }
65 69
66 return SW_OKAY; 70 return SW_OKAY;
67 } 71 }
68 72
69 static sw_result HOWL_API _resolve_reply(sw_discovery discovery, 73 static sw_result HOWL_API
70 sw_discovery_oid oid, sw_uint32 interface_index, sw_const_string name, 74 _resolve_reply(sw_discovery discovery, sw_discovery_oid oid,
71 sw_const_string type, sw_const_string domain, sw_ipv4_address address, 75 sw_uint32 interface_index, sw_const_string name,
72 sw_port port, sw_octets text_record, sw_ulong text_record_len, 76 sw_const_string type, sw_const_string domain,
73 sw_opaque extra) 77 sw_ipv4_address address, sw_port port,
74 { 78 sw_octets text_record, sw_ulong text_record_len,
75 BonjourBuddy* buddy; 79 sw_opaque extra)
76 GaimAccount* account = (GaimAccount*)extra; 80 {
77 gchar* txtvers = NULL; 81 BonjourBuddy *buddy;
78 gchar* version = NULL; 82 GaimAccount *account = (GaimAccount*)extra;
79 gchar* first = NULL; 83 gchar *txtvers = NULL;
84 gchar *version = NULL;
85 gchar *first = NULL;
80 gint port_p2pj = -1; 86 gint port_p2pj = -1;
81 gchar* phsh = NULL; 87 gchar *phsh = NULL;
82 gchar* status = NULL; 88 gchar *status = NULL;
83 gchar* email = NULL; 89 gchar *email = NULL;
84 gchar* last = NULL; 90 gchar *last = NULL;
85 gchar* jid = NULL; 91 gchar *jid = NULL;
86 gchar* AIM = NULL; 92 gchar *AIM = NULL;
87 gchar* vc = NULL; 93 gchar *vc = NULL;
88 gchar* msg = NULL; 94 gchar *msg = NULL;
89 gint address_length = 16; 95 gint address_length = 16;
90 gchar* ip = NULL; 96 gchar *ip = NULL;
91 sw_text_record_iterator iterator; 97 sw_text_record_iterator iterator;
92 char key[SW_TEXT_RECORD_MAX_LEN]; 98 char key[SW_TEXT_RECORD_MAX_LEN];
93 char value[SW_TEXT_RECORD_MAX_LEN]; 99 char value[SW_TEXT_RECORD_MAX_LEN];
94 sw_uint32 value_length; 100 sw_uint32 value_length;
95 101
96 sw_discovery_cancel(discovery, oid); 102 sw_discovery_cancel(discovery, oid);
97 103
98 // Get the ip as a string 104 // Get the ip as a string
99 ip = malloc(address_length); 105 ip = malloc(address_length);
100 sw_ipv4_address_name(address, ip, address_length); 106 sw_ipv4_address_name(address, ip, address_length);
101 107
102 // Obtain the parameters from the text_record 108 // Obtain the parameters from the text_record
103 if ((text_record_len > 0) && (text_record) && (*text_record != '\0')) { 109 if ((text_record_len > 0) && (text_record) && (*text_record != '\0'))
110 {
104 sw_text_record_iterator_init(&iterator, text_record, text_record_len); 111 sw_text_record_iterator_init(&iterator, text_record, text_record_len);
105 while (sw_text_record_iterator_next(iterator, key, (sw_octet *)value, &value_length) == SW_OKAY) { 112 while (sw_text_record_iterator_next(iterator, key, (sw_octet *)value, &value_length) == SW_OKAY)
106 // Compare the keys with the possible ones and save them on 113 {
114 // Compare the keys with the possible ones and save them on
107 // the appropiate place of the buddy_list 115 // the appropiate place of the buddy_list
108 if (strcmp(key, "txtvers") == 0) { 116 if (strcmp(key, "txtvers") == 0) {
109 txtvers = g_strdup(value); 117 txtvers = g_strdup(value);
110 } else if (strcmp(key, "version") == 0) { 118 } else if (strcmp(key, "version") == 0) {
111 version = g_strdup(value); 119 version = g_strdup(value);
131 msg = g_strdup(value); 139 msg = g_strdup(value);
132 } 140 }
133 } 141 }
134 } 142 }
135 143
136 // Put the parameters of the text_record in a buddy and add the buddy to 144 // Put the parameters of the text_record in a buddy and add the buddy to
137 // the buddy list 145 // the buddy list
138 buddy = bonjour_buddy_new((gchar*)name, first, port_p2pj, phsh, status, email, 146 buddy = bonjour_buddy_new((gchar *)name, first, port_p2pj, phsh,
139 last, jid, AIM, vc, ip, msg); 147 status, email, last, jid, AIM, vc, ip, msg);
140 148
141 if (bonjour_buddy_check(buddy) == FALSE) { 149 if (bonjour_buddy_check(buddy) == FALSE)
150 {
142 return SW_DISCOVERY_E_UNKNOWN; 151 return SW_DISCOVERY_E_UNKNOWN;
143 } 152 }
144 153
145 /* Add or update the buddy in our buddy list */ 154 /* Add or update the buddy in our buddy list */
146 bonjour_buddy_add_to_gaim(account, buddy); 155 bonjour_buddy_add_to_gaim(account, buddy);
147 156
148 // Free all the temporal strings 157 // Free all the temporal strings
149 g_free(txtvers); 158 g_free(txtvers);
150 g_free(version); 159 g_free(version);
151 g_free(first); 160 g_free(first);
152 g_free(last); 161 g_free(last);
155 g_free(jid); 164 g_free(jid);
156 g_free(AIM); 165 g_free(AIM);
157 g_free(vc); 166 g_free(vc);
158 g_free(phsh); 167 g_free(phsh);
159 g_free(msg); 168 g_free(msg);
160 169
161 return SW_OKAY; 170 return SW_OKAY;
162 } 171 }
163 172
164 static sw_result HOWL_API _browser_reply(sw_discovery discovery, sw_discovery_oid oid, 173 static sw_result HOWL_API
165 sw_discovery_browse_status status, sw_uint32 interface_index, sw_const_string name, 174 _browser_reply(sw_discovery discovery, sw_discovery_oid oid,
166 sw_const_string type, sw_const_string domain, sw_opaque_t extra) 175 sw_discovery_browse_status status,
176 sw_uint32 interface_index, sw_const_string name,
177 sw_const_string type, sw_const_string domain,
178 sw_opaque_t extra)
167 { 179 {
168 sw_discovery_resolve_id rid; 180 sw_discovery_resolve_id rid;
169 GaimAccount* account = (GaimAccount*)extra; 181 GaimAccount *account = (GaimAccount*)extra;
170 GaimBuddy* gb = NULL; 182 GaimBuddy *gb = NULL;
171 183
172 switch(status){ 184 switch (status)
185 {
173 case SW_DISCOVERY_BROWSE_INVALID: 186 case SW_DISCOVERY_BROWSE_INVALID:
174 gaim_debug_warning("bonjour", "_browser_reply --> Invalid\n"); 187 gaim_debug_warning("bonjour", "_browser_reply --> Invalid\n");
175 break; 188 break;
176 case SW_DISCOVERY_BROWSE_RELEASE: 189 case SW_DISCOVERY_BROWSE_RELEASE:
177 gaim_debug_warning("bonjour", "_browser_reply --> Release\n"); 190 gaim_debug_warning("bonjour", "_browser_reply --> Release\n");
186 gaim_debug_warning("bonjour", "_browser_reply --> Remove domain\n"); 199 gaim_debug_warning("bonjour", "_browser_reply --> Remove domain\n");
187 break; 200 break;
188 case SW_DISCOVERY_BROWSE_ADD_SERVICE: 201 case SW_DISCOVERY_BROWSE_ADD_SERVICE:
189 // A new peer has join the network and uses iChat bonjour 202 // A new peer has join the network and uses iChat bonjour
190 gaim_debug_info("bonjour", "_browser_reply --> Add service\n"); 203 gaim_debug_info("bonjour", "_browser_reply --> Add service\n");
191 if (g_ascii_strcasecmp(name, account->username) != 0){ 204 if (g_ascii_strcasecmp(name, account->username) != 0)
192 if (sw_discovery_resolve(discovery, interface_index, name, type, 205 {
193 domain, _resolve_reply, extra, &rid) != SW_OKAY) { 206 if (sw_discovery_resolve(discovery, interface_index, name, type,
207 domain, _resolve_reply, extra, &rid) != SW_OKAY)
208 {
194 gaim_debug_warning("bonjour", "_browser_reply --> Cannot send resolve\n"); 209 gaim_debug_warning("bonjour", "_browser_reply --> Cannot send resolve\n");
195 } 210 }
196 } 211 }
197 break; 212 break;
198 case SW_DISCOVERY_BROWSE_REMOVE_SERVICE: 213 case SW_DISCOVERY_BROWSE_REMOVE_SERVICE:
199 gaim_debug_info("bonjour", "_browser_reply --> Remove service\n"); 214 gaim_debug_info("bonjour", "_browser_reply --> Remove service\n");
200 gb = gaim_find_buddy((GaimAccount*)extra, name); 215 gb = gaim_find_buddy((GaimAccount*)extra, name);
201 if (gb != NULL) { 216 if (gb != NULL)
217 {
202 bonjour_buddy_delete(gb->proto_data); 218 bonjour_buddy_delete(gb->proto_data);
203 gaim_blist_remove_buddy(gb); 219 gaim_blist_remove_buddy(gb);
204 } 220 }
205 break; 221 break;
206 case SW_DISCOVERY_BROWSE_RESOLVED: 222 case SW_DISCOVERY_BROWSE_RESOLVED:
207 gaim_debug_info("bonjour", "_browse_reply --> Resolved\n"); 223 gaim_debug_info("bonjour", "_browse_reply --> Resolved\n");
208 break; 224 break;
209 default: 225 default:
210 break; 226 break;
211 } 227 }
212 228
213 return SW_OKAY; 229 return SW_OKAY;
214 } 230 }
215 231
216 int _dns_sd_publish(BonjourDnsSd* data, PublishType type) 232 int
233 _dns_sd_publish(BonjourDnsSd *data, PublishType type)
217 { 234 {
218 sw_text_record dns_data; 235 sw_text_record dns_data;
219 sw_result publish_result; 236 sw_result publish_result;
220 237
221 // Fill the data for the service 238 // Fill the data for the service
222 if(sw_text_record_init(&dns_data) != SW_OKAY){ 239 if (sw_text_record_init(&dns_data) != SW_OKAY)
240 {
223 gaim_debug_error("bonjour", "Unable to initialize the data for the mDNS."); 241 gaim_debug_error("bonjour", "Unable to initialize the data for the mDNS.");
224 return -1; 242 return -1;
225 } 243 }
226 244
227 sw_text_record_add_key_and_string_value(dns_data, "txtvers", data->txtvers); 245 sw_text_record_add_key_and_string_value(dns_data, "txtvers", data->txtvers);
237 sw_text_record_add_key_and_string_value(dns_data, "vc", data->vc); 255 sw_text_record_add_key_and_string_value(dns_data, "vc", data->vc);
238 sw_text_record_add_key_and_string_value(dns_data, "jid", data->jid); 256 sw_text_record_add_key_and_string_value(dns_data, "jid", data->jid);
239 sw_text_record_add_key_and_string_value(dns_data, "AIM", data->AIM); 257 sw_text_record_add_key_and_string_value(dns_data, "AIM", data->AIM);
240 258
241 // Publish the service 259 // Publish the service
242 switch (type) { 260 switch (type)
261 {
243 case PUBLISH_START: 262 case PUBLISH_START:
244 publish_result = sw_discovery_publish(*(data->session), 0, data->name, ICHAT_SERVICE, NULL, 263 publish_result = sw_discovery_publish(*(data->session), 0, data->name, ICHAT_SERVICE, NULL,
245 NULL, data->port_p2pj, sw_text_record_bytes(dns_data), sw_text_record_len(dns_data), 264 NULL, data->port_p2pj, sw_text_record_bytes(dns_data), sw_text_record_len(dns_data),
246 _publish_reply, NULL, &(data->session_id)); 265 _publish_reply, NULL, &(data->session_id));
247 break; 266 break;
248 case PUBLISH_UPDATE: 267 case PUBLISH_UPDATE:
249 publish_result = sw_discovery_publish_update(*(data->session),data->session_id, 268 publish_result = sw_discovery_publish_update(*(data->session),data->session_id,
250 sw_text_record_bytes(dns_data), sw_text_record_len(dns_data)); 269 sw_text_record_bytes(dns_data), sw_text_record_len(dns_data));
251 break; 270 break;
252 } 271 }
253 if(publish_result != SW_OKAY){ 272 if (publish_result != SW_OKAY)
273 {
254 gaim_debug_error("bonjour", "Unable to publish or change the status of the _presence._tcp service."); 274 gaim_debug_error("bonjour", "Unable to publish or change the status of the _presence._tcp service.");
255 return -1; 275 return -1;
256 } 276 }
257 277
258 // Free the memory used by temp data 278 // Free the memory used by temp data
259 sw_text_record_fina(dns_data); 279 sw_text_record_fina(dns_data);
260 280
261 return 0; 281 return 0;
262 } 282 }
263 283
264 gboolean _dns_sd_handle_packets(GIOChannel* source, GIOCondition condition, gpointer data) 284 gboolean
285 _dns_sd_handle_packets(GIOChannel *source, GIOCondition condition, gpointer data)
265 { 286 {
266 sw_discovery_read_socket(*((sw_discovery*)data)); 287 sw_discovery_read_socket(*((sw_discovery*)data));
267 return TRUE; 288 return TRUE;
268 } 289 }
269 290
270 gpointer _dns_sd_wait_for_connections(gpointer data) 291 gpointer
292 _dns_sd_wait_for_connections(gpointer data)
271 { 293 {
272 sw_discovery_oid session_id; 294 sw_discovery_oid session_id;
273 BonjourDnsSd* dns_sd_data = (BonjourDnsSd*)data; 295 BonjourDnsSd *dns_sd_data = (BonjourDnsSd*)data;
274 296
275 // Advise the daemon that we are waiting for connections 297 // Advise the daemon that we are waiting for connections
276 if(sw_discovery_browse(*(dns_sd_data->session), 0, ICHAT_SERVICE, NULL, _browser_reply, 298 if (sw_discovery_browse(*(dns_sd_data->session), 0, ICHAT_SERVICE, NULL, _browser_reply,
277 dns_sd_data->account, &session_id) != SW_OKAY){ 299 dns_sd_data->account, &session_id) != SW_OKAY)
300 {
278 gaim_debug_error("bonjour", "Unable to get service."); 301 gaim_debug_error("bonjour", "Unable to get service.");
279 return NULL; 302 return NULL;
280 } 303 }
281 304
282 // Yields control of the cpu to the daemon 305 // Yields control of the cpu to the daemon
283 sw_discovery_run(*(dns_sd_data->session)); 306 sw_discovery_run(*(dns_sd_data->session));
284 307
285 return NULL; 308 return NULL;
286 } 309 }
287 310
288 // End private functions 311 // End private functions
289 312
290 /** 313 /**
291 * Allocate space for the dns-sd data. 314 * Allocate space for the dns-sd data.
292 */ 315 */
293 BonjourDnsSd* bonjour_dns_sd_new() 316 BonjourDnsSd *
294 { 317 bonjour_dns_sd_new()
295 BonjourDnsSd* data = g_new(BonjourDnsSd, 1); 318 {
319 BonjourDnsSd *data = g_new(BonjourDnsSd, 1);
296 data->session = g_malloc(sizeof(sw_discovery)); 320 data->session = g_malloc(sizeof(sw_discovery));
297 321
298 return data; 322 return data;
299 } 323 }
300 324
301 /** 325 /**
302 * Deallocate the space of the dns-sd data. 326 * Deallocate the space of the dns-sd data.
303 */ 327 */
304 void bonjour_dns_sd_free(BonjourDnsSd* data) 328 void
329 bonjour_dns_sd_free(BonjourDnsSd *data)
305 { 330 {
306 g_free(data->session); 331 g_free(data->session);
307 g_free(data->first); 332 g_free(data->first);
308 g_free(data->last); 333 g_free(data->last);
309 g_free(data->email); 334 g_free(data->email);
311 } 336 }
312 337
313 /** 338 /**
314 * Send a new dns-sd packet updating our status. 339 * Send a new dns-sd packet updating our status.
315 */ 340 */
316 void bonjour_dns_sd_send_status(BonjourDnsSd *data, const char *status, const char* status_message) 341 void
342 bonjour_dns_sd_send_status(BonjourDnsSd *data, const char *status, const char *status_message)
317 { 343 {
318 g_free(data->status); 344 g_free(data->status);
319 g_free(data->msg); 345 g_free(data->msg);
320 346
321 data->status = g_strdup(status); 347 data->status = g_strdup(status);
327 353
328 /** 354 /**
329 * Advertise our presence within the dns-sd daemon and start browsing 355 * Advertise our presence within the dns-sd daemon and start browsing
330 * for other bonjour peers. 356 * for other bonjour peers.
331 */ 357 */
332 void bonjour_dns_sd_start(BonjourDnsSd* data) 358 void
333 { 359 bonjour_dns_sd_start(BonjourDnsSd *data)
334 GIOChannel* io_channel; 360 {
361 GIOChannel *io_channel;
335 gint dns_sd_socket; 362 gint dns_sd_socket;
336 sw_discovery_oid session_id; 363 sw_discovery_oid session_id;
337 364
338 // Initilizations of the dns-sd data and session 365 // Initilizations of the dns-sd data and session
339 data->session = malloc(sizeof(sw_discovery)); 366 data->session = malloc(sizeof(sw_discovery));
340 if(sw_discovery_init(data->session) != SW_OKAY){ 367 if (sw_discovery_init(data->session) != SW_OKAY)
368 {
341 gaim_debug_error("bonjour", "Unable to initialize a mDNS session."); 369 gaim_debug_error("bonjour", "Unable to initialize a mDNS session.");
342 return; 370 return;
343 } 371 }
344 372
345 // Publish our bonjour IM client at the mDNS daemon 373 // Publish our bonjour IM client at the mDNS daemon
346 _dns_sd_publish(data, PUBLISH_START); // <--We must control the errors 374 _dns_sd_publish(data, PUBLISH_START); // <--We must control the errors
347 375
348
349 // Advise the daemon that we are waiting for connections 376 // Advise the daemon that we are waiting for connections
350 if(sw_discovery_browse(*(data->session), 0, ICHAT_SERVICE, NULL, _browser_reply, 377 if (sw_discovery_browse(*(data->session), 0, ICHAT_SERVICE, NULL, _browser_reply,
351 data->account, &session_id) != SW_OKAY){ 378 data->account, &session_id) != SW_OKAY)
379 {
352 gaim_debug_error("bonjour", "Unable to get service."); 380 gaim_debug_error("bonjour", "Unable to get service.");
353 return; 381 return;
354 } 382 }
355 383
356 // Get the socket that communicates with the mDNS daemon and bind it to a 384 // Get the socket that communicates with the mDNS daemon and bind it to a
357 // callback that will handle the dns_sd packets 385 // callback that will handle the dns_sd packets
358 dns_sd_socket = sw_discovery_socket(*(data->session)); 386 dns_sd_socket = sw_discovery_socket(*(data->session));
359 io_channel = g_io_channel_unix_new(dns_sd_socket); 387 io_channel = g_io_channel_unix_new(dns_sd_socket);
360 g_io_add_watch(io_channel, G_IO_IN, _dns_sd_handle_packets, data->session); // Add more for other conditions like when the conn. has been broken 388 // Add more for other conditions like when the conn. has been broken
389 g_io_add_watch(io_channel, G_IO_IN, _dns_sd_handle_packets, data->session);
361 } 390 }
362 391
363 /** 392 /**
364 * Unregister the "_presence._tcp" service at the mDNS daemon. 393 * Unregister the "_presence._tcp" service at the mDNS daemon.
365 */ 394 */
366 int bonjour_dns_sd_stop(BonjourDnsSd* data) 395 int
396 bonjour_dns_sd_stop(BonjourDnsSd *data)
367 { 397 {
368 sw_discovery_cancel(*(data->session), data->session_id); 398 sw_discovery_cancel(*(data->session), data->session_id);
369 399
370 return 0; 400 return 0;
371 } 401 }