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,5 +63,5 @@ int init_iscsidev ( struct iscsi_device *iscsidev ) {
63 63
  * @v iscsidev		iSCSI device
64 64
  */
65 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,8 +36,8 @@ enum ftp_state {
36 36
  *
37 37
  */
38 38
 struct ftp_request {
39
-	/** TCP connection for this request */
40
-	struct tcp_connection tcp;
39
+	/** Server address */
40
+	struct sockaddr_tcpip server;
41 41
 	/** File to download */
42 42
 	const char *filename;
43 43
 	/** Callback function
@@ -49,10 +49,6 @@ 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;
54
-	/** Asynchronous operation for this FTP operation */
55
-	struct async_operation aop;
56 52
 
57 53
 	/** Current state */
58 54
 	enum ftp_state state;
@@ -67,8 +63,13 @@ struct ftp_request {
67 63
 	/** Passive-mode parameters, as text */
68 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 75
 struct async_operation * ftp_get ( struct ftp_request *ftp );

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

@@ -21,14 +21,10 @@ enum hello_state {
21 21
  *
22 22
  */
23 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 26
 	/** Message to be transmitted */
29 27
 	const char *message;
30
-	/** Amount of message remaining to be transmitted */
31
-	size_t remaining;
32 28
 	/** Callback function
33 29
 	 *
34 30
 	 * @v data	Received data
@@ -38,6 +34,15 @@ struct hello_request {
38 34
 	 * remote server.
39 35
 	 */
40 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 46
 	/** Asynchronous operation */
42 47
 	struct async_operation aop;
43 48
 };

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

@@ -29,8 +29,10 @@ enum http_state {
29 29
 struct http_request;
30 30
 
31 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 36
 	/** Current state */
35 37
 	enum http_state state;
36 38
         /** File to download */

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

@@ -486,40 +486,33 @@ enum iscsi_rx_state {
486 486
 
487 487
 /** An iSCSI session */
488 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 504
 	/** Session status
492 505
 	 *
493 506
 	 * This is the bitwise-OR of zero or more ISCSI_STATUS_XXX
494 507
 	 * constants.
495 508
 	 */
496 509
 	int status;
497
-	/** Asynchronous operation for the current iSCSI operation */
498
-	struct async_operation aop;
499 510
 	/** Retry count
500 511
 	 *
501 512
 	 * Number of times that the connection has been retried.
502 513
 	 * Reset upon a successful connection.
503 514
 	 */
504 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 516
 	/** CHAP challenge/response */
524 517
 	struct chap_challenge chap;
525 518
 
@@ -597,6 +590,8 @@ struct iscsi_session {
597 590
 	 * Set to NULL when command is complete.
598 591
 	 */
599 592
 	struct scsi_command *command;
593
+	/** Asynchronous operation for the current iSCSI operation */
594
+	struct async_operation aop;
600 595
 };
601 596
 
602 597
 /** iSCSI session is currently in the security negotiation phase */
@@ -632,15 +627,12 @@ struct iscsi_session {
632 627
 /** Mask for all iSCSI "needs to send" flags */
633 628
 #define ISCSI_STATUS_STRINGS_MASK 0xff00
634 629
 
635
-/** iSCSI session is closing down */
636
-#define ISCSI_STATUS_CLOSING 0x00010000
637
-
638 630
 /** Maximum number of retries at connecting */
639 631
 #define ISCSI_MAX_RETRIES 2
640 632
 
641 633
 extern struct async_operation * iscsi_issue ( struct iscsi_session *iscsi,
642 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 637
 /** An iSCSI device */
646 638
 struct iscsi_device {

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

@@ -9,13 +9,215 @@
9 9
  *
10 10
  */
11 11
 
12
-#include <stddef.h>
13
-#include <gpxe/list.h>
12
+#include "latch.h"
14 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 223
  * TCP operations
@@ -25,7 +227,7 @@ struct tcp_operations {
25 227
 	/*
26 228
 	 * Connection closed
27 229
 	 *
28
-	 * @v conn	TCP connection
230
+	 * @v app	TCP application
29 231
 	 * @v status	Error code, if any
30 232
 	 *
31 233
 	 * This is called when the connection is closed for any
@@ -33,42 +235,41 @@ struct tcp_operations {
33 235
 	 * contains the negative error number, if the closure is due
34 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 251
 	 * Data acknowledged
51 252
 	 *
52
-	 * @v conn	TCP connection
253
+	 * @v app	TCP application
53 254
 	 * @v len	Length of acknowledged data
54 255
 	 *
55 256
 	 * @c len is guaranteed to not exceed the outstanding amount
56 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 261
 	 * New data received
61 262
 	 *
62
-	 * @v conn	TCP connection
263
+	 * @v app	TCP application
63 264
 	 * @v data	Data
64 265
 	 * @v len	Length of data
65 266
 	 */
66
-	void ( * newdata ) ( struct tcp_connection *conn,
267
+	void ( * newdata ) ( struct tcp_application *app,
67 268
 			     void *data, size_t len );
68 269
 	/**
69 270
 	 * Transmit data
70 271
 	 *
71
-	 * @v conn	TCP connection
272
+	 * @v app	TCP application
72 273
 	 * @v buf	Temporary data buffer
73 274
 	 * @v len	Length of temporary data buffer
74 275
 	 *
@@ -86,137 +287,36 @@ struct tcp_operations {
86 287
 	 * the buffer is not compulsory; the application may call
87 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 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 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 318
 		      size_t len );
219 319
 
220
-#endif /* USE_UIP */
320
+extern struct tcpip_protocol tcp_protocol;
221 321
 
222 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,49 +58,31 @@ static inline const void * ftp_string_data ( struct ftp_request *ftp,
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 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 73
  * @v ftp		FTP request
74 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,7 +113,7 @@ static void ftp_parse_value ( char **text, uint8_t *value, size_t len ) {
131 113
  *
132 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 118
 static void ftp_reply ( struct ftp_request *ftp ) {
137 119
 	char status_major = ftp->status_text[0];
@@ -147,21 +129,31 @@ static void ftp_reply ( struct ftp_request *ftp ) {
147 129
 	 * fatal error.
148 130
 	 */
149 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 137
 	/* Open passive connection when we get "PASV" response */
154 138
 	if ( ftp->state == FTP_PASV ) {
155 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 159
 	/* Move to next state */
@@ -176,26 +168,21 @@ static void ftp_reply ( struct ftp_request *ftp ) {
176 168
 	}
177 169
 
178 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 174
  * Handle new data arriving on FTP control channel
188 175
  *
189
- * @v conn	TCP connection
176
+ * @v app	TCP application
190 177
  * @v data	New data
191 178
  * @v len	Length of new data
192 179
  *
193 180
  * Data is collected until a complete line is received, at which point
194 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 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 186
 	char *recvbuf = ftp->recvbuf;
200 187
 	size_t recvsize = ftp->recvsize;
201 188
 	char c;
@@ -242,10 +229,10 @@ static void ftp_newdata ( struct tcp_connection *conn,
242 229
 /**
243 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 237
 	/* Mark off ACKed portion of the currently-transmitted data */
251 238
 	ftp->already_sent += len;
@@ -254,13 +241,13 @@ static void ftp_acked ( struct tcp_connection *conn, size_t len ) {
254 241
 /**
255 242
  * Construct data to send on FTP control channel
256 243
  *
257
- * @v conn	TCP connection
244
+ * @v app	TCP application
258 245
  * @v buf	Temporary data buffer
259 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 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 251
 	const struct ftp_string *string;
265 252
 
266 253
 	/* Send the as-yet-unACKed portion of the string for the
@@ -269,31 +256,24 @@ static void ftp_senddata ( struct tcp_connection *conn,
269 256
 	string = &ftp_strings[ftp->state];
270 257
 	len = snprintf ( buf, len, string->format,
271 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 263
  * Handle control channel being closed
277 264
  *
278
- * @v conn		TCP connection
265
+ * @v app		TCP application
279 266
  *
280 267
  * When the control channel is closed, the data channel must also be
281 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 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 279
 /** FTP control channel operations */
@@ -311,20 +291,20 @@ static struct tcp_operations ftp_tcp_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 297
  * @ret ftp		FTP request
318 298
  */
319 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 305
  * Handle data channel being closed
326 306
  *
327
- * @v conn		TCP connection
307
+ * @v app		TCP application
328 308
  *
329 309
  * When the data channel is closed, the control channel should be left
330 310
  * alone; the server will send a completion message via the control
@@ -332,36 +312,28 @@ tcp_to_ftp_data ( struct tcp_connection *conn ) {
332 312
  *
333 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 318
 	DBG ( "FTP %p data connection closed (status %d)\n", ftp, status );
339 319
 	
340 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 326
  * Handle new data arriving on the FTP data channel
355 327
  *
356
- * @v conn	TCP connection
328
+ * @v app	TCP application
357 329
  * @v data	New data
358 330
  * @v len	Length of new data
359 331
  *
360 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 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 338
 	ftp->callback ( data, len );
367 339
 }
@@ -384,14 +356,16 @@ static struct tcp_operations ftp_data_tcp_operations = {
384 356
  * @v ftp	FTP request
385 357
  */
386 358
 struct async_operation * ftp_get ( struct ftp_request *ftp ) {
387
-	
359
+	int rc;
360
+
388 361
 	DBG ( "FTP %p fetching %s\n", ftp, ftp->filename );
389 362
 
390 363
 	ftp->tcp.tcp_op = &ftp_tcp_operations;
391 364
 	ftp->tcp_data.tcp_op = &ftp_data_tcp_operations;
392 365
 	ftp->recvbuf = ftp->status_text;
393 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 370
 	return &ftp->aop;
397 371
 }

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

@@ -10,9 +10,9 @@
10 10
  * "Hello world" TCP protocol
11 11
  *
12 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 16
  * hello_request::callback(), and once the connection has been closed,
17 17
  * the asynchronous operation associated with the request will be
18 18
  * marked as complete.
@@ -26,13 +26,13 @@
26 26
  *   }
27 27
  *
28 28
  *   struct hello_request hello = {
29
+ *     .server = {
30
+ *       ...
31
+ *     },
29 32
  *     .message = "hello world!",
30 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 36
  *   rc = async_wait ( say_hello ( &hello ) );
37 37
  *
38 38
  * @endcode
@@ -44,25 +44,25 @@
44 44
  */
45 45
 
46 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 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 60
 	hello->remaining = strlen ( hello->message );
61 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 67
 	hello->message += len;
68 68
 	hello->remaining -= len;
@@ -84,18 +84,18 @@ static void hello_acked ( struct tcp_connection *conn, size_t 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 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 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 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 101
 static struct tcp_operations hello_tcp_operations = {
@@ -112,7 +112,11 @@ static struct tcp_operations hello_tcp_operations = {
112 112
  * @v hello	"Hello world" request
113 113
  */
114 114
 struct async_operation * say_hello ( struct hello_request *hello ) {
115
+	int rc;
116
+
115 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 121
 	return &hello->aop;
118 122
 }

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

@@ -39,28 +39,28 @@
39 39
  */
40 40
 
41 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 47
  * Close an HTTP connection
48 48
  *
49
- * @v conn	a TCP Connection
49
+ * @v app	a TCP Application
50 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 54
 	async_done ( &http->aop, status );
55 55
 }
56 56
 
57 57
 /**
58 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 65
 	http->state = HTTP_REQUEST_FILE;
66 66
 }
@@ -68,11 +68,11 @@ static void http_connected ( struct tcp_connection *conn ) {
68 68
 /**
69 69
  * Callback for when TCP data is acknowledged
70 70
  *
71
- * @v conn	a TCP Connection
71
+ * @v app	a TCP Application
72 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 77
 	// assume that the whole GET request was sent in on epacket
78 78
 
@@ -84,7 +84,7 @@ static void http_acked ( struct tcp_connection *conn, size_t len __attribute__ (
84 84
 	case HTTP_RECV_FILE:
85 85
 		break;
86 86
 	case HTTP_DONE:
87
-		//tcp_close(conn);
87
+		//tcp_close(app);
88 88
 		break;
89 89
 	default:
90 90
 		break;
@@ -95,13 +95,13 @@ static void http_acked ( struct tcp_connection *conn, size_t len __attribute__ (
95 95
 /**
96 96
  * Callback when new TCP data is recieved
97 97
  *
98
- * @v conn	a TCP Connection
98
+ * @v app	a TCP Application
99 99
  * @v data	a pointer to the data recieved
100 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 103
 			    size_t len ) {
104
-	struct http_request *http = tcp_to_http ( conn );
104
+	struct http_request *http = tcp_to_http ( app );
105 105
 	char *content_length;
106 106
 	char *start = data;
107 107
 	char *rcp; int rc;
@@ -142,7 +142,7 @@ static void http_newdata ( struct tcp_connection *conn, void *data,
142 142
 		//printf("File recv is %d\n", http->file_recv);
143 143
 		if ( http->file_recv == http->file_size ){
144 144
 			http->state = HTTP_DONE;
145
-			tcp_close(conn);
145
+			tcp_close(app);
146 146
 		}
147 147
 		break;
148 148
 	case HTTP_REQUEST_FILE:
@@ -155,10 +155,10 @@ static void http_newdata ( struct tcp_connection *conn, void *data,
155 155
 /**
156 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 163
 	switch ( http->state ){
164 164
 	case HTTP_REQUEST_FILE:
@@ -166,13 +166,13 @@ static void http_senddata ( struct tcp_connection *conn, void *buf, size_t len )
166 166
 		printf("%s\n",(char *)buf);
167 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 170
 		break;
171 171
 	case HTTP_PARSE_HEADER:
172 172
 	case HTTP_RECV_FILE:
173 173
 		break;
174 174
 	case HTTP_DONE:
175
-		//tcp_close(conn)
175
+		//tcp_close(app)
176 176
 		break;
177 177
 	default:
178 178
 		break;
@@ -193,8 +193,12 @@ static struct tcp_operations http_tcp_operations = {
193 193
  * @v http	a HTTP request
194 194
  */
195 195
 struct async_operation * get_http ( struct http_request *http ) {
196
+	int rc;
197
+
196 198
 	http->tcp.tcp_op = &http_tcp_operations;
197 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 203
 	return &http->aop;
200 204
 }

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

@@ -720,11 +720,14 @@ static void iscsi_rx_login_response ( struct iscsi_session *iscsi, void *data,
720 720
 	/* Check for login redirection */
721 721
 	if ( response->status_class == ISCSI_STATUS_REDIRECT ) {
722 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 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 731
 		return;
729 732
 	}
730 733
 
@@ -778,8 +781,8 @@ static void iscsi_rx_login_response ( struct iscsi_session *iscsi, void *data,
778 781
  */
779 782
 
780 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,8 +862,8 @@ static void iscsi_tx_done ( struct iscsi_session *iscsi ) {
859 862
  * Updates iscsi->tx_offset and, if applicable, transitions to the
860 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 867
 	struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
865 868
 	enum iscsi_tx_state next_state;
866 869
 	
@@ -916,9 +919,9 @@ static void iscsi_acked ( struct tcp_connection *conn, size_t len ) {
916 919
  * 
917 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 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 925
 	struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
923 926
 	static const char pad[] = { '\0', '\0', '\0' };
924 927
 
@@ -927,7 +930,7 @@ static void iscsi_senddata ( struct tcp_connection *conn,
927 930
 		/* Nothing to send */
928 931
 		break;
929 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 934
 			   ( sizeof ( iscsi->tx_bhs ) - iscsi->tx_offset ) );
932 935
 		break;
933 936
 	case ISCSI_TX_AHS:
@@ -938,7 +941,7 @@ static void iscsi_senddata ( struct tcp_connection *conn,
938 941
 		iscsi_tx_data ( iscsi, buf, len );
939 942
 		break;
940 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 945
 					- iscsi->tx_offset ) );
943 946
 		break;
944 947
 	default:
@@ -1029,7 +1032,7 @@ static void iscsi_rx_bhs ( struct iscsi_session *iscsi, void *data,
1029 1032
 /**
1030 1033
  * Receive new data
1031 1034
  *
1032
- * @v tcp		TCP connection
1035
+ * @v tcp		TCP application
1033 1036
  * @v data		Received data
1034 1037
  * @v len		Length of received data
1035 1038
  *
@@ -1040,9 +1043,9 @@ static void iscsi_rx_bhs ( struct iscsi_session *iscsi, void *data,
1040 1043
  * always has a full copy of the BHS available, even for portions of
1041 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 1047
 			    size_t len ) {
1045
-	struct iscsi_session *iscsi = tcp_to_iscsi ( conn );
1048
+	struct iscsi_session *iscsi = tcp_to_iscsi ( app );
1046 1049
 	struct iscsi_bhs_common *common = &iscsi->rx_bhs.common;
1047 1050
 	void ( *process ) ( struct iscsi_session *iscsi, void *data,
1048 1051
 			    size_t len, size_t remaining );
@@ -1098,38 +1101,28 @@ static void iscsi_newdata ( struct tcp_connection *conn, void *data,
1098 1101
 	}
1099 1102
 }
1100 1103
 
1101
-#warning "Remove me soon"
1102
-static struct tcp_operations iscsi_tcp_operations;
1103
-
1104 1104
 /**
1105 1105
  * Handle TCP connection closure
1106 1106
  *
1107
- * @v conn		TCP connection
1107
+ * @v app		TCP application
1108 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 1115
 	/* Clear session status */
1116 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 1118
 	/* Retry connection if within the retry limit, otherwise fail */
1125 1119
 	if ( ++iscsi->retry_count <= ISCSI_MAX_RETRIES ) {
1126 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 1126
 	} else {
1134 1127
 		printf ( "iSCSI %p retry count exceeded\n", iscsi );
1135 1128
 		iscsi_done ( iscsi, status );
@@ -1139,11 +1132,11 @@ static void iscsi_closed ( struct tcp_connection *conn, int status ) {
1139 1132
 /**
1140 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 1141
 	/* Set connected flag and reset retry count */
1149 1142
 	iscsi->status = ( ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE |
@@ -1179,6 +1172,8 @@ static struct tcp_operations iscsi_tcp_operations = {
1179 1172
  */
1180 1173
 struct async_operation * iscsi_issue ( struct iscsi_session *iscsi,
1181 1174
 				       struct scsi_command *command ) {
1175
+	int rc;
1176
+
1182 1177
 	assert ( iscsi->command == NULL );
1183 1178
 	iscsi->command = command;
1184 1179
 
@@ -1198,9 +1193,12 @@ struct async_operation * iscsi_issue ( struct iscsi_session *iscsi,
1198 1193
 	} else {
1199 1194
 		/* Session not open: initiate login */
1200 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 1204
 	return &iscsi->aop;
@@ -1212,10 +1210,7 @@ struct async_operation * iscsi_issue ( struct iscsi_session *iscsi,
1212 1210
  * @v iscsi		iSCSI session
1213 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,7 +29,7 @@ void test_ftp ( struct sockaddr_tcpip *server, const char *filename ) {
29 29
 	printf ( "FTP fetching %s\n", filename );
30 30
 	
31 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 33
 	ftp.filename = filename;
34 34
 	ftp.callback = test_ftp_callback;
35 35
 

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

@@ -32,7 +32,7 @@ void test_hello ( struct sockaddr_tcpip *server, const char *message ) {
32 32
 		 inet_ntoa ( sin->sin_addr ), ntohs ( sin->sin_port ) );
33 33
 	
34 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 36
 	hello.message = message;
37 37
 	hello.callback = test_hello_callback;
38 38
 

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

@@ -21,7 +21,7 @@ void test_http ( struct net_device *netdev, struct sockaddr_tcpip *server, const
21 21
 	int rc;
22 22
 
23 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 25
 	http.filename = filename;
26 26
 	http.callback = test_http_callback;
27 27
 

Loading…
Cancel
Save