TCP: only store up to 1000 unacked segments (in each direction).
authorJeff Morriss <jeff.morriss.ws@gmail.com>
Mon, 12 Oct 2015 22:04:01 +0000 (18:04 -0400)
committerAnders Broman <a.broman58@gmail.com>
Wed, 14 Oct 2015 04:20:02 +0000 (04:20 +0000)
If we're seeing only one side of a conversation (we're not seeing any ACKs)
then things get really, really slow as the number of unacked segments grows.

1000 is, of course, an arbitrary limit.

Bug: 11589
Change-Id: I42652965b736da50122c722e6ac386c4d481e57f
Reviewed-on: https://code.wireshark.org/review/10971
Petri-Dish: Jeff Morriss <jeff.morriss.ws@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
epan/dissectors/packet-tcp.c
epan/dissectors/packet-tcp.h

index 0adb5c74514b4f6a24bcbeb534d04996246354db..4bf940399c80c1775c4ac7845bad71854863ee98 100644 (file)
@@ -1395,11 +1395,14 @@ finished_fwd:
 finished_checking_retransmission_type:
 
     nextseq = seq+seglen;
-    if (seglen || flags&(TH_SYN|TH_FIN)) {
-        /* add this new sequence number to the fwd list */
+    if ((seglen || flags&(TH_SYN|TH_FIN)) && tcpd->fwd->segment_count < TCP_MAX_UNACKED_SEGMENTS) {
+        /* Add this new sequence number to the fwd list.  But only if there
+        * aren't "too many" unacked segements (e.g., we're not seeing the ACKs).
+        */
         ual = wmem_new(wmem_file_scope(), tcp_unacked_t);
         ual->next=tcpd->fwd->segments;
         tcpd->fwd->segments=ual;
+        tcpd->fwd->segment_count++;
         ual->frame=pinfo->fd->num;
         ual->seq=seq;
         ual->ts=pinfo->fd->abs_ts;
@@ -1502,6 +1505,7 @@ finished_checking_retransmission_type:
         }
         wmem_free(wmem_file_scope(), ual);
         ual = tmpual;
+        tcpd->rev->segment_count--;
     }
 
     /* how many bytes of data are there in flight after this frame
index e071919db1fcdc53b934b492fea3eff218ba759b..54c6bfda8e438d288f5cac6adff99f261ee89e09 100644 (file)
@@ -150,7 +150,9 @@ struct tcp_multisegment_pdu {
 typedef struct _tcp_flow_t {
        gboolean base_seq_set; /* true if base seq set */
        guint32 base_seq;       /* base seq number (used by relative sequence numbers)*/
-       tcp_unacked_t *segments;
+#define TCP_MAX_UNACKED_SEGMENTS 1000 /* The most unacked segments we'll store */
+       tcp_unacked_t *segments;/* List of segments for which we haven't seen an ACK */
+       guint16 segment_count;  /* How many unacked segments we're currently storing */
        guint32 fin;            /* frame number of the final FIN */
        guint32 lastack;        /* last seen ack */
        nstime_t lastacktime;   /* Time of the last ack packet */