TCP_CLOSED state (i.e. after the final FIN/ACK exchange), and has been
removed from the list of TCP connections.
* @v over Failure indicator
*/
void tcp_expired ( struct retry_timer *timer, int over ) {
* @v over Failure indicator
*/
void tcp_expired ( struct retry_timer *timer, int over ) {
- struct tcp_connection *conn;
- conn = ( struct tcp_connection * ) container_of ( timer,
- struct tcp_connection, timer );
+ struct tcp_connection *conn =
+ container_of ( timer, struct tcp_connection, timer );
+
DBG ( "Timer expired in %s\n", tcp_states[conn->tcp_state] );
switch ( conn->tcp_state ) {
case TCP_SYN_SENT:
if ( over ) {
DBG ( "Timer expired in %s\n", tcp_states[conn->tcp_state] );
switch ( conn->tcp_state ) {
case TCP_SYN_SENT:
if ( over ) {
+ list_del ( &conn->list );
tcp_trans ( conn, TCP_CLOSED );
tcp_trans ( conn, TCP_CLOSED );
+ if ( conn->tcp_op->closed )
+ conn->tcp_op->closed ( conn, -ETIMEDOUT );
DBG ( "Timeout! Connection closed\n" );
return;
}
goto send_tcp_nomsg;
case TCP_SYN_RCVD:
if ( over ) {
DBG ( "Timeout! Connection closed\n" );
return;
}
goto send_tcp_nomsg;
case TCP_SYN_RCVD:
if ( over ) {
+ list_del ( &conn->list );
tcp_trans ( conn, TCP_CLOSED );
tcp_trans ( conn, TCP_CLOSED );
+ if ( conn->tcp_op->closed )
+ conn->tcp_op->closed ( conn, -ETIMEDOUT );
goto send_tcp_nomsg;
}
goto send_tcp_nomsg;
goto send_tcp_nomsg;
}
goto send_tcp_nomsg;
}
return;
case TCP_TIME_WAIT:
}
return;
case TCP_TIME_WAIT:
+ list_del ( &conn->list );
tcp_trans ( conn, TCP_CLOSED );
tcp_trans ( conn, TCP_CLOSED );
+ if ( conn->tcp_op->closed )
+ conn->tcp_op->closed ( conn, 0 );
return;
}
/* Retransmit the data */
return;
}
/* Retransmit the data */
case TCP_SYN_RCVD:
case TCP_ESTABLISHED:
tcp_trans ( conn, TCP_FIN_WAIT_1 );
case TCP_SYN_RCVD:
case TCP_ESTABLISHED:
tcp_trans ( conn, TCP_FIN_WAIT_1 );
- if ( conn->tcp_op->closed )
- conn->tcp_op->closed ( conn, CONN_SNDCLOSE ); /* TODO: Check! */
/* FIN consumes one byte on the snd stream */
// conn->snd_una++;
goto send_tcp_nomsg;
/* FIN consumes one byte on the snd stream */
// conn->snd_una++;
goto send_tcp_nomsg;
list_del ( &conn->list );
tcp_trans ( conn, TCP_CLOSED );
if ( conn->tcp_op->closed )
list_del ( &conn->list );
tcp_trans ( conn, TCP_CLOSED );
if ( conn->tcp_op->closed )
- conn->tcp_op->closed ( conn, CONN_SNDCLOSE );
+ conn->tcp_op->closed ( conn, 0 );
return 0;
case TCP_CLOSE_WAIT:
tcp_trans ( conn, TCP_LAST_ACK );
return 0;
case TCP_CLOSE_WAIT:
tcp_trans ( conn, TCP_LAST_ACK );
- if ( conn->tcp_op->closed )
- conn->tcp_op->closed ( conn, CONN_SNDCLOSE ); /* TODO: Check! */
/* FIN consumes one byte on the snd stream */
// conn->snd_una++;
goto send_tcp_nomsg;
/* FIN consumes one byte on the snd stream */
// conn->snd_una++;
goto send_tcp_nomsg;
struct sockaddr_tcpip *st_dest __unused ) {
struct tcp_connection *conn;
struct tcp_header *tcphdr;
struct sockaddr_tcpip *st_dest __unused ) {
struct tcp_connection *conn;
struct tcp_header *tcphdr;
- uint32_t acked, toack;
- int hlen;
+ int32_t acked, toack;
+ unsigned int hlen;
int rc;
/* Sanity check */
int rc;
/* Sanity check */
if ( tcphdr->flags & TCP_RST ) {
tcp_trans ( conn, TCP_LISTEN );
if ( conn->tcp_op->closed )
if ( tcphdr->flags & TCP_RST ) {
tcp_trans ( conn, TCP_LISTEN );
if ( conn->tcp_op->closed )
- conn->tcp_op->closed ( conn, CONN_RESTART );
+ conn->tcp_op->closed ( conn, -ECONNRESET );
if ( tcphdr->flags & TCP_FIN ) {
conn->rcv_nxt++;
conn->tcp_flags |= TCP_ACK;
if ( tcphdr->flags & TCP_FIN ) {
conn->rcv_nxt++;
conn->tcp_flags |= TCP_ACK;
- if ( conn->tcp_op->closed )
- conn->tcp_op->closed ( conn, CONN_SNDCLOSE );
-
if ( tcphdr->flags & TCP_ACK ) {
tcp_trans ( conn, TCP_TIME_WAIT );
} else {
if ( tcphdr->flags & TCP_ACK ) {
tcp_trans ( conn, TCP_TIME_WAIT );
} else {
break;
case TCP_LAST_ACK:
if ( tcphdr->flags & TCP_ACK ) {
break;
case TCP_LAST_ACK:
if ( tcphdr->flags & TCP_ACK ) {
+ list_del ( &conn->list );
tcp_trans ( conn, TCP_CLOSED );
tcp_trans ( conn, TCP_CLOSED );
+ if ( conn->tcp_op->closed )
+ conn->tcp_op->closed ( conn, 0 );