Browse Source

Merge changes from mcb-tcp-fixes branch.

tags/v0.9.3
Michael Brown 18 years ago
parent
commit
61ed298bc7

+ 1
- 1
src/drivers/scsi/iscsidev.c View File

63
  * @v iscsidev		iSCSI device
63
  * @v iscsidev		iSCSI device
64
  */
64
  */
65
 void fini_iscsidev ( struct iscsi_device *iscsidev ) {
65
 void fini_iscsidev ( struct iscsi_device *iscsidev ) {
66
-	async_wait ( iscsi_shutdown ( &iscsidev->iscsi ) );
66
+	iscsi_shutdown ( &iscsidev->iscsi );
67
 }
67
 }

+ 9
- 8
src/include/gpxe/ftp.h View File

36
  *
36
  *
37
  */
37
  */
38
 struct ftp_request {
38
 struct ftp_request {
39
-	/** TCP connection for this request */
40
-	struct tcp_connection tcp;
39
+	/** Server address */
40
+	struct sockaddr_tcpip server;
41
 	/** File to download */
41
 	/** File to download */
42
 	const char *filename;
42
 	const char *filename;
43
 	/** Callback function
43
 	/** Callback function
49
 	 * remote server.
49
 	 * remote server.
50
 	 */
50
 	 */
51
 	void ( *callback ) ( char *data, size_t len );
51
 	void ( *callback ) ( char *data, size_t len );
52
-	/** Eventual return status */
53
-	int rc;
54
-	/** Asynchronous operation for this FTP operation */
55
-	struct async_operation aop;
56
 
52
 
57
 	/** Current state */
53
 	/** Current state */
58
 	enum ftp_state state;
54
 	enum ftp_state state;
67
 	/** Passive-mode parameters, as text */
63
 	/** Passive-mode parameters, as text */
68
 	char passive_text[24]; /* "aaa,bbb,ccc,ddd,eee,fff" */
64
 	char passive_text[24]; /* "aaa,bbb,ccc,ddd,eee,fff" */
69
 
65
 
70
-	/** TCP connection for the data channel */
71
-	struct tcp_connection tcp_data;
66
+	/** TCP application for the control channel */
67
+	struct tcp_application tcp;
68
+	/** TCP application for the data channel */
69
+	struct tcp_application tcp_data;
70
+
71
+	/** Asynchronous operation for this FTP operation */
72
+	struct async_operation aop;
72
 };
73
 };
73
 
74
 
74
 struct async_operation * ftp_get ( struct ftp_request *ftp );
75
 struct async_operation * ftp_get ( struct ftp_request *ftp );

+ 11
- 6
src/include/gpxe/hello.h View File

21
  *
21
  *
22
  */
22
  */
23
 struct hello_request {
23
 struct hello_request {
24
-	/** TCP connection for this request */
25
-	struct tcp_connection tcp;
26
-	/** Current state */
27
-	enum hello_state state;
24
+	/** Server to connect to */
25
+	struct sockaddr_tcpip server;
28
 	/** Message to be transmitted */
26
 	/** Message to be transmitted */
29
 	const char *message;
27
 	const char *message;
30
-	/** Amount of message remaining to be transmitted */
31
-	size_t remaining;
32
 	/** Callback function
28
 	/** Callback function
33
 	 *
29
 	 *
34
 	 * @v data	Received data
30
 	 * @v data	Received data
38
 	 * remote server.
34
 	 * remote server.
39
 	 */
35
 	 */
40
 	void ( *callback ) ( char *data, size_t len );
36
 	void ( *callback ) ( char *data, size_t len );
37
+
38
+	/** Current state */
39
+	enum hello_state state;
40
+	/** Amount of message remaining to be transmitted */
41
+	size_t remaining;
42
+
43
+	/** TCP application for this request */
44
+	struct tcp_application tcp;
45
+
41
 	/** Asynchronous operation */
46
 	/** Asynchronous operation */
42
 	struct async_operation aop;
47
 	struct async_operation aop;
43
 };
48
 };

+ 4
- 2
src/include/gpxe/http.h View File

29
 struct http_request;
29
 struct http_request;
30
 
30
 
