diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c index 115cfb00..b3360f12 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -1660,10 +1660,12 @@ tcp_parseopt(struct tcp_pcb *pcb) return; } /* TCP timestamp option with valid length */ - tsval = (opts[c+2]) | (opts[c+3] << 8) | + tsval = (opts[c+2]) | (opts[c+3] << 8) | (opts[c+4] << 16) | (opts[c+5] << 24); if (flags & TCP_SYN) { pcb->ts_recent = ntohl(tsval); + /* Enable sending timestamps in every segment now that we know + the remote host supports it. */ pcb->flags |= TF_TIMESTAMP; } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) { pcb->ts_recent = ntohl(tsval); diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c index 8bd5d3ba..472e2963 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c @@ -393,6 +393,8 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) #if LWIP_TCP_TIMESTAMPS if ((pcb->flags & TF_TIMESTAMP)) { + /* Make sure the timestamp option is only included in data segments if we + agreed about it with the remote host. */ optflags = TF_SEG_OPTS_TS; optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS); } @@ -754,7 +756,9 @@ tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags) #endif /* LWIP_WND_SCALE */ } #if LWIP_TCP_TIMESTAMPS - if ((pcb->flags & TF_TIMESTAMP)) { + if ((pcb->flags & TF_TIMESTAMP) { + /* Make sure the timestamp option is only included in data segments if we + agreed about it with the remote host. */ optflags |= TF_SEG_OPTS_TS; } #endif /* LWIP_TCP_TIMESTAMPS */ diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 468c8bdc..82946d0f 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1055,6 +1055,9 @@ /** * LWIP_TCP_TIMESTAMPS==1: support the TCP timestamp option. + * The timestamp option is currently only used to help remote hosts, it is not + * really used locally. Therefore, it is only enabled when a TS option is + * received in the initial SYN packet from a remote host. */ #ifndef LWIP_TCP_TIMESTAMPS #define LWIP_TCP_TIMESTAMPS 0