pidgin: 7777eca0: Improve error handling for xmpp file tra...
datallah at pidgin.im
datallah at pidgin.im
Fri Jun 13 23:25:39 EDT 2008
-----------------------------------------------------------------
Revision: 7777eca09d173823e2c26e8363ec73fffc6035b9
Ancestor: 78904b4aec8280b63f8a2cae39f10b8edf53ae8d
Author: datallah at pidgin.im
Date: 2008-06-14T03:20:19
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/7777eca09d173823e2c26e8363ec73fffc6035b9
Modified files:
libpurple/protocols/jabber/si.c
ChangeLog:
Improve error handling for xmpp file transfers.
-------------- next part --------------
============================================================
--- libpurple/protocols/jabber/si.c b22d4c91a87feb627c5acb261f349cf2bb77f9d4
+++ libpurple/protocols/jabber/si.c 3a82e5902038877892223bc1b5164303625dc9cf
@@ -623,7 +623,7 @@ jabber_si_xfer_bytestreams_send_connecte
return;
else if(acceptfd == -1) {
purple_debug_warning("jabber", "accept: %s\n", g_strerror(errno));
- /* TODO: This should cancel the ft */
+ /* Don't cancel the ft - allow it to fall to the next streamhost.*/
return;
}
@@ -659,8 +659,11 @@ jabber_si_connect_proxy_cb(JabberStream
jsx = xfer->data;
- if(!(type = xmlnode_get_attrib(packet, "type")) || strcmp(type, "result"))
+ if(!(type = xmlnode_get_attrib(packet, "type")) || strcmp(type, "result")) {
+ if (type && !strcmp(type, "error"))
+ purple_xfer_cancel_remote(xfer);
return;
+ }
if(!(from = xmlnode_get_attrib(packet, "from")))
return;
@@ -718,14 +721,17 @@ jabber_si_xfer_bytestreams_listen_cb(int
JabberSIXfer *jsx;
JabberIq *iq;
xmlnode *query, *streamhost;
- char *jid, port[6];
- const char *local_ip, *public_ip, *ft_proxies;
+ const char *ft_proxies;
+ char port[6];
GList *tmp;
JabberBytestreamsStreamhost *sh, *sh2;
+ int streamhost_count = 0;
jsx = xfer->data;
jsx->listen_data = NULL;
+ /* I'm not sure under which conditions this can happen
+ * (it seems like it shouldn't be possible */
if (purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL) {
purple_xfer_unref(xfer);
return;
@@ -733,13 +739,6 @@ jabber_si_xfer_bytestreams_listen_cb(int
purple_xfer_unref(xfer);
- if (sock < 0) {
- purple_xfer_cancel_local(xfer);
- 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);
@@ -747,41 +746,45 @@ jabber_si_xfer_bytestreams_listen_cb(int
xmlnode_set_attrib(query, "sid", jsx->stream_id);
- jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node,
+ /* If we successfully started listening locally */
+ if (sock >= 0) {
+ gchar *jid;
+ const char *local_ip, *public_ip;
+
+ jsx->local_streamhost_fd = sock;
+
+ jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node,
jsx->js->user->domain, jsx->js->user->resource);
- xfer->local_port = purple_network_get_port_from_fd(sock);
- g_snprintf(port, sizeof(port), "%hu", xfer->local_port);
+ xfer->local_port = purple_network_get_port_from_fd(sock);
+ g_snprintf(port, sizeof(port), "%hu", xfer->local_port);
- /* TODO: Should there be an option to not use the local host as a ft proxy?
- * (to prevent revealing IP address, etc.) */
+ /* Include the localhost's IP (for in-network transfers) */
+ local_ip = purple_network_get_local_system_ip(jsx->js->fd);
+ if (strcmp(local_ip, "0.0.0.0") != 0) {
+ streamhost_count++;
+ streamhost = xmlnode_new_child(query, "streamhost");
+ xmlnode_set_attrib(streamhost, "jid", jid);
+ xmlnode_set_attrib(streamhost, "host", local_ip);
+ xmlnode_set_attrib(streamhost, "port", port);
+ }
- /* Include the localhost's IP (for in-network transfers) */
- local_ip = purple_network_get_local_system_ip(jsx->js->fd);
- if (strcmp(local_ip, "0.0.0.0") != 0)
- {
- streamhost = xmlnode_new_child(query, "streamhost");
- xmlnode_set_attrib(streamhost, "jid", jid);
- xmlnode_set_attrib(streamhost, "host", local_ip);
- xmlnode_set_attrib(streamhost, "port", port);
- }
+ /* Include the public IP (assuming that there is a port mapped somehow) */
+ public_ip = purple_network_get_my_ip(jsx->js->fd);
+ if (strcmp(public_ip, local_ip) != 0 && strcmp(public_ip, "0.0.0.0") != 0) {
+ streamhost_count++;
+ streamhost = xmlnode_new_child(query, "streamhost");
+ xmlnode_set_attrib(streamhost, "jid", jid);
+ xmlnode_set_attrib(streamhost, "host", public_ip);
+ xmlnode_set_attrib(streamhost, "port", port);
+ }
- /* Include the public IP (assuming that there is a port mapped somehow) */
- /* TODO: Check that it isn't the same as above and is a valid IP */
- public_ip = purple_network_get_my_ip(jsx->js->fd);
- if (strcmp(public_ip, local_ip) != 0)
- {
- streamhost = xmlnode_new_child(query, "streamhost");
- xmlnode_set_attrib(streamhost, "jid", jid);
- xmlnode_set_attrib(streamhost, "host", public_ip);
- xmlnode_set_attrib(streamhost, "port", port);
+ g_free(jid);
+
+ /* The listener for the local proxy */
+ xfer->watcher = purple_input_add(sock, PURPLE_INPUT_READ,
+ jabber_si_xfer_bytestreams_send_connected_cb, xfer);
}
- g_free(jid);
-
- /* The listener for the local proxy */
- xfer->watcher = purple_input_add(sock, PURPLE_INPUT_READ,
- jabber_si_xfer_bytestreams_send_connected_cb, xfer);
-
/* insert proxies here */
ft_proxies = purple_account_get_string(xfer->account, "ft_proxies", NULL);
if (ft_proxies) {
@@ -811,6 +814,7 @@ jabber_si_xfer_bytestreams_listen_cb(int
if(g_list_find_custom(jsx->streamhosts, ft_proxy_list[i], jabber_si_compare_jid) != NULL)
continue;
+ streamhost_count++;
streamhost = xmlnode_new_child(query, "streamhost");
xmlnode_set_attrib(streamhost, "jid", ft_proxy_list[i]);
xmlnode_set_attrib(streamhost, "host", ft_proxy_list[i]);
@@ -840,6 +844,7 @@ jabber_si_xfer_bytestreams_listen_cb(int
if(g_list_find_custom(jsx->streamhosts, sh->jid, jabber_si_compare_jid) != NULL)
continue;
+ streamhost_count++;
streamhost = xmlnode_new_child(query, "streamhost");
xmlnode_set_attrib(streamhost, "jid", sh->jid);
xmlnode_set_attrib(streamhost, "host", sh->host);
@@ -855,6 +860,14 @@ jabber_si_xfer_bytestreams_listen_cb(int
jsx->streamhosts = g_list_prepend(jsx->streamhosts, sh2);
}
+ /* We have no way of transferring, cancel the transfer */
+ if (streamhost_count == 0) {
+ jabber_iq_free(iq);
+ /* We should probably notify the target, but this really shouldn't ever happen */
+ purple_xfer_cancel_local(xfer);
+ return;
+ }
+
jabber_iq_set_callback(iq, jabber_si_connect_proxy_cb, xfer);
jabber_iq_send(iq);
@@ -869,13 +882,14 @@ jabber_si_xfer_bytestreams_send_init(Pur
purple_xfer_ref(xfer);
jsx = xfer->data;
+
+ /* TODO: Should there be an option to not use the local host as a ft proxy?
+ * (to prevent revealing IP address, etc.) */
jsx->listen_data = purple_network_listen_range(0, 0, SOCK_STREAM,
jabber_si_xfer_bytestreams_listen_cb, xfer);
if (jsx->listen_data == NULL) {
- purple_xfer_unref(xfer);
- /* XXX: couldn't open a port, we're fscked */
- purple_xfer_cancel_local(xfer);
- return;
+ /* We couldn't open a local port. Perhaps we can use a proxy. */
+ jabber_si_xfer_bytestreams_listen_cb(-1, xfer);
}
}
More information about the Commits
mailing list