From 2dfdcae938b3aaae2cb5d48bf2cf45c23ee4b312 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 6 Feb 2015 12:08:54 +0000 Subject: [PATCH] [tftp] Explicitly abort connection whenever parent interface is closed Fetching the TFTP file size is currently implemented via a custom "tftpsize://" protocol hack. Generalise this approach to instead close the TFTP connection whenever the parent data-transfer interface is closed. Signed-off-by: Michael Brown --- src/arch/i386/interface/pxe/pxe_tftp.c | 17 ++++---- src/net/udp/tftp.c | 54 ++++++++------------------ 2 files changed, 23 insertions(+), 48 deletions(-) diff --git a/src/arch/i386/interface/pxe/pxe_tftp.c b/src/arch/i386/interface/pxe/pxe_tftp.c index f4801bad0..01afa954c 100644 --- a/src/arch/i386/interface/pxe/pxe_tftp.c +++ b/src/arch/i386/interface/pxe/pxe_tftp.c @@ -171,8 +171,7 @@ static struct pxe_tftp_connection pxe_tftp = { * @ret rc Return status code */ static int pxe_tftp_open ( uint32_t ipaddress, unsigned int port, - const unsigned char *filename, size_t blksize, - int sizeonly ) { + const unsigned char *filename, size_t blksize ) { char uri_string[PXE_TFTP_URI_LEN]; struct in_addr address; int rc; @@ -189,10 +188,9 @@ static int pxe_tftp_open ( uint32_t ipaddress, unsigned int port, address.s_addr = ipaddress; if ( ! port ) port = htons ( TFTP_PORT ); - snprintf ( uri_string, sizeof ( uri_string ), "tftp%s://%s:%d%s%s", - sizeonly ? "size" : "", inet_ntoa ( address ), - ntohs ( port ), ( ( filename[0] == '/' ) ? "" : "/" ), - filename ); + snprintf ( uri_string, sizeof ( uri_string ), "tftp://%s:%d%s%s", + inet_ntoa ( address ), ntohs ( port ), + ( ( filename[0] == '/' ) ? "" : "/" ), filename ); DBG ( " %s", uri_string ); /* Open PXE TFTP connection */ @@ -259,8 +257,7 @@ static PXENV_EXIT_t pxenv_tftp_open ( struct s_PXENV_TFTP_OPEN *tftp_open ) { if ( ( rc = pxe_tftp_open ( tftp_open->ServerIPAddress, tftp_open->TFTPPort, tftp_open->FileName, - tftp_open->PacketSize, - 0) ) != 0 ) { + tftp_open->PacketSize ) ) != 0 ) { tftp_open->Status = PXENV_STATUS ( rc ); return PXENV_EXIT_FAILURE; } @@ -483,7 +480,7 @@ PXENV_EXIT_t pxenv_tftp_read_file ( struct s_PXENV_TFTP_READ_FILE /* Open TFTP file */ if ( ( rc = pxe_tftp_open ( tftp_read_file->ServerIPAddress, 0, - tftp_read_file->FileName, 0, 0 ) ) != 0 ) { + tftp_read_file->FileName, 0 ) ) != 0 ) { tftp_read_file->Status = PXENV_STATUS ( rc ); return PXENV_EXIT_FAILURE; } @@ -553,7 +550,7 @@ static PXENV_EXIT_t pxenv_tftp_get_fsize ( struct s_PXENV_TFTP_GET_FSIZE /* Open TFTP file */ if ( ( rc = pxe_tftp_open ( tftp_get_fsize->ServerIPAddress, 0, - tftp_get_fsize->FileName, 0, 1 ) ) != 0 ) { + tftp_get_fsize->FileName, 0 ) ) != 0 ) { tftp_get_fsize->Status = PXENV_STATUS ( rc ); return PXENV_EXIT_FAILURE; } diff --git a/src/net/udp/tftp.c b/src/net/udp/tftp.c index ee827ae3d..375d55e6f 100644 --- a/src/net/udp/tftp.c +++ b/src/net/udp/tftp.c @@ -149,8 +149,6 @@ enum { TFTP_FL_RRQ_MULTICAST = 0x0004, /** Perform MTFTP recovery on timeout */ TFTP_FL_MTFTP_RECOVERY = 0x0008, - /** Only get filesize and then abort the transfer */ - TFTP_FL_SIZEONLY = 0x0010, }; /** Maximum number of MTFTP open requests before falling back to TFTP */ @@ -759,14 +757,6 @@ static int tftp_rx_oack ( struct tftp_request *tftp, void *buf, size_t len ) { goto done; } - /* Abort request if only trying to determine file size */ - if ( tftp->flags & TFTP_FL_SIZEONLY ) { - rc = 0; - tftp_send_error ( tftp, 0, "TFTP Aborted" ); - tftp_done ( tftp, rc ); - return rc; - } - /* Request next data block */ tftp_send_packet ( tftp ); @@ -794,13 +784,6 @@ static int tftp_rx_data ( struct tftp_request *tftp, size_t data_len; int rc; - if ( tftp->flags & TFTP_FL_SIZEONLY ) { - /* If we get here then server doesn't support SIZE option */ - rc = -ENOTSUP; - tftp_send_error ( tftp, 0, "TFTP Aborted" ); - goto done; - } - /* Sanity check */ if ( iob_len ( iobuf ) < sizeof ( *data ) ) { DBGC ( tftp, "TFTP %p received underlength DATA packet " @@ -1036,10 +1019,25 @@ static size_t tftp_xfer_window ( struct tftp_request *tftp ) { return tftp->blksize; } +/** + * Terminate download + * + * @v tftp TFTP connection + * @v rc Reason for close + */ +static void tftp_close ( struct tftp_request *tftp, int rc ) { + + /* Abort download */ + tftp_send_error ( tftp, 0, "TFTP Aborted" ); + + /* Close TFTP request */ + tftp_done ( tftp, rc ); +} + /** TFTP data transfer interface operations */ static struct interface_operation tftp_xfer_operations[] = { INTF_OP ( xfer_window, struct tftp_request *, tftp_xfer_window ), - INTF_OP ( intf_close, struct tftp_request *, tftp_done ), + INTF_OP ( intf_close, struct tftp_request *, tftp_close ), }; /** TFTP data transfer interface descriptor */ @@ -1125,26 +1123,6 @@ struct uri_opener tftp_uri_opener __uri_opener = { .open = tftp_open, }; -/** - * Initiate TFTP-size request - * - * @v xfer Data transfer interface - * @v uri Uniform Resource Identifier - * @ret rc Return status code - */ -static int tftpsize_open ( struct interface *xfer, struct uri *uri ) { - return tftp_core_open ( xfer, uri, TFTP_PORT, NULL, - ( TFTP_FL_RRQ_SIZES | - TFTP_FL_SIZEONLY ) ); - -} - -/** TFTP URI opener */ -struct uri_opener tftpsize_uri_opener __uri_opener = { - .scheme = "tftpsize", - .open = tftpsize_open, -}; - /** * Initiate TFTM download *