diff options
author | Olivier Crête <olivier.crete@collabora.com> | 2016-04-14 13:32:51 +0200 |
---|---|---|
committer | Olivier Crête <olivier.crete@collabora.com> | 2016-06-03 18:35:40 -0400 |
commit | f645ea6b11c167b1d7f4c5034f79664bdb8706d6 (patch) | |
tree | 5327dbe58d179e5a8fd8f0c86e9fcd8bbca48713 /agent | |
parent | adba0d4a51f4e0deac888ab08f7976cef70a8e99 (diff) | |
download | libnice-f645ea6b11c167b1d7f4c5034f79664bdb8706d6.tar.gz |
pseudotcp: Make sure duplicate ack representing losses have no data
If they have data in them, they won't be recognized as duplicate acks by
the sender.
Diffstat (limited to 'agent')
-rw-r--r-- | agent/pseudotcp.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/agent/pseudotcp.c b/agent/pseudotcp.c index 39130cb..21cec65 100644 --- a/agent/pseudotcp.c +++ b/agent/pseudotcp.c @@ -429,6 +429,7 @@ typedef enum { sfImmediateAck, sfFin, sfRst, + sfDuplicateAck, } SendFlags; typedef struct { @@ -1936,7 +1937,7 @@ process(PseudoTcpSocket *self, Segment *seg) * see RFC 793, §3.3. Also see: RFC 793, §3.5. */ if (seg->seq != priv->rcv_nxt) { - sflags = sfImmediateAck; // (Fast Recovery) + sflags = sfDuplicateAck; // (Fast Recovery) } else if (seg->len != 0) { if (priv->ack_delay == 0) { sflags = sfImmediateAck; @@ -1949,7 +1950,7 @@ process(PseudoTcpSocket *self, Segment *seg) sflags = sfImmediateAck; } - if (sflags == sfImmediateAck) { + if (sflags == sfDuplicateAck) { if (seg->seq > priv->rcv_nxt) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "too new"); } else if (SMALLER_OR_EQUAL(seg->seq + seg->len, priv->rcv_nxt)) { @@ -2208,12 +2209,19 @@ attempt_send(PseudoTcpSocket *self, SendFlags sflags) available_space, snd_buffered - nInFlight, priv->ssthresh); } + if (sflags == sfDuplicateAck) { + packet(self, priv->snd_nxt, 0, 0, 0, now); + sflags = sfNone; + continue; + } + if (nAvailable == 0 && sflags != sfFin && sflags != sfRst) { if (sflags == sfNone) return; // If this is an immediate ack, or the second delayed ack - if ((sflags == sfImmediateAck) || priv->t_ack) { + if ((sflags == sfImmediateAck || sflags == sfDuplicateAck) || + priv->t_ack) { packet(self, priv->snd_nxt, 0, 0, 0, now); } else { priv->t_ack = now; |