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 @@ 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 @@ { 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_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_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 @@ 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 @@ 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 @@ 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 @@ pr_debug("%s\n", __func__); - if (!ratp_has_data(hdr)) - return 0; - if (ratp_sn_expected(ri, hdr)) return 0; @@ -727,15 +730,19 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ # 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 @@ 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 @@ 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 @@ 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)