31
 struct http_request {
31
 struct http_request {
32
-	/** TCP connection for this request */
33
-	struct tcp_connection tcp;
32
+	/** Server address */
33
+	struct sockaddr_tcpip server;
34
+	/** TCP application for this request */
35
+	struct tcp_application tcp;
34
 	/** Current state */
36
 	/** Current state */
35
 	enum http_state state;
37
 	enum http_state state;
36
         /** File to download */
38
         /** File to download */

+ 18
- 26
src/include/gpxe/iscsi.h View File

486
 
486
 
487
 /** An iSCSI session */
487
 /** An iSCSI session */
488
 struct iscsi_session {
488
 struct iscsi_session {
489
-	/** TCP connection for this session */
490
-	struct tcp_connection tcp;
489
+	/** Initiator IQN */
490
+	const char *initiator_iqn;
491
+	/** Target address */
492
+	struct sockaddr_tcpip target;
493
+	/** Target IQN */
494
+	const char *target_iqn;
495
+	/** Logical Unit Number (LUN) */
496
+	uint64_t lun;
497
+	/** Username */
498
+	const char *username;
499
+	/** Password */
500
+	const char *password;
501
+
502
+	/** TCP application for this session */
503
+	struct tcp_application tcp;
491
 	/** Session status
504
 	/** Session status
492
 	 *
505
 	 *
493
 	 * This is the bitwise-OR of zero or more ISCSI_STATUS_XXX
506
 	 * This is the bitwise-OR of zero or more ISCSI_STATUS_XXX
494
 	 * constants.
507
 	 * constants.
495
 	 */
508
 	 */
496
 	int status;
509
 	int status;
497
-	/** Asynchronous operation for the current iSCSI operation */
498
-	struct async_operation aop;
499
 	/** Retry count
510
 	/** Retry count
500
 	 *
511
 	 *
501
 	 * Number of times that the connection has been retried.
512
 	 * Number of times that the connection has been retried.
502
 	 * Reset upon a successful connection.
513
 	 * Reset upon a successful connection.
503
 	 */
514
 	 */
504
 	int retry_count;
515
 	int retry_count;
505
-
506
-	/** Initiator IQN */
507
-	const char *initiator_iqn;
508
-	/** Target address
509
-	 *
510
-	 * Kept separate from the TCP connection structure because we
511
-	 * may need to handle login redirection.
512
-	 */
513
-	struct sockaddr_tcpip target;
514
-	/** Target IQN */
515
-	const char *target_iqn;
516
-	/** Logical Unit Number (LUN) */
517
-	uint64_t lun;
518
-
519
-	/** Username */
520
-	const char *username;
521
-	/** Password */
522
-	const char *password;
523
 	/** CHAP challenge/response */
516
 	/** CHAP challenge/response */
524
 	struct chap_challenge chap;
517
 	struct chap_challenge chap;
525
 
518
 
597
 	 * Set to NULL when command is complete.
590
 	 * Set to NULL when command is complete.
598
 	 */
591
 	 */
599
 	struct scsi_command *command;
592
 	struct scsi_command *command;
593
+	/** Asynchronous operation for the current iSCSI operation */
594
+	struct async_operation aop;
600
 };
595
 };
601
 
596
 
602
 /** iSCSI session is currently in the security negotiation phase */
597
 /** iSCSI session is currently in the security negotiation phase */
632
 /** Mask for all iSCSI "needs to send" flags */
627
 /** Mask for all iSCSI "needs to send" flags */
633
 #define ISCSI_STATUS_STRINGS_MASK 0xff00
628
 #define ISCSI_STATUS_STRINGS_MASK 0xff00
634
 
629
 
635
-/** iSCSI session is closing down */
636
-#define ISCSI_STATUS_CLOSING 0x00010000
637
-
638
 /** Maximum number of retries at connecting */
630
 /** Maximum number of retries at connecting */
639
 #define ISCSI_MAX_RETRIES 2
631
 #define ISCSI_MAX_RETRIES 2
640
 
632
 
641
 extern struct async_operation * iscsi_issue ( struct iscsi_session *iscsi,
633
 extern struct async_operation * iscsi_issue ( struct iscsi_session *iscsi,
642
 					      struct scsi_command *command );
634
 					      struct scsi_command *command );
643
-extern struct async_operation * iscsi_shutdown ( struct iscsi_session *iscsi );
635
+extern void iscsi_shutdown ( struct iscsi_session *iscsi );
644
 
636
 
645
 /** An iSCSI device */
637
 /** An iSCSI device */
646
 struct iscsi_device {
638
 struct iscsi_device {

+ 240
- 140
src/include/gpxe/tcp.h View File

9
  *
9
  *
10
  */
10
  */
11
 
11
 
12
-#include <stddef.h>
13
-#include <gpxe/list.h>
12
+#include "latch.h"
14
 #include <gpxe/tcpip.h>
13
 #include <gpxe/tcpip.h>
15
-#include <gpxe/pkbuff.h>
16
-#include <gpxe/retry.h>
17
 
14
 
18
-struct tcp_connection;
15
+/**
16
+ * A TCP header
17
+ */
18
+struct tcp_header {
19
+	uint16_t src;		/* Source port */
20
+	uint16_t dest;		/* Destination port */
21
+	uint32_t seq;		/* Sequence number */
22
+	uint32_t ack;		/* Acknowledgement number */
23
+	uint8_t hlen;		/* Header length (4), Reserved (4) */
24
+	uint8_t flags;		/* Reserved (2), Flags (6) */
25
+	uint16_t win;		/* Advertised window */
26
+	uint16_t csum;		/* Checksum */
27
+	uint16_t urg;		/* Urgent pointer */
28
+};
29
+
30
+/*
31
+ * TCP flags
32
+ */
33
+#define TCP_CWR		0x80
34
+#define TCP_ECE		0x40
35
+#define TCP_URG		0x20
36
+#define TCP_ACK		0x10
37
+#define TCP_PSH		0x08
38
+#define TCP_RST		0x04
39
+#define TCP_SYN		0x02
40
+#define TCP_FIN		0x01
41
+
42
+/**
43
+* @defgroup tcpstates TCP states
44
+*
45
+* The TCP state is defined by a combination of the flags that are
46
+* currently being sent in outgoing packets, the flags that have been
47
+* sent and acknowledged by the peer, and the flags that have been
48
+* received from the peer.
49
+*
50
+* @{
51
+*/
52
+
53
+/** TCP flags that are currently being sent in outgoing packets */
54
+#define TCP_STATE_SENDING(flags) ( (flags) << 0 )
55
+#define TCP_FLAGS_SENDING(state) ( ( (state) >> 0 ) & 0xff )
56
+
57
+/** TCP flags that have been acknowledged by the peer
58
+ *
59
+ * Note that this applies only to SYN and FIN.
60
+ */
61
+#define TCP_STATE_ACKED(flags) ( (flags) << 8 )
62
+#define TCP_FLAGS_ACKED(state) ( ( (state) >> 8 ) & 0x03 )
63
+
64
+/** TCP flags that have been received from the peer
65
+ *
66
+ * Note that this applies only to SYN and FIN, and that once SYN has
67
+ * been received, we should always be sending ACK.
68
+ */
69
+#define TCP_STATE_RCVD(flags) ( (flags) << 12 )
70
+#define TCP_FLAGS_RCVD(state) ( ( (state) >> 12 ) & 0x03 )
71
+
72
+/** CLOSED
73
+ *
74
+ * The connection has not yet been used for anything.
75
+ */
76
+#define TCP_CLOSED TCP_RST
77
+
78
+/** LISTEN
79
+ *
80
+ * Not currently used as a state; we have no support for listening
81
+ * connections.  Given a unique value to avoid compiler warnings.
82
+ */
83
+#define TCP_LISTEN 0
84
+
85
+/** SYN_SENT
86
+ *
87
+ * SYN has been sent, nothing has yet been received or acknowledged.
88
+ */
89
+#define TCP_SYN_SENT	( TCP_STATE_SENDING ( TCP_SYN ) )
90
+
91
+/** SYN_RCVD
92
+ *
93
+ * SYN has been sent but not acknowledged, SYN has been received.
94
+ */
95
+#define TCP_SYN_RCVD	( TCP_STATE_SENDING ( TCP_SYN | TCP_ACK ) |	\
96
+			  TCP_STATE_RCVD ( TCP_SYN ) )
97
+
98
+/** ESTABLISHED
99
+ *
100
+ * SYN has been sent and acknowledged, SYN has been received.
101
+ */
102
+#define TCP_ESTABLISHED	( TCP_STATE_SENDING ( TCP_ACK ) |		\
103
+			  TCP_STATE_ACKED ( TCP_SYN ) |			\
104
+			  TCP_STATE_RCVD ( TCP_SYN ) )
105
+
106
+/** FIN_WAIT_1
107
+ *
108
+ * SYN has been sent and acknowledged, SYN has been received, FIN has
109
+ * been sent but not acknowledged, FIN has not been received.
110
+ *
111
+ * RFC 793 shows that we can enter FIN_WAIT_1 without have had SYN
112
+ * acknowledged, i.e. if the application closes the connection after
113
+ * sending and receiving SYN, but before having had SYN acknowledged.
114
+ * However, we have to *pretend* that SYN has been acknowledged
115
+ * anyway, otherwise we end up sending SYN and FIN in the same
116
+ * sequence number slot.  Therefore, when we transition from SYN_RCVD
117
+ * to FIN_WAIT_1, we have to remember to set TCP_STATE_ACKED(TCP_SYN)
118
+ * and increment our sequence number.
119
+ */
120
+#define TCP_FIN_WAIT_1	( TCP_STATE_SENDING ( TCP_ACK | TCP_FIN ) |	\
121
+			  TCP_STATE_ACKED ( TCP_SYN ) |			\
122
+			  TCP_STATE_RCVD ( TCP_SYN ) )
123
+
124
+/** FIN_WAIT_2
125
+ *
126
+ * SYN has been sent and acknowledged, SYN has been received, FIN has
127
+ * been sent and acknowledged, FIN ha not been received.
128
+ */
129
+#define TCP_FIN_WAIT_2	( TCP_STATE_SENDING ( TCP_ACK ) |		\
130
+			  TCP_STATE_ACKED ( TCP_SYN | TCP_FIN ) |	\
131
+			  TCP_STATE_RCVD ( TCP_SYN ) )
132
+
133
+/** CLOSING / LAST_ACK
134
+ *
135
+ * SYN has been sent and acknowledged, SYN has been received, FIN has
136
+ * been sent but not acknowledged, FIN has been received.
137
+ *
138
+ * This state actually encompasses both CLOSING and LAST_ACK; they are
139
+ * identical with the definition of state that we use.  I don't
140
+ * *believe* that they need to be distinguished.
141
+ */
142
+#define TCP_CLOSING_OR_LAST_ACK					\
143
+			( TCP_STATE_SENDING ( TCP_ACK | TCP_FIN ) |	\
144
+			  TCP_STATE_ACKED ( TCP_SYN ) |			\
145
+			  TCP_STATE_RCVD ( TCP_SYN | TCP_FIN ) )
146
+
147
+/** TIME_WAIT
148
+ *
149
+ * SYN has been sent and acknowledged, SYN has been received, FIN has
150
+ * been sent and acknowledged, FIN has been received.
151
+ */
152
+#define TCP_TIME_WAIT	( TCP_STATE_SENDING ( TCP_ACK ) |		\
153
+			  TCP_STATE_ACKED ( TCP_SYN | TCP_FIN ) |	\
154
+			  TCP_STATE_RCVD ( TCP_SYN | TCP_FIN ) )
155
+
156
+/** CLOSE_WAIT
157
+ *
158
+ * SYN has been sent and acknowledged, SYN has been received, FIN has
159
+ * been received.
160
+ */
161
+#define TCP_CLOSE_WAIT	( TCP_STATE_SENDING ( TCP_ACK ) |		\
162
+			  TCP_STATE_ACKED ( TCP_SYN ) |			\
163
+			  TCP_STATE_RCVD ( TCP_SYN | TCP_FIN ) )
164
+
165
+/** Can send data in current state
166
+ *
167
+ * We can send data if and only if we have had our SYN acked and we
168
+ * have not yet sent our FIN.
169
+ */
170
+#define TCP_CAN_SEND_DATA(state)					\
171
+	( ( (state) & ( TCP_STATE_ACKED ( TCP_SYN | TCP_FIN ) |		\
172
+		      TCP_STATE_SENDING ( TCP_FIN ) ) )			\
173
+	  == TCP_STATE_ACKED ( TCP_SYN ) )
174
+
175
+/** Have closed gracefully
176
+ *
177
+ * We have closed gracefully if we have both received a FIN and had
178
+ * our own FIN acked.
179
+ */
180
+#define TCP_CLOSED_GRACEFULLY(state)					\
181
+	( ( (state) & ( TCP_STATE_ACKED ( TCP_FIN ) |			\
182
+			TCP_STATE_RCVD ( TCP_FIN ) ) )			\
183
+	  == ( TCP_STATE_ACKED ( TCP_FIN ) | TCP_STATE_RCVD ( TCP_FIN ) ) )
184
+
185
+/** @} */
186
+
187
+/** Mask for TCP header length field */
188
+#define TCP_MASK_HLEN	0xf0
189
+
190
+/** Smallest port number on which a TCP connection can listen */
191
+#define TCP_MIN_PORT 1
192
+
193
+/* Some PKB constants */
194
+#define MAX_HDR_LEN	100
195
+#define MAX_PKB_LEN	1500
196
+#define MIN_PKB_LEN	MAX_HDR_LEN + 100 /* To account for padding by LL */
197
+
198
+/**
199
+ * Advertised TCP window size
200
+ *
201
+ * Our TCP window is actually limited by the amount of space available
202
+ * for RX packets in the NIC's RX ring; we tend to populate the rings
203
+ * with far fewer descriptors than a typical driver.  Since we have no
204
+ * way of knowing how much of this RX ring space will be available for
205
+ * received TCP packets (consider, for example, that they may all be
206
+ * consumed by a series of unrelated ARP requests between other
207
+ * machines on the network), it is actually not even theoretically
208
+ * possible for us to specify an accurate window size.  We therefore
209
+ * guess an arbitrary number that is empirically as large as possible
210
+ * while avoiding retransmissions due to dropped packets.
211
+ */
212
+#define TCP_WINDOW_SIZE	2048
213
+
214
+/** TCP maximum segment lifetime
215
+ *
216
+ * Currently set to 2 minutes, as per RFC 793.
217
+ */
218
+#define TCP_MSL ( 2 * 60 * TICKS_PER_SEC )
219
+
220
+struct tcp_application;
19
 
