Browse Source

[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>
tags/v1.20.1
Michael Brown 11 years ago
parent
commit
02b914e812
3 changed files with 28 additions and 29 deletions
  1. 20
    7
      src/arch/i386/interface/pxe/pxe_tftp.c
  2. 0
    2
      src/include/ipxe/tftp.h
  3. 8
    20
      src/net/udp/tftp.c

+ 20
- 7
src/arch/i386/interface/pxe/pxe_tftp.c View File

@@ -71,6 +71,17 @@ static void pxe_tftp_close ( struct pxe_tftp_connection *pxe_tftp, int rc ) {
71 71
 	pxe_tftp->rc = rc;
72 72
 }
73 73
 
74
+/**
75
+ * Check flow control window
76
+ *
77
+ * @v pxe_tftp		PXE TFTP connection
78
+ * @ret len		Length of window
79
+ */
80
+static size_t pxe_tftp_xfer_window ( struct pxe_tftp_connection *pxe_tftp ) {
81
+
82
+	return pxe_tftp->blksize;
83
+}
84
+
74 85
 /**
75 86
  * Receive new data
76 87
  *
@@ -128,6 +139,8 @@ static int pxe_tftp_xfer_deliver ( struct pxe_tftp_connection *pxe_tftp,
128 139
 static struct interface_operation pxe_tftp_xfer_ops[] = {
129 140
 	INTF_OP ( xfer_deliver, struct pxe_tftp_connection *,
130 141
 		  pxe_tftp_xfer_deliver ),
142
+	INTF_OP ( xfer_window, struct pxe_tftp_connection *,
143
+		  pxe_tftp_xfer_window ),
131 144
 	INTF_OP ( intf_close, struct pxe_tftp_connection *, pxe_tftp_close ),
132 145
 };
133 146
 
@@ -167,19 +180,19 @@ static int pxe_tftp_open ( uint32_t ipaddress, unsigned int port,
167 180
 	/* Reset PXE TFTP connection structure */
168 181
 	memset ( &pxe_tftp, 0, sizeof ( pxe_tftp ) );
169 182
 	intf_init ( &pxe_tftp.xfer, &pxe_tftp_xfer_desc, NULL );
183
+	if ( blksize < TFTP_DEFAULT_BLKSIZE )
184
+		blksize = TFTP_DEFAULT_BLKSIZE;
185
+	pxe_tftp.blksize = blksize;
170 186
 	pxe_tftp.rc = -EINPROGRESS;
171 187
 
172 188
 	/* Construct URI string */
173 189
 	address.s_addr = ipaddress;
174 190
 	if ( ! port )
175 191
 		port = htons ( TFTP_PORT );
176
-	if ( blksize < TFTP_DEFAULT_BLKSIZE )
177
-		blksize = TFTP_DEFAULT_BLKSIZE;
178
-	snprintf ( uri_string, sizeof ( uri_string ),
179
-		   "tftp%s://%s:%d%s%s?blksize=%zd",
180
-		   sizeonly ? "size" : "",
181
-		   inet_ntoa ( address ), ntohs ( port ),
182
-		   ( ( filename[0] == '/' ) ? "" : "/" ), filename, blksize );
192
+	snprintf ( uri_string, sizeof ( uri_string ), "tftp%s://%s:%d%s%s",
193
+		   sizeonly ? "size" : "", inet_ntoa ( address ),
194
+		   ntohs ( port ), ( ( filename[0] == '/' ) ? "" : "/" ),
195
+		   filename );
183 196
 	DBG ( " %s", uri_string );
184 197
 
185 198
 	/* Open PXE TFTP connection */

+ 0
- 2
src/include/ipxe/tftp.h View File

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

+ 8
- 20
src/net/udp/tftp.c View File

@@ -287,24 +287,6 @@ static int tftp_presize ( struct tftp_request *tftp, size_t filesize ) {
287 287
 	return 0;
288 288
 }
289 289
 
290
-/**
291
- * TFTP requested blocksize
292
- *
293
- * This is treated as a global configuration parameter.
294
- */
295
-static unsigned int tftp_request_blksize = TFTP_MAX_BLKSIZE;
296
-
297
-/**
298
- * Set TFTP request blocksize
299
- *
300
- * @v blksize		Requested block size
301
- */
302
-void tftp_set_request_blksize ( unsigned int blksize ) {
303
-	if ( blksize < TFTP_DEFAULT_BLKSIZE )
304
-		blksize = TFTP_DEFAULT_BLKSIZE;
305
-	tftp_request_blksize = blksize;
306
-}
307
-
308 290
 /**
309 291
  * MTFTP multicast receive address
310 292
  *
@@ -345,6 +327,7 @@ static int tftp_send_rrq ( struct tftp_request *tftp ) {
345 327
 	const char *path;
346 328
 	size_t len;
347 329
 	struct io_buffer *iobuf;
330
+	size_t blksize;
348 331
 
349 332
 	/* Strip initial '/' if present.  If we were opened via the
350 333
 	 * URI interface, then there will be an initial '/', since a
@@ -370,6 +353,11 @@ static int tftp_send_rrq ( struct tftp_request *tftp ) {
370 353
 	if ( ! iobuf )
371 354
 		return -ENOMEM;
372 355
 
356
+	/* Determine block size */
357
+	blksize = xfer_window ( &tftp->xfer );
358
+	if ( blksize > TFTP_MAX_BLKSIZE )
359
+		blksize = TFTP_MAX_BLKSIZE;
360
+
373 361
 	/* Build request */
374 362
 	rrq = iob_put ( iobuf, sizeof ( *rrq ) );
375 363
 	rrq->opcode = htons ( TFTP_RRQ );
@@ -378,8 +366,8 @@ static int tftp_send_rrq ( struct tftp_request *tftp ) {
378 366
 	if ( tftp->flags & TFTP_FL_RRQ_SIZES ) {
379 367
 		iob_put ( iobuf, snprintf ( iobuf->tail,
380 368
 					    iob_tailroom ( iobuf ),
381
-					    "blksize%c%d%ctsize%c0", 0,
382
-					    tftp_request_blksize, 0, 0 ) + 1 );
369
+					    "blksize%c%zd%ctsize%c0",
370
+					    0, blksize, 0, 0 ) + 1 );
383 371
 	}
384 372
 	if ( tftp->flags & TFTP_FL_RRQ_MULTICAST ) {
385 373
 		iob_put ( iobuf, snprintf ( iobuf->tail,

Loading…
Cancel
Save