summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Brown2009-03-30 14:24:56 +0200
committerMichael Brown2009-03-30 14:24:56 +0200
commit323cdf8c4c510fc6da081b96994d0131c11a29dd (patch)
tree268806d5d1de34a96a446356a065057b060c7282 /src
parent[bzimage] Support old (pre-2.00 bootloader) Linux kernel formats (diff)
downloadipxe-323cdf8c4c510fc6da081b96994d0131c11a29dd.tar.gz
ipxe-323cdf8c4c510fc6da081b96994d0131c11a29dd.tar.xz
ipxe-323cdf8c4c510fc6da081b96994d0131c11a29dd.zip
[xfer] Implement xfer_vreopen() to properly handle redirections
When handling a redirection event, we need to close the existing connection before opening the new connection.
Diffstat (limited to 'src')
-rw-r--r--src/arch/i386/interface/pxe/pxe_tftp.c2
-rw-r--r--src/core/downloader.c2
-rw-r--r--src/core/open.c28
-rw-r--r--src/core/posix_io.c2
-rw-r--r--src/include/gpxe/open.h2
-rw-r--r--src/net/tcp/ftp.c4
-rw-r--r--src/net/tcp/http.c2
-rw-r--r--src/net/tcp/iscsi.c2
-rw-r--r--src/net/tls.c2
-rw-r--r--src/net/udp/dhcp.c2
-rw-r--r--src/net/udp/dns.c2
-rw-r--r--src/net/udp/slam.c4
-rw-r--r--src/net/udp/tftp.c4
13 files changed, 44 insertions, 14 deletions
diff --git a/src/arch/i386/interface/pxe/pxe_tftp.c b/src/arch/i386/interface/pxe/pxe_tftp.c
index 715a0b61e..cc7f830a3 100644
--- a/src/arch/i386/interface/pxe/pxe_tftp.c
+++ b/src/arch/i386/interface/pxe/pxe_tftp.c
@@ -138,7 +138,7 @@ static void pxe_tftp_xfer_close ( struct xfer_interface *xfer __unused,
static struct xfer_interface_operations pxe_tftp_xfer_ops = {
.close = pxe_tftp_xfer_close,
- .vredirect = xfer_vopen,
+ .vredirect = xfer_vreopen,
.window = unlimited_xfer_window,
.alloc_iob = default_xfer_alloc_iob,
.deliver_iob = pxe_tftp_xfer_deliver_iob,
diff --git a/src/core/downloader.c b/src/core/downloader.c
index 0a443db23..83027d388 100644
--- a/src/core/downloader.c
+++ b/src/core/downloader.c
@@ -205,7 +205,7 @@ static void downloader_xfer_close ( struct xfer_interface *xfer, int rc ) {
/** Downloader data transfer interface operations */
static struct xfer_interface_operations downloader_xfer_operations = {
.close = downloader_xfer_close,
- .vredirect = xfer_vopen,
+ .vredirect = xfer_vreopen,
.window = unlimited_xfer_window,
.alloc_iob = default_xfer_alloc_iob,
.deliver_iob = downloader_xfer_deliver_iob,
diff --git a/src/core/open.c b/src/core/open.c
index 89a96d72e..beb67a037 100644
--- a/src/core/open.c
+++ b/src/core/open.c
@@ -53,6 +53,8 @@ int xfer_open_uri ( struct xfer_interface *xfer, struct uri *uri ) {
/* Find opener which supports this URI scheme */
for_each_table_entry ( opener, URI_OPENERS ) {
if ( strcmp ( resolved_uri->scheme, opener->scheme ) == 0 ) {
+ DBGC ( xfer, "XFER %p opening %s URI\n",
+ xfer, opener->scheme );
rc = opener->open ( xfer, resolved_uri );
goto done;
}
@@ -170,3 +172,29 @@ int xfer_open ( struct xfer_interface *xfer, int type, ... ) {
va_end ( args );
return rc;
}
+
+/**
+ * Reopen location
+ *
+ * @v xfer Data transfer interface
+ * @v type Location type
+ * @v args Remaining arguments depend upon location type
+ * @ret rc Return status code
+ *
+ * This will close the existing connection and open a new connection
+ * using xfer_vopen(). It is intended to be used as a .vredirect
+ * method handler.
+ */
+int xfer_vreopen ( struct xfer_interface *xfer, int type, va_list args ) {
+ struct xfer_interface_operations *op = xfer->op;
+
+ /* Close existing connection */
+ xfer_nullify ( xfer );
+ xfer_close ( xfer, 0 );
+
+ /* Restore to operational status */
+ xfer->op = op;
+
+ /* Open new location */
+ return xfer_vopen ( xfer, type, args );
+}
diff --git a/src/core/posix_io.c b/src/core/posix_io.c
index e0459bdf1..6f6d815ac 100644
--- a/src/core/posix_io.c
+++ b/src/core/posix_io.c
@@ -137,7 +137,7 @@ posix_file_xfer_deliver_iob ( struct xfer_interface *xfer,
/** POSIX file data transfer interface operations */
static struct xfer_interface_operations posix_file_xfer_operations = {
.close = posix_file_xfer_close,
- .vredirect = xfer_vopen,
+ .vredirect = xfer_vreopen,
.window = unlimited_xfer_window,
.alloc_iob = default_xfer_alloc_iob,
.deliver_iob = posix_file_xfer_deliver_iob,
diff --git a/src/include/gpxe/open.h b/src/include/gpxe/open.h
index 61fb0ef51..136ff87f8 100644
--- a/src/include/gpxe/open.h
+++ b/src/include/gpxe/open.h
@@ -97,5 +97,7 @@ extern int xfer_open_socket ( struct xfer_interface *xfer, int semantics,
struct sockaddr *peer, struct sockaddr *local );
extern int xfer_vopen ( struct xfer_interface *xfer, int type, va_list args );
extern int xfer_open ( struct xfer_interface *xfer, int type, ... );
+extern int xfer_vreopen ( struct xfer_interface *xfer, int type,
+ va_list args );
#endif /* _GPXE_OPEN_H */
diff --git a/src/net/tcp/ftp.c b/src/net/tcp/ftp.c
index 445e32bb4..0719bf728 100644
--- a/src/net/tcp/ftp.c
+++ b/src/net/tcp/ftp.c
@@ -335,7 +335,7 @@ static int ftp_control_deliver_raw ( struct xfer_interface *control,
/** FTP control channel operations */
static struct xfer_interface_operations ftp_control_operations = {
.close = ftp_control_close,
- .vredirect = xfer_vopen,
+ .vredirect = xfer_vreopen,
.window = unlimited_xfer_window,
.alloc_iob = default_xfer_alloc_iob,
.deliver_iob = xfer_deliver_as_raw,
@@ -402,7 +402,7 @@ static int ftp_data_deliver_iob ( struct xfer_interface *data,
/** FTP data channel operations */
static struct xfer_interface_operations ftp_data_operations = {
.close = ftp_data_closed,
- .vredirect = xfer_vopen,
+ .vredirect = xfer_vreopen,
.window = unlimited_xfer_window,
.alloc_iob = default_xfer_alloc_iob,
.deliver_iob = ftp_data_deliver_iob,
diff --git a/src/net/tcp/http.c b/src/net/tcp/http.c
index 93ccfd3bd..b7cbea465 100644
--- a/src/net/tcp/http.c
+++ b/src/net/tcp/http.c
@@ -464,7 +464,7 @@ static void http_socket_close ( struct xfer_interface *socket, int rc ) {
/** HTTP socket operations */
static struct xfer_interface_operations http_socket_operations = {
.close = http_socket_close,
- .vredirect = xfer_vopen,
+ .vredirect = xfer_vreopen,
.window = unlimited_xfer_window,
.alloc_iob = default_xfer_alloc_iob,
.deliver_iob = http_socket_deliver_iob,
diff --git a/src/net/tcp/iscsi.c b/src/net/tcp/iscsi.c
index 45519e667..51c2beeaa 100644
--- a/src/net/tcp/iscsi.c
+++ b/src/net/tcp/iscsi.c
@@ -1514,7 +1514,7 @@ static int iscsi_vredirect ( struct xfer_interface *socket, int type,
va_end ( tmp );
}
- return xfer_vopen ( socket, type, args );
+ return xfer_vreopen ( socket, type, args );
}
diff --git a/src/net/tls.c b/src/net/tls.c
index 73f9ad062..25f18f79b 100644
--- a/src/net/tls.c
+++ b/src/net/tls.c
@@ -1625,7 +1625,7 @@ static int tls_cipherstream_deliver_raw ( struct xfer_interface *xfer,
/** TLS ciphertext stream operations */
static struct xfer_interface_operations tls_cipherstream_operations = {
.close = tls_cipherstream_close,
- .vredirect = xfer_vopen,
+ .vredirect = xfer_vreopen,
.window = filter_window,
.alloc_iob = default_xfer_alloc_iob,
.deliver_iob = xfer_deliver_as_raw,
diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c
index 97e64617f..289e41ade 100644
--- a/src/net/udp/dhcp.c
+++ b/src/net/udp/dhcp.c
@@ -1107,7 +1107,7 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer,
/** DHCP data transfer interface operations */
static struct xfer_interface_operations dhcp_xfer_operations = {
.close = ignore_xfer_close,
- .vredirect = xfer_vopen,
+ .vredirect = xfer_vreopen,
.window = unlimited_xfer_window,
.alloc_iob = default_xfer_alloc_iob,
.deliver_iob = dhcp_deliver_iob,
diff --git a/src/net/udp/dns.c b/src/net/udp/dns.c
index a498aefc0..c1da454b7 100644
--- a/src/net/udp/dns.c
+++ b/src/net/udp/dns.c
@@ -459,7 +459,7 @@ static void dns_xfer_close ( struct xfer_interface *socket, int rc ) {
/** DNS socket operations */
static struct xfer_interface_operations dns_socket_operations = {
.close = dns_xfer_close,
- .vredirect = xfer_vopen,
+ .vredirect = xfer_vreopen,
.window = unlimited_xfer_window,
.alloc_iob = default_xfer_alloc_iob,
.deliver_iob = xfer_deliver_as_raw,
diff --git a/src/net/udp/slam.c b/src/net/udp/slam.c
index 6add99bc2..71043f45a 100644
--- a/src/net/udp/slam.c
+++ b/src/net/udp/slam.c
@@ -614,7 +614,7 @@ static void slam_socket_close ( struct xfer_interface *socket, int rc ) {
/** SLAM unicast socket data transfer operations */
static struct xfer_interface_operations slam_socket_operations = {
.close = slam_socket_close,
- .vredirect = xfer_vopen,
+ .vredirect = xfer_vreopen,
.window = unlimited_xfer_window,
.alloc_iob = default_xfer_alloc_iob,
.deliver_iob = slam_socket_deliver,
@@ -640,7 +640,7 @@ static void slam_mc_socket_close ( struct xfer_interface *mc_socket, int rc ){
/** SLAM multicast socket data transfer operations */
static struct xfer_interface_operations slam_mc_socket_operations = {
.close = slam_mc_socket_close,
- .vredirect = xfer_vopen,
+ .vredirect = xfer_vreopen,
.window = unlimited_xfer_window,
.alloc_iob = default_xfer_alloc_iob,
.deliver_iob = slam_mc_socket_deliver,
diff --git a/src/net/udp/tftp.c b/src/net/udp/tftp.c
index 19525f79a..be7e58afc 100644
--- a/src/net/udp/tftp.c
+++ b/src/net/udp/tftp.c
@@ -934,7 +934,7 @@ static int tftp_socket_deliver_iob ( struct xfer_interface *socket,
/** TFTP socket operations */
static struct xfer_interface_operations tftp_socket_operations = {
.close = ignore_xfer_close,
- .vredirect = xfer_vopen,
+ .vredirect = xfer_vreopen,
.window = unlimited_xfer_window,
.alloc_iob = default_xfer_alloc_iob,
.deliver_iob = tftp_socket_deliver_iob,
@@ -961,7 +961,7 @@ static int tftp_mc_socket_deliver_iob ( struct xfer_interface *mc_socket,
/** TFTP multicast socket operations */
static struct xfer_interface_operations tftp_mc_socket_operations = {
.close = ignore_xfer_close,
- .vredirect = xfer_vopen,
+ .vredirect = xfer_vreopen,
.window = unlimited_xfer_window,
.alloc_iob = default_xfer_alloc_iob,
.deliver_iob = tftp_mc_socket_deliver_iob,