Skip to content

Commit

Permalink
[tftp] Allow TFTP block size to be controlled via the PXE TFTP API
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
mcb30 committed Mar 6, 2013
1 parent c080251 commit 02b914e
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 29 deletions.
27 changes: 20 additions & 7 deletions src/arch/i386/interface/pxe/pxe_tftp.c
Expand Up @@ -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
*
Expand Down Expand Up @@ -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 ),
};

Expand Down Expand Up @@ -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 */
Expand Down
2 changes: 0 additions & 2 deletions src/include/ipxe/tftp.h
Expand Up @@ -80,6 +80,4 @@ union tftp_any {
struct tftp_oack oack;
};

extern void tftp_set_request_blksize ( unsigned int blksize );

#endif /* _IPXE_TFTP_H */
28 changes: 8 additions & 20 deletions src/net/udp/tftp.c
Expand Up @@ -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
*
Expand Down Expand Up @@ -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
Expand All @@ -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 );
Expand All @@ -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,
Expand Down

0 comments on commit 02b914e

Please sign in to comment.