net: tcp: Add TCP sequence number comparison compliant with RFC793.

RFC793, "Transmission Control Protocol", defines sequence numbers
just as 32-bit numbers without a sign. It doesn't specify any adhoc
rules for comparing them, so standard modular arithmetic should be
used.

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
This commit is contained in:
Paul Sokolovsky 2017-05-15 13:03:17 +03:00 committed by Jukka Rissanen
commit 72a30f3843
2 changed files with 33 additions and 11 deletions

View file

@ -863,6 +863,37 @@ int net_addr_pton(sa_family_t family, const char *src, void *dst);
char *net_addr_ntop(sa_family_t family, const void *src,
char *dst, size_t size);
/**
* @brief Compare TCP sequence numbers.
*
* @details This function compares TCP sequence numbers,
* accounting for wraparound effects.
*
* @param seq1 First sequence number
* @param seq2 Seconds sequence number
*
* @return < 0 if seq1 < seq2, 0 if seq1 == seq2, > 0 if seq > seq2
*/
static inline s32_t net_tcp_seq_cmp(u32_t seq1, u32_t seq2)
{
return (s32_t)(seq1 - seq2);
}
/**
* @brief Check that one TCP sequence number is greater.
*
* @details This is convenience function on top of net_tcp_seq_cmp().
*
* @param seq1 First sequence number
* @param seq2 Seconds sequence number
*
* @return True if seq > seq2
*/
static inline bool net_tcp_seq_greater(u32_t seq1, u32_t seq2)
{
return net_tcp_seq_cmp(seq1, seq2) > 0;
}
#ifdef __cplusplus
}
#endif

View file

@ -369,15 +369,6 @@ static inline u32_t get_recv_wnd(struct net_tcp *tcp)
return min(NET_TCP_MAX_WIN, NET_TCP_BUF_MAX_LEN);
}
/* True if the (signed!) difference "seq1 - seq2" is positive and less
* than 2^29. That is, seq1 is "after" seq2.
*/
static inline bool seq_greater(u32_t seq1, u32_t seq2)
{
int d = (int)(seq1 - seq2);
return d > 0 && d < 0x20000000;
}
int net_tcp_prepare_segment(struct net_tcp *tcp, u8_t flags,
void *options, size_t optlen,
const struct sockaddr_ptr *local,
@ -447,7 +438,7 @@ int net_tcp_prepare_segment(struct net_tcp *tcp, u8_t flags,
tcp->send_seq = seq;
if (seq_greater(tcp->send_seq, tcp->recv_max_ack)) {
if (net_tcp_seq_greater(tcp->send_seq, tcp->recv_max_ack)) {
tcp->recv_max_ack = tcp->send_seq;
}
@ -796,7 +787,7 @@ void net_tcp_ack_received(struct net_context *ctx, u32_t ack)
seq = sys_get_be32(tcphdr->seq) + net_pkt_appdatalen(pkt) - 1;
if (!seq_greater(ack, seq)) {
if (!net_tcp_seq_greater(ack, seq)) {
break;
}