summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2017-06-21 21:13:21 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2017-06-23 13:34:07 +0200
commit5113a3dee9f6798dd015500dc33ee29277f37e49 (patch)
tree1dcdb098d83879f9ec4d7f6b96311c471ca1121a
parent6b3a3e56faa63397b3c160e74767c620ebca91a7 (diff)
downloadbarebox-5113a3dee9f6798dd015500dc33ee29277f37e49.tar.gz
barebox-5113a3dee9f6798dd015500dc33ee29277f37e49.tar.xz
ratp: don't ignore data that may arrive in behaviour H1
If an input packet arrives H1 that has data in it, we need to: * track sn_received * if we have data pending, send it * if we don't have data pending, send a plain ACK This process, as noted in RFC916, is the same as the I1 procedure, so go and run it: Go to the ESTABLISHED state and execute procedure I1 to process any data which might be in this packet. This fix allows the peer to queue data in the last packet doing the connection establishment. It doesn't apply to the barebox<->bbremote interaction because bbremote won't queue data until the connection is completely established, but it allows third party ratp implementations to do that. Signed-off-by: Aleksander Morgado <aleksander@aleksander.es> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--lib/ratp.c8
-rw-r--r--scripts/remote/ratp.py14
2 files changed, 13 insertions, 9 deletions
diff --git a/lib/ratp.c b/lib/ratp.c
index e810a9e54..2dee41009 100644
--- a/lib/ratp.c
+++ b/lib/ratp.c
@@ -1042,6 +1042,8 @@ static int ratp_behaviour_g(struct ratp_internal *ri, void *pkt)
return 0;
}
+static int ratp_behaviour_i1(struct ratp_internal *ri, void *pkt);
+
/*
* Our SYN has been acknowledged. At this point we are
* technically in the ESTABLISHED state. Send any initial data
@@ -1062,7 +1064,11 @@ static int ratp_behaviour_h1(struct ratp_internal *ri, void *pkt)
ratp_state_change(ri, RATP_STATE_ESTABLISHED);
- return 0;
+ /* If the input message has data (i.e. it is not just an ACK
+ * without data) then we need to send back an ACK ourselves,
+ * or even data if we have it pending. This is the same
+ * procedure done in i1, so just run it. */
+ return ratp_behaviour_i1 (ri, pkt);
}
/*
diff --git a/scripts/remote/ratp.py b/scripts/remote/ratp.py
index e6b3e19b6..7972d31f2 100644
--- a/scripts/remote/ratp.py
+++ b/scripts/remote/ratp.py
@@ -489,12 +489,8 @@ class RatpConnection(object):
def _h1(self, r):
logging.info("H1")
-
- # FIXME: initial data?
self._state = RatpState.established
- self._r_sn = r.c_sn
-
- return False
+ return self._common_i1(r)
def _h2(self, r):
logging.info("H2")
@@ -584,9 +580,7 @@ class RatpConnection(object):
self._time_wait_deadline = monotonic() + self._get_rto()
return False
- def _i1(self, r):
- logging.info("I1")
-
+ def _common_i1(self, r):
if r.c_so:
self._r_sn = r.c_sn
self._rx_buf.append(chr(r.length))
@@ -608,6 +602,10 @@ class RatpConnection(object):
self._write(s)
return False
+ def _i1(self, r):
+ logging.info("I1")
+ return self._common_i1(r)
+
def _machine(self, pkt):
logging.info("State: %r", self._state)
if self._state == RatpState.listen: