Browse Source

Redefine TCP state to include "flags that have been sent" rather than

"flags that are currently being sent".  This allows at least one special
case (checking that we haven't already sent a FIN in tcp_rx_fin()) to be
collapsed.
tags/v0.9.3
Michael Brown 18 years ago
parent
commit
ce9819af27
2 changed files with 46 additions and 47 deletions
  1. 31
    28
      src/include/gpxe/tcp.h
  2. 15
    19
      src/net/tcp.c

+ 31
- 28
src/include/gpxe/tcp.h View File

42
 /**
42
 /**
43
 * @defgroup tcpstates TCP states
43
 * @defgroup tcpstates TCP states
44
 *
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.
45
+* The TCP state is defined by a combination of the flags that have
46
+* been sent to the peer, the flags that have been acknowledged by the
47
+* peer, and the flags that have been received from the peer.
49
 *
48
 *
50
 * @{
49
 * @{
51
 */
50
 */
52
 
51
 
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 )
52
+/** TCP flags that have been sent in outgoing packets */
53
+#define TCP_STATE_SENT(flags) ( (flags) << 0 )
54
+#define TCP_FLAGS_SENT(state) ( ( (state) >> 0 ) & 0xff )
56
 
55
 
57
 /** TCP flags that have been acknowledged by the peer
56
 /** TCP flags that have been acknowledged by the peer
58
  *
57
  *
69
 #define TCP_STATE_RCVD(flags) ( (flags) << 12 )
68
 #define TCP_STATE_RCVD(flags) ( (flags) << 12 )
70
 #define TCP_FLAGS_RCVD(state) ( ( (state) >> 12 ) & 0x03 )
69
 #define TCP_FLAGS_RCVD(state) ( ( (state) >> 12 ) & 0x03 )
71
 
70
 
71
+/** TCP flags that are currently being sent in outgoing packets */
72
+#define TCP_FLAGS_SENDING(state) \
73
+	( TCP_FLAGS_SENT ( state ) & ~TCP_FLAGS_ACKED ( state ) )
74
+
72
 /** CLOSED
75
 /** CLOSED
73
  *
76
  *
74
  * The connection has not yet been used for anything.
77
  * The connection has not yet been used for anything.
86
  *
89
  *
87
  * SYN has been sent, nothing has yet been received or acknowledged.
90
  * SYN has been sent, nothing has yet been received or acknowledged.
88
  */
91
  */
89
-#define TCP_SYN_SENT	( TCP_STATE_SENDING ( TCP_SYN ) )
92
+#define TCP_SYN_SENT	( TCP_STATE_SENT ( TCP_SYN ) )
90
 
93
 
91
 /** SYN_RCVD
94
 /** SYN_RCVD
92
  *
95
  *
93
  * SYN has been sent but not acknowledged, SYN has been received.
96
  * SYN has been sent but not acknowledged, SYN has been received.
94
  */
97
  */
95
-#define TCP_SYN_RCVD	( TCP_STATE_SENDING ( TCP_SYN | TCP_ACK ) |	\
98
+#define TCP_SYN_RCVD	( TCP_STATE_SENT ( TCP_SYN | TCP_ACK ) |	    \
96
 			  TCP_STATE_RCVD ( TCP_SYN ) )
99
 			  TCP_STATE_RCVD ( TCP_SYN ) )
97
 
100
 
98
 /** ESTABLISHED
101
 /** ESTABLISHED
99
  *
102
  *
100
  * SYN has been sent and acknowledged, SYN has been received.
103
  * SYN has been sent and acknowledged, SYN has been received.
101
  */
104
  */
102
-#define TCP_ESTABLISHED	( TCP_STATE_SENDING ( TCP_ACK ) |		\
103
-			  TCP_STATE_ACKED ( TCP_SYN ) |			\
105
+#define TCP_ESTABLISHED	( TCP_STATE_SENT ( TCP_SYN | TCP_ACK ) |	    \
106
+			  TCP_STATE_ACKED ( TCP_SYN ) |			    \
104
 			  TCP_STATE_RCVD ( TCP_SYN ) )
107
 			  TCP_STATE_RCVD ( TCP_SYN ) )
105
 
108
 
106
 /** FIN_WAIT_1
109
 /** FIN_WAIT_1
117
  * to FIN_WAIT_1, we have to remember to set TCP_STATE_ACKED(TCP_SYN)
120
  * to FIN_WAIT_1, we have to remember to set TCP_STATE_ACKED(TCP_SYN)
118
  * and increment our sequence number.
121
  * and increment our sequence number.
119
  */
122
  */
