|  | @@ -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
 |