gvfs r2091 - in trunk: . daemon
- From: otte svn gnome org
- To: svn-commits-list gnome org
- Subject: gvfs r2091 - in trunk: . daemon
- Date: Mon, 17 Nov 2008 11:11:10 +0000 (UTC)
Author: otte
Date: Mon Nov 17 11:11:09 2008
New Revision: 2091
URL: http://svn.gnome.org/viewvc/gvfs?rev=2091&view=rev
Log:
* daemon/gvfsbackendftp.c:
(ftp_connection_ensure_data_connection_epsv),
(ftp_connection_ensure_data_connection_pasv):
Add workarounds for EPSV/PASV data connection failures.
- don't use EPSV if we get successful return codes but fails to
connect.
- don't use address in PASV response if we fail to connect to it
(use the same address as the command connection is established to).
Modified:
trunk/ChangeLog
trunk/daemon/gvfsbackendftp.c
Modified: trunk/daemon/gvfsbackendftp.c
==============================================================================
--- trunk/daemon/gvfsbackendftp.c (original)
+++ trunk/daemon/gvfsbackendftp.c Mon Nov 17 11:11:09 2008
@@ -107,6 +107,11 @@
FTP_SYSTEM_WINDOWS
} FtpSystem;
+typedef enum {
+ FTP_WORKAROUND_BROKEN_EPSV = (1 << 0),
+ FTP_WORKAROUND_PASV_ADDR = (1 << 1),
+} FtpWorkarounds;
+
struct _GVfsBackendFtp
{
GVfsBackend backend;
@@ -147,6 +152,7 @@
FtpFeatures features;
FtpSystem system;
+ FtpWorkarounds workarounds;
SoupSocket * commands;
gchar * read_buffer;
@@ -816,10 +822,14 @@
guint port;
SoupAddress *addr;
guint status;
+ gboolean connected;
if ((conn->features & FTP_FEATURE_EPSV) == 0)
return FALSE;
+ if (conn->workarounds & FTP_WORKAROUND_BROKEN_EPSV)
+ return FALSE;
+
status = ftp_connection_send (conn, RESPONSE_PASS_500, "EPSV");
if (STATUS_GROUP (status) != 2)
return FALSE;
@@ -837,15 +847,22 @@
soup_address_get_name (soup_socket_get_remote_address (conn->commands)),
port);
- return ftp_connection_open_data_connection (conn, addr);
+ connected = ftp_connection_open_data_connection (conn, addr);
+ if (!connected)
+ {
+ DEBUG ("Successful EPSV response code, but data connection failed. Enabling FTP_WORKAROUND_BROKEN_EPSV.\n");
+ conn->workarounds |= FTP_WORKAROUND_BROKEN_EPSV;
+ g_clear_error (&conn->error);
+ }
+ return connected;
}
static gboolean
ftp_connection_ensure_data_connection_pasv (FtpConnection *conn)
{
guint ip1, ip2, ip3, ip4, port1, port2;
- char *ip;
const char *s;
+ gboolean connected;
SoupAddress *addr;
guint status;
@@ -860,8 +877,8 @@
for (s = conn->read_buffer; *s; s++)
{
if (sscanf (s, "%u,%u,%u,%u,%u,%u",
- &ip1, &ip2, &ip3, &ip4,
- &port1, &port2) == 6)
+ &ip1, &ip2, &ip3, &ip4,
+ &port1, &port2) == 6)
break;
}
if (*s == 0)
@@ -871,10 +888,33 @@
return FALSE;
}
- ip = g_strdup_printf ("%u.%u.%u.%u", ip1, ip2, ip3, ip4);
- addr = soup_address_new (ip, port1 << 8 | port2);
- g_free (ip);
+ if (!(conn->workarounds & FTP_WORKAROUND_PASV_ADDR))
+ {
+ char *ip;
+
+ ip = g_strdup_printf ("%u.%u.%u.%u", ip1, ip2, ip3, ip4);
+ addr = soup_address_new (ip, port1 << 8 | port2);
+ g_free (ip);
+ connected = ftp_connection_open_data_connection (conn, addr);
+ if (!connected)
+ {
+ /* set workaround flag (see below), so we don't try this again */
+ DEBUG ("Successfull PASV response but data connection failed. Enabling FTP_WORKAROUND_PASV_ADDR.\n");
+ conn->workarounds |= FTP_WORKAROUND_PASV_ADDR;
+ g_clear_error (&conn->error);
+ }
+ }
+
+ /* Workaround code:
+ * Various ftp servers aren;t setup correctly when behind a NAT. They report
+ * their own IP address (like 10.0.0.4) and not the address in front of the
+ * NAT. But this is likely the same address that we connected to with our
+ * command connetion. So if the address given by PASV fails, we fall back
+ * to the address of the command stream.
+ */
+ addr = soup_address_new (soup_address_get_name (soup_socket_get_remote_address (conn->commands)),
+ port1 << 8 | port2);
return ftp_connection_open_data_connection (conn, addr);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]