changeset 25750:5d65993761c1

Add timeout when receiver waits for initiator to open an IBB session This should prevent file transfers from stalling if the the receiver doesn't open an IBB session.
author Marcus Lundblad <ml@update.uu.se>
date Sat, 13 Dec 2008 00:25:51 +0000
parents aaff578063d1
children d7cdbee6d9be
files libpurple/protocols/jabber/si.c
diffstat 1 files changed, 33 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/jabber/si.c	Tue Dec 09 20:31:12 2008 +0000
+++ b/libpurple/protocols/jabber/si.c	Sat Dec 13 00:25:51 2008 +0000
@@ -186,6 +186,22 @@
 	return FALSE;
 }
 
+static gboolean
+jabber_si_bytestreams_ibb_timeout_cb(gpointer data)
+{
+	PurpleXfer *xfer = (PurpleXfer *) data;
+	JabberSIXfer *jsx = xfer->data;
+	
+	if (!jsx->ibb_session) {
+		purple_debug_info("jabber", 
+			"jabber_si_bytestreams_ibb_timeout called and IBB session not set "
+			" up yet, cancel transfer");
+		purple_xfer_cancel_local(xfer);
+	}
+	
+	return FALSE;
+}
+
 static void jabber_si_bytestreams_attempt_connect(PurpleXfer *xfer)
 {
 	JabberSIXfer *jsx = xfer->data;
@@ -223,6 +239,10 @@
 			if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND
 				&& !jsx->ibb_session) {
 				jabber_si_xfer_ibb_send_init(jsx->js, xfer);
+			} else {
+				/* setup a timeout to cancel waiting for IBB open */
+				purple_timeout_add_seconds(30, 
+					jabber_si_bytestreams_ibb_timeout_cb, xfer);
 			}
 			/* if we are the receiver, just wait for IBB open, callback is
 			  already set up... */
@@ -706,6 +726,9 @@
 				if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND
 					&& !jsx->ibb_session) {
 					jabber_si_xfer_ibb_send_init(js, xfer);
+				} else {
+					purple_timeout_add_seconds(30,
+						jabber_si_bytestreams_ibb_timeout_cb, xfer);
 				}
 				/* if we are receiver, just wait for IBB open stanza, callback
 				  is already set up */
@@ -745,6 +768,9 @@
 					"jabber_si_connect_proxy_cb: trying to revert to IBB\n");
 				if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
 					jabber_si_xfer_ibb_send_init(jsx->js, xfer);
+				} else {
+					purple_timeout_add_seconds(30,
+						jabber_si_bytestreams_ibb_timeout_cb, xfer);
 				}
 				/* if we are the receiver, we are already set up...*/
 			} else {
@@ -886,6 +912,9 @@
 			if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
 				/* if we are the sender, init the IBB session... */
 				jabber_si_xfer_ibb_send_init(jsx->js, xfer);
+			} else {
+				purple_timeout_add_seconds(30,
+					jabber_si_bytestreams_ibb_timeout_cb, xfer);
 			}
 			/* if we are the receiver, we should just wait... the IBB open
 			  handler has already been set up... */
@@ -1231,6 +1260,8 @@
 	field = xmlnode_new_child(x, "field");
 	xmlnode_set_attrib(field, "var", "stream-method");
 	xmlnode_set_attrib(field, "type", "list-single");
+	/* maybe we should add an option to always skip bytestreams for people
+		behind troublesome firewalls */
 	option = xmlnode_new_child(field, "option");
 	value = xmlnode_new_child(option, "value");
 	xmlnode_insert_data(value, "http://jabber.org/protocol/bytestreams", -1);
@@ -1479,6 +1510,8 @@
 		/* we should maybe "remember" if bytestreams has failed before (in the
 			same session) with this JID, and only present IBB as an option to
 			avoid unnessesary timeout */
+		/* maybe we should have an account option to always just try IBB
+			for people who know their firewalls are very restrictive */
 		if (jsx->stream_method & STREAM_METHOD_BYTESTREAMS) {
 			value = xmlnode_new_child(field, "value");
 			xmlnode_insert_data(value, "http://jabber.org/protocol/bytestreams", -1);