From: Guo-Fu Tseng <coolda...@cooldavid.org> gPXE did not check the ACK number while receiving a response from remote server with ACK flag set. gPXE assumes the remote server ACKed the SYN/FIN sent by gPXE if received ANY packet with ACK flag being set. This error might occur when the packet is out-of-order.
Signed-off-by: Guo-Fu Tseng <coolda...@cooldavid.org> --- src/net/tcp.c | 26 +++++++++++++++++++++++--- 1 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/net/tcp.c b/src/net/tcp.c index 22f3936..c9ebc35 100644 --- a/src/net/tcp.c +++ b/src/net/tcp.c @@ -63,6 +63,17 @@ struct tcp_connection { * Equivalent to SND.WND in RFC 793 terminology */ uint32_t snd_win; + /** Send SYN sequence + * + * Sequence number of sent SYN packet + */ + uint32_t snd_syn_seq; + /** Send FIN sequence + * + * Sequence number of sent FIN packet + */ + uint32_t snd_fin_seq; + /** Current acknowledgement number * * Equivalent to RCV.NXT in RFC 793 terminology. @@ -525,6 +536,11 @@ static int tcp_xmit ( struct tcp_connection *tcp, int force_send ) { return rc; } + if ( flags & TCP_SYN ) + tcp->snd_syn_seq = tcp->snd_seq; + if ( flags & TCP_FIN ) + tcp->snd_fin_seq = tcp->snd_seq; + return 0; } @@ -745,7 +761,7 @@ static int tcp_rx_ack ( struct tcp_connection *tcp, uint32_t ack, uint32_t win ) { uint32_t ack_len = ( ack - tcp->snd_seq ); size_t len; - unsigned int acked_flags; + unsigned int acked_flags = 0; /* Check for out-of-range or old duplicate ACKs */ if ( ack_len > tcp->snd_sent ) { @@ -780,8 +796,12 @@ static int tcp_rx_ack ( struct tcp_connection *tcp, uint32_t ack, /* Determine acknowledged flags and data length */ len = ack_len; - acked_flags = ( TCP_FLAGS_SENDING ( tcp->tcp_state ) & - ( TCP_SYN | TCP_FIN ) ); + if ( ( TCP_FLAGS_SENDING ( tcp->tcp_state ) & TCP_SYN ) && + after ( ack, tcp->snd_syn_seq ) ) + acked_flags |= TCP_SYN; + if ( ( TCP_FLAGS_SENDING ( tcp->tcp_state ) & TCP_FIN ) && + after ( ack, tcp->snd_fin_seq ) ) + acked_flags |= TCP_FIN; if ( acked_flags ) len--; -- 1.7.1 _______________________________________________ gPXE-devel mailing list gPXE-devel@etherboot.org http://etherboot.org/mailman/listinfo/gpxe-devel