summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2017-06-30 14:24:32 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2017-06-30 14:24:32 +0200
commit9a2a703e50e2370f6b1dcebc8cfd25ef9cc5a2e5 (patch)
treefeef7674aa4e93ee5aff9b8852687f258a682802
parent840b0e06374bfe98d1fabf7f541445d34ba22ed5 (diff)
parent5bde92c92b0efb675969d09386667f110f63cd6c (diff)
downloadbarebox-9a2a703e50e2370f6b1dcebc8cfd25ef9cc5a2e5.tar.gz
Merge branch 'for-next/ratp'
-rw-r--r--lib/ratp.c116
-rw-r--r--scripts/remote/ratp.py38
2 files changed, 78 insertions, 76 deletions
diff --git a/lib/ratp.c b/lib/ratp.c
index 22e8363..e7fbf64 100644
--- a/lib/ratp.c
+++ b/lib/ratp.c
@@ -139,8 +139,10 @@ static bool ratp_an(struct ratp_header *hdr)
return hdr->control & RATP_CONTROL_AN ? 1 : 0;
}
-#define ratp_set_sn(sn) (((sn) % 2) ? RATP_CONTROL_SN : 0)
-#define ratp_set_an(an) (((an) % 2) ? RATP_CONTROL_AN : 0)
+#define ratp_set_sn(sn) (sn ? RATP_CONTROL_SN : 0)
+#define ratp_set_an(an) (an ? RATP_CONTROL_AN : 0)
+#define ratp_set_next_sn(sn) (((sn + 1) % 2) ? RATP_CONTROL_SN : 0)
+#define ratp_set_next_an(an) (((an + 1) % 2) ? RATP_CONTROL_AN : 0)
static inline int ratp_header_ok(struct ratp_internal *ri, struct ratp_header *h)
{
@@ -165,7 +167,7 @@ static bool ratp_has_data(struct ratp_header *hdr)
{
if (hdr->control & RATP_CONTROL_SO)
return 1;
- if (hdr->data_length)
+ if (!(hdr->control & (RATP_CONTROL_SYN | RATP_CONTROL_RST | RATP_CONTROL_FIN)) && hdr->data_length)
return 1;
return 0;
}
@@ -359,18 +361,17 @@ static bool ratp_an_expected(struct ratp_internal *ri, struct ratp_header *hdr)
static bool ratp_sn_expected(struct ratp_internal *ri, struct ratp_header *hdr)
{
- return ratp_sn(hdr) != ri->sn_received;
+ return ratp_sn(hdr) == (ri->sn_received + 1) % 2;
}
static int ratp_send_ack(struct ratp_internal *ri, struct ratp_header *hdr)
{
- uint8_t control = RATP_CONTROL_ACK;
+ uint8_t control;
int ret;
- if (hdr->control & RATP_CONTROL_SN)
- control |= RATP_CONTROL_AN;
- else
- control |= 0;
+ control = ratp_set_sn(ratp_an(hdr)) |
+ ratp_set_next_an(ratp_sn(hdr)) |
+ RATP_CONTROL_ACK;
ret = ratp_send_hdr(ri, control);
if (ret)
@@ -382,8 +383,9 @@ static int ratp_send_ack(struct ratp_internal *ri, struct ratp_header *hdr)
static int ratp_send_next_data(struct ratp_internal *ri)
{
uint16_t crc;
- uint8_t control = RATP_CONTROL_ACK;
+ uint8_t control;
struct ratp_header *hdr;
+ uint8_t *data;
int pktlen;
struct ratp_message *msg;
int len;
@@ -404,24 +406,24 @@ static int ratp_send_next_data(struct ratp_internal *ri)
len = msg->len;
- control = ratp_set_sn(ri->sn_sent + 1) |
- ratp_set_an(ri->sn_received + 1) |
+ control = ratp_set_next_sn(ri->sn_sent) |
+ ratp_set_next_an(ri->sn_received) |
RATP_CONTROL_ACK;
hdr = msg->buf;
+ data = (uint8_t *)(hdr + 1);
if (msg->eor)
control |= RATP_CONTROL_EOR;
+ pktlen = sizeof(struct ratp_header);
if (len > 1) {
- void *data = hdr + 1;
- pktlen = sizeof(*hdr) + len + 2;
+ pktlen += len + 2;
crc = cyg_crc16(data, len);
put_unaligned_be16(crc, data + len);
- } else {
- pktlen = sizeof(struct ratp_header);
+ } else if (len == 1) {
control |= RATP_CONTROL_SO;
- len = 0;
+ len = *data;
}
ratp_create_packet(ri, hdr, control, len);
@@ -594,7 +596,7 @@ static void ratp_behaviour_b(struct ratp_internal *ri, void *pkt)
if ((hdr->control & RATP_CONTROL_ACK) && !ratp_an_expected(ri, hdr)) {
if (!(hdr->control & RATP_CONTROL_RST)) {
- uint8_t control = RATP_CONTROL_RST;
+ uint8_t control;
control = RATP_CONTROL_RST |
ratp_set_sn(ratp_an(hdr));
@@ -619,21 +621,25 @@ static void ratp_behaviour_b(struct ratp_internal *ri, void *pkt)
if (hdr->control & RATP_CONTROL_SYN) {
uint8_t control;
+ ri->sn_received = ratp_sn(hdr);
+
if (hdr->control & RATP_CONTROL_ACK) {
- control = ratp_set_sn(ratp_an(hdr)) |
- ratp_set_an(!ratp_sn(hdr)) |
- RATP_CONTROL_ACK;
+ ratp_state_change(ri, RATP_STATE_ESTABLISHED);
+ if (list_empty(&ri->sendmsg) || ri->sendmsg_current)
+ ratp_send_ack(ri, hdr);
+ else
+ ratp_send_next_data(ri);
} else {
- control = ratp_set_an(!ratp_sn(hdr)) |
+ struct ratp_header synack = {};
+
+ control = ratp_set_next_an(ratp_sn(hdr)) |
RATP_CONTROL_SYN |
RATP_CONTROL_ACK;
+ ratp_create_packet(ri, &synack, control, 255);
+ ratp_send_pkt(ri, &synack, sizeof(synack));
+ ratp_state_change(ri, RATP_STATE_SYN_RECEIVED);
}
-
- ri->sn_received = ratp_sn(hdr);
-
- ratp_send_hdr(ri, control);
- ratp_state_change(ri, RATP_STATE_ESTABLISHED);
}
}
@@ -716,9 +722,6 @@ static int ratp_behaviour_c2(struct ratp_internal *ri, void *pkt)
pr_debug("%s\n", __func__);
- if (!ratp_has_data(hdr))
- return 0;
-
if (ratp_sn_expected(ri, hdr))
return 0;
@@ -727,15 +730,19 @@ static int ratp_behaviour_c2(struct ratp_internal *ri, void *pkt)
return 1;
if (hdr->control & RATP_CONTROL_SYN) {
+ uint8_t control;
+
ri->status = -ECONNRESET;
pr_debug("Error: Connection reset\n");
+
+ control = RATP_CONTROL_RST | RATP_CONTROL_ACK |
+ ratp_set_sn(ratp_an(hdr)) | ratp_set_next_an(ratp_sn(hdr));
+ ratp_send_hdr(ri, control);
+
ratp_state_change(ri, RATP_STATE_CLOSED);
return 1;
}
- if (!ratp_has_data(hdr))
- return 1;
-
pr_debug("Sending ack for duplicate message\n");
ret = ratp_send_ack(ri, hdr);
if (ret)
@@ -1022,18 +1029,23 @@ static int ratp_behaviour_g(struct ratp_internal *ri, void *pkt)
pr_debug("%s\n", __func__);
+ if (hdr->control & RATP_CONTROL_RST)
+ return 0;
+
control = RATP_CONTROL_RST;
if (hdr->control & RATP_CONTROL_ACK)
control |= ratp_set_sn(ratp_an(hdr));
else
- control = ratp_set_an(ratp_sn(hdr) + 1) | RATP_CONTROL_ACK;
+ control |= ratp_set_next_an(ratp_sn(hdr)) | RATP_CONTROL_ACK;
ratp_send_hdr(ri, control);
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
@@ -1054,7 +1066,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);
}
/*
@@ -1085,7 +1101,7 @@ static int ratp_behaviour_h2(struct ratp_internal *ri, void *pkt)
ri->status = -ENETDOWN;
control = ratp_set_sn(ratp_an(hdr)) |
- ratp_set_an(ratp_sn(hdr) + 1) |
+ ratp_set_next_an(ratp_sn(hdr)) |
RATP_CONTROL_FIN |
RATP_CONTROL_ACK;
@@ -1151,7 +1167,7 @@ static int ratp_behaviour_h3(struct ratp_internal *ri, void *pkt)
if (ratp_has_data(hdr)) {
control = ratp_set_sn(ratp_an(hdr)) |
- ratp_set_an(ratp_sn(hdr) + 1) |
+ ratp_set_next_an(ratp_sn(hdr)) |
RATP_CONTROL_RST |
RATP_CONTROL_ACK;
ratp_send_hdr(ri, control);
@@ -1162,7 +1178,7 @@ static int ratp_behaviour_h3(struct ratp_internal *ri, void *pkt)
}
control = ratp_set_sn(ratp_an(hdr)) |
- ratp_set_an(ratp_sn(hdr) + 1) |
+ ratp_set_next_an(ratp_sn(hdr)) |
RATP_CONTROL_ACK;
expected = ratp_an_expected(ri, hdr);
@@ -1264,7 +1280,7 @@ static int ratp_behaviour_h6(struct ratp_internal *ri, void *pkt)
if (!(hdr->control & RATP_CONTROL_FIN))
return 1;
- control = ratp_set_sn(ratp_an(hdr) + 1) | RATP_CONTROL_ACK;
+ control = ratp_set_next_sn(ratp_an(hdr)) | RATP_CONTROL_ACK;
ratp_send_hdr(ri, control);
@@ -1322,9 +1338,8 @@ static int msg_recv(struct ratp_internal *ri, void *pkt)
static int ratp_behaviour_i1(struct ratp_internal *ri, void *pkt)
{
struct ratp_header *hdr = pkt;
- uint8_t control = 0;
- if (!hdr->data_length && !(hdr->control & RATP_CONTROL_SO))
+ if (!ratp_has_data (hdr))
return 1;
pr_vdebug("%s **received** %d\n", __func__, hdr->data_length);
@@ -1333,15 +1348,10 @@ static int ratp_behaviour_i1(struct ratp_internal *ri, void *pkt)
msg_recv(ri, pkt);
- if (list_empty(&ri->sendmsg) || ri->sendmsg_current) {
- control = ratp_set_sn(!ri->sn_sent) |
- ratp_set_an(ri->sn_received + 1) |
- RATP_CONTROL_ACK;
-
- ratp_send_hdr(ri, control);
- } else {
+ if (list_empty(&ri->sendmsg) || ri->sendmsg_current)
+ ratp_send_ack(ri, hdr);
+ else
ratp_send_next_data(ri);
- }
return 0;
}
@@ -1679,7 +1689,7 @@ void ratp_close(struct ratp *ratp)
if (!ri)
return;
- if (ri->state == RATP_STATE_ESTABLISHED) {
+ if (ri->state == RATP_STATE_ESTABLISHED || ri->state == RATP_STATE_SYN_RECEIVED) {
uint64_t start;
u8 control;
@@ -1687,8 +1697,8 @@ void ratp_close(struct ratp *ratp)
ratp_state_change(ri, RATP_STATE_FIN_WAIT);
- control = ratp_set_sn(!ri->sn_sent) |
- ratp_set_an(ri->sn_received + 1) |
+ control = ratp_set_next_sn(ri->sn_sent) |
+ ratp_set_next_an(ri->sn_received) |
RATP_CONTROL_FIN | RATP_CONTROL_ACK;
ratp_create_packet(ri, &fin, control, 0);
@@ -1831,4 +1841,4 @@ eor:
}
return 0;
-} \ No newline at end of file
+}
diff --git a/scripts/remote/ratp.py b/scripts/remote/ratp.py
index 079fb87..44f3e2f 100644
--- a/scripts/remote/ratp.py
+++ b/scripts/remote/ratp.py
@@ -339,9 +339,6 @@ class RatpConnection(object):
def _c2(self, r):
logging.info("C2")
- if r.length == 0 and r.c_so == 0:
- return True
-
if r.c_sn != self._r_sn:
return True
@@ -358,14 +355,11 @@ class RatpConnection(object):
self._state = RatpState.closed
return False
- # FIXME: only ack duplicate data packages?
- # This is not documented in RFC 916
- if r.length or r.c_so:
- logging.info("C2: duplicate data packet, dropping")
- s = RatpPacket(flags='A')
- s.c_sn = r.c_an
- s.c_an = (r.c_sn + 1) % 2
- self._write(s)
+ logging.info("C2: duplicate packet")
+ s = RatpPacket(flags='A')
+ s.c_sn = r.c_an
+ s.c_an = (r.c_sn + 1) % 2
+ self._write(s)
return False
@@ -495,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")
@@ -525,7 +515,7 @@ class RatpConnection(object):
# Our fin was lost, rely on retransmission
return False
- if r.length or r.c_so:
+ if (r.length and not r.c_syn and not r.c_rst and not r.c_fin) or r.c_so:
self._retrans = None
s = RatpPacket(flags='RA')
s.c_sn = r.c_an
@@ -590,13 +580,11 @@ 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))
- elif r.length:
+ elif r.length and not r.c_syn and not r.c_rst and not r.c_fin:
self._r_sn = r.c_sn
self._rx_buf.append(r.payload)
else:
@@ -614,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:
@@ -729,8 +721,8 @@ class RatpConnection(object):
def close(self, timeout=1.0):
deadline = monotonic() + timeout
logging.info("CLOSE")
- if self._state == RatpState.established:
- fin = RatpPacket(flags='FA') # FIXME: only F?
+ if self._state == RatpState.established or self._state == RatpState.syn_received:
+ fin = RatpPacket(flags='FA')
fin.c_sn = (self._s_sn + 1) % 2
fin.c_an = (self._r_sn + 1) % 2
self._write(fin)