Mercurial > pidgin
comparison libgaim/protocols/oscar/flap_connection.c @ 14392:92eb7a040663
[gaim-migrate @ 17099]
Better connection error messages for dnsquery failures in
general and for oscar
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Thu, 31 Aug 2006 09:44:51 +0000 |
parents | 80b05108652c |
children | 648e33275d9d |
comparison
equal
deleted
inserted
replaced
14391:6e89bfd2b33f | 14392:92eb7a040663 |
---|---|
161 flap_connection_send_close(od, conn); | 161 flap_connection_send_close(od, conn); |
162 | 162 |
163 close(conn->fd); | 163 close(conn->fd); |
164 conn->fd = -1; | 164 conn->fd = -1; |
165 } | 165 } |
166 | |
167 if (conn->watcher_incoming != 0) | |
168 { | |
169 gaim_input_remove(conn->watcher_incoming); | |
170 conn->watcher_incoming = 0; | |
171 } | |
172 | |
173 if (conn->watcher_outgoing != 0) | |
174 { | |
175 gaim_input_remove(conn->watcher_outgoing); | |
176 conn->watcher_outgoing = 0; | |
177 } | |
178 | |
179 g_free(conn->buffer_incoming.data.data); | |
180 conn->buffer_incoming.data.data = NULL; | |
181 | |
182 gaim_circ_buffer_destroy(conn->buffer_outgoing); | |
183 conn->buffer_outgoing = NULL; | |
166 } | 184 } |
167 | 185 |
168 static void | 186 static void |
169 flap_connection_destroy_rates(struct rateclass *head) | 187 flap_connection_destroy_rates(struct rateclass *head) |
170 { | 188 { |
197 OscarData *od; | 215 OscarData *od; |
198 GaimAccount *account; | 216 GaimAccount *account; |
199 | 217 |
200 conn = data; | 218 conn = data; |
201 od = conn->od; | 219 od = conn->od; |
220 account = gaim_connection_get_account(od->gc); | |
202 | 221 |
203 gaim_debug_info("oscar", "Destroying oscar connection of " | 222 gaim_debug_info("oscar", "Destroying oscar connection of " |
204 "type 0x%04hx\n", conn->type); | 223 "type 0x%04hx\n", conn->type); |
205 | 224 |
206 flap_connection_close(od, conn); | |
207 | |
208 g_free(conn->cookie); | |
209 | |
210 if (conn->watcher_incoming != 0) | |
211 gaim_input_remove(conn->watcher_incoming); | |
212 if (conn->watcher_outgoing != 0) | |
213 gaim_input_remove(conn->watcher_outgoing); | |
214 g_free(conn->buffer_incoming.data.data); | |
215 gaim_circ_buffer_destroy(conn->buffer_outgoing); | |
216 | |
217 /* | |
218 * Free conn->internal, if necessary | |
219 */ | |
220 if (conn->type == SNAC_FAMILY_CHAT) | |
221 flap_connection_destroy_chat(od, conn); | |
222 | |
223 g_slist_free(conn->groups); | |
224 flap_connection_destroy_rates(conn->rates); | |
225 | |
226 od->oscar_connections = g_slist_remove(od->oscar_connections, conn); | 225 od->oscar_connections = g_slist_remove(od->oscar_connections, conn); |
227 | |
228 account = gaim_connection_get_account(od->gc); | |
229 | 226 |
230 /* | 227 /* |
231 * TODO: If we don't have a SNAC_FAMILY_LOCATE connection then | 228 * TODO: If we don't have a SNAC_FAMILY_LOCATE connection then |
232 * we should try to request one instead of disconnecting. | 229 * we should try to request one instead of disconnecting. |
233 */ | 230 */ |
234 if (!account->disconnecting && ((od->oscar_connections == NULL) | 231 if (!account->disconnecting && ((od->oscar_connections == NULL) |
235 || (!flap_connection_getbytype(od, SNAC_FAMILY_LOCATE)))) | 232 || (!flap_connection_getbytype(od, SNAC_FAMILY_LOCATE)))) |
236 { | 233 { |
237 /* No more FLAP connections! Sign off this GaimConnection! */ | 234 /* No more FLAP connections! Sign off this GaimConnection! */ |
238 const gchar *tmp; | 235 gchar *tmp; |
239 if (conn->disconnect_reason == OSCAR_DISCONNECT_REMOTE_CLOSED) | 236 if (conn->disconnect_reason == OSCAR_DISCONNECT_REMOTE_CLOSED) |
240 tmp = _("Server closed the connection."); | 237 tmp = g_strdup(_("Server closed the connection.")); |
241 else if (conn->disconnect_reason == OSCAR_DISCONNECT_LOST_CONNECTION) | 238 else if (conn->disconnect_reason == OSCAR_DISCONNECT_LOST_CONNECTION) |
242 tmp = _("Lost connection with server for an unknown reason."); | 239 tmp = g_strdup_printf(_("Lost connection with server:\n%s"), |
240 conn->error_message); | |
243 else if (conn->disconnect_reason == OSCAR_DISCONNECT_INVALID_DATA) | 241 else if (conn->disconnect_reason == OSCAR_DISCONNECT_INVALID_DATA) |
244 tmp = _("Received invalid data on connection with server."); | 242 tmp = g_strdup(_("Received invalid data on connection with server.")); |
245 else if (conn->disconnect_reason == OSCAR_DISCONNECT_COULD_NOT_CONNECT) | 243 else if (conn->disconnect_reason == OSCAR_DISCONNECT_COULD_NOT_CONNECT) |
246 tmp = _("Could not establish a connection with the server."); | 244 tmp = g_strdup_printf(_("Could not establish a connection with the server:\n%s"), |
245 conn->error_message); | |
247 else | 246 else |
248 /* | 247 /* |
249 * We shouldn't print a message for some disconnect_reasons. | 248 * We shouldn't print a message for some disconnect_reasons. |
250 * Like OSCAR_DISCONNECT_LOCAL_CLOSED. | 249 * Like OSCAR_DISCONNECT_LOCAL_CLOSED. |
251 */ | 250 */ |
252 tmp = NULL; | 251 tmp = NULL; |
253 | 252 |
254 if (tmp != NULL) | 253 if (tmp != NULL) |
254 { | |
255 gaim_connection_error(od->gc, tmp); | 255 gaim_connection_error(od->gc, tmp); |
256 } | 256 g_free(tmp); |
257 } | |
258 } | |
259 | |
260 flap_connection_close(od, conn); | |
261 | |
262 g_free(conn->error_message); | |
263 g_free(conn->cookie); | |
264 | |
265 /* | |
266 * Free conn->internal, if necessary | |
267 */ | |
268 if (conn->type == SNAC_FAMILY_CHAT) | |
269 flap_connection_destroy_chat(od, conn); | |
270 | |
271 g_slist_free(conn->groups); | |
272 flap_connection_destroy_rates(conn->rates); | |
257 | 273 |
258 g_free(conn); | 274 g_free(conn); |
259 | 275 |
260 return FALSE; | 276 return FALSE; |
261 } | 277 } |
262 | 278 |
279 /** | |
280 * See the comments for the parameters of | |
281 * flap_connection_schedule_destroy(). | |
282 */ | |
263 void | 283 void |
264 flap_connection_destroy(FlapConnection *conn, OscarDisconnectReason reason) | 284 flap_connection_destroy(FlapConnection *conn, OscarDisconnectReason reason, const gchar *error_message) |
265 { | 285 { |
266 if (conn->destroy_timeout != 0) | 286 if (conn->destroy_timeout != 0) |
267 gaim_timeout_remove(conn->destroy_timeout); | 287 gaim_timeout_remove(conn->destroy_timeout); |
268 conn->disconnect_reason = reason; | 288 conn->disconnect_reason = reason; |
289 g_free(conn->error_message); | |
290 conn->error_message = g_strdup(error_message); | |
269 flap_connection_destroy_cb(conn); | 291 flap_connection_destroy_cb(conn); |
270 } | 292 } |
271 | 293 |
272 /** | 294 /** |
273 * Schedule Gaim to destroy the given FlapConnection as soon as we | 295 * Schedule Gaim to destroy the given FlapConnection as soon as we |
274 * return control back to the program's main loop. We must do this | 296 * return control back to the program's main loop. We must do this |
275 * if we want to destroy the connection but we are still using it | 297 * if we want to destroy the connection but we are still using it |
276 * for some reason. | 298 * for some reason. |
299 * | |
300 * @param reason The reason for the disconnection. | |
301 * @param error_message A brief error message that gives more detail | |
302 * regarding the reason for the disconnecting. This should | |
303 * be NULL for everything except OSCAR_DISCONNECT_LOST_CONNECTION, | |
304 * in which case it should contain the value of strerror(errno), | |
305 * and OSCAR_DISCONNECT_COULD_NOT_CONNECT, in which case it | |
306 * should contain the error_message passed back from the call | |
307 * to gaim_proxy_connect(). | |
277 */ | 308 */ |
278 void | 309 void |
279 flap_connection_schedule_destroy(FlapConnection *conn, OscarDisconnectReason reason) | 310 flap_connection_schedule_destroy(FlapConnection *conn, OscarDisconnectReason reason, const gchar *error_message) |
280 { | 311 { |
281 if (conn->destroy_timeout != 0) | 312 if (conn->destroy_timeout != 0) |
282 /* Already taken care of */ | 313 /* Already taken care of */ |
283 return; | 314 return; |
284 | 315 |
285 gaim_debug_info("oscar", "Scheduling destruction of FLAP " | 316 gaim_debug_info("oscar", "Scheduling destruction of FLAP " |
286 "connection of type 0x%04hx\n", conn->type); | 317 "connection of type 0x%04hx\n", conn->type); |
287 conn->disconnect_reason = reason; | 318 conn->disconnect_reason = reason; |
319 conn->error_message = g_strdup(error_message); | |
288 conn->destroy_timeout = gaim_timeout_add(0, flap_connection_destroy_cb, conn); | 320 conn->destroy_timeout = gaim_timeout_add(0, flap_connection_destroy_cb, conn); |
289 } | 321 } |
290 | 322 |
291 /** | 323 /** |
292 * In OSCAR, every connection has a set of SNAC groups associated | 324 * In OSCAR, every connection has a set of SNAC groups associated |
569 /* Error! */ | 601 /* Error! */ |
570 gaim_debug_warning("oscar", "Expecting FLAP version " | 602 gaim_debug_warning("oscar", "Expecting FLAP version " |
571 "0x00000001 but received FLAP version %08lx. Closing connection.\n", | 603 "0x00000001 but received FLAP version %08lx. Closing connection.\n", |
572 flap_version); | 604 flap_version); |
573 flap_connection_schedule_destroy(conn, | 605 flap_connection_schedule_destroy(conn, |
574 OSCAR_DISCONNECT_INVALID_DATA); | 606 OSCAR_DISCONNECT_INVALID_DATA, NULL); |
575 } | 607 } |
576 else | 608 else |
577 conn->connected = TRUE; | 609 conn->connected = TRUE; |
578 | 610 |
579 } else if (frame->channel == 0x02) { | 611 } else if (frame->channel == 0x02) { |
614 | 646 |
615 /* Check if the FLAP server closed the connection */ | 647 /* Check if the FLAP server closed the connection */ |
616 if (read == 0) | 648 if (read == 0) |
617 { | 649 { |
618 flap_connection_schedule_destroy(conn, | 650 flap_connection_schedule_destroy(conn, |
619 OSCAR_DISCONNECT_REMOTE_CLOSED); | 651 OSCAR_DISCONNECT_REMOTE_CLOSED, NULL); |
620 break; | 652 break; |
621 } | 653 } |
622 | 654 |
623 /* If there was an error then close the connection */ | 655 /* If there was an error then close the connection */ |
624 if (read == -1) | 656 if (read == -1) |
627 /* No worries */ | 659 /* No worries */ |
628 break; | 660 break; |
629 | 661 |
630 /* Error! */ | 662 /* Error! */ |
631 flap_connection_schedule_destroy(conn, | 663 flap_connection_schedule_destroy(conn, |
632 OSCAR_DISCONNECT_LOST_CONNECTION); | 664 OSCAR_DISCONNECT_LOST_CONNECTION, strerror(errno)); |
633 break; | 665 break; |
634 } | 666 } |
635 | 667 |
636 /* If we don't even have a complete FLAP header then do nothing */ | 668 /* If we don't even have a complete FLAP header then do nothing */ |
637 if (read < 6) | 669 if (read < 6) |
642 | 674 |
643 /* All FLAP frames must start with the byte 0x2a */ | 675 /* All FLAP frames must start with the byte 0x2a */ |
644 if (aimutil_get8(&header[0]) != 0x2a) | 676 if (aimutil_get8(&header[0]) != 0x2a) |
645 { | 677 { |
646 flap_connection_schedule_destroy(conn, | 678 flap_connection_schedule_destroy(conn, |
647 OSCAR_DISCONNECT_INVALID_DATA); | 679 OSCAR_DISCONNECT_INVALID_DATA, NULL); |
648 break; | 680 break; |
649 } | 681 } |
650 | 682 |
651 /* Initialize a new temporary FlapFrame for incoming data */ | 683 /* Initialize a new temporary FlapFrame for incoming data */ |
652 conn->buffer_incoming.channel = aimutil_get8(&header[1]); | 684 conn->buffer_incoming.channel = aimutil_get8(&header[1]); |
666 | 698 |
667 /* Check if the FLAP server closed the connection */ | 699 /* Check if the FLAP server closed the connection */ |
668 if (read == 0) | 700 if (read == 0) |
669 { | 701 { |
670 flap_connection_schedule_destroy(conn, | 702 flap_connection_schedule_destroy(conn, |
671 OSCAR_DISCONNECT_REMOTE_CLOSED); | 703 OSCAR_DISCONNECT_REMOTE_CLOSED, NULL); |
672 break; | 704 break; |
673 } | 705 } |
674 | 706 |
675 if (read == -1) | 707 if (read == -1) |
676 { | 708 { |
678 /* No worries */ | 710 /* No worries */ |
679 break; | 711 break; |
680 | 712 |
681 /* Error! */ | 713 /* Error! */ |
682 flap_connection_schedule_destroy(conn, | 714 flap_connection_schedule_destroy(conn, |
683 OSCAR_DISCONNECT_LOST_CONNECTION); | 715 OSCAR_DISCONNECT_LOST_CONNECTION, strerror(errno)); |
684 break; | 716 break; |
685 } | 717 } |
686 | 718 |
687 conn->buffer_incoming.data.offset += read; | 719 conn->buffer_incoming.data.offset += read; |
688 if (conn->buffer_incoming.data.offset < conn->buffer_incoming.data.len) | 720 if (conn->buffer_incoming.data.offset < conn->buffer_incoming.data.len) |
722 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) | 754 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) |
723 /* No worries */ | 755 /* No worries */ |
724 return; | 756 return; |
725 | 757 |
726 /* Error! */ | 758 /* Error! */ |
727 flap_connection_schedule_destroy(conn, OSCAR_DISCONNECT_LOST_CONNECTION); | 759 flap_connection_schedule_destroy(conn, |
760 OSCAR_DISCONNECT_LOST_CONNECTION, strerror(errno)); | |
728 return; | 761 return; |
729 } | 762 } |
730 | 763 |
731 gaim_circ_buffer_mark_read(conn->buffer_outgoing, ret); | 764 gaim_circ_buffer_mark_read(conn->buffer_outgoing, ret); |
732 } | 765 } |