[xfer] Implement xfer_vreopen() to properly handle redirections
authorMichael Brown <mcb30@etherboot.org>
Mon, 30 Mar 2009 12:24:56 +0000 (13:24 +0100)
committerMichael Brown <mcb30@etherboot.org>
Mon, 30 Mar 2009 12:24:56 +0000 (13:24 +0100)
When handling a redirection event, we need to close the existing
connection before opening the new connection.

13 files changed:
src/arch/i386/interface/pxe/pxe_tftp.c
src/core/downloader.c
src/core/open.c
src/core/posix_io.c
src/include/gpxe/open.h
src/net/tcp/ftp.c
src/net/tcp/http.c
src/net/tcp/iscsi.c
src/net/tls.c
src/net/udp/dhcp.c
src/net/udp/dns.c
src/net/udp/slam.c
src/net/udp/tftp.c

index 715a0b6..cc7f830 100644 (file)
@@ -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,
index 0a443db..83027d3 100644 (file)
@@ -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,
index 89a96d7..beb67a0 100644 (file)
@@ -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 );
+}
index e0459bd..6f6d815 100644 (file)
@@ -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,
index 61fb0ef..136ff87 100644 (file)
@@ -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 */
index 445e32b..0719bf7 100644 (file)
@@ -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,
index 93ccfd3..b7cbea4 100644 (file)
@@ -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,
index 45519e6..51c2bee 100644 (file)
@@ -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 );
 }
                             
 
index 73f9ad0..25f18f7 100644 (file)
@@ -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,
index 97e6461..289e41a 100644 (file)
@@ -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,
index a498aef..c1da454 100644 (file)
@@ -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,
index 6add99b..71043f4 100644 (file)
@@ -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,
index 19525f7..be7e58a 100644 (file)
@@ -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,