mirror of
https://github.com/xcat2/xNBA.git
synced 2024-11-26 19:29:04 +00:00
[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:
parent
c08025137b
commit
02b914e812
@ -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 */
|
||||
|
@ -80,6 +80,4 @@ union tftp_any {
|
||||
struct tftp_oack oack;
|
||||
};
|
||||
|
||||
extern void tftp_set_request_blksize ( unsigned int blksize );
|
||||
|
||||
#endif /* _IPXE_TFTP_H */
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user