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
 	pxe_tftp->rc = rc;
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
  * Receive new data
86
  * Receive new data
76
  *
87
  *
128
 static struct interface_operation pxe_tftp_xfer_ops[] = {
139
 static struct interface_operation pxe_tftp_xfer_ops[] = {
129
 	INTF_OP ( xfer_deliver, struct pxe_tftp_connection *,
140
 	INTF_OP ( xfer_deliver, struct pxe_tftp_connection *,
130
 		  pxe_tftp_xfer_deliver ),
141
 		  pxe_tftp_xfer_deliver ),
142
+	INTF_OP ( xfer_window, struct pxe_tftp_connection *,
143
+		  pxe_tftp_xfer_window ),
131
 	INTF_OP ( intf_close, struct pxe_tftp_connection *, pxe_tftp_close ),
144
 	INTF_OP ( intf_close, struct pxe_tftp_connection *, pxe_tftp_close ),
132
 };
145
 };
133
 
146
 
167
 	/* Reset PXE TFTP connection structure */
180
 	/* Reset PXE TFTP connection structure */
168
 	memset ( &pxe_tftp, 0, sizeof ( pxe_tftp ) );
181
 	memset ( &pxe_tftp, 0, sizeof ( pxe_tftp ) );
169
 	intf_init ( &pxe_tftp.xfer, &pxe_tftp_xfer_desc, NULL );
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
 	pxe_tftp.rc = -EINPROGRESS;
186
 	pxe_tftp.rc = -EINPROGRESS;
171
 
187
 
172
 	/* Construct URI string */
188
 	/* Construct URI string */
173
 	address.s_addr = ipaddress;
189
 	address.s_addr = ipaddress;
174
 	if ( ! port )
190
 	if ( ! port )
175
 		port = htons ( TFTP_PORT );
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
 	DBG ( " %s", uri_string );
196
 	DBG ( " %s", uri_string );
184
 
197
 
185
 	/* Open PXE TFTP connection */
198
 	/* Open PXE TFTP connection */

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

80
 	struct tftp_oack	oack;
80
 	struct tftp_oack	oack;
81
 };
81
 };
82
 
82
 
83
-extern void tftp_set_request_blksize ( unsigned int blksize );
84
-
85
 #endif /* _IPXE_TFTP_H */
83
 #endif /* _IPXE_TFTP_H */

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

287
 	return 0;
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
  * MTFTP multicast receive address
291
  * MTFTP multicast receive address
310
  *
292
  *
345
 	const char *path;
327
 	const char *path;
346
 	size_t len;
328
 	size_t len;
347
 	struct io_buffer *iobuf;
329
 	struct io_buffer *iobuf;
330
+	size_t blksize;
348
 
331
 
349
 	/* Strip initial '/' if present.  If we were opened via the
332
 	/* Strip initial '/' if present.  If we were opened via the
350
 	 * URI interface, then there will be an initial '/', since a
333
 	 * URI interface, then there will be an initial '/', since a
370
 	if ( ! iobuf )
353
 	if ( ! iobuf )
371
 		return -ENOMEM;
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
 	/* Build request */
361
 	/* Build request */
374
 	rrq = iob_put ( iobuf, sizeof ( *rrq ) );
362
 	rrq = iob_put ( iobuf, sizeof ( *rrq ) );
375
 	rrq->opcode = htons ( TFTP_RRQ );
363
 	rrq->opcode = htons ( TFTP_RRQ );
378
 	if ( tftp->flags & TFTP_FL_RRQ_SIZES ) {
366
 	if ( tftp->flags & TFTP_FL_RRQ_SIZES ) {
379
 		iob_put ( iobuf, snprintf ( iobuf->tail,
367
 		iob_put ( iobuf, snprintf ( iobuf->tail,
380
 					    iob_tailroom ( iobuf ),
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
 	if ( tftp->flags & TFTP_FL_RRQ_MULTICAST ) {
372
 	if ( tftp->flags & TFTP_FL_RRQ_MULTICAST ) {
385
 		iob_put ( iobuf, snprintf ( iobuf->tail,
373
 		iob_put ( iobuf, snprintf ( iobuf->tail,

Loading…
Cancel
Save