]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[tftp] Allow TFTP block size to be controlled via the PXE TFTP API
authorMichael Brown <mcb30@ipxe.org>
Wed, 6 Mar 2013 17:35:30 +0000 (17:35 +0000)
committerMichael Brown <mcb30@ipxe.org>
Wed, 6 Mar 2013 17:35:30 +0000 (17:35 +0000)
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>
src/arch/i386/interface/pxe/pxe_tftp.c
src/include/ipxe/tftp.h
src/net/udp/tftp.c

index aab376e8296bbe327e2d2df2c038bdbf912b2851..f4801bad0da2b1022994190608d00e41f53e1f14 100644 (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 */
index 38be0d4da4710bc69ff1a3bf0e46d0976986c9ce..aecafa2aedd3f293a84503ed583b0c45bbd4db1b 100644 (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 */
index a6c64b4abdd96d24504f0e0f3f82209e600c4109..d686aac9adbc81afa02975768caff46dfc789e12 100644 (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,