120
-#define TCP_FIN_WAIT_1	( TCP_STATE_SENDING ( TCP_ACK | TCP_FIN ) |	\
121
-			  TCP_STATE_ACKED ( TCP_SYN ) |			\
123
+#define TCP_FIN_WAIT_1	( TCP_STATE_SENT ( TCP_SYN | TCP_ACK | TCP_FIN ) |  \
124
+			  TCP_STATE_ACKED ( TCP_SYN ) |			    \
122
 			  TCP_STATE_RCVD ( TCP_SYN ) )
125
 			  TCP_STATE_RCVD ( TCP_SYN ) )
123
 
126
 
124
 /** FIN_WAIT_2
127
 /** FIN_WAIT_2
126
  * SYN has been sent and acknowledged, SYN has been received, FIN has
129
  * SYN has been sent and acknowledged, SYN has been received, FIN has
127
  * been sent and acknowledged, FIN ha not been received.
130
  * been sent and acknowledged, FIN ha not been received.
128
  */
131
  */
129
-#define TCP_FIN_WAIT_2	( TCP_STATE_SENDING ( TCP_ACK ) |		\
130
-			  TCP_STATE_ACKED ( TCP_SYN | TCP_FIN ) |	\
132
+#define TCP_FIN_WAIT_2	( TCP_STATE_SENT ( TCP_SYN | TCP_ACK | TCP_FIN ) |  \
133
+			  TCP_STATE_ACKED ( TCP_SYN | TCP_FIN ) |	    \
131
 			  TCP_STATE_RCVD ( TCP_SYN ) )
134
 			  TCP_STATE_RCVD ( TCP_SYN ) )
132
 
135
 
133
 /** CLOSING / LAST_ACK
136
 /** CLOSING / LAST_ACK
139
  * identical with the definition of state that we use.  I don't
142
  * identical with the definition of state that we use.  I don't
140
  * *believe* that they need to be distinguished.
143
  * *believe* that they need to be distinguished.
141
  */
144
  */
142
-#define TCP_CLOSING_OR_LAST_ACK					\
143
-			( TCP_STATE_SENDING ( TCP_ACK | TCP_FIN ) |	\
144
-			  TCP_STATE_ACKED ( TCP_SYN ) |			\
145
+#define TCP_CLOSING_OR_LAST_ACK						    \
146
+			( TCP_STATE_SENT ( TCP_SYN | TCP_ACK | TCP_FIN ) |  \
147
+			  TCP_STATE_ACKED ( TCP_SYN ) |			    \
145
 			  TCP_STATE_RCVD ( TCP_SYN | TCP_FIN ) )
148
 			  TCP_STATE_RCVD ( TCP_SYN | TCP_FIN ) )
146
 
149
 
147
 /** TIME_WAIT
150
 /** TIME_WAIT
149
  * SYN has been sent and acknowledged, SYN has been received, FIN has
152
  * SYN has been sent and acknowledged, SYN has been received, FIN has
150
  * been sent and acknowledged, FIN has been received.
153
  * been sent and acknowledged, FIN has been received.
151
  */
154
  */
152
-#define TCP_TIME_WAIT	( TCP_STATE_SENDING ( TCP_ACK ) |		\
153
-			  TCP_STATE_ACKED ( TCP_SYN | TCP_FIN ) |	\
155
+#define TCP_TIME_WAIT	( TCP_STATE_SENT ( TCP_SYN | TCP_ACK | TCP_FIN ) |  \
156
+			  TCP_STATE_ACKED ( TCP_SYN | TCP_FIN ) |	    \
154
 			  TCP_STATE_RCVD ( TCP_SYN | TCP_FIN ) )
157
 			  TCP_STATE_RCVD ( TCP_SYN | TCP_FIN ) )
155
 
158
 
156
 /** CLOSE_WAIT
159
 /** CLOSE_WAIT
158
  * SYN has been sent and acknowledged, SYN has been received, FIN has
161
  * SYN has been sent and acknowledged, SYN has been received, FIN has
159
  * been received.
162
  * been received.
160
  */
163
  */
161
-#define TCP_CLOSE_WAIT	( TCP_STATE_SENDING ( TCP_ACK ) |		\
162
-			  TCP_STATE_ACKED ( TCP_SYN ) |			\
164
+#define TCP_CLOSE_WAIT	( TCP_STATE_SENT ( TCP_SYN | TCP_ACK ) |	    \
165
+			  TCP_STATE_ACKED ( TCP_SYN ) |			    \
163
 			  TCP_STATE_RCVD ( TCP_SYN | TCP_FIN ) )
166
 			  TCP_STATE_RCVD ( TCP_SYN | TCP_FIN ) )
164
 
167
 
165
 /** Can send data in current state
168
 /** Can send data in current state
167
  * We can send data if and only if we have had our SYN acked and we
170
  * We can send data if and only if we have had our SYN acked and we
168
  * have not yet sent our FIN.
171
  * have not yet sent our FIN.
169
  */
172
  */
170
-#define TCP_CAN_SEND_DATA(state)					\
171
-	( ( (state) & ( TCP_STATE_ACKED ( TCP_SYN | TCP_FIN ) |		\
172
-		      TCP_STATE_SENDING ( TCP_FIN ) ) )			\
173
+#define TCP_CAN_SEND_DATA(state)					    \
174
+	( ( (state) & ( TCP_STATE_ACKED ( TCP_SYN ) |			    \
175
+			TCP_STATE_SENT ( TCP_FIN ) ) )			    \
173
 	  == TCP_STATE_ACKED ( TCP_SYN ) )
176
 	  == TCP_STATE_ACKED ( TCP_SYN ) )
174
 
177
 
175
 /** Have closed gracefully
178
 /** Have closed gracefully
177
  * We have closed gracefully if we have both received a FIN and had
180
  * We have closed gracefully if we have both received a FIN and had
178
  * our own FIN acked.
181
  * our own FIN acked.
179
  */
182
  */
180
-#define TCP_CLOSED_GRACEFULLY(state)					\
181
-	( ( (state) & ( TCP_STATE_ACKED ( TCP_FIN ) |			\
182
-			TCP_STATE_RCVD ( TCP_FIN ) ) )			\
183
+#define TCP_CLOSED_GRACEFULLY(state)					    \
184
+	( ( (state) & ( TCP_STATE_ACKED ( TCP_FIN ) |			    \
185
+			TCP_STATE_RCVD ( TCP_FIN ) ) )			    \
183
 	  == ( TCP_STATE_ACKED ( TCP_FIN ) | TCP_STATE_RCVD ( TCP_FIN ) ) )
186
 	  == ( TCP_STATE_ACKED ( TCP_FIN ) | TCP_STATE_RCVD ( TCP_FIN ) ) )
184
 
187
 
185
 /** @} */
188
 /** @} */

+ 15
- 19
src/net/tcp.c View File

229
 	struct tcp_application *app = conn->app;
229
 	struct tcp_application *app = conn->app;
230
 	struct pk_buff *pkb;
230
 	struct pk_buff *pkb;
231
 	struct tcp_header *tcphdr;
231
 	struct tcp_header *tcphdr;
232
+	unsigned int flags;
232
 	size_t len;
233
 	size_t len;
233
 	size_t seq_len;
234
 	size_t seq_len;
234
 
235
 
264
 	 */
265
 	 */
265
 	len = pkb_len ( pkb );
266
 	len = pkb_len ( pkb );
266
 	seq_len = len;
267
 	seq_len = len;
267
-	assert ( ! ( ( conn->tcp_state & TCP_STATE_SENDING ( TCP_SYN ) ) &&
268
-		     ( conn->tcp_state & TCP_STATE_SENDING ( TCP_FIN ) ) ) );
269
-	if ( conn->tcp_state & TCP_STATE_SENDING ( TCP_SYN | TCP_FIN ) )
268
+	flags = TCP_FLAGS_SENDING ( conn->tcp_state );
269
+	assert ( ! ( ( flags & TCP_SYN ) && ( flags & TCP_FIN ) ) );
270
+	if ( flags & ( TCP_SYN | TCP_FIN ) )
270
 		seq_len++;
271
 		seq_len++;
271
 	conn->snd_sent = seq_len;
272
 	conn->snd_sent = seq_len;
272
 
273
 
291
 	tcphdr->seq = htonl ( conn->snd_seq );
292
 	tcphdr->seq = htonl ( conn->snd_seq );
292
 	tcphdr->ack = htonl ( conn->rcv_ack );
293
 	tcphdr->ack = htonl ( conn->rcv_ack );
293
 	tcphdr->hlen = ( ( sizeof ( *tcphdr ) / 4 ) << 4 );
294
 	tcphdr->hlen = ( ( sizeof ( *tcphdr ) / 4 ) << 4 );
294
-	tcphdr->flags = TCP_FLAGS_SENDING ( conn->tcp_state );
295
+	tcphdr->flags = flags;
295
 	tcphdr->win = htons ( TCP_WINDOW_SIZE );
296
 	tcphdr->win = htons ( TCP_WINDOW_SIZE );
296
 	tcphdr->csum = tcpip_chksum ( pkb->data, pkb_len ( pkb ) );
297
 	tcphdr->csum = tcpip_chksum ( pkb->data, pkb_len ( pkb ) );
297
 
298
 
458
 		return 0;
459
 		return 0;
459
 
460
 
460
 	/* Mark SYN as received and start sending ACKs with each packet */
461
 	/* Mark SYN as received and start sending ACKs with each packet */
461
-	conn->tcp_state |= ( TCP_STATE_SENDING ( TCP_ACK ) |
462
+	conn->tcp_state |= ( TCP_STATE_SENT ( TCP_ACK ) |
462
 			     TCP_STATE_RCVD ( TCP_SYN ) );
463
 			     TCP_STATE_RCVD ( TCP_SYN ) );
463
 
464
 
464
 	/* Acknowledge SYN */
465
 	/* Acknowledge SYN */
517
 		app->tcp_op->acked ( app, len );
518
 		app->tcp_op->acked ( app, len );
518
 
519
 
519
 	/* Mark SYN/FIN as acknowledged if applicable. */
520
 	/* Mark SYN/FIN as acknowledged if applicable. */
520
-	if ( acked_flags ) {
521
-		conn->tcp_state &= ~TCP_STATE_SENDING ( TCP_SYN | TCP_FIN );
521
+	if ( acked_flags )
522
 		conn->tcp_state |= TCP_STATE_ACKED ( acked_flags );
522
 		conn->tcp_state |= TCP_STATE_ACKED ( acked_flags );
523
-	}
524
 
523
 
525
 	/* Notify application of established connection, if applicable */
524
 	/* Notify application of established connection, if applicable */
526
 	if ( ( acked_flags & TCP_SYN ) && app && app->tcp_op->connected )
525
 	if ( ( acked_flags & TCP_SYN ) && app && app->tcp_op->connected )
573
 	if ( ( conn->rcv_ack - seq ) > 0 )
572
 	if ( ( conn->rcv_ack - seq ) > 0 )
574
 		return 0;
573
 		return 0;
575
 
574
 
576
-	/* Mark FIN as received and acknowledge it */
577
-	conn->tcp_state |= TCP_STATE_RCVD ( TCP_FIN );
575
+	/* Mark FIN as received, acknowledge it, and send our own FIN */
576
+	conn->tcp_state |= ( TCP_STATE_RCVD ( TCP_FIN ) |
577
+			     TCP_STATE_SENT ( TCP_FIN ) );
578
 	conn->rcv_ack++;
578
 	conn->rcv_ack++;
579
 
579
 
580
-	/* If we haven't already sent our FIN, send a FIN */
581
-	if ( ! ( conn->tcp_state & TCP_STATE_ACKED ( TCP_FIN ) ) )
582
-		conn->tcp_state |= TCP_STATE_SENDING ( TCP_FIN );
583
-
584
 	/* Break association with application */
580
 	/* Break association with application */
585
 	tcp_disassociate ( conn );
581
 	tcp_disassociate ( conn );
586
 
582
 
832
 		return;
828
 		return;
833
 	}
829
 	}
834
 
830
 
835
-	/* If we have sent a SYN but not had it acknowledged (i.e. we
836
-	 * are in SYN_RCVD), pretend that it has been acknowledged so
837
-	 * that we can send a FIN without breaking things.
831
+	/* If we have not had our SYN acknowledged (i.e. we are in
832
+	 * SYN_RCVD), pretend that it has been acknowledged so that we
833
+	 * can send a FIN without breaking things.
838
 	 */
834
 	 */
839
-	if ( conn->tcp_state & TCP_STATE_SENDING ( TCP_SYN ) )
835
+	if ( ! ( conn->tcp_state & TCP_STATE_ACKED ( TCP_SYN ) ) )
840
 		tcp_rx_ack ( conn, ( conn->snd_seq + 1 ), 0 );
836
 		tcp_rx_ack ( conn, ( conn->snd_seq + 1 ), 0 );
841
 
837
 
842
 	/* Send a FIN to initiate the close */
838
 	/* Send a FIN to initiate the close */
843
-	conn->tcp_state |= TCP_STATE_SENDING ( TCP_FIN );
839
+	conn->tcp_state |= TCP_STATE_SENT ( TCP_FIN );
844
 	tcp_dump_state ( conn );
840
 	tcp_dump_state ( conn );
845
 	tcp_senddata_conn ( conn, 0 );
841
 	tcp_senddata_conn ( conn, 0 );
846
 }
842
 }

Loading…
Cancel
Save