Просмотр исходного кода

Update ftp.c to work with Nikhil's TCP stack.

Remove the now-totally-obsolete sockaddr_in field from tcp.h.
tags/v0.9.3
Michael Brown 18 лет назад
Родитель
Сommit
89bcb57201
5 измененных файлов: 99 добавлений и 33 удалений
  1. 2
    0
      src/include/gpxe/ftp.h
  2. 4
    4
      src/include/gpxe/tcp.h
  3. 43
    18
      src/net/tcp/ftp.c
  4. 47
    7
      src/tests/dhcptest.c
  5. 3
    4
      src/tests/ftptest.c

+ 2
- 0
src/include/gpxe/ftp.h Просмотреть файл

@@ -49,6 +49,8 @@ struct ftp_request {
49 49
 	 * remote server.
50 50
 	 */
51 51
 	void ( *callback ) ( char *data, size_t len );
52
+	/** Eventual return status */
53
+	int rc;
52 54
 	/** Asynchronous operation for this FTP operation */
53 55
 	struct async_operation aop;
54 56
 

+ 4
- 4
src/include/gpxe/tcp.h Просмотреть файл

@@ -144,10 +144,6 @@ extern void tcp_close ( struct tcp_connection *conn );
144 144
  */
145 145
 struct tcp_connection {
146 146
 	struct sockaddr_tcpip peer;	/* Remote socket address */
147
-
148
-	/* FIXME: this field should no longer be present */
149
-	struct sockaddr_in sin;
150
-
151 147
 	uint16_t local_port;		/* Local port, in network byte order */
152 148
 	int tcp_state;			/* TCP state */
153 149
 	int tcp_lstate;			/* Last TCP state */
@@ -206,6 +202,10 @@ struct tcp_header {
206 202
 
207 203
 extern struct tcpip_protocol tcp_protocol;
208 204
 
205
+static inline int tcp_closed ( struct tcp_connection *conn ) {
206
+	return ( conn->tcp_state == TCP_CLOSED );
207
+}
208
+
209 209
 extern void tcp_init_conn ( struct tcp_connection *conn );
210 210
 extern int tcp_connect ( struct tcp_connection *conn );
211 211
 extern int tcp_connectto ( struct tcp_connection *conn,

+ 43
- 18
src/net/tcp/ftp.c Просмотреть файл

@@ -67,17 +67,22 @@ static inline struct ftp_request * tcp_to_ftp ( struct tcp_connection *conn ) {
67 67
 	return container_of ( conn, struct ftp_request, tcp );
68 68
 }
69 69
 
70
+static void ftp_set_status ( struct ftp_request *ftp, int rc ) {
71
+	if ( ! ftp->rc )
72
+		ftp->rc = rc;
73
+}
74
+
75
+static void ftp_clear_status ( struct ftp_request *ftp ) {
76
+	ftp->rc = 0;
77
+}
78
+
70 79
 /**
71
- * Mark FTP request as complete
80
+ * Mark FTP operation as complete
72 81
  *
73 82
  * @v ftp		FTP request
74
- * @v rc		Return status code
75
- *
76 83
  */
77
-static void ftp_done ( struct ftp_request *ftp, int rc ) {
78
-	tcp_close ( &ftp->tcp_data );
79
-	tcp_close ( &ftp->tcp );
80
-	async_done ( &ftp->aop, rc );
84
+static void ftp_done ( struct ftp_request *ftp ) {
85
+	async_done ( &ftp->aop, ftp->rc );
81 86
 }
82 87
 
83 88
 /**
@@ -128,13 +133,14 @@ static void ftp_reply ( struct ftp_request *ftp ) {
128 133
 	/* Open passive connection when we get "PASV" response */
129 134
 	if ( ftp->state == FTP_PASV ) {
130 135
 		char *ptr = ftp->passive_text;
131
-
132
-		ftp_parse_value ( &ptr,
133
-				  ( uint8_t * ) &ftp->tcp_data.sin.sin_addr,
134
-				  sizeof ( ftp->tcp_data.sin.sin_addr ) );
135
-		ftp_parse_value ( &ptr,
136
-				  ( uint8_t * ) &ftp->tcp_data.sin.sin_port,
137
-				  sizeof ( ftp->tcp_data.sin.sin_port ) );
136
+		struct sockaddr_in *sin =
137
+			( struct sockaddr_in * ) &ftp->tcp_data.peer;
138
+
139
+		sin->sin_family = AF_INET;
140
+		ftp_parse_value ( &ptr, ( uint8_t * ) &sin->sin_addr,
141
+				  sizeof ( sin->sin_addr ) );
142
+		ftp_parse_value ( &ptr, ( uint8_t * ) &sin->sin_port,
143
+				  sizeof ( sin->sin_port ) );
138 144
 		tcp_connect ( &ftp->tcp_data );
139 145
 	}
140 146
 
@@ -146,7 +152,8 @@ static void ftp_reply ( struct ftp_request *ftp ) {
146 152
 
147 153
  err:
148 154
 	/* Flag protocol error and close connections */
149
-	ftp_done ( ftp, -EPROTO );
155
+	ftp_set_status ( ftp, -EPROTO );
156
+	tcp_close ( &ftp->tcp );
150 157
 }
151 158
 
152 159
 /**
@@ -249,7 +256,15 @@ static void ftp_senddata ( struct tcp_connection *conn,
249 256
 static void ftp_closed ( struct tcp_connection *conn, int status ) {
250 257
 	struct ftp_request *ftp = tcp_to_ftp ( conn );
251 258
 
252
-	ftp_done ( ftp, status );
259
+	/* Close data channel and record status */
260
+	ftp_set_status ( ftp, status );
261
+	tcp_close ( &ftp->tcp_data );
262
+
263
+	/* Mark FTP operation as complete if we are the last
264
+	 * connection to close
265
+	 */
266
+	if ( tcp_closed ( &ftp->tcp_data ) )
267
+		ftp_done ( ftp );
253 268
 }
254 269
 
255 270
 /** FTP control channel operations */
@@ -290,9 +305,18 @@ tcp_to_ftp_data ( struct tcp_connection *conn ) {
290 305
  */
291 306
 static void ftp_data_closed ( struct tcp_connection *conn, int status ) {
292 307
 	struct ftp_request *ftp = tcp_to_ftp_data ( conn );
308
+	
309
+	/* If there was an error, close control channel and record status */
310
+	if ( status ) {
311
+		ftp_set_status ( ftp, status );
312
+		tcp_close ( &ftp->tcp );
313
+	}
293 314
 
294
-	if ( status )
295
-		ftp_done ( ftp, status );
315
+	/* Mark FTP operation as complete if we are the last
316
+	 * connection to close
317
+	 */
318
+	if ( tcp_closed ( &ftp->tcp ) )
319
+		ftp_done ( ftp );
296 320
 }
297 321
 
298 322
 /**
@@ -333,6 +357,7 @@ struct async_operation * ftp_get ( struct ftp_request *ftp ) {
333 357
 	ftp->tcp_data.tcp_op = &ftp_data_tcp_operations;
334 358
 	ftp->recvbuf = ftp->status_text;
335 359
 	ftp->recvsize = sizeof ( ftp->status_text ) - 1;
360
+	ftp_clear_status ( ftp );
336 361
 	tcp_connect ( &ftp->tcp );
337 362
 	return &ftp->aop;
338 363
 }

+ 47
- 7
src/tests/dhcptest.c Просмотреть файл

@@ -14,8 +14,10 @@ static int test_dhcp_aoe_boot ( struct net_device *netdev,
14 14
 	return test_aoeboot ( netdev, aoename, drivenum );
15 15
 }
16 16
 
17
-static int test_dhcp_iscsi_boot ( struct net_device *netdev, char *iscsiname ) {
18
-	char *initiator_iqn = "iqn.1900-01.localdomain.localhost:initiator";
17
+static int test_dhcp_iscsi_boot ( struct net_device *netdev,
18
+				  char *iscsiname ) {
19
+	char initiator_iqn_buf[32];
20
+	char *initiator_iqn = initiator_iqn_buf;
19 21
 	char username[32];
20 22
 	char password[32];
21 23
 	char *target_iqn;
@@ -24,6 +26,7 @@ static int test_dhcp_iscsi_boot ( struct net_device *netdev, char *iscsiname ) {
24 26
 		struct sockaddr_tcpip st;
25 27
 	} target;
26 28
 	unsigned int drivenum;
29
+	struct dhcp_option *option;
27 30
 	
28 31
 	memset ( &target, 0, sizeof ( target ) );
29 32
 	target.sin.sin_family = AF_INET;
@@ -36,6 +39,10 @@ static int test_dhcp_iscsi_boot ( struct net_device *netdev, char *iscsiname ) {
36 39
 	}
37 40
 	inet_aton ( iscsiname, &target.sin.sin_addr );
38 41
 
42
+	dhcp_snprintf ( initiator_iqn, sizeof ( initiator_iqn ),
43
+			find_global_dhcp_option ( DHCP_ISCSI_INITIATOR_IQN ) );
44
+	if ( ! *initiator_iqn )
45
+		initiator_iqn = "iqn.1900-01.localdomain.localhost:initiator";
39 46
 	dhcp_snprintf ( username, sizeof ( username ),
40 47
 			find_global_dhcp_option ( DHCP_EB_USERNAME ) );
41 48
 	dhcp_snprintf ( password, sizeof ( password ),
@@ -89,6 +96,29 @@ static int test_dhcp_http ( struct net_device *netdev, char *url ) {
89 96
 	return 0;
90 97
 }
91 98
 
99
+static int test_dhcp_ftp ( struct net_device *netdev, char *ftpname ) {
100
+	union {
101
+		struct sockaddr_in sin;
102
+		struct sockaddr_tcpip st;
103
+	} target;
104
+	char *filename;
105
+
106
+	filename = strchr ( ftpname, ':' );
107
+	if ( ! filename ) {
108
+		printf ( "Invalid FTP path \"%s\"\n", ftpname );
109
+		return -EINVAL;
110
+	}
111
+	*filename++ = '\0';
112
+
113
+	memset ( &target, 0, sizeof ( target ) );
114
+	target.sin.sin_family = AF_INET;
115
+	target.sin.sin_port = htons ( 21 );
116
+	inet_aton ( ftpname, &target.sin.sin_addr );
117
+
118
+	test_ftp ( &target, filename );
119
+	return 0;	
120
+}
121
+
92 122
 static int test_dhcp_tftp ( struct net_device *netdev, char *tftpname ) {
93 123
 	union {
94 124
 		struct sockaddr_in sin;
@@ -105,17 +135,27 @@ static int test_dhcp_tftp ( struct net_device *netdev, char *tftpname ) {
105 135
 }
106 136
 
107 137
 static int test_dhcp_boot ( struct net_device *netdev, char *filename ) {
138
+	/*
108 139
 	if ( strncmp ( filename, "aoe:", 4 ) == 0 ) {
109 140
 		return test_dhcp_aoe_boot ( netdev, &filename[4] );
110
-	} else if ( strncmp ( filename, "iscsi:", 6 ) == 0 ) {
141
+	} 
142
+	*/
143
+	if ( strncmp ( filename, "iscsi:", 6 ) == 0 ) {
111 144
 		return test_dhcp_iscsi_boot ( netdev, &filename[6] );
112
-	} else if ( strncmp ( filename, "hello:", 6 ) == 0 ) {
145
+	}
146
+	if ( strncmp ( filename, "ftp:", 4 ) == 0 ) {
147
+		return test_dhcp_ftp ( netdev, &filename[4] );
148
+	}
149
+	/*
150
+	if ( strncmp ( filename, "hello:", 6 ) == 0 ) {
113 151
 		return test_dhcp_hello ( &filename[6] );
114
-	} else if ( strncmp ( filename, "http:", 5 ) == 0 ) {
152
+	}
153
+	if ( strncmp ( filename, "http:", 5 ) == 0 ) {
115 154
 		return test_dhcp_http ( netdev, filename );
116
-	} else {
117
-		return test_dhcp_tftp ( netdev, filename );
118 155
 	}
156
+	return test_dhcp_tftp ( netdev, filename );
157
+	*/
158
+	return -EPROTONOSUPPORT;
119 159
 }
120 160
 
121 161
 int test_dhcp ( struct net_device *netdev ) {

+ 3
- 4
src/tests/ftptest.c Просмотреть файл

@@ -22,15 +22,14 @@ static void test_ftp_callback ( char *data, size_t len ) {
22 22
 	}
23 23
 }
24 24
 
25
-void test_ftp ( struct in_addr server, const char *filename ) {
25
+void test_ftp ( struct sockaddr_tcpip *server, const char *filename ) {
26 26
 	struct ftp_request ftp;
27 27
 	int rc;
28 28
 
29
-	printf ( "FTP fetching %s:%s\n", inet_ntoa ( server ), filename );
29
+	printf ( "FTP fetching %s\n", filename );
30 30
 	
31 31
 	memset ( &ftp, 0, sizeof ( ftp ) );
32
-	ftp.tcp.sin.sin_addr.s_addr = server.s_addr;
33
-	ftp.tcp.sin.sin_port = htons ( FTP_PORT );
32
+	memcpy ( &ftp.tcp.peer, server, sizeof ( ftp.tcp.peer ) );
34 33
 	ftp.filename = filename;
35 34
 	ftp.callback = test_ftp_callback;
36 35
 

Загрузка…
Отмена
Сохранить