221
 
20
 /**
222
 /**
21
  * TCP operations
223
  * TCP operations
25
 	/*
227
 	/*
26
 	 * Connection closed
228
 	 * Connection closed
27
 	 *
229
 	 *
28
-	 * @v conn	TCP connection
230
+	 * @v app	TCP application
29
 	 * @v status	Error code, if any
231
 	 * @v status	Error code, if any
30
 	 *
232
 	 *
31
 	 * This is called when the connection is closed for any
233
 	 * This is called when the connection is closed for any
33
 	 * contains the negative error number, if the closure is due
235
 	 * contains the negative error number, if the closure is due
34
 	 * to an error.
236
 	 * to an error.
35
 	 *
237
 	 *
36
-	 * Note that acked() and newdata() may be called after
37
-	 * closed(), if the packet containing the FIN also
38
-	 * acknowledged data or contained new data.  Note also that
39
-	 * connected() may not have been called before closed(), if
40
-	 * the close is due to an error.
238
+	 * When closed() is called, the application no longer has a
239
+	 * valid TCP connection.  Note that connected() may not have
240
+	 * been called before closed(), if the close is due to an
241
+	 * error during connection setup.
41
 	 */
242
 	 */
42
-	void ( * closed ) ( struct tcp_connection *conn, int status );
243
+	void ( * closed ) ( struct tcp_application *app, int status );
43
 	/**
244
 	/**
44
-	 * Connection established (SYNACK received)
245
+	 * Connection established
45
 	 *
246
 	 *
46
-	 * @v conn	TCP connection
247
+	 * @v app	TCP application
47
 	 */
248
 	 */
48
-	void ( * connected ) ( struct tcp_connection *conn );
249
+	void ( * connected ) ( struct tcp_application *app );
49
 	/**
250
 	/**
50
 	 * Data acknowledged
251
 	 * Data acknowledged
51
 	 *
252
 	 *
52
-	 * @v conn	TCP connection
253
+	 * @v app	TCP application
53
 	 * @v len	Length of acknowledged data
254
 	 * @v len	Length of acknowledged data
54
 	 *
255
 	 *
55
 	 * @c len is guaranteed to not exceed the outstanding amount
256
 	 * @c len is guaranteed to not exceed the outstanding amount
56
 	 * of unacknowledged data.
257
 	 * of unacknowledged data.
57
 	 */
258
 	 */
58
-	void ( * acked ) ( struct tcp_connection *conn, size_t len );
259
+	void ( * acked ) ( struct tcp_application *app, size_t len );
59
 	/**
260
 	/**
60
 	 * New data received
261
 	 * New data received
61
 	 *
262
 	 *
62
-	 * @v conn	TCP connection
263
+	 * @v app	TCP application
63
 	 * @v data	Data
264
 	 * @v data	Data
64
 	 * @v len	Length of data
265
 	 * @v len	Length of data
65
 	 */
266
 	 */
66
-	void ( * newdata ) ( struct tcp_connection *conn,
267
+	void ( * newdata ) ( struct tcp_application *app,
67
 			     void *data, size_t len );
268
 			     void *data, size_t len );
68
 	/**
269
 	/**
69
 	 * Transmit data
270
 	 * Transmit data
70
 	 *
271
 	 *
71
-	 * @v conn	TCP connection
272
+	 * @v app	TCP application
72
 	 * @v buf	Temporary data buffer
273
 	 * @v buf	Temporary data buffer
73
 	 * @v len	Length of temporary data buffer
274
 	 * @v len	Length of temporary data buffer
74
 	 *
275
 	 *
86
 	 * the buffer is not compulsory; the application may call
287
 	 * the buffer is not compulsory; the application may call
87
 	 * tcp_send() on any block of data.
288
 	 * tcp_send() on any block of data.
88
 	 */
289
 	 */
89
-	void ( * senddata ) ( struct tcp_connection *conn, void *buf,
290
+	void ( * senddata ) ( struct tcp_application *app, void *buf,
90
 			      size_t len );
291
 			      size_t len );
91
 };
292
 };
92
 
293
 
93
-#if USE_UIP
294
+struct tcp_connection;
94
 
295
 
95
 /**
296
 /**
96
- * A TCP connection
297
+ * A TCP application
97
  *
298
  *
299
+ * This data structure represents an application with a TCP connection.
98
  */
300
  */
99
-struct tcp_connection {
100
-	/** Address of the remote end of the connection */
101
-	struct sockaddr_in sin;
102
-	/** Operations table for this connection */
301
+struct tcp_application {
302
+	/** TCP connection data
303
+	 *
304
+	 * This is filled in by TCP calls that initiate a connection,
305
+	 * and reset to NULL when the connection is closed.
306
+	 */
307
+	struct tcp_connection *conn;
308
+	/** TCP connection operations table */
103
 	struct tcp_operations *tcp_op;
309
 	struct tcp_operations *tcp_op;
104
 };
310
 };
105
 
311
 
106
-extern void tcp_connect ( struct tcp_connection *conn );
107
-extern void tcp_send ( struct tcp_connection *conn, const void *data,
108
-		       size_t len );
109
-extern void tcp_kick ( struct tcp_connection *conn );
110
-extern void tcp_close ( struct tcp_connection *conn );
111
-
112
-#else
113
-
114
-#define TCP_NOMSG ""
115
-#define TCP_NOMSG_LEN 0
116
-
117
-/* Smallest port number on which a TCP connection can listen */
118
-#define TCP_MIN_PORT 1
119
-
120
-/* Some PKB constants */
121
-#define MAX_HDR_LEN	100
122
-#define MAX_PKB_LEN	1500
123
-#define MIN_PKB_LEN	MAX_HDR_LEN + 100 /* To account for padding by LL */
124
-
125
-/**
126
- * TCP states
127
- */
128
-#define TCP_CLOSED	0
129
-#define TCP_LISTEN	1
130
-#define TCP_SYN_SENT	2
131
-#define TCP_SYN_RCVD	3
132
-#define TCP_ESTABLISHED	4
133
-#define TCP_FIN_WAIT_1	5
134
-#define TCP_FIN_WAIT_2	6
135
-#define TCP_CLOSING	7
136
-#define TCP_TIME_WAIT	8
137
-#define TCP_CLOSE_WAIT	9
138
-#define TCP_LAST_ACK	10
139
-
140
-#define TCP_INVALID	11
141
-
142
-/**
143
- * A TCP connection
144
- */
145
-struct tcp_connection {
146
-	struct sockaddr_tcpip peer;	/* Remote socket address */
147
-	uint16_t local_port;		/* Local port, in network byte order */
148
-	int tcp_state;			/* TCP state */
149
-	int tcp_lstate;			/* Last TCP state */
150
-	uint32_t snd_una;		/* Lowest unacked byte on snd stream */
151
-	uint32_t snd_win;		/* Offered by remote end */
152
-	uint32_t rcv_nxt;		/* Next expected byte on rcv stream */
153
-	uint32_t rcv_win;		/* Advertised to receiver */
154
-	uint8_t tcp_flags;		/* TCP header flags */
155
-	struct list_head list;		/* List of TCP connections */
156
-	struct pk_buff *tx_pkb;		/* Transmit packet buffer */
157
-	struct retry_timer timer;	/* Retransmission timer */
158
-	struct tcp_operations *tcp_op;	/* Operations table for connection */
159
-};
160
-
161
-/** Retry timer values */
162
-#define MAX_RETRANSMITS	3
163
-
164
-/**
165
- * Connection closed status codes
166
- */
167
-#define CONN_SNDCLOSE	0
168
-#define CONN_RESTART	1
169
-#define CONN_TIMEOUT	2
170
-#define CONN_RCVCLOSE	3
171
-
172
-/**
173
- * A TCP header
174
- */
175
-struct tcp_header {
176
-	uint16_t src;		/* Source port */
177
-	uint16_t dest;		/* Destination port */
178
-	uint32_t seq;		/* Sequence number */
179
-	uint32_t ack;		/* Acknowledgement number */
180
-	uint8_t hlen;		/* Header length (4), Reserved (4) */
181
-	uint8_t flags;		/* Reserved (2), Flags (6) */
182
-	uint16_t win;		/* Advertised window */
183
-	uint16_t csum;		/* Checksum */
184
-	uint16_t urg;		/* Urgent pointer */
185
-};
186
-
187
-/**
188
- * TCP masks
189
- */
190
-#define TCP_MASK_HLEN	0xf0
191
-#define TCP_MASK_FLAGS	0x3f
192
-
193
-/**
194
- * TCP flags
195
- */
196
-#define TCP_URG		0x20
197
-#define TCP_ACK		0x10
198
-#define TCP_PSH		0x08
199
-#define TCP_RST		0x04
200
-#define TCP_SYN		0x02
201
-#define TCP_FIN		0x01
202
-
203
-extern struct tcpip_protocol tcp_protocol;
204
-
205
-static inline int tcp_closed ( struct tcp_connection *conn ) {
206
-	return ( conn->tcp_state == TCP_CLOSED );
207
-}
208
-
209
-extern void tcp_init_conn ( struct tcp_connection *conn );
210
-extern int tcp_connect ( struct tcp_connection *conn );
211
-extern int tcp_connectto ( struct tcp_connection *conn,
212
-			   struct sockaddr_tcpip *peer );
213
-extern int tcp_listen ( struct tcp_connection *conn, uint16_t port );
214
-extern int tcp_senddata ( struct tcp_connection *conn );
215
-extern int tcp_close ( struct tcp_connection *conn );
216
-
217
-extern int tcp_send ( struct tcp_connection *conn, const void *data, 
312
+extern int tcp_connect ( struct tcp_application *app,
313
+			 struct sockaddr_tcpip *peer,
314
+			 uint16_t local_port );
315
+extern void tcp_close ( struct tcp_application *app );
316
+extern int tcp_senddata ( struct tcp_application *app );
317
+extern int tcp_send ( struct tcp_application *app, const void *data, 
218
 		      size_t len );
318
 		      size_t len );
