|
@@ -1004,14 +1004,21 @@ static void tcp_rx_enqueue ( struct tcp_connection *tcp, uint32_t seq,
|
1004
|
1004
|
*/
|
1005
|
1005
|
static void tcp_process_rx_queue ( struct tcp_connection *tcp ) {
|
1006
|
1006
|
struct io_buffer *iobuf;
|
1007
|
|
- struct io_buffer *tmp;
|
1008
|
1007
|
struct tcp_rx_queued_header *tcpqhdr;
|
1009
|
1008
|
uint32_t seq;
|
1010
|
1009
|
unsigned int flags;
|
1011
|
1010
|
size_t len;
|
1012
|
1011
|
|
1013
|
|
- /* Process all applicable received buffers */
|
1014
|
|
- list_for_each_entry_safe ( iobuf, tmp, &tcp->rx_queue, list ) {
|
|
1012
|
+ /* Process all applicable received buffers. Note that we
|
|
1013
|
+ * cannot use list_for_each_entry() to iterate over the RX
|
|
1014
|
+ * queue, since tcp_discard() may remove packets from the RX
|
|
1015
|
+ * queue while we are processing.
|
|
1016
|
+ */
|
|
1017
|
+ while ( ! list_empty ( &tcp->rx_queue ) ) {
|
|
1018
|
+ list_for_each_entry ( iobuf, &tcp->rx_queue, list )
|
|
1019
|
+ break;
|
|
1020
|
+
|
|
1021
|
+ /* Stop processing when we hit the first gap */
|
1015
|
1022
|
tcpqhdr = iobuf->data;
|
1016
|
1023
|
if ( tcp_cmp ( tcpqhdr->seq, tcp->rcv_ack ) > 0 )
|
1017
|
1024
|
break;
|
|
@@ -1183,6 +1190,34 @@ struct tcpip_protocol tcp_protocol __tcpip_protocol = {
|
1183
|
1190
|
.tcpip_proto = IP_TCP,
|
1184
|
1191
|
};
|
1185
|
1192
|
|
|
1193
|
+/**
|
|
1194
|
+ * Discard some cached TCP data
|
|
1195
|
+ *
|
|
1196
|
+ * @ret discarded Number of cached items discarded
|
|
1197
|
+ */
|
|
1198
|
+static unsigned int tcp_discard ( void ) {
|
|
1199
|
+ struct tcp_connection *tcp;
|
|
1200
|
+ struct io_buffer *iobuf;
|
|
1201
|
+ unsigned int discarded = 0;
|
|
1202
|
+
|
|
1203
|
+ /* Try to drop one queued RX packet from each connection */
|
|
1204
|
+ list_for_each_entry ( tcp, &tcp_conns, list ) {
|
|
1205
|
+ list_for_each_entry_reverse ( iobuf, &tcp->rx_queue, list ) {
|
|
1206
|
+ list_del ( &iobuf->list );
|
|
1207
|
+ free_iob ( iobuf );
|
|
1208
|
+ discarded++;
|
|
1209
|
+ break;
|
|
1210
|
+ }
|
|
1211
|
+ }
|
|
1212
|
+
|
|
1213
|
+ return discarded;
|
|
1214
|
+}
|
|
1215
|
+
|
|
1216
|
+/** TCP cache discarder */
|
|
1217
|
+struct cache_discarder tcp_cache_discarder __cache_discarder = {
|
|
1218
|
+ .discard = tcp_discard,
|
|
1219
|
+};
|
|
1220
|
+
|
1186
|
1221
|
/***************************************************************************
|
1187
|
1222
|
*
|
1188
|
1223
|
* Data transfer interface
|