summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Brown2006-08-09 17:50:20 +0200
committerMichael Brown2006-08-09 17:50:20 +0200
commitf0718d562f2143f3058c914bf26c69c6790085d8 (patch)
treebc3c5c46bdc404a864988d4089f490e9c7f6fdab /src
parentChanged the TCP state machines behaviour in the ESTABLISHED state (diff)
downloadipxe-f0718d562f2143f3058c914bf26c69c6790085d8.tar.gz
ipxe-f0718d562f2143f3058c914bf26c69c6790085d8.tar.xz
ipxe-f0718d562f2143f3058c914bf26c69c6790085d8.zip
Don't call stop_timer() from within the timer expiry callback; it's
already stopped. Don't call start_timer() when sending a dataless ACK. This may or may not be the right thing to do; I can't tell. Back out broken "send ACK only if required to" logic temporarily.
Diffstat (limited to 'src')
-rw-r--r--src/net/tcp.c21
1 files changed, 10 insertions, 11 deletions
diff --git a/src/net/tcp.c b/src/net/tcp.c
index c3b7271d9..097b77d96 100644
--- a/src/net/tcp.c
+++ b/src/net/tcp.c
@@ -384,7 +384,6 @@ void tcp_expired ( struct retry_timer *timer, int over ) {
case TCP_SYN_SENT:
if ( over ) {
tcp_trans ( conn, TCP_CLOSED );
- stop_timer ( &conn->timer );
DBG ( "Timeout! Connection closed\n" );
return;
}
@@ -392,7 +391,6 @@ void tcp_expired ( struct retry_timer *timer, int over ) {
case TCP_SYN_RCVD:
if ( over ) {
tcp_trans ( conn, TCP_CLOSED );
- stop_timer ( &conn->timer );
goto send_tcp_nomsg;
}
goto send_tcp_nomsg;
@@ -417,7 +415,6 @@ void tcp_expired ( struct retry_timer *timer, int over ) {
return;
case TCP_TIME_WAIT:
tcp_trans ( conn, TCP_CLOSED );
- stop_timer ( &conn->timer );
return;
}
/* Retransmit the data */
@@ -632,6 +629,10 @@ int tcp_senddata ( struct tcp_connection *conn ) {
/* Call the senddata() call back function */
conn->tcp_op->senddata ( conn, conn->tx_pkb->data,
pkb_available ( conn->tx_pkb ) );
+ /* Send pure ACK if senddata() didn't call tcp_send() */
+ if ( conn->tx_pkb ) {
+ tcp_send ( conn, TCP_NOMSG, TCP_NOMSG_LEN );
+ }
return 0;
}
@@ -685,7 +686,8 @@ int tcp_send ( struct tcp_connection *conn, const void *data, size_t len ) {
/* Start the timer */
if ( ( conn->tcp_state == TCP_ESTABLISHED && conn->tcp_lstate == TCP_SYN_SENT ) ||
( conn->tcp_state == TCP_LISTEN && conn->tcp_lstate == TCP_SYN_RCVD ) ||
- ( conn->tcp_state == TCP_CLOSED && conn->tcp_lstate == TCP_SYN_RCVD ) ) {
+ ( conn->tcp_state == TCP_CLOSED && conn->tcp_lstate == TCP_SYN_RCVD ) ||
+ ( conn->tcp_state == TCP_ESTABLISHED && ( len == 0 ) ) ) {
// Don't start the timer
} else {
start_timer ( &conn->timer );
@@ -912,13 +914,10 @@ static int tcp_rx ( struct pk_buff *pkb,
ntohl ( tcphdr->seq ), conn->rcv_nxt );
}
- /* Send an ACK only if required to */
- if ( conn->rcv_nxt <= ntohl ( tcphdr->seq ) ) {
- /* Acknowledge new data */
- conn->tcp_flags |= TCP_ACK;
- if ( !( tcphdr->flags & TCP_ACK ) ) {
- goto send_tcp_nomsg;
- }
+ /* Acknowledge new data */
+ conn->tcp_flags |= TCP_ACK;
+ if ( !( tcphdr->flags & TCP_ACK ) ) {
+ goto send_tcp_nomsg;
}
}