219
 
319
 
220
-#endif /* USE_UIP */
320
+extern struct tcpip_protocol tcp_protocol;
221
 
321
 
222
 #endif /* _GPXE_TCP_H */
322
 #endif /* _GPXE_TCP_H */

+ 669
- 827
src/net/tcp.c
File diff suppressed because it is too large
View File


+ 66
- 92
src/net/tcp/ftp.c View File

58
 }
58
 }
59
 
59
 
60
 /**
60
 /**
61
- * Get FTP request from control TCP connection
61
+ * Get FTP request from control TCP application
62
  *
62
  *
63
- * @v conn		TCP connection
63
+ * @v app		TCP application
64
  * @ret ftp		FTP request
64
  * @ret ftp		FTP request
65
  */
65
  */
66
-static inline struct ftp_request * tcp_to_ftp ( struct tcp_connection *conn ) {
67
-	return container_of ( conn, struct ftp_request, tcp );
66
+static inline struct ftp_request * tcp_to_ftp ( struct tcp_application *app ) {
67
+	return container_of ( app, struct ftp_request, tcp );
68
 }
68
 }
69
 
69
 
70
 /**
70
 /**
71
- * Set overall FTP operation status
71
+ * Mark FTP operation as complete
72
  *
72
  *
73
  * @v ftp		FTP request
73
  * @v ftp		FTP request
74
  * @v rc		Return status code
74
  * @v rc		Return status code
75
- *
76
- * Set the return status that will eventually be returned via
77
- * ftp_done().  If multiple errors are flagged, only the first will be
78
- * returned.
79
  */
75
  */
80
-static void ftp_set_status ( struct ftp_request *ftp, int rc ) {
81
-	if ( ! ftp->rc )
82
-		ftp->rc = rc;
83
-}
76
+static void ftp_done ( struct ftp_request *ftp, int rc ) {
84
 
77
 
85
-/**
86
- * Clear overall FTP operation status
87
- *
88
- * @v ftp		FTP request
89
- */
90
-static void ftp_clear_status ( struct ftp_request *ftp ) {
91
-	ftp->rc = 0;
92
-}
78
+	DBG ( "FTP %p completed with status %d\n", ftp, rc );
93
 
79
 
94
-/**
95
- * Mark FTP operation as complete
96
- *
97
- * @v ftp		FTP request
98
- */
99
-static void ftp_done ( struct ftp_request *ftp ) {
100
-
101
-	DBG ( "FTP %p completed with status %d\n", ftp, ftp->rc );
80
+	/* Close both TCP connections */
81
+	tcp_close ( &ftp->tcp );
82
+	tcp_close ( &ftp->tcp_data );
102
 
83
 
103
-	async_done ( &ftp->aop, ftp->rc );
84
+	/* Mark asynchronous operation as complete */
85
+	async_done ( &ftp->aop, rc );
104
 }
86
 }
105
 
87
 
106
 /**
88
 /**
131
  *
113
  *
132
  * @v ftp	FTP request
114
  * @v ftp	FTP request
133
  *
115
  *
134
- * This is called once we have received a complete repsonse line.
116
+ * This is called once we have received a complete response line.
135
  */
117
  */
136
 static void ftp_reply ( struct ftp_request *ftp ) {
118
 static void ftp_reply ( struct ftp_request *ftp ) {
137
 	char status_major = ftp->status_text[0];
119
 	char status_major = ftp->status_text[0];
147
 	 * fatal error.
129
 	 * fatal error.
148
 	 */
130
 	 */
149
 	if ( ! ( ( status_major == '2' ) ||
131
 	if ( ! ( ( status_major == '2' ) ||
150
-		 ( ( status_major == '3' ) && ( ftp->state == FTP_USER ) ) ) )
151
-		goto err;
132
+		 ( ( status_major == '3' ) && ( ftp->state == FTP_USER ) ) ) ){
133
+		/* Flag protocol error and close connections */
134
+		ftp_done ( ftp, -EPROTO );
135
+	}
152
 
136
 
153
 	/* Open passive connection when we get "PASV" response */
137
 	/* Open passive connection when we get "PASV" response */
154
 	if ( ftp->state == FTP_PASV ) {
138
 	if ( ftp->state == FTP_PASV ) {
155
 		char *ptr = ftp->passive_text;
139
 		char *ptr = ftp->passive_text;
156
-		struct sockaddr_in *sin =
157
-			( struct sockaddr_in * ) &ftp->tcp_data.peer;
158
-
159
-		sin->sin_family = AF_INET;
160
-		ftp_parse_value ( &ptr, ( uint8_t * ) &sin->sin_addr,
161
-				  sizeof ( sin->sin_addr ) );
162
-		ftp_parse_value ( &ptr, ( uint8_t * ) &sin->sin_port,
163
-				  sizeof ( sin->sin_port ) );
164
-		tcp_connect ( &ftp->tcp_data );
140
+		union {
141
+			struct sockaddr_in sin;
142
+			struct sockaddr_tcpip st;
143
+		} sa;
144
+		int rc;
145
+
146
+		sa.sin.sin_family = AF_INET;
147
+		ftp_parse_value ( &ptr, ( uint8_t * ) &sa.sin.sin_addr,
148
+				  sizeof ( sa.sin.sin_addr ) );
149
+		ftp_parse_value ( &ptr, ( uint8_t * ) &sa.sin.sin_port,
150
+				  sizeof ( sa.sin.sin_port ) );
151
+		if ( ( rc = tcp_connect ( &ftp->tcp_data, &sa.st, 0 ) ) != 0 ){
152
+			DBG ( "FTP %p could not create data connection\n",
153
+			      ftp );
154
+			ftp_done ( ftp, rc );
155
+			return;
156
+		}
165
 	}
157
 	}
166
 
158
 
167
 	/* Move to next state */
159
 	/* Move to next state */
176
 	}
168
 	}
177
 
169
 
178
 	return;
170
 	return;
179
-
180
- err:
181
-	/* Flag protocol error and close connections */
182
-	ftp_set_status ( ftp, -EPROTO );
183
-	tcp_close ( &ftp->tcp );
184
 }
171
 }
185
 
172
 
186
 /**
173
 /**
187
  * Handle new data arriving on FTP control channel
174
  * Handle new data arriving on FTP control channel
188
  *
175
  *
189
- * @v conn	TCP connection
176
+ * @v app	TCP application
190
  * @v data	New data
177
  * @v data	New data
191
  * @v len	Length of new data
178
  * @v len	Length of new data
192
  *
179
  *
193
  * Data is collected until a complete line is received, at which point
180
  * Data is collected until a complete line is received, at which point
194
  * its information is passed to ftp_reply().
181
  * its information is passed to ftp_reply().
195
  */
182
  */
196
-static void ftp_newdata ( struct tcp_connection *conn,
183
+static void ftp_newdata ( struct tcp_application *app,
197
 			  void *data, size_t len ) {
184
 			  void *data, size_t len ) {
198
-	struct ftp_request *ftp = tcp_to_ftp ( conn );
185
+	struct ftp_request *ftp = tcp_to_ftp ( app );
199
 	char *recvbuf = ftp->recvbuf;
186
 	char *recvbuf = ftp->recvbuf;
200
 	size_t recvsize = ftp->recvsize;
187
 	size_t recvsize = ftp->recvsize;
201
 	char c;
188
 	char c;
242
 /**
229
 /**
243
  * Handle acknowledgement of data sent on FTP control channel
230
  * Handle acknowledgement of data sent on FTP control channel
244
  *
231
  *
245
- * @v conn	TCP connection
232
+ * @v app	TCP application
246
  */
233
  */
247
-static void ftp_acked ( struct tcp_connection *conn, size_t len ) {
248
-	struct ftp_request *ftp = tcp_to_ftp ( conn );
234
+static void ftp_acked ( struct tcp_application *app, size_t len ) {
235
+	struct ftp_request *ftp = tcp_to_ftp ( app );
249
 	
236
 	
250
 	/* Mark off ACKed portion of the currently-transmitted data */
237
 	/* Mark off ACKed portion of the currently-transmitted data */
251
 	ftp->already_sent += len;
238
 	ftp->already_sent += len;
254
 /**
241
 /**
255
  * Construct data to send on FTP control channel
242
  * Construct data to send on FTP control channel
256
  *
243
  *
257
- * @v conn	TCP connection
244
+ * @v app	TCP application
258
  * @v buf	Temporary data buffer
245
  * @v buf	Temporary data buffer
259
  * @v len	Length of temporary data buffer
246
  * @v len	Length of temporary data buffer
260
  */
247
  */
261
-static void ftp_senddata ( struct tcp_connection *conn,
248
+static void ftp_senddata ( struct tcp_application *app,
262
 			   void *buf, size_t len ) {
249
 			   void *buf, size_t len ) {
263
-	struct ftp_request *ftp = tcp_to_ftp ( conn );
250
+	struct ftp_request *ftp = tcp_to_ftp ( app );
264
 	const struct ftp_string *string;
251
 	const struct ftp_string *string;
265
 
252
 
266
 	/* Send the as-yet-unACKed portion of the string for the
253
 	/* Send the as-yet-unACKed portion of the string for the
269
 	string = &ftp_strings[ftp->state];
256
 	string = &ftp_strings[ftp->state];
270
 	len = snprintf ( buf, len, string->format,
257
 	len = snprintf ( buf, len, string->format,
271
 			 ftp_string_data ( ftp, string->data_offset ) );
258
 			 ftp_string_data ( ftp, string->data_offset ) );
272
-	tcp_send ( conn, buf + ftp->already_sent, len - ftp->already_sent );
259
+	tcp_send ( app, buf + ftp->already_sent, len - ftp->already_sent );
273
 }
260
 }
274
 
261
 
275
 /**
262
 /**
276
  * Handle control channel being closed
263
  * Handle control channel being closed
277
  *
264
  *
278
- * @v conn		TCP connection
265
+ * @v app		TCP application
279
  *
266
  *
280
  * When the control channel is closed, the data channel must also be
267
  * When the control channel is closed, the data channel must also be
281
  * closed, if it is currently open.
268
  * closed, if it is currently open.
282
  */
269
  */
283
-static void ftp_closed ( struct tcp_connection *conn, int status ) {
284
-	struct ftp_request *ftp = tcp_to_ftp ( conn );
270
+static void ftp_closed ( struct tcp_application *app, int status ) {
271
+	struct ftp_request *ftp = tcp_to_ftp ( app );
285
 
272
 
286
 	DBG ( "FTP %p control connection closed (status %d)\n", ftp, status );
273
 	DBG ( "FTP %p control connection closed (status %d)\n", ftp, status );
287
 
274
 
288
-	/* Close data channel and record status */
289
-	ftp_set_status ( ftp, status );
290
-	tcp_close ( &ftp->tcp_data );
291
-
292
-	/* Mark FTP operation as complete if we are the last
293
-	 * connection to close
294
-	 */
295
-	if ( tcp_closed ( &ftp->tcp_data ) )
296
-		ftp_done ( ftp );
275
+	/* Complete FTP operation */
276
+	ftp_done ( ftp, status );
297
 }
277
 }
298
 
278
 
299
 /** FTP control channel operations */
279
 /** FTP control channel operations */
311
  */
291
  */
312
 
292
 
313
 /**
293
 /**
314
- * Get FTP request from data TCP connection
294
+ * Get FTP request from data TCP application
315
  *
295
  *
316
- * @v conn		TCP connection
296
+ * @v app		TCP application
317
  * @ret ftp		FTP request
297
  * @ret ftp		FTP request
318
  */
298
  */
319
 static inline struct ftp_request *
299
 static inline struct ftp_request *
320
-tcp_to_ftp_data ( struct tcp_connection *conn ) {
321
-	return container_of ( conn, struct ftp_request, tcp_data );
300
+tcp_to_ftp_data ( struct tcp_application *app ) {
301
+	return container_of ( app, struct ftp_request, tcp_data );
322
 }
302
 }
323
 
303
 
324
 /**
304
 /**
325
  * Handle data channel being closed
305
  * Handle data channel being closed
326
  *
306
  *
327
- * @v conn		TCP connection
307
+ * @v app		TCP application
328
  *
308
  *
329
  * When the data channel is closed, the control channel should be left
309
  * When the data channel is closed, the control channel should be left
330
  * alone; the server will send a completion message via the control
310
  * alone; the server will send a completion message via the control
332
  *
312
  *
333
  * If the data channel is closed due to an error, we abort the request.
313
  * If the data channel is closed due to an error, we abort the request.
334
  */
314
  */
335
-static void ftp_data_closed ( struct tcp_connection *conn, int status ) {
336
-	struct ftp_request *ftp = tcp_to_ftp_data ( conn );
315
+static void ftp_data_closed ( struct tcp_application *app, int status ) {
316
+	struct ftp_request *ftp = tcp_to_ftp_data ( app );
337
 
317
 
338
 	DBG ( "FTP %p data connection closed (status %d)\n", ftp, status );
318
 	DBG ( "FTP %p data connection closed (status %d)\n", ftp, status );
339
 	
319
 	
340
 	/* If there was an error, close control channel and record status */
320
 	/* If there was an error, close control channel and record status */
341
-	if ( status ) {
342
-		ftp_set_status ( ftp, status );
343
-		tcp_close ( &ftp->tcp );
344
-	}
345
-
346
-	/* Mark FTP operation as complete if we are the last
347
-	 * connection to close
348
-	 */
349
-	if ( tcp_closed ( &ftp->tcp ) )
350
-		ftp_done ( ftp );
321
+	if ( status )
322
+		ftp_done ( ftp, status );
351
 }
323
 }
352
 
324
 
353
 /**
325
 /**
354
  * Handle new data arriving on the FTP data channel
326
  * Handle new data arriving on the FTP data channel
355
  *
327
  *
356
- * @v conn	TCP connection
328
+ * @v app	TCP application
357
  * @v data	New data
329
  * @v data	New data
358
  * @v len	Length of new data
330
  * @v len	Length of new data
359
  *
331
  *
360
  * Data is handed off to the callback registered in the FTP request.
332
  * Data is handed off to the callback registered in the FTP request.
361
  */
333
  */
362
-static void ftp_data_newdata ( struct tcp_connection *conn,
334
+static void ftp_data_newdata ( struct tcp_application *app,
363
 			       void *data, size_t len ) {
335
 			       void *data, size_t len ) {
364
-	struct ftp_request *ftp = tcp_to_ftp_data ( conn );
336
+	struct ftp_request *ftp = tcp_to_ftp_data ( app );
365
 
337
 
366
 	ftp->callback ( data, len );
338
 	ftp->callback ( data, len );
367
 }
339
 }
384
  * @v ftp	FTP request
356
  * @v ftp	FTP request
385
  */
357
  */
386
 struct async_operation * ftp_get ( struct ftp_request *ftp ) {
358
 struct async_operation * ftp_get ( struct ftp_request *ftp ) {
387
-	
359
+	int rc;
360
+
388
 	DBG ( "FTP %p fetching %s\n", ftp, ftp->filename );
361
 	DBG ( "FTP %p fetching %s\n", ftp, ftp->filename );
389
 
362
 
390
 	ftp->tcp.tcp_op = &ftp_tcp_operations;
363
 	ftp->tcp.tcp_op = &ftp_tcp_operations;
391
 	ftp->tcp_data.tcp_op = &ftp_data_tcp_operations;
364
 	ftp->tcp_data.tcp_op = &ftp_data_tcp_operations;
392
 	ftp->recvbuf = ftp->status_text;
365
 	ftp->recvbuf = ftp->status_text;
393
 	ftp->recvsize = sizeof ( ftp->status_text ) - 1;
366
 	ftp->recvsize = sizeof ( ftp->status_text ) - 1;
394
-	ftp_clear_status ( ftp );
395
-	tcp_connect ( &ftp->tcp );
367
+	if ( ( rc = tcp_connect ( &ftp->tcp, &ftp->server, 0 ) ) != 0 )
368
+		ftp_done ( ftp, rc );
369
+
396
 	return &ftp->aop;
370
 	return &ftp->aop;
397
 }
371
 }

+ 24
- 20
src/net/tcp/hello.c View File

10
  * "Hello world" TCP protocol
10
  * "Hello world" TCP protocol
11
  *
11
  *
12
  * This file implements a trivial TCP-based protocol.  It connects to
12
  * This file implements a trivial TCP-based protocol.  It connects to
13
- * the server specified in hello_request::tcp and transmits a single
14
- * message (hello_request::message).  Any data received from the
15
- * server will be passed to the callback function,
13
+ * the server specified in hello_request::server and transmits a
14
+ * single message (hello_request::message).  Any data received from
15
+ * the server will be passed to the callback function,
16
  * hello_request::callback(), and once the connection has been closed,
16
  * hello_request::callback(), and once the connection has been closed,
17
  * the asynchronous operation associated with the request will be
17
  * the asynchronous operation associated with the request will be
18
  * marked as complete.
18
  * marked as complete.
26
  *   }
26
  *   }
27
  *
27
  *
28
  *   struct hello_request hello = {
28
  *   struct hello_request hello = {
29
+ *     .server = {
30
+ *       ...
31
+ *     },
29
  *     .message = "hello world!",
32
  *     .message = "hello world!",
30
  *     .callback = my_callback,
33
  *     .callback = my_callback,
31
  *   };
34
  *   };
32
  *
35
  *
33
- *   hello.sin.sin_addr.s_addr = ... server IP address ...
34
- *   hello.sin.sin_port = ... server port ...
35
- *
36
  *   rc = async_wait ( say_hello ( &hello ) );
36
  *   rc = async_wait ( say_hello ( &hello ) );
37
  *
37
  *
38
  * @endcode
38
  * @endcode
44
  */
44
  */
45
 
45
 
46
 static inline struct hello_request *
46
 static inline struct hello_request *
47
-tcp_to_hello ( struct tcp_connection *conn ) {
48
-	return container_of ( conn, struct hello_request, tcp );
47
+tcp_to_hello ( struct tcp_application *app ) {
48
+	return container_of ( app, struct hello_request, tcp );
49
 }
49
 }
50
 
50
 
51
-static void hello_closed ( struct tcp_connection *conn, int status ) {
52
-	struct hello_request *hello = tcp_to_hello ( conn );
51
+static void hello_closed ( struct tcp_application *app, int status ) {
52
+	struct hello_request *hello = tcp_to_hello ( app );
53
 
53
 
54
 	async_done ( &hello->aop, status );
54
 	async_done ( &hello->aop, status );
55
 }
55
 }
56
 
56
 
57
-static void hello_connected ( struct tcp_connection *conn ) {
58
-	struct hello_request *hello = tcp_to_hello ( conn );
57
+static void hello_connected ( struct tcp_application *app ) {
58
+	struct hello_request *hello = tcp_to_hello ( app );
59
 
59
 
60
 	hello->remaining = strlen ( hello->message );
60
 	hello->remaining = strlen ( hello->message );
61
 	hello->state = HELLO_SENDING_MESSAGE;
61
 	hello->state = HELLO_SENDING_MESSAGE;
62
 }
62
 }
63
 
63
 
64
-static void hello_acked ( struct tcp_connection *conn, size_t len ) {
65
-	struct hello_request *hello = tcp_to_hello ( conn );
64
+static void hello_acked ( struct tcp_application *app, size_t len ) {
65
+	struct hello_request *hello = tcp_to_hello ( app );
66
 	
66
 	
67
 	hello->message += len;
67
 	hello->message += len;
68
 	hello->remaining -= len;
68
 	hello->remaining -= len;
84
 	}
84
 	}
85
 }
85
 }
86
 
86
 
87
-static void hello_newdata ( struct tcp_connection *conn, void *data,
87
+static void hello_newdata ( struct tcp_application *app, void *data,
88
 			    size_t len ) {
88
 			    size_t len ) {
89
-	struct hello_request *hello = tcp_to_hello ( conn );
89
+	struct hello_request *hello = tcp_to_hello ( app );
90
 
90
 
91
 	hello->callback ( data, len );
91
 	hello->callback ( data, len );
92
 }
92
 }
93
 
93
 
94
-static void hello_senddata ( struct tcp_connection *conn,
94
+static void hello_senddata ( struct tcp_application *app,
95
 			     void *buf __unused, size_t len __unused ) {
95
 			     void *buf __unused, size_t len __unused ) {
96
-	struct hello_request *hello = tcp_to_hello ( conn );
96
+	struct hello_request *hello = tcp_to_hello ( app );
97
 
97
 
98
-	tcp_send ( conn, hello->message, hello->remaining );
98
+	tcp_send ( app, hello->message, hello->remaining );
99
 }
99
 }
100
 
100
 
101
 static struct tcp_operations hello_tcp_operations = {
101
 static struct tcp_operations hello_tcp_operations = {
112
  * @v hello	"Hello world" request
112
  * @v hello	"Hello world" request
113
  */
113
  */
114
 struct async_operation * say_hello ( struct hello_request *hello ) {
114
 struct async_operation * say_hello ( struct hello_request *hello ) {
115
+	int rc;
116
+
115
 	hello->tcp.tcp_op = &hello_tcp_operations;
117
 	hello->tcp.tcp_op = &hello_tcp_operations;
116
-	tcp_connect ( &hello->tcp );
118
+	if ( ( rc = tcp_connect ( &hello->tcp, &hello->server, 0 ) ) != 0 )
119
+		async_done ( &hello->aop, rc );
120
+
117
 	return &hello->aop;
121
 	return &hello->aop;
118
 }
122
 }

+ 26
- 22
src/net/tcp/http.c View File

39
  */
39
  */
40
 
40
 
41
 static inline struct http_request *
41
 static inline struct http_request *
42
-tcp_to_http ( struct tcp_connection *conn ) {
43
-	return container_of ( conn, struct http_request, tcp );
42
+tcp_to_http ( struct tcp_application *app ) {
43
+	return container_of ( app, struct http_request, tcp );
44
 }
44
 }
45
 
45
 
46
 /**
46
 /**
47
  * Close an HTTP connection
47
  * Close an HTTP connection
48
  *
48
  *
49
- * @v conn	a TCP Connection
49
+ * @v app	a TCP Application
50
  * @v status	connection status at close
50
  * @v status	connection status at close
51
  */
51
  */
52
-static void http_closed ( struct tcp_connection *conn, int status ) {
53
-	struct http_request *http = tcp_to_http ( conn );
52
+static void http_closed ( struct tcp_application *app, int status ) {
53
+	struct http_request *http = tcp_to_http ( app );
54
 	async_done ( &http->aop, status );
54
 	async_done ( &http->aop, status );
55
 }
55
 }
56
 
56
 
57
 /**
57
 /**
58
  * Callback after a TCP connection is established
58
  * Callback after a TCP connection is established
59
  *
59
  *
60
- * @v conn	a TCP Connection
60
+ * @v app	a TCP Application
61
  */
61
  */
62
-static void http_connected ( struct tcp_connection *conn ) {
63
-	struct http_request *http = tcp_to_http ( conn );
62
+static void http_connected ( struct tcp_application *app ) {
63
+	struct http_request *http = tcp_to_http ( app );
64
 
64
 
65
 	http->state = HTTP_REQUEST_FILE;
65
 	http->state = HTTP_REQUEST_FILE;
66
 }
66
 }
68
 /**
68
 /**
69
  * Callback for when TCP data is acknowledged
69
  * Callback for when TCP data is acknowledged
70
  *
70
  *
71
- * @v conn	a TCP Connection
71
+ * @v app	a TCP Application
72
  * @v len	the length of data acked
72
  * @v len	the length of data acked
73
  */
73
  */
74
-static void http_acked ( struct tcp_connection *conn, size_t len __attribute__ ((unused)) ) {
75
-	struct http_request *http = tcp_to_http ( conn );
74
+static void http_acked ( struct tcp_application *app, size_t len __attribute__ ((unused)) ) {
75
+	struct http_request *http = tcp_to_http ( app );
76
 
76
 
77
 	// assume that the whole GET request was sent in on epacket
77
 	// assume that the whole GET request was sent in on epacket
78
 
78
 
84
 	case HTTP_RECV_FILE:
84
 	case HTTP_RECV_FILE:
85
 		break;
85
 		break;
86
 	case HTTP_DONE:
86
 	case HTTP_DONE:
87
-		//tcp_close(conn);
87
+		//tcp_close(app);
88
 		break;
88
 		break;
89
 	default:
89
 	default:
90
 		break;
90
 		break;
95
 /**
95
 /**
96
  * Callback when new TCP data is recieved
96
  * Callback when new TCP data is recieved
97
  *
97
  *
98
- * @v conn	a TCP Connection
98
+ * @v app	a TCP Application
99
  * @v data	a pointer to the data recieved
99
  * @v data	a pointer to the data recieved
100
  * @v len	length of data buffer
100
  * @v len	length of data buffer
101
  */
101
  */
102
-static void http_newdata ( struct tcp_connection *conn, void *data,
102
+static void http_newdata ( struct tcp_application *app, void *data,
103
 			    size_t len ) {
103
 			    size_t len ) {
104
-	struct http_request *http = tcp_to_http ( conn );
104
+	struct http_request *http = tcp_to_http ( app );
105
 	char *content_length;
105
 	char *content_length;
106
 	char *start = data;
106
 	char *start = data;
107
 	char *rcp; int rc;
107
 	char *rcp; int rc;
142
 		//printf("File recv is %d\n", http->file_recv);
142
 		//printf("File recv is %d\n", http->file_recv);
143
 		if ( http->file_recv == http->file_size ){
143
 		if ( http->file_recv == http->file_size ){
144
 			http->state = HTTP_DONE;
144
 			http->state = HTTP_DONE;
145
-			tcp_close(conn);
145
+			tcp_close(app);
146
 		}
146
 		}
147
 		break;
147
 		break;
148
 	case HTTP_REQUEST_FILE:
148
 	case HTTP_REQUEST_FILE:
155
 /**
155
 /**
156
  * Callback for sending TCP data
156
  * Callback for sending TCP data
157
  *
157
  *
158
- * @v conn	a TCP Connection
158
+ * @v app	a TCP Application
159
  */
159
  */
160
-static void http_senddata ( struct tcp_connection *conn, void *buf, size_t len ) {
161
-	struct http_request *http = tcp_to_http ( conn );
160
+static void http_senddata ( struct tcp_application *app, void *buf, size_t len ) {
161
+	struct http_request *http = tcp_to_http ( app );
162
 
162
 
163
 	switch ( http->state ){
163
 	switch ( http->state ){
164
 	case HTTP_REQUEST_FILE:
164
 	case HTTP_REQUEST_FILE:
166
 		printf("%s\n",(char *)buf);
166
 		printf("%s\n",(char *)buf);
167
         	// string is: GET <file> HTTP/1.0\r\n\r\n
167
         	// string is: GET <file> HTTP/1.0\r\n\r\n
168
 
168
 
169
-		tcp_send ( conn, buf, len);
169
+		tcp_send ( app, buf, len);
170
 		break;
170
 		break;
171
 	case HTTP_PARSE_HEADER:
171
 	case HTTP_PARSE_HEADER:
172
 	case HTTP_RECV_FILE:
172
 	case HTTP_RECV_FILE:
173
 		break;
173
 		break;
174
 	case HTTP_DONE:
174
 	case HTTP_DONE:
175
-		//tcp_close(conn)
175
+		//tcp_close(app)
176
 		break;
176
 		break;
177
 	default:
177
 	default:
178
 		break;
178
 		break;
193
  * @v http	a HTTP request
193
  * @v http	a HTTP request
194
  */
194
  */
195
 struct async_operation * get_http ( struct http_request *http ) {
195
 struct async_operation * get_http ( struct http_request *http ) {
196
+	int rc;
197
+
196
 	http->tcp.tcp_op = &http_tcp_operations;
198
 	http->tcp.tcp_op = &http_tcp_operations;
197
 	http->state = HTTP_REQUEST_FILE;
199
 	http->state = HTTP_REQUEST_FILE;
198
-	tcp_connect ( &http->tcp );
200
+	if ( ( rc = tcp_connect ( &http->tcp, &http->server, 0 ) ) != 0 )
201
+		async_done ( &http->aop, rc );
202
+
199
 	return &http->aop;
203
 	return &http->aop;
200
 }
204
 }

+ 41
- 46
src/net/tcp/iscsi.c View File

720
 	/* Check for login redirection */
720
 	/* Check for login redirection */
721
 	if ( response->status_class == ISCSI_STATUS_REDIRECT ) {
721
 	if ( response->status_class == ISCSI_STATUS_REDIRECT ) {
722
 		DBG ( "iSCSI %p redirecting to new server\n", iscsi );
722
 		DBG ( "iSCSI %p redirecting to new server\n", iscsi );
723
-		/* Close the TCP connection; our TCP closed() method
724
-		 * will take care of the reconnection once this
725
-		 * connection has been cleanly terminated.
726
-		 */
727
 		tcp_close ( &iscsi->tcp );
723
 		tcp_close ( &iscsi->tcp );
724
+		iscsi->status = 0;
725
+		if ( ( rc = tcp_connect ( &iscsi->tcp, &iscsi->target,
726
+					  0 ) ) != 0 ) {
727
+			DBG ( "iSCSI %p could not open TCP connection\n",
728
+			      iscsi );
729
+			iscsi_done ( iscsi, rc );
730
+		}
728
 		return;
731
 		return;
729
 	}
732
 	}
730
 
733
 
778
  */
781
  */
779
 
782
 
780
 static inline struct iscsi_session *
783
 static inline struct iscsi_session *
781
-tcp_to_iscsi ( struct tcp_connection *conn ) {
782
-	return container_of ( conn, struct iscsi_session, tcp );
784
+tcp_to_iscsi ( struct tcp_application *app ) {
785
+	return container_of ( app, struct iscsi_session, tcp );
783
 }
786
 }
784
 
787
 
785
 /**
788
 /**
859
  * Updates iscsi->tx_offset and, if applicable, transitions to the
862
  * Updates iscsi->tx_offset and, if applicable, transitions to the
860
  * next TX state.
863
  * next TX state.
861
  */
864
  */
862
-static void iscsi_acked ( struct tcp_connection *conn, size_t len ) {
863
-	struct iscsi_session *iscsi = tcp_to_iscsi ( conn );
865
+static void iscsi_acked ( struct tcp_application *app, size_t len ) {
866
+	struct iscsi_session *iscsi = tcp_to_iscsi ( app );
864
 	struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
867
 	struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
865
 	enum iscsi_tx_state next_state;
868
 	enum iscsi_tx_state next_state;
866
 	
869
 	
916
  * 
919
  * 
917
  * Constructs data to be sent for the current TX state
920
  * Constructs data to be sent for the current TX state
918
  */
921
  */
919
-static void iscsi_senddata ( struct tcp_connection *conn,
922
+static void iscsi_senddata ( struct tcp_application *app,
920
 			     void *buf, size_t len ) {
923
 			     void *buf, size_t len ) {
921
-	struct iscsi_session *iscsi = tcp_to_iscsi ( conn );
924
+	struct iscsi_session *iscsi = tcp_to_iscsi ( app );
922
 	struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
925
 	struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
923
 	static const char pad[] = { '\0', '\0', '\0' };
926
 	static const char pad[] = { '\0', '\0', '\0' };
924
 
927
 
927
 		/* Nothing to send */
930
 		/* Nothing to send */
928
 		break;
931
 		break;
929
 	case ISCSI_TX_BHS:
932
 	case ISCSI_TX_BHS:
930
-		tcp_send ( conn, &iscsi->tx_bhs.bytes[iscsi->tx_offset],
933
+		tcp_send ( app, &iscsi->tx_bhs.bytes[iscsi->tx_offset],
931
 			   ( sizeof ( iscsi->tx_bhs ) - iscsi->tx_offset ) );
934
 			   ( sizeof ( iscsi->tx_bhs ) - iscsi->tx_offset ) );
932
 		break;
935
 		break;
933
 	case ISCSI_TX_AHS:
936
 	case ISCSI_TX_AHS:
938
 		iscsi_tx_data ( iscsi, buf, len );
941
 		iscsi_tx_data ( iscsi, buf, len );
939
 		break;
942
 		break;
940
 	case ISCSI_TX_DATA_PADDING:
943
 	case ISCSI_TX_DATA_PADDING:
941
-		tcp_send ( conn, pad, ( ISCSI_DATA_PAD_LEN ( common->lengths )
944
+		tcp_send ( app, pad, ( ISCSI_DATA_PAD_LEN ( common->lengths )
942
 					- iscsi->tx_offset ) );
945
 					- iscsi->tx_offset ) );
943
 		break;
946
 		break;
944
 	default:
947
 	default:
1029
 /**
1032
 /**
1030
  * Receive new data
1033
  * Receive new data
1031
  *
1034
  *
1032
- * @v tcp		TCP connection
1035
+ * @v tcp		TCP application
1033
  * @v data		Received data
1036
  * @v data		Received data
1034
  * @v len		Length of received data
1037
  * @v len		Length of received data
1035
  *
1038
  *
1040
  * always has a full copy of the BHS available, even for portions of
1043
  * always has a full copy of the BHS available, even for portions of
1041
  * the data in different packets to the BHS.
1044
  * the data in different packets to the BHS.
1042
  */
1045
  */
1043
-static void iscsi_newdata ( struct tcp_connection *conn, void *data,
1046
+static void iscsi_newdata ( struct tcp_application *app, void *data,
1044
 			    size_t len ) {
1047
 			    size_t len ) {
1045
-	struct iscsi_session *iscsi = tcp_to_iscsi ( conn );
1048
+	struct iscsi_session *iscsi = tcp_to_iscsi ( app );
1046
 	struct iscsi_bhs_common *common = &iscsi->rx_bhs.common;
1049
 	struct iscsi_bhs_common *common = &iscsi->rx_bhs.common;
1047
 	void ( *process ) ( struct iscsi_session *iscsi, void *data,
1050
 	void ( *process ) ( struct iscsi_session *iscsi, void *data,
1048
 			    size_t len, size_t remaining );
1051
 			    size_t len, size_t remaining );
1098
 	}
1101
 	}
1099
 }
1102
 }
1100
 
1103
 
1101
-#warning "Remove me soon"
1102
-static struct tcp_operations iscsi_tcp_operations;
1103
-
1104
 /**
1104
 /**
1105
  * Handle TCP connection closure
1105
  * Handle TCP connection closure
1106
  *
1106
  *
1107
- * @v conn		TCP connection
1107
+ * @v app		TCP application
1108
  * @v status		Error code, if any
1108
  * @v status		Error code, if any
1109
  *
1109
  *
1110
  */
1110
  */
1111
-static void iscsi_closed ( struct tcp_connection *conn, int status ) {
1112
-	struct iscsi_session *iscsi = tcp_to_iscsi ( conn );
1113
-	int session_status = iscsi->status;
1111
+static void iscsi_closed ( struct tcp_application *app, int status ) {
1112
+	struct iscsi_session *iscsi = tcp_to_iscsi ( app );
1113
+	int rc;
1114
 
1114
 
1115
 	/* Clear session status */
1115
 	/* Clear session status */
1116
 	iscsi->status = 0;
1116
 	iscsi->status = 0;
1117
 
1117
 
1118
-	/* If we are deliberately closing down, exit cleanly */
1119
-	if ( session_status & ISCSI_STATUS_CLOSING ) {
1120
-		iscsi_done ( iscsi, status );
1121
-		return;
1122
-	}
1123
-
1124
 	/* Retry connection if within the retry limit, otherwise fail */
1118
 	/* Retry connection if within the retry limit, otherwise fail */
1125
 	if ( ++iscsi->retry_count <= ISCSI_MAX_RETRIES ) {
1119
 	if ( ++iscsi->retry_count <= ISCSI_MAX_RETRIES ) {
1126
 		DBG ( "iSCSI %p retrying connection\n", iscsi );
1120
 		DBG ( "iSCSI %p retrying connection\n", iscsi );
1127
-		/* Re-copy address to handle redirection */
1128
-		memset ( &iscsi->tcp, 0, sizeof ( iscsi->tcp ) );
1129
-		iscsi->tcp.tcp_op = &iscsi_tcp_operations;
1130
-		memcpy ( &iscsi->tcp.peer, &iscsi->target,
1131
-			 sizeof ( iscsi->tcp.peer ) );
1132
-		tcp_connect ( conn );
1121
+		if ( ( rc = tcp_connect ( app, &iscsi->target, 0 ) ) != 0 ) {
1122
+			DBG ( "iSCSI %p could not open TCP connection\n",
1123
+			      iscsi );
1124
+			iscsi_done ( iscsi, rc );
1125
+		}
1133
 	} else {
1126
 	} else {
1134
 		printf ( "iSCSI %p retry count exceeded\n", iscsi );
1127
 		printf ( "iSCSI %p retry count exceeded\n", iscsi );
1135
 		iscsi_done ( iscsi, status );
1128
 		iscsi_done ( iscsi, status );
1139
 /**
1132
 /**
1140
  * Handle TCP connection opening
1133
  * Handle TCP connection opening
1141
  *
1134
  *
1142
- * @v conn		TCP connection
1135
+ * @v app		TCP application
1143
  *
1136
  *
1144
  */
1137
  */
1145
-static void iscsi_connected ( struct tcp_connection *conn ) {
1146
-	struct iscsi_session *iscsi = tcp_to_iscsi ( conn );
1138
+static void iscsi_connected ( struct tcp_application *app ) {
1139
+	struct iscsi_session *iscsi = tcp_to_iscsi ( app );
1147
 
1140
 
1148
 	/* Set connected flag and reset retry count */
1141
 	/* Set connected flag and reset retry count */
1149
 	iscsi->status = ( ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE |
1142
 	iscsi->status = ( ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE |
1179
  */
1172
  */
1180
 struct async_operation * iscsi_issue ( struct iscsi_session *iscsi,
1173
 struct async_operation * iscsi_issue ( struct iscsi_session *iscsi,
1181
 				       struct scsi_command *command ) {
1174
 				       struct scsi_command *command ) {
1175
+	int rc;
1176
+
1182
 	assert ( iscsi->command == NULL );
1177
 	assert ( iscsi->command == NULL );
1183
 	iscsi->command = command;
1178
 	iscsi->command = command;
1184
 
1179
 
1198
 	} else {
1193
 	} else {
1199
 		/* Session not open: initiate login */
1194
 		/* Session not open: initiate login */
1200
 		iscsi->tcp.tcp_op = &iscsi_tcp_operations;
1195
 		iscsi->tcp.tcp_op = &iscsi_tcp_operations;
1201
-		memcpy ( &iscsi->tcp.peer, &iscsi->target,
1202
-			 sizeof ( iscsi->tcp.peer ) );
1203
-		tcp_connect ( &iscsi->tcp );
1196
+		if ( ( rc = tcp_connect ( &iscsi->tcp, &iscsi->target,
1197
+					  0 ) ) != 0 ) {
1198
+			DBG ( "iSCSI %p could not open TCP connection\n",
1199
+			      iscsi );
1200
+			iscsi_done ( iscsi, rc );
1201
+		}
1204
 	}
1202
 	}
1205
 
1203
 
1206
 	return &iscsi->aop;
1204
 	return &iscsi->aop;
1212
  * @v iscsi		iSCSI session
1210
  * @v iscsi		iSCSI session
1213
  * @ret aop		Asynchronous operation
1211
  * @ret aop		Asynchronous operation
1214
  */
1212
  */
1215
-struct async_operation * iscsi_shutdown ( struct iscsi_session *iscsi ) {
1216
-	if ( iscsi->status ) {
1217
-		iscsi->status |= ISCSI_STATUS_CLOSING;
1218
-		tcp_close ( &iscsi->tcp );
1219
-	}
1220
-	return &iscsi->aop;
1213
+void iscsi_shutdown ( struct iscsi_session *iscsi ) {
1214
+	iscsi->status = 0;
1215
+	tcp_close ( &iscsi->tcp );
1221
 }
1216
 }

+ 1
- 1
src/tests/ftptest.c View File

29
 	printf ( "FTP fetching %s\n", filename );
29
 	printf ( "FTP fetching %s\n", filename );
30
 	
30
 	
31
 	memset ( &ftp, 0, sizeof ( ftp ) );
31
 	memset ( &ftp, 0, sizeof ( ftp ) );
32
-	memcpy ( &ftp.tcp.peer, server, sizeof ( ftp.tcp.peer ) );
32
+	memcpy ( &ftp.server, server, sizeof ( ftp.server ) );
33
 	ftp.filename = filename;
33
 	ftp.filename = filename;
34
 	ftp.callback = test_ftp_callback;
34
 	ftp.callback = test_ftp_callback;
35
 
35
 

+ 1
- 1
src/tests/hellotest.c View File

32
 		 inet_ntoa ( sin->sin_addr ), ntohs ( sin->sin_port ) );
32
 		 inet_ntoa ( sin->sin_addr ), ntohs ( sin->sin_port ) );
33
 	
33
 	
34
 	memset ( &hello, 0, sizeof ( hello ) );
34
 	memset ( &hello, 0, sizeof ( hello ) );
35
-	memcpy ( &hello.tcp.peer, server, sizeof ( hello.tcp.peer ) );
35
+	memcpy ( &hello.server, server, sizeof ( hello.server ) );
36
 	hello.message = message;
36
 	hello.message = message;
37
 	hello.callback = test_hello_callback;
37
 	hello.callback = test_hello_callback;
38
 
38
 

+ 1
- 1
src/tests/httptest.c View File

21
 	int rc;
21
 	int rc;
22
 
22
 
23
 	memset ( &http, 0, sizeof ( http ) );
23
 	memset ( &http, 0, sizeof ( http ) );
24
-	memcpy ( &http.tcp.peer, server, sizeof ( http.tcp.peer ) );
24
+	memcpy ( &http.server, server, sizeof ( http.server ) );
25
 	http.filename = filename;
25
 	http.filename = filename;
26
 	http.callback = test_http_callback;
26
 	http.callback = test_http_callback;
27
 
27
 

Loading…
Cancel
Save