# HG changeset patch # User Daniel Atallah # Date 1213845133 0 # Node ID 3c33405fd63096dc9cdd30e0233dd2f56b2ff23c # Parent f47438e456c207d034a87af3dbf9375b837b5b8d applied changes from 904a276588f7de13ba13b578905c82c0493184ce through 5dec4714953825272bec5164be3761db1d7fdc9a diff -r f47438e456c2 -r 3c33405fd630 libpurple/protocols/jabber/si.c --- a/libpurple/protocols/jabber/si.c Thu Jun 19 03:11:47 2008 +0000 +++ b/libpurple/protocols/jabber/si.c Thu Jun 19 03:12:13 2008 +0000 @@ -63,6 +63,7 @@ char *rxqueue; size_t rxlen; gsize rxmaxlen; + int local_streamhost_fd; } JabberSIXfer; static PurpleXfer* @@ -347,7 +348,11 @@ g_free(jsx->rxqueue); jsx->rxqueue = NULL; - purple_xfer_start(xfer, source, NULL, -1); + /* Before actually starting sending the file, we need to wait until the + * recipient sends the IQ result with + */ + purple_debug_info("jabber", "SOCKS5 connection negotiation completed. " + "Waiting for IQ result to start file transfer.\n"); } static void @@ -608,6 +613,7 @@ PurpleInputCondition cond) { PurpleXfer *xfer = data; + JabberSIXfer *jsx = xfer->data; int acceptfd; purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_connected_cb\n"); @@ -623,6 +629,7 @@ purple_input_remove(xfer->watcher); close(source); + jsx->local_streamhost_fd = -1; xfer->watcher = purple_input_add(acceptfd, PURPLE_INPUT_READ, jabber_si_xfer_bytestreams_send_read_cb, xfer); @@ -633,17 +640,25 @@ gpointer data) { PurpleXfer *xfer = data; - JabberSIXfer *jsx = xfer->data; + JabberSIXfer *jsx; xmlnode *query, *streamhost_used; const char *from, *type, *jid; GList *matched; /* TODO: This need to send errors if we don't see what we're looking for */ + /* Make sure that the xfer is actually still valid and we're not just receiving an old iq response */ + if (!g_list_find(js->file_transfers, xfer)) { + purple_debug_error("jabber", "Got bytestreams response for no longer existing xfer (%p)\n", xfer); + return; + } + /* In the case of a direct file transfer, this is expected to return */ - if(!jsx) + if(!xfer->data) return; + jsx = xfer->data; + if(!(type = xmlnode_get_attrib(packet, "type")) || strcmp(type, "result")) return; @@ -659,22 +674,33 @@ if(!(jid = xmlnode_get_attrib(streamhost_used, "jid"))) return; - purple_debug_info("jabber", "jabber_si_connect_proxy_cb() will be looking at jsx %p: jsx->streamhosts is %p and jid is %p", + purple_debug_info("jabber", "jabber_si_connect_proxy_cb() will be looking at jsx %p: jsx->streamhosts is %p and jid is %s\n", jsx, jsx->streamhosts, jid); if(!(matched = g_list_find_custom(jsx->streamhosts, jid, jabber_si_compare_jid))) { gchar *my_jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node, jsx->js->user->domain, jsx->js->user->resource); - if (!strcmp(jid, my_jid)) + if (!strcmp(jid, my_jid)) { purple_debug_info("jabber", "Got local SOCKS5 streamhost-used.\n"); - else + purple_xfer_start(xfer, xfer->fd, NULL, -1); + } else { purple_debug_info("jabber", "streamhost-used does not match any proxy that was offered to target\n"); + purple_xfer_cancel_local(xfer); + } g_free(my_jid); return; } - /* TODO: Clean up the local SOCKS5 proxy - it isn't going to be used.*/ + /* Clean up the local streamhost - it isn't going to be used.*/ + if (xfer->watcher > 0) { + purple_input_remove(xfer->watcher); + xfer->watcher = 0; + } + if (jsx->local_streamhost_fd >= 0) { + close(jsx->local_streamhost_fd); + jsx->local_streamhost_fd = -1; + } jsx->streamhosts = g_list_remove_link(jsx->streamhosts, matched); g_list_foreach(jsx->streamhosts, jabber_si_free_streamhost, NULL); @@ -712,6 +738,8 @@ return; } + jsx->local_streamhost_fd = sock; + iq = jabber_iq_new_query(jsx->js, JABBER_IQ_SET, "http://jabber.org/protocol/bytestreams"); xmlnode_set_attrib(iq->node, "to", xfer->who); @@ -956,7 +984,8 @@ purple_network_listen_cancel(jsx->listen_data); if (jsx->iq_id != NULL) jabber_iq_remove_callback_by_id(js, jsx->iq_id); - + if (jsx->local_streamhost_fd >= 0) + close(jsx->local_streamhost_fd); if (jsx->connect_timeout > 0) purple_timeout_remove(jsx->connect_timeout); @@ -1164,6 +1193,7 @@ { xfer->data = jsx = g_new0(JabberSIXfer, 1); jsx->js = js; + jsx->local_streamhost_fd = -1; purple_xfer_set_init_fnc(xfer, jabber_si_xfer_init); purple_xfer_set_cancel_send_fnc(xfer, jabber_si_xfer_cancel_send); @@ -1237,6 +1267,7 @@ return; jsx = g_new0(JabberSIXfer, 1); + jsx->local_streamhost_fd = -1; for(field = xmlnode_get_child(x, "field"); field; field = xmlnode_get_next_twin(field)) { const char *var = xmlnode_get_attrib(field, "var");