summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2013-03-06 18:35:30 +0100
committerMichael Brown2013-03-06 18:35:30 +0100
commit02b914e8129c55a1b8766de0ab49928929392e89 (patch)
treed7259f5a4796e2b7bcf6ecb175191ed4a2892d8e
parent[menu] Prevent separators with shortcut keys from being selected (diff)
downloadipxe-02b914e8129c55a1b8766de0ab49928929392e89.tar.gz
ipxe-02b914e8129c55a1b8766de0ab49928929392e89.tar.xz
ipxe-02b914e8129c55a1b8766de0ab49928929392e89.zip
[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>
-rw-r--r--src/arch/i386/interface/pxe/pxe_tftp.c27
-rw-r--r--src/include/ipxe/tftp.h2
-rw-r--r--src/net/udp/tftp.c28
3 files changed, 28 insertions, 29 deletions
diff --git a/src/arch/i386/interface/pxe/pxe_tftp.c b/src/arch/i386/interface/pxe/pxe_tftp.c
index aab376e8..f4801bad 100644
--- a/src/arch/i386/interface/pxe/pxe_tftp.c
+++ b/src/arch/i386/interface/pxe/pxe_tftp.c
@@ -72,6 +72,17 @@ static void pxe_tftp_close ( struct pxe_tftp_connection *pxe_tftp, int 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
*
* @v pxe_tftp PXE TFTP connection
@@ -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 */
diff --git a/src/include/ipxe/tftp.h b/src/include/ipxe/tftp.h
index 38be0d4d..aecafa2a 100644
--- a/src/include/ipxe/tftp.h
+++ b/src/include/ipxe/tftp.h
@@ -80,6 +80,4 @@ union tftp_any {
struct tftp_oack oack;
};
-extern void tftp_set_request_blksize ( unsigned int blksize );
-
#endif /* _IPXE_TFTP_H */
diff --git a/src/net/udp/tftp.c b/src/net/udp/tftp.c
index a6c64b4a..d686aac9 100644
--- a/src/net/udp/tftp.c
+++ b/src/net/udp/tftp.c
@@ -288,24 +288,6 @@ static int tftp_presize ( struct tftp_request *tftp, size_t filesize ) {
}
/**
- * 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
*
* This is treated as a global configuration parameter.
@@ -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,