Mercurial > pidgin
annotate src/protocols/bonjour/dns_sd.c @ 11888:7d2d926704aa
[gaim-migrate @ 14179]
Gtk 2.0 support. Deja Vu.
committer: Tailor Script <tailor@pidgin.im>
author | Stu Tomlinson <stu@nosnilmot.com> |
---|---|
date | Sat, 29 Oct 2005 14:45:15 +0000 |
parents | 4669e7461968 |
children | 0d9c6d2ad64b |
rev | line source |
---|---|
11477 | 1 /* |
2 * This program is free software; you can redistribute it and/or modify | |
3 * it under the terms of the GNU General Public License as published by | |
4 * the Free Software Foundation; either version 2 of the License, or | |
5 * (at your option) any later version. | |
6 * | |
7 * This program is distributed in the hope that it will be useful, | |
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
10 * GNU Library General Public License for more details. | |
11 * | |
12 * You should have received a copy of the GNU General Public License | |
13 * along with this program; if not, write to the Free Software | |
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
15 */ | |
16 | |
17 #include <string.h> | |
18 | |
19 #include "dns_sd.h" | |
20 #include "bonjour.h" | |
21 #include "buddy.h" | |
22 #include "debug.h" | |
23 | |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
24 /* Private data */ |
11477 | 25 |
11539 | 26 typedef struct _dns_sd_packet |
27 { | |
28 gchar *name; | |
29 gchar *txtvers; | |
30 gchar *version; | |
31 gchar *first; | |
32 gchar *last; | |
11477 | 33 gint port_p2pj; |
11539 | 34 gchar *phsh; |
35 gchar *status; | |
36 gchar *message; | |
37 gchar *email; | |
38 gchar *vc; | |
39 gchar *jid; | |
40 gchar *AIM; | |
41 } dns_sd_packet; | |
11477 | 42 |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
43 /* End private data */ |
11477 | 44 |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
45 /* Private functions */ |
11477 | 46 |
11539 | 47 static sw_result HOWL_API |
48 _publish_reply(sw_discovery discovery, sw_discovery_oid oid, | |
49 sw_discovery_publish_status status, sw_opaque extra) | |
11477 | 50 { |
11539 | 51 gaim_debug_warning("bonjour", "_publish_reply --> Start\n"); |
52 | |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
53 /* Check the answer from the mDNS daemon */ |
11539 | 54 switch (status) |
55 { | |
11477 | 56 case SW_DISCOVERY_PUBLISH_STARTED : |
57 gaim_debug_info("bonjour", "_publish_reply --> Service started\n"); | |
58 break; | |
59 case SW_DISCOVERY_PUBLISH_STOPPED : | |
60 gaim_debug_info("bonjour", "_publish_reply --> Service stopped\n"); | |
61 break; | |
62 case SW_DISCOVERY_PUBLISH_NAME_COLLISION : | |
63 gaim_debug_info("bonjour", "_publish_reply --> Name collision\n"); | |
64 break; | |
65 case SW_DISCOVERY_PUBLISH_INVALID : | |
66 gaim_debug_info("bonjour", "_publish_reply --> Service invalid\n"); | |
67 break; | |
68 } | |
11539 | 69 |
11477 | 70 return SW_OKAY; |
71 } | |
72 | |
11539 | 73 static sw_result HOWL_API |
74 _resolve_reply(sw_discovery discovery, sw_discovery_oid oid, | |
75 sw_uint32 interface_index, sw_const_string name, | |
76 sw_const_string type, sw_const_string domain, | |
77 sw_ipv4_address address, sw_port port, | |
78 sw_octets text_record, sw_ulong text_record_len, | |
79 sw_opaque extra) | |
11477 | 80 { |
11539 | 81 BonjourBuddy *buddy; |
82 GaimAccount *account = (GaimAccount*)extra; | |
83 gchar *txtvers = NULL; | |
84 gchar *version = NULL; | |
85 gchar *first = NULL; | |
11477 | 86 gint port_p2pj = -1; |
11539 | 87 gchar *phsh = NULL; |
88 gchar *status = NULL; | |
89 gchar *email = NULL; | |
90 gchar *last = NULL; | |
91 gchar *jid = NULL; | |
92 gchar *AIM = NULL; | |
93 gchar *vc = NULL; | |
94 gchar *msg = NULL; | |
11477 | 95 gint address_length = 16; |
11539 | 96 gchar *ip = NULL; |
11477 | 97 sw_text_record_iterator iterator; |
11498 | 98 char key[SW_TEXT_RECORD_MAX_LEN]; |
99 char value[SW_TEXT_RECORD_MAX_LEN]; | |
11477 | 100 sw_uint32 value_length; |
101 | |
102 sw_discovery_cancel(discovery, oid); | |
11539 | 103 |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
104 /* Get the ip as a string */ |
11477 | 105 ip = malloc(address_length); |
106 sw_ipv4_address_name(address, ip, address_length); | |
107 | |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
108 /* Obtain the parameters from the text_record */ |
11539 | 109 if ((text_record_len > 0) && (text_record) && (*text_record != '\0')) |
110 { | |
11477 | 111 sw_text_record_iterator_init(&iterator, text_record, text_record_len); |
11539 | 112 while (sw_text_record_iterator_next(iterator, key, (sw_octet *)value, &value_length) == SW_OKAY) |
113 { | |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
114 /* Compare the keys with the possible ones and save them on */ |
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
115 /* the appropiate place of the buddy_list */ |
11477 | 116 if (strcmp(key, "txtvers") == 0) { |
117 txtvers = g_strdup(value); | |
118 } else if (strcmp(key, "version") == 0) { | |
119 version = g_strdup(value); | |
120 } else if (strcmp(key, "1st") == 0) { | |
121 first = g_strdup(value); | |
122 } else if (strcmp(key, "port.p2pj") == 0) { | |
123 port_p2pj = atoi(value); | |
124 } else if (strcmp(key, "status") == 0) { | |
125 status = g_strdup(value); | |
126 } else if (strcmp(key, "email") == 0) { | |
127 email = g_strdup(value); | |
128 } else if (strcmp(key, "last") == 0) { | |
129 last = g_strdup(value); | |
130 } else if (strcmp(key, "jid") == 0) { | |
131 jid = g_strdup(value); | |
132 } else if (strcmp(key, "AIM") == 0) { | |
133 AIM = g_strdup(value); | |
134 } else if (strcmp(key, "vc") == 0) { | |
135 vc = g_strdup(value); | |
136 } else if (strcmp(key, "phsh") == 0) { | |
137 phsh = g_strdup(value); | |
138 } else if (strcmp(key, "msg") == 0) { | |
139 msg = g_strdup(value); | |
140 } | |
141 } | |
142 } | |
143 | |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
144 /* Put the parameters of the text_record in a buddy and add the buddy to */ |
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
145 /* the buddy list */ |
11539 | 146 buddy = bonjour_buddy_new((gchar *)name, first, port_p2pj, phsh, |
147 status, email, last, jid, AIM, vc, ip, msg); | |
148 | |
149 if (bonjour_buddy_check(buddy) == FALSE) | |
150 { | |
11477 | 151 return SW_DISCOVERY_E_UNKNOWN; |
152 } | |
11539 | 153 |
11496 | 154 /* Add or update the buddy in our buddy list */ |
155 bonjour_buddy_add_to_gaim(account, buddy); | |
11539 | 156 |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
157 /* Free all the temporal strings */ |
11477 | 158 g_free(txtvers); |
159 g_free(version); | |
160 g_free(first); | |
161 g_free(last); | |
162 g_free(status); | |
163 g_free(email); | |
164 g_free(jid); | |
165 g_free(AIM); | |
166 g_free(vc); | |
167 g_free(phsh); | |
168 g_free(msg); | |
11539 | 169 |
11477 | 170 return SW_OKAY; |
171 } | |
172 | |
11539 | 173 static sw_result HOWL_API |
174 _browser_reply(sw_discovery discovery, sw_discovery_oid oid, | |
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) | |
11477 | 179 { |
180 sw_discovery_resolve_id rid; | |
11539 | 181 GaimAccount *account = (GaimAccount*)extra; |
182 GaimBuddy *gb = NULL; | |
183 | |
184 switch (status) | |
185 { | |
11477 | 186 case SW_DISCOVERY_BROWSE_INVALID: |
187 gaim_debug_warning("bonjour", "_browser_reply --> Invalid\n"); | |
188 break; | |
189 case SW_DISCOVERY_BROWSE_RELEASE: | |
190 gaim_debug_warning("bonjour", "_browser_reply --> Release\n"); | |
191 break; | |
192 case SW_DISCOVERY_BROWSE_ADD_DOMAIN: | |
193 gaim_debug_warning("bonjour", "_browser_reply --> Add domain\n"); | |
194 break; | |
195 case SW_DISCOVERY_BROWSE_ADD_DEFAULT_DOMAIN: | |
196 gaim_debug_warning("bonjour", "_browser_reply --> Add default domain\n"); | |
197 break; | |
198 case SW_DISCOVERY_BROWSE_REMOVE_DOMAIN: | |
199 gaim_debug_warning("bonjour", "_browser_reply --> Remove domain\n"); | |
200 break; | |
201 case SW_DISCOVERY_BROWSE_ADD_SERVICE: | |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
202 /* A new peer has join the network and uses iChat bonjour */ |
11477 | 203 gaim_debug_info("bonjour", "_browser_reply --> Add service\n"); |
11539 | 204 if (g_ascii_strcasecmp(name, account->username) != 0) |
205 { | |
206 if (sw_discovery_resolve(discovery, interface_index, name, type, | |
207 domain, _resolve_reply, extra, &rid) != SW_OKAY) | |
208 { | |
11477 | 209 gaim_debug_warning("bonjour", "_browser_reply --> Cannot send resolve\n"); |
210 } | |
211 } | |
212 break; | |
213 case SW_DISCOVERY_BROWSE_REMOVE_SERVICE: | |
214 gaim_debug_info("bonjour", "_browser_reply --> Remove service\n"); | |
215 gb = gaim_find_buddy((GaimAccount*)extra, name); | |
11539 | 216 if (gb != NULL) |
217 { | |
11477 | 218 bonjour_buddy_delete(gb->proto_data); |
219 gaim_blist_remove_buddy(gb); | |
220 } | |
221 break; | |
222 case SW_DISCOVERY_BROWSE_RESOLVED: | |
223 gaim_debug_info("bonjour", "_browse_reply --> Resolved\n"); | |
224 break; | |
225 default: | |
226 break; | |
227 } | |
11539 | 228 |
11477 | 229 return SW_OKAY; |
230 } | |
231 | |
11677 | 232 static int |
11539 | 233 _dns_sd_publish(BonjourDnsSd *data, PublishType type) |
11477 | 234 { |
235 sw_text_record dns_data; | |
11773
92cf092f194e
[gaim-migrate @ 14064]
Gary Kramlich <grim@reaperworld.com>
parents:
11678
diff
changeset
|
236 sw_result publish_result = SW_OKAY; |
11477 | 237 |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
238 /* Fill the data for the service */ |
11539 | 239 if (sw_text_record_init(&dns_data) != SW_OKAY) |
240 { | |
11477 | 241 gaim_debug_error("bonjour", "Unable to initialize the data for the mDNS."); |
242 return -1; | |
243 } | |
244 | |
245 sw_text_record_add_key_and_string_value(dns_data, "txtvers", data->txtvers); | |
246 sw_text_record_add_key_and_string_value(dns_data, "version", data->version); | |
247 sw_text_record_add_key_and_string_value(dns_data, "1st", data->first); | |
248 sw_text_record_add_key_and_string_value(dns_data, "last", data->last); | |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
249 /* sw_text_record_add_key_and_string_value(dns_data, "port.p2pj", itoa(data->port_p2pj)); */ |
11477 | 250 sw_text_record_add_key_and_string_value(dns_data, "port.p2pj", BONJOUR_DEFAULT_PORT); |
251 sw_text_record_add_key_and_string_value(dns_data, "phsh", data->phsh); | |
252 sw_text_record_add_key_and_string_value(dns_data, "status", data->status); | |
253 sw_text_record_add_key_and_string_value(dns_data, "msg", data->msg); | |
254 sw_text_record_add_key_and_string_value(dns_data, "email", data->email); | |
255 sw_text_record_add_key_and_string_value(dns_data, "vc", data->vc); | |
256 sw_text_record_add_key_and_string_value(dns_data, "jid", data->jid); | |
257 sw_text_record_add_key_and_string_value(dns_data, "AIM", data->AIM); | |
258 | |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
259 /* Publish the service */ |
11539 | 260 switch (type) |
261 { | |
11477 | 262 case PUBLISH_START: |
11539 | 263 publish_result = sw_discovery_publish(*(data->session), 0, data->name, ICHAT_SERVICE, NULL, |
264 NULL, data->port_p2pj, sw_text_record_bytes(dns_data), sw_text_record_len(dns_data), | |
11477 | 265 _publish_reply, NULL, &(data->session_id)); |
266 break; | |
267 case PUBLISH_UPDATE: | |
268 publish_result = sw_discovery_publish_update(*(data->session),data->session_id, | |
269 sw_text_record_bytes(dns_data), sw_text_record_len(dns_data)); | |
270 break; | |
271 } | |
11539 | 272 if (publish_result != SW_OKAY) |
273 { | |
11477 | 274 gaim_debug_error("bonjour", "Unable to publish or change the status of the _presence._tcp service."); |
275 return -1; | |
276 } | |
277 | |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
278 /* Free the memory used by temp data */ |
11477 | 279 sw_text_record_fina(dns_data); |
280 | |
281 return 0; | |
282 } | |
283 | |
11678 | 284 static void |
285 _dns_sd_handle_packets(gpointer data, gint source, GaimInputCondition condition) | |
11477 | 286 { |
287 sw_discovery_read_socket(*((sw_discovery*)data)); | |
288 } | |
289 | |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
290 /* End private functions */ |
11477 | 291 |
292 /** | |
293 * Allocate space for the dns-sd data. | |
294 */ | |
11539 | 295 BonjourDnsSd * |
296 bonjour_dns_sd_new() | |
11477 | 297 { |
11539 | 298 BonjourDnsSd *data = g_new(BonjourDnsSd, 1); |
11477 | 299 data->session = g_malloc(sizeof(sw_discovery)); |
11539 | 300 |
11477 | 301 return data; |
302 } | |
303 | |
304 /** | |
305 * Deallocate the space of the dns-sd data. | |
306 */ | |
11539 | 307 void |
308 bonjour_dns_sd_free(BonjourDnsSd *data) | |
11477 | 309 { |
310 g_free(data->session); | |
11496 | 311 g_free(data->first); |
312 g_free(data->last); | |
313 g_free(data->email); | |
11477 | 314 g_free(data); |
315 } | |
316 | |
317 /** | |
318 * Send a new dns-sd packet updating our status. | |
319 */ | |
11539 | 320 void |
321 bonjour_dns_sd_send_status(BonjourDnsSd *data, const char *status, const char *status_message) | |
11477 | 322 { |
11496 | 323 g_free(data->status); |
324 g_free(data->msg); | |
11477 | 325 |
326 data->status = g_strdup(status); | |
327 data->msg = g_strdup(status_message); | |
328 | |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
329 /* Update our text record with the new status */ |
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
330 _dns_sd_publish(data, PUBLISH_UPDATE); /* <--We must control the errors */ |
11477 | 331 } |
332 | |
333 /** | |
11496 | 334 * Advertise our presence within the dns-sd daemon and start browsing |
335 * for other bonjour peers. | |
11477 | 336 */ |
11539 | 337 void |
338 bonjour_dns_sd_start(BonjourDnsSd *data) | |
339 { | |
11678 | 340 GaimAccount *account; |
341 GaimConnection *gc; | |
11477 | 342 gint dns_sd_socket; |
343 sw_discovery_oid session_id; | |
11539 | 344 |
11678 | 345 account = data->account; |
346 gc = gaim_account_get_connection(account); | |
347 | |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
348 /* Initilizations of the dns-sd data and session */ |
11477 | 349 data->session = malloc(sizeof(sw_discovery)); |
11539 | 350 if (sw_discovery_init(data->session) != SW_OKAY) |
351 { | |
11477 | 352 gaim_debug_error("bonjour", "Unable to initialize a mDNS session."); |
353 return; | |
354 } | |
11539 | 355 |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
356 /* Publish our bonjour IM client at the mDNS daemon */ |
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
357 _dns_sd_publish(data, PUBLISH_START); /* <--We must control the errors */ |
11539 | 358 |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
359 /* Advise the daemon that we are waiting for connections */ |
11539 | 360 if (sw_discovery_browse(*(data->session), 0, ICHAT_SERVICE, NULL, _browser_reply, |
361 data->account, &session_id) != SW_OKAY) | |
362 { | |
11477 | 363 gaim_debug_error("bonjour", "Unable to get service."); |
364 return; | |
365 } | |
11539 | 366 |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
367 /* Get the socket that communicates with the mDNS daemon and bind it to a */ |
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11773
diff
changeset
|
368 /* callback that will handle the dns_sd packets */ |
11477 | 369 dns_sd_socket = sw_discovery_socket(*(data->session)); |
11678 | 370 gc->inpa = gaim_input_add(dns_sd_socket, GAIM_INPUT_READ, |
371 _dns_sd_handle_packets, data->session); | |
11477 | 372 } |
373 | |
374 /** | |
375 * Unregister the "_presence._tcp" service at the mDNS daemon. | |
376 */ | |
11539 | 377 int |
378 bonjour_dns_sd_stop(BonjourDnsSd *data) | |
11477 | 379 { |
11678 | 380 GaimAccount *account; |
381 GaimConnection *gc; | |
382 | |
11477 | 383 sw_discovery_cancel(*(data->session), data->session_id); |
11539 | 384 |
11678 | 385 account = data->account; |
386 gc = gaim_account_get_connection(account); | |
387 gaim_input_remove(gc->inpa); | |
388 | |
11477 | 389 return 0; |
390 } |