Переглянути джерело

Merge TCP aborted(), timedout() and closed() methods into a single

closed() method with a reason code.
tags/v0.9.3
Michael Brown 18 роки тому
джерело
коміт
9e1becaf8a
6 змінених файлів з 131 додано та 102 видалено
  1. 6
    0
      src/include/gpxe/ftp.h
  2. 11
    15
      src/include/gpxe/tcp.h
  3. 9
    12
      src/net/tcp.c
  4. 101
    43
      src/net/tcp/ftp.c
  5. 3
    19
      src/net/tcp/hello.c
  6. 1
    13
      src/proto/iscsi.c

+ 6
- 0
src/include/gpxe/ftp.h Переглянути файл

@@ -10,6 +10,12 @@
10 10
 #include <stdint.h>
11 11
 #include <gpxe/tcp.h>
12 12
 
13
+/**
14
+ * FTP states
15
+ *
16
+ * These @b must be sequential, i.e. a successful FTP session must
17
+ * pass through each of these states in order.
18
+ */
13 19
 enum ftp_state {
14 20
 	FTP_CONNECT = 0,
15 21
 	FTP_USER,

+ 11
- 15
src/include/gpxe/tcp.h Переглянути файл

@@ -19,28 +19,24 @@ struct tcp_connection;
19 19
  *
20 20
  */
21 21
 struct tcp_operations {
22
-	/**
23
-	 * Connection aborted (RST received)
24
-	 *
25
-	 * @v conn	TCP connection
26
-	 */
27
-	void ( * aborted ) ( struct tcp_connection *conn );
28
-	/**
29
-	 * Connection timed out
22
+	/*
23
+	 * Connection closed
30 24
 	 *
31 25
 	 * @v conn	TCP connection
32
-	 */
33
-	void ( * timedout ) ( struct tcp_connection *conn );
34
-	/**
35
-	 * Connection aborted (FIN received)
26
+	 * @v status	Error code, if any
36 27
 	 *
37
-	 * @v conn	TCP connection
28
+	 * This is called when the connection is closed for any
29
+	 * reason, including timeouts or aborts.  The status code
30
+	 * contains the negative error number, if the closure is due
31
+	 * to an error.
38 32
 	 *
39 33
 	 * Note that acked() and newdata() may be called after
40 34
 	 * closed(), if the packet containing the FIN also
41
-	 * acknowledged data or contained new data.
35
+	 * acknowledged data or contained new data.  Note also that
36
+	 * connected() may not have been called before closed(), if
37
+	 * the close is due to an error.
42 38
 	 */
43
-	void ( * closed ) ( struct tcp_connection *conn );
39
+	void ( * closed ) ( struct tcp_connection *conn, int status );
44 40
 	/**
45 41
 	 * Connection established (SYNACK received)
46 42
 	 *

+ 9
- 12
src/net/tcp.c Переглянути файл

@@ -2,6 +2,7 @@
2 2
 #include <assert.h>
3 3
 #include <byteswap.h>
4 4
 #include <latch.h>
5
+#include <errno.h>
5 6
 #include <gpxe/process.h>
6 7
 #include <gpxe/init.h>
7 8
 #include <gpxe/netdevice.h>
@@ -131,18 +132,14 @@ void uip_tcp_appcall ( void ) {
131 132
 	struct tcp_connection *conn = *( ( void ** ) uip_conn->appstate );
132 133
 	struct tcp_operations *op = conn->tcp_op;
133 134
 
134
-	assert ( conn->tcp_op->closed != NULL );
135
-	assert ( conn->tcp_op->connected != NULL );
136
-	assert ( conn->tcp_op->acked != NULL );
137
-	assert ( conn->tcp_op->newdata != NULL );
138
-	assert ( conn->tcp_op->senddata != NULL );
139
-
140
-	if ( uip_aborted() && op->aborted )
141
-		op->aborted ( conn );
142
-	if ( uip_timedout() && op->timedout )
143
-		op->timedout ( conn );
144
-	if ( uip_closed() && op->closed )
145
-		op->closed ( conn );
135
+	if ( op->closed ) {
136
+		if ( uip_aborted() )
137
+			op->closed ( conn, -ECONNABORTED );
138
+		if ( uip_timedout() )
139
+			op->closed ( conn, -ETIMEDOUT );
140
+		if ( uip_closed() )
141
+			op->closed ( conn, 0 );
142
+	}
146 143
 	if ( uip_connected() && op->connected )
147 144
 		op->connected ( conn );
148 145
 	if ( uip_acked() && op->acked )

+ 101
- 43
src/net/tcp/ftp.c Переглянути файл

@@ -12,6 +12,12 @@
12 12
  *
13 13
  */
14 14
 
15
+/*****************************************************************************
16
+ *
17
+ * FTP control channel
18
+ *
19
+ */
20
+
15 21
 /** An FTP control channel string */
16 22
 struct ftp_string {
17 23
 	/** String format */
@@ -25,8 +31,18 @@ struct ftp_string {
25 31
 	off_t data_offset;
26 32
 };
27 33
 
28
-#define ftp_string_offset( fieldname ) \
29
-	offsetof ( struct ftp_request, fieldname )
34
+/** FTP control channel strings */
35
+static const struct ftp_string ftp_strings[] = {
36
+	[FTP_CONNECT]	= { "", 0 },
37
+	[FTP_USER]	= { "USER anonymous\r\n", 0 },
38
+	[FTP_PASS]	= { "PASS etherboot@etherboot.org\r\n", 0 },
39
+	[FTP_TYPE]	= { "TYPE I\r\n", 0 },
40
+	[FTP_PASV]	= { "PASV\r\n", 0 },
41
+	[FTP_RETR]	= { "RETR %s\r\n", 
42
+			    offsetof ( struct ftp_request, filename ) },
43
+	[FTP_QUIT]	= { "QUIT\r\n", 0 },
44
+	[FTP_DONE]	= { "", 0 },
45
+};
30 46
 
31 47
 /**
32 48
  * Get data associated with an FTP control channel string
@@ -40,23 +56,23 @@ static inline const void * ftp_string_data ( struct ftp_request *ftp,
40 56
 	return * ( ( void ** ) ( ( ( void * ) ftp ) + data_offset ) );
41 57
 }
42 58
 
43
-/** FTP control channel strings */
44
-const struct ftp_string ftp_strings[] = {
45
-	[FTP_CONNECT]	= { "", 0 },
46
-	[FTP_USER]	= { "USER anonymous\r\n", 0 },
47
-	[FTP_PASS]	= { "PASS etherboot@etherboot.org\r\n", 0 },
48
-	[FTP_TYPE]	= { "TYPE I\r\n", 0 },
49
-	[FTP_PASV]	= { "PASV\r\n", 0 },
50
-	[FTP_RETR]	= { "RETR %s\r\n", ftp_string_offset ( filename ) },
51
-	[FTP_QUIT]	= { "QUIT\r\n", 0 },
52
-	[FTP_DONE]	= { "", 0 },
53
-};
54
-
55
-static inline struct ftp_request *
56
-tcp_to_ftp ( struct tcp_connection *conn ) {
59
+/**
60
+ * Get FTP request from control TCP connection
61
+ *
62
+ * @v conn		TCP connection
63
+ * @ret ftp		FTP request
64
+ */
65
+static inline struct ftp_request * tcp_to_ftp ( struct tcp_connection *conn ) {
57 66
 	return container_of ( conn, struct ftp_request, tcp );
58 67
 }
59 68
 
69
+/**
70
+ * Mark FTP request as complete
71
+ *
72
+ * @v ftp		FTP request
73
+ * @v complete		Completion indicator
74
+ *
75
+ */
60 76
 static void ftp_complete ( struct ftp_request *ftp, int complete ) {
61 77
 	ftp->complete = complete;
62 78
 	tcp_close ( &ftp->tcp_data );
@@ -87,7 +103,7 @@ static void ftp_parse_value ( char **text, uint8_t *value, size_t len ) {
87 103
 }
88 104
 
89 105
 /**
90
- * Handle a response from an FTP server
106
+ * Handle an FTP control channel response
91 107
  *
92 108
  * @v ftp	FTP request
93 109
  *
@@ -132,6 +148,16 @@ static void ftp_reply ( struct ftp_request *ftp ) {
132 148
 	ftp_complete ( ftp, -EPROTO );
133 149
 }
134 150
 
151
+/**
152
+ * Handle new data arriving on FTP control channel
153
+ *
154
+ * @v conn	TCP connection
155
+ * @v data	New data
156
+ * @v len	Length of new data
157
+ *
158
+ * Data is collected until a complete line is received, at which point
159
+ * its information is passed to ftp_reply().
160
+ */
135 161
 static void ftp_newdata ( struct tcp_connection *conn,
136 162
 			  void *data, size_t len ) {
137 163
 	struct ftp_request *ftp = tcp_to_ftp ( conn );
@@ -178,6 +204,11 @@ static void ftp_newdata ( struct tcp_connection *conn,
178 204
 	ftp->recvsize = recvsize;
179 205
 }
180 206
 
207
+/**
208
+ * Handle acknowledgement of data sent on FTP control channel
209
+ *
210
+ * @v conn	TCP connection
211
+ */
181 212
 static void ftp_acked ( struct tcp_connection *conn, size_t len ) {
182 213
 	struct ftp_request *ftp = tcp_to_ftp ( conn );
183 214
 	
@@ -185,6 +216,11 @@ static void ftp_acked ( struct tcp_connection *conn, size_t len ) {
185 216
 	ftp->already_sent += len;
186 217
 }
187 218
 
219
+/**
220
+ * Construct data to send on FTP control channel
221
+ *
222
+ * @v conn	TCP connection
223
+ */
188 224
 static void ftp_senddata ( struct tcp_connection *conn ) {
189 225
 	struct ftp_request *ftp = tcp_to_ftp ( conn );
190 226
 	const struct ftp_string *string;
@@ -200,50 +236,72 @@ static void ftp_senddata ( struct tcp_connection *conn ) {
200 236
 		   len - ftp->already_sent );
201 237
 }
202 238
 
203
-static void ftp_aborted ( struct tcp_connection *conn ) {
204
-	struct ftp_request *ftp = tcp_to_ftp ( conn );
205
-
206
-	ftp_complete ( ftp, -ECONNABORTED );
207
-}
208
-
209
-static void ftp_timedout ( struct tcp_connection *conn ) {
210
-	struct ftp_request *ftp = tcp_to_ftp ( conn );
211
-
212
-	ftp_complete ( ftp, -ETIMEDOUT );
213
-}
214
-
215
-static void ftp_closed ( struct tcp_connection *conn ) {
239
+/**
240
+ * Handle control channel being closed
241
+ *
242
+ * @v conn		TCP connection
243
+ *
244
+ * When the control channel is closed, the data channel must also be
245
+ * closed, if it is currently open.
246
+ */
247
+static void ftp_closed ( struct tcp_connection *conn, int status ) {
216 248
 	struct ftp_request *ftp = tcp_to_ftp ( conn );
217 249
 
218
-	ftp_complete ( ftp, 1 );
250
+	ftp_complete ( ftp, status ? status : 1 );
219 251
 }
220 252
 
253
+/** FTP control channel operations */
221 254
 static struct tcp_operations ftp_tcp_operations = {
222
-	.aborted	= ftp_aborted,
223
-	.timedout	= ftp_timedout,
224 255
 	.closed		= ftp_closed,
225 256
 	.acked		= ftp_acked,
226 257
 	.newdata	= ftp_newdata,
227 258
 	.senddata	= ftp_senddata,
228 259
 };
229 260
 
261
+/*****************************************************************************
262
+ *
263
+ * FTP control channel
264
+ *
265
+ */
266
+
267
+/**
268
+ * Get FTP request from data TCP connection
269
+ *
270
+ * @v conn		TCP connection
271
+ * @ret ftp		FTP request
272
+ */
230 273
 static inline struct ftp_request *
231 274
 tcp_to_ftp_data ( struct tcp_connection *conn ) {
232 275
 	return container_of ( conn, struct ftp_request, tcp_data );
233 276
 }
234 277
 
235
-static void ftp_data_aborted ( struct tcp_connection *conn ) {
236
-	struct ftp_request *ftp = tcp_to_ftp_data ( conn );
237
-
238
-	ftp_complete ( ftp, -ECONNABORTED );
239
-}
240
-
241
-static void ftp_data_timedout ( struct tcp_connection *conn ) {
278
+/**
279
+ * Handle data channel being closed
280
+ *
281
+ * @v conn		TCP connection
282
+ *
283
+ * When the data channel is closed, the control channel should be left
284
+ * alone; the server will send a completion message via the control
285
+ * channel which we'll pick up.
286
+ *
287
+ * If the data channel is closed due to an error, we abort the request.
288
+ */
289
+static void ftp_data_closed ( struct tcp_connection *conn, int status ) {
242 290
 	struct ftp_request *ftp = tcp_to_ftp_data ( conn );
243 291
 
244
-	ftp_complete ( ftp, -ETIMEDOUT );
292
+	if ( status )
293
+		ftp_complete ( ftp, status );
245 294
 }
246 295
 
296
+/**
297
+ * Handle new data arriving on the FTP data channel
298
+ *
299
+ * @v conn	TCP connection
300
+ * @v data	New data
301
+ * @v len	Length of new data
302
+ *
303
+ * Data is handed off to the callback registered in the FTP request.
304
+ */
247 305
 static void ftp_data_newdata ( struct tcp_connection *conn,
248 306
 			       void *data, size_t len ) {
249 307
 	struct ftp_request *ftp = tcp_to_ftp_data ( conn );
@@ -251,9 +309,9 @@ static void ftp_data_newdata ( struct tcp_connection *conn,
251 309
 	ftp->callback ( data, len );
252 310
 }
253 311
 
312
+/** FTP data channel operations */
254 313
 static struct tcp_operations ftp_data_tcp_operations = {
255
-	.aborted	= ftp_data_aborted,
256
-	.timedout	= ftp_data_timedout,
314
+	.closed		= ftp_data_closed,
257 315
 	.newdata	= ftp_data_newdata,
258 316
 };
259 317
 

+ 3
- 19
src/net/tcp/hello.c Переглянути файл

@@ -13,7 +13,7 @@
13 13
  * message (hello_request::message).  Any data received from the
14 14
  * server will be passed to the callback function,
15 15
  * hello_request::callback(), and once the connection has been closed,
16
- * hello_request::complete will be set to 1.
16
+ * hello_request::complete will be set to a non-zero value.
17 17
  *
18 18
  * To use this code, do something like:
19 19
  *
@@ -49,24 +49,10 @@ tcp_to_hello ( struct tcp_connection *conn ) {
49 49
 	return container_of ( conn, struct hello_request, tcp );
50 50
 }
51 51
 
52
-static void hello_aborted ( struct tcp_connection *conn ) {
52
+static void hello_closed ( struct tcp_connection *conn, int status ) {
53 53
 	struct hello_request *hello = tcp_to_hello ( conn );
54 54
 
55
-	printf ( "Connection aborted\n" );
56
-	hello->complete = 1;
57
-}
58
-
59
-static void hello_timedout ( struct tcp_connection *conn ) {
60
-	struct hello_request *hello = tcp_to_hello ( conn );
61
-
62
-	printf ( "Connection timed out\n" );
63
-	hello->complete = 1;
64
-}
65
-
66
-static void hello_closed ( struct tcp_connection *conn ) {
67
-	struct hello_request *hello = tcp_to_hello ( conn );
68
-
69
-	hello->complete = 1;
55
+	hello->complete = ( status ? status : 1 );
70 56
 }
71 57
 
72 58
 static void hello_connected ( struct tcp_connection *conn ) {
@@ -113,8 +99,6 @@ static void hello_senddata ( struct tcp_connection *conn ) {
113 99
 }
114 100
 
115 101
 static struct tcp_operations hello_tcp_operations = {
116
-	.aborted	= hello_aborted,
117
-	.timedout	= hello_timedout,
118 102
 	.closed		= hello_closed,
119 103
 	.connected	= hello_connected,
120 104
 	.acked		= hello_acked,

+ 1
- 13
src/proto/iscsi.c Переглянути файл

@@ -251,17 +251,7 @@ tcp_to_iscsi ( struct tcp_connection *conn ) {
251 251
 	return container_of ( conn, struct iscsi_session, tcp );
252 252
 }
253 253
 
254
-static void iscsi_aborted ( struct tcp_connection *conn ) {
255
-	struct iscsi_session *iscsi = tcp_to_iscsi ( conn );
256
-
257
-}
258
-
259
-static void iscsi_timedout ( struct tcp_connection *conn ) {
260
-	struct iscsi_session *iscsi = tcp_to_iscsi ( conn );
261
-
262
-}
263
-
264
-static void iscsi_closed ( struct tcp_connection *conn ) {
254
+static void iscsi_closed ( struct tcp_connection *conn, int status ) {
265 255
 	struct iscsi_session *iscsi = tcp_to_iscsi ( conn );
266 256
 
267 257
 }
@@ -523,8 +513,6 @@ static void iscsi_newdata ( struct tcp_connection *conn, void *data,
523 513
 
524 514
 /** iSCSI TCP operations */
525 515
 static struct tcp_operations iscsi_tcp_operations = {
526
-	.aborted	= iscsi_aborted,
527
-	.timedout	= iscsi_timedout,
528 516
 	.closed		= iscsi_closed,
529 517
 	.connected	= iscsi_connected,
530 518
 	.acked		= iscsi_acked,

Завантаження…
Відмінити
Зберегти