# HG changeset patch
# User Marcus Lundblad <ml@update.uu.se>
# Date 1229127951 0
# Node ID 5d65993761c16135108fb38d0c859316fd8745f4
# Parent  aaff578063d1c2011531c996b20bf2e71e53378e
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.

diff -r aaff578063d1 -r 5d65993761c1 libpurple/protocols/jabber/si.c
--- 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);