david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[tftp] Allow TFTP block size to be controlled via the PXE TFTP API

The PXE TFTP API allows the caller to request a particular TFTP block
size.  Since mid-2008, iPXE has appended a "?blksize=xxx" parameter to
the TFTP URI constructed internally; nothing has ever parsed this
parameter.  Nobody seems to have cared that this parameter has been
ignored for almost five years.

Fix by using xfer_window(), which provides a fairly natural way to
convey the block size information from the PXE TFTP API to the TFTP
protocol layer.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2013-03-06 17:35:30 +00:00
parent c08025137b
commit 02b914e812
3 changed files with 28 additions and 29 deletions

View File

@ -71,6 +71,17 @@ static void pxe_tftp_close ( struct pxe_tftp_connection *pxe_tftp, int rc ) {
pxe_tftp->rc = rc;
}
/**
* Check flow control window
*
* @v pxe_tftp PXE TFTP connection
* @ret len Length of window
*/
static size_t pxe_tftp_xfer_window ( struct pxe_tftp_connection *pxe_tftp ) {
return pxe_tftp->blksize;
}
/**
* Receive new data
*
@ -128,6 +139,8 @@ static int pxe_tftp_xfer_deliver ( struct pxe_tftp_connection *pxe_tftp,
static struct interface_operation pxe_tftp_xfer_ops[] = {
INTF_OP ( xfer_deliver, struct pxe_tftp_connection *,
pxe_tftp_xfer_deliver ),
INTF_OP ( xfer_window, struct pxe_tftp_connection *,
pxe_tftp_xfer_window ),
INTF_OP ( intf_close, struct pxe_tftp_connection *, pxe_tftp_close ),
};
@ -167,19 +180,19 @@ static int pxe_tftp_open ( uint32_t ipaddress, unsigned int port,
/* Reset PXE TFTP connection structure */
memset ( &pxe_tftp, 0, sizeof ( pxe_tftp ) );
intf_init ( &pxe_tftp.xfer, &pxe_tftp_xfer_desc, NULL );
if ( blksize < TFTP_DEFAULT_BLKSIZE )
blksize = TFTP_DEFAULT_BLKSIZE;
pxe_tftp.blksize = blksize;
pxe_tftp.rc = -EINPROGRESS;
/* Construct URI string */
address.s_addr = ipaddress;
if ( ! port )
port = htons ( TFTP_PORT );
if ( blksize < TFTP_DEFAULT_BLKSIZE )
blksize = TFTP_DEFAULT_BLKSIZE;
snprintf ( uri_string, sizeof ( uri_string ),
"tftp%s://%s:%d%s%s?blksize=%zd",
sizeonly ? "size" : "",
inet_ntoa ( address ), ntohs ( port ),
( ( filename[0] == '/' ) ? "" : "/" ), filename, blksize );
snprintf ( uri_string, sizeof ( uri_string ), "tftp%s://%s:%d%s%s",
sizeonly ? "size" : "", inet_ntoa ( address ),
ntohs ( port ), ( ( filename[0] == '/' ) ? "" : "/" ),
filename );
DBG ( " %s", uri_string );
/* Open PXE TFTP connection */

View File

@ -80,6 +80,4 @@ union tftp_any {
struct tftp_oack oack;
};
extern void tftp_set_request_blksize ( unsigned int blksize );
#endif /* _IPXE_TFTP_H */

View File

@ -287,24 +287,6 @@ static int tftp_presize ( struct tftp_request *tftp, size_t filesize ) {
return 0;
}
/**
* TFTP requested blocksize
*
* This is treated as a global configuration parameter.
*/
static unsigned int tftp_request_blksize = TFTP_MAX_BLKSIZE;
/**
* Set TFTP request blocksize
*
* @v blksize Requested block size
*/
void tftp_set_request_blksize ( unsigned int blksize ) {
if ( blksize < TFTP_DEFAULT_BLKSIZE )
blksize = TFTP_DEFAULT_BLKSIZE;
tftp_request_blksize = blksize;
}
/**
* MTFTP multicast receive address
*
@ -345,6 +327,7 @@ static int tftp_send_rrq ( struct tftp_request *tftp ) {
const char *path;
size_t len;
struct io_buffer *iobuf;
size_t blksize;
/* Strip initial '/' if present. If we were opened via the
* URI interface, then there will be an initial '/', since a
@ -370,6 +353,11 @@ static int tftp_send_rrq ( struct tftp_request *tftp ) {
if ( ! iobuf )
return -ENOMEM;
/* Determine block size */
blksize = xfer_window ( &tftp->xfer );
if ( blksize > TFTP_MAX_BLKSIZE )
blksize = TFTP_MAX_BLKSIZE;
/* Build request */
rrq = iob_put ( iobuf, sizeof ( *rrq ) );
rrq->opcode = htons ( TFTP_RRQ );
@ -378,8 +366,8 @@ static int tftp_send_rrq ( struct tftp_request *tftp ) {
if ( tftp->flags & TFTP_FL_RRQ_SIZES ) {
iob_put ( iobuf, snprintf ( iobuf->tail,
iob_tailroom ( iobuf ),
"blksize%c%d%ctsize%c0", 0,
tftp_request_blksize, 0, 0 ) + 1 );
"blksize%c%zd%ctsize%c0",
0, blksize, 0, 0 ) + 1 );
}
if ( tftp->flags & TFTP_FL_RRQ_MULTICAST ) {
iob_put ( iobuf, snprintf ( iobuf->tail,