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 }