mirror of https://github.com/ipxe/ipxe.git
[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 <mcb30@ipxe.org>pull/34/head
parent
2d3f2b2446
commit
2dfdcae938
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue