summaryrefslogtreecommitdiff
path: root/agent
diff options
context:
space:
mode:
authorOlivier Crête <olivier.crete@collabora.com>2016-04-14 13:32:51 +0200
committerOlivier Crête <olivier.crete@collabora.com>2016-06-03 18:35:40 -0400
commitf645ea6b11c167b1d7f4c5034f79664bdb8706d6 (patch)
tree5327dbe58d179e5a8fd8f0c86e9fcd8bbca48713 /agent
parentadba0d4a51f4e0deac888ab08f7976cef70a8e99 (diff)
downloadlibnice-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.c14
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;