Browse Source

[tftp] Explicitly abort connection whenever parent interface is closed

Fetching the TFTP file size is currently implemented via a custom
"tftpsize://" protocol hack.  Generalise this approach to instead
close the TFTP connection whenever the parent data-transfer interface
is closed.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
2dfdcae938
2 changed files with 23 additions and 48 deletions
  1. 7
    10
      src/arch/i386/interface/pxe/pxe_tftp.c
  2. 16
    38
      src/net/udp/tftp.c

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

171
  * @ret rc		Return status code
171
  * @ret rc		Return status code
172
  */
172
  */
173
 static int pxe_tftp_open ( uint32_t ipaddress, unsigned int port,
173
 static int pxe_tftp_open ( uint32_t ipaddress, unsigned int port,
174
-			   const unsigned char *filename, size_t blksize,
175
-			   int sizeonly ) {
174
+			   const unsigned char *filename, size_t blksize ) {
176
 	char uri_string[PXE_TFTP_URI_LEN];
175
 	char uri_string[PXE_TFTP_URI_LEN];
177
 	struct in_addr address;
176
 	struct in_addr address;
178
 	int rc;
177
 	int rc;
189
 	address.s_addr = ipaddress;
188
 	address.s_addr = ipaddress;
190
 	if ( ! port )
189
 	if ( ! port )
191
 		port = htons ( TFTP_PORT );
190
 		port = htons ( TFTP_PORT );
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 );
191
+	snprintf ( uri_string, sizeof ( uri_string ), "tftp://%s:%d%s%s",
192
+		   inet_ntoa ( address ), ntohs ( port ),
193
+		   ( ( filename[0] == '/' ) ? "" : "/" ), filename );
196
 	DBG ( " %s", uri_string );
194
 	DBG ( " %s", uri_string );
197
 
195
 
198
 	/* Open PXE TFTP connection */
196
 	/* Open PXE TFTP connection */
259
 	if ( ( rc = pxe_tftp_open ( tftp_open->ServerIPAddress,
257
 	if ( ( rc = pxe_tftp_open ( tftp_open->ServerIPAddress,
260
 				    tftp_open->TFTPPort,
258
 				    tftp_open->TFTPPort,
261
 				    tftp_open->FileName,
259
 				    tftp_open->FileName,
262
-				    tftp_open->PacketSize,
263
-				    0) ) != 0 ) {
260
+				    tftp_open->PacketSize ) ) != 0 ) {
264
 		tftp_open->Status = PXENV_STATUS ( rc );
261
 		tftp_open->Status = PXENV_STATUS ( rc );
265
 		return PXENV_EXIT_FAILURE;
262
 		return PXENV_EXIT_FAILURE;
266
 	}
263
 	}
483
 
480
 
484
 	/* Open TFTP file */
481
 	/* Open TFTP file */
485
 	if ( ( rc = pxe_tftp_open ( tftp_read_file->ServerIPAddress, 0,
482
 	if ( ( rc = pxe_tftp_open ( tftp_read_file->ServerIPAddress, 0,
486
-				    tftp_read_file->FileName, 0, 0 ) ) != 0 ) {
483
+				    tftp_read_file->FileName, 0 ) ) != 0 ) {
487
 		tftp_read_file->Status = PXENV_STATUS ( rc );
484
 		tftp_read_file->Status = PXENV_STATUS ( rc );
488
 		return PXENV_EXIT_FAILURE;
485
 		return PXENV_EXIT_FAILURE;
489
 	}
486
 	}
553
 
550
 
554
 	/* Open TFTP file */
551
 	/* Open TFTP file */
555
 	if ( ( rc = pxe_tftp_open ( tftp_get_fsize->ServerIPAddress, 0,
552
 	if ( ( rc = pxe_tftp_open ( tftp_get_fsize->ServerIPAddress, 0,
556
-				    tftp_get_fsize->FileName, 0, 1 ) ) != 0 ) {
553
+				    tftp_get_fsize->FileName, 0 ) ) != 0 ) {
557
 		tftp_get_fsize->Status = PXENV_STATUS ( rc );
554
 		tftp_get_fsize->Status = PXENV_STATUS ( rc );
558
 		return PXENV_EXIT_FAILURE;
555
 		return PXENV_EXIT_FAILURE;
559
 	}
556
 	}

+ 16
- 38
src/net/udp/tftp.c View File

149
 	TFTP_FL_RRQ_MULTICAST = 0x0004,
149
 	TFTP_FL_RRQ_MULTICAST = 0x0004,
150
 	/** Perform MTFTP recovery on timeout */
150
 	/** Perform MTFTP recovery on timeout */
151
 	TFTP_FL_MTFTP_RECOVERY = 0x0008,
151
 	TFTP_FL_MTFTP_RECOVERY = 0x0008,
152
-	/** Only get filesize and then abort the transfer */
153
-	TFTP_FL_SIZEONLY = 0x0010,
154
 };
152
 };
155
 
153
 
156
 /** Maximum number of MTFTP open requests before falling back to TFTP */
154
 /** Maximum number of MTFTP open requests before falling back to TFTP */
759
 			goto done;
757
 			goto done;
760
 	}
758
 	}
761
 
759
 
762
-	/* Abort request if only trying to determine file size */
763
-	if ( tftp->flags & TFTP_FL_SIZEONLY ) {
764
-		rc = 0;
765
-		tftp_send_error ( tftp, 0, "TFTP Aborted" );
766
-		tftp_done ( tftp, rc );
767
-		return rc;
768
-	}
769
-
770
 	/* Request next data block */
760
 	/* Request next data block */
771
 	tftp_send_packet ( tftp );
761
 	tftp_send_packet ( tftp );
772
 
762
 
794
 	size_t data_len;
784
 	size_t data_len;
795
 	int rc;
785
 	int rc;
796
 
786
 
797
-	if ( tftp->flags & TFTP_FL_SIZEONLY ) {
798
-		/* If we get here then server doesn't support SIZE option */
799
-		rc = -ENOTSUP;
800
-		tftp_send_error ( tftp, 0, "TFTP Aborted" );
801
-		goto done;
802
-	}
803
-
804
 	/* Sanity check */
787
 	/* Sanity check */
805
 	if ( iob_len ( iobuf ) < sizeof ( *data ) ) {
788
 	if ( iob_len ( iobuf ) < sizeof ( *data ) ) {
806
 		DBGC ( tftp, "TFTP %p received underlength DATA packet "
789
 		DBGC ( tftp, "TFTP %p received underlength DATA packet "
1036
 	return tftp->blksize;
1019
 	return tftp->blksize;
1037
 }
1020
 }
1038
 
1021
 
1022
+/**
1023
+ * Terminate download
1024
+ *
1025
+ * @v tftp		TFTP connection
1026
+ * @v rc		Reason for close
1027
+ */
1028
+static void tftp_close ( struct tftp_request *tftp, int rc ) {
1029
+
1030
+	/* Abort download */
1031
+	tftp_send_error ( tftp, 0, "TFTP Aborted" );
1032
+
1033
+	/* Close TFTP request */
1034
+	tftp_done ( tftp, rc );
1035
+}
1036
+
1039
 /** TFTP data transfer interface operations */
1037
 /** TFTP data transfer interface operations */
1040
 static struct interface_operation tftp_xfer_operations[] = {
1038
 static struct interface_operation tftp_xfer_operations[] = {
1041
 	INTF_OP ( xfer_window, struct tftp_request *, tftp_xfer_window ),
1039
 	INTF_OP ( xfer_window, struct tftp_request *, tftp_xfer_window ),
1042
-	INTF_OP ( intf_close, struct tftp_request *, tftp_done ),
1040
+	INTF_OP ( intf_close, struct tftp_request *, tftp_close ),
1043
 };
1041
 };
1044
 
1042
 
1045
 /** TFTP data transfer interface descriptor */
1043
 /** TFTP data transfer interface descriptor */
1125
 	.open	= tftp_open,
1123
 	.open	= tftp_open,
1126
 };
1124
 };
1127
 
1125
 
1128
-/**
1129
- * Initiate TFTP-size request
1130
- *
1131
- * @v xfer		Data transfer interface
1132
- * @v uri		Uniform Resource Identifier
1133
- * @ret rc		Return status code
1134
- */
1135
-static int tftpsize_open ( struct interface *xfer, struct uri *uri ) {
1136
-	return tftp_core_open ( xfer, uri, TFTP_PORT, NULL,
1137
-				( TFTP_FL_RRQ_SIZES |
1138
-				  TFTP_FL_SIZEONLY ) );
1139
-
1140
-}
1141
-
1142
-/** TFTP URI opener */
1143
-struct uri_opener tftpsize_uri_opener __uri_opener = {
1144
-	.scheme	= "tftpsize",
1145
-	.open	= tftpsize_open,
1146
-};
1147
-
1148
 /**
1126
 /**
1149
  * Initiate TFTM download
1127
  * Initiate TFTM download
1150
  *
1128
  *

Loading…
Cancel
Save