static PurpleXmlNode * jabber_bosh_connection_parse(PurpleJabberBOSHConnection *conn, PurpleHttpResponse *response) { PurpleXmlNode *root; const gchar *data; size_t data_len; const gchar *type; g_return_val_if_fail(conn != NULL, NULL); g_return_val_if_fail(response != NULL, NULL); if (conn->is_terminating || purple_account_is_disconnecting( purple_connection_get_account(conn->js->gc))) { return NULL; } if (!purple_http_response_is_successful(response)) { purple_connection_error(conn->js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); return NULL; } data = purple_http_response_get_data(response, &data_len); root = purple_xmlnode_from_str(data, data_len); type = purple_xmlnode_get_attrib(root, "type"); if (g_strcmp0(type, "terminate") == 0) { purple_connection_error(conn->js->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("The BOSH " "connection manager terminated your session.")); purple_xmlnode_free(root); return NULL; } return root; }
static gboolean flap_connection_destroy_cb(gpointer data) { FlapConnection *conn; OscarData *od; PurpleAccount *account; aim_rxcallback_t userfunc; conn = data; /* Explicitly added for debugging #5927. Don't re-order this, only * consider removing it. */ purple_debug_info("oscar", "Destroying FLAP connection %p\n", conn); od = conn->od; account = purple_connection_get_account(od->gc); purple_debug_info("oscar", "Destroying oscar connection (%p) of " "type 0x%04hx. Disconnect reason is %d\n", conn, conn->type, conn->disconnect_reason); od->oscar_connections = g_slist_remove(od->oscar_connections, conn); if ((userfunc = aim_callhandler(od, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR))) userfunc(od, conn, NULL, conn->disconnect_code, conn->error_message); /* * TODO: If we don't have a SNAC_FAMILY_LOCATE connection then * we should try to request one instead of disconnecting. */ if (!purple_account_is_disconnecting(account) && ((od->oscar_connections == NULL) || (!flap_connection_getbytype(od, SNAC_FAMILY_LOCATE)))) { /* No more FLAP connections! Sign off this PurpleConnection! */ gchar *tmp; PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR; if (conn->disconnect_code == 0x0001) { reason = PURPLE_CONNECTION_ERROR_NAME_IN_USE; tmp = g_strdup(_("You have signed on from another location")); if (!purple_account_get_remember_password(account)) purple_account_set_password(account, NULL, NULL, NULL); } else if (conn->disconnect_reason == OSCAR_DISCONNECT_REMOTE_CLOSED) tmp = g_strdup(_("Server closed the connection")); else if (conn->disconnect_reason == OSCAR_DISCONNECT_LOST_CONNECTION) tmp = g_strdup_printf(_("Lost connection with server: %s"), conn->error_message); else if (conn->disconnect_reason == OSCAR_DISCONNECT_INVALID_DATA) tmp = g_strdup(_("Received invalid data on connection with server")); else if (conn->disconnect_reason == OSCAR_DISCONNECT_COULD_NOT_CONNECT) tmp = g_strdup_printf(_("Unable to connect: %s"), conn->error_message); else /* * We shouldn't print a message for some disconnect_reasons. * Like OSCAR_DISCONNECT_LOCAL_CLOSED. */ tmp = NULL; if (tmp != NULL) { purple_connection_error(od->gc, reason, tmp); g_free(tmp); } } flap_connection_close(od, conn); g_free(conn->error_message); g_free(conn->cookie); /* * Free conn->internal, if necessary */ if (conn->type == SNAC_FAMILY_CHAT) flap_connection_destroy_chat(od, conn); g_slist_free(conn->groups); while (conn->rateclasses != NULL) { g_free(conn->rateclasses->data); conn->rateclasses = g_slist_delete_link(conn->rateclasses, conn->rateclasses); } g_hash_table_destroy(conn->rateclass_members); if (conn->queued_snacs) { while (!g_queue_is_empty(conn->queued_snacs)) { QueuedSnac *queued_snac; queued_snac = g_queue_pop_head(conn->queued_snacs); flap_frame_destroy(queued_snac->frame); g_free(queued_snac); } g_queue_free(conn->queued_snacs); } if (conn->queued_lowpriority_snacs) { while (!g_queue_is_empty(conn->queued_lowpriority_snacs)) { QueuedSnac *queued_snac; queued_snac = g_queue_pop_head(conn->queued_lowpriority_snacs); flap_frame_destroy(queued_snac->frame); g_free(queued_snac); } g_queue_free(conn->queued_lowpriority_snacs); } if (conn->queued_timeout > 0) purple_timeout_remove(conn->queued_timeout); g_free(conn); return FALSE; }
static void skypeweb_attempt_connection(SkypeWebConnection *skypewebcon) { gboolean is_proxy = FALSE; SkypeWebAccount *sa = skypewebcon->sa; PurpleProxyInfo *proxy_info = NULL; if (sa && sa->account && !(skypewebcon->method & SKYPEWEB_METHOD_SSL)) { proxy_info = purple_proxy_get_setup(sa->account); if (purple_proxy_info_get_proxy_type(proxy_info) == PURPLE_PROXY_USE_GLOBAL) proxy_info = purple_global_proxy_get_info(); if (purple_proxy_info_get_proxy_type(proxy_info) == PURPLE_PROXY_HTTP) { is_proxy = TRUE; } } #if 0 /* Connection to attempt retries. This code doesn't work perfectly, but * remains here for future reference if needed */ if (time(NULL) - skypewebcon->request_time > 5) { /* We've continuously tried to remake this connection for a * bit now. It isn't happening, sadly. Time to die. */ purple_debug_error("skypeweb", "could not connect after retries\n"); skypeweb_fatal_connection_cb(skypewebcon); return; } purple_debug_info("skypeweb", "making connection attempt\n"); /* TODO: If we're retrying the connection, consider clearing the cached * DNS value. This will require some juggling with the hostname param */ /* TODO/FIXME: This retries almost instantenously, which in some cases * runs at blinding speed. Slow it down. */ /* TODO/FIXME: this doesn't retry properly on non-ssl connections */ #endif sa->conns = g_slist_prepend(sa->conns, skypewebcon); /* * Do a separate DNS lookup for the given host name and cache it * for next time. * * TODO: It would be better if we did this before we call * purple_proxy_connect(), so we could re-use the result. * Or even better: Use persistent HTTP connections for servers * that we access continually. * * TODO: This cache of the hostname<-->IP address does not respect * the TTL returned by the DNS server. We should expire things * from the cache after some amount of time. */ if (!is_proxy && !(skypewebcon->method & SKYPEWEB_METHOD_SSL) && !g_hostname_is_ip_address(skypewebcon->hostname)) { /* Don't do this for proxy connections, since proxies do the DNS lookup */ gchar *host_ip; host_ip = g_hash_table_lookup(sa->hostname_ip_cache, skypewebcon->hostname); if (host_ip != NULL) { g_free(skypewebcon->hostname); skypewebcon->hostname = g_strdup(host_ip); } else if (sa->account && !purple_account_is_disconnecting(sa->account)) { GSList *host_lookup_list = NULL; PurpleDnsQueryData *query; host_lookup_list = g_slist_prepend( host_lookup_list, g_strdup(skypewebcon->hostname)); host_lookup_list = g_slist_prepend( host_lookup_list, sa); query = purple_dnsquery_a( #if PURPLE_VERSION_CHECK(3, 0, 0) skypewebcon->sa->account, #endif skypewebcon->hostname, 80, skypeweb_host_lookup_cb, host_lookup_list); sa->dns_queries = g_slist_prepend(sa->dns_queries, query); host_lookup_list = g_slist_append(host_lookup_list, query); } } if (skypewebcon->method & SKYPEWEB_METHOD_SSL) { skypewebcon->ssl_conn = purple_ssl_connect(sa->account, skypewebcon->hostname, 443, skypeweb_post_or_get_ssl_connect_cb, skypeweb_ssl_connection_error, skypewebcon); } else { skypewebcon->connect_data = purple_proxy_connect(NULL, sa->account, skypewebcon->hostname, 80, skypeweb_post_or_get_connect_cb, skypewebcon); } skypewebcon->timeout_watcher = purple_timeout_add_seconds(120, skypeweb_connection_timedout, skypewebcon